Move WebKitSite to Websites
[WebKit-https.git] / Websites / webkit.org / perf / sunspider-0.9.1 / sunspider-0.9.1 / sunspider-test-contents.js
1 var testContents = [ "<!DOCTYPE html>\n\
2 <head>\n\
3 \n\
4 <meta charset=utf8>\n\
5 \n\
6 <!--\n\
7  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
8 \n\
9  Redistribution and use in source and binary forms, with or without\n\
10  modification, are permitted provided that the following conditions\n\
11  are met:\n\
12  1. Redistributions of source code must retain the above copyright\n\
13     notice, this list of conditions and the following disclaimer.\n\
14  2. Redistributions in binary form must reproduce the above copyright\n\
15     notice, this list of conditions and the following disclaimer in the\n\
16     documentation and/or other materials provided with the distribution.\n\
17 \n\
18  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
19  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
20  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
21  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
22  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
23  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
24  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
25  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
26  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
27  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
28  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
29 -->\n\
30 \n\
31 <title>SunSpider 3d-cube</title>\n\
32 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
33 </head>\n\
34 \n\
35 <body>\n\
36 <h3>3d-cube</h3>\n\
37 <div id=\"console\">\n\
38 </div>\n\
39 <script>\n\
40 function record(time) {\n\
41     document.getElementById(\"console\").innerHTML = time + \"ms\";\n\
42     if (window.parent) {\n\
43         parent.recordResult(time);\n\
44     }\n\
45 }\n\
46 \n\
47 var _sunSpiderStartDate = new Date();\n\
48 \n\
49 // 3D Cube Rotation\n\
50 // http://www.speich.net/computer/moztesting/3d.htm\n\
51 // Created by Simon Speich\n\
52 \n\
53 var Q = new Array();\n\
54 var MTrans = new Array();  // transformation matrix\n\
55 var MQube = new Array();  // position information of qube\n\
56 var I = new Array();      // entity matrix\n\
57 var Origin = new Object();\n\
58 var Testing = new Object();\n\
59 var LoopTimer;\n\
60 \n\
61 var DisplArea = new Object();\n\
62 DisplArea.Width = 300;\n\
63 DisplArea.Height = 300;\n\
64 \n\
65 function DrawLine(From, To) {\n\
66   var x1 = From.V[0];\n\
67   var x2 = To.V[0];\n\
68   var y1 = From.V[1];\n\
69   var y2 = To.V[1];\n\
70   var dx = Math.abs(x2 - x1);\n\
71   var dy = Math.abs(y2 - y1);\n\
72   var x = x1;\n\
73   var y = y1;\n\
74   var IncX1, IncY1;\n\
75   var IncX2, IncY2;  \n\
76   var Den;\n\
77   var Num;\n\
78   var NumAdd;\n\
79   var NumPix;\n\
80 \n\
81   if (x2 >= x1) {  IncX1 = 1; IncX2 = 1;  }\n\
82   else { IncX1 = -1; IncX2 = -1; }\n\
83   if (y2 >= y1)  {  IncY1 = 1; IncY2 = 1; }\n\
84   else { IncY1 = -1; IncY2 = -1; }\n\
85   if (dx >= dy) {\n\
86     IncX1 = 0;\n\
87     IncY2 = 0;\n\
88     Den = dx;\n\
89     Num = dx / 2;\n\
90     NumAdd = dy;\n\
91     NumPix = dx;\n\
92   }\n\
93   else {\n\
94     IncX2 = 0;\n\
95     IncY1 = 0;\n\
96     Den = dy;\n\
97     Num = dy / 2;\n\
98     NumAdd = dx;\n\
99     NumPix = dy;\n\
100   }\n\
101 \n\
102   NumPix = Math.round(Q.LastPx + NumPix);\n\
103 \n\
104   var i = Q.LastPx;\n\
105   for (; i < NumPix; i++) {\n\
106     Num += NumAdd;\n\
107     if (Num >= Den) {\n\
108       Num -= Den;\n\
109       x += IncX1;\n\
110       y += IncY1;\n\
111     }\n\
112     x += IncX2;\n\
113     y += IncY2;\n\
114   }\n\
115   Q.LastPx = NumPix;\n\
116 }\n\
117 \n\
118 function CalcCross(V0, V1) {\n\
119   var Cross = new Array();\n\
120   Cross[0] = V0[1]*V1[2] - V0[2]*V1[1];\n\
121   Cross[1] = V0[2]*V1[0] - V0[0]*V1[2];\n\
122   Cross[2] = V0[0]*V1[1] - V0[1]*V1[0];\n\
123   return Cross;\n\
124 }\n\
125 \n\
126 function CalcNormal(V0, V1, V2) {\n\
127   var A = new Array();   var B = new Array(); \n\
128   for (var i = 0; i < 3; i++) {\n\
129     A[i] = V0[i] - V1[i];\n\
130     B[i] = V2[i] - V1[i];\n\
131   }\n\
132   A = CalcCross(A, B);\n\
133   var Length = Math.sqrt(A[0]*A[0] + A[1]*A[1] + A[2]*A[2]); \n\
134   for (var i = 0; i < 3; i++) A[i] = A[i] / Length;\n\
135   A[3] = 1;\n\
136   return A;\n\
137 }\n\
138 \n\
139 function CreateP(X,Y,Z) {\n\
140   this.V = [X,Y,Z,1];\n\
141 }\n\
142 \n\
143 // multiplies two matrices\n\
144 function MMulti(M1, M2) {\n\
145   var M = [[],[],[],[]];\n\
146   var i = 0;\n\
147   var j = 0;\n\
148   for (; i < 4; i++) {\n\
149     j = 0;\n\
150     for (; j < 4; j++) M[i][j] = M1[i][0] * M2[0][j] + M1[i][1] * M2[1][j] + M1[i][2] * M2[2][j] + M1[i][3] * M2[3][j];\n\
151   }\n\
152   return M;\n\
153 }\n\
154 \n\
155 //multiplies matrix with vector\n\
156 function VMulti(M, V) {\n\
157   var Vect = new Array();\n\
158   var i = 0;\n\
159   for (;i < 4; i++) Vect[i] = M[i][0] * V[0] + M[i][1] * V[1] + M[i][2] * V[2] + M[i][3] * V[3];\n\
160   return Vect;\n\
161 }\n\
162 \n\
163 function VMulti2(M, V) {\n\
164   var Vect = new Array();\n\
165   var i = 0;\n\
166   for (;i < 3; i++) Vect[i] = M[i][0] * V[0] + M[i][1] * V[1] + M[i][2] * V[2];\n\
167   return Vect;\n\
168 }\n\
169 \n\
170 // add to matrices\n\
171 function MAdd(M1, M2) {\n\
172   var M = [[],[],[],[]];\n\
173   var i = 0;\n\
174   var j = 0;\n\
175   for (; i < 4; i++) {\n\
176     j = 0;\n\
177     for (; j < 4; j++) M[i][j] = M1[i][j] + M2[i][j];\n\
178   }\n\
179   return M;\n\
180 }\n\
181 \n\
182 function Translate(M, Dx, Dy, Dz) {\n\
183   var T = [\n\
184   [1,0,0,Dx],\n\
185   [0,1,0,Dy],\n\
186   [0,0,1,Dz],\n\
187   [0,0,0,1]\n\
188   ];\n\
189   return MMulti(T, M);\n\
190 }\n\
191 \n\
192 function RotateX(M, Phi) {\n\
193   var a = Phi;\n\
194   a *= Math.PI / 180;\n\
195   var Cos = Math.cos(a);\n\
196   var Sin = Math.sin(a);\n\
197   var R = [\n\
198   [1,0,0,0],\n\
199   [0,Cos,-Sin,0],\n\
200   [0,Sin,Cos,0],\n\
201   [0,0,0,1]\n\
202   ];\n\
203   return MMulti(R, M);\n\
204 }\n\
205 \n\
206 function RotateY(M, Phi) {\n\
207   var a = Phi;\n\
208   a *= Math.PI / 180;\n\
209   var Cos = Math.cos(a);\n\
210   var Sin = Math.sin(a);\n\
211   var R = [\n\
212   [Cos,0,Sin,0],\n\
213   [0,1,0,0],\n\
214   [-Sin,0,Cos,0],\n\
215   [0,0,0,1]\n\
216   ];\n\
217   return MMulti(R, M);\n\
218 }\n\
219 \n\
220 function RotateZ(M, Phi) {\n\
221   var a = Phi;\n\
222   a *= Math.PI / 180;\n\
223   var Cos = Math.cos(a);\n\
224   var Sin = Math.sin(a);\n\
225   var R = [\n\
226   [Cos,-Sin,0,0],\n\
227   [Sin,Cos,0,0],\n\
228   [0,0,1,0],   \n\
229   [0,0,0,1]\n\
230   ];\n\
231   return MMulti(R, M);\n\
232 }\n\
233 \n\
234 function DrawQube() {\n\
235   // calc current normals\n\
236   var CurN = new Array();\n\
237   var i = 5;\n\
238   Q.LastPx = 0;\n\
239   for (; i > -1; i--) CurN[i] = VMulti2(MQube, Q.Normal[i]);\n\
240   if (CurN[0][2] < 0) {\n\
241     if (!Q.Line[0]) { DrawLine(Q[0], Q[1]); Q.Line[0] = true; };\n\
242     if (!Q.Line[1]) { DrawLine(Q[1], Q[2]); Q.Line[1] = true; };\n\
243     if (!Q.Line[2]) { DrawLine(Q[2], Q[3]); Q.Line[2] = true; };\n\
244     if (!Q.Line[3]) { DrawLine(Q[3], Q[0]); Q.Line[3] = true; };\n\
245   }\n\
246   if (CurN[1][2] < 0) {\n\
247     if (!Q.Line[2]) { DrawLine(Q[3], Q[2]); Q.Line[2] = true; };\n\
248     if (!Q.Line[9]) { DrawLine(Q[2], Q[6]); Q.Line[9] = true; };\n\
249     if (!Q.Line[6]) { DrawLine(Q[6], Q[7]); Q.Line[6] = true; };\n\
250     if (!Q.Line[10]) { DrawLine(Q[7], Q[3]); Q.Line[10] = true; };\n\
251   }\n\
252   if (CurN[2][2] < 0) {\n\
253     if (!Q.Line[4]) { DrawLine(Q[4], Q[5]); Q.Line[4] = true; };\n\
254     if (!Q.Line[5]) { DrawLine(Q[5], Q[6]); Q.Line[5] = true; };\n\
255     if (!Q.Line[6]) { DrawLine(Q[6], Q[7]); Q.Line[6] = true; };\n\
256     if (!Q.Line[7]) { DrawLine(Q[7], Q[4]); Q.Line[7] = true; };\n\
257   }\n\
258   if (CurN[3][2] < 0) {\n\
259     if (!Q.Line[4]) { DrawLine(Q[4], Q[5]); Q.Line[4] = true; };\n\
260     if (!Q.Line[8]) { DrawLine(Q[5], Q[1]); Q.Line[8] = true; };\n\
261     if (!Q.Line[0]) { DrawLine(Q[1], Q[0]); Q.Line[0] = true; };\n\
262     if (!Q.Line[11]) { DrawLine(Q[0], Q[4]); Q.Line[11] = true; };\n\
263   }\n\
264   if (CurN[4][2] < 0) {\n\
265     if (!Q.Line[11]) { DrawLine(Q[4], Q[0]); Q.Line[11] = true; };\n\
266     if (!Q.Line[3]) { DrawLine(Q[0], Q[3]); Q.Line[3] = true; };\n\
267     if (!Q.Line[10]) { DrawLine(Q[3], Q[7]); Q.Line[10] = true; };\n\
268     if (!Q.Line[7]) { DrawLine(Q[7], Q[4]); Q.Line[7] = true; };\n\
269   }\n\
270   if (CurN[5][2] < 0) {\n\
271     if (!Q.Line[8]) { DrawLine(Q[1], Q[5]); Q.Line[8] = true; };\n\
272     if (!Q.Line[5]) { DrawLine(Q[5], Q[6]); Q.Line[5] = true; };\n\
273     if (!Q.Line[9]) { DrawLine(Q[6], Q[2]); Q.Line[9] = true; };\n\
274     if (!Q.Line[1]) { DrawLine(Q[2], Q[1]); Q.Line[1] = true; };\n\
275   }\n\
276   Q.Line = [false,false,false,false,false,false,false,false,false,false,false,false];\n\
277   Q.LastPx = 0;\n\
278 }\n\
279 \n\
280 function Loop() {\n\
281   if (Testing.LoopCount > Testing.LoopMax) return;\n\
282   var TestingStr = String(Testing.LoopCount);\n\
283   while (TestingStr.length < 3) TestingStr = \"0\" + TestingStr;\n\
284   MTrans = Translate(I, -Q[8].V[0], -Q[8].V[1], -Q[8].V[2]);\n\
285   MTrans = RotateX(MTrans, 1);\n\
286   MTrans = RotateY(MTrans, 3);\n\
287   MTrans = RotateZ(MTrans, 5);\n\
288   MTrans = Translate(MTrans, Q[8].V[0], Q[8].V[1], Q[8].V[2]);\n\
289   MQube = MMulti(MTrans, MQube);\n\
290   var i = 8;\n\
291   for (; i > -1; i--) {\n\
292     Q[i].V = VMulti(MTrans, Q[i].V);\n\
293   }\n\
294   DrawQube();\n\
295   Testing.LoopCount++;\n\
296   Loop();\n\
297 }\n\
298 \n\
299 function Init(CubeSize) {\n\
300   // init/reset vars\n\
301   Origin.V = [150,150,20,1];\n\
302   Testing.LoopCount = 0;\n\
303   Testing.LoopMax = 50;\n\
304   Testing.TimeMax = 0;\n\
305   Testing.TimeAvg = 0;\n\
306   Testing.TimeMin = 0;\n\
307   Testing.TimeTemp = 0;\n\
308   Testing.TimeTotal = 0;\n\
309   Testing.Init = false;\n\
310 \n\
311   // transformation matrix\n\
312   MTrans = [\n\
313   [1,0,0,0],\n\
314   [0,1,0,0],\n\
315   [0,0,1,0],\n\
316   [0,0,0,1]\n\
317   ];\n\
318   \n\
319   // position information of qube\n\
320   MQube = [\n\
321   [1,0,0,0],\n\
322   [0,1,0,0],\n\
323   [0,0,1,0],\n\
324   [0,0,0,1]\n\
325   ];\n\
326   \n\
327   // entity matrix\n\
328   I = [\n\
329   [1,0,0,0],\n\
330   [0,1,0,0],\n\
331   [0,0,1,0],\n\
332   [0,0,0,1]\n\
333   ];\n\
334   \n\
335   // create qube\n\
336   Q[0] = new CreateP(-CubeSize,-CubeSize, CubeSize);\n\
337   Q[1] = new CreateP(-CubeSize, CubeSize, CubeSize);\n\
338   Q[2] = new CreateP( CubeSize, CubeSize, CubeSize);\n\
339   Q[3] = new CreateP( CubeSize,-CubeSize, CubeSize);\n\
340   Q[4] = new CreateP(-CubeSize,-CubeSize,-CubeSize);\n\
341   Q[5] = new CreateP(-CubeSize, CubeSize,-CubeSize);\n\
342   Q[6] = new CreateP( CubeSize, CubeSize,-CubeSize);\n\
343   Q[7] = new CreateP( CubeSize,-CubeSize,-CubeSize);\n\
344   \n\
345   // center of gravity\n\
346   Q[8] = new CreateP(0, 0, 0);\n\
347   \n\
348   // anti-clockwise edge check\n\
349   Q.Edge = [[0,1,2],[3,2,6],[7,6,5],[4,5,1],[4,0,3],[1,5,6]];\n\
350   \n\
351   // calculate squad normals\n\
352   Q.Normal = new Array();\n\
353   for (var i = 0; i < Q.Edge.length; i++) Q.Normal[i] = CalcNormal(Q[Q.Edge[i][0]].V, Q[Q.Edge[i][1]].V, Q[Q.Edge[i][2]].V);\n\
354   \n\
355   // line drawn ?\n\
356   Q.Line = [false,false,false,false,false,false,false,false,false,false,false,false];\n\
357   \n\
358   // create line pixels\n\
359   Q.NumPx = 9 * 2 * CubeSize;\n\
360   for (var i = 0; i < Q.NumPx; i++) CreateP(0,0,0);\n\
361   \n\
362   MTrans = Translate(MTrans, Origin.V[0], Origin.V[1], Origin.V[2]);\n\
363   MQube = MMulti(MTrans, MQube);\n\
364 \n\
365   var i = 0;\n\
366   for (; i < 9; i++) {\n\
367     Q[i].V = VMulti(MTrans, Q[i].V);\n\
368   }\n\
369   DrawQube();\n\
370   Testing.Init = true;\n\
371   Loop();\n\
372 }\n\
373 \n\
374 for ( var i = 20; i <= 160; i *= 2 ) {\n\
375   Init(i);\n\
376 }\n\
377 \n\
378 Q = null;\n\
379 MTrans = null;\n\
380 MQube = null;\n\
381 I = null;\n\
382 Origin = null;\n\
383 Testing = null;\n\
384 LoopTime = null;\n\
385 DisplArea = null;\n\
386 \n\
387 \n\
388 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
389 \n\
390 record(_sunSpiderInterval);\n\
391 </script>\n\
392 \n\
393 \n\
394 </body>\n\
395 </html>\n\
396 ", "<!DOCTYPE html>\n\
397 <head>\n\
398 \n\
399 <meta charset=utf8>\n\
400 \n\
401 <!--\n\
402  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
403 \n\
404  Redistribution and use in source and binary forms, with or without\n\
405  modification, are permitted provided that the following conditions\n\
406  are met:\n\
407  1. Redistributions of source code must retain the above copyright\n\
408     notice, this list of conditions and the following disclaimer.\n\
409  2. Redistributions in binary form must reproduce the above copyright\n\
410     notice, this list of conditions and the following disclaimer in the\n\
411     documentation and/or other materials provided with the distribution.\n\
412 \n\
413  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
414  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
415  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
416  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
417  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
418  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
419  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
420  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
421  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
422  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
423  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
424 -->\n\
425 \n\
426 <title>SunSpider 3d-morph</title>\n\
427 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
428 </head>\n\
429 \n\
430 <body>\n\
431 <h3>3d-morph</h3>\n\
432 <div id=\"console\">\n\
433 </div>\n\
434 <script>\n\
435 function record(time) {\n\
436     document.getElementById(\"console\").innerHTML = time + \"ms\";\n\
437     if (window.parent) {\n\
438         parent.recordResult(time);\n\
439     }\n\
440 }\n\
441 \n\
442 var _sunSpiderStartDate = new Date();\n\
443 \n\
444 /*\n\
445  * Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
446  *\n\
447  * Redistribution and use in source and binary forms, with or without\n\
448  * modification, are permitted provided that the following conditions\n\
449  * are met:\n\
450  * 1. Redistributions of source code must retain the above copyright\n\
451  *    notice, this list of conditions and the following disclaimer.\n\
452  * 2. Redistributions in binary form must reproduce the above copyright\n\
453  *    notice, this list of conditions and the following disclaimer in the\n\
454  *    documentation and/or other materials provided with the distribution.\n\
455  *\n\
456  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
457  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
458  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
459  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
460  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
461  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
462  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
463  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
464  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
465  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
466  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
467  */\n\
468 \n\
469 var loops = 15\n\
470 var nx = 120\n\
471 var nz = 120\n\
472 \n\
473 function morph(a, f) {\n\
474     var PI2nx = Math.PI * 8/nx\n\
475     var sin = Math.sin\n\
476     var f30 = -(50 * sin(f*Math.PI*2))\n\
477     \n\
478     for (var i = 0; i < nz; ++i) {\n\
479         for (var j = 0; j < nx; ++j) {\n\
480             a[3*(i*nx+j)+1]    = sin((j-1) * PI2nx ) * -f30\n\
481         }\n\
482     }\n\
483 }\n\
484 \n\
485     \n\
486 var a = Array()\n\
487 for (var i=0; i < nx*nz*3; ++i) \n\
488     a[i] = 0\n\
489 \n\
490 for (var i = 0; i < loops; ++i) {\n\
491     morph(a, i/loops)\n\
492 }\n\
493 \n\
494 testOutput = 0;\n\
495 for (var i = 0; i < nx; i++)\n\
496     testOutput += a[3*(i*nx+i)+1];\n\
497 a = null;\n\
498 \n\
499 \n\
500 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
501 \n\
502 record(_sunSpiderInterval);\n\
503 </script>\n\
504 \n\
505 \n\
506 </body>\n\
507 </html>\n\
508 ", "<!DOCTYPE html>\n\
509 <head>\n\
510 \n\
511 <meta charset=utf8>\n\
512 \n\
513 <!--\n\
514  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
515 \n\
516  Redistribution and use in source and binary forms, with or without\n\
517  modification, are permitted provided that the following conditions\n\
518  are met:\n\
519  1. Redistributions of source code must retain the above copyright\n\
520     notice, this list of conditions and the following disclaimer.\n\
521  2. Redistributions in binary form must reproduce the above copyright\n\
522     notice, this list of conditions and the following disclaimer in the\n\
523     documentation and/or other materials provided with the distribution.\n\
524 \n\
525  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
526  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
527  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
528  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
529  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
530  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
531  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
532  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
533  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
534  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
535  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
536 -->\n\
537 \n\
538 <title>SunSpider 3d-raytrace</title>\n\
539 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
540 </head>\n\
541 \n\
542 <body>\n\
543 <h3>3d-raytrace</h3>\n\
544 <div id=\"console\">\n\
545 </div>\n\
546 <script>\n\
547 function record(time) {\n\
548     document.getElementById(\"console\").innerHTML = time + \"ms\";\n\
549     if (window.parent) {\n\
550         parent.recordResult(time);\n\
551     }\n\
552 }\n\
553 \n\
554 var _sunSpiderStartDate = new Date();\n\
555 \n\
556 /*\n\
557  * Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
558  *\n\
559  * Redistribution and use in source and binary forms, with or without\n\
560  * modification, are permitted provided that the following conditions\n\
561  * are met:\n\
562  * 1. Redistributions of source code must retain the above copyright\n\
563  *    notice, this list of conditions and the following disclaimer.\n\
564  * 2. Redistributions in binary form must reproduce the above copyright\n\
565  *    notice, this list of conditions and the following disclaimer in the\n\
566  *    documentation and/or other materials provided with the distribution.\n\
567  *\n\
568  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
569  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
570  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
571  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
572  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
573  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
574  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
575  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
576  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
577  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
578  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
579  */\n\
580 \n\
581 function createVector(x,y,z) {\n\
582     return new Array(x,y,z);\n\
583 }\n\
584 \n\
585 function sqrLengthVector(self) {\n\
586     return self[0] * self[0] + self[1] * self[1] + self[2] * self[2];\n\
587 }\n\
588 \n\
589 function lengthVector(self) {\n\
590     return Math.sqrt(self[0] * self[0] + self[1] * self[1] + self[2] * self[2]);\n\
591 }\n\
592 \n\
593 function addVector(self, v) {\n\
594     self[0] += v[0];\n\
595     self[1] += v[1];\n\
596     self[2] += v[2];\n\
597     return self;\n\
598 }\n\
599 \n\
600 function subVector(self, v) {\n\
601     self[0] -= v[0];\n\
602     self[1] -= v[1];\n\
603     self[2] -= v[2];\n\
604     return self;\n\
605 }\n\
606 \n\
607 function scaleVector(self, scale) {\n\
608     self[0] *= scale;\n\
609     self[1] *= scale;\n\
610     self[2] *= scale;\n\
611     return self;\n\
612 }\n\
613 \n\
614 function normaliseVector(self) {\n\
615     var len = Math.sqrt(self[0] * self[0] + self[1] * self[1] + self[2] * self[2]);\n\
616     self[0] /= len;\n\
617     self[1] /= len;\n\
618     self[2] /= len;\n\
619     return self;\n\
620 }\n\
621 \n\
622 function add(v1, v2) {\n\
623     return new Array(v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]);\n\
624 }\n\
625 \n\
626 function sub(v1, v2) {\n\
627     return new Array(v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2]);\n\
628 }\n\
629 \n\
630 function scalev(v1, v2) {\n\
631     return new Array(v1[0] * v2[0], v1[1] * v2[1], v1[2] * v2[2]);\n\
632 }\n\
633 \n\
634 function dot(v1, v2) {\n\
635     return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];\n\
636 }\n\
637 \n\
638 function scale(v, scale) {\n\
639     return [v[0] * scale, v[1] * scale, v[2] * scale];\n\
640 }\n\
641 \n\
642 function cross(v1, v2) {\n\
643     return [v1[1] * v2[2] - v1[2] * v2[1], \n\
644             v1[2] * v2[0] - v1[0] * v2[2],\n\
645             v1[0] * v2[1] - v1[1] * v2[0]];\n\
646 \n\
647 }\n\
648 \n\
649 function normalise(v) {\n\
650     var len = lengthVector(v);\n\
651     return [v[0] / len, v[1] / len, v[2] / len];\n\
652 }\n\
653 \n\
654 function transformMatrix(self, v) {\n\
655     var vals = self;\n\
656     var x  = vals[0] * v[0] + vals[1] * v[1] + vals[2] * v[2] + vals[3];\n\
657     var y  = vals[4] * v[0] + vals[5] * v[1] + vals[6] * v[2] + vals[7];\n\
658     var z  = vals[8] * v[0] + vals[9] * v[1] + vals[10] * v[2] + vals[11];\n\
659     return [x, y, z];\n\
660 }\n\
661 \n\
662 function invertMatrix(self) {\n\
663     var temp = new Array(16);\n\
664     var tx = -self[3];\n\
665     var ty = -self[7];\n\
666     var tz = -self[11];\n\
667     for (h = 0; h < 3; h++) \n\
668         for (v = 0; v < 3; v++) \n\
669             temp[h + v * 4] = self[v + h * 4];\n\
670     for (i = 0; i < 11; i++)\n\
671         self[i] = temp[i];\n\
672     self[3] = tx * self[0] + ty * self[1] + tz * self[2];\n\
673     self[7] = tx * self[4] + ty * self[5] + tz * self[6];\n\
674     self[11] = tx * self[8] + ty * self[9] + tz * self[10];\n\
675     return self;\n\
676 }\n\
677 \n\
678 \n\
679 // Triangle intersection using barycentric coord method\n\
680 function Triangle(p1, p2, p3) {\n\
681     var edge1 = sub(p3, p1);\n\
682     var edge2 = sub(p2, p1);\n\
683     var normal = cross(edge1, edge2);\n\
684     if (Math.abs(normal[0]) > Math.abs(normal[1]))\n\
685         if (Math.abs(normal[0]) > Math.abs(normal[2]))\n\
686             this.axis = 0; \n\
687         else \n\
688             this.axis = 2;\n\
689     else\n\
690         if (Math.abs(normal[1]) > Math.abs(normal[2])) \n\
691             this.axis = 1;\n\
692         else \n\
693             this.axis = 2;\n\
694     var u = (this.axis + 1) % 3;\n\
695     var v = (this.axis + 2) % 3;\n\
696     var u1 = edge1[u];\n\
697     var v1 = edge1[v];\n\
698     \n\
699     var u2 = edge2[u];\n\
700     var v2 = edge2[v];\n\
701     this.normal = normalise(normal);\n\
702     this.nu = normal[u] / normal[this.axis];\n\
703     this.nv = normal[v] / normal[this.axis];\n\
704     this.nd = dot(normal, p1) / normal[this.axis];\n\
705     var det = u1 * v2 - v1 * u2;\n\
706     this.eu = p1[u];\n\
707     this.ev = p1[v]; \n\
708     this.nu1 = u1 / det;\n\
709     this.nv1 = -v1 / det;\n\
710     this.nu2 = v2 / det;\n\
711     this.nv2 = -u2 / det; \n\
712     this.material = [0.7, 0.7, 0.7];\n\
713 }\n\
714 \n\
715 Triangle.prototype.intersect = function(orig, dir, near, far) {\n\
716     var u = (this.axis + 1) % 3;\n\
717     var v = (this.axis + 2) % 3;\n\
718     var d = dir[this.axis] + this.nu * dir[u] + this.nv * dir[v];\n\
719     var t = (this.nd - orig[this.axis] - this.nu * orig[u] - this.nv * orig[v]) / d;\n\
720     if (t < near || t > far)\n\
721         return null;\n\
722     var Pu = orig[u] + t * dir[u] - this.eu;\n\
723     var Pv = orig[v] + t * dir[v] - this.ev;\n\
724     var a2 = Pv * this.nu1 + Pu * this.nv1;\n\
725     if (a2 < 0) \n\
726         return null;\n\
727     var a3 = Pu * this.nu2 + Pv * this.nv2;\n\
728     if (a3 < 0) \n\
729         return null;\n\
730 \n\
731     if ((a2 + a3) > 1) \n\
732         return null;\n\
733     return t;\n\
734 }\n\
735 \n\
736 function Scene(a_triangles) {\n\
737     this.triangles = a_triangles;\n\
738     this.lights = [];\n\
739     this.ambient = [0,0,0];\n\
740     this.background = [0.8,0.8,1];\n\
741 }\n\
742 var zero = new Array(0,0,0);\n\
743 \n\
744 Scene.prototype.intersect = function(origin, dir, near, far) {\n\
745     var closest = null;\n\
746     for (i = 0; i < this.triangles.length; i++) {\n\
747         var triangle = this.triangles[i];   \n\
748         var d = triangle.intersect(origin, dir, near, far);\n\
749         if (d == null || d > far || d < near)\n\
750             continue;\n\
751         far = d;\n\
752         closest = triangle;\n\
753     }\n\
754     \n\
755     if (!closest)\n\
756         return [this.background[0],this.background[1],this.background[2]];\n\
757         \n\
758     var normal = closest.normal;\n\
759     var hit = add(origin, scale(dir, far)); \n\
760     if (dot(dir, normal) > 0)\n\
761         normal = [-normal[0], -normal[1], -normal[2]];\n\
762     \n\
763     var colour = null;\n\
764     if (closest.shader) {\n\
765         colour = closest.shader(closest, hit, dir);\n\
766     } else {\n\
767         colour = closest.material;\n\
768     }\n\
769     \n\
770     // do reflection\n\
771     var reflected = null;\n\
772     if (colour.reflection > 0.001) {\n\
773         var reflection = addVector(scale(normal, -2*dot(dir, normal)), dir);\n\
774         reflected = this.intersect(hit, reflection, 0.0001, 1000000);\n\
775         if (colour.reflection >= 0.999999)\n\
776             return reflected;\n\
777     }\n\
778     \n\
779     var l = [this.ambient[0], this.ambient[1], this.ambient[2]];\n\
780     for (var i = 0; i < this.lights.length; i++) {\n\
781         var light = this.lights[i];\n\
782         var toLight = sub(light, hit);\n\
783         var distance = lengthVector(toLight);\n\
784         scaleVector(toLight, 1.0/distance);\n\
785         distance -= 0.0001;\n\
786         if (this.blocked(hit, toLight, distance))\n\
787             continue;\n\
788         var nl = dot(normal, toLight);\n\
789         if (nl > 0)\n\
790             addVector(l, scale(light.colour, nl));\n\
791     }\n\
792     l = scalev(l, colour);\n\
793     if (reflected) {\n\
794         l = addVector(scaleVector(l, 1 - colour.reflection), scaleVector(reflected, colour.reflection));\n\
795     }\n\
796     return l;\n\
797 }\n\
798 \n\
799 Scene.prototype.blocked = function(O, D, far) {\n\
800     var near = 0.0001;\n\
801     var closest = null;\n\
802     for (i = 0; i < this.triangles.length; i++) {\n\
803         var triangle = this.triangles[i];   \n\
804         var d = triangle.intersect(O, D, near, far);\n\
805         if (d == null || d > far || d < near)\n\
806             continue;\n\
807         return true;\n\
808     }\n\
809     \n\
810     return false;\n\
811 }\n\
812 \n\
813 \n\
814 // this camera code is from notes i made ages ago, it is from *somewhere* -- i cannot remember where\n\
815 // that somewhere is\n\
816 function Camera(origin, lookat, up) {\n\
817     var zaxis = normaliseVector(subVector(lookat, origin));\n\
818     var xaxis = normaliseVector(cross(up, zaxis));\n\
819     var yaxis = normaliseVector(cross(xaxis, subVector([0,0,0], zaxis)));\n\
820     var m = new Array(16);\n\
821     m[0] = xaxis[0]; m[1] = xaxis[1]; m[2] = xaxis[2];\n\
822     m[4] = yaxis[0]; m[5] = yaxis[1]; m[6] = yaxis[2];\n\
823     m[8] = zaxis[0]; m[9] = zaxis[1]; m[10] = zaxis[2];\n\
824     invertMatrix(m);\n\
825     m[3] = 0; m[7] = 0; m[11] = 0;\n\
826     this.origin = origin;\n\
827     this.directions = new Array(4);\n\
828     this.directions[0] = normalise([-0.7,  0.7, 1]);\n\
829     this.directions[1] = normalise([ 0.7,  0.7, 1]);\n\
830     this.directions[2] = normalise([ 0.7, -0.7, 1]);\n\
831     this.directions[3] = normalise([-0.7, -0.7, 1]);\n\
832     this.directions[0] = transformMatrix(m, this.directions[0]);\n\
833     this.directions[1] = transformMatrix(m, this.directions[1]);\n\
834     this.directions[2] = transformMatrix(m, this.directions[2]);\n\
835     this.directions[3] = transformMatrix(m, this.directions[3]);\n\
836 }\n\
837 \n\
838 Camera.prototype.generateRayPair = function(y) {\n\
839     rays = new Array(new Object(), new Object());\n\
840     rays[0].origin = this.origin;\n\
841     rays[1].origin = this.origin;\n\
842     rays[0].dir = addVector(scale(this.directions[0], y), scale(this.directions[3], 1 - y));\n\
843     rays[1].dir = addVector(scale(this.directions[1], y), scale(this.directions[2], 1 - y));\n\
844     return rays;\n\
845 }\n\
846 \n\
847 function renderRows(camera, scene, pixels, width, height, starty, stopy) {\n\
848     for (var y = starty; y < stopy; y++) {\n\
849         var rays = camera.generateRayPair(y / height);\n\
850         for (var x = 0; x < width; x++) {\n\
851             var xp = x / width;\n\
852             var origin = addVector(scale(rays[0].origin, xp), scale(rays[1].origin, 1 - xp));\n\
853             var dir = normaliseVector(addVector(scale(rays[0].dir, xp), scale(rays[1].dir, 1 - xp)));\n\
854             var l = scene.intersect(origin, dir);\n\
855             pixels[y][x] = l;\n\
856         }\n\
857     }\n\
858 }\n\
859 \n\
860 Camera.prototype.render = function(scene, pixels, width, height) {\n\
861     var cam = this;\n\
862     var row = 0;\n\
863     renderRows(cam, scene, pixels, width, height, 0, height);\n\
864 }\n\
865 \n\
866 \n\
867 \n\
868 function raytraceScene()\n\
869 {\n\
870     var startDate = new Date().getTime();\n\
871     var numTriangles = 2 * 6;\n\
872     var triangles = new Array();//numTriangles);\n\
873     var tfl = createVector(-10,  10, -10);\n\
874     var tfr = createVector( 10,  10, -10);\n\
875     var tbl = createVector(-10,  10,  10);\n\
876     var tbr = createVector( 10,  10,  10);\n\
877     var bfl = createVector(-10, -10, -10);\n\
878     var bfr = createVector( 10, -10, -10);\n\
879     var bbl = createVector(-10, -10,  10);\n\
880     var bbr = createVector( 10, -10,  10);\n\
881     \n\
882     // cube!!!\n\
883     // front\n\
884     var i = 0;\n\
885     \n\
886     triangles[i++] = new Triangle(tfl, tfr, bfr);\n\
887     triangles[i++] = new Triangle(tfl, bfr, bfl);\n\
888     // back\n\
889     triangles[i++] = new Triangle(tbl, tbr, bbr);\n\
890     triangles[i++] = new Triangle(tbl, bbr, bbl);\n\
891     //        triangles[i-1].material = [0.7,0.2,0.2];\n\
892     //            triangles[i-1].material.reflection = 0.8;\n\
893     // left\n\
894     triangles[i++] = new Triangle(tbl, tfl, bbl);\n\
895     //            triangles[i-1].reflection = 0.6;\n\
896     triangles[i++] = new Triangle(tfl, bfl, bbl);\n\
897     //            triangles[i-1].reflection = 0.6;\n\
898     // right\n\
899     triangles[i++] = new Triangle(tbr, tfr, bbr);\n\
900     triangles[i++] = new Triangle(tfr, bfr, bbr);\n\
901     // top\n\
902     triangles[i++] = new Triangle(tbl, tbr, tfr);\n\
903     triangles[i++] = new Triangle(tbl, tfr, tfl);\n\
904     // bottom\n\
905     triangles[i++] = new Triangle(bbl, bbr, bfr);\n\
906     triangles[i++] = new Triangle(bbl, bfr, bfl);\n\
907     \n\
908     //Floor!!!!\n\
909     var green = createVector(0.0, 0.4, 0.0);\n\
910     var grey = createVector(0.4, 0.4, 0.4);\n\
911     grey.reflection = 1.0;\n\
912     var floorShader = function(tri, pos, view) {\n\
913         var x = ((pos[0]/32) % 2 + 2) % 2;\n\
914         var z = ((pos[2]/32 + 0.3) % 2 + 2) % 2;\n\
915         if (x < 1 != z < 1) {\n\
916             //in the real world we use the fresnel term...\n\
917             //    var angle = 1-dot(view, tri.normal);\n\
918             //   angle *= angle;\n\
919             //  angle *= angle;\n\
920             // angle *= angle;\n\
921             //grey.reflection = angle;\n\
922             return grey;\n\
923         } else \n\
924             return green;\n\
925     }\n\
926     var ffl = createVector(-1000, -30, -1000);\n\
927     var ffr = createVector( 1000, -30, -1000);\n\
928     var fbl = createVector(-1000, -30,  1000);\n\
929     var fbr = createVector( 1000, -30,  1000);\n\
930     triangles[i++] = new Triangle(fbl, fbr, ffr);\n\
931     triangles[i-1].shader = floorShader;\n\
932     triangles[i++] = new Triangle(fbl, ffr, ffl);\n\
933     triangles[i-1].shader = floorShader;\n\
934     \n\
935     var _scene = new Scene(triangles);\n\
936     _scene.lights[0] = createVector(20, 38, -22);\n\
937     _scene.lights[0].colour = createVector(0.7, 0.3, 0.3);\n\
938     _scene.lights[1] = createVector(-23, 40, 17);\n\
939     _scene.lights[1].colour = createVector(0.7, 0.3, 0.3);\n\
940     _scene.lights[2] = createVector(23, 20, 17);\n\
941     _scene.lights[2].colour = createVector(0.7, 0.7, 0.7);\n\
942     _scene.ambient = createVector(0.1, 0.1, 0.1);\n\
943     //  _scene.background = createVector(0.7, 0.7, 1.0);\n\
944     \n\
945     var size = 30;\n\
946     var pixels = new Array();\n\
947     for (var y = 0; y < size; y++) {\n\
948         pixels[y] = new Array();\n\
949         for (var x = 0; x < size; x++) {\n\
950             pixels[y][x] = 0;\n\
951         }\n\
952     }\n\
953 \n\
954     var _camera = new Camera(createVector(-40, 40, 40), createVector(0, 0, 0), createVector(0, 1, 0));\n\
955     _camera.render(_scene, pixels, size, size);\n\
956 \n\
957     return pixels;\n\
958 }\n\
959 \n\
960 function arrayToCanvasCommands(pixels)\n\
961 {\n\
962     var s = '<canvas id=\"renderCanvas\" width=\"30px\" height=\"30px\"></canvas><scr' + 'ipt>\\nvar pixels = [';\n\
963     var size = 30;\n\
964     for (var y = 0; y < size; y++) {\n\
965         s += \"[\";\n\
966         for (var x = 0; x < size; x++) {\n\
967             s += \"[\" + pixels[y][x] + \"],\";\n\
968         }\n\
969         s+= \"],\";\n\
970     }\n\
971     s += '];\\n    var canvas = document.getElementById(\"renderCanvas\").getContext(\"2d\");\\n\\\n\
972 \\n\\\n\
973 \\n\\\n\
974     var size = 30;\\n\\\n\
975     canvas.fillStyle = \"red\";\\n\\\n\
976     canvas.fillRect(0, 0, size, size);\\n\\\n\
977     canvas.scale(1, -1);\\n\\\n\
978     canvas.translate(0, -size);\\n\\\n\
979 \\n\\\n\
980     if (!canvas.setFillColor)\\n\\\n\
981         canvas.setFillColor = function(r, g, b, a) {\\n\\\n\
982             this.fillStyle = \"rgb(\"+[Math.floor(r * 255), Math.floor(g * 255), Math.floor(b * 255)]+\")\";\\n\\\n\
983     }\\n\\\n\
984 \\n\\\n\
985 for (var y = 0; y < size; y++) {\\n\\\n\
986   for (var x = 0; x < size; x++) {\\n\\\n\
987     var l = pixels[y][x];\\n\\\n\
988     canvas.setFillColor(l[0], l[1], l[2], 1);\\n\\\n\
989     canvas.fillRect(x, y, 1, 1);\\n\\\n\
990   }\\n\\\n\
991 }</scr' + 'ipt>';\n\
992 \n\
993     return s;\n\
994 }\n\
995 \n\
996 testOutput = arrayToCanvasCommands(raytraceScene());\n\
997 \n\
998 \n\
999 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
1000 \n\
1001 record(_sunSpiderInterval);\n\
1002 </script>\n\
1003 \n\
1004 \n\
1005 </body>\n\
1006 </html>\n\
1007 ", "<!DOCTYPE html>\n\
1008 <head>\n\
1009 \n\
1010 <meta charset=utf8>\n\
1011 \n\
1012 <!--\n\
1013  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
1014 \n\
1015  Redistribution and use in source and binary forms, with or without\n\
1016  modification, are permitted provided that the following conditions\n\
1017  are met:\n\
1018  1. Redistributions of source code must retain the above copyright\n\
1019     notice, this list of conditions and the following disclaimer.\n\
1020  2. Redistributions in binary form must reproduce the above copyright\n\
1021     notice, this list of conditions and the following disclaimer in the\n\
1022     documentation and/or other materials provided with the distribution.\n\
1023 \n\
1024  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
1025  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
1026  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
1027  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
1028  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
1029  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
1030  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
1031  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
1032  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
1033  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
1034  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
1035 -->\n\
1036 \n\
1037 <title>SunSpider access-binary-trees</title>\n\
1038 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
1039 </head>\n\
1040 \n\
1041 <body>\n\
1042 <h3>access-binary-trees</h3>\n\
1043 <div id=\"console\">\n\
1044 </div>\n\
1045 <script>\n\
1046 function record(time) {\n\
1047     document.getElementById(\"console\").innerHTML = time + \"ms\";\n\
1048     if (window.parent) {\n\
1049         parent.recordResult(time);\n\
1050     }\n\
1051 }\n\
1052 \n\
1053 var _sunSpiderStartDate = new Date();\n\
1054 \n\
1055 /* The Great Computer Language Shootout\n\
1056    http://shootout.alioth.debian.org/\n\
1057    contributed by Isaac Gouy */\n\
1058 \n\
1059 function TreeNode(left,right,item){\n\
1060    this.left = left;\n\
1061    this.right = right;\n\
1062    this.item = item;\n\
1063 }\n\
1064 \n\
1065 TreeNode.prototype.itemCheck = function(){\n\
1066    if (this.left==null) return this.item;\n\
1067    else return this.item + this.left.itemCheck() - this.right.itemCheck();\n\
1068 }\n\
1069 \n\
1070 function bottomUpTree(item,depth){\n\
1071    if (depth>0){\n\
1072       return new TreeNode(\n\
1073           bottomUpTree(2*item-1, depth-1)\n\
1074          ,bottomUpTree(2*item, depth-1)\n\
1075          ,item\n\
1076       );\n\
1077    }\n\
1078    else {\n\
1079       return new TreeNode(null,null,item);\n\
1080    }\n\
1081 }\n\
1082 \n\
1083 var ret;\n\
1084 \n\
1085 for ( var n = 4; n <= 7; n += 1 ) {\n\
1086     var minDepth = 4;\n\
1087     var maxDepth = Math.max(minDepth + 2, n);\n\
1088     var stretchDepth = maxDepth + 1;\n\
1089     \n\
1090     var check = bottomUpTree(0,stretchDepth).itemCheck();\n\
1091     \n\
1092     var longLivedTree = bottomUpTree(0,maxDepth);\n\
1093     for (var depth=minDepth; depth<=maxDepth; depth+=2){\n\
1094         var iterations = 1 << (maxDepth - depth + minDepth);\n\
1095 \n\
1096         check = 0;\n\
1097         for (var i=1; i<=iterations; i++){\n\
1098             check += bottomUpTree(i,depth).itemCheck();\n\
1099             check += bottomUpTree(-i,depth).itemCheck();\n\
1100         }\n\
1101     }\n\
1102 \n\
1103     ret = longLivedTree.itemCheck();\n\
1104 }\n\
1105 \n\
1106 \n\
1107 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
1108 \n\
1109 record(_sunSpiderInterval);\n\
1110 </script>\n\
1111 \n\
1112 \n\
1113 </body>\n\
1114 </html>\n\
1115 ", "<!DOCTYPE html>\n\
1116 <head>\n\
1117 \n\
1118 <meta charset=utf8>\n\
1119 \n\
1120 <!--\n\
1121  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
1122 \n\
1123  Redistribution and use in source and binary forms, with or without\n\
1124  modification, are permitted provided that the following conditions\n\
1125  are met:\n\
1126  1. Redistributions of source code must retain the above copyright\n\
1127     notice, this list of conditions and the following disclaimer.\n\
1128  2. Redistributions in binary form must reproduce the above copyright\n\
1129     notice, this list of conditions and the following disclaimer in the\n\
1130     documentation and/or other materials provided with the distribution.\n\
1131 \n\
1132  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
1133  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
1134  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
1135  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
1136  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
1137  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
1138  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
1139  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
1140  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
1141  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
1142  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
1143 -->\n\
1144 \n\
1145 <title>SunSpider access-fannkuch</title>\n\
1146 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
1147 </head>\n\
1148 \n\
1149 <body>\n\
1150 <h3>access-fannkuch</h3>\n\
1151 <div id=\"console\">\n\
1152 </div>\n\
1153 <script>\n\
1154 function record(time) {\n\
1155     document.getElementById(\"console\").innerHTML = time + \"ms\";\n\
1156     if (window.parent) {\n\
1157         parent.recordResult(time);\n\
1158     }\n\
1159 }\n\
1160 \n\
1161 var _sunSpiderStartDate = new Date();\n\
1162 \n\
1163 /* The Great Computer Language Shootout\n\
1164    http://shootout.alioth.debian.org/\n\
1165    contributed by Isaac Gouy */\n\
1166 \n\
1167 function fannkuch(n) {\n\
1168    var check = 0;\n\
1169    var perm = Array(n);\n\
1170    var perm1 = Array(n);\n\
1171    var count = Array(n);\n\
1172    var maxPerm = Array(n);\n\
1173    var maxFlipsCount = 0;\n\
1174    var m = n - 1;\n\
1175 \n\
1176    for (var i = 0; i < n; i++) perm1[i] = i;\n\
1177    var r = n;\n\
1178 \n\
1179    while (true) {\n\
1180       // write-out the first 30 permutations\n\
1181       if (check < 30){\n\
1182          var s = \"\";\n\
1183          for(var i=0; i<n; i++) s += (perm1[i]+1).toString();\n\
1184          check++;\n\
1185       }\n\
1186 \n\
1187       while (r != 1) { count[r - 1] = r; r--; }\n\
1188       if (!(perm1[0] == 0 || perm1[m] == m)) {\n\
1189          for (var i = 0; i < n; i++) perm[i] = perm1[i];\n\
1190 \n\
1191          var flipsCount = 0;\n\
1192          var k;\n\
1193 \n\
1194          while (!((k = perm[0]) == 0)) {\n\
1195             var k2 = (k + 1) >> 1;\n\
1196             for (var i = 0; i < k2; i++) {\n\
1197                var temp = perm[i]; perm[i] = perm[k - i]; perm[k - i] = temp;\n\
1198             }\n\
1199             flipsCount++;\n\
1200          }\n\
1201 \n\
1202          if (flipsCount > maxFlipsCount) {\n\
1203             maxFlipsCount = flipsCount;\n\
1204             for (var i = 0; i < n; i++) maxPerm[i] = perm1[i];\n\
1205          }\n\
1206       }\n\
1207 \n\
1208       while (true) {\n\
1209          if (r == n) return maxFlipsCount;\n\
1210          var perm0 = perm1[0];\n\
1211          var i = 0;\n\
1212          while (i < r) {\n\
1213             var j = i + 1;\n\
1214             perm1[i] = perm1[j];\n\
1215             i = j;\n\
1216          }\n\
1217          perm1[r] = perm0;\n\
1218 \n\
1219          count[r] = count[r] - 1;\n\
1220          if (count[r] > 0) break;\n\
1221          r++;\n\
1222       }\n\
1223    }\n\
1224 }\n\
1225 \n\
1226 var n = 8;\n\
1227 var ret = fannkuch(n);\n\
1228 \n\
1229 \n\
1230 \n\
1231 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
1232 \n\
1233 record(_sunSpiderInterval);\n\
1234 </script>\n\
1235 \n\
1236 \n\
1237 </body>\n\
1238 </html>\n\
1239 ", "<!DOCTYPE html>\n\
1240 <head>\n\
1241 \n\
1242 <meta charset=utf8>\n\
1243 \n\
1244 <!--\n\
1245  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
1246 \n\
1247  Redistribution and use in source and binary forms, with or without\n\
1248  modification, are permitted provided that the following conditions\n\
1249  are met:\n\
1250  1. Redistributions of source code must retain the above copyright\n\
1251     notice, this list of conditions and the following disclaimer.\n\
1252  2. Redistributions in binary form must reproduce the above copyright\n\
1253     notice, this list of conditions and the following disclaimer in the\n\
1254     documentation and/or other materials provided with the distribution.\n\
1255 \n\
1256  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
1257  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
1258  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
1259  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
1260  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
1261  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
1262  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
1263  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
1264  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
1265  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
1266  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
1267 -->\n\
1268 \n\
1269 <title>SunSpider access-nbody</title>\n\
1270 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
1271 </head>\n\
1272 \n\
1273 <body>\n\
1274 <h3>access-nbody</h3>\n\
1275 <div id=\"console\">\n\
1276 </div>\n\
1277 <script>\n\
1278 function record(time) {\n\
1279     document.getElementById(\"console\").innerHTML = time + \"ms\";\n\
1280     if (window.parent) {\n\
1281         parent.recordResult(time);\n\
1282     }\n\
1283 }\n\
1284 \n\
1285 var _sunSpiderStartDate = new Date();\n\
1286 \n\
1287 /* The Great Computer Language Shootout\n\
1288    http://shootout.alioth.debian.org/\n\
1289    contributed by Isaac Gouy */\n\
1290 \n\
1291 var PI = 3.141592653589793;\n\
1292 var SOLAR_MASS = 4 * PI * PI;\n\
1293 var DAYS_PER_YEAR = 365.24;\n\
1294 \n\
1295 function Body(x,y,z,vx,vy,vz,mass){\n\
1296    this.x = x;\n\
1297    this.y = y;\n\
1298    this.z = z;\n\
1299    this.vx = vx;\n\
1300    this.vy = vy;\n\
1301    this.vz = vz;\n\
1302    this.mass = mass;\n\
1303 }\n\
1304 \n\
1305 Body.prototype.offsetMomentum = function(px,py,pz) {\n\
1306    this.vx = -px / SOLAR_MASS;\n\
1307    this.vy = -py / SOLAR_MASS;\n\
1308    this.vz = -pz / SOLAR_MASS;\n\
1309    return this;\n\
1310 }\n\
1311 \n\
1312 function Jupiter(){\n\
1313    return new Body(\n\
1314       4.84143144246472090e+00,\n\
1315       -1.16032004402742839e+00,\n\
1316       -1.03622044471123109e-01,\n\
1317       1.66007664274403694e-03 * DAYS_PER_YEAR,\n\
1318       7.69901118419740425e-03 * DAYS_PER_YEAR,\n\
1319       -6.90460016972063023e-05 * DAYS_PER_YEAR,\n\
1320       9.54791938424326609e-04 * SOLAR_MASS\n\
1321    );\n\
1322 }\n\
1323 \n\
1324 function Saturn(){\n\
1325    return new Body(\n\
1326       8.34336671824457987e+00,\n\
1327       4.12479856412430479e+00,\n\
1328       -4.03523417114321381e-01,\n\
1329       -2.76742510726862411e-03 * DAYS_PER_YEAR,\n\
1330       4.99852801234917238e-03 * DAYS_PER_YEAR,\n\
1331       2.30417297573763929e-05 * DAYS_PER_YEAR,\n\
1332       2.85885980666130812e-04 * SOLAR_MASS\n\
1333    );\n\
1334 }\n\
1335 \n\
1336 function Uranus(){\n\
1337    return new Body(\n\
1338       1.28943695621391310e+01,\n\
1339       -1.51111514016986312e+01,\n\
1340       -2.23307578892655734e-01,\n\
1341       2.96460137564761618e-03 * DAYS_PER_YEAR,\n\
1342       2.37847173959480950e-03 * DAYS_PER_YEAR,\n\
1343       -2.96589568540237556e-05 * DAYS_PER_YEAR,\n\
1344       4.36624404335156298e-05 * SOLAR_MASS\n\
1345    );\n\
1346 }\n\
1347 \n\
1348 function Neptune(){\n\
1349    return new Body(\n\
1350       1.53796971148509165e+01,\n\
1351       -2.59193146099879641e+01,\n\
1352       1.79258772950371181e-01,\n\
1353       2.68067772490389322e-03 * DAYS_PER_YEAR,\n\
1354       1.62824170038242295e-03 * DAYS_PER_YEAR,\n\
1355       -9.51592254519715870e-05 * DAYS_PER_YEAR,\n\
1356       5.15138902046611451e-05 * SOLAR_MASS\n\
1357    );\n\
1358 }\n\
1359 \n\
1360 function Sun(){\n\
1361    return new Body(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, SOLAR_MASS);\n\
1362 }\n\
1363 \n\
1364 \n\
1365 function NBodySystem(bodies){\n\
1366    this.bodies = bodies;\n\
1367    var px = 0.0;\n\
1368    var py = 0.0;\n\
1369    var pz = 0.0;\n\
1370    var size = this.bodies.length;\n\
1371    for (var i=0; i<size; i++){\n\
1372       var b = this.bodies[i];\n\
1373       var m = b.mass;\n\
1374       px += b.vx * m;\n\
1375       py += b.vy * m;\n\
1376       pz += b.vz * m;\n\
1377    }\n\
1378    this.bodies[0].offsetMomentum(px,py,pz);\n\
1379 }\n\
1380 \n\
1381 NBodySystem.prototype.advance = function(dt){\n\
1382    var dx, dy, dz, distance, mag;\n\
1383    var size = this.bodies.length;\n\
1384 \n\
1385    for (var i=0; i<size; i++) {\n\
1386       var bodyi = this.bodies[i];\n\
1387       for (var j=i+1; j<size; j++) {\n\
1388          var bodyj = this.bodies[j];\n\
1389          dx = bodyi.x - bodyj.x;\n\
1390          dy = bodyi.y - bodyj.y;\n\
1391          dz = bodyi.z - bodyj.z;\n\
1392 \n\
1393          distance = Math.sqrt(dx*dx + dy*dy + dz*dz);\n\
1394          mag = dt / (distance * distance * distance);\n\
1395 \n\
1396          bodyi.vx -= dx * bodyj.mass * mag;\n\
1397          bodyi.vy -= dy * bodyj.mass * mag;\n\
1398          bodyi.vz -= dz * bodyj.mass * mag;\n\
1399 \n\
1400          bodyj.vx += dx * bodyi.mass * mag;\n\
1401          bodyj.vy += dy * bodyi.mass * mag;\n\
1402          bodyj.vz += dz * bodyi.mass * mag;\n\
1403       }\n\
1404    }\n\
1405 \n\
1406    for (var i=0; i<size; i++) {\n\
1407       var body = this.bodies[i];\n\
1408       body.x += dt * body.vx;\n\
1409       body.y += dt * body.vy;\n\
1410       body.z += dt * body.vz;\n\
1411    }\n\
1412 }\n\
1413 \n\
1414 NBodySystem.prototype.energy = function(){\n\
1415    var dx, dy, dz, distance;\n\
1416    var e = 0.0;\n\
1417    var size = this.bodies.length;\n\
1418 \n\
1419    for (var i=0; i<size; i++) {\n\
1420       var bodyi = this.bodies[i];\n\
1421 \n\
1422       e += 0.5 * bodyi.mass *\n\
1423          ( bodyi.vx * bodyi.vx\n\
1424          + bodyi.vy * bodyi.vy\n\
1425          + bodyi.vz * bodyi.vz );\n\
1426 \n\
1427       for (var j=i+1; j<size; j++) {\n\
1428          var bodyj = this.bodies[j];\n\
1429          dx = bodyi.x - bodyj.x;\n\
1430          dy = bodyi.y - bodyj.y;\n\
1431          dz = bodyi.z - bodyj.z;\n\
1432 \n\
1433          distance = Math.sqrt(dx*dx + dy*dy + dz*dz);\n\
1434          e -= (bodyi.mass * bodyj.mass) / distance;\n\
1435       }\n\
1436    }\n\
1437    return e;\n\
1438 }\n\
1439 \n\
1440 var ret;\n\
1441 \n\
1442 for ( var n = 3; n <= 24; n *= 2 ) {\n\
1443     (function(){\n\
1444         var bodies = new NBodySystem( Array(\n\
1445            Sun(),Jupiter(),Saturn(),Uranus(),Neptune()\n\
1446         ));\n\
1447         var max = n * 100;\n\
1448         \n\
1449         ret = bodies.energy();\n\
1450         for (var i=0; i<max; i++){\n\
1451             bodies.advance(0.01);\n\
1452         }\n\
1453         ret = bodies.energy();\n\
1454     })();\n\
1455 }\n\
1456 \n\
1457 \n\
1458 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
1459 \n\
1460 record(_sunSpiderInterval);\n\
1461 </script>\n\
1462 \n\
1463 \n\
1464 </body>\n\
1465 </html>\n\
1466 ", "<!DOCTYPE html>\n\
1467 <head>\n\
1468 \n\
1469 <meta charset=utf8>\n\
1470 \n\
1471 <!--\n\
1472  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
1473 \n\
1474  Redistribution and use in source and binary forms, with or without\n\
1475  modification, are permitted provided that the following conditions\n\
1476  are met:\n\
1477  1. Redistributions of source code must retain the above copyright\n\
1478     notice, this list of conditions and the following disclaimer.\n\
1479  2. Redistributions in binary form must reproduce the above copyright\n\
1480     notice, this list of conditions and the following disclaimer in the\n\
1481     documentation and/or other materials provided with the distribution.\n\
1482 \n\
1483  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
1484  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
1485  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
1486  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
1487  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
1488  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
1489  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
1490  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
1491  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
1492  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
1493  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
1494 -->\n\
1495 \n\
1496 <title>SunSpider access-nsieve</title>\n\
1497 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
1498 </head>\n\
1499 \n\
1500 <body>\n\
1501 <h3>access-nsieve</h3>\n\
1502 <div id=\"console\">\n\
1503 </div>\n\
1504 <script>\n\
1505 function record(time) {\n\
1506     document.getElementById(\"console\").innerHTML = time + \"ms\";\n\
1507     if (window.parent) {\n\
1508         parent.recordResult(time);\n\
1509     }\n\
1510 }\n\
1511 \n\
1512 var _sunSpiderStartDate = new Date();\n\
1513 \n\
1514 // The Great Computer Language Shootout\n\
1515 // http://shootout.alioth.debian.org/\n\
1516 //\n\
1517 // modified by Isaac Gouy\n\
1518 \n\
1519 function pad(number,width){\n\
1520    var s = number.toString();\n\
1521    var prefixWidth = width - s.length;\n\
1522    if (prefixWidth>0){\n\
1523       for (var i=1; i<=prefixWidth; i++) s = \" \" + s;\n\
1524    }\n\
1525    return s;\n\
1526 }\n\
1527 \n\
1528 function nsieve(m, isPrime){\n\
1529    var i, k, count;\n\
1530 \n\
1531    for (i=2; i<=m; i++) { isPrime[i] = true; }\n\
1532    count = 0;\n\
1533 \n\
1534    for (i=2; i<=m; i++){\n\
1535       if (isPrime[i]) {\n\
1536          for (k=i+i; k<=m; k+=i) isPrime[k] = false;\n\
1537          count++;\n\
1538       }\n\
1539    }\n\
1540    return count;\n\
1541 }\n\
1542 \n\
1543 function sieve() {\n\
1544     for (var i = 1; i <= 3; i++ ) {\n\
1545         var m = (1<<i)*10000;\n\
1546         var flags = Array(m+1);\n\
1547         nsieve(m, flags);\n\
1548     }\n\
1549 }\n\
1550 \n\
1551 sieve();\n\
1552 \n\
1553 \n\
1554 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
1555 \n\
1556 record(_sunSpiderInterval);\n\
1557 </script>\n\
1558 \n\
1559 \n\
1560 </body>\n\
1561 </html>\n\
1562 ", "<!DOCTYPE html>\n\
1563 <head>\n\
1564 \n\
1565 <meta charset=utf8>\n\
1566 \n\
1567 <!--\n\
1568  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
1569 \n\
1570  Redistribution and use in source and binary forms, with or without\n\
1571  modification, are permitted provided that the following conditions\n\
1572  are met:\n\
1573  1. Redistributions of source code must retain the above copyright\n\
1574     notice, this list of conditions and the following disclaimer.\n\
1575  2. Redistributions in binary form must reproduce the above copyright\n\
1576     notice, this list of conditions and the following disclaimer in the\n\
1577     documentation and/or other materials provided with the distribution.\n\
1578 \n\
1579  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
1580  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
1581  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
1582  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
1583  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
1584  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
1585  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
1586  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
1587  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
1588  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
1589  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
1590 -->\n\
1591 \n\
1592 <title>SunSpider bitops-3bit-bits-in-byte</title>\n\
1593 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
1594 </head>\n\
1595 \n\
1596 <body>\n\
1597 <h3>bitops-3bit-bits-in-byte</h3>\n\
1598 <div id=\"console\">\n\
1599 </div>\n\
1600 <script>\n\
1601 function record(time) {\n\
1602     document.getElementById(\"console\").innerHTML = time + \"ms\";\n\
1603     if (window.parent) {\n\
1604         parent.recordResult(time);\n\
1605     }\n\
1606 }\n\
1607 \n\
1608 var _sunSpiderStartDate = new Date();\n\
1609 \n\
1610 // Copyright (c) 2004 by Arthur Langereis (arthur_ext at domain xfinitegames, tld com\n\
1611 \n\
1612 // 1 op = 6 ANDs, 3 SHRs, 3 SHLs, 4 assigns, 2 ADDs\n\
1613 // O(1)\n\
1614 function fast3bitlookup(b) {\n\
1615 var c, bi3b = 0xE994; // 0b1110 1001 1001 0100; // 3 2 2 1  2 1 1 0\n\
1616 c  = 3 & (bi3b >> ((b << 1) & 14));\n\
1617 c += 3 & (bi3b >> ((b >> 2) & 14));\n\
1618 c += 3 & (bi3b >> ((b >> 5) & 6));\n\
1619 return c;\n\
1620 \n\
1621 /*\n\
1622 lir4,0xE994; 9 instructions, no memory access, minimal register dependence, 6 shifts, 2 adds, 1 inline assign\n\
1623 rlwinmr5,r3,1,28,30\n\
1624 rlwinmr6,r3,30,28,30\n\
1625 rlwinmr7,r3,27,29,30\n\
1626 rlwnmr8,r4,r5,30,31\n\
1627 rlwnmr9,r4,r6,30,31\n\
1628 rlwnmr10,r4,r7,30,31\n\
1629 addr3,r8,r9\n\
1630 addr3,r3,r10\n\
1631 */\n\
1632 }\n\
1633 \n\
1634 \n\
1635 function TimeFunc(func) {\n\
1636 var x, y, t;\n\
1637 for(var x=0; x<500; x++)\n\
1638 for(var y=0; y<256; y++) func(y);\n\
1639 }\n\
1640 \n\
1641 TimeFunc(fast3bitlookup);\n\
1642 \n\
1643 \n\
1644 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
1645 \n\
1646 record(_sunSpiderInterval);\n\
1647 </script>\n\
1648 \n\
1649 \n\
1650 </body>\n\
1651 </html>\n\
1652 ", "<!DOCTYPE html>\n\
1653 <head>\n\
1654 \n\
1655 <meta charset=utf8>\n\
1656 \n\
1657 <!--\n\
1658  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
1659 \n\
1660  Redistribution and use in source and binary forms, with or without\n\
1661  modification, are permitted provided that the following conditions\n\
1662  are met:\n\
1663  1. Redistributions of source code must retain the above copyright\n\
1664     notice, this list of conditions and the following disclaimer.\n\
1665  2. Redistributions in binary form must reproduce the above copyright\n\
1666     notice, this list of conditions and the following disclaimer in the\n\
1667     documentation and/or other materials provided with the distribution.\n\
1668 \n\
1669  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
1670  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
1671  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
1672  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
1673  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
1674  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
1675  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
1676  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
1677  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
1678  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
1679  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
1680 -->\n\
1681 \n\
1682 <title>SunSpider bitops-bits-in-byte</title>\n\
1683 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
1684 </head>\n\
1685 \n\
1686 <body>\n\
1687 <h3>bitops-bits-in-byte</h3>\n\
1688 <div id=\"console\">\n\
1689 </div>\n\
1690 <script>\n\
1691 function record(time) {\n\
1692     document.getElementById(\"console\").innerHTML = time + \"ms\";\n\
1693     if (window.parent) {\n\
1694         parent.recordResult(time);\n\
1695     }\n\
1696 }\n\
1697 \n\
1698 var _sunSpiderStartDate = new Date();\n\
1699 \n\
1700 // Copyright (c) 2004 by Arthur Langereis (arthur_ext at domain xfinitegames, tld com)\n\
1701 \n\
1702 \n\
1703 // 1 op = 2 assigns, 16 compare/branches, 8 ANDs, (0-8) ADDs, 8 SHLs\n\
1704 // O(n)\n\
1705 function bitsinbyte(b) {\n\
1706 var m = 1, c = 0;\n\
1707 while(m<0x100) {\n\
1708 if(b & m) c++;\n\
1709 m <<= 1;\n\
1710 }\n\
1711 return c;\n\
1712 }\n\
1713 \n\
1714 function TimeFunc(func) {\n\
1715 var x, y, t;\n\
1716 for(var x=0; x<350; x++)\n\
1717 for(var y=0; y<256; y++) func(y);\n\
1718 }\n\
1719 \n\
1720 TimeFunc(bitsinbyte);\n\
1721 \n\
1722 \n\
1723 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
1724 \n\
1725 record(_sunSpiderInterval);\n\
1726 </script>\n\
1727 \n\
1728 \n\
1729 </body>\n\
1730 </html>\n\
1731 ", "<!DOCTYPE html>\n\
1732 <head>\n\
1733 \n\
1734 <meta charset=utf8>\n\
1735 \n\
1736 <!--\n\
1737  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
1738 \n\
1739  Redistribution and use in source and binary forms, with or without\n\
1740  modification, are permitted provided that the following conditions\n\
1741  are met:\n\
1742  1. Redistributions of source code must retain the above copyright\n\
1743     notice, this list of conditions and the following disclaimer.\n\
1744  2. Redistributions in binary form must reproduce the above copyright\n\
1745     notice, this list of conditions and the following disclaimer in the\n\
1746     documentation and/or other materials provided with the distribution.\n\
1747 \n\
1748  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
1749  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
1750  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
1751  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
1752  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
1753  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
1754  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
1755  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
1756  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
1757  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
1758  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
1759 -->\n\
1760 \n\
1761 <title>SunSpider bitops-bitwise-and</title>\n\
1762 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
1763 </head>\n\
1764 \n\
1765 <body>\n\
1766 <h3>bitops-bitwise-and</h3>\n\
1767 <div id=\"console\">\n\
1768 </div>\n\
1769 <script>\n\
1770 function record(time) {\n\
1771     document.getElementById(\"console\").innerHTML = time + \"ms\";\n\
1772     if (window.parent) {\n\
1773         parent.recordResult(time);\n\
1774     }\n\
1775 }\n\
1776 \n\
1777 var _sunSpiderStartDate = new Date();\n\
1778 \n\
1779 /*\n\
1780  * Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
1781  *\n\
1782  * Redistribution and use in source and binary forms, with or without\n\
1783  * modification, are permitted provided that the following conditions\n\
1784  * are met:\n\
1785  * 1. Redistributions of source code must retain the above copyright\n\
1786  *    notice, this list of conditions and the following disclaimer.\n\
1787  * 2. Redistributions in binary form must reproduce the above copyright\n\
1788  *    notice, this list of conditions and the following disclaimer in the\n\
1789  *    documentation and/or other materials provided with the distribution.\n\
1790  *\n\
1791  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
1792  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
1793  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
1794  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
1795  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
1796  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
1797  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
1798  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
1799  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
1800  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
1801  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
1802  */\n\
1803 \n\
1804 bitwiseAndValue = 4294967296;\n\
1805 for (var i = 0; i < 600000; i++)\n\
1806     bitwiseAndValue = bitwiseAndValue & i;\n\
1807 \n\
1808 \n\
1809 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
1810 \n\
1811 record(_sunSpiderInterval);\n\
1812 </script>\n\
1813 \n\
1814 \n\
1815 </body>\n\
1816 </html>\n\
1817 ", "<!DOCTYPE html>\n\
1818 <head>\n\
1819 \n\
1820 <meta charset=utf8>\n\
1821 \n\
1822 <!--\n\
1823  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
1824 \n\
1825  Redistribution and use in source and binary forms, with or without\n\
1826  modification, are permitted provided that the following conditions\n\
1827  are met:\n\
1828  1. Redistributions of source code must retain the above copyright\n\
1829     notice, this list of conditions and the following disclaimer.\n\
1830  2. Redistributions in binary form must reproduce the above copyright\n\
1831     notice, this list of conditions and the following disclaimer in the\n\
1832     documentation and/or other materials provided with the distribution.\n\
1833 \n\
1834  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
1835  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
1836  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
1837  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
1838  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
1839  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
1840  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
1841  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
1842  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
1843  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
1844  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
1845 -->\n\
1846 \n\
1847 <title>SunSpider bitops-nsieve-bits</title>\n\
1848 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
1849 </head>\n\
1850 \n\
1851 <body>\n\
1852 <h3>bitops-nsieve-bits</h3>\n\
1853 <div id=\"console\">\n\
1854 </div>\n\
1855 <script>\n\
1856 function record(time) {\n\
1857     document.getElementById(\"console\").innerHTML = time + \"ms\";\n\
1858     if (window.parent) {\n\
1859         parent.recordResult(time);\n\
1860     }\n\
1861 }\n\
1862 \n\
1863 var _sunSpiderStartDate = new Date();\n\
1864 \n\
1865 // The Great Computer Language Shootout\n\
1866 //  http://shootout.alioth.debian.org\n\
1867 //\n\
1868 //  Contributed by Ian Osgood\n\
1869 \n\
1870 function pad(n,width) {\n\
1871   var s = n.toString();\n\
1872   while (s.length < width) s = ' ' + s;\n\
1873   return s;\n\
1874 }\n\
1875 \n\
1876 function primes(isPrime, n) {\n\
1877   var i, count = 0, m = 10000<<n, size = m+31>>5;\n\
1878 \n\
1879   for (i=0; i<size; i++) isPrime[i] = 0xffffffff;\n\
1880 \n\
1881   for (i=2; i<m; i++)\n\
1882     if (isPrime[i>>5] & 1<<(i&31)) {\n\
1883       for (var j=i+i; j<m; j+=i)\n\
1884         isPrime[j>>5] &= ~(1<<(j&31));\n\
1885       count++;\n\
1886     }\n\
1887 }\n\
1888 \n\
1889 function sieve() {\n\
1890     for (var i = 4; i <= 4; i++) {\n\
1891         var isPrime = new Array((10000<<i)+31>>5);\n\
1892         primes(isPrime, i);\n\
1893     }\n\
1894 }\n\
1895 \n\
1896 sieve();\n\
1897 \n\
1898 \n\
1899 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
1900 \n\
1901 record(_sunSpiderInterval);\n\
1902 </script>\n\
1903 \n\
1904 \n\
1905 </body>\n\
1906 </html>\n\
1907 ", "<!DOCTYPE html>\n\
1908 <head>\n\
1909 \n\
1910 <meta charset=utf8>\n\
1911 \n\
1912 <!--\n\
1913  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
1914 \n\
1915  Redistribution and use in source and binary forms, with or without\n\
1916  modification, are permitted provided that the following conditions\n\
1917  are met:\n\
1918  1. Redistributions of source code must retain the above copyright\n\
1919     notice, this list of conditions and the following disclaimer.\n\
1920  2. Redistributions in binary form must reproduce the above copyright\n\
1921     notice, this list of conditions and the following disclaimer in the\n\
1922     documentation and/or other materials provided with the distribution.\n\
1923 \n\
1924  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
1925  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
1926  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
1927  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
1928  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
1929  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
1930  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
1931  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
1932  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
1933  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
1934  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
1935 -->\n\
1936 \n\
1937 <title>SunSpider controlflow-recursive</title>\n\
1938 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
1939 </head>\n\
1940 \n\
1941 <body>\n\
1942 <h3>controlflow-recursive</h3>\n\
1943 <div id=\"console\">\n\
1944 </div>\n\
1945 <script>\n\
1946 function record(time) {\n\
1947     document.getElementById(\"console\").innerHTML = time + \"ms\";\n\
1948     if (window.parent) {\n\
1949         parent.recordResult(time);\n\
1950     }\n\
1951 }\n\
1952 \n\
1953 var _sunSpiderStartDate = new Date();\n\
1954 \n\
1955 // The Computer Language Shootout\n\
1956 // http://shootout.alioth.debian.org/\n\
1957 // contributed by Isaac Gouy\n\
1958 \n\
1959 function ack(m,n){\n\
1960    if (m==0) { return n+1; }\n\
1961    if (n==0) { return ack(m-1,1); }\n\
1962    return ack(m-1, ack(m,n-1) );\n\
1963 }\n\
1964 \n\
1965 function fib(n) {\n\
1966     if (n < 2){ return 1; }\n\
1967     return fib(n-2) + fib(n-1);\n\
1968 }\n\
1969 \n\
1970 function tak(x,y,z) {\n\
1971     if (y >= x) return z;\n\
1972     return tak(tak(x-1,y,z), tak(y-1,z,x), tak(z-1,x,y));\n\
1973 }\n\
1974 \n\
1975 for ( var i = 3; i <= 5; i++ ) {\n\
1976     ack(3,i);\n\
1977     fib(17.0+i);\n\
1978     tak(3*i+3,2*i+2,i+1);\n\
1979 }\n\
1980 \n\
1981 \n\
1982 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
1983 \n\
1984 record(_sunSpiderInterval);\n\
1985 </script>\n\
1986 \n\
1987 \n\
1988 </body>\n\
1989 </html>\n\
1990 ", "<!DOCTYPE html>\n\
1991 <head>\n\
1992 \n\
1993 <meta charset=utf8>\n\
1994 \n\
1995 <!--\n\
1996  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
1997 \n\
1998  Redistribution and use in source and binary forms, with or without\n\
1999  modification, are permitted provided that the following conditions\n\
2000  are met:\n\
2001  1. Redistributions of source code must retain the above copyright\n\
2002     notice, this list of conditions and the following disclaimer.\n\
2003  2. Redistributions in binary form must reproduce the above copyright\n\
2004     notice, this list of conditions and the following disclaimer in the\n\
2005     documentation and/or other materials provided with the distribution.\n\
2006 \n\
2007  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
2008  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
2009  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
2010  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
2011  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
2012  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
2013  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
2014  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
2015  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
2016  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
2017  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
2018 -->\n\
2019 \n\
2020 <title>SunSpider crypto-aes</title>\n\
2021 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
2022 </head>\n\
2023 \n\
2024 <body>\n\
2025 <h3>crypto-aes</h3>\n\
2026 <div id=\"console\">\n\
2027 </div>\n\
2028 <script>\n\
2029 function record(time) {\n\
2030     document.getElementById(\"console\").innerHTML = time + \"ms\";\n\
2031     if (window.parent) {\n\
2032         parent.recordResult(time);\n\
2033     }\n\
2034 }\n\
2035 \n\
2036 var _sunSpiderStartDate = new Date();\n\
2037 \n\
2038 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */\n\
2039 \n\
2040 /*\n\
2041  * AES Cipher function: encrypt 'input' with Rijndael algorithm\n\
2042  *\n\
2043  *   takes   byte-array 'input' (16 bytes)\n\
2044  *           2D byte-array key schedule 'w' (Nr+1 x Nb bytes)\n\
2045  *\n\
2046  *   applies Nr rounds (10/12/14) using key schedule w for 'add round key' stage\n\
2047  *\n\
2048  *   returns byte-array encrypted value (16 bytes)\n\
2049  */\n\
2050 function Cipher(input, w) {    // main Cipher function [§5.1]\n\
2051   var Nb = 4;               // block size (in words): no of columns in state (fixed at 4 for AES)\n\
2052   var Nr = w.length/Nb - 1; // no of rounds: 10/12/14 for 128/192/256-bit keys\n\
2053 \n\
2054   var state = [[],[],[],[]];  // initialise 4xNb byte-array 'state' with input [§3.4]\n\
2055   for (var i=0; i<4*Nb; i++) state[i%4][Math.floor(i/4)] = input[i];\n\
2056 \n\
2057   state = AddRoundKey(state, w, 0, Nb);\n\
2058 \n\
2059   for (var round=1; round<Nr; round++) {\n\
2060     state = SubBytes(state, Nb);\n\
2061     state = ShiftRows(state, Nb);\n\
2062     state = MixColumns(state, Nb);\n\
2063     state = AddRoundKey(state, w, round, Nb);\n\
2064   }\n\
2065 \n\
2066   state = SubBytes(state, Nb);\n\
2067   state = ShiftRows(state, Nb);\n\
2068   state = AddRoundKey(state, w, Nr, Nb);\n\
2069 \n\
2070   var output = new Array(4*Nb);  // convert state to 1-d array before returning [§3.4]\n\
2071   for (var i=0; i<4*Nb; i++) output[i] = state[i%4][Math.floor(i/4)];\n\
2072   return output;\n\
2073 }\n\
2074 \n\
2075 \n\
2076 function SubBytes(s, Nb) {    // apply SBox to state S [§5.1.1]\n\
2077   for (var r=0; r<4; r++) {\n\
2078     for (var c=0; c<Nb; c++) s[r][c] = Sbox[s[r][c]];\n\
2079   }\n\
2080   return s;\n\
2081 }\n\
2082 \n\
2083 \n\
2084 function ShiftRows(s, Nb) {    // shift row r of state S left by r bytes [§5.1.2]\n\
2085   var t = new Array(4);\n\
2086   for (var r=1; r<4; r++) {\n\
2087     for (var c=0; c<4; c++) t[c] = s[r][(c+r)%Nb];  // shift into temp copy\n\
2088     for (var c=0; c<4; c++) s[r][c] = t[c];         // and copy back\n\
2089   }          // note that this will work for Nb=4,5,6, but not 7,8 (always 4 for AES):\n\
2090   return s;  // see fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.311.pdf \n\
2091 }\n\
2092 \n\
2093 \n\
2094 function MixColumns(s, Nb) {   // combine bytes of each col of state S [§5.1.3]\n\
2095   for (var c=0; c<4; c++) {\n\
2096     var a = new Array(4);  // 'a' is a copy of the current column from 's'\n\
2097     var b = new Array(4);  // 'b' is a•{02} in GF(2^8)\n\
2098     for (var i=0; i<4; i++) {\n\
2099       a[i] = s[i][c];\n\
2100       b[i] = s[i][c]&0x80 ? s[i][c]<<1 ^ 0x011b : s[i][c]<<1;\n\
2101     }\n\
2102     // a[n] ^ b[n] is a•{03} in GF(2^8)\n\
2103     s[0][c] = b[0] ^ a[1] ^ b[1] ^ a[2] ^ a[3]; // 2*a0 + 3*a1 + a2 + a3\n\
2104     s[1][c] = a[0] ^ b[1] ^ a[2] ^ b[2] ^ a[3]; // a0 * 2*a1 + 3*a2 + a3\n\
2105     s[2][c] = a[0] ^ a[1] ^ b[2] ^ a[3] ^ b[3]; // a0 + a1 + 2*a2 + 3*a3\n\
2106     s[3][c] = a[0] ^ b[0] ^ a[1] ^ a[2] ^ b[3]; // 3*a0 + a1 + a2 + 2*a3\n\
2107   }\n\
2108   return s;\n\
2109 }\n\
2110 \n\
2111 \n\
2112 function AddRoundKey(state, w, rnd, Nb) {  // xor Round Key into state S [§5.1.4]\n\
2113   for (var r=0; r<4; r++) {\n\
2114     for (var c=0; c<Nb; c++) state[r][c] ^= w[rnd*4+c][r];\n\
2115   }\n\
2116   return state;\n\
2117 }\n\
2118 \n\
2119 \n\
2120 function KeyExpansion(key) {  // generate Key Schedule (byte-array Nr+1 x Nb) from Key [§5.2]\n\
2121   var Nb = 4;            // block size (in words): no of columns in state (fixed at 4 for AES)\n\
2122   var Nk = key.length/4  // key length (in words): 4/6/8 for 128/192/256-bit keys\n\
2123   var Nr = Nk + 6;       // no of rounds: 10/12/14 for 128/192/256-bit keys\n\
2124 \n\
2125   var w = new Array(Nb*(Nr+1));\n\
2126   var temp = new Array(4);\n\
2127 \n\
2128   for (var i=0; i<Nk; i++) {\n\
2129     var r = [key[4*i], key[4*i+1], key[4*i+2], key[4*i+3]];\n\
2130     w[i] = r;\n\
2131   }\n\
2132 \n\
2133   for (var i=Nk; i<(Nb*(Nr+1)); i++) {\n\
2134     w[i] = new Array(4);\n\
2135     for (var t=0; t<4; t++) temp[t] = w[i-1][t];\n\
2136     if (i % Nk == 0) {\n\
2137       temp = SubWord(RotWord(temp));\n\
2138       for (var t=0; t<4; t++) temp[t] ^= Rcon[i/Nk][t];\n\
2139     } else if (Nk > 6 && i%Nk == 4) {\n\
2140       temp = SubWord(temp);\n\
2141     }\n\
2142     for (var t=0; t<4; t++) w[i][t] = w[i-Nk][t] ^ temp[t];\n\
2143   }\n\
2144 \n\
2145   return w;\n\
2146 }\n\
2147 \n\
2148 function SubWord(w) {    // apply SBox to 4-byte word w\n\
2149   for (var i=0; i<4; i++) w[i] = Sbox[w[i]];\n\
2150   return w;\n\
2151 }\n\
2152 \n\
2153 function RotWord(w) {    // rotate 4-byte word w left by one byte\n\
2154   w[4] = w[0];\n\
2155   for (var i=0; i<4; i++) w[i] = w[i+1];\n\
2156   return w;\n\
2157 }\n\
2158 \n\
2159 \n\
2160 // Sbox is pre-computed multiplicative inverse in GF(2^8) used in SubBytes and KeyExpansion [§5.1.1]\n\
2161 var Sbox =  [0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,\n\
2162              0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,\n\
2163              0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,\n\
2164              0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,\n\
2165              0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,\n\
2166              0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,\n\
2167              0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,\n\
2168              0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,\n\
2169              0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,\n\
2170              0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,\n\
2171              0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,\n\
2172              0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,\n\
2173              0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,\n\
2174              0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,\n\
2175              0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,\n\
2176              0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16];\n\
2177 \n\
2178 // Rcon is Round Constant used for the Key Expansion [1st col is 2^(r-1) in GF(2^8)] [§5.2]\n\
2179 var Rcon = [ [0x00, 0x00, 0x00, 0x00],\n\
2180              [0x01, 0x00, 0x00, 0x00],\n\
2181              [0x02, 0x00, 0x00, 0x00],\n\
2182              [0x04, 0x00, 0x00, 0x00],\n\
2183              [0x08, 0x00, 0x00, 0x00],\n\
2184              [0x10, 0x00, 0x00, 0x00],\n\
2185              [0x20, 0x00, 0x00, 0x00],\n\
2186              [0x40, 0x00, 0x00, 0x00],\n\
2187              [0x80, 0x00, 0x00, 0x00],\n\
2188              [0x1b, 0x00, 0x00, 0x00],\n\
2189              [0x36, 0x00, 0x00, 0x00] ]; \n\
2190 \n\
2191 \n\
2192 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */\n\
2193 \n\
2194 /* \n\
2195  * Use AES to encrypt 'plaintext' with 'password' using 'nBits' key, in 'Counter' mode of operation\n\
2196  *                           - see http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf\n\
2197  *   for each block\n\
2198  *   - outputblock = cipher(counter, key)\n\
2199  *   - cipherblock = plaintext xor outputblock\n\
2200  */\n\
2201 function AESEncryptCtr(plaintext, password, nBits) {\n\
2202   if (!(nBits==128 || nBits==192 || nBits==256)) return '';  // standard allows 128/192/256 bit keys\n\
2203 \n\
2204   // for this example script, generate the key by applying Cipher to 1st 16/24/32 chars of password; \n\
2205   // for real-world applications, a more secure approach would be to hash the password e.g. with SHA-1\n\
2206   var nBytes = nBits/8;  // no bytes in key\n\
2207   var pwBytes = new Array(nBytes);\n\
2208   for (var i=0; i<nBytes; i++) pwBytes[i] = password.charCodeAt(i) & 0xff;\n\
2209   var key = Cipher(pwBytes, KeyExpansion(pwBytes));\n\
2210   key = key.concat(key.slice(0, nBytes-16));  // key is now 16/24/32 bytes long\n\
2211 \n\
2212   // initialise counter block (NIST SP800-38A §B.2): millisecond time-stamp for nonce in 1st 8 bytes,\n\
2213   // block counter in 2nd 8 bytes\n\
2214   var blockSize = 16;  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES\n\
2215   var counterBlock = new Array(blockSize);  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES\n\
2216   var nonce = (new Date()).getTime();  // milliseconds since 1-Jan-1970\n\
2217 \n\
2218   // encode nonce in two stages to cater for JavaScript 32-bit limit on bitwise ops\n\
2219   for (var i=0; i<4; i++) counterBlock[i] = (nonce >>> i*8) & 0xff;\n\
2220   for (var i=0; i<4; i++) counterBlock[i+4] = (nonce/0x100000000 >>> i*8) & 0xff; \n\
2221 \n\
2222   // generate key schedule - an expansion of the key into distinct Key Rounds for each round\n\
2223   var keySchedule = KeyExpansion(key);\n\
2224 \n\
2225   var blockCount = Math.ceil(plaintext.length/blockSize);\n\
2226   var ciphertext = new Array(blockCount);  // ciphertext as array of strings\n\
2227   \n\
2228   for (var b=0; b<blockCount; b++) {\n\
2229     // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)\n\
2230     // again done in two stages for 32-bit ops\n\
2231     for (var c=0; c<4; c++) counterBlock[15-c] = (b >>> c*8) & 0xff;\n\
2232     for (var c=0; c<4; c++) counterBlock[15-c-4] = (b/0x100000000 >>> c*8)\n\
2233 \n\
2234     var cipherCntr = Cipher(counterBlock, keySchedule);  // -- encrypt counter block --\n\
2235     \n\
2236     // calculate length of final block:\n\
2237     var blockLength = b<blockCount-1 ? blockSize : (plaintext.length-1)%blockSize+1;\n\
2238 \n\
2239     var ct = '';\n\
2240     for (var i=0; i<blockLength; i++) {  // -- xor plaintext with ciphered counter byte-by-byte --\n\
2241       var plaintextByte = plaintext.charCodeAt(b*blockSize+i);\n\
2242       var cipherByte = plaintextByte ^ cipherCntr[i];\n\
2243       ct += String.fromCharCode(cipherByte);\n\
2244     }\n\
2245     // ct is now ciphertext for this block\n\
2246 \n\
2247     ciphertext[b] = escCtrlChars(ct);  // escape troublesome characters in ciphertext\n\
2248   }\n\
2249 \n\
2250   // convert the nonce to a string to go on the front of the ciphertext\n\
2251   var ctrTxt = '';\n\
2252   for (var i=0; i<8; i++) ctrTxt += String.fromCharCode(counterBlock[i]);\n\
2253   ctrTxt = escCtrlChars(ctrTxt);\n\
2254 \n\
2255   // use '-' to separate blocks, use Array.join to concatenate arrays of strings for efficiency\n\
2256   return ctrTxt + '-' + ciphertext.join('-');\n\
2257 }\n\
2258 \n\
2259 \n\
2260 /* \n\
2261  * Use AES to decrypt 'ciphertext' with 'password' using 'nBits' key, in Counter mode of operation\n\
2262  *\n\
2263  *   for each block\n\
2264  *   - outputblock = cipher(counter, key)\n\
2265  *   - cipherblock = plaintext xor outputblock\n\
2266  */\n\
2267 function AESDecryptCtr(ciphertext, password, nBits) {\n\
2268   if (!(nBits==128 || nBits==192 || nBits==256)) return '';  // standard allows 128/192/256 bit keys\n\
2269 \n\
2270   var nBytes = nBits/8;  // no bytes in key\n\
2271   var pwBytes = new Array(nBytes);\n\
2272   for (var i=0; i<nBytes; i++) pwBytes[i] = password.charCodeAt(i) & 0xff;\n\
2273   var pwKeySchedule = KeyExpansion(pwBytes);\n\
2274   var key = Cipher(pwBytes, pwKeySchedule);\n\
2275   key = key.concat(key.slice(0, nBytes-16));  // key is now 16/24/32 bytes long\n\
2276 \n\
2277   var keySchedule = KeyExpansion(key);\n\
2278 \n\
2279   ciphertext = ciphertext.split('-');  // split ciphertext into array of block-length strings \n\
2280 \n\
2281   // recover nonce from 1st element of ciphertext\n\
2282   var blockSize = 16;  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES\n\
2283   var counterBlock = new Array(blockSize);\n\
2284   var ctrTxt = unescCtrlChars(ciphertext[0]);\n\
2285   for (var i=0; i<8; i++) counterBlock[i] = ctrTxt.charCodeAt(i);\n\
2286 \n\
2287   var plaintext = new Array(ciphertext.length-1);\n\
2288 \n\
2289   for (var b=1; b<ciphertext.length; b++) {\n\
2290     // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)\n\
2291     for (var c=0; c<4; c++) counterBlock[15-c] = ((b-1) >>> c*8) & 0xff;\n\
2292     for (var c=0; c<4; c++) counterBlock[15-c-4] = ((b/0x100000000-1) >>> c*8) & 0xff;\n\
2293 \n\
2294     var cipherCntr = Cipher(counterBlock, keySchedule);  // encrypt counter block\n\
2295 \n\
2296     ciphertext[b] = unescCtrlChars(ciphertext[b]);\n\
2297 \n\
2298     var pt = '';\n\
2299     for (var i=0; i<ciphertext[b].length; i++) {\n\
2300       // -- xor plaintext with ciphered counter byte-by-byte --\n\
2301       var ciphertextByte = ciphertext[b].charCodeAt(i);\n\
2302       var plaintextByte = ciphertextByte ^ cipherCntr[i];\n\
2303       pt += String.fromCharCode(plaintextByte);\n\
2304     }\n\
2305     // pt is now plaintext for this block\n\
2306 \n\
2307     plaintext[b-1] = pt;  // b-1 'cos no initial nonce block in plaintext\n\
2308   }\n\
2309 \n\
2310   return plaintext.join('');\n\
2311 }\n\
2312 \n\
2313 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */\n\
2314 \n\
2315 function escCtrlChars(str) {  // escape control chars which might cause problems handling ciphertext\n\
2316   return str.replace(/[\\0\\t\\n\\v\\f\\r\\xa0'\"!-]/g, function(c) { return '!' + c.charCodeAt(0) + '!'; });\n\
2317 }  // \\xa0 to cater for bug in Firefox; include '-' to leave it free for use as a block marker\n\
2318 \n\
2319 function unescCtrlChars(str) {  // unescape potentially problematic control characters\n\
2320   return str.replace(/!\\d\\d?\\d?!/g, function(c) { return String.fromCharCode(c.slice(1,-1)); });\n\
2321 }\n\
2322 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */\n\
2323 \n\
2324 /*\n\
2325  * if escCtrlChars()/unescCtrlChars() still gives problems, use encodeBase64()/decodeBase64() instead\n\
2326  */\n\
2327 var b64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";\n\
2328 \n\
2329 function encodeBase64(str) {  // http://tools.ietf.org/html/rfc4648\n\
2330    var o1, o2, o3, h1, h2, h3, h4, bits, i=0, enc='';\n\
2331    \n\
2332    str = encodeUTF8(str);  // encode multi-byte chars into UTF-8 for byte-array\n\
2333 \n\
2334    do {  // pack three octets into four hexets\n\
2335       o1 = str.charCodeAt(i++);\n\
2336       o2 = str.charCodeAt(i++);\n\
2337       o3 = str.charCodeAt(i++);\n\
2338       \n\
2339       bits = o1<<16 | o2<<8 | o3;\n\
2340       \n\
2341       h1 = bits>>18 & 0x3f;\n\
2342       h2 = bits>>12 & 0x3f;\n\
2343       h3 = bits>>6 & 0x3f;\n\
2344       h4 = bits & 0x3f;\n\
2345       \n\
2346       // end of string? index to '=' in b64\n\
2347       if (isNaN(o3)) h4 = 64;\n\
2348       if (isNaN(o2)) h3 = 64;\n\
2349       \n\
2350       // use hexets to index into b64, and append result to encoded string\n\
2351       enc += b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);\n\
2352    } while (i < str.length);\n\
2353    \n\
2354    return enc;\n\
2355 }\n\
2356 \n\
2357 function decodeBase64(str) {\n\
2358    var o1, o2, o3, h1, h2, h3, h4, bits, i=0, enc='';\n\
2359 \n\
2360    do {  // unpack four hexets into three octets using index points in b64\n\
2361       h1 = b64.indexOf(str.charAt(i++));\n\
2362       h2 = b64.indexOf(str.charAt(i++));\n\
2363       h3 = b64.indexOf(str.charAt(i++));\n\
2364       h4 = b64.indexOf(str.charAt(i++));\n\
2365       \n\
2366       bits = h1<<18 | h2<<12 | h3<<6 | h4;\n\
2367       \n\
2368       o1 = bits>>16 & 0xff;\n\
2369       o2 = bits>>8 & 0xff;\n\
2370       o3 = bits & 0xff;\n\
2371       \n\
2372       if (h3 == 64)      enc += String.fromCharCode(o1);\n\
2373       else if (h4 == 64) enc += String.fromCharCode(o1, o2);\n\
2374       else               enc += String.fromCharCode(o1, o2, o3);\n\
2375    } while (i < str.length);\n\
2376 \n\
2377    return decodeUTF8(enc);  // decode UTF-8 byte-array back to Unicode\n\
2378 }\n\
2379 \n\
2380 function encodeUTF8(str) {  // encode multi-byte string into utf-8 multiple single-byte characters \n\
2381   str = str.replace(\n\
2382       /[\\u0080-\\u07ff]/g,  // U+0080 - U+07FF = 2-byte chars\n\
2383       function(c) { \n\
2384         var cc = c.charCodeAt(0);\n\
2385         return String.fromCharCode(0xc0 | cc>>6, 0x80 | cc&0x3f); }\n\
2386     );\n\
2387   str = str.replace(\n\
2388       /[\\u0800-\\uffff]/g,  // U+0800 - U+FFFF = 3-byte chars\n\
2389       function(c) { \n\
2390         var cc = c.charCodeAt(0); \n\
2391         return String.fromCharCode(0xe0 | cc>>12, 0x80 | cc>>6&0x3F, 0x80 | cc&0x3f); }\n\
2392     );\n\
2393   return str;\n\
2394 }\n\
2395 \n\
2396 function decodeUTF8(str) {  // decode utf-8 encoded string back into multi-byte characters\n\
2397   str = str.replace(\n\
2398       /[\\u00c0-\\u00df][\\u0080-\\u00bf]/g,                 // 2-byte chars\n\
2399       function(c) { \n\
2400         var cc = (c.charCodeAt(0)&0x1f)<<6 | c.charCodeAt(1)&0x3f;\n\
2401         return String.fromCharCode(cc); }\n\
2402     );\n\
2403   str = str.replace(\n\
2404       /[\\u00e0-\\u00ef][\\u0080-\\u00bf][\\u0080-\\u00bf]/g,  // 3-byte chars\n\
2405       function(c) { \n\
2406         var cc = (c.charCodeAt(0)&0x0f)<<12 | (c.charCodeAt(1)&0x3f<<6) | c.charCodeAt(2)&0x3f; \n\
2407         return String.fromCharCode(cc); }\n\
2408     );\n\
2409   return str;\n\
2410 }\n\
2411 \n\
2412 \n\
2413 function byteArrayToHexStr(b) {  // convert byte array to hex string for displaying test vectors\n\
2414   var s = '';\n\
2415   for (var i=0; i<b.length; i++) s += b[i].toString(16) + ' ';\n\
2416   return s;\n\
2417 }\n\
2418 \n\
2419 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */\n\
2420 \n\
2421 \n\
2422 var plainText = \"ROMEO: But, soft! what light through yonder window breaks?\\n\\\n\
2423 It is the east, and Juliet is the sun.\\n\\\n\
2424 Arise, fair sun, and kill the envious moon,\\n\\\n\
2425 Who is already sick and pale with grief,\\n\\\n\
2426 That thou her maid art far more fair than she:\\n\\\n\
2427 Be not her maid, since she is envious;\\n\\\n\
2428 Her vestal livery is but sick and green\\n\\\n\
2429 And none but fools do wear it; cast it off.\\n\\\n\
2430 It is my lady, O, it is my love!\\n\\\n\
2431 O, that she knew she were!\\n\\\n\
2432 She speaks yet she says nothing: what of that?\\n\\\n\
2433 Her eye discourses; I will answer it.\\n\\\n\
2434 I am too bold, 'tis not to me she speaks:\\n\\\n\
2435 Two of the fairest stars in all the heaven,\\n\\\n\
2436 Having some business, do entreat her eyes\\n\\\n\
2437 To twinkle in their spheres till they return.\\n\\\n\
2438 What if her eyes were there, they in her head?\\n\\\n\
2439 The brightness of her cheek would shame those stars,\\n\\\n\
2440 As daylight doth a lamp; her eyes in heaven\\n\\\n\
2441 Would through the airy region stream so bright\\n\\\n\
2442 That birds would sing and think it were not night.\\n\\\n\
2443 See, how she leans her cheek upon her hand!\\n\\\n\
2444 O, that I were a glove upon that hand,\\n\\\n\
2445 That I might touch that cheek!\\n\\\n\
2446 JULIET: Ay me!\\n\\\n\
2447 ROMEO: She speaks:\\n\\\n\
2448 O, speak again, bright angel! for thou art\\n\\\n\
2449 As glorious to this night, being o'er my head\\n\\\n\
2450 As is a winged messenger of heaven\\n\\\n\
2451 Unto the white-upturned wondering eyes\\n\\\n\
2452 Of mortals that fall back to gaze on him\\n\\\n\
2453 When he bestrides the lazy-pacing clouds\\n\\\n\
2454 And sails upon the bosom of the air.\";\n\
2455 \n\
2456 var password = \"O Romeo, Romeo! wherefore art thou Romeo?\";\n\
2457 \n\
2458 var cipherText = AESEncryptCtr(plainText, password, 256);\n\
2459 var decryptedText = AESDecryptCtr(cipherText, password, 256);\n\
2460 \n\
2461 \n\
2462 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
2463 \n\
2464 record(_sunSpiderInterval);\n\
2465 </script>\n\
2466 \n\
2467 \n\
2468 </body>\n\
2469 </html>\n\
2470 ", "<!DOCTYPE html>\n\
2471 <head>\n\
2472 \n\
2473 <meta charset=utf8>\n\
2474 \n\
2475 <!--\n\
2476  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
2477 \n\
2478  Redistribution and use in source and binary forms, with or without\n\
2479  modification, are permitted provided that the following conditions\n\
2480  are met:\n\
2481  1. Redistributions of source code must retain the above copyright\n\
2482     notice, this list of conditions and the following disclaimer.\n\
2483  2. Redistributions in binary form must reproduce the above copyright\n\
2484     notice, this list of conditions and the following disclaimer in the\n\
2485     documentation and/or other materials provided with the distribution.\n\
2486 \n\
2487  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
2488  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
2489  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
2490  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
2491  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
2492  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
2493  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
2494  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
2495  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
2496  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
2497  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
2498 -->\n\
2499 \n\
2500 <title>SunSpider crypto-md5</title>\n\
2501 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
2502 </head>\n\
2503 \n\
2504 <body>\n\
2505 <h3>crypto-md5</h3>\n\
2506 <div id=\"console\">\n\
2507 </div>\n\
2508 <script>\n\
2509 function record(time) {\n\
2510     document.getElementById(\"console\").innerHTML = time + \"ms\";\n\
2511     if (window.parent) {\n\
2512         parent.recordResult(time);\n\
2513     }\n\
2514 }\n\
2515 \n\
2516 var _sunSpiderStartDate = new Date();\n\
2517 \n\
2518 /*\n\
2519  * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message\n\
2520  * Digest Algorithm, as defined in RFC 1321.\n\
2521  * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.\n\
2522  * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet\n\
2523  * Distributed under the BSD License\n\
2524  * See http://pajhome.org.uk/crypt/md5 for more info.\n\
2525  */\n\
2526 \n\
2527 /*\n\
2528  * Configurable variables. You may need to tweak these to be compatible with\n\
2529  * the server-side, but the defaults work in most cases.\n\
2530  */\n\
2531 var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */\n\
2532 var b64pad  = \"\"; /* base-64 pad character. \"=\" for strict RFC compliance   */\n\
2533 var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */\n\
2534 \n\
2535 /*\n\
2536  * These are the functions you'll usually want to call\n\
2537  * They take string arguments and return either hex or base-64 encoded strings\n\
2538  */\n\
2539 function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}\n\
2540 function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}\n\
2541 function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}\n\
2542 function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }\n\
2543 function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }\n\
2544 function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }\n\
2545 \n\
2546 /*\n\
2547  * Perform a simple self-test to see if the VM is working\n\
2548  */\n\
2549 function md5_vm_test()\n\
2550 {\n\
2551   return hex_md5(\"abc\") == \"900150983cd24fb0d6963f7d28e17f72\";\n\
2552 }\n\
2553 \n\
2554 /*\n\
2555  * Calculate the MD5 of an array of little-endian words, and a bit length\n\
2556  */\n\
2557 function core_md5(x, len)\n\
2558 {\n\
2559   /* append padding */\n\
2560   x[len >> 5] |= 0x80 << ((len) % 32);\n\
2561   x[(((len + 64) >>> 9) << 4) + 14] = len;\n\
2562 \n\
2563   var a =  1732584193;\n\
2564   var b = -271733879;\n\
2565   var c = -1732584194;\n\
2566   var d =  271733878;\n\
2567 \n\
2568   for(var i = 0; i < x.length; i += 16)\n\
2569   {\n\
2570     var olda = a;\n\
2571     var oldb = b;\n\
2572     var oldc = c;\n\
2573     var oldd = d;\n\
2574 \n\
2575     a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);\n\
2576     d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);\n\
2577     c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);\n\
2578     b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);\n\
2579     a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);\n\
2580     d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);\n\
2581     c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);\n\
2582     b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);\n\
2583     a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);\n\
2584     d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);\n\
2585     c = md5_ff(c, d, a, b, x[i+10], 17, -42063);\n\
2586     b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);\n\
2587     a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);\n\
2588     d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);\n\
2589     c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);\n\
2590     b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);\n\
2591 \n\
2592     a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);\n\
2593     d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);\n\
2594     c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);\n\
2595     b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);\n\
2596     a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);\n\
2597     d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);\n\
2598     c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);\n\
2599     b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);\n\
2600     a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);\n\
2601     d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);\n\
2602     c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);\n\
2603     b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);\n\
2604     a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);\n\
2605     d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);\n\
2606     c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);\n\
2607     b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);\n\
2608 \n\
2609     a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);\n\
2610     d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);\n\
2611     c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);\n\
2612     b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);\n\
2613     a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);\n\
2614     d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);\n\
2615     c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);\n\
2616     b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);\n\
2617     a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);\n\
2618     d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);\n\
2619     c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);\n\
2620     b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);\n\
2621     a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);\n\
2622     d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);\n\
2623     c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);\n\
2624     b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);\n\
2625 \n\
2626     a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);\n\
2627     d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);\n\
2628     c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);\n\
2629     b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);\n\
2630     a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);\n\
2631     d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);\n\
2632     c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);\n\
2633     b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);\n\
2634     a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);\n\
2635     d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);\n\
2636     c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);\n\
2637     b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);\n\
2638     a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);\n\
2639     d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);\n\
2640     c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);\n\
2641     b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);\n\
2642 \n\
2643     a = safe_add(a, olda);\n\
2644     b = safe_add(b, oldb);\n\
2645     c = safe_add(c, oldc);\n\
2646     d = safe_add(d, oldd);\n\
2647   }\n\
2648   return Array(a, b, c, d);\n\
2649 \n\
2650 }\n\
2651 \n\
2652 /*\n\
2653  * These functions implement the four basic operations the algorithm uses.\n\
2654  */\n\
2655 function md5_cmn(q, a, b, x, s, t)\n\
2656 {\n\
2657   return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);\n\
2658 }\n\
2659 function md5_ff(a, b, c, d, x, s, t)\n\
2660 {\n\
2661   return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);\n\
2662 }\n\
2663 function md5_gg(a, b, c, d, x, s, t)\n\
2664 {\n\
2665   return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);\n\
2666 }\n\
2667 function md5_hh(a, b, c, d, x, s, t)\n\
2668 {\n\
2669   return md5_cmn(b ^ c ^ d, a, b, x, s, t);\n\
2670 }\n\
2671 function md5_ii(a, b, c, d, x, s, t)\n\
2672 {\n\
2673   return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);\n\
2674 }\n\
2675 \n\
2676 /*\n\
2677  * Calculate the HMAC-MD5, of a key and some data\n\
2678  */\n\
2679 function core_hmac_md5(key, data)\n\
2680 {\n\
2681   var bkey = str2binl(key);\n\
2682   if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);\n\
2683 \n\
2684   var ipad = Array(16), opad = Array(16);\n\
2685   for(var i = 0; i < 16; i++)\n\
2686   {\n\
2687     ipad[i] = bkey[i] ^ 0x36363636;\n\
2688     opad[i] = bkey[i] ^ 0x5C5C5C5C;\n\
2689   }\n\
2690 \n\
2691   var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);\n\
2692   return core_md5(opad.concat(hash), 512 + 128);\n\
2693 }\n\
2694 \n\
2695 /*\n\
2696  * Add integers, wrapping at 2^32. This uses 16-bit operations internally\n\
2697  * to work around bugs in some JS interpreters.\n\
2698  */\n\
2699 function safe_add(x, y)\n\
2700 {\n\
2701   var lsw = (x & 0xFFFF) + (y & 0xFFFF);\n\
2702   var msw = (x >> 16) + (y >> 16) + (lsw >> 16);\n\
2703   return (msw << 16) | (lsw & 0xFFFF);\n\
2704 }\n\
2705 \n\
2706 /*\n\
2707  * Bitwise rotate a 32-bit number to the left.\n\
2708  */\n\
2709 function bit_rol(num, cnt)\n\
2710 {\n\
2711   return (num << cnt) | (num >>> (32 - cnt));\n\
2712 }\n\
2713 \n\
2714 /*\n\
2715  * Convert a string to an array of little-endian words\n\
2716  * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.\n\
2717  */\n\
2718 function str2binl(str)\n\
2719 {\n\
2720   var bin = Array();\n\
2721   var mask = (1 << chrsz) - 1;\n\
2722   for(var i = 0; i < str.length * chrsz; i += chrsz)\n\
2723     bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);\n\
2724   return bin;\n\
2725 }\n\
2726 \n\
2727 /*\n\
2728  * Convert an array of little-endian words to a string\n\
2729  */\n\
2730 function binl2str(bin)\n\
2731 {\n\
2732   var str = \"\";\n\
2733   var mask = (1 << chrsz) - 1;\n\
2734   for(var i = 0; i < bin.length * 32; i += chrsz)\n\
2735     str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);\n\
2736   return str;\n\
2737 }\n\
2738 \n\
2739 /*\n\
2740  * Convert an array of little-endian words to a hex string.\n\
2741  */\n\
2742 function binl2hex(binarray)\n\
2743 {\n\
2744   var hex_tab = hexcase ? \"0123456789ABCDEF\" : \"0123456789abcdef\";\n\
2745   var str = \"\";\n\
2746   for(var i = 0; i < binarray.length * 4; i++)\n\
2747   {\n\
2748     str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +\n\
2749            hex_tab.charAt((binarray[i>>2] >> ((i%4)*8  )) & 0xF);\n\
2750   }\n\
2751   return str;\n\
2752 }\n\
2753 \n\
2754 /*\n\
2755  * Convert an array of little-endian words to a base-64 string\n\
2756  */\n\
2757 function binl2b64(binarray)\n\
2758 {\n\
2759   var tab = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\
2760   var str = \"\";\n\
2761   for(var i = 0; i < binarray.length * 4; i += 3)\n\
2762   {\n\
2763     var triplet = (((binarray[i   >> 2] >> 8 * ( i   %4)) & 0xFF) << 16)\n\
2764                 | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )\n\
2765                 |  ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);\n\
2766     for(var j = 0; j < 4; j++)\n\
2767     {\n\
2768       if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;\n\
2769       else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);\n\
2770     }\n\
2771   }\n\
2772   return str;\n\
2773 }\n\
2774 \n\
2775 var plainText = \"Rebellious subjects, enemies to peace,\\n\\\n\
2776 Profaners of this neighbour-stained steel,--\\n\\\n\
2777 Will they not hear? What, ho! you men, you beasts,\\n\\\n\
2778 That quench the fire of your pernicious rage\\n\\\n\
2779 With purple fountains issuing from your veins,\\n\\\n\
2780 On pain of torture, from those bloody hands\\n\\\n\
2781 Throw your mistemper'd weapons to the ground,\\n\\\n\
2782 And hear the sentence of your moved prince.\\n\\\n\
2783 Three civil brawls, bred of an airy word,\\n\\\n\
2784 By thee, old Capulet, and Montague,\\n\\\n\
2785 Have thrice disturb'd the quiet of our streets,\\n\\\n\
2786 And made Verona's ancient citizens\\n\\\n\
2787 Cast by their grave beseeming ornaments,\\n\\\n\
2788 To wield old partisans, in hands as old,\\n\\\n\
2789 Canker'd with peace, to part your canker'd hate:\\n\\\n\
2790 If ever you disturb our streets again,\\n\\\n\
2791 Your lives shall pay the forfeit of the peace.\\n\\\n\
2792 For this time, all the rest depart away:\\n\\\n\
2793 You Capulet; shall go along with me:\\n\\\n\
2794 And, Montague, come you this afternoon,\\n\\\n\
2795 To know our further pleasure in this case,\\n\\\n\
2796 To old Free-town, our common judgment-place.\\n\\\n\
2797 Once more, on pain of death, all men depart.\"\n\
2798 \n\
2799 for (var i = 0; i <4; i++) {\n\
2800     plainText += plainText;\n\
2801 }\n\
2802 \n\
2803 var md5Output = hex_md5(plainText);\n\
2804 \n\
2805 \n\
2806 var _sunSpiderInterval = new Date() - _sunSpiderStartDate;\n\
2807 \n\
2808 record(_sunSpiderInterval);\n\
2809 </script>\n\
2810 \n\
2811 \n\
2812 </body>\n\
2813 </html>\n\
2814 ", "<!DOCTYPE html>\n\
2815 <head>\n\
2816 \n\
2817 <meta charset=utf8>\n\
2818 \n\
2819 <!--\n\
2820  Copyright (C) 2007 Apple Inc.  All rights reserved.\n\
2821 \n\
2822  Redistribution and use in source and binary forms, with or without\n\
2823  modification, are permitted provided that the following conditions\n\
2824  are met:\n\
2825  1. Redistributions of source code must retain the above copyright\n\
2826     notice, this list of conditions and the following disclaimer.\n\
2827  2. Redistributions in binary form must reproduce the above copyright\n\
2828     notice, this list of conditions and the following disclaimer in the\n\
2829     documentation and/or other materials provided with the distribution.\n\
2830 \n\
2831  THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\n\
2832  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
2833  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n\
2834  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\n\
2835  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
2836  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
2837  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
2838  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n\
2839  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
2840  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
2841  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n\
2842 -->\n\
2843 \n\
2844 <title>SunSpider crypto-sha1</title>\n\
2845 <link rel=\"stylesheet\" href=\"../sunspider.css\">\n\
2846 </head>\n\
2847 \n\
2848 <body>\n\
2849 <h3>crypto-sha1</h3>\n\
2850 <div id=\"console\">\n\
2851 </div>\n\
2852 <script>\n\
2853 function record(time) {\n\
2854     document.getElementById(\"console\").innerHTML = time + \"ms\";\n\
2855     if (window.parent) {\n\
2856         parent.recordResult(time);\n\
2857     }\n\
2858 }\n\
2859 \n\
2860 var _sunSpiderStartDate = new Date();\n\
2861 \n\
2862 /*\n\
2863  * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined\n\
2864  * in FIPS PUB 180-1\n\
2865  * Version 2.1a Copyright Paul Johnston 2000 - 2002.\n\
2866  * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet\n\
2867  * Distributed under the BSD License\n\
2868  * See http://pajhome.org.uk/crypt/md5 for details.\n\
2869  */\n\
2870 \n\
2871 /*\n\
2872  * Configurable variables. You may need to tweak these to be compatible with\n\
2873  * the server-side, but the defaults work in most cases.\n\
2874  */\n\
2875 var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */\n\
2876 var b64pad  = \"\"; /* base-64 pad character. \"=\" for strict RFC compliance   */\n\
2877 var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */\n\
2878 \n\
2879 /*\n\
2880  * These are the functions you'll usually want to call\n\
2881  * They take string arguments and return either hex or base-64 encoded strings\n\
2882  */\n\
2883 function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));}\n\
2884 function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz));}\n\
2885 function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));}\n\
2886 function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));}\n\
2887 function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}\n\
2888 function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}\n\
2889 \n\
2890 /*\n\
2891  * Perform a simple self-test to see if the VM is working\n\
2892  */\n\
2893 function sha1_vm_test()\n\
2894 {\n\
2895   return hex_sha1(\"abc\") == \"a9993e364706816aba3e25717850c26c9cd0d89d\";\n\
2896 }\n\
2897 \n\
2898 /*\n\
2899  * Calculate the SHA-1 of an array of big-endian words, and a bit length\n\
2900  */\n\
2901 function core_sha1(x, len)\n\
2902 {\n\
2903   /* append padding */\n\
2904   x[len >> 5] |= 0x80 << (24 - len % 32);\n\
2905   x[((len + 64 >> 9) << 4) + 15] = len;\n\
2906 \n\
2907   var w = Array(80);\n\
2908   var a =  1732584193;\n\
2909   var b = -271733879;\n\
2910   var c = -1732584194;\n\
2911   var d =  271733878;\n\
2912   var e = -1009589776;\n\
2913 \n\
2914   for(var i = 0; i < x.length; i += 16)\n\
2915   {\n\
2916     var olda = a;\n\
2917     var oldb = b;\n\
2918     var oldc = c;\n\
2919     var oldd = d;\n\
2920     var olde = e;\n\
2921 \n\
2922     for(var j = 0; j < 80; j++)\n\
2923     {\n\
2924       if(j < 16) w[j] = x[i + j];\n\
2925       else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);\n\
2926       var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),\n\
2927                        safe_add(safe_add(e, w[j]), sha1_kt(j)));\n\
2928       e = d;\n\
2929       d = c;\n\
2930       c = rol(b, 30);\n\
2931       b = a;\n\
2932       a = t;\n\
2933     }\n\
2934 \n\
2935     a = safe_add(a, olda);\n\
2936     b = safe_add(b, oldb);\n\
2937     c = safe_add(c, oldc);\n\
2938     d = safe_add(d, oldd);\n\
2939     e = safe_add(e, olde);\n\
2940   }\n\
2941   return Array(a, b, c, d, e);\n\
2942 \n\
2943 }\n\
2944 \n\
2945 /*\n\
2946  * Perform the appropriate triplet combination function for the current\n\
2947  * iteration\n\
2948  */\n\
2949 function sha1_ft(t, b, c, d)\n\
2950 {\n\
2951   if(t < 20) return (b & c) | ((~b) & d);\n\
2952   if(t < 40) return b ^ c ^ d;\n\
2953   if(t < 60) return (b & c) | (b & d) | (c & d);\n\
2954   return b ^ c ^ d;\n\
2955 }\n\
2956 \n\
2957 /*\n\
2958  * Determine the appropriate additive constant for the current iteration\n\
2959  */\n\
2960 function sha1_kt(t)\n\
2961 {\n\
2962   return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :\n\
2963          (t < 60) ? -1894007588 : -899497514;\n\
2964 }\n\
2965 \n\
2966 /*\n\
2967  * Calculate the HMAC-SHA1 of a key and some data\n\
2968  */\n\
2969 function core_hmac_sha1(key, data)\n\
2970 {\n\
2971   var bkey = str2binb(key);\n\
2972   if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);\n\
2973 \n\
2974   var ipad = Array(16), opad = Array(16);\n\
2975   for(var i = 0; i < 16; i++)\n\
2976   {\n\
2977     ipad[i] = bkey[i] ^ 0x36363636;\n\
2978     opad[i] = bkey[i] ^ 0x5C5C5C5C;\n\
2979   }\n\
2980 \n\
2981   var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);\n\
2982   return core_sha1(opad.concat(hash), 512 + 160);\n\
2983 }\n\
2984 \n\
2985 /*\n\
2986  * Add integers, wrapping at 2^32. This uses 16-bit operations internally\n\
2987  * to work around bugs in some JS interpreters.\n\
2988  */\n\
2989 function safe_add(x, y)\n\
2990 {\n\
2991   var lsw = (x & 0xFFFF) + (y & 0xFFFF);\n\
2992   var msw = (x >> 16) + (y >> 16) + (lsw >> 16);\n\
2993   return (msw << 16) | (lsw & 0xFFFF);\n\
2994 }\n\
2995 \n\
2996 /*\n\
2997  * Bitwise rotate a 32-bit number to the left.\n\
2998  */\n\
2999 function rol(num, cnt)\n\
3000 {\n\
3001   return (num << cnt) | (num >>> (32 - cnt));\n\
3002 }\n\
3003 \n\
3004 /*\n\
3005  * Convert an 8-bit or 16-bit string to an array of big-endian words\n\
3006  * In 8-bit function, characters >255 have their hi-byte silently ignored.\n\
3007  */\n\
3008 function str2binb(str)\n\
3009 {\n\
3010   var bin = Array();\n\
3011   var mask = (1 << chrsz) - 1;\n\
3012   for(var i = 0; i < str.length * chrsz; i += chrsz)\n\
3013     bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);\n\
3014   return bin;\n\
3015 }\n\
3016 \n\
3017 /*\n\
3018  * Convert an array of big-endian words to a string\n\
3019  */\n\
3020 function binb2str(bin)\n\
3021 {\n\
3022   var str = \"\";\n\
3023   var mask = (1 << chrsz) - 1;\n\
3024   for(var i = 0; i < bin.length * 32; i += chrsz)\n\
3025     str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);\n\
3026   return str;\n\
3027 }\n\
3028 \n\
3029 /*\n\
3030  * Convert an array of big-endian words to a hex string.\n\
3031  */\n\
3032 function binb2hex(binarray)\n\
3033 {\n\
3034   var hex_tab = hexcase ? \"0123456789ABCDEF\" : \"0123456789abcdef\";\n\
3035   var str = \"\";\n\
3036   for(var i = 0; i < binarray.length * 4; i++)\n\
3037   {\n\
3038     str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +\n\
3039            hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);\n\
3040   }\n\
3041   return str;\n\
3042 }\n\
3043 \n\
3044 /*\n\
3045  * Convert an array of big-endian words to a base-64 string\n\
3046  */\n\
3047 function binb2b64(binarray)\n\
3048 {\n\
3049   var tab = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\
3050   var str = \"\";\n\
3051   for(var i = 0; i < binarray.length * 4; i += 3)\n\
3052   {\n\
3053     var triplet = (((binarray[i   >> 2] >> 8 * (3 -  i   %4)) & 0xFF) << 16)\n\
3054                 | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )\n\
3055                 |  ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);\n\
3056     for(var j = 0; j < 4; j++)\n\
3057     {\n\
3058       if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;\n\
3059       else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);\n\
3060     }\n\
3061   }\n\
3062   return str;\n\
3063 }\n\
3064 \n\
3065 \n\
3066 var plainText = \"Two households, both alike in dignity,\\n\\\n\