diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..a3839a1e34 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +Jint.Tests/* linguist-vendored +Jint.Tests.Ecma/* linguist-vendored +Jint.Tests.CommonScripts/* linguist-vendored diff --git a/.gitignore b/.gitignore index b66510d910..fba4ce910d 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ build/ *_p.c *.ilk *.meta +*.nupkg *.obj *.pch *.pdb @@ -101,6 +102,7 @@ publish/ # NuGet Packages Directory ## TODO: If you have NuGet Package Restore enabled, uncomment the next line packages/ +.nuget/ # Windows Azure Build Output csx @@ -151,3 +153,8 @@ $RECYCLE.BIN/ # Mac crap .DS_Store +Jint.sln.ide/* +/Jint.sln.GhostDoc.xml +.vs +project.lock.json +.build diff --git a/.nuget/NuGet.Config b/.nuget/NuGet.Config deleted file mode 100644 index 67f8ea046e..0000000000 --- a/.nuget/NuGet.Config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.nuget/NuGet.exe b/.nuget/NuGet.exe deleted file mode 100644 index 8f61340295..0000000000 Binary files a/.nuget/NuGet.exe and /dev/null differ diff --git a/.nuget/NuGet.targets b/.nuget/NuGet.targets deleted file mode 100644 index 83fe906016..0000000000 --- a/.nuget/NuGet.targets +++ /dev/null @@ -1,136 +0,0 @@ - - - - $(MSBuildProjectDirectory)\..\ - - - false - - - false - - - true - - - false - - - - - - - - - - - $([System.IO.Path]::Combine($(SolutionDir), ".nuget")) - $([System.IO.Path]::Combine($(ProjectDir), "packages.config")) - - - - - $(SolutionDir).nuget - packages.config - - - - - $(NuGetToolsPath)\NuGet.exe - @(PackageSource) - - "$(NuGetExePath)" - mono --runtime=v4.0.30319 $(NuGetExePath) - - $(TargetDir.Trim('\\')) - - -RequireConsent - -NonInteractive - - "$(SolutionDir) " - "$(SolutionDir)" - - - $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir) - $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols - - - - RestorePackages; - $(BuildDependsOn); - - - - - $(BuildDependsOn); - BuildPackage; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Common.props b/Common.props new file mode 100644 index 0000000000..3f6b2ded4c --- /dev/null +++ b/Common.props @@ -0,0 +1,18 @@ + + + + Sebastien Ros + Sebastien Ros + true + portable + false + false + false + false + false + false + false + true + + + diff --git a/Jint.Benchmark/App.config b/Jint.Benchmark/App.config deleted file mode 100644 index 8e15646352..0000000000 --- a/Jint.Benchmark/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Jint.Benchmark/Jint.Benchmark.csproj b/Jint.Benchmark/Jint.Benchmark.csproj index ba8ed1b30b..17511eb9e0 100644 --- a/Jint.Benchmark/Jint.Benchmark.csproj +++ b/Jint.Benchmark/Jint.Benchmark.csproj @@ -1,93 +1,25 @@ - - - + + - Debug - AnyCPU - {8922A952-4F82-4A97-B41C-C0A9932BFFA8} - Exe - Properties - Jint.Benchmark + net45 Jint.Benchmark - v4.5 - 512 - ..\ - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 + Exe + Jint.Benchmark + false + false + false + false + false + false + false + false - - - False - ..\packages\FSharp.Core.4.0.0\lib\FSharp.Core.dll - - - ..\packages\IronJS.Core.0.2.0.1\lib\net40\IronJS.dll - - - False - ..\packages\Jurassic.2.2.0\lib\Jurassic.dll - - - ..\packages\IronJS.Core.0.2.0.1\lib\net40\Microsoft.Dynamic.dll - - - ..\packages\IronJS.Core.0.2.0.1\lib\net40\Microsoft.Scripting.dll - - - ..\packages\IronJS.Core.0.2.0.1\lib\net40\Microsoft.Scripting.Core.dll - - - ..\packages\IronJS.Core.0.2.0.1\lib\net40\Microsoft.Scripting.ExtensionAttribute.dll - + + + + - - - - - - - - - - - - - - - - - - {678738da-f723-4920-b9e5-cad667104bda} - Jint - - - - - - \ No newline at end of file + + diff --git a/Jint.Benchmark/Program.cs b/Jint.Benchmark/Program.cs index d8d1dcaf13..09d7fe8bb6 100644 --- a/Jint.Benchmark/Program.cs +++ b/Jint.Benchmark/Program.cs @@ -14,11 +14,11 @@ class Program if(o.Blah != 'bar42.0001') throw TypeError; function fib(n){ - if(n<2) { - return n; + if(n<2) { + return n; } - - return fib(n-1) + fib(n-2); + + return fib(n-1) + fib(n-2); } if(fib(3) != 2) throw TypeError; @@ -26,34 +26,34 @@ function fib(n){ static void Main() { - const bool runIronJs = true; + //const bool runIronJs = true; const bool runJint = true; const bool runJurassic = true; - const int iterations = 100; + const int iterations = 1000; const bool reuseEngine = false; var watch = new Stopwatch(); - if (runIronJs) - { - IronJS.Hosting.CSharp.Context ironjs; - ironjs = new IronJS.Hosting.CSharp.Context(); - ironjs.Execute(Script); - watch.Restart(); - for (var i = 0; i < iterations; i++) - { - if (!reuseEngine) - { - ironjs = new IronJS.Hosting.CSharp.Context(); - } - - ironjs.Execute(Script); - } - - Console.WriteLine("IronJs: {0} iterations in {1} ms", iterations, watch.ElapsedMilliseconds); - } + //if (runIronJs) + //{ + // IronJS.Hosting.CSharp.Context ironjs; + // ironjs = new IronJS.Hosting.CSharp.Context(); + // ironjs.Execute(Script); + // watch.Restart(); + // for (var i = 0; i < iterations; i++) + // { + // if (!reuseEngine) + // { + // ironjs = new IronJS.Hosting.CSharp.Context(); + // } + + // ironjs.Execute(Script); + // } + + // Console.WriteLine("IronJs: {0} iterations in {1} ms", iterations, watch.ElapsedMilliseconds); + //} if (runJint) { diff --git a/Jint.Benchmark/packages.config b/Jint.Benchmark/packages.config deleted file mode 100644 index 792d1a5854..0000000000 --- a/Jint.Benchmark/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/Jint.Repl/App.config b/Jint.Repl/App.config deleted file mode 100644 index 8e15646352..0000000000 --- a/Jint.Repl/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Jint.Repl/Jint.Repl.csproj b/Jint.Repl/Jint.Repl.csproj index ea44cc113d..1f83a4e972 100644 --- a/Jint.Repl/Jint.Repl.csproj +++ b/Jint.Repl/Jint.Repl.csproj @@ -1,64 +1,25 @@ - - - + + - Debug - AnyCPU - {A69FD3C5-F2B0-4055-A518-F4173EBA5E4D} + net45 + Jint.Repl Exe - Properties - Jint.Repl - jint - v4.5 - 512 + Jint.Repl + false + false + false + false + false + false + false + false + false - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - + + + - - - - - - - - - - - - - - - - {678738DA-F723-4920-B9E5-CAD667104BDA} - Jint - - - - \ No newline at end of file + + diff --git a/Jint.Repl/Program.cs b/Jint.Repl/Program.cs index dbb08e1c51..14ab3bd3ab 100644 --- a/Jint.Repl/Program.cs +++ b/Jint.Repl/Program.cs @@ -66,7 +66,7 @@ static void Main(string[] args) Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(e.Message); } - + } } } diff --git a/Jint.Repl/Properties/AssemblyInfo.cs b/Jint.Repl/Properties/AssemblyInfo.cs index c0dd407c1d..ef3edbd898 100644 --- a/Jint.Repl/Properties/AssemblyInfo.cs +++ b/Jint.Repl/Properties/AssemblyInfo.cs @@ -16,5 +16,5 @@ [assembly: AssemblyCulture("")] [assembly: NeutralResourcesLanguage("en")] -[assembly: AssemblyVersion("2.2.0")] -[assembly: AssemblyFileVersion("2.2.0")] +[assembly: AssemblyVersion("2.9.1")] +[assembly: AssemblyFileVersion("2.9.1")] diff --git a/Jint.Tests.CommonScripts/Jint.Tests.CommonScripts.csproj b/Jint.Tests.CommonScripts/Jint.Tests.CommonScripts.csproj index a07ed66182..9c6a03d798 100644 --- a/Jint.Tests.CommonScripts/Jint.Tests.CommonScripts.csproj +++ b/Jint.Tests.CommonScripts/Jint.Tests.CommonScripts.csproj @@ -1,71 +1,39 @@ - - - + + - Debug - AnyCPU - {9A78C21A-8887-4B1B-9AFE-246B53EE23B4} - Library - Properties - Jint.Tests.CommonScripts + netcoreapp1.0;net451 Jint.Tests.CommonScripts - v4.5 - 512 - ..\ - true - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 + Jint.Tests.CommonScripts + true + 1.0.4 + false + false + false + false + false + false + false + false + - - - - - - - - - ..\packages\xunit.1.9.2\lib\net20\xunit.dll - - - ..\packages\xunit.extensions.1.9.2\lib\net20\xunit.extensions.dll - + + - - + + - + + + + - - - {678738da-f723-4920-b9e5-cad667104bda} - Jint - + + + + - - - - \ No newline at end of file + + diff --git a/Jint.Tests.CommonScripts/Scripts/3d-cube.js b/Jint.Tests.CommonScripts/Scripts/3d-cube.js new file mode 100644 index 0000000000..db4932f9c6 --- /dev/null +++ b/Jint.Tests.CommonScripts/Scripts/3d-cube.js @@ -0,0 +1,355 @@ +// 3D Cube Rotation +// http://www.speich.net/computer/moztesting/3d.htm +// Created by Simon Speich + +var Q = new Array(); +var MTrans = new Array(); // transformation matrix +var MQube = new Array(); // position information of qube +var I = new Array(); // entity matrix +var Origin = new Object(); +var Testing = new Object(); +var LoopTimer; + +var validation = { + 20: 2889.0000000000045, + 40: 2889.0000000000055, + 80: 2889.000000000005, + 160: 2889.0000000000055 +}; + +var DisplArea = new Object(); +DisplArea.Width = 300; +DisplArea.Height = 300; + +function DrawLine(From, To) { + var x1 = From.V[0]; + var x2 = To.V[0]; + var y1 = From.V[1]; + var y2 = To.V[1]; + var dx = Math.abs(x2 - x1); + var dy = Math.abs(y2 - y1); + var x = x1; + var y = y1; + var IncX1, IncY1; + var IncX2, IncY2; + var Den; + var Num; + var NumAdd; + var NumPix; + + if (x2 >= x1) { IncX1 = 1; IncX2 = 1; } + else { IncX1 = -1; IncX2 = -1; } + if (y2 >= y1) { IncY1 = 1; IncY2 = 1; } + else { IncY1 = -1; IncY2 = -1; } + if (dx >= dy) { + IncX1 = 0; + IncY2 = 0; + Den = dx; + Num = dx / 2; + NumAdd = dy; + NumPix = dx; + } + else { + IncX2 = 0; + IncY1 = 0; + Den = dy; + Num = dy / 2; + NumAdd = dx; + NumPix = dy; + } + + NumPix = Math.round(Q.LastPx + NumPix); + + var i = Q.LastPx; + for (; i < NumPix; i++) { + Num += NumAdd; + if (Num >= Den) { + Num -= Den; + x += IncX1; + y += IncY1; + } + x += IncX2; + y += IncY2; + } + Q.LastPx = NumPix; +} + +function CalcCross(V0, V1) { + var Cross = new Array(); + Cross[0] = V0[1]*V1[2] - V0[2]*V1[1]; + Cross[1] = V0[2]*V1[0] - V0[0]*V1[2]; + Cross[2] = V0[0]*V1[1] - V0[1]*V1[0]; + return Cross; +} + +function CalcNormal(V0, V1, V2) { + var A = new Array(); var B = new Array(); + for (var i = 0; i < 3; i++) { + A[i] = V0[i] - V1[i]; + B[i] = V2[i] - V1[i]; + } + A = CalcCross(A, B); + var Length = Math.sqrt(A[0]*A[0] + A[1]*A[1] + A[2]*A[2]); + for (var i = 0; i < 3; i++) A[i] = A[i] / Length; + A[3] = 1; + return A; +} + +function CreateP(X,Y,Z) { + this.V = [X,Y,Z,1]; +} + +// multiplies two matrices +function MMulti(M1, M2) { + var M = [[],[],[],[]]; + var i = 0; + var j = 0; + for (; i < 4; i++) { + j = 0; + 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]; + } + return M; +} + +//multiplies matrix with vector +function VMulti(M, V) { + var Vect = new Array(); + var i = 0; + 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]; + return Vect; +} + +function VMulti2(M, V) { + var Vect = new Array(); + var i = 0; + for (;i < 3; i++) Vect[i] = M[i][0] * V[0] + M[i][1] * V[1] + M[i][2] * V[2]; + return Vect; +} + +// add to matrices +function MAdd(M1, M2) { + var M = [[],[],[],[]]; + var i = 0; + var j = 0; + for (; i < 4; i++) { + j = 0; + for (; j < 4; j++) M[i][j] = M1[i][j] + M2[i][j]; + } + return M; +} + +function Translate(M, Dx, Dy, Dz) { + var T = [ + [1,0,0,Dx], + [0,1,0,Dy], + [0,0,1,Dz], + [0,0,0,1] + ]; + return MMulti(T, M); +} + +function RotateX(M, Phi) { + var a = Phi; + a *= Math.PI / 180; + var Cos = Math.cos(a); + var Sin = Math.sin(a); + var R = [ + [1,0,0,0], + [0,Cos,-Sin,0], + [0,Sin,Cos,0], + [0,0,0,1] + ]; + return MMulti(R, M); +} + +function RotateY(M, Phi) { + var a = Phi; + a *= Math.PI / 180; + var Cos = Math.cos(a); + var Sin = Math.sin(a); + var R = [ + [Cos,0,Sin,0], + [0,1,0,0], + [-Sin,0,Cos,0], + [0,0,0,1] + ]; + return MMulti(R, M); +} + +function RotateZ(M, Phi) { + var a = Phi; + a *= Math.PI / 180; + var Cos = Math.cos(a); + var Sin = Math.sin(a); + var R = [ + [Cos,-Sin,0,0], + [Sin,Cos,0,0], + [0,0,1,0], + [0,0,0,1] + ]; + return MMulti(R, M); +} + +function DrawQube() { + // calc current normals + var CurN = new Array(); + var i = 5; + Q.LastPx = 0; + for (; i > -1; i--) CurN[i] = VMulti2(MQube, Q.Normal[i]); + if (CurN[0][2] < 0) { + if (!Q.Line[0]) { DrawLine(Q[0], Q[1]); Q.Line[0] = true; }; + if (!Q.Line[1]) { DrawLine(Q[1], Q[2]); Q.Line[1] = true; }; + if (!Q.Line[2]) { DrawLine(Q[2], Q[3]); Q.Line[2] = true; }; + if (!Q.Line[3]) { DrawLine(Q[3], Q[0]); Q.Line[3] = true; }; + } + if (CurN[1][2] < 0) { + if (!Q.Line[2]) { DrawLine(Q[3], Q[2]); Q.Line[2] = true; }; + if (!Q.Line[9]) { DrawLine(Q[2], Q[6]); Q.Line[9] = true; }; + if (!Q.Line[6]) { DrawLine(Q[6], Q[7]); Q.Line[6] = true; }; + if (!Q.Line[10]) { DrawLine(Q[7], Q[3]); Q.Line[10] = true; }; + } + if (CurN[2][2] < 0) { + if (!Q.Line[4]) { DrawLine(Q[4], Q[5]); Q.Line[4] = true; }; + if (!Q.Line[5]) { DrawLine(Q[5], Q[6]); Q.Line[5] = true; }; + if (!Q.Line[6]) { DrawLine(Q[6], Q[7]); Q.Line[6] = true; }; + if (!Q.Line[7]) { DrawLine(Q[7], Q[4]); Q.Line[7] = true; }; + } + if (CurN[3][2] < 0) { + if (!Q.Line[4]) { DrawLine(Q[4], Q[5]); Q.Line[4] = true; }; + if (!Q.Line[8]) { DrawLine(Q[5], Q[1]); Q.Line[8] = true; }; + if (!Q.Line[0]) { DrawLine(Q[1], Q[0]); Q.Line[0] = true; }; + if (!Q.Line[11]) { DrawLine(Q[0], Q[4]); Q.Line[11] = true; }; + } + if (CurN[4][2] < 0) { + if (!Q.Line[11]) { DrawLine(Q[4], Q[0]); Q.Line[11] = true; }; + if (!Q.Line[3]) { DrawLine(Q[0], Q[3]); Q.Line[3] = true; }; + if (!Q.Line[10]) { DrawLine(Q[3], Q[7]); Q.Line[10] = true; }; + if (!Q.Line[7]) { DrawLine(Q[7], Q[4]); Q.Line[7] = true; }; + } + if (CurN[5][2] < 0) { + if (!Q.Line[8]) { DrawLine(Q[1], Q[5]); Q.Line[8] = true; }; + if (!Q.Line[5]) { DrawLine(Q[5], Q[6]); Q.Line[5] = true; }; + if (!Q.Line[9]) { DrawLine(Q[6], Q[2]); Q.Line[9] = true; }; + if (!Q.Line[1]) { DrawLine(Q[2], Q[1]); Q.Line[1] = true; }; + } + Q.Line = [false,false,false,false,false,false,false,false,false,false,false,false]; + Q.LastPx = 0; +} + +function Loop() { + if (Testing.LoopCount > Testing.LoopMax) return; + var TestingStr = String(Testing.LoopCount); + while (TestingStr.length < 3) TestingStr = "0" + TestingStr; + MTrans = Translate(I, -Q[8].V[0], -Q[8].V[1], -Q[8].V[2]); + MTrans = RotateX(MTrans, 1); + MTrans = RotateY(MTrans, 3); + MTrans = RotateZ(MTrans, 5); + MTrans = Translate(MTrans, Q[8].V[0], Q[8].V[1], Q[8].V[2]); + MQube = MMulti(MTrans, MQube); + var i = 8; + for (; i > -1; i--) { + Q[i].V = VMulti(MTrans, Q[i].V); + } + DrawQube(); + Testing.LoopCount++; + Loop(); +} + +function Init(CubeSize) { + // init/reset vars + Origin.V = [150,150,20,1]; + Testing.LoopCount = 0; + Testing.LoopMax = 50; + Testing.TimeMax = 0; + Testing.TimeAvg = 0; + Testing.TimeMin = 0; + Testing.TimeTemp = 0; + Testing.TimeTotal = 0; + Testing.Init = false; + + // transformation matrix + MTrans = [ + [1,0,0,0], + [0,1,0,0], + [0,0,1,0], + [0,0,0,1] + ]; + + // position information of qube + MQube = [ + [1,0,0,0], + [0,1,0,0], + [0,0,1,0], + [0,0,0,1] + ]; + + // entity matrix + I = [ + [1,0,0,0], + [0,1,0,0], + [0,0,1,0], + [0,0,0,1] + ]; + + // create qube + Q[0] = new CreateP(-CubeSize,-CubeSize, CubeSize); + Q[1] = new CreateP(-CubeSize, CubeSize, CubeSize); + Q[2] = new CreateP( CubeSize, CubeSize, CubeSize); + Q[3] = new CreateP( CubeSize,-CubeSize, CubeSize); + Q[4] = new CreateP(-CubeSize,-CubeSize,-CubeSize); + Q[5] = new CreateP(-CubeSize, CubeSize,-CubeSize); + Q[6] = new CreateP( CubeSize, CubeSize,-CubeSize); + Q[7] = new CreateP( CubeSize,-CubeSize,-CubeSize); + + // center of gravity + Q[8] = new CreateP(0, 0, 0); + + // anti-clockwise edge check + Q.Edge = [[0,1,2],[3,2,6],[7,6,5],[4,5,1],[4,0,3],[1,5,6]]; + + // calculate squad normals + Q.Normal = new Array(); + 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); + + // line drawn ? + Q.Line = [false,false,false,false,false,false,false,false,false,false,false,false]; + + // create line pixels + Q.NumPx = 9 * 2 * CubeSize; + for (var i = 0; i < Q.NumPx; i++) CreateP(0,0,0); + + MTrans = Translate(MTrans, Origin.V[0], Origin.V[1], Origin.V[2]); + MQube = MMulti(MTrans, MQube); + + var i = 0; + for (; i < 9; i++) { + Q[i].V = VMulti(MTrans, Q[i].V); + } + DrawQube(); + Testing.Init = true; + Loop(); + + // Perform a simple sum-based verification. + var sum = 0; + for (var i = 0; i < Q.length; ++i) { + var vector = Q[i].V; + for (var j = 0; j < vector.length; ++j) + sum += vector[j]; + } + if (sum != validation[CubeSize]) + throw "Error: bad vector sum for CubeSize = " + CubeSize + "; expected " + validation[CubeSize] + " but got " + sum; +} + +for ( var i = 20; i <= 160; i *= 2 ) { + Init(i); +} + +Q = null; +MTrans = null; +MQube = null; +I = null; +Origin = null; +Testing = null; +LoopTime = null; +DisplArea = null; + diff --git a/Jint.Tests.CommonScripts/Scripts/3d-morph.js b/Jint.Tests.CommonScripts/Scripts/3d-morph.js new file mode 100644 index 0000000000..0043b319e9 --- /dev/null +++ b/Jint.Tests.CommonScripts/Scripts/3d-morph.js @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +var loops = 15 +var nx = 120 +var nz = 120 + +function morph(a, f) { + var PI2nx = Math.PI * 8/nx + var sin = Math.sin + var f30 = -(50 * sin(f*Math.PI*2)) + + for (var i = 0; i < nz; ++i) { + for (var j = 0; j < nx; ++j) { + a[3*(i*nx+j)+1] = sin((j-1) * PI2nx ) * -f30 + } + } +} + + +var a = Array() +for (var i=0; i < nx*nz*3; ++i) + a[i] = 0 + +for (var i = 0; i < loops; ++i) { + morph(a, i/loops) +} + +testOutput = 0; +for (var i = 0; i < nx; i++) + testOutput += a[3*(i*nx+i)+1]; +a = null; + +// This has to be an approximate test since ECMAscript doesn't formally specify +// what sin() returns. Even if it did specify something like for example what Java 7 +// says - that sin() has to return a value within 1 ulp of exact - then we still +// would not be able to do an exact test here since that would allow for just enough +// low-bit slop to create possibly big errors due to testOutput being a sum. +var epsilon = 1e-13; +if (Math.abs(testOutput) >= epsilon) + throw "Error: bad test output: expected magnitude below " + epsilon + " but got " + testOutput; diff --git a/Jint.Tests.CommonScripts/Scripts/3d-raytrace.js b/Jint.Tests.CommonScripts/Scripts/3d-raytrace.js new file mode 100644 index 0000000000..a7edf7f1f8 --- /dev/null +++ b/Jint.Tests.CommonScripts/Scripts/3d-raytrace.js @@ -0,0 +1,447 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +function createVector(x,y,z) { + return new Array(x,y,z); +} + +function sqrLengthVector(self) { + return self[0] * self[0] + self[1] * self[1] + self[2] * self[2]; +} + +function lengthVector(self) { + return Math.sqrt(self[0] * self[0] + self[1] * self[1] + self[2] * self[2]); +} + +function addVector(self, v) { + self[0] += v[0]; + self[1] += v[1]; + self[2] += v[2]; + return self; +} + +function subVector(self, v) { + self[0] -= v[0]; + self[1] -= v[1]; + self[2] -= v[2]; + return self; +} + +function scaleVector(self, scale) { + self[0] *= scale; + self[1] *= scale; + self[2] *= scale; + return self; +} + +function normaliseVector(self) { + var len = Math.sqrt(self[0] * self[0] + self[1] * self[1] + self[2] * self[2]); + self[0] /= len; + self[1] /= len; + self[2] /= len; + return self; +} + +function add(v1, v2) { + return new Array(v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]); +} + +function sub(v1, v2) { + return new Array(v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2]); +} + +function scalev(v1, v2) { + return new Array(v1[0] * v2[0], v1[1] * v2[1], v1[2] * v2[2]); +} + +function dot(v1, v2) { + return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; +} + +function scale(v, scale) { + return [v[0] * scale, v[1] * scale, v[2] * scale]; +} + +function cross(v1, v2) { + return [v1[1] * v2[2] - v1[2] * v2[1], + v1[2] * v2[0] - v1[0] * v2[2], + v1[0] * v2[1] - v1[1] * v2[0]]; + +} + +function normalise(v) { + var len = lengthVector(v); + return [v[0] / len, v[1] / len, v[2] / len]; +} + +function transformMatrix(self, v) { + var vals = self; + var x = vals[0] * v[0] + vals[1] * v[1] + vals[2] * v[2] + vals[3]; + var y = vals[4] * v[0] + vals[5] * v[1] + vals[6] * v[2] + vals[7]; + var z = vals[8] * v[0] + vals[9] * v[1] + vals[10] * v[2] + vals[11]; + return [x, y, z]; +} + +function invertMatrix(self) { + var temp = new Array(16); + var tx = -self[3]; + var ty = -self[7]; + var tz = -self[11]; + for (h = 0; h < 3; h++) + for (v = 0; v < 3; v++) + temp[h + v * 4] = self[v + h * 4]; + for (i = 0; i < 11; i++) + self[i] = temp[i]; + self[3] = tx * self[0] + ty * self[1] + tz * self[2]; + self[7] = tx * self[4] + ty * self[5] + tz * self[6]; + self[11] = tx * self[8] + ty * self[9] + tz * self[10]; + return self; +} + + +// Triangle intersection using barycentric coord method +function Triangle(p1, p2, p3) { + var edge1 = sub(p3, p1); + var edge2 = sub(p2, p1); + var normal = cross(edge1, edge2); + if (Math.abs(normal[0]) > Math.abs(normal[1])) + if (Math.abs(normal[0]) > Math.abs(normal[2])) + this.axis = 0; + else + this.axis = 2; + else + if (Math.abs(normal[1]) > Math.abs(normal[2])) + this.axis = 1; + else + this.axis = 2; + var u = (this.axis + 1) % 3; + var v = (this.axis + 2) % 3; + var u1 = edge1[u]; + var v1 = edge1[v]; + + var u2 = edge2[u]; + var v2 = edge2[v]; + this.normal = normalise(normal); + this.nu = normal[u] / normal[this.axis]; + this.nv = normal[v] / normal[this.axis]; + this.nd = dot(normal, p1) / normal[this.axis]; + var det = u1 * v2 - v1 * u2; + this.eu = p1[u]; + this.ev = p1[v]; + this.nu1 = u1 / det; + this.nv1 = -v1 / det; + this.nu2 = v2 / det; + this.nv2 = -u2 / det; + this.material = [0.7, 0.7, 0.7]; +} + +Triangle.prototype.intersect = function(orig, dir, near, far) { + var u = (this.axis + 1) % 3; + var v = (this.axis + 2) % 3; + var d = dir[this.axis] + this.nu * dir[u] + this.nv * dir[v]; + var t = (this.nd - orig[this.axis] - this.nu * orig[u] - this.nv * orig[v]) / d; + if (t < near || t > far) + return null; + var Pu = orig[u] + t * dir[u] - this.eu; + var Pv = orig[v] + t * dir[v] - this.ev; + var a2 = Pv * this.nu1 + Pu * this.nv1; + if (a2 < 0) + return null; + var a3 = Pu * this.nu2 + Pv * this.nv2; + if (a3 < 0) + return null; + + if ((a2 + a3) > 1) + return null; + return t; +} + +function Scene(a_triangles) { + this.triangles = a_triangles; + this.lights = []; + this.ambient = [0,0,0]; + this.background = [0.8,0.8,1]; +} +var zero = new Array(0,0,0); + +Scene.prototype.intersect = function(origin, dir, near, far) { + var closest = null; + for (i = 0; i < this.triangles.length; i++) { + var triangle = this.triangles[i]; + var d = triangle.intersect(origin, dir, near, far); + if (d == null || d > far || d < near) + continue; + far = d; + closest = triangle; + } + + if (!closest) + return [this.background[0],this.background[1],this.background[2]]; + + var normal = closest.normal; + var hit = add(origin, scale(dir, far)); + if (dot(dir, normal) > 0) + normal = [-normal[0], -normal[1], -normal[2]]; + + var colour = null; + if (closest.shader) { + colour = closest.shader(closest, hit, dir); + } else { + colour = closest.material; + } + + // do reflection + var reflected = null; + if (colour.reflection > 0.001) { + var reflection = addVector(scale(normal, -2*dot(dir, normal)), dir); + reflected = this.intersect(hit, reflection, 0.0001, 1000000); + if (colour.reflection >= 0.999999) + return reflected; + } + + var l = [this.ambient[0], this.ambient[1], this.ambient[2]]; + for (var i = 0; i < this.lights.length; i++) { + var light = this.lights[i]; + var toLight = sub(light, hit); + var distance = lengthVector(toLight); + scaleVector(toLight, 1.0/distance); + distance -= 0.0001; + if (this.blocked(hit, toLight, distance)) + continue; + var nl = dot(normal, toLight); + if (nl > 0) + addVector(l, scale(light.colour, nl)); + } + l = scalev(l, colour); + if (reflected) { + l = addVector(scaleVector(l, 1 - colour.reflection), scaleVector(reflected, colour.reflection)); + } + return l; +} + +Scene.prototype.blocked = function(O, D, far) { + var near = 0.0001; + var closest = null; + for (i = 0; i < this.triangles.length; i++) { + var triangle = this.triangles[i]; + var d = triangle.intersect(O, D, near, far); + if (d == null || d > far || d < near) + continue; + return true; + } + + return false; +} + + +// this camera code is from notes i made ages ago, it is from *somewhere* -- i cannot remember where +// that somewhere is +function Camera(origin, lookat, up) { + var zaxis = normaliseVector(subVector(lookat, origin)); + var xaxis = normaliseVector(cross(up, zaxis)); + var yaxis = normaliseVector(cross(xaxis, subVector([0,0,0], zaxis))); + var m = new Array(16); + m[0] = xaxis[0]; m[1] = xaxis[1]; m[2] = xaxis[2]; + m[4] = yaxis[0]; m[5] = yaxis[1]; m[6] = yaxis[2]; + m[8] = zaxis[0]; m[9] = zaxis[1]; m[10] = zaxis[2]; + invertMatrix(m); + m[3] = 0; m[7] = 0; m[11] = 0; + this.origin = origin; + this.directions = new Array(4); + this.directions[0] = normalise([-0.7, 0.7, 1]); + this.directions[1] = normalise([ 0.7, 0.7, 1]); + this.directions[2] = normalise([ 0.7, -0.7, 1]); + this.directions[3] = normalise([-0.7, -0.7, 1]); + this.directions[0] = transformMatrix(m, this.directions[0]); + this.directions[1] = transformMatrix(m, this.directions[1]); + this.directions[2] = transformMatrix(m, this.directions[2]); + this.directions[3] = transformMatrix(m, this.directions[3]); +} + +Camera.prototype.generateRayPair = function(y) { + rays = new Array(new Object(), new Object()); + rays[0].origin = this.origin; + rays[1].origin = this.origin; + rays[0].dir = addVector(scale(this.directions[0], y), scale(this.directions[3], 1 - y)); + rays[1].dir = addVector(scale(this.directions[1], y), scale(this.directions[2], 1 - y)); + return rays; +} + +function renderRows(camera, scene, pixels, width, height, starty, stopy) { + for (var y = starty; y < stopy; y++) { + var rays = camera.generateRayPair(y / height); + for (var x = 0; x < width; x++) { + var xp = x / width; + var origin = addVector(scale(rays[0].origin, xp), scale(rays[1].origin, 1 - xp)); + var dir = normaliseVector(addVector(scale(rays[0].dir, xp), scale(rays[1].dir, 1 - xp))); + var l = scene.intersect(origin, dir); + pixels[y][x] = l; + } + } +} + +Camera.prototype.render = function(scene, pixels, width, height) { + var cam = this; + var row = 0; + renderRows(cam, scene, pixels, width, height, 0, height); +} + + + +function raytraceScene() +{ + var startDate = new Date().getTime(); + var numTriangles = 2 * 6; + var triangles = new Array();//numTriangles); + var tfl = createVector(-10, 10, -10); + var tfr = createVector( 10, 10, -10); + var tbl = createVector(-10, 10, 10); + var tbr = createVector( 10, 10, 10); + var bfl = createVector(-10, -10, -10); + var bfr = createVector( 10, -10, -10); + var bbl = createVector(-10, -10, 10); + var bbr = createVector( 10, -10, 10); + + // cube!!! + // front + var i = 0; + + triangles[i++] = new Triangle(tfl, tfr, bfr); + triangles[i++] = new Triangle(tfl, bfr, bfl); + // back + triangles[i++] = new Triangle(tbl, tbr, bbr); + triangles[i++] = new Triangle(tbl, bbr, bbl); + // triangles[i-1].material = [0.7,0.2,0.2]; + // triangles[i-1].material.reflection = 0.8; + // left + triangles[i++] = new Triangle(tbl, tfl, bbl); + // triangles[i-1].reflection = 0.6; + triangles[i++] = new Triangle(tfl, bfl, bbl); + // triangles[i-1].reflection = 0.6; + // right + triangles[i++] = new Triangle(tbr, tfr, bbr); + triangles[i++] = new Triangle(tfr, bfr, bbr); + // top + triangles[i++] = new Triangle(tbl, tbr, tfr); + triangles[i++] = new Triangle(tbl, tfr, tfl); + // bottom + triangles[i++] = new Triangle(bbl, bbr, bfr); + triangles[i++] = new Triangle(bbl, bfr, bfl); + + //Floor!!!! + var green = createVector(0.0, 0.4, 0.0); + var grey = createVector(0.4, 0.4, 0.4); + grey.reflection = 1.0; + var floorShader = function(tri, pos, view) { + var x = ((pos[0]/32) % 2 + 2) % 2; + var z = ((pos[2]/32 + 0.3) % 2 + 2) % 2; + if (x < 1 != z < 1) { + //in the real world we use the fresnel term... + // var angle = 1-dot(view, tri.normal); + // angle *= angle; + // angle *= angle; + // angle *= angle; + //grey.reflection = angle; + return grey; + } else + return green; + } + var ffl = createVector(-1000, -30, -1000); + var ffr = createVector( 1000, -30, -1000); + var fbl = createVector(-1000, -30, 1000); + var fbr = createVector( 1000, -30, 1000); + triangles[i++] = new Triangle(fbl, fbr, ffr); + triangles[i-1].shader = floorShader; + triangles[i++] = new Triangle(fbl, ffr, ffl); + triangles[i-1].shader = floorShader; + + var _scene = new Scene(triangles); + _scene.lights[0] = createVector(20, 38, -22); + _scene.lights[0].colour = createVector(0.7, 0.3, 0.3); + _scene.lights[1] = createVector(-23, 40, 17); + _scene.lights[1].colour = createVector(0.7, 0.3, 0.3); + _scene.lights[2] = createVector(23, 20, 17); + _scene.lights[2].colour = createVector(0.7, 0.7, 0.7); + _scene.ambient = createVector(0.1, 0.1, 0.1); + // _scene.background = createVector(0.7, 0.7, 1.0); + + var size = 30; + var pixels = new Array(); + for (var y = 0; y < size; y++) { + pixels[y] = new Array(); + for (var x = 0; x < size; x++) { + pixels[y][x] = 0; + } + } + + var _camera = new Camera(createVector(-40, 40, 40), createVector(0, 0, 0), createVector(0, 1, 0)); + _camera.render(_scene, pixels, size, size); + + return pixels; +} + +function arrayToCanvasCommands(pixels) +{ + var s = '\nvar pixels = ['; + var size = 30; + for (var y = 0; y < size; y++) { + s += "["; + for (var x = 0; x < size; x++) { + s += "[" + pixels[y][x] + "],"; + } + s+= "],"; + } + s += '];\n var canvas = document.getElementById("renderCanvas").getContext("2d");\n\ +\n\ +\n\ + var size = 30;\n\ + canvas.fillStyle = "red";\n\ + canvas.fillRect(0, 0, size, size);\n\ + canvas.scale(1, -1);\n\ + canvas.translate(0, -size);\n\ +\n\ + if (!canvas.setFillColor)\n\ + canvas.setFillColor = function(r, g, b, a) {\n\ + this.fillStyle = "rgb("+[Math.floor(r * 255), Math.floor(g * 255), Math.floor(b * 255)]+")";\n\ + }\n\ +\n\ +for (var y = 0; y < size; y++) {\n\ + for (var x = 0; x < size; x++) {\n\ + var l = pixels[y][x];\n\ + canvas.setFillColor(l[0], l[1], l[2], 1);\n\ + canvas.fillRect(x, y, 1, 1);\n\ + }\n\ +}'; + + return s; +} + +testOutput = arrayToCanvasCommands(raytraceScene()); + +var expectedLength = 20970; + +if (testOutput.length != expectedLength) + throw "Error: bad result: expected length " + expectedLength + " but got " + testOutput.length; + diff --git a/Jint.Tests.CommonScripts/Scripts/access-binary-trees.js b/Jint.Tests.CommonScripts/Scripts/access-binary-trees.js new file mode 100644 index 0000000000..80771a8d97 --- /dev/null +++ b/Jint.Tests.CommonScripts/Scripts/access-binary-trees.js @@ -0,0 +1,54 @@ +/* The Great Computer Language Shootout + http://shootout.alioth.debian.org/ + contributed by Isaac Gouy */ + +function TreeNode(left,right,item){ + this.left = left; + this.right = right; + this.item = item; +} + +TreeNode.prototype.itemCheck = function(){ + if (this.left==null) return this.item; + else return this.item + this.left.itemCheck() - this.right.itemCheck(); +} + +function bottomUpTree(item,depth){ + if (depth>0){ + return new TreeNode( + bottomUpTree(2*item-1, depth-1) + ,bottomUpTree(2*item, depth-1) + ,item + ); + } + else { + return new TreeNode(null,null,item); + } +} + +var ret = 0; + +for ( var n = 4; n <= 7; n += 1 ) { + var minDepth = 4; + var maxDepth = Math.max(minDepth + 2, n); + var stretchDepth = maxDepth + 1; + + var check = bottomUpTree(0,stretchDepth).itemCheck(); + + var longLivedTree = bottomUpTree(0,maxDepth); + for (var depth=minDepth; depth<=maxDepth; depth+=2){ + var iterations = 1 << (maxDepth - depth + minDepth); + + check = 0; + for (var i=1; i<=iterations; i++){ + check += bottomUpTree(i,depth).itemCheck(); + check += bottomUpTree(-i,depth).itemCheck(); + } + } + + ret += longLivedTree.itemCheck(); +} + +var expected = -4; +if (ret != expected) + throw "ERROR: bad result: expected " + expected + " but got " + ret; \ No newline at end of file diff --git a/Jint.Tests.CommonScripts/Scripts/access-fannkuch.js b/Jint.Tests.CommonScripts/Scripts/access-fannkuch.js new file mode 100644 index 0000000000..5c62d570f9 --- /dev/null +++ b/Jint.Tests.CommonScripts/Scripts/access-fannkuch.js @@ -0,0 +1,70 @@ +/* The Great Computer Language Shootout + http://shootout.alioth.debian.org/ + contributed by Isaac Gouy */ + +function fannkuch(n) { + var check = 0; + var perm = Array(n); + var perm1 = Array(n); + var count = Array(n); + var maxPerm = Array(n); + var maxFlipsCount = 0; + var m = n - 1; + + for (var i = 0; i < n; i++) perm1[i] = i; + var r = n; + + while (true) { + // write-out the first 30 permutations + if (check < 30){ + var s = ""; + for(var i=0; i> 1; + for (var i = 0; i < k2; i++) { + var temp = perm[i]; perm[i] = perm[k - i]; perm[k - i] = temp; + } + flipsCount++; + } + + if (flipsCount > maxFlipsCount) { + maxFlipsCount = flipsCount; + for (var i = 0; i < n; i++) maxPerm[i] = perm1[i]; + } + } + + while (true) { + if (r == n) return maxFlipsCount; + var perm0 = perm1[0]; + var i = 0; + while (i < r) { + var j = i + 1; + perm1[i] = perm1[j]; + i = j; + } + perm1[r] = perm0; + + count[r] = count[r] - 1; + if (count[r] > 0) break; + r++; + } + } +} + +var n = 8; +var ret = fannkuch(n); + +var expected = 22; +if (ret != expected) + throw "ERROR: bad result: expected " + expected + " but got " + ret; + diff --git a/Jint.Tests.CommonScripts/Scripts/access-nbody.js b/Jint.Tests.CommonScripts/Scripts/access-nbody.js new file mode 100644 index 0000000000..7a52358aa7 --- /dev/null +++ b/Jint.Tests.CommonScripts/Scripts/access-nbody.js @@ -0,0 +1,174 @@ +/* The Great Computer Language Shootout + http://shootout.alioth.debian.org/ + contributed by Isaac Gouy */ + +var PI = 3.141592653589793; +var SOLAR_MASS = 4 * PI * PI; +var DAYS_PER_YEAR = 365.24; + +function Body(x,y,z,vx,vy,vz,mass){ + this.x = x; + this.y = y; + this.z = z; + this.vx = vx; + this.vy = vy; + this.vz = vz; + this.mass = mass; +} + +Body.prototype.offsetMomentum = function(px,py,pz) { + this.vx = -px / SOLAR_MASS; + this.vy = -py / SOLAR_MASS; + this.vz = -pz / SOLAR_MASS; + return this; +} + +function Jupiter(){ + return new Body( + 4.84143144246472090e+00, + -1.16032004402742839e+00, + -1.03622044471123109e-01, + 1.66007664274403694e-03 * DAYS_PER_YEAR, + 7.69901118419740425e-03 * DAYS_PER_YEAR, + -6.90460016972063023e-05 * DAYS_PER_YEAR, + 9.54791938424326609e-04 * SOLAR_MASS + ); +} + +function Saturn(){ + return new Body( + 8.34336671824457987e+00, + 4.12479856412430479e+00, + -4.03523417114321381e-01, + -2.76742510726862411e-03 * DAYS_PER_YEAR, + 4.99852801234917238e-03 * DAYS_PER_YEAR, + 2.30417297573763929e-05 * DAYS_PER_YEAR, + 2.85885980666130812e-04 * SOLAR_MASS + ); +} + +function Uranus(){ + return new Body( + 1.28943695621391310e+01, + -1.51111514016986312e+01, + -2.23307578892655734e-01, + 2.96460137564761618e-03 * DAYS_PER_YEAR, + 2.37847173959480950e-03 * DAYS_PER_YEAR, + -2.96589568540237556e-05 * DAYS_PER_YEAR, + 4.36624404335156298e-05 * SOLAR_MASS + ); +} + +function Neptune(){ + return new Body( + 1.53796971148509165e+01, + -2.59193146099879641e+01, + 1.79258772950371181e-01, + 2.68067772490389322e-03 * DAYS_PER_YEAR, + 1.62824170038242295e-03 * DAYS_PER_YEAR, + -9.51592254519715870e-05 * DAYS_PER_YEAR, + 5.15138902046611451e-05 * SOLAR_MASS + ); +} + +function Sun(){ + return new Body(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, SOLAR_MASS); +} + + +function NBodySystem(bodies){ + this.bodies = bodies; + var px = 0.0; + var py = 0.0; + var pz = 0.0; + var size = this.bodies.length; + for (var i=0; i0){ + for (var i=1; i<=prefixWidth; i++) s = " " + s; + } + return s; +} + +function nsieve(m, isPrime){ + var i, k, count; + + for (i=2; i<=m; i++) { isPrime[i] = true; } + count = 0; + + for (i=2; i<=m; i++){ + if (isPrime[i]) { + for (k=i+i; k<=m; k+=i) isPrime[k] = false; + count++; + } + } + return count; +} + +function sieve() { + var sum = 0; + for (var i = 1; i <= 3; i++ ) { + var m = (1<> ((b << 1) & 14)); +c += 3 & (bi3b >> ((b >> 2) & 14)); +c += 3 & (bi3b >> ((b >> 5) & 6)); +return c; + +/* +lir4,0xE994; 9 instructions, no memory access, minimal register dependence, 6 shifts, 2 adds, 1 inline assign +rlwinmr5,r3,1,28,30 +rlwinmr6,r3,30,28,30 +rlwinmr7,r3,27,29,30 +rlwnmr8,r4,r5,30,31 +rlwnmr9,r4,r6,30,31 +rlwnmr10,r4,r7,30,31 +addr3,r8,r9 +addr3,r3,r10 +*/ +} + + +function TimeFunc(func) { +var x, y, t; +var sum = 0; +for(var x=0; x<500; x++) +for(var y=0; y<256; y++) sum += func(y); +return sum; +} + +sum = TimeFunc(fast3bitlookup); + +var expected = 512000; +if (sum != expected) + throw "ERROR: bad result: expected " + expected + " but got " + sum; diff --git a/Jint.Tests.CommonScripts/Scripts/bitops-bits-in-byte.js b/Jint.Tests.CommonScripts/Scripts/bitops-bits-in-byte.js new file mode 100644 index 0000000000..208d5f7d7e --- /dev/null +++ b/Jint.Tests.CommonScripts/Scripts/bitops-bits-in-byte.js @@ -0,0 +1,30 @@ +// Copyright (c) 2004 by Arthur Langereis (arthur_ext at domain xfinitegames, tld com) + + +var result = 0; + +// 1 op = 2 assigns, 16 compare/branches, 8 ANDs, (0-8) ADDs, 8 SHLs +// O(n) +function bitsinbyte(b) { +var m = 1, c = 0; +while(m<0x100) { +if(b & m) c++; +m <<= 1; +} +return c; +} + +function TimeFunc(func) { +var x, y, t; +var sum = 0; +for(var x=0; x<350; x++) +for(var y=0; y<256; y++) sum += func(y); +return sum; +} + +result = TimeFunc(bitsinbyte); + +var expected = 358400; +if (result != expected) + throw "ERROR: bad result: expected " + expected + " but got " + result; + diff --git a/Jint.Tests.CommonScripts/Scripts/bitops-bitwise-and.js b/Jint.Tests.CommonScripts/Scripts/bitops-bitwise-and.js new file mode 100644 index 0000000000..bc74b22103 --- /dev/null +++ b/Jint.Tests.CommonScripts/Scripts/bitops-bitwise-and.js @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +bitwiseAndValue = 4294967296; +for (var i = 0; i < 600000; i++) + bitwiseAndValue = bitwiseAndValue & i; + +var result = bitwiseAndValue; + +var expected = 0; +if (result != expected) + throw "ERROR: bad result: expected " + expected + " but got " + result; + diff --git a/Jint.Tests.CommonScripts/Scripts/bitops-nsieve-bits.js b/Jint.Tests.CommonScripts/Scripts/bitops-nsieve-bits.js new file mode 100644 index 0000000000..dc6051b32e --- /dev/null +++ b/Jint.Tests.CommonScripts/Scripts/bitops-nsieve-bits.js @@ -0,0 +1,42 @@ +// The Great Computer Language Shootout +// http://shootout.alioth.debian.org +// +// Contributed by Ian Osgood + +function pad(n,width) { + var s = n.toString(); + while (s.length < width) s = ' ' + s; + return s; +} + +function primes(isPrime, n) { + var i, count = 0, m = 10000<>5; + + for (i=0; i>5] & 1<<(i&31)) { + for (var j=i+i; j>5] &= ~(1<<(j&31)); + count++; + } +} + +function sieve() { + for (var i = 4; i <= 4; i++) { + var isPrime = new Array((10000<>5); + primes(isPrime, i); + } + return isPrime; +} + +var result = sieve(); + +var sum = 0; +for (var i = 0; i < result.length; ++i) + sum += result[i]; + +var expected = -1286749544853; +if (sum != expected) + throw "ERROR: bad result: expected " + expected + " but got " + sum; + diff --git a/Jint.Tests.CommonScripts/Scripts/controlflow-recursive.js b/Jint.Tests.CommonScripts/Scripts/controlflow-recursive.js new file mode 100644 index 0000000000..718c765332 --- /dev/null +++ b/Jint.Tests.CommonScripts/Scripts/controlflow-recursive.js @@ -0,0 +1,32 @@ +// The Computer Language Shootout +// http://shootout.alioth.debian.org/ +// contributed by Isaac Gouy + +function ack(m,n){ + if (m==0) { return n+1; } + if (n==0) { return ack(m-1,1); } + return ack(m-1, ack(m,n-1) ); +} + +function fib(n) { + if (n < 2){ return 1; } + return fib(n-2) + fib(n-1); +} + +function tak(x,y,z) { + if (y >= x) return z; + return tak(tak(x-1,y,z), tak(y-1,z,x), tak(z-1,x,y)); +} + +var result = 0; + +for ( var i = 3; i <= 5; i++ ) { + result += ack(3,i); + result += fib(17.0+i); + result += tak(3*i+3,2*i+2,i+1); +} + +var expected = 57775; +if (result != expected) + throw "ERROR: bad result: expected " + expected + " but got " + result; + diff --git a/Jint.Tests.CommonScripts/Scripts/crypto-aes.js b/Jint.Tests.CommonScripts/Scripts/crypto-aes.js new file mode 100644 index 0000000000..a7d527b831 --- /dev/null +++ b/Jint.Tests.CommonScripts/Scripts/crypto-aes.js @@ -0,0 +1,426 @@ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +/* + * AES Cipher function: encrypt 'input' with Rijndael algorithm + * + * takes byte-array 'input' (16 bytes) + * 2D byte-array key schedule 'w' (Nr+1 x Nb bytes) + * + * applies Nr rounds (10/12/14) using key schedule w for 'add round key' stage + * + * returns byte-array encrypted value (16 bytes) + */ +function Cipher(input, w) { // main Cipher function [§5.1] + var Nb = 4; // block size (in words): no of columns in state (fixed at 4 for AES) + var Nr = w.length/Nb - 1; // no of rounds: 10/12/14 for 128/192/256-bit keys + + var state = [[],[],[],[]]; // initialise 4xNb byte-array 'state' with input [§3.4] + for (var i=0; i<4*Nb; i++) state[i%4][Math.floor(i/4)] = input[i]; + + state = AddRoundKey(state, w, 0, Nb); + + for (var round=1; round 6 && i%Nk == 4) { + temp = SubWord(temp); + } + for (var t=0; t<4; t++) w[i][t] = w[i-Nk][t] ^ temp[t]; + } + + return w; +} + +function SubWord(w) { // apply SBox to 4-byte word w + for (var i=0; i<4; i++) w[i] = Sbox[w[i]]; + return w; +} + +function RotWord(w) { // rotate 4-byte word w left by one byte + w[4] = w[0]; + for (var i=0; i<4; i++) w[i] = w[i+1]; + return w; +} + + +// Sbox is pre-computed multiplicative inverse in GF(2^8) used in SubBytes and KeyExpansion [§5.1.1] +var Sbox = [0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76, + 0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0, + 0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15, + 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75, + 0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84, + 0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf, + 0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8, + 0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2, + 0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73, + 0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb, + 0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79, + 0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08, + 0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a, + 0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e, + 0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf, + 0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16]; + +// Rcon is Round Constant used for the Key Expansion [1st col is 2^(r-1) in GF(2^8)] [§5.2] +var Rcon = [ [0x00, 0x00, 0x00, 0x00], + [0x01, 0x00, 0x00, 0x00], + [0x02, 0x00, 0x00, 0x00], + [0x04, 0x00, 0x00, 0x00], + [0x08, 0x00, 0x00, 0x00], + [0x10, 0x00, 0x00, 0x00], + [0x20, 0x00, 0x00, 0x00], + [0x40, 0x00, 0x00, 0x00], + [0x80, 0x00, 0x00, 0x00], + [0x1b, 0x00, 0x00, 0x00], + [0x36, 0x00, 0x00, 0x00] ]; + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +/* + * Use AES to encrypt 'plaintext' with 'password' using 'nBits' key, in 'Counter' mode of operation + * - see http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + * for each block + * - outputblock = cipher(counter, key) + * - cipherblock = plaintext xor outputblock + */ +function AESEncryptCtr(plaintext, password, nBits) { + if (!(nBits==128 || nBits==192 || nBits==256)) return ''; // standard allows 128/192/256 bit keys + + // for this example script, generate the key by applying Cipher to 1st 16/24/32 chars of password; + // for real-world applications, a more secure approach would be to hash the password e.g. with SHA-1 + var nBytes = nBits/8; // no bytes in key + var pwBytes = new Array(nBytes); + for (var i=0; i>> i*8) & 0xff; + for (var i=0; i<4; i++) counterBlock[i+4] = (nonce/0x100000000 >>> i*8) & 0xff; + + // generate key schedule - an expansion of the key into distinct Key Rounds for each round + var keySchedule = KeyExpansion(key); + + var blockCount = Math.ceil(plaintext.length/blockSize); + var ciphertext = new Array(blockCount); // ciphertext as array of strings + + for (var b=0; b>> c*8) & 0xff; + for (var c=0; c<4; c++) counterBlock[15-c-4] = (b/0x100000000 >>> c*8) + + var cipherCntr = Cipher(counterBlock, keySchedule); // -- encrypt counter block -- + + // calculate length of final block: + var blockLength = b>> c*8) & 0xff; + for (var c=0; c<4; c++) counterBlock[15-c-4] = ((b/0x100000000-1) >>> c*8) & 0xff; + + var cipherCntr = Cipher(counterBlock, keySchedule); // encrypt counter block + + ciphertext[b] = unescCtrlChars(ciphertext[b]); + + var pt = ''; + for (var i=0; i>18 & 0x3f; + h2 = bits>>12 & 0x3f; + h3 = bits>>6 & 0x3f; + h4 = bits & 0x3f; + + // end of string? index to '=' in b64 + if (isNaN(o3)) h4 = 64; + if (isNaN(o2)) h3 = 64; + + // use hexets to index into b64, and append result to encoded string + enc += b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4); + } while (i < str.length); + + return enc; +} + +function decodeBase64(str) { + var o1, o2, o3, h1, h2, h3, h4, bits, i=0, enc=''; + + do { // unpack four hexets into three octets using index points in b64 + h1 = b64.indexOf(str.charAt(i++)); + h2 = b64.indexOf(str.charAt(i++)); + h3 = b64.indexOf(str.charAt(i++)); + h4 = b64.indexOf(str.charAt(i++)); + + bits = h1<<18 | h2<<12 | h3<<6 | h4; + + o1 = bits>>16 & 0xff; + o2 = bits>>8 & 0xff; + o3 = bits & 0xff; + + if (h3 == 64) enc += String.fromCharCode(o1); + else if (h4 == 64) enc += String.fromCharCode(o1, o2); + else enc += String.fromCharCode(o1, o2, o3); + } while (i < str.length); + + return decodeUTF8(enc); // decode UTF-8 byte-array back to Unicode +} + +function encodeUTF8(str) { // encode multi-byte string into utf-8 multiple single-byte characters + str = str.replace( + /[\u0080-\u07ff]/g, // U+0080 - U+07FF = 2-byte chars + function(c) { + var cc = c.charCodeAt(0); + return String.fromCharCode(0xc0 | cc>>6, 0x80 | cc&0x3f); } + ); + str = str.replace( + /[\u0800-\uffff]/g, // U+0800 - U+FFFF = 3-byte chars + function(c) { + var cc = c.charCodeAt(0); + return String.fromCharCode(0xe0 | cc>>12, 0x80 | cc>>6&0x3F, 0x80 | cc&0x3f); } + ); + return str; +} + +function decodeUTF8(str) { // decode utf-8 encoded string back into multi-byte characters + str = str.replace( + /[\u00c0-\u00df][\u0080-\u00bf]/g, // 2-byte chars + function(c) { + var cc = (c.charCodeAt(0)&0x1f)<<6 | c.charCodeAt(1)&0x3f; + return String.fromCharCode(cc); } + ); + str = str.replace( + /[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g, // 3-byte chars + function(c) { + var cc = (c.charCodeAt(0)&0x0f)<<12 | (c.charCodeAt(1)&0x3f<<6) | c.charCodeAt(2)&0x3f; + return String.fromCharCode(cc); } + ); + return str; +} + + +function byteArrayToHexStr(b) { // convert byte array to hex string for displaying test vectors + var s = ''; + for (var i=0; i> 5] |= 0x80 << ((len) % 32); + x[(((len + 64) >>> 9) << 4) + 14] = len; + + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + + for(var i = 0; i < x.length; i += 16) + { + var olda = a; + var oldb = b; + var oldc = c; + var oldd = d; + + a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); + d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); + c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); + b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); + a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); + d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); + c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); + b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); + a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); + d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); + c = md5_ff(c, d, a, b, x[i+10], 17, -42063); + b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); + a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); + d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); + c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); + b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); + + a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); + d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); + c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); + b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); + a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); + d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); + c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); + b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); + a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); + d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); + c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); + b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); + a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); + d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); + c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); + b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); + + a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); + d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); + c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); + b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); + a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); + d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); + c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); + b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); + a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); + d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); + c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); + b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); + a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); + d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); + c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); + b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); + + a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); + d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); + c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); + b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); + a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); + d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); + c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); + b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); + a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); + d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); + c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); + b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); + a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); + d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); + c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); + b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); + + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + } + return Array(a, b, c, d); + +} + +/* + * These functions implement the four basic operations the algorithm uses. + */ +function md5_cmn(q, a, b, x, s, t) +{ + return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); +} +function md5_ff(a, b, c, d, x, s, t) +{ + return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); +} +function md5_gg(a, b, c, d, x, s, t) +{ + return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); +} +function md5_hh(a, b, c, d, x, s, t) +{ + return md5_cmn(b ^ c ^ d, a, b, x, s, t); +} +function md5_ii(a, b, c, d, x, s, t) +{ + return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); +} + +/* + * Calculate the HMAC-MD5, of a key and some data + */ +function core_hmac_md5(key, data) +{ + var bkey = str2binl(key); + if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz); + + var ipad = Array(16), opad = Array(16); + for(var i = 0; i < 16; i++) + { + ipad[i] = bkey[i] ^ 0x36363636; + opad[i] = bkey[i] ^ 0x5C5C5C5C; + } + + var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz); + return core_md5(opad.concat(hash), 512 + 128); +} + +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ +function safe_add(x, y) +{ + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +} + +/* + * Bitwise rotate a 32-bit number to the left. + */ +function bit_rol(num, cnt) +{ + return (num << cnt) | (num >>> (32 - cnt)); +} + +/* + * Convert a string to an array of little-endian words + * If chrsz is ASCII, characters >255 have their hi-byte silently ignored. + */ +function str2binl(str) +{ + var bin = Array(); + var mask = (1 << chrsz) - 1; + for(var i = 0; i < str.length * chrsz; i += chrsz) + bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32); + return bin; +} + +/* + * Convert an array of little-endian words to a string + */ +function binl2str(bin) +{ + var str = ""; + var mask = (1 << chrsz) - 1; + for(var i = 0; i < bin.length * 32; i += chrsz) + str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask); + return str; +} + +/* + * Convert an array of little-endian words to a hex string. + */ +function binl2hex(binarray) +{ + var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; + var str = ""; + for(var i = 0; i < binarray.length * 4; i++) + { + str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) + + hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF); + } + return str; +} + +/* + * Convert an array of little-endian words to a base-64 string + */ +function binl2b64(binarray) +{ + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var str = ""; + for(var i = 0; i < binarray.length * 4; i += 3) + { + var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16) + | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 ) + | ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF); + for(var j = 0; j < 4; j++) + { + if(i * 8 + j * 6 > binarray.length * 32) str += b64pad; + else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); + } + } + return str; +} + +var plainText = "Rebellious subjects, enemies to peace,\n\ +Profaners of this neighbour-stained steel,--\n\ +Will they not hear? What, ho! you men, you beasts,\n\ +That quench the fire of your pernicious rage\n\ +With purple fountains issuing from your veins,\n\ +On pain of torture, from those bloody hands\n\ +Throw your mistemper'd weapons to the ground,\n\ +And hear the sentence of your moved prince.\n\ +Three civil brawls, bred of an airy word,\n\ +By thee, old Capulet, and Montague,\n\ +Have thrice disturb'd the quiet of our streets,\n\ +And made Verona's ancient citizens\n\ +Cast by their grave beseeming ornaments,\n\ +To wield old partisans, in hands as old,\n\ +Canker'd with peace, to part your canker'd hate:\n\ +If ever you disturb our streets again,\n\ +Your lives shall pay the forfeit of the peace.\n\ +For this time, all the rest depart away:\n\ +You Capulet; shall go along with me:\n\ +And, Montague, come you this afternoon,\n\ +To know our further pleasure in this case,\n\ +To old Free-town, our common judgment-place.\n\ +Once more, on pain of death, all men depart." + +for (var i = 0; i <4; i++) { + plainText += plainText; +} + +var md5Output = hex_md5(plainText); + +var expected = "a831e91e0f70eddcb70dc61c6f82f6cd"; + +if (md5Output != expected) + throw "ERROR: bad result: expected " + expected + " but got " + md5Output; + diff --git a/Jint.Tests.CommonScripts/Scripts/crypto-sha1.js b/Jint.Tests.CommonScripts/Scripts/crypto-sha1.js new file mode 100644 index 0000000000..7301e9ec40 --- /dev/null +++ b/Jint.Tests.CommonScripts/Scripts/crypto-sha1.js @@ -0,0 +1,228 @@ +/* + * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined + * in FIPS PUB 180-1 + * Version 2.1a Copyright Paul Johnston 2000 - 2002. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for details. + */ + +/* + * Configurable variables. You may need to tweak these to be compatible with + * the server-side, but the defaults work in most cases. + */ +var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ +var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ +var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ + +/* + * These are the functions you'll usually want to call + * They take string arguments and return either hex or base-64 encoded strings + */ +function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));} +function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz));} +function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));} +function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));} +function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));} +function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));} + +/* + * Perform a simple self-test to see if the VM is working + */ +function sha1_vm_test() +{ + return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d"; +} + +/* + * Calculate the SHA-1 of an array of big-endian words, and a bit length + */ +function core_sha1(x, len) +{ + /* append padding */ + x[len >> 5] |= 0x80 << (24 - len % 32); + x[((len + 64 >> 9) << 4) + 15] = len; + + var w = Array(80); + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + var e = -1009589776; + + for(var i = 0; i < x.length; i += 16) + { + var olda = a; + var oldb = b; + var oldc = c; + var oldd = d; + var olde = e; + + for(var j = 0; j < 80; j++) + { + if(j < 16) w[j] = x[i + j]; + else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1); + var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), + safe_add(safe_add(e, w[j]), sha1_kt(j))); + e = d; + d = c; + c = rol(b, 30); + b = a; + a = t; + } + + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + e = safe_add(e, olde); + } + return Array(a, b, c, d, e); + +} + +/* + * Perform the appropriate triplet combination function for the current + * iteration + */ +function sha1_ft(t, b, c, d) +{ + if(t < 20) return (b & c) | ((~b) & d); + if(t < 40) return b ^ c ^ d; + if(t < 60) return (b & c) | (b & d) | (c & d); + return b ^ c ^ d; +} + +/* + * Determine the appropriate additive constant for the current iteration + */ +function sha1_kt(t) +{ + return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : + (t < 60) ? -1894007588 : -899497514; +} + +/* + * Calculate the HMAC-SHA1 of a key and some data + */ +function core_hmac_sha1(key, data) +{ + var bkey = str2binb(key); + if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz); + + var ipad = Array(16), opad = Array(16); + for(var i = 0; i < 16; i++) + { + ipad[i] = bkey[i] ^ 0x36363636; + opad[i] = bkey[i] ^ 0x5C5C5C5C; + } + + var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz); + return core_sha1(opad.concat(hash), 512 + 160); +} + +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ +function safe_add(x, y) +{ + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +} + +/* + * Bitwise rotate a 32-bit number to the left. + */ +function rol(num, cnt) +{ + return (num << cnt) | (num >>> (32 - cnt)); +} + +/* + * Convert an 8-bit or 16-bit string to an array of big-endian words + * In 8-bit function, characters >255 have their hi-byte silently ignored. + */ +function str2binb(str) +{ + var bin = Array(); + var mask = (1 << chrsz) - 1; + for(var i = 0; i < str.length * chrsz; i += chrsz) + bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32); + return bin; +} + +/* + * Convert an array of big-endian words to a string + */ +function binb2str(bin) +{ + var str = ""; + var mask = (1 << chrsz) - 1; + for(var i = 0; i < bin.length * 32; i += chrsz) + str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask); + return str; +} + +/* + * Convert an array of big-endian words to a hex string. + */ +function binb2hex(binarray) +{ + var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; + var str = ""; + for(var i = 0; i < binarray.length * 4; i++) + { + str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) + + hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF); + } + return str; +} + +/* + * Convert an array of big-endian words to a base-64 string + */ +function binb2b64(binarray) +{ + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var str = ""; + for(var i = 0; i < binarray.length * 4; i += 3) + { + var triplet = (((binarray[i >> 2] >> 8 * (3 - i %4)) & 0xFF) << 16) + | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 ) + | ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF); + for(var j = 0; j < 4; j++) + { + if(i * 8 + j * 6 > binarray.length * 32) str += b64pad; + else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); + } + } + return str; +} + + +var plainText = "Two households, both alike in dignity,\n\ +In fair Verona, where we lay our scene,\n\ +From ancient grudge break to new mutiny,\n\ +Where civil blood makes civil hands unclean.\n\ +From forth the fatal loins of these two foes\n\ +A pair of star-cross'd lovers take their life;\n\ +Whole misadventured piteous overthrows\n\ +Do with their death bury their parents' strife.\n\ +The fearful passage of their death-mark'd love,\n\ +And the continuance of their parents' rage,\n\ +Which, but their children's end, nought could remove,\n\ +Is now the two hours' traffic of our stage;\n\ +The which if you with patient ears attend,\n\ +What here shall miss, our toil shall strive to mend."; + +for (var i = 0; i <4; i++) { + plainText += plainText; +} + +var sha1Output = hex_sha1(plainText); + +var expected = "2524d264def74cce2498bf112bedf00e6c0b796d"; +if (sha1Output != expected) + throw "ERROR: bad result: expected " + expected + " but got " + sha1Output; diff --git a/Jint.Tests.CommonScripts/Scripts/date-format-tofte.js b/Jint.Tests.CommonScripts/Scripts/date-format-tofte.js new file mode 100644 index 0000000000..54126ad7c5 --- /dev/null +++ b/Jint.Tests.CommonScripts/Scripts/date-format-tofte.js @@ -0,0 +1,301 @@ +function arrayExists(array, x) { + for (var i = 0; i < array.length; i++) { + if (array[i] == x) return true; + } + return false; +} + +Date.prototype.formatDate = function (input,time) { + // formatDate : + // a PHP date like function, for formatting date strings + // See: http://www.php.net/date + // + // input : format string + // time : epoch time (seconds, and optional) + // + // if time is not passed, formatting is based on + // the current "this" date object's set time. + // + // supported: + // a, A, B, d, D, F, g, G, h, H, i, j, l (lowercase L), L, + // m, M, n, O, r, s, S, t, U, w, W, y, Y, z + // + // unsupported: + // I (capital i), T, Z + + var switches = ["a", "A", "B", "d", "D", "F", "g", "G", "h", "H", + "i", "j", "l", "L", "m", "M", "n", "O", "r", "s", + "S", "t", "U", "w", "W", "y", "Y", "z"]; + var daysLong = ["Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday"]; + var daysShort = ["Sun", "Mon", "Tue", "Wed", + "Thu", "Fri", "Sat"]; + var monthsShort = ["Jan", "Feb", "Mar", "Apr", + "May", "Jun", "Jul", "Aug", "Sep", + "Oct", "Nov", "Dec"]; + var monthsLong = ["January", "February", "March", "April", + "May", "June", "July", "August", "September", + "October", "November", "December"]; + var daysSuffix = ["st", "nd", "rd", "th", "th", "th", "th", // 1st - 7th + "th", "th", "th", "th", "th", "th", "th", // 8th - 14th + "th", "th", "th", "th", "th", "th", "st", // 15th - 21st + "nd", "rd", "th", "th", "th", "th", "th", // 22nd - 28th + "th", "th", "st"]; // 29th - 31st + + function a() { + // Lowercase Ante meridiem and Post meridiem + return self.getHours() > 11? "pm" : "am"; + } + function A() { + // Uppercase Ante meridiem and Post meridiem + return self.getHours() > 11? "PM" : "AM"; + } + + function B(){ + // Swatch internet time. code simply grabbed from ppk, + // since I was feeling lazy: + // http://www.xs4all.nl/~ppk/js/beat.html + var off = (self.getTimezoneOffset() + 60)*60; + var theSeconds = (self.getHours() * 3600) + + (self.getMinutes() * 60) + + self.getSeconds() + off; + var beat = Math.floor(theSeconds/86.4); + if (beat > 1000) beat -= 1000; + if (beat < 0) beat += 1000; + if ((""+beat).length == 1) beat = "00"+beat; + if ((""+beat).length == 2) beat = "0"+beat; + return beat; + } + + function d() { + // Day of the month, 2 digits with leading zeros + return new String(self.getDate()).length == 1? + "0"+self.getDate() : self.getDate(); + } + function D() { + // A textual representation of a day, three letters + return daysShort[self.getDay()]; + } + function F() { + // A full textual representation of a month + return monthsLong[self.getMonth()]; + } + function g() { + // 12-hour format of an hour without leading zeros + return self.getHours() > 12? self.getHours()-12 : self.getHours(); + } + function G() { + // 24-hour format of an hour without leading zeros + return self.getHours(); + } + function h() { + // 12-hour format of an hour with leading zeros + if (self.getHours() > 12) { + var s = new String(self.getHours()-12); + return s.length == 1? + "0"+ (self.getHours()-12) : self.getHours()-12; + } else { + var s = new String(self.getHours()); + return s.length == 1? + "0"+self.getHours() : self.getHours(); + } + } + function H() { + // 24-hour format of an hour with leading zeros + return new String(self.getHours()).length == 1? + "0"+self.getHours() : self.getHours(); + } + function i() { + // Minutes with leading zeros + return new String(self.getMinutes()).length == 1? + "0"+self.getMinutes() : self.getMinutes(); + } + function j() { + // Day of the month without leading zeros + return self.getDate(); + } + function l() { + // A full textual representation of the day of the week + return daysLong[self.getDay()]; + } + function L() { + // leap year or not. 1 if leap year, 0 if not. + // the logic should match iso's 8601 standard. + var y_ = Y(); + if ( + (y_ % 4 == 0 && y_ % 100 != 0) || + (y_ % 4 == 0 && y_ % 100 == 0 && y_ % 400 == 0) + ) { + return 1; + } else { + return 0; + } + } + function m() { + // Numeric representation of a month, with leading zeros + return self.getMonth() < 9? + "0"+(self.getMonth()+1) : + self.getMonth()+1; + } + function M() { + // A short textual representation of a month, three letters + return monthsShort[self.getMonth()]; + } + function n() { + // Numeric representation of a month, without leading zeros + return self.getMonth()+1; + } + function O() { + // Difference to Greenwich time (GMT) in hours + var os = Math.abs(self.getTimezoneOffset()); + var h = ""+Math.floor(os/60); + var m = ""+(os%60); + h.length == 1? h = "0"+h:1; + m.length == 1? m = "0"+m:1; + return self.getTimezoneOffset() < 0 ? "+"+h+m : "-"+h+m; + } + function r() { + // RFC 822 formatted date + var r; // result + // Thu , 21 Dec 2000 + r = D() + ", " + j() + " " + M() + " " + Y() + + // 16 : 01 : 07 +0200 + " " + H() + ":" + i() + ":" + s() + " " + O(); + return r; + } + function S() { + // English ordinal suffix for the day of the month, 2 characters + return daysSuffix[self.getDate()-1]; + } + function s() { + // Seconds, with leading zeros + return new String(self.getSeconds()).length == 1? + "0"+self.getSeconds() : self.getSeconds(); + } + function t() { + + // thanks to Matt Bannon for some much needed code-fixes here! + var daysinmonths = [null,31,28,31,30,31,30,31,31,30,31,30,31]; + if (L()==1 && n()==2) return 29; // leap day + return daysinmonths[n()]; + } + function U() { + // Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) + return Math.round(self.getTime()/1000); + } + function W() { + // Weeknumber, as per ISO specification: + // http://www.cl.cam.ac.uk/~mgk25/iso-time.html + + // if the day is three days before newyears eve, + // there's a chance it's "week 1" of next year. + // here we check for that. + var beforeNY = 364+L() - z(); + var afterNY = z(); + var weekday = w()!=0?w()-1:6; // makes sunday (0), into 6. + if (beforeNY <= 2 && weekday <= 2-beforeNY) { + return 1; + } + // similarly, if the day is within threedays of newyears + // there's a chance it belongs in the old year. + var ny = new Date("January 1 " + Y() + " 00:00:00"); + var nyDay = ny.getDay()!=0?ny.getDay()-1:6; + if ( + (afterNY <= 2) && + (nyDay >=4) && + (afterNY >= (6-nyDay)) + ) { + // Since I'm not sure we can just always return 53, + // i call the function here again, using the last day + // of the previous year, as the date, and then just + // return that week. + var prevNY = new Date("December 31 " + (Y()-1) + " 00:00:00"); + return prevNY.formatDate("W"); + } + + // week 1, is the week that has the first thursday in it. + // note that this value is not zero index. + if (nyDay <= 3) { + // first day of the year fell on a thursday, or earlier. + return 1 + Math.floor( ( z() + nyDay ) / 7 ); + } else { + // first day of the year fell on a friday, or later. + return 1 + Math.floor( ( z() - ( 7 - nyDay ) ) / 7 ); + } + } + function w() { + // Numeric representation of the day of the week + return self.getDay(); + } + + function Y() { + // A full numeric representation of a year, 4 digits + + // we first check, if getFullYear is supported. if it + // is, we just use that. ppks code is nice, but wont + // work with dates outside 1900-2038, or something like that + if (self.getFullYear) { + var newDate = new Date("January 1 2001 00:00:00 +0000"); + var x = newDate .getFullYear(); + if (x == 2001) { + // i trust the method now + return self.getFullYear(); + } + } + // else, do this: + // codes thanks to ppk: + // http://www.xs4all.nl/~ppk/js/introdate.html + var x = self.getYear(); + var y = x % 100; + y += (y < 38) ? 2000 : 1900; + return y; + } + function y() { + // A two-digit representation of a year + var y = Y()+""; + return y.substring(y.length-2,y.length); + } + function z() { + // The day of the year, zero indexed! 0 through 366 + var t = new Date("January 1 " + Y() + " 00:00:00"); + var diff = self.getTime() - t.getTime(); + return Math.floor(diff/1000/60/60/24); + } + + var self = this; + if (time) { + // save time + var prevTime = self.getTime(); + self.setTime(time); + } + + var ia = input.split(""); + var ij = 0; + while (ia[ij]) { + if (ia[ij] == "\\") { + // this is our way of allowing users to escape stuff + ia.splice(ij,1); + } else { + if (arrayExists(switches,ia[ij])) { + ia[ij] = eval(ia[ij] + "()"); + } + } + ij++; + } + // reset time, back to what it was + if (prevTime) { + self.setTime(prevTime); + } + return ia.join(""); +} + +var date = new Date("1/1/2007 1:11:11"); + +for (i = 0; i < 500; ++i) { + var shortFormat = date.formatDate("Y-m-d"); + var longFormat = date.formatDate("l, F d, Y g:i:s A"); + date.setTime(date.getTime() + 84266956); +} + +// FIXME: Find a way to validate this test. +// https://bugs.webkit.org/show_bug.cgi?id=114849 diff --git a/Jint.Tests.CommonScripts/Scripts/date-format-xparb.js b/Jint.Tests.CommonScripts/Scripts/date-format-xparb.js new file mode 100644 index 0000000000..0eee7f51bd --- /dev/null +++ b/Jint.Tests.CommonScripts/Scripts/date-format-xparb.js @@ -0,0 +1,420 @@ +/* + * Copyright (C) 2004 Baron Schwartz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, version 2.1. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + */ + +Date.parseFunctions = {count:0}; +Date.parseRegexes = []; +Date.formatFunctions = {count:0}; + +Date.prototype.dateFormat = function(format) { + if (Date.formatFunctions[format] == null) { + Date.createNewFormat(format); + } + var func = Date.formatFunctions[format]; + return this[func](); +} + +Date.createNewFormat = function(format) { + var funcName = "format" + Date.formatFunctions.count++; + Date.formatFunctions[format] = funcName; + var code = "Date.prototype." + funcName + " = function(){return "; + var special = false; + var ch = ''; + for (var i = 0; i < format.length; ++i) { + ch = format.charAt(i); + if (!special && ch == "\\") { + special = true; + } + else if (special) { + special = false; + code += "'" + String.escape(ch) + "' + "; + } + else { + code += Date.getFormatCode(ch); + } + } + eval(code.substring(0, code.length - 3) + ";}"); +} + +Date.getFormatCode = function(character) { + switch (character) { + case "d": + return "String.leftPad(this.getDate(), 2, '0') + "; + case "D": + return "Date.dayNames[this.getDay()].substring(0, 3) + "; + case "j": + return "this.getDate() + "; + case "l": + return "Date.dayNames[this.getDay()] + "; + case "S": + return "this.getSuffix() + "; + case "w": + return "this.getDay() + "; + case "z": + return "this.getDayOfYear() + "; + case "W": + return "this.getWeekOfYear() + "; + case "F": + return "Date.monthNames[this.getMonth()] + "; + case "m": + return "String.leftPad(this.getMonth() + 1, 2, '0') + "; + case "M": + return "Date.monthNames[this.getMonth()].substring(0, 3) + "; + case "n": + return "(this.getMonth() + 1) + "; + case "t": + return "this.getDaysInMonth() + "; + case "L": + return "(this.isLeapYear() ? 1 : 0) + "; + case "Y": + return "this.getFullYear() + "; + case "y": + return "('' + this.getFullYear()).substring(2, 4) + "; + case "a": + return "(this.getHours() < 12 ? 'am' : 'pm') + "; + case "A": + return "(this.getHours() < 12 ? 'AM' : 'PM') + "; + case "g": + return "((this.getHours() %12) ? this.getHours() % 12 : 12) + "; + case "G": + return "this.getHours() + "; + case "h": + return "String.leftPad((this.getHours() %12) ? this.getHours() % 12 : 12, 2, '0') + "; + case "H": + return "String.leftPad(this.getHours(), 2, '0') + "; + case "i": + return "String.leftPad(this.getMinutes(), 2, '0') + "; + case "s": + return "String.leftPad(this.getSeconds(), 2, '0') + "; + case "O": + return "this.getGMTOffset() + "; + case "T": + return "this.getTimezone() + "; + case "Z": + return "(this.getTimezoneOffset() * -60) + "; + default: + return "'" + String.escape(character) + "' + "; + } +} + +Date.parseDate = function(input, format) { + if (Date.parseFunctions[format] == null) { + Date.createParser(format); + } + var func = Date.parseFunctions[format]; + return Date[func](input); +} + +Date.createParser = function(format) { + var funcName = "parse" + Date.parseFunctions.count++; + var regexNum = Date.parseRegexes.length; + var currentGroup = 1; + Date.parseFunctions[format] = funcName; + + var code = "Date." + funcName + " = function(input){\n" + + "var y = -1, m = -1, d = -1, h = -1, i = -1, s = -1;\n" + + "var d = new Date();\n" + + "y = d.getFullYear();\n" + + "m = d.getMonth();\n" + + "d = d.getDate();\n" + + "var results = input.match(Date.parseRegexes[" + regexNum + "]);\n" + + "if (results && results.length > 0) {" + var regex = ""; + + var special = false; + var ch = ''; + for (var i = 0; i < format.length; ++i) { + ch = format.charAt(i); + if (!special && ch == "\\") { + special = true; + } + else if (special) { + special = false; + regex += String.escape(ch); + } + else { + obj = Date.formatCodeToRegex(ch, currentGroup); + currentGroup += obj.g; + regex += obj.s; + if (obj.g && obj.c) { + code += obj.c; + } + } + } + + code += "if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0)\n" + + "{return new Date(y, m, d, h, i, s);}\n" + + "else if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0)\n" + + "{return new Date(y, m, d, h, i);}\n" + + "else if (y > 0 && m >= 0 && d > 0 && h >= 0)\n" + + "{return new Date(y, m, d, h);}\n" + + "else if (y > 0 && m >= 0 && d > 0)\n" + + "{return new Date(y, m, d);}\n" + + "else if (y > 0 && m >= 0)\n" + + "{return new Date(y, m);}\n" + + "else if (y > 0)\n" + + "{return new Date(y);}\n" + + "}return null;}"; + + Date.parseRegexes[regexNum] = new RegExp("^" + regex + "$"); + eval(code); +} + +Date.formatCodeToRegex = function(character, currentGroup) { + switch (character) { + case "D": + return {g:0, + c:null, + s:"(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)"}; + case "j": + case "d": + return {g:1, + c:"d = parseInt(results[" + currentGroup + "], 10);\n", + s:"(\\d{1,2})"}; + case "l": + return {g:0, + c:null, + s:"(?:" + Date.dayNames.join("|") + ")"}; + case "S": + return {g:0, + c:null, + s:"(?:st|nd|rd|th)"}; + case "w": + return {g:0, + c:null, + s:"\\d"}; + case "z": + return {g:0, + c:null, + s:"(?:\\d{1,3})"}; + case "W": + return {g:0, + c:null, + s:"(?:\\d{2})"}; + case "F": + return {g:1, + c:"m = parseInt(Date.monthNumbers[results[" + currentGroup + "].substring(0, 3)], 10);\n", + s:"(" + Date.monthNames.join("|") + ")"}; + case "M": + return {g:1, + c:"m = parseInt(Date.monthNumbers[results[" + currentGroup + "]], 10);\n", + s:"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)"}; + case "n": + case "m": + return {g:1, + c:"m = parseInt(results[" + currentGroup + "], 10) - 1;\n", + s:"(\\d{1,2})"}; + case "t": + return {g:0, + c:null, + s:"\\d{1,2}"}; + case "L": + return {g:0, + c:null, + s:"(?:1|0)"}; + case "Y": + return {g:1, + c:"y = parseInt(results[" + currentGroup + "], 10);\n", + s:"(\\d{4})"}; + case "y": + return {g:1, + c:"var ty = parseInt(results[" + currentGroup + "], 10);\n" + + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n", + s:"(\\d{1,2})"}; + case "a": + return {g:1, + c:"if (results[" + currentGroup + "] == 'am') {\n" + + "if (h == 12) { h = 0; }\n" + + "} else { if (h < 12) { h += 12; }}", + s:"(am|pm)"}; + case "A": + return {g:1, + c:"if (results[" + currentGroup + "] == 'AM') {\n" + + "if (h == 12) { h = 0; }\n" + + "} else { if (h < 12) { h += 12; }}", + s:"(AM|PM)"}; + case "g": + case "G": + case "h": + case "H": + return {g:1, + c:"h = parseInt(results[" + currentGroup + "], 10);\n", + s:"(\\d{1,2})"}; + case "i": + return {g:1, + c:"i = parseInt(results[" + currentGroup + "], 10);\n", + s:"(\\d{2})"}; + case "s": + return {g:1, + c:"s = parseInt(results[" + currentGroup + "], 10);\n", + s:"(\\d{2})"}; + case "O": + return {g:0, + c:null, + s:"[+-]\\d{4}"}; + case "T": + return {g:0, + c:null, + s:"[A-Z]{3}"}; + case "Z": + return {g:0, + c:null, + s:"[+-]\\d{1,5}"}; + default: + return {g:0, + c:null, + s:String.escape(character)}; + } +} + +Date.prototype.getTimezone = function() { + return this.toString().replace( + /^.*? ([A-Z]{3}) [0-9]{4}.*$/, "$1").replace( + /^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/, "$1$2$3"); +} + +Date.prototype.getGMTOffset = function() { + return (this.getTimezoneOffset() > 0 ? "-" : "+") + + String.leftPad(Math.floor(this.getTimezoneOffset() / 60), 2, "0") + + String.leftPad(this.getTimezoneOffset() % 60, 2, "0"); +} + +Date.prototype.getDayOfYear = function() { + var num = 0; + Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28; + for (var i = 0; i < this.getMonth(); ++i) { + num += Date.daysInMonth[i]; + } + return num + this.getDate() - 1; +} + +Date.prototype.getWeekOfYear = function() { + // Skip to Thursday of this week + var now = this.getDayOfYear() + (4 - this.getDay()); + // Find the first Thursday of the year + var jan1 = new Date(this.getFullYear(), 0, 1); + var then = (7 - jan1.getDay() + 4); + document.write(then); + return String.leftPad(((now - then) / 7) + 1, 2, "0"); +} + +Date.prototype.isLeapYear = function() { + var year = this.getFullYear(); + return ((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year))); +} + +Date.prototype.getFirstDayOfMonth = function() { + var day = (this.getDay() - (this.getDate() - 1)) % 7; + return (day < 0) ? (day + 7) : day; +} + +Date.prototype.getLastDayOfMonth = function() { + var day = (this.getDay() + (Date.daysInMonth[this.getMonth()] - this.getDate())) % 7; + return (day < 0) ? (day + 7) : day; +} + +Date.prototype.getDaysInMonth = function() { + Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28; + return Date.daysInMonth[this.getMonth()]; +} + +Date.prototype.getSuffix = function() { + switch (this.getDate()) { + case 1: + case 21: + case 31: + return "st"; + case 2: + case 22: + return "nd"; + case 3: + case 23: + return "rd"; + default: + return "th"; + } +} + +String.escape = function(string) { + return string.replace(/('|\\)/g, "\\$1"); +} + +String.leftPad = function (val, size, ch) { + var result = new String(val); + if (ch == null) { + ch = " "; + } + while (result.length < size) { + result = ch + result; + } + return result; +} + +Date.daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31]; +Date.monthNames = + ["January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December"]; +Date.dayNames = + ["Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday"]; +Date.y2kYear = 50; +Date.monthNumbers = { + Jan:0, + Feb:1, + Mar:2, + Apr:3, + May:4, + Jun:5, + Jul:6, + Aug:7, + Sep:8, + Oct:9, + Nov:10, + Dec:11}; +Date.patterns = { + ISO8601LongPattern:"Y-m-d H:i:s", + ISO8601ShortPattern:"Y-m-d", + ShortDatePattern: "n/j/Y", + LongDatePattern: "l, F d, Y", + FullDateTimePattern: "l, F d, Y g:i:s A", + MonthDayPattern: "F d", + ShortTimePattern: "g:i A", + LongTimePattern: "g:i:s A", + SortableDateTimePattern: "Y-m-d\\TH:i:s", + UniversalSortableDateTimePattern: "Y-m-d H:i:sO", + YearMonthPattern: "F, Y"}; + +var date = new Date("1/1/2007 1:11:11"); + +for (i = 0; i < 4000; ++i) { + var shortFormat = date.dateFormat("Y-m-d"); + var longFormat = date.dateFormat("l, F d, Y g:i:s A"); + date.setTime(date.getTime() + 84266956); +} + +// FIXME: Find a way to validate this test. +// https://bugs.webkit.org/show_bug.cgi?id=114849 diff --git a/Jint.Tests.CommonScripts/Scripts/math-cordic.js b/Jint.Tests.CommonScripts/Scripts/math-cordic.js new file mode 100644 index 0000000000..f71bd11186 --- /dev/null +++ b/Jint.Tests.CommonScripts/Scripts/math-cordic.js @@ -0,0 +1,106 @@ +/* + * Copyright (C) Rich Moore. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////. Start CORDIC + +var AG_CONST = 0.6072529350; + +function FIXED(X) +{ + return X * 65536.0; +} + +function FLOAT(X) +{ + return X / 65536.0; +} + +function DEG2RAD(X) +{ + return 0.017453 * (X); +} + +var Angles = [ + FIXED(45.0), FIXED(26.565), FIXED(14.0362), FIXED(7.12502), + FIXED(3.57633), FIXED(1.78991), FIXED(0.895174), FIXED(0.447614), + FIXED(0.223811), FIXED(0.111906), FIXED(0.055953), + FIXED(0.027977) + ]; + +var Target = 28.027; + +function cordicsincos(Target) { + var X; + var Y; + var TargetAngle; + var CurrAngle; + var Step; + + X = FIXED(AG_CONST); /* AG_CONST * cos(0) */ + Y = 0; /* AG_CONST * sin(0) */ + + TargetAngle = FIXED(Target); + CurrAngle = 0; + for (Step = 0; Step < 12; Step++) { + var NewX; + if (TargetAngle > CurrAngle) { + NewX = X - (Y >> Step); + Y = (X >> Step) + Y; + X = NewX; + CurrAngle += Angles[Step]; + } else { + NewX = X + (Y >> Step); + Y = -(X >> Step) + Y; + X = NewX; + CurrAngle -= Angles[Step]; + } + } + + return FLOAT(X) * FLOAT(Y); +} + +///// End CORDIC + +var total = 0; + +function cordic( runs ) { + var start = new Date(); + + for ( var i = 0 ; i < runs ; i++ ) { + total += cordicsincos(Target); + } + + var end = new Date(); + + return end.getTime() - start.getTime(); +} + +cordic(25000); + +var expected = 10362.570468755888; + +if (total != expected) + throw "ERROR: bad result: expected " + expected + " but got " + total; + diff --git a/Jint.Tests.CommonScripts/Scripts/math-partial-sums.js b/Jint.Tests.CommonScripts/Scripts/math-partial-sums.js new file mode 100644 index 0000000000..67d376554a --- /dev/null +++ b/Jint.Tests.CommonScripts/Scripts/math-partial-sums.js @@ -0,0 +1,45 @@ +// The Computer Language Shootout +// http://shootout.alioth.debian.org/ +// contributed by Isaac Gouy + +function partial(n){ + var a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = a9 = 0.0; + var twothirds = 2.0/3.0; + var alt = -1.0; + var k2 = k3 = sk = ck = 0.0; + + for (var k = 1; k <= n; k++){ + k2 = k*k; + k3 = k2*k; + sk = Math.sin(k); + ck = Math.cos(k); + alt = -alt; + + a1 += Math.pow(twothirds,k-1); + a2 += Math.pow(k,-0.5); + a3 += 1.0/(k*(k+1.0)); + a4 += 1.0/(k3 * sk*sk); + a5 += 1.0/(k3 * ck*ck); + a6 += 1.0/k; + a7 += 1.0/k2; + a8 += alt/k; + a9 += alt/(2*k -1); + } + + // NOTE: We don't try to validate anything from pow(), sin() or cos() because those aren't + // well-specified in ECMAScript. + return a6 + a7 + a8 + a9; +} + +var total = 0; + +for (var i = 1024; i <= 16384; i *= 2) { + total += partial(i); +} + +var expected = 60.08994194659945; + +if (total != expected) { + throw "ERROR: bad result: expected " + expected + " but got " + total; +} + diff --git a/Jint.Tests.CommonScripts/Scripts/math-spectral-norm.js b/Jint.Tests.CommonScripts/Scripts/math-spectral-norm.js new file mode 100644 index 0000000000..ebf36933fb --- /dev/null +++ b/Jint.Tests.CommonScripts/Scripts/math-spectral-norm.js @@ -0,0 +1,59 @@ +// The Great Computer Language Shootout +// http://shootout.alioth.debian.org/ +// +// contributed by Ian Osgood + +function A(i,j) { + return 1/((i+j)*(i+j+1)/2+i+1); +} + +function Au(u,v) { + for (var i=0; i.*\n|\n/g,"") +clen = dnaInput.length + +var dnaOutputString = ""; + +for(i in seqs) + dnaOutputString += seqs[i].source + " " + (dnaInput.match(seqs[i]) || []).length + "\n"; + // match returns null if no matches, so replace with empty + +for(k in subs) + dnaInput = dnaInput.replace(k, subs[k]) // FIXME: Would like this to be a global substitution in a future version of SunSpider. + // search string, replacement string, flags + +var expectedDNAOutputString = "agggtaaa|tttaccct 0\n[cgt]gggtaaa|tttaccc[acg] 9\na[act]ggtaaa|tttacc[agt]t 27\nag[act]gtaaa|tttac[agt]ct 24\nagg[act]taaa|ttta[agt]cct 30\naggg[acg]aaa|ttt[cgt]ccct 9\nagggt[cgt]aa|tt[acg]accct 12\nagggta[cgt]a|t[acg]taccct 9\nagggtaa[cgt]|[acg]ttaccct 15\n"; +var expectedDNAInput = "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCctt(c|g|t)tatcatatgcta(g|t)gg(a|c|g|t)cataaa(c|t)atgtaaa(a|g|t)cD(a|g)tBggDtctttataattcBgtcgtactDtDagcctatttS(a|c|g)(a|c|t)tHttKtgtH(a|c)aSattg(a|t)aHKHttttagacatWatgtRgaaaNtactMcSMt(c|t)tcMgRtacttctWBacgaaatatagScDtttgaagacacatagtVgYgtcattHWtMMWcStgttaggKtSgaYaaccWStcgBttgcgaMttBYatcWtgacaYcagagtaBDtRacttttcWatMttDBcatWtatcttactaBgaYtcttgttttttttYaaScYaHgtgttNtSatcMtcVaaaStccRcctDaataataStcYtRDSaMtDttgttSagtRRcatttHatSttMtWgtcgtatSSagactYaaattcaMtWatttaSgYttaRgKaRtccactttattRggaMcDaWaWagttttgacatgttctacaaaRaatataataaMttcgDacgaSStacaStYRctVaNMtMgtaggcKatcttttattaaaaagVWaHKYagtttttatttaaccttacgtVtcVaattVMBcttaMtttaStgacttagattWWacVtgWYagWVRctDattBYtgtttaagaagattattgacVatMaacattVctgtBSgaVtgWWggaKHaatKWcBScSWaaccRVacacaaactaccScattRatatKVtactatatttHttaagtttSKtRtacaaagtRDttcaaaaWgcacatWaDgtDKacgaacaattacaRNWaatHtttStgttattaaMtgttgDcgtMgcatBtgcttcgcgaDWgagctgcgaggggVtaaScNatttacttaatgacagcccccacatYScaMgtaggtYaNgttctgaMaacNaMRaacaaacaKctacatagYWctgttWaaataaaataRattagHacacaagcgKatacBttRttaagtatttccgatctHSaatactcNttMaagtattMtgRtgaMgcataatHcMtaBSaRattagttgatHtMttaaKaggYtaaBataSaVatactWtataVWgKgttaaaacagtgcgRatatacatVtHRtVYataSaKtWaStVcNKHKttactatccctcatgWHatWaRcttactaggatctataDtDHBttataaaaHgtacVtagaYttYaKcctattcttcttaataNDaaggaaaDYgcggctaaWSctBaaNtgctggMBaKctaMVKagBaactaWaDaMaccYVtNtaHtVWtKgRtcaaNtYaNacggtttNattgVtttctgtBaWgtaattcaagtcaVWtactNggattctttaYtaaagccgctcttagHVggaYtgtNcDaVagctctctKgacgtatagYcctRYHDtgBattDaaDgccKtcHaaStttMcctagtattgcRgWBaVatHaaaataYtgtttagMDMRtaataaggatMtttctWgtNtgtgaaaaMaatatRtttMtDgHHtgtcattttcWattRSHcVagaagtacgggtaKVattKYagactNaatgtttgKMMgYNtcccgSKttctaStatatNVataYHgtNaBKRgNacaactgatttcctttaNcgatttctctataScaHtataRagtcRVttacDSDttaRtSatacHgtSKacYagttMHtWataggatgactNtatSaNctataVtttRNKtgRacctttYtatgttactttttcctttaaacatacaHactMacacggtWataMtBVacRaSaatccgtaBVttccagccBcttaRKtgtgcctttttRtgtcagcRttKtaaacKtaaatctcacaattgcaNtSBaaccgggttattaaBcKatDagttactcttcattVtttHaaggctKKgatacatcBggScagtVcacattttgaHaDSgHatRMaHWggtatatRgccDttcgtatcgaaacaHtaagttaRatgaVacttagattVKtaaYttaaatcaNatccRttRRaMScNaaaDgttVHWgtcHaaHgacVaWtgttScactaagSgttatcttagggDtaccagWattWtRtgttHWHacgattBtgVcaYatcggttgagKcWtKKcaVtgaYgWctgYggVctgtHgaNcVtaBtWaaYatcDRaaRtSctgaHaYRttagatMatgcatttNattaDttaattgttctaaccctcccctagaWBtttHtBccttagaVaatMcBHagaVcWcagBVttcBtaYMccagatgaaaaHctctaacgttagNWRtcggattNatcRaNHttcagtKttttgWatWttcSaNgggaWtactKKMaacatKatacNattgctWtatctaVgagctatgtRaHtYcWcttagccaatYttWttaWSSttaHcaaaaagVacVgtaVaRMgattaVcDactttcHHggHRtgNcctttYatcatKgctcctctatVcaaaaKaaaagtatatctgMtWtaaaacaStttMtcgactttaSatcgDataaactaaacaagtaaVctaggaSccaatMVtaaSKNVattttgHccatcacBVctgcaVatVttRtactgtVcaattHgtaaattaaattttYtatattaaRSgYtgBagaHSBDgtagcacRHtYcBgtcacttacactaYcgctWtattgSHtSatcataaatataHtcgtYaaMNgBaatttaRgaMaatatttBtttaaaHHKaatctgatWatYaacttMctcttttVctagctDaaagtaVaKaKRtaacBgtatccaaccactHHaagaagaaggaNaaatBWattccgStaMSaMatBttgcatgRSacgttVVtaaDMtcSgVatWcaSatcttttVatagttactttacgatcaccNtaDVgSRcgVcgtgaacgaNtaNatatagtHtMgtHcMtagaaattBgtataRaaaacaYKgtRccYtatgaagtaataKgtaaMttgaaRVatgcagaKStctHNaaatctBBtcttaYaBWHgtVtgacagcaRcataWctcaBcYacYgatDgtDHcctaaagacYRcaggattHaYgtKtaatgcVcaataMYacccatatcacgWDBtgaatcBaatacKcttRaRtgatgaBDacggtaattaaYtataStgVHDtDctgactcaaatKtacaatgcgYatBtRaDatHaactgtttatatDttttaaaKVccYcaaccNcBcgHaaVcattHctcgattaaatBtatgcaaaaatYMctSactHatacgaWacattacMBgHttcgaatVaaaacaBatatVtctgaaaaWtctRacgBMaatSgRgtgtcgactatcRtattaScctaStagKgaDcWgtYtDDWKRgRtHatRtggtcgaHgggcgtattaMgtcagccaBggWVcWctVaaattcgNaatcKWagcNaHtgaaaSaaagctcYctttRVtaaaatNtataaccKtaRgtttaMtgtKaBtRtNaggaSattHatatWactcagtgtactaKctatttgRYYatKatgtccgtRtttttatttaatatVgKtttgtatgtNtataRatWYNgtRtHggtaaKaYtKSDcatcKgtaaYatcSRctaVtSMWtVtRWHatttagataDtVggacagVcgKWagBgatBtaaagNcaRtagcataBggactaacacRctKgttaatcctHgDgttKHHagttgttaatgHBtatHcDaagtVaBaRccctVgtgDtacRHSctaagagcggWYaBtSaKtHBtaaactYacgNKBaVYgtaacttagtVttcttaatgtBtatMtMtttaattaatBWccatRtttcatagVgMMtagctStKctaMactacDNYgKYHgaWcgaHgagattacVgtttgtRaSttaWaVgataatgtgtYtaStattattMtNgWtgttKaccaatagNYttattcgtatHcWtctaaaNVYKKttWtggcDtcgaagtNcagatacgcattaagaccWctgcagcttggNSgaNcHggatgtVtcatNtRaaBNcHVagagaaBtaaSggDaatWaatRccaVgggStctDaacataKttKatttggacYtattcSatcttagcaatgaVBMcttDattctYaaRgatgcattttNgVHtKcYRaatRKctgtaaacRatVSagctgtWacBtKVatctgttttKcgtctaaDcaagtatcSataWVgcKKataWaYttcccSaatgaaaacccWgcRctWatNcWtBRttYaattataaNgacacaatagtttVNtataNaYtaatRaVWKtBatKagtaatataDaNaaaaataMtaagaaStccBcaatNgaataWtHaNactgtcDtRcYaaVaaaaaDgtttRatctatgHtgttKtgaaNSgatactttcgagWaaatctKaaDaRttgtggKKagcDgataaattgSaacWaVtaNMacKtcaDaaatttctRaaVcagNacaScRBatatctRatcctaNatWgRtcDcSaWSgttRtKaRtMtKaatgttBHcYaaBtgatSgaSWaScMgatNtctcctatttctYtatMatMtRRtSaattaMtagaaaaStcgVgRttSVaScagtgDtttatcatcatacRcatatDcttatcatVRtttataaHtattcYtcaaaatactttgVctagtaaYttagatagtSYacKaaacgaaKtaaatagataatSatatgaaatSgKtaatVtttatcctgKHaatHattagaaccgtYaaHactRcggSBNgtgctaaBagBttgtRttaaattYtVRaaaattgtaatVatttctcttcatgBcVgtgKgaHaaatattYatagWacNctgaaMcgaattStagWaSgtaaKagttttaagaDgatKcctgtaHtcatggKttVDatcaaggtYcgccagNgtgcVttttagagatgctaccacggggtNttttaSHaNtatNcctcatSaaVgtactgBHtagcaYggYVKNgtaKBcRttgaWatgaatVtagtcgattYgatgtaatttacDacSctgctaaaStttaWMagDaaatcaVYctccgggcgaVtaaWtStaKMgDtttcaaMtVgBaatccagNaaatcYRMBggttWtaaScKttMWtYataRaDBMaDataatHBcacDaaKDactaMgagttDattaHatHtaYatDtattDcRNStgaatattSDttggtattaaNSYacttcDMgYgBatWtaMagactVWttctttgYMaYaacRgHWaattgRtaagcattctMKVStatactacHVtatgatcBtVNataaBttYtSttacKgggWgYDtgaVtYgatDaacattYgatggtRDaVDttNactaSaMtgNttaacaaSaBStcDctaccacagacgcaHatMataWKYtaYattMcaMtgSttDagcHacgatcaHttYaKHggagttccgatYcaatgatRaVRcaagatcagtatggScctatattaNtagcgacgtgKaaWaactSgagtMYtcttccaKtStaacggMtaagNttattatcgtctaRcactctctDtaacWYtgaYaSaagaWtNtatttRacatgNaatgttattgWDDcNaHcctgaaHacSgaataaRaataMHttatMtgaSDSKatatHHaNtacagtccaYatWtcactaactatKDacSaStcggataHgYatagKtaatKagStaNgtatactatggRHacttgtattatgtDVagDVaRctacMYattDgtttYgtctatggtKaRSttRccRtaaccttagagRatagSaaMaacgcaNtatgaaatcaRaagataatagatactcHaaYKBctccaagaRaBaStNagataggcgaatgaMtagaatgtcaKttaaatgtaWcaBttaatRcggtgNcacaaKtttScRtWtgcatagtttWYaagBttDKgcctttatMggNttattBtctagVtacataaaYttacacaaRttcYtWttgHcaYYtaMgBaBatctNgcDtNttacgacDcgataaSatYaSttWtcctatKaatgcagHaVaacgctgcatDtgttaSataaaaYSNttatagtaNYtaDaaaNtggggacttaBggcHgcgtNtaaMcctggtVtaKcgNacNtatVaSWctWtgaWcggNaBagctctgaYataMgaagatBSttctatacttgtgtKtaattttRagtDtacatatatatgatNHVgBMtKtaKaNttDHaagatactHaccHtcatttaaagttVaMcNgHatatKtaNtgYMccttatcaaNagctggacStttcNtggcaVtattactHaSttatgNMVattMMDtMactattattgWMSgtHBttStStgatatRaDaagattttctatMtaaaaaggtactaaVttaSacNaatactgMttgacHaHRttgMacaaaatagttaatatWKRgacDgaRtatatttattatcYttaWtgtBRtWatgHaaattHataagtVaDtWaVaWtgStcgtMSgaSRgMKtaaataVacataatgtaSaatttagtcgaaHtaKaatgcacatcggRaggSKctDcagtcSttcccStYtccRtctctYtcaaKcgagtaMttttcRaYDttgttatctaatcataNctctgctatcaMatactataggDaHaaSttMtaDtcNatataattctMcStaaBYtaNagatgtaatHagagSttgWHVcttatKaYgDctcttggtgttMcRaVgSgggtagacaataaDtaattSaDaNaHaBctattgNtaccaaRgaVtKNtaaYggHtaKKgHcatctWtctDtttctttggSDtNtaStagttataaacaattgcaBaBWggHgcaaaBtYgctaatgaaatWcDcttHtcMtWWattBHatcatcaaatctKMagtDNatttWaBtHaaaNgMttaaStagttctctaatDtcRVaYttgttMtRtgtcaSaaYVgSWDRtaatagctcagDgcWWaaaBaaRaBctgVgggNgDWStNaNBKcBctaaKtttDcttBaaggBttgaccatgaaaNgttttttttatctatgttataccaaDRaaSagtaVtDtcaWatBtacattaWacttaSgtattggDgKaaatScaattacgWcagKHaaccaYcRcaRttaDttRtttHgaHVggcttBaRgtccctDatKaVtKtcRgYtaKttacgtatBtStaagcaattaagaRgBagSaattccSWYtttattVaataNctgHgttaaNBgcVYgtRtcccagWNaaaacaDNaBcaaaaRVtcWMgBagMtttattacgDacttBtactatcattggaaatVccggttRttcatagttVYcatYaSHaHcttaaagcNWaHataaaRWtctVtRYtagHtaaaYMataHYtNBctNtKaatattStgaMcBtRgctaKtgcScSttDgYatcVtggaaKtaagatWccHccgKYctaNNctacaWcttttgcRtgtVcgaKttcMRHgctaHtVaataaDtatgKDcttatBtDttggNtacttttMtgaacRattaaNagaactcaaaBBVtcDtcgaStaDctgaaaSgttMaDtcgttcaccaaaaggWtcKcgSMtcDtatgtttStaaBtatagDcatYatWtaaaBacaKgcaDatgRggaaYctaRtccagattDaWtttggacBaVcHtHtaacDacYgtaatataMagaatgHMatcttatacgtatttttatattacHactgttataMgStYaattYaccaattgagtcaaattaYtgtatcatgMcaDcgggtcttDtKgcatgWRtataatatRacacNRBttcHtBgcRttgtgcgtcatacMtttBctatctBaatcattMttMYgattaaVYatgDaatVagtattDacaacDMatcMtHcccataagatgBggaccattVWtRtSacatgctcaaggggYtttDtaaNgNtaaBatggaatgtctRtaBgBtcNYatatNRtagaacMgagSaSDDSaDcctRagtVWSHtVSRggaacaBVaccgtttaStagaacaMtactccagtttVctaaRaaHttNcttagcaatttattaatRtaaaatctaacDaBttggSagagctacHtaaRWgattcaaBtctRtSHaNtgtacattVcaHaNaagtataccacaWtaRtaaVKgMYaWgttaKggKMtKcgWatcaDatYtKSttgtacgaccNctSaattcDcatcttcaaaDKttacHtggttHggRRaRcaWacaMtBWVHSHgaaMcKattgtaRWttScNattBBatYtaNRgcggaagacHSaattRtttcYgaccBRccMacccKgatgaacttcgDgHcaaaaaRtatatDtatYVtttttHgSHaSaatagctNYtaHYaVYttattNtttgaaaYtaKttWtctaNtgagaaaNctNDctaaHgttagDcRttatagccBaacgcaRBtRctRtggtaMYYttWtgataatcgaataattattataVaaaaattacNRVYcaaMacNatRttcKatMctgaagactaattataaYgcKcaSYaatMNctcaacgtgatttttBacNtgatDccaattattKWWcattttatatatgatBcDtaaaagttgaaVtaHtaHHtBtataRBgtgDtaataMttRtDgDcttattNtggtctatctaaBcatctaRatgNacWtaatgaagtcMNaacNgHttatactaWgcNtaStaRgttaaHacccgaYStacaaaatWggaYaWgaattattcMaactcBKaaaRVNcaNRDcYcgaBctKaacaaaaaSgctccYBBHYaVagaatagaaaacagYtctVccaMtcgtttVatcaatttDRtgWctagtacRttMctgtDctttcKtWttttataaatgVttgBKtgtKWDaWagMtaaagaaattDVtaggttacatcatttatgtcgMHaVcttaBtVRtcgtaYgBRHatttHgaBcKaYWaatcNSctagtaaaaatttacaatcactSWacgtaatgKttWattagttttNaggtctcaagtcactattcttctaagKggaataMgtttcataagataaaaatagattatDgcBVHWgaBKttDgcatRHaagcaYcRaattattatgtMatatattgHDtcaDtcaaaHctStattaatHaccgacNattgatatattttgtgtDtRatagSacaMtcRtcattcccgacacSattgttKaWattNHcaacttccgtttSRtgtctgDcgctcaaMagVtBctBMcMcWtgtaacgactctcttRggRKSttgYtYatDccagttDgaKccacgVatWcataVaaagaataMgtgataaKYaaatcHDaacgataYctRtcYatcgcaMgtNttaBttttgatttaRtStgcaacaaaataccVgaaDgtVgDcStctatatttattaaaaRKDatagaaagaKaaYYcaYSgKStctccSttacagtcNactttDVttagaaagMHttRaNcSaRaMgBttattggtttaRMggatggcKDgWRtNaataataWKKacttcKWaaagNaBttaBatMHtccattaacttccccYtcBcYRtagattaagctaaYBDttaNtgaaaccHcaRMtKtaaHMcNBttaNaNcVcgVttWNtDaBatgataaVtcWKcttRggWatcattgaRagHgaattNtatttctctattaattaatgaDaaMatacgttgggcHaYVaaNaDDttHtcaaHtcVVDgBVagcMacgtgttaaBRNtatRtcagtaagaggtttaagacaVaaggttaWatctccgtVtaDtcDatttccVatgtacNtttccgtHttatKgScBatgtVgHtYcWagcaKtaMYaaHgtaattaSaHcgcagtWNaatNccNNYcacgVaagaRacttctcattcccRtgtgtaattagcSttaaStWaMtctNNcSMacattataaactaDgtatWgtagtttaagaaaattgtagtNagtcaataaatttgatMMYactaatatcggBWDtVcYttcDHtVttatacYaRgaMaacaStaatcRttttVtagaDtcacWatttWtgaaaagaaagNRacDtttStVatBaDNtaactatatcBSMcccaSttccggaMatgattaaWatKMaBaBatttgataNctgttKtVaagtcagScgaaaDggaWgtgttttKtWtatttHaatgtagttcactaaKMagttSYBtKtaYgaactcagagRtatagtVtatcaaaWYagcgNtaDagtacNSaaYDgatBgtcgataacYDtaaactacagWDcYKaagtttattagcatcgagttKcatDaattgattatDtcagRtWSKtcgNtMaaaaacaMttKcaWcaaSVMaaaccagMVtaMaDtMaHaBgaacataBBVtaatVYaNSWcSgNtDNaaKacacBtttatKtgtttcaaHaMctcagtaacgtcgYtactDcgcctaNgagagcYgatattttaaatttccattttacatttDaaRctattttWctttacgtDatYtttcagacgcaaVttagtaaKaaaRtgVtccataBggacttatttgtttaWNtgttVWtaWNVDaattgtatttBaagcBtaaBttaaVatcHcaVgacattccNggtcgacKttaaaRtagRtctWagaYggtgMtataatMtgaaRttattttgWcttNtDRRgMDKacagaaaaggaaaRStcccagtYccVattaNaaKStNWtgacaVtagaagcttSaaDtcacaacgDYacWDYtgtttKatcVtgcMaDaSKStVcgtagaaWaKaagtttcHaHgMgMtctataagBtKaaaKKcactggagRRttaagaBaaNatVVcgRcKSttDaactagtSttSattgttgaaRYatggttVttaataaHttccaagDtgatNWtaagHtgcYtaactRgcaatgMgtgtRaatRaNaacHKtagactactggaatttcgccataacgMctRgatgttaccctaHgtgWaYcactcacYaattcttaBtgacttaaacctgYgaWatgBttcttVttcgttWttMcNYgtaaaatctYgMgaaattacNgaHgaacDVVMtttggtHtctaaRgtacagacgHtVtaBMNBgattagcttaRcttacaHcRctgttcaaDBggttKaacatgKtttYataVaNattccgMcgcgtagtRaVVaattaKaatggttRgaMcagtatcWBttNtHagctaatctagaaNaaacaYBctatcgcVctBtgcaaagDgttVtgaHtactSNYtaaNccatgtgDacgaVtDcgKaRtacDcttgctaagggcagMDagggtBWRtttSgccttttttaacgtcHctaVtVDtagatcaNMaVtcVacatHctDWNaataRgcgtaVHaggtaaaaSgtttMtattDgBtctgatSgtRagagYtctSaKWaataMgattRKtaacatttYcgtaacacattRWtBtcggtaaatMtaaacBatttctKagtcDtttgcBtKYYBaKttctVttgttaDtgattttcttccacttgSaaacggaaaNDaattcYNNaWcgaaYattttMgcBtcatRtgtaaagatgaWtgaccaYBHgaatagataVVtHtttVgYBtMctaMtcctgaDcYttgtccaaaRNtacagcMctKaaaggatttacatgtttaaWSaYaKttBtagDacactagctMtttNaKtctttcNcSattNacttggaacaatDagtattRtgSHaataatgccVgacccgatactatccctgtRctttgagaSgatcatatcgDcagWaaHSgctYYWtatHttggttctttatVattatcgactaagtgtagcatVgtgHMtttgtttcgttaKattcMatttgtttWcaaStNatgtHcaaaDtaagBaKBtRgaBgDtSagtatMtaacYaatYtVcKatgtgcaacVaaaatactKcRgtaYtgtNgBBNcKtcttaccttKgaRaYcaNKtactttgagSBtgtRagaNgcaaaNcacagtVtttHWatgttaNatBgtttaatNgVtctgaatatcaRtattcttttttttRaaKcRStctcggDgKagattaMaaaKtcaHacttaataataKtaRgDtKVBttttcgtKaggHHcatgttagHggttNctcgtatKKagVagRaaaggaaBtNatttVKcRttaHctaHtcaaatgtaggHccaBataNaNaggttgcWaatctgatYcaaaHaatWtaVgaaBttagtaagaKKtaaaKtRHatMaDBtBctagcatWtatttgWttVaaaScMNattRactttgtYtttaaaagtaagtMtaMaSttMBtatgaBtttaKtgaatgagYgtNNacMtcNRacMMHcttWtgtRtctttaacaacattattcYaMagBaacYttMatcttKcRMtgMNccattaRttNatHaHNaSaaHMacacaVaatacaKaSttHatattMtVatWgattttttaYctttKttHgScWaacgHtttcaVaaMgaacagNatcgttaacaaaaagtacaHBNaattgttKtcttVttaaBtctgctacgBgcWtttcaggacacatMgacatcccagcggMgaVKaBattgacttaatgacacacaaaaaatRKaaBctacgtRaDcgtagcVBaacDSBHaaaaSacatatacagacRNatcttNaaVtaaaataHattagtaaaaSWccgtatWatggDttaactattgcccatcttHaSgYataBttBaactattBtcHtgatcaataSttaBtatKSHYttWggtcYtttBttaataccRgVatStaHaKagaatNtagRMNgtcttYaaSaactcagDSgagaaYtMttDtMRVgWKWtgMaKtKaDttttgactatacataatcNtatNaHattVagacgYgatatatttttgtStWaaatctWaMgagaRttRatacgStgattcttaagaDtaWccaaatRcagcagaaNKagtaaDggcgccBtYtagSBMtactaaataMataBSacRMgDgattMMgtcHtcaYDtRaDaacggttDaggcMtttatgttaNctaattaVacgaaMMtaatDccSgtattgaRtWWaccaccgagtactMcgVNgctDctaMScatagcgtcaactatacRacgHRttgctatttaatgaattataYKttgtaagWgtYttgcHgMtaMattWaWVtaRgcttgYgttBHtYataSccStBtgtagMgtDtggcVaaSBaatagDttgBgtctttctcattttaNagtHKtaMWcYactVcgcgtatMVtttRacVagDaatcttgctBBcRDgcaacKttgatSKtYtagBMagaRtcgBattHcBWcaactgatttaatttWDccatttatcgagSKaWttataHactaHMttaatHtggaHtHagaatgtKtaaRactgtttMatacgatcaagDgatKaDctataMggtHDtggHacctttRtatcttYattttgacttgaaSaataaatYcgBaaaaccgNatVBttMacHaKaataagtatKgtcaagactcttaHttcggaattgttDtctaaccHttttWaaatgaaatataaaWattccYDtKtaaaacggtgaggWVtctattagtgactattaagtMgtttaagcatttgSgaaatatccHaaggMaaaattttcWtatKctagDtYtMcctagagHcactttactatacaaacattaacttaHatcVMYattYgVgtMttaaRtgaaataaDatcaHgtHHatKcDYaatcttMtNcgatYatgSaMaNtcttKcWataScKggtatcttacgcttWaaagNatgMgHtctttNtaacVtgttcMaaRatccggggactcMtttaYMtcWRgNctgNccKatcttgYDcMgattNYaRagatHaaHgKctcataRDttacatBatccattgDWttatttaWgtcggagaaaaatacaatacSNtgggtttccttacSMaagBattacaMaNcactMttatgaRBacYcYtcaaaWtagctSaacttWgDMHgaggatgBVgcHaDtggaactttggtcNatNgtaKaBcccaNtaagttBaacagtatacDYttcctNgWgcgSMcacatStctHatgRcNcgtacacaatRttMggaNKKggataaaSaYcMVcMgtaMaHtgattYMatYcggtcttcctHtcDccgtgRatcattgcgccgatatMaaYaataaYSggatagcgcBtNtaaaScaKgttBgagVagttaKagagtatVaactaSacWactSaKatWccaKaaaatBKgaaKtDMattttgtaaatcRctMatcaaMagMttDgVatggMaaWgttcgaWatgaaatttgRtYtattaWHKcRgctacatKttctaccaaHttRatctaYattaaWatVNccatNgagtcKttKataStRaatatattcctRWatDctVagttYDgSBaatYgttttgtVaatttaatagcagMatRaacttBctattgtMagagattaaactaMatVtHtaaatctRgaaaaaaaatttWacaacaYccYDSaattMatgaccKtaBKWBattgtcaagcHKaagttMMtaatttcKcMagNaaKagattggMagaggtaatttYacatcWaaDgatMgKHacMacgcVaacaDtaDatatYggttBcgtatgWgaSatttgtagaHYRVacaRtctHaaRtatgaactaatatctSSBgggaaHMWtcaagatKgagtDaSatagttgattVRatNtctMtcSaagaSHaataNataataRaaRgattctttaataaagWaRHcYgcatgtWRcttgaaggaMcaataBRaaccagStaaacNtttcaatataYtaatatgHaDgcStcWttaacctaRgtYaRtataKtgMttttatgactaaaatttacYatcccRWtttHRtattaaatgtttatatttgttYaatMcaRcSVaaDatcgtaYMcatgtagacatgaaattgRtcaaYaaYtRBatKacttataccaNaaattVaBtctggacaagKaaYaaatatWtMtatcYaaVNtcgHaactBaagKcHgtctacaatWtaDtSgtaHcataHtactgataNctRgttMtDcDttatHtcgtacatcccaggSttaBgtcacacWtccNMcNatMVaVgtccDYStatMaccDatggYaRKaaagataRatttHKtSaaatDgataaacttaHgttgVBtcttVttHgDacgaKatgtatatNYataactctSatatatattgcHRRYttStggaactHgttttYtttaWtatMcttttctatctDtagVHYgMRBgtHttcctaatYRttKtaagatggaVRataKDctaMtKBNtMtHNtWtttYcVtattMcgRaacMcctNSctcatttaaagDcaHtYccSgatgcaatYaaaaDcttcgtaWtaattctcgttttScttggtaatctttYgtctaactKataHacctMctcttacHtKataacacagcNRatgKatttttSaaatRYcgDttaMRcgaaattactMtgcgtaagcgttatBtttttaattaagtNacatHgttcRgacKcBBtVgatKttcgaBaatactDRgtRtgaNacWtcacYttaaKcgttctHaKttaNaMgWgWaggtctRgaKgWttSttBtDcNtgtttacaaatYcDRtgVtgcctattcNtctaaaDMNttttNtggctgagaVctDaacVtWccaagtaacacaNctgaScattccDHcVBatcgatgtMtaatBgHaatDctMYgagaatgYWKcctaatNaStHaaaKccgHgcgtYaaYtattgtStgtgcaaRtattaKatattagaWVtcaMtBagttattagNaWHcVgcaattttDcMtgtaRHVYtHtctgtaaaaHVtMKacatcgNaatttMatatgttgttactagWYtaRacgataKagYNKcattataNaRtgaacKaYgcaaYYacaNccHatMatDcNgtHttRaWttagaaDcaaaaaatagggtKDtStaDaRtaVtHWKNtgtattVctSVgRgataDaRaWataBgaagaaKtaataaYgDcaStaNgtaDaaggtattHaRaWMYaYaWtggttHYgagVtgtgcttttcaaDKcagVcgttagacNaaWtagtaataDttctggttVcatcataaagtgKaaaNaMtaBBaattaatWaattgctHaVKaSgDaaVKaHtatatatHatcatSBagNgHtatcHYMHgttDgtaHtBttWatcgtttaRaattgStKgSKNWKatcagDtctcagatttctRtYtBatBgHHtKaWtgYBgacVVWaKtacKcDttKMaKaVcggtgttataagaataaHaatattagtataatMHgttYgaRttagtaRtcaaVatacggtcMcgagtaaRttacWgactKRYataaaagSattYaWgagatYagKagatgSaagKgttaatMggtataatgttWYttatgagaaacctNVataatHcccKtDctcctaatactggctHggaSaggRtKHaWaattcgSatMatttagaggcYtctaMcgctcataSatatgRagacNaaDaggaVBagaYttKtacNaKgtSYtagttggaWcatcWttaatctatgaVtcgtgtMtatcaYcgtRccaaYgDctgcMgtgtWgacWtgataacacgcgctBtgttaKtYDtatDcatcagKaVMctaatcttgVcaaRgcRMtDcgattaHttcaNatgaatMtactacVgtRgatggaWtttactaaKatgagSaaKggtaNtactVaYtaaKRagaacccacaMtaaMtKtatBcttgtaaWBtMctaataaVcDaaYtcRHBtcgttNtaaHatttBNgRStVDattBatVtaagttaYatVattaagaBcacggtSgtVtatttaRattgatgtaHDKgcaatattKtggcctatgaWDKRYcggattgRctatNgatacaatMNttctgtcRBYRaaaHctNYattcHtaWcaattctBtMKtVgYataatMgYtcagcttMDataVtggRtKtgaatgccNcRttcaMtRgattaacattRcagcctHtWMtgtDRagaKaBtgDttYaaaaKatKgatctVaaYaacWcgcatagBVtaNtRtYRaggBaaBtgKgttacataagagcatgtRattccacttaccatRaaatgWgDaMHaYVgVtaSctatcgKaatatattaDgacccYagtgtaYNaaatKcagtBRgagtccatgKgaaaccBgaagBtgSttWtacgatWHaYatcgatttRaaNRgcaNaKVacaNtDgattgHVaatcDaagcgtatgcNttaDataatcSataaKcaataaHWataBtttatBtcaKtKtatagttaDgSaYctacaRatNtaWctSaatatttYaKaKtaccWtatcRagacttaYttVcKgSDcgagaagatccHtaattctSttatggtKYgtMaHagVaBRatttctgtRgtctatgggtaHKgtHacHtSYacgtacacHatacKaaBaVaccaDtatcSaataaHaagagaatScagactataaRttagcaaVcaHataKgDacatWccccaagcaBgagWatctaYttgaaatctVNcYtttWagHcgcgcDcVaaatgttKcHtNtcaatagtgtNRaactttttcaatggWgBcgDtgVgtttctacMtaaataaaRggaaacWaHttaRtNtgctaaRRtVBctYtVtatDcattDtgaccYatagatYRKatNYKttNgcctagtaWtgaactaMVaacctgaStttctgaKVtaaVaRKDttVtVctaDNtataaaDtccccaagtWtcgatcactDgYaBcatcctMtVtacDaaBtYtMaKNatNtcaNacgDatYcatcgcaRatWBgaacWttKttagYtaattcggttgSWttttDWctttacYtatatWtcatDtMgtBttgRtVDggttaacYtacgtacatgaattgaaWcttMStaDgtatattgaDtcRBcattSgaaVBRgagccaaKtttcDgcgaSMtatgWattaKttWtgDBMaggBBttBaatWttRtgcNtHcgttttHtKtcWtagHStaacagttgatatBtaWSaWggtaataaMttaKacDaatactcBttcaatatHttcBaaSaaatYggtaRtatNtHcaatcaHtagVtgtattataNggaMtcttHtNagctaaaggtagaYctMattNaMVNtcKtactBKcaHHcBttaSagaKacataYgctaKaYgttYcgacWVttWtSagcaacatcccHaccKtcttaacgaKttcacKtNtacHtatatRtaaatacactaBtttgaHaRttggttWtatYagcatYDatcggagagcWBataagRtacctataRKgtBgatgaDatataSttagBaHtaatNtaDWcWtgtaattacagKttcNtMagtattaNgtctcgtcctcttBaHaKcKccgtRcaaYagSattaagtKataDatatatagtcDtaacaWHcaKttDgaaRcgtgYttgtcatatNtatttttatggccHtgDtYHtWgttatYaacaattcaWtatNgctcaaaSttRgctaatcaaatNatcgtttaBtNNVtgttataagcaaagattBacgtDatttNatttaaaDcBgtaSKgacgtagataatttcHMVNttgttBtDtgtaWKaaRMcKMtHtaVtagataWctccNNaSWtVaHatctcMgggDgtNHtDaDttatatVWttgttatttaacctttcacaaggaSaDcggttttttatatVtctgVtaacaStDVaKactaMtttaSNagtgaaattaNacttSKctattcctctaSagKcaVttaagNaVcttaVaaRNaHaaHttatgtHttgtgatMccaggtaDcgaccgtWgtWMtttaHcRtattgScctatttKtaaccaagtYagaHgtWcHaatgccKNRtttagtMYSgaDatctgtgaWDtccMNcgHgcaaacNDaaaRaStDWtcaaaaHKtaNBctagBtgtattaactaattttVctagaatggcWSatMacccttHttaSgSgtgMRcatRVKtatctgaaaccDNatYgaaVHNgatMgHRtacttaaaRtatStRtDtatDttYatattHggaBcttHgcgattgaKcKtttcRataMtcgaVttWacatNcatacctRataDDatVaWNcggttgaHtgtMacVtttaBHtgagVttMaataattatgttcttagtttgtgcDtSatttgBtcaacHattaaBagVWcgcaSYttMgcttacYKtVtatcaYaKctgBatgcgggcYcaaaaacgNtctagKBtattatctttKtaVttatagtaYtRagNtaYataaVtgaatatcHgcaaRataHtacacatgtaNtgtcgYatWMatttgaactacRctaWtWtatacaatctBatatgYtaagtatgtgtatSttactVatcttYtaBcKgRaSggRaaaaatgcagtaaaWgtaRgcgataatcBaataccgtatttttccatcNHtatWYgatHSaaaDHttgctgtccHtggggcctaataatttttctatattYWtcattBtgBRcVttaVMRSgctaatMagtYtttaaaaatBRtcBttcaaVtaacagctccSaaSttKNtHtKYcagcagaaaccccRtttttaaDcDtaStatccaagcgctHtatcttaDRYgatDHtWcaaaBcWgKWHttHataagHacgMNKttMKHccaYcatMVaacgttaKgYcaVaaBtacgcaactttMctaaHaatgtBatgagaSatgtatgSRgHgWaVWgataaatatttccKagVgataattWaHNcYggaaatgctHtKtaDtctaaagtMaatVDVactWtSaaWaaMtaHtaSKtcBRaNcttStggtBttacNagcatagRgtKtgcgaacaacBcgKaatgataagatgaaaattgtactgcgggtccHHWHaaNacaBttNKtKtcaaBatatgctaHNgtKcDWgtttatNgVDHgaccaacWctKaaggHttgaRgYaatHcaBacaatgagcaaattactgtaVaaYaDtagattgagNKggtggtgKtWKaatacagDRtatRaMRtgattDggtcaaYRtatttNtagaDtcacaaSDctDtataatcgtactaHttatacaatYaacaaHttHatHtgcgatRRttNgcatSVtacWWgaaggagtatVMaVaaattScDDKNcaYBYaDatHgtctatBagcaacaagaatgagaaRcataaKNaRtBDatcaaacgcattttttaaBtcSgtacaRggatgtMNaattggatatWtgagtattaaaVctgcaYMtatgatttttYgaHtgtcttaagWBttHttgtcttattDtcgtatWtataataSgctaHagcDVcNtaatcaagtaBDaWaDgtttagYctaNccDtaKtaHcttaataacccaRKtacaVaatNgcWRaMgaattatgaBaaagattVYaHMDcaDHtcRcgYtcttaaaWaaaVKgatacRtttRRKYgaatacaWVacVcRtatMacaBtactggMataaattttHggNagSctacHgtBagcgtcgtgattNtttgatSaaggMttctttcttNtYNagBtaaacaaatttMgaccttacataattgYtcgacBtVMctgStgMDtagtaRctHtatgttcatatVRNWataDKatWcgaaaaagttaaaagcacgHNacgtaatctttMRtgacttttDacctataaacgaaatatgattagaactccSYtaBctttaataacWgaaaYatagatgWttcatKtNgatttttcaagHtaYgaaRaDaagtaggagcttatVtagtctttcattaaaatcgKtattaRttacagVaDatgcatVgattgggtctttHVtagKaaRBtaHtaaggccccaaaaKatggtttaMWgtBtaaacttcactttKHtcgatctccctaYaBacMgtcttBaBaNgcgaaacaatctagtHccHtKttcRtRVttccVctttcatacYagMVtMcagaMaaacaataBctgYtaatRaaagattaaccatVRatHtaRagcgcaBcgDttStttttcVtttaDtKgcaaWaaaaatSccMcVatgtKgtaKgcgatatgtagtSaaaDttatacaaacatYaRRcVRHctKtcgacKttaaVctaDaatgttMggRcWaacttttHaDaKaDaBctgtaggcgtttaHBccatccattcNHtDaYtaataMttacggctNVaacDattgatattttacVttSaattacaaRtataNDgacVtgaacataVRttttaDtcaaacataYDBtttaatBaDtttYDaDaMccMttNBttatatgagaaMgaNtattHccNataattcaHagtgaaggDgatgtatatatgYatgaStcataaBStWacgtcccataRMaaDattggttaaattcMKtctMacaBSactcggaatDDgatDgcWctaacaccgggaVcacWKVacggtaNatatacctMtatgatagtgcaKagggVaDtgtaacttggagtcKatatcgMcttRaMagcattaBRaStctYSggaHYtacaactMBaagDcaBDRaaacMYacaHaattagcattaaaHgcgctaaggSccKtgaaKtNaBtatDDcKBSaVtgatVYaagVtctSgMctacgttaacWaaattctSgtDactaaStaaattgcagBBRVctaatatacctNttMcRggctttMttagacRaHcaBaacVKgaataHttttMgYgattcYaNRgttMgcVaaacaVVcDHaatttgKtMYgtatBtVVctWgVtatHtacaaHttcacgatagcagtaaNattBatatatttcVgaDagcggttMaagtcScHagaaatgcYNggcgtttttMtStggtRatctacttaaatVVtBacttHNttttaRcaaatcacagHgagagtMgatcSWaNRacagDtatactaaDKaSRtgattctccatSaaRttaaYctacacNtaRtaactggatgaccYtacactttaattaattgattYgttcagDtNKttagDttaaaaaaaBtttaaNaYWKMBaaaacVcBMtatWtgBatatgaacVtattMtYatMNYDKNcKgDttDaVtaaaatgggatttctgtaaatWtctcWgtVVagtcgRgacttcccctaDcacagcRcagagtgtWSatgtacatgttaaSttgtaaHcgatgggMagtgaacttatRtttaVcaccaWaMgtactaatSSaHtcMgaaYtatcgaaggYgggcgtgaNDtgttMNgaNDMtaattcgVttttaacatgVatgtWVMatatcaKgaaattcaBcctccWcttgaaWHtWgHtcgNWgaRgctcBgSgaattgcaaHtgattgtgNagtDttHHgBttaaWcaaWagcaSaHHtaaaVctRaaMagtaDaatHtDMtcVaWMtagSagcttHSattaacaaagtRacMtRtctgttagcMtcaBatVKtKtKacgagaSNatSactgtatatcBctgagVtYactgtaaattaaaggcYgDHgtaacatSRDatMMccHatKgttaacgactKtgKagtcttcaaHRVtccttKgtSataatttacaactggatDNgaacttcaRtVaagDcaWatcBctctHYatHaDaaatttagYatSatccaWtttagaaatVaacBatHcatcgtacaatatcgcNYRcaataYaRaYtgattVttgaatgaVaactcRcaNStgtgtattMtgaggtNttBaDRcgaaaagctNgBcWaWgtSaDcVtgVaatMKBtttcgtttctaaHctaaagYactgMtatBDtcStgaccgtSDattYaataHctgggaYYttcggttaWaatctggtRagWMaDagtaacBccactacgHWMKaatgatWatcctgHcaBaSctVtcMtgtDttacctaVgatYcWaDRaaaaRtagatcgaMagtggaRaWctctgMgcWttaagKBRtaaDaaWtctgtaagYMttactaHtaatcttcataacggcacBtSgcgttNHtgtHccatgttttaaagtatcgaKtMttVcataYBBaKtaMVaVgtattNDSataHcagtWMtaggtaSaaKgttgBtVtttgttatcatKcgHacacRtctHatNVagSBgatgHtgaRaSgttRcctaacaaattDNttgacctaaYtBgaaaatagttattactcttttgatgtNNtVtgtatMgtcttRttcatttgatgacacttcHSaaaccaWWDtWagtaRDDVNacVaRatgttBccttaatHtgtaaacStcVNtcacaSRttcYagacagaMMttttgMcNttBcgWBtactgVtaRttctccaaYHBtaaagaBattaYacgatttacatctgtaaMKaRYtttttactaaVatWgctBtttDVttctggcDaHaggDaagtcgaWcaagtagtWttHtgKtVataStccaMcWcaagataagatcactctHatgtcYgaKcatcagatactaagNSStHcctRRNtattgtccttagttagMVgtatagactaactctVcaatMctgtttgtgttgccttatWgtaBVtttctggMcaaKgDWtcgtaaYStgSactatttHgatctgKagtagBtVacRaagRtMctatgggcaaaKaaaatacttcHctaRtgtDcttDattaggaaatttcYHaRaaBttaatggcacKtgctHVcaDcaaaVDaaaVcgMttgtNagcgtaDWgtcgttaatDgKgagcSatatcSHtagtagttggtgtHaWtaHKtatagctgtVgattaBVaatgaataagtaatVatSttaHctttKtttgtagttaccttaatcgtagtcctgBcgactatttVcMacHaaaggaatgDatggKtaHtgStatattaaSagctWcctccRtataBaDYcgttgcNaagaggatRaaaYtaWgNtSMcaatttactaacatttaaWttHtatBattgtcgacaatNgattgcNgtMaaaKaBDattHacttggtRtttaYaacgVactBtaBaKtgBttatgVttgtVttcaatcWcNctDBaaBgaDHacBttattNtgtDtatttVSaaacaggatgcRatSgtaSaNtgBatagttcHBgcBBaaattaHgtDattatDaKaatBaaYaaMaataaataKtttYtagtBgMatNcatgtttgaNagtgttgtgKaNaSagtttgaSMaYBcaaaacDStagttVacaaaaactaaWttBaagtctgtgcgtMgtaattctcctacctcaNtttaaccaaaaVtBcacataacaccccBcWMtatVtggaatgaWtcaaWaaaaaaaaWtDtaatatRcctDWtcctaccMtVVatKttaWaaKaaatataaagScHBagaggBaSMtaWaVtatattactSaaaKNaactatNatccttgaYctattcaaaVgatttYHcRagattttaSataggttattcVtaaagaKgtattattKtRttNcggcRgtgtgtWYtaacHgKatKgatYtacYagDtWcHBDctctgRaYKaYagcactKcacSaRtBttttBHKcMtNtcBatttatttttgSatVgaaagaWtcDtagDatatgMacaacRgatatatgtttgtKtNRaatatNatgYcaHtgHataacKtgagtagtaacYttaNccaaatHcacaacaVDtagtaYtccagcattNtacKtBtactaaagaBatVtKaaHBctgStgtBgtatgaSNtgDataaccctgtagcaBgtgatcttaDataStgaMaccaSBBgWagtacKcgattgaDgNNaaaacacagtSatBacKDgcgtataBKcatacactaSaatYtYcDaactHttcatRtttaatcaattataRtttgtaagMcgNttcatcBtYBagtNWNMtSHcattcRctttttRWgaKacKttgggagBcgttcgcMaWHtaatactgtctctatttataVgtttaBScttttaBMaNaatMacactYtBMggtHacMagtaRtctgcatttaHtcaaaatttgagKtgNtactBacaHtcgtatttctMaSRagcagttaatgtNtaaattgagagWcKtaNttagVtacgatttgaatttcgRtgtWcVatcgttaaDVctgtttBWgaccagaaagtcSgtVtatagaBccttttcctaaattgHtatcggRattttcaaggcYSKaagWaWtRactaaaacccBatMtttBaatYtaagaactSttcgaaScaatagtattgaccaagtgttttctaacatgtttNVaatcaaagagaaaNattaaRttttaVaaaccgcaggNMtatattVctcaagaggaacgBgtttaacaagttcKcYaatatactaaccBaaaSggttcNtattctagttRtBacgScVctcaatttaatYtaaaaaaatgSaatgatagaMBRatgRcMcgttgaWHtcaVYgaatYtaatctttYttatRaWtctgBtDcgatNatcKaBaDgatgtaNatWKctccgatattaacattNaaacDatgBgttctgtDtaaaMggtgaBaSHataacgccSctaBtttaRBtcNHcDatcDcctagagtcRtaBgWttDRVHagattYatgtatcWtaHtttYcattWtaaagtctNgtStggRNcgcggagSSaaagaaaatYcHDtcgctttaatgYcKBVSgtattRaYBaDaaatBgtatgaHtaaRaRgcaSWNtagatHaacttNctBtcaccatctMcatattccaSatttgcgaDagDgtatYtaaaVDtaagtttWVaagtagYatRttaagDcNgacKBcScagHtattatcDaDactaaaaaYgHttBcgaDttggataaaKSRcBMaBcgaBSttcWtgNBatRaccgattcatttataacggHVtaattcacaagagVttaaRaatVVRKcgWtVgacctgDgYaaHaWtctttcacMagggatVgactagMaaataKaaNWagKatagNaaWtaaaatttgaattttatttgctaaVgaHatBatcaaBWcBgttcMatcgBaaNgttcgSNaggSaRtttgHtRtattaNttcDcatSaVttttcgaaaaattgHatctaRaggSaNatMDaaatDcacgattttagaHgHaWtYgattaatHNSttatMSgggNtcKtYatRggtttgtMWVtttaYtagcagBagHaYagttatatggtBacYcattaRSataBatMtttaaatctHcaaaSaaaagttNSaaWcWRccRtKaagtBWtcaaattSttMtattggaaaccttaacgttBtWatttatatWcDaatagattcctScacctaagggRaaYtaNaatgVtBcttaaBaacaMVaaattatStYgRcctgtactatcMcVKatttcgSgatRHMaaaHtagtaaHtVgcaaataatatcgKKtgccaatBNgaaWcVttgagttaKatagttcaggKDatDtattgaKaVcaKtaataDataataHSaHcattagttaatRVYcNaHtaRcaaggtNHcgtcaaccaBaaagYtHWaaaRcKgaYaaDttgcWYtataRgaatatgtYtgcKtaNttWacatYHctRaDtYtattcBttttatcSataYaYgttWaRagcacHMgtttHtYttYaatcggtatStttcgtRSattaaDaKMaatatactaNBaWgctacacYtgaYVgtgHtaaaRaaRgHtagtWattataaaSDaaWtgMattatcgaaaagtaYRSaWtSgNtBgagcRYaMDtactaacttaWgtatctagacaagNtattHggataatYttYatcataDcgHgttBttctttVttgccgaaWtaaaacgKgtatctaaaaaNtccDtaDatBMaMggaatNKtatBaaatVtccRaHtaSacataHattgtttKVYattcataVaattWtcgtgMttcttKtgtctaacVtatctatatBRataactcgKatStatattcatHHRttKtccaacgtgggtgRgtgaMtattattggctatcgtgacMtRcBDtcttgtactaatRHttttaagatcgVMDStattatYBtttDttgtBtNttgRcMtYtgBacHaWaBaatDKctaagtgaaactaatgRaaKgatccaagNaaaatattaggWNtaagtatacttttKcgtcggSYtcttgRctataYcttatataaagtatattaatttataVaacacaDHatctatttttKYVatHRactttaBHccaWagtactBtcacgaVgcgttRtttttttSVgtSagtBaaattctgaHgactcttgMcattttagVtaagaattHctHtcaDaaNtaacRggWatagttcgtSttgaDatcNgNagctagDgatcNttKgttgtaDtctttRaaYStRatDtgMggactSttaDtagSaVtBDttgtDgccatcacaMattaaaMtNacaVcgSWcVaaDatcaHaatgaattaMtatccVtctBtaattgtWattatBRcWcaatgNNtactWYtDaKttaaatcactcagtRaaRgatggtKgcgccaaHgaggatStattYcaNMtcaBttacttatgagDaNtaMgaaWtgtttcttctaHtMNgttatctaWWatMtBtaaatagDVatgtBYtatcggcttaagacMRtaHScgatatYgRDtcattatSDaHggaaataNgaWSRRaaaBaatagBattaDctttgHWNttacaataaaaaaatacggtttgHgVtaHtWMttNtBtctagtMcgKMgHgYtataHaNagWtcaacYattaataYRgtaWKgaBctataaccgatttaHaNBRaRaMtccggtNgacMtctcatttgcaattcWgMacttacaaDaaNtactWatVtttagccttMaatcagVaagtctVaaDaBtattaattaYtNaYtggattaKtaKctYaMtattYgatattataatKtVgDcttatatNBtcgttgtStttttMagaggttaHYSttcKgtcKtDNtataagttataagSgttatDtRttattgttttSNggRtcaaKMNatgaatattgtBWtaMacctgggYgaSgaagYataagattacgagaatBtggtRcVHtgYggaDgaYaKagWagctatagacgaaHgtWaNgacttHRatVaWacKYtgRVNgVcSgRWctacatcKSactctgWYtBggtataagcttNRttVtgRcaWaaatDMatYattaactttcgaagRatSctgccttgcRKaccHtttSNVagtagHagBagttagaccaRtataBccataatSHatRtcHagacBWatagcaMtacaRtgtgaaBatctKRtScttccaNaatcNgtaatatWtcaMgactctBtWtaaNactHaaaaRctcgcatggctMcaaNtcagaaaaacacagtggggWttRttagtaagaVctVMtcgaatcttcMaaaHcaHBttcgattatgtcaDagcYRtBtYcgacMgtDcagcgaNgttaataatagcagKYYtcgtaBtYctMaRtaRtDagaaaacacatgYaBttgattattcgaaNttBctSataaMataWRgaHtttccgtDgaYtatggtDgHKgMtatttVtMtVagttaRatMattRagataaccctKctMtSttgaHagtcStctatttccSagatgttccacgaggYNttHRacgattcDatatDcataaaatBBttatcgaHtNHaaatatDNaggctgaNcaaggagttBttMgRagVatBcRtaWgatgBtSgaKtcgHtttgaatcaaDaHttcSBgHcagtVaaSttDcagccgttNBtgttHagYtattctttRWaaVtSttcatatKaaRaaaNacaVtVctMtSDtDtRHRcgtaatgctcttaaatSacacaatcgHattcaWcttaaaatHaaatcNctWttaNMcMtaKctVtcctaagYgatgatcYaaaRactctaRDaYagtaacgtDgaggaaatctcaaacatcaScttcKttNtaccatNtaNatacatttHaaDHgcaDatMWaaBttcRggctMaagctVYcacgatcaDttatYtaatcKatWatcaatVYtNagatttgattgaYttttYgacttVtcKaRagaaaHVgDtaMatKYagagttNatWttaccNtYtcDWgSatgaRgtMatgKtcgacaagWtacttaagtcgKtgatccttNcttatagMatHVggtagcgHctatagccctYttggtaattKNaacgaaYatatVctaataMaaaYtgVtcKaYtaataacagaatHcacVagatYWHttagaaSMaatWtYtgtaaagNaaacaVgaWtcacNWgataNttcaSagctMDaRttgNactaccgataMaaatgtttattDtcaagacgctDHYYatggttcaagccNctccttcMctttagacBtaaWtaWVHggaaaaNatttaDtDtgctaaHHtMtatNtMtagtcatttgcaaaRatacagRHtatDNtgtDgaatVgtVNtcaaatYBMaaaagcaKgtgatgatMgWWMaHttttMgMagatDtataaattaaccaactMtacataaattgRataatacgBtKtaataattRgtatDagDtcRDacctatRcagagcSHatNtcaScNtttggacNtaaggaccgtgKNttgttNcttgaaRgYgRtNtcagttBcttttcHtKtgcttYaaNgYagtaaatgaatggWaMattBHtatctatSgtcYtgcHtaattHgaaMtHcagaaSatggtatgccaHBtYtcNattWtgtNgctttaggtttgtWatNtgHtgcDttactttttttgcNtactKtWRaVcttcatagtgSNKaNccgaataaBttataataYtSagctttaaatSttggctaaKSaatRccgWHgagDttaaatcatgagMtcgagtVtaDggaBtatttgDacataaacgtagYRagBWtgDStKDgatgaagttcattatttaKWcataaatWRgatataRgttRacaaNKttNtKagaaYaStaactScattattaacgatttaaatgDtaattagatHgaYataaactatggggatVHtgccgtNgatNYcaStRtagaccacWcaMtatRagHgVactYtWHtcttcatgatWgagaKggagtatgaWtDtVtNaNtcgYYgtaaactttaDtBactagtaDctatagtaatatttatatataacgHaaaRagKattSagttYtStagagagacgatgaaaattaatcgtcaatacgctggcgaacactgagggggacccaatgctcttctcggtctaaaaaggaatgtgtcagaaattggtcagttcaaaagtagaccggatctttgcggagaacaattcacggaacgtagcgttgggaaatatcctttctaccacacatcggattttcgccctctcccattatttattgtgttctcacatagaattattgtttagacatccctcgttgtatggagagttgcccgagcgtaaaggcataatccatataccgccgggtgagtgacctgaaattgtttttagttgggatttcgctatggattagcttacacgaagagattctaatggtactataggataattataatgctgcgtggcgcagtacaccgttacaaacgtcgttcgcatatgtggctaacacggtgaaaatacctacatcgtatttgcaatttcggtcgtttcatagagcgcattgaattactcaaaaattatatatgttgattatttgattagactgcgtggaaagaaggggtactcaagccatttgtaaaagctgcatctcgcttaagtttgagagcttacattagtctatttcagtcttctaggaaatgtctgtgtgagtggttgtcgtccataggtcactggcatatgcgattcatgacatgctaaactaagaaagtagattactattaccggcatgcctaatgcgattgcactgctatgaaggtgcggacgtcgcgcccatgtagccctgataataccaatacttacatttggtcagcaattctgacattatacctagcacccataaatttactcagacttgaggacaggctcttggagtcgatcttctgtttgtatgcatgtgatcatatagatgaataagcgatgcgactagttagggcatagtatagatctgtgtatacagttcagctgaacgtccgcgagtggaagtacagctgagatctatcctaaaatgcaaccatatcgttcacacatgatatgaacccagggggaaacattgagttcagttaaattggcagcgaatcccccaagaagaaggcggagtgacgttgaacgggcttatggtttttcagtacttcctccgtataagttgagcgaaatgtaaacagaataatcgttgtgttaacaacattaaaatcgcggaatatgatgagaatacacagtgtgagcatttcacttgtaaaatatctttggtagaacttactttgctttaaatatgttaaaccgatctaataatctacaaaacggtagattttgcctagcacattgcgtccttctctattcagatagaggcaatactcagaaggttttatccaaagcactgtgttgactaacctaagttttagtctaataatcatgattgattataggtgccgtggactacatgactcgtccacaaataatacttagcagatcagcaattggccaagcacccgacttttatttaatggttgtgcaatagtccagattcgtattcgggactctttcaaataatagtttcctggcatctaagtaagaaaagctcataaggaagcgatattatgacacgctcttccgccgctgttttgaaacttgagtattgctcgtccgaaattgagggtcacttcaaaatttactgagaagacgaagatcgactaaagttaaaatgctagtccacagttggtcaagttgaattcatccacgagttatatagctattttaatttatagtcgagtgtacaaaaaacatccacaataagatttatcttagaataacaacccccgtatcatcgaaatcctccgttatggcctgactcctcgagcttatagcatttgtgctggcgctcttgccaggaacttgctcgcgaggtggtgacgagtgagatgatcagtttcattatgatgatacgattttatcgcgactagttaatcatcatagcaagtaaaatttgaattatgtcattatcatgctccattaacaggttatttaattgatactgacgaaattttttcacaatgggttttctagaatttaatatcagtaattgaagccttcataggggtcctactagtatcctacacgacgcaggtccgcagtatcctggagggacgtgttactgattaaaagggtcaaaggaatgaaggctcacaatgttacctgcttcaccatagtgagccgatgagttttacattagtactaaatcccaaatcatactttacgatgaggcttgctagcgctaaagagaatacatacaccaccacatagaattgttagcgatgatatcaaatagactcctggaagtgtcagggggaaactgttcaatatttcgtccacaggactgaccaggcatggaaaagactgacgttggaaactataccatctcacgcccgacgcttcactaattgatgatccaaaaaatatagcccggattcctgattagcaaagggttcacagagaaagatattatcgacgtatatcccaaaaaacagacgtaatgtgcatcttcgaatcgggatgaatacttgtatcataaaaatgtgacctctagtatacaggttaatgttagtgatacacaatactcgtgggccatgggttctcaaataaaatgtaatattgcgtcgatcactcacccacgtatttggtctaattatgttttatttagtgacaatccaatagataaccggtcctattaagggctatatttttagcgaccacgcgtttaaacaaaggattgtatgtagatggtaccagtttaattgccagtgggcaatcctaagcaaaatgagattctatcctaaagtttgggcttgatataagatttcggatgtatgggttttataatcgttggagagctcaatcatgagctaatacatggatttcgctacctcaccgagagaccttgcatgaagaattctaaccaaaagtttaataggccggattggattgagttaattaagaccttgttcagtcatagtaaaaacccttaaattttaccgattgacaaagtgagcagtcgcaataccctatgcgaaacgcctcgatagtgactaggtatacaaggtttttgagttcctttgaaatagttaactaatttaaaattaattaacgacatggaaatcacagaacctaatgctttgtaggagttatttatgctgtttactgcctctacaaccctaataaagcagtcctaagaatgaaacgcatcttttagttcagaaagtggtatccagggtggtcaatttaataaattcaacatcgggtctcaggatattcggtcatataatttattaagggctcttcgagtcttactctgagtgaaattggaaacagtcatccttttcgttgtgaggcatcttacaccgctatcgatatacaatgcattccaccgcggtgtcccgtacacaaggaaacttgttaccttggggatataagaaaactcacacgtctcattattaaactgagtacaatttttgcacgagaaagtaatgcaatacaatatgatgaaagccagctaatgaaaagggatggaacgcacctcggatctgttgcactggattaaaatccgattatttttaaaaatattcagtgctagagcatatcaggtctacttttttatctggtatgtaaagcccacggagcgatagtgagatccttacgactcaacgaaaagttataacataactcccgttagccaaagcccaatcccgattactgccctaccctaacgtctgccatctaaatatcgaacttgttatgatcaatgtgactacctcccaccctttccccttcatttgttccactggggataagctagcgttttcagaatcaatgcaataagaatagccaattgtctcacttcatcagagctcttggcaattccaggcgctacgtggttctggaatatattcatttttcaaatagtaatacgtttagtgttgctattgtctacacgtttggatattacgttatgtgagcggacatcaatagttgtctaactctttagtaagccagagatagcactcttagcgaatggataccatcttccataagtttagttaatagtccgaaacaactgcttcgagcatatttgaacctccttgtaggcaaatagcctcttcaaagcaatcttactaatagatagagtttgttttaagggactactagaaatgggacaatcttaatagtatgacctaaactgacatttaaagatatatccaggtggcaagcataaagatcattgcgccacctccaccgtgggattacttatcagtcgatatcctatatgctaagtttgcgacggcagaatacaaactaagctgagttgatgctaaccttacctatgataccccattggaccggttaacagccctacttattccaaataaaagaacttttatgctgtagaagctattatagtgatgcctggtaacttcagtatattaaaatgacacacatacgccatatagagctcctggaactttgaataatgagcgaacttcgaagttgaagagcaagaaaccatatgtcacggttgcctaaagcccggtaaccagacatgtgctatcattgatcattatcgaggttttcataaccttgacccattatcggctgtgcgcggacaagtacttaaatcactagtttcttcacctgcttatcggtaagaaataaggttggcaaagaatcgcataagacggacgtagagccgcagcgttgtgcgagtccaggtgcatgcgcagcaataggattttaaattttgttccatttttaatttagccgtaaggatgtccgtaaatgattgaaaattggattcaatctttgggcctatgctactggaacctgatcgacaaaatttcaaacatacgttaactccgaaagaccgtatttttgcggctagaatagtcagtcgcttggagccatataccttaccacttaaacgacgtgctcctgtagttgaaatataaacagaacacaaagactaccgatcatatcaactgaagatctttgtaactttgaggcgaagcaccctcttcgagacaactaagagtaaagtaccgggcgccgcaaggagtcgattgggaccctaaatcttgacgaattgctaagaggctcagagctaccactgtaatttctctagagcccataataaatgaacgatacatccgtaggtagcacctaagggattataatggaagccaaatgcagttaataatattatatactggcgtacacgattcgacggatctctcacatagtgattcacgacccccccctttgattgacacagcgtcagcattttgcaagaacgatcttctgcatagggtgcgccaccgtaaggatgacgtcgaagctacaactgggtataatttaccatgcttccctgatgctgagtgcaatacactaagaatgagtttttaccccatatcaccagtatttgttctgttattgcgaagaaatggctatgctgagttggcgactaaagtcacccatcctttttattaggtaaccccctcccttaaactaactgatttgctggagctgccctgcatacatatactttatcatttatggacgtccgtgacgcttattatccaccatagtcgatatgctacacggattcattaatggatcgtaggagtttaagttatatttactaagatcggtctcggctactatcccgccttacccggcgctatttacggccatttttaatatattgacggtaattattcctatggtttcgaccgcacgtccttggacaagaaagaatggcaaaaaaaatgtaaaagaaaaaaaatattgagtccctaccatcatataaaaaatatgtgatgagtaacttgacgaaatgttagtggttattaaagactatctattacaccttttgttttctgtcgtagtatattaaagtctagaagccttacaggaaaatcagggttatacagccgatactccgcagcatgaatcatcgaggaggtgtcctaccatcgcgccttgtaatcttgtctgtgtatactgtatttagaccttttatacaaagtaaatatctcggctttatgtgattgggaggggcctactcaaacatgatgacttgacctaataatcactgtgcgggcgtcttatgactagctattccttgaaatccaccaccaaatggttaatatgtaaaaactttgacgatgaaacaaggtgaatgtgtagttactttgtgtaattagctgcgtcgagcattgcttgtaaaaccgtcaatcgcacacgttacttccataaaatttctacgaatacacccttcttaaaaaaaacgtaggaattcacgagtttaacaaacgataactgtataaagtggaagtccgaagaaagcagatgcccgaactactcgaagatgtttcgttttcttaaccataggggcttcttaatggcccactacgcacattttgttcaagcccgagagggacatccccattacgggagtattactaaaactgttccgtaatacgttcagcaagggatgaaaaaggccactgctcaagttattgacgtgggagtattacatcggaagcctgaatcccacactatgatggtctgtacaggcctagggactgcgtctagacggtattaccggcttctaatcatacgatcgtgagtcttaacgggaagtaaggctcacacctaccccaaaccatttatctatgtaagtataaaattgtgcgtaagtgttcaaagtggacaataaagacgtggcaaaaacccccgcacataagccgctttagatttcacaaataccaatgcggttaaaaacatccttgagtcgtacatacaccatactcgcgttaaacggatataacagaagataataaatccggatgtggagtcggtgtaactatagaaagccaagtgaaataatgcttaccagtcatttagctatacggctttcatttcatgtcaagagggtggagtttgacctgtacagttgatatatcaccgatacttagaactcacctaaagctaaaattgctcgcagcgtgtaatccgcatattacaaacaatagatgggattcattatacataagacacgatgatctgctttttcaggttgcgagatgttgcctatcgtcaatcgagtcctgccttacaccacttaaacaaaagtattgacagggaacctattttcgaggtattatatagtccagcttgaatatcaatttgacagttaacctagtgaaaatcagtaagaggaaatacgccacattctccagtgaaattctacgggttatcgtctagtccaactatcaattataactcacgagatataagtaaattctcgtacttggcctgatttttattatactttggatccttagtaaacaggaagggagaaaccttcaacgaaaaacactggattttgttttactctcaaagctcttatatgacggaaataccctgtcaagtcttaactttattactagactaatgaaatgggcttggggtggccagaatcatagtacaatttagcggatacactattcggactttcctatcggctgtctggttggataagtatggggactaataggctagacatacctatacttaaactatacaggcgtcatctatctctgcaactttggagttccctgatgttctcccgccctttgggttcacatcttctataccgacacccctaataacgattagtttgtgggttagagtaaattaatacggttaatattaatgtatcgttgaaaagctggtgtcgccaataaggtaaccggctaggcagagtatatgtcacgaagtataactaccctaatgataagctgtaggaataaaattaatgctgtctctaagcgaagagatatttccgactctgttttaatgacgaatctcattacttctgacttgcaaatgttcaatatggcacggtttcacggcacctttgtgacgcatataatgaacttagaagattataacgacggaactttatatgataatccgttacgattaaagaatctgttaaatatcataatggcattcagttctagaccgtgcatcatggtaaacttactttctctgcatggcgacatacatttcgctattcaaattcgcgtgtggttacacccactcgcacctttggaatattaagagaagatgatcagaaaatccattcgctcaatttttctgacgtacgtctaatttatcctaggagacaaatcgttttatgtctctcacatttttgaagaaaggttcgagagacaatactcaggtcctgaactgctagaagatactcggtggagcgtggcaacaatgaaaaactcgtgacataaatgaatgatacttttccaagttcagttaagtgaatatgtttaacatacccggcttttcgatcttaagctgacgctggacgtgcgagtaatgtcagtctcttacatacactagtgactccaagtttcgtcaaaaacgccccctcccttctcgagcccactcacgctatgtattgacgcgaacttgttcgggatcagacttttcaggagttcggtcgcgtgtccctatgtgctaatatataagttagatcgcattagatgctaatctgaatacttatagacgaccttcaacgagaacgggtaccaccttgaggctagagttaggtgtgaaacgacaggtagggacatataaaatttgagtgcggctttagttaagggtttaattacctactcaaacatcacgctcgcgcccttcgtacgtaatcgaccatctagaggctaaggggactgtactaggtagtgattaatgatatcctagacgcacgtgccttagatcttcagactctgatggtccgcgatcaccgtaattgtagtcctccaactcgatcactttgttggcgtcaaagaaattacgatatctaaatacttataatacaataaccaaggatgagaatgactcatcgcgttggagttatattgcttgaagttctatggaatgaaagcacgttatctgccgtcccaatatctccagtgagctaattcattggacggtccactttgatcaatccccgaggagatgttcggacactttagtctgtaacacttagcgttgagaccacgaacaattgattactcagtcttgaaggtgttttccaaagttcattttaaataagactacgataggcctttcctattgatataaactacccggctctgttgttcgtgtgagtcgtacttctctgtgtttttctgattatagcaagattcgattcttagtgtaaacagcgatttttatttgacccgtcaatgagaagcgcataggatctaagcaaaattatcaagttgtgccacaaggtaagatctttccagttattgcaggtaggatgtatcccacgttgatagtatgaggtctgacgtcaactgtctaggagagttgaccgcgtgcgggtacaccggatttgcatcgatgttgagaacgcagaactcccactgtcgtggcggcgttcctgatatttagcaagaggcgttgataaagccctcatcatctagatctcgacctcatctgccctcttgctccatcattttctacacagactactttcctatctacgttagtataattgctttctatcttagtatcatttagagcttctccgtcaacaggttcgtgctattaaagttagtacgaaagggacaacttgtagcaacgcatttaatcggttttcgactacttcgcacaaaatcagataaagaagtttgtcattctattagacattgaattgcgcaattgacttgtaccacttatgatcgaacactgaatcaagactgtgattaactaaaatagacaagccactatatcaactaataaaaacgcccctggtggtcgaacatagttgactacaggataattaattggactggagccattacattctctacaatcgtatcacttcccaagtagacaactttgaccttgtagtttcatgtacaaaaaaatgctttcgcaggagcacattggtagttcaatagtttcatgggaacctcttgagccgtcttctgtgggtgtgttcggatagtaggtactgataaagtcgtgtcgctttcgatgagagggaattcaccggaaaacaccttggttaacaggatagtctatgtaaacttcgagacatgtttaagagttaccagcttaatccacggtgctctactagtatcatcagctgtcttgcctcgcctagaaatatgcattctatcgttatcctatcaacggttgccgtactgagcagccttattgtggaagagtaatatataaatgtagtcttgtctttacgaagcagacgtaagtaataatgacttggaataccaaaactaaacatagtggattatcatactcaagaactctccagataaataacagtttttacgatacgtcaccaatgagcttaaagattaggatcctcaaaactgatacaaacgctaattcatttgttattggatccagtatcagttaaactgaatggagtgaagattgtagaatgttgttctggcctcgcatggggtctaggtgatatacaatttctcatacttacacggtagtggaaatctgattctagcttcgtagctgactatactcaaggaaccactgctcaaggtaggagactagttccgaccctacagtcaaagtggccgaagcttaaactatagactagttgttaaatgctgatttcaagatatcatctatatacagtttggacaattatgtgtgcgaaactaaaattcatgctattcagatggatttcacttatgccttagaaacagatattgcccgagctcaatcaacagttttagccggaaacaatcgaagcatagggacaatgtatcttttcctaaattgccatgtgcagatttctgagtgtcacgaagcgcataatagaatcttgtgttgcctcaactcgttgaaaagtttaaaacaatcgcagcagtctttttggggtctactgtgtgtttgcaaaataactgaaagaaacgcttgaacaactctgaagtagctcgagtactcattaaagtgtaacacattagtgaatatcggccaatgaaccaaacgcttcccggtacgctatctctctcatcgggaggcgatgtgcaggttatctacgaaagcatccctttacgttgagagtgtcgatgcatgaacctcattgtaacaatagcccagcaaattctcatacgtgcctcagggtccgggcgtactcctccatggaagggcgcgcatctagtgttataccaactcgctttttaactactatgctgtagttctacaggcatagtggccagtattttctaacttctctggatagatgctctcactcctcatccatcacggcttcagtttacgtcttacttgcttgttcagcaacggatggaggcattaagtatcttcactgttccctaaaattgctgttcaatatcaaagtaaggacgatacagggaaagctcaagcacactcattgaatactgccccagttgcaacctcacttaatctgacaaaaataatgactactctaagtgttgcggaagcagtctcttccacgagcttgtctgtatcacttcgtataggcatgtaactcgatagacacgaacaccgagtgagaaactatattcttgcttccgtgtgtgtgacaccaggtaattgatgcggatataagctggagatcactcacgcccacacaaggcgctgctacctctttattccaatgtgtaagaatttgctaacttcatttctagaccgcagctttgcggtcataatttcacggtacggacccttgggttagagacttgataacacacttcgcagtttccaccgcgcacatgttttagtggcttctaacatagaatttttgttgtgacataaagagtgcgtgggagacttgcccgaccgttaagccataatcaattgaaagccccgtgagtcacatctaattggttgtactgcgcatttagctatcctttagctgactcgaagagattcgattcctaatataggttaattagatggctgccgcgcgaagtaaaacgtgaaaaacgtagtgcgcagatctgcataactcgcgcttaattacttatgagtagttccaagttcgctacgttatgagagagattggaattaagcaaatatgttttatggtgattttgggatgagaaggactgctaagtacggctactaaacaaatttctaaaaccgccatctaccttatcttggagacatttaagttgtatatgtcactagtctagcttttgtctgtgggacgcgttctcggaatgagggaaatgcaagagccgattcatcaaatgcttatctaagaaagtagtggactattacaccaagcacgaatgccagggaactgctttcttgctcaggacctcgcgacaaggtaccccgcataagtcctagaattacatttggtcagcaatgctgacatttgaccgtgaaaacataattttaatcagaaggcagctcacccgcttgctctagatcttatctttgtatgaatgtcagaatttactgcaatatccgttccgaatagtgagggcttagtatagttctctgtatacaggtcacatcaaactccccctgtcctagtacagctctgagctttaattaattgcatacatttccttcaatcatcagatgaaaacaccgcgaatcatgctcttctcgtatagggcaagagaagcaacaaacaactagcccgactcacgttcatccgccgtatccttgttcagttcttactccgtattaggtcagcgaaatctaatcagaataatcggtcgcgtatcaaaattaaaatcccgcttgaggttgacaattaaaacgctgagcagttatcggctattagatagtggggtgaaagtaattggctggaattatgttaaaacgtgatattaagctaaaatacgctacttgttgccgacctaattcagtcattcgatattcagttagagccaagaataacaagcttgtataaattgaacggggtgcactaaacgatgtgttactctaatattcagcttggagtatacctgaaggcgaattcatgtatcggccaataataagacgttgaagatcacaatttggactagcaaaagaaggtgatttatgcgtggggattgagtccactgtacgagtacggtctctggaaaattataggttcagggaatataaggaagtaaagataattaccaagagatttttggtatcgctatgacccagaggtgttctaacgtctgttttgatccgcagaatttctgcctcaatgcatatttgacggacttgaactagagcctctaaagttaaatggcgacgcaactgttcctaaacttcaattattactactctttttttcctagggtattgtagaggccagtggacaaaataaatcaaatttaagatgtttcggacattaacatcccccgtagcatagaaatcatcagttatccaatctctcatcgagcttttacaatttctgctggcgctatggacagcatatgccgcgagacctccgcaagactcacttgatcactgtaagtatcttcattagaggttagagcctatagttaagctgctgacctagtaaaattggtattttctaattttattgctcaagttaaaggttagtgaagggataatgacgttatttttgaacaatgggttgtattcaattttatatcacgaatggaacccttcattcccggcataatactagacgacacgaacaagctccgatctatcagccaggcacgtgttaaggtttaattccggcaaaccaatgaagcatcaaaaggtgacctgatgcaacttagggtcacgatgagtttttcaggactacttattacctattaataagttaacatgagccttcataccccgtaagacaatacatactccaccaattagaattctgagccatcttatctttttgtatcatcgaagggtatggccgaataggttaattagttactcctaacgtctctacaggcatgcatttgacgcaccttcgaaaatagtcaatctctcgccacacgcgtctagtatgcagcatcaaaaatatagtccacggtttccggattaccaaacgcggcaaagagaaacattgtatcgacggagataacttaatacagaaggaaggggcatcttcgaatacggatgaataattctatctgtttattctgacatcttgttttcaggttaatcttacgcattcaaatgacgcctgccccatgcgtgcgcaattattttctaatattgacgagagcaatctcactccttttgggtctatttatgttttattgaggcacaagcctatacagaacaggtactattaaggccgtgagtgtgagactcaaaccgtggaaacaaaggatgggttgttcttggtacaagttttagtgcatgtgggcaatccttaccaaaatcagatgctatccttaactttgggctgcatttaagatggcggttggaggcctgtgagaatcctgcgtgtcatctttaatgaccgaattcatccatgtagattcagatcacacactcattccttgatgttgtctaaacaaaagttgttgtggacgcattggagggagttaagtaacaacttgggatcgcatacttataaaaattatatgttaaactttcacaaacgctgaagtccaaagtaactagcccaaacgcctcgagagtcactaggtattaatggtgtttgagttcctgtgaaatagtgttcgaaggtaaaatttatgtaccaaatcgaaagaacacttaataaggcttgcttgcacggaggtatgatgtttactgactctacaaccctaattttccagtacgtacattcattccaataggttagttctcaaagtgctatacaggctcctcaattgatgatatgcttcagccgctctatggatattagctcattttatttaggaagcccgcttagaggcttactatgagggaaatgccaaaatgtcatacttttcggtgtgtcccatatgacaccgctttacatagaatttgaattaaaacgcgctctcccgttcactaccatacttggtaccgtgcgcatattacatatagatataggatcattttttaaagctgtactaggtttgatcgacaatcttatgctatactatatgatgtaaccctcataatcaataccgatcgtacgatcctagcataggtggcaagcgattttatgccgattattgtgttaaatagtctgtgagtgtgattatcagggctacgttggtagaggggttgtatagacctcgcacacattgtgacatacttaacaatatacgaaaactgatataataaatccccttacccaaacaccaatcccgttgaatcaactaccataacgtctcccatataaattgcctacttgtttgcataaatctgaatacataacaccattgcaccttcttgtgttccaatcccgttaagattgccttgtcagatgatatgcaagaacaatagcatttgctagcaattattaacagctcttcgaattgcctccacataacgcgggagggtatattttaatttggcaaatactaagtactgttggcgtcatatgctattaacggttggatattaagttatgtcagccgtaagcaagagtgggcgaaatattttgttacccagtgagagcactcttagagtttggatacaataggccatatgttgacttaagaggacgtaactacgccgtacaccattgttcaaccgacttcttggcaaatagaatcgtattagcaatcttaagaatagagacacgttcgtgttagggtatactacaaatccgaaaatcttaagaggatcacctaaactgaaatttatacatatttcaacgtggatagatttaacataattcagccacctccaacctgggagtaattttcagtagatttactagatgattagtggcccaacgcacttgactatataagatctggggatcctaacctgacctatgagacaaaattggaaacgttaacagcccttatgtgtacaaagaaaagtaagttgttgctgttcaacagatgatagtcatgacgcgtaacttcactatagtaaattgaaacaaatacgcaatttagacagaatggtacggtcatgaatgacagtaattcgaagtgctagaccaacttaaaataggtaaacgtgcccgaaaccccccttaacagaaagctgctatcatggtgcagtatcgacgtgttcagaaacttgtaacttttgagcaggtccgagcacatggaagtatatcacgtgtttctgaaccggcttatccctaagatatatccgtcgcaaactttcgatttagtcccacgtagagcccaagcgttgtgcgactccacgtgcatgcccagaaatacgagtttaaatttggttacatggttaattttgaccgaagcatcgcactttatgattgataattggattcaatatgtcgccctatgcgaatgcaacatgatccacaatttggctataagacgtttaatccgtatcacactttgtttgcggctagtatagtaacgcccgtgcaccaagagtcagtaacaattataagtactccgcaggtacttcaaatataaaaactaatcaaacacgacccatatgatcatctgaagatatttggaactttctcgacaaccaccctcgtactcaatacttacactaatcgacaggcacacgcaacgtgtacagtcgcaccatattgagtcaagatttgcttagtggcgatgagcgtacacgcttatttctctagtcacaattagttatctacgagacatcacgagggagcaaataagcgatgttatggctacacataggcacgtatgaatatgatataagccagttaaacagtcgaaccatcgagcaaattctcatgcaccaacccacacgttgaggcacaaagagtaagctgtttgaatgtaacttcttctgctgagcgggccccaacgtaaggatcaactagaagagaaaactcggtattagtttaaatgcgtcacggagcatgagtgcatttcactaagaatgtctgtgtaaccaatataacatctatttgttatctgattgcctacttatggctttgcggtcgtggcgactaatgtctccaatccttttgaggtcggtaccaactccctttaaattacgctgtgcaggctcatgcactgcatacatatacggtagcaggtagggacctcacgcacccttattataatcaatagtagttatcagtcaacgaggcaggaatgctgaggtcgaggtgttggtatattttctatgtgccgtctaggcgactatcacgcattaccaggcgagatttaagccaattttgaatatagtcaacgtaatttttactatgggttccaccgaaacgccttgcacaactaagaatcccataaaatatcgatatcaaataaaagattgtgtcaataccttcatatatattttttcggttgactaacgtgaactaaggttaggggttttgtatgtctatataggaaacagtttcttttctgtcctactttagtaaagtcttcaagccttactccaaaatcacggtgattaagccgttactcagcagcatgattctgcctgctcgggtcctaaaatccagccttgtaagagtcgctgtgtattagctagggagacctttgttaaaaaggatatatcgcggcgggatgtgagtgcgtggcgcatactcaatcttcagctcgtgtcattataatatctctcccccacgcttttcactagatatgccgtgtaagcaaacaccttatgcttaatttcgaaaatattggtacttgaaaaaagctgtaggggtacttaatgtctggtaggagatcaggagagaattgagtgtaaaaccgtaaagccctcacctgacttcatgtaaatggcttagaagactccatgatttaataaatactacgaaggaaagactggatctaaagataactctagtaaggccaactcccttcaatgctgttgccagttataatccaagagctgtccttttctgaaccatagcggcttctgaagcgaactagaagcaaagttggttctagccagacagccacataccctgtacgggtgtattactaaaactggtccggtattagttcaccaagggaggaattaggcaaaggatctaggtatgcaagtcggagtattacatccctaccctgaatccatcaataggttcctctgtactggccttcgcaatgagtattcaaggttgtacagccgtataataataagatagtgactatgaacgggaagtaacccgctcaccttccccaaaacattgttatatctaagtattaaagtctgccgtagtgttaatactcgaaaataaacaactggcaaattacaccgcacttaagccgcttttgatttatatttttccaatgcgcttttaaaaataattcagtcctacatactaattaagacccttaaacggagatatcacaagttaagttttaaccatctcgactaggtggaactatagatacccaactcaatttatcattacctgtaatgttcctagaaggattgcatttcatgtcaagacggtggagtttcacagcgaaacttcagtgtgaacagattctgagaaatcacctaaacctattagtcagagcacccggttagaaccagttgtcaaaaaatagagcggttgcatgagacagaagtaacgatgagatccgttgtaacgttgagacatctggcctatcgtcaatacagtcctcccttaaaaatatttttaaatactaggcaaacccaacataggttagtcctatgtgatacgccacatggtatatcattttgtaacgttacctagggataatcaggaagtggaattacgcaaaagtagacagtgaaatgcttagggttatagtctagtccaaagataaaggataaagcacgtcagagaactatattagccgaatgggaatcattgttaggagactgtggatcatgtctaaaaagcaacgcagaaacagtcatcgaaaaaatctcgtttttgtttgaatctaaaagagctttgatgaccgatagtacctgtatactagttactgtattacgtgtctaatgatttcggattggggtccccagaatcagacgtcattgtagacgattcaagtttaccaatttaatttcccagctctccttggagaactatcgccaataattgcagtcactttccttttctgaaacgataaagccgtcagagttctctgcaacgttggacttacctgaggttctaacccactttcggttctaatagtagttaacgacacaacgaataacctttactgtggggctttcacgatattttttcgcttattattaatggttacgtcataagctggtgtccaaattaaggttaccggcttcgcagagtagttgtatccaagtataacttccctaatcataagatcgaggtagaaaattaatgctgtctctaaccgaacagatatgtcccactatgtggtatggacgttgctaattacttctgaagggaaattggtcattatggatacgtgtctaccatcaggtcggacgcagatatggttctgtcttcagttgatccaccgttctttataggataataactgacgattaaagattatggtaaatagattaagccaattctcttcttgtcagtgaagcatccttaactgacttgctctgcagcccctcatacatttagctattcaaagtaccggctcgtttcaaactctcccacctttggaagaggttgtcaacttgataagtatatcatttacagcattttttcggacgtacctctaatgtttcattgcagaaaattagttttttctatcgcacattttgcaagtaacgttagagacacaattatctgcgaatgaactgctagatctgacgaccgggagcctcgcaaatatcaaaaaagactgacatatatcaaggagtcgttgacaagtgctggtaagtcaattggtttatctgtcccggcgtttcgatcttaagctgaccatgcacggcagagtaatgtcactctcgttcttacaagtctgtctccaagggtcggcaaaaaagacccctccattctcgagcccactcacgatatgtagggacgacaacttgtgcggcttatgaattgtctggactgcgggcgagggtccatatctccgaagttagaagggacatacctttagatgataagatcaattcttattgacgaaattcatccacaacggggaacaacttcaccctagacttacgtctgaaaagacacctagcgtcttataaaaggtcagtgccccgtttcgtaaggctggaattacctacgcaaacttaaacctcgcgcccttccttacgtatcgacaagatagaggctatcgcgaatgtactacggaggcatgaatcatatactagaaccaagtgcctgtgatattaacaagatgatccgacgcgagcaccgtaattctaggcataaaactccagcaatttgggggccgaaaacaaatgacgttagctaattaattatatgacatgatcaaaggaggtcaatcacgcatcgagttcgacgtatattcattgaacttcgtgcgtttgaaagaaacttttatgaaggcaaaattgatcctgtctcctatttcatgcgtacctcctagttgataattccccgagcagtggttaggacacttttgtcggtatcaagttccggtctcaaaacgtaaaattctgtaatctgtatggatggtctgtgaattagttaatttttatgaagtcgtcgagacgcagttcctattgatttattctaaacggagatgtgcttcgtgggactcggaagtagatctgtgtttatgattattgctactttagatgctgactgttaactccgtgttgtttttcaaccgtatatcacaaccgaattggatagaacctatagtttcaagttctgccacaaggtatcatatttacagttagtgctggttgcttctttcaaacgtggtgagtttgtgctatcacgtcaacggtagagctcagtggaccgagtgcgcgttcaaccctgttccagagagggtgtgatagcacatataccacgctcgtcgaggcgttcatgatagtttgcaagagccggtgttaaacacatattattattgttatccaactaatcggacctatgcataaagcattgtctaaacagaataattgcctatatacggtagttttagtgatttatatcttagtatcagttagagcttcgaactcttcaggttcctcatatttaacgttcttcgaaagcgaaaacttctacaaacgaatgtaagcggttttccaagtagtacctataaatcacagaaagatctgtctcagtatagttgaaatggtattcagctagtgacgtgtaccaattatcatagttcactcaagcaagacgctcattaacgaatatagacaagacactatatcatataataaaaaagaacatggtgctcgaacatagttgaattcaccatattgaaggggaatgctgacatgtaattcgctactagacgatcaattccctacttgtcaaagttgaactggtacgttcttggaattaaatatgattgcgctggaccaaattgcgacttcttgagtttcagggcaaacgattgagccggaggatgtccgtctcttacctttcttgcttatgataaacgacggtccctgtacatcactgggaattctcagcaaaaataattgggtaaatcgagactcgatgtattcggccacaaaggtgttagacgttaaagattattcaacggggcgataataggatcataaccggtatgcaagcgcattgaaagagccatgagatccttatccgataaacgctgcacggtatgtgcagccttattgtcgatcacgaatttataaatgtagtctgggctgtaagttgaagacctaagttataatgaagtgcaataccaaatcgattcatagtggattatcagactcaagatatctcctgataaattacagttgttaagatacggataaaatgagatttaagattagcagcctctaatctgtttcaatcccgttggaatgtggtatgcgatcaaggttaagttaaaatcaagcctgtcttcagtcttgattcttgttctgccatcgcatgcggtctacgtgagttaatatgtagcttacgttctagcttgtgctaatctgagtatagattcgtagaggaatattatcaagcttccacgcctcaacgtacgtgtattggtcacacaagacactaaaagtggaagtagcgtaaactatagtctagttgttaaatgctcagttcttgttatattcgatatactcttggctaatttatgtctgagtatataaaattaatgatattaacttgcatttcacggatcccttagaaaaagattttgaccgagcgcattataaacggttacaccgaatcaatagaagcatacccaatagctttctttgaatttattgcctgcgcaacttggctgactctctagatccgaataattctatatggtcgtgacgaaactagttcattactgtttaaaatgccaacatgtcttttgggccgataatggctctttgcaaaattactcaatgatacgattgatcaaagcggtagttgctagtggtagcatgtaagtctatcaaatgtctgattatccgaaaatcttccaaaagagtccacgtaccatatctatctcatagcgacgcgaggggaaccttatctaactatcattccatttaccgggtgactctcgatgcaggatccgattgggataaattgcccagaaatggctcattcctgactaagggtaaggccgttctcagcaagggaaccccgcgaatctaggcttataccatctagattgttaactacttgcctgtagttctacagccatactggacagttgtttctaaatgatcgggattcatgctagcactcctctgaatgcaccgcgtaagtttaactattacgtccgtgggcagataaggatggaggctgtatgtatcttaactgttacctaatatggctggtaattatcaaagtaaggaccttaatgccatagcgctagcaatcgctttgtatactgaccatgtgccaacctctcttaatctgtaaaatataatgtcttagctaactgtggacgatcatgtctctgcctagagcttcgctgtatcaattcctatagccagcgtactagtgacacaacaacaccgtgtgagaaaagatattagtccttacgtctgtctctctacagcttattgatgaggattgaacatggacatatagctccccctcaaaagcagatgctacctctttattccattctcgaacatttgccgaacttaatttcgacaaacctgaggtcacgtcttaatttatcggtaacgtcacgtccctttgagactggataaatatattaccaggggccaacgagcaattgttggaggcgcttctataatacaaggtgtcttgtcaaagaaagacggcgtgcgtctcgtgcaactcacttaaccaatattaatgtgaaacccccctctctcacatcttatgcggtgtactgccctggtacatttcctgtacaggactccaacagtgtagattcctaagatagctgttggagttgcctcacgccagatcgaaaaactgaataaactagtgagctgagctgcagaaataccgcttaattacttatgactagttcaaagggacctacgtgatgtcagacattgcaaggaagaaattaggtttgtgcgtcattttggctggactagcactccttacttcccctactattcaaatgtcgtaaacagcatgagacaggatcgtgctgacatttaaggtctattgggaacgaggctacctttggtcgcgcgctcgcgttctccgaatgaccgaaatgcatgagcacagtatgcaattgcttatagatctaaggtctggtcgttgaaaccaagcacgtaggcctgggaaatcagttcttcctcagcaactacacaaaagcgtccaagcattagtacttgtagtaaatgtccgaacctatgcgctcatttgaaagtcaaaaaatatttttaagcagtaggcacctaacccgattcctctacttagtagctttctttgattctcagaattgactgcaatatcactgcacaattctgtgccattactagacttctctgtattaacgtctcatcttactaacactcgcctaggacacatctgagagtgaagtatttcaatacatttactgaaatcttcagttctaaaatccccgaataaggctcttatcggtttggccaacacaagaaaaaaacttcttgcaccactcaccttcatacgcaggagcctggggaacttagtaataactatttcggcagacaaagcttataacaagttgccggcgcgtataatatttaaaagaccccttgagctgctcaattaaaacgctcacctggtataggctattagatagtgccgtcttagtaaggggcgggaattatcggataaactgatattttgataaaataaccgacttgttcacgacataagtcactaaggagattttatctttctccaaagtatatcttccttggataatttcaaagcgctgcaatttaagttctgttactagtttatgctgctgggaggtgaccggaaggcgtagtaatctagaggcaaattataagaagttcatcatatcattttcgactacaaaaacaaggtgttgtatgccggcgcattgtgtaaactggacgagtaccctagatggaaaattatacgttaagccaagatttcgatgtaatgataattacctacacatttttgctatccataggaacaagagctgttctataggctcgtggcatacgaacatttgctgccgctatgaatattggaagctcttcaactacagactctattcttaattgccgtcgaaaatgggccgaatcggctattattaatactcggtttttccgaggggattgttgtcgacagtcgtaattattattaatattgatgttggtgaggtcatttaaatacaaccttgcagacaatgaataagggatccaatctctcatactccttttacaattgctcatgcccctatgcaaaccttatgccgccacacctccgcaactctctcttctgaactgtaagtagcttcattactggtttgagactatactgaagctgatgacattctaaaatggctattttcgaatgtgattcataatgtttatcgtttgggatggcagaatcacgttatttttgatatagcccgggtattctattgtatagaacgtatgctacaagtcattccccgaagaagactagaagtaaacaacatgcgaccatcgttaagccacgcaaggctgtagctttatttcccgataacctatcttccataaatagcggacagcaggatactgacgctcaacatcagtggttatggtctaatttttaacttttaataaggtaacttcagcaggcatacacagtaactctttaatttataatcaaattagaagtctgacacttcttatatttttctatcatccaacgcgatcgcccattagcttattgtgttactaataacgtatctaaaccaatccttttcaagctactgcctatattgtcaatatatacaaacaacaggatagtaggctgcttaaaaaatattgtcaaccgtgtacgctttacaatacccggaaatcacaaactttgtagacaacgagtgaaatttatacactacgaagggccagcgtacaagacccatgaattaggcgatatgtttattctgacatattggtttatccttaatctgtcgctgtaaaatgaagccgcccccatccctgcgaattttttttcgaagattcacgactgaaatataaatacgtttggctatatttatgttggagggaggcaatagcctttactgttaaccgaagatttagccagtgagtgtgacactaaaacactggaataaatgcaggcgttcttctgggtaaaaggtttagtcaatctcgcctataagttcatatagctctggatataattatctggcccatgcatttatcatggcgcttggtgccctgtgtgaagccggcctctcatattgaaggtccgaagtattccatgtacattaagatcactctctcattcatgcatcttggcttaacaaatctggttgtccaagctttccaggcacgtatggtacaaattcggatcgaatacttataaaaatgatatgttaaactgtctaaaacgctcatctacaaagtaaagtgcactaaccaatagagtctcaagaccgtgtaatgctggtgcactgaatgtgtaatacggttagaagggattagttatgttacaaatccattgaaaacttaagaagcattgcgtgctcggagggtgcatcttttatcaagagactaacattattttcaacgacgtacatgctttacaatagggtacttatcaaacgccgagaaacgcgcctatagtgatgttatgattatgacccgatatccattggaccgaattttatgtaggttcccagcgtactcgcgtaatatctcggtattgccataatgtaatacttgtcggtctctcccagatgaaaaagcgttacagagtatttcaatgaaaaacagcgcgcaacgtcaatacctttaggggtaacggccgctgatttcatatagatatacgataagttggtatagctctactaggtggcatccacaatcgttgcatttactatagctggttacaatcataatctataccgttccttacatactaccatagcgggatagcgtttttttgccgttgattgggtttaagaggatgtcagtctcattatatccgattcggtgggagagccgttgttttcaaatcgcacactttgtgacataatgtacaagataacaaaactgatataagatataaactgtcaatatcaccttgacacttgaatcaaagtaaattaactcgcaaatataatttgactaattgggtgcagatttctcaattaataaaaaaatggcaccggatgggcttacaagccccttatcattcacttgtatcatgatttccaagaacaatagaatttgctagcaagtatgaacagagattcgaattgcatccacagtacgccggagcgtttattttaatgtggatatgacgatgtactgttggcggcatttgctagtaaccggtccttatttacgtagcgcacacgtaagcatgtctgggagaaatatggtggtacaatctcagagaaagattacagtttggtttaaataggacttatcgggtcggaagtggaacttaataagcagtacacaattgggcaacagacgtcttgcctattacaataggattacaatgcgttagatttcagacacgttcgtgtttggctattcgtcaattccctaaatagttagacgatcaactattatcaaagtgattctttgttcatcctccattcatgtaacagatggcacactacgcataacgccgaggaattttaacgagatttaagagagcagttcgggcacaacccacttgactttataacagctcggcagcataaacggtaatatgtgacaaatttccaaacgttataagaacgtatgtgtacttagaaaactaagtggttcatgttcaacagatgtgacgcagcaagcctaacttatctattggttttgctataaaagaacaaagttacacagaatcctaagggcttgtttcacacttatgcctagtgcttcaccatcttaaaatagcgaaaccggcacgaatcaaaccttaaaacaatgcgcagatattggtgatggtgactccgggtatgataatggtaactgttgaccagcgcccacctcatcgaagtatagaaagtggttaggataaggatgagaccgaacttatttccggccataactttagattttctacctagtacacaacatcagggcggacacgaaaccgccatcacatcatataccaggtttaatttgcttaatgggggaagtgtcaacgaaccttcgaactttagcaggcatatggccattatatatggccccagagcagaatgctacagcagacaaaatttggatttatgtagtttaatacctatcaaacttggtgtgaccatacttgtctaacgacagtgcacaaagtgtaagttacaattattactactcagcagcttctgcaatgataaaatcttatcatacacgtcacatatgataatatctacttagggggaacgggctccacaacctacatagtactcaatacttacactattcgacaggcacaccaaacctgtacagtcccaaaagattgagtcaactttgcagtactgcagatcacagtaatagcttagttagcgagtcaaaattagttttctacgagactgcacgaccgtgcaaatttccgatgtgttggctacaaatagcaacgtatgaatttgtttgaagccacgtaaactgtacaaccttagagataagtctcaggctactaaaaacacgttgtggcactaacaggatcatggttgattcttacttattcggctgaccggcccaataagtaaccttcaactagaacagaataatcgggagtagtttaattcagtcaaggtgcaggtctcattgtaactaacaagctctgtgtaaccaagttaaaatcgttttcttagcggattccctacttatggatttgagctcgtccacaatattcgatacaagaagtttgtggtccgtaacaacgaaattttaattacgctgtgcagcctcatccaaggaattaatagaaggttgatggtaggctccgaacgctccatgattataatcaagtggactgtgcagtaaacgaggaaggtatcctgacgtcgtggtgttcgtttttgttatttgtgccctatacgagtagataaaccatgaacagcacagtgtgaacccatggttgattttaggctaccttatttttaatttccgttacacagaaacgaattccacaactaacatgccattaatttttcgatatcttataaaagatggtcgaaattcattcatttattttttttcggttctcgaaagtcaactaagctgtcgcgttttgtttctctttagaggtaaaagtggctttgatctcctacgtttggatactagtcaaccattactccatttgatccgtgagtatcacctgtctaacatccagcattatgactcctcggcgaagaaaagacacacttcttagagtcgatgtgtattagctagggacacagttgtttaatacgatagtgagcccagggagggcagtgcgtcccccagtagatttattcagctagtgtaagtataagatatctcacccacgaggttcaagtgatatgcagtcttagaataatacttatcctgaatttcgatattatgggtacttcaataatccgctagcgctactttatgtctcgttggacagcaggacacatggcagtcttaaacactaaagacatcacctgaatgaatgtaatgggattacaagaatcaatgaggtattatatacgacgtaggaaactctggatatatacagtaatctagttacgccatcgcacttcattcctctggaaacttagaagacatcagctgtacgtggaggaaccagacccccgtatgtagccaaatagaaccaaagttgcttatacaaacacacccaatgacaatggaccgctggagttcgtaaactcggaacgtagtactgcacaaacccagcatttagcaataggagctacgtatgcaactcccacgtggtaataccttcaagctatcaatatataggtgcctagctaatcgcattcgcaagcagtattcaagcttgtaaaccagtataataattacagaggctctatgaaacccaactttccagctaaaagtcccaattaaatggttatttcgtacttttaaagtcgcccgttctgttattacgcgaattgattctactccaaaattaaacacaaattatcaaccgtttcatttatatttgtcaatgcagctgtttaaaataaggctctactaaattataattaagacacttattaccagatttctctagttaagtttgaaccagctcgactaccgcgaaagatacattcccttctctatttttcagttcatctatgggtcagagaagcattgaatttattctattcaccctcgtcgttcacagcgaatcgtcagtgtgatcagtgtatgagaaatatcctaaaccgtttagtcagaccacacgcttagaacaagtggtctaaaaagactgccctggaaggagtaagaagtatacagctgatccggtgtatccttcagtcatctgccctatactaattacacgacgcaaggaaaaataggtttattttctaggcaaacccttcataggtgactccgatgtgttacgaatcatgcttgagaatgtgctatcgttaccgacggataataacgatctccaatgaaccaaatgtagaatgtctattgattacccttttactattcgacttagagataggagatagaacctcagtgtacttttttagccgaatgggaatctttgggaggtgaatggccataaggtcgtaaatccaaccctcttaaagtcttccatattatatcgttgttcgtggaatcgataacagatttgttgacccatagtaaatgtatactagtttatgttgtaagtgtagattgttttccgattgccgtccaaactttatgtcgtaattgtagaccagtaaagttgaccaaggtaagtgcccagcgatcctgcgagatcgatcgccaatttttccagtcactgtaagtgtaggtttagataaagccgtatgagttatatcataagggcctcggaaagcagcttcgaaccaaagttcccttataatagtagtttaactataaaagtatatactggtctgtcgccctttcacgatttgttttaccggtttatgaagcgttacgtcattagagcggctccaatttaaggttaacggcttccatgtgtagttgtatacaaggataacttaaagtatctgttcagcgagctagttaagttatcctcgatagaacacaactcagaggtcccaagatcgggtttgcaacttgctaatttattctcaaggcaaattgggaattatcgatacctgtataccataaggtcgctcgatgtgatgcttatgtcttctggtgatcctaccttagttagtgctgattaacggaacattaatgtttatcgttttgagatttagccaattctctgattctaactcaagatgccttatctgacgtgctatgcagcccctaagtattttacattgtaataggacacgctcctttaaaactcgccaaaaggtcgttgtggttctctactggttaactatataatttacagctttgttgagctagttcctctttggtttaagtcctcaatattagttggttcgagcgataagttggctagttaccttagtcactatattagatccgaatgttatgcttcatctgaagaccgccaccctccaaaatttcttttaagactcacttattgcaaggtgtaggtgaattcggctcgtttctcaagtggtgtatctgtacacgagtttccatattttcatcaacagccaccgcacacttatgtcactctaggtattaaaagtcgctctacaaggggacgcaattaagaaacagacatgctagtcaaaaataaacatagcgaggcaccactaattcggccgcttatcaatgggatgctctgcgcgagacgcgccagagctcagtagttagttcggacatacatttacttcagatgatcaattagttttctacaaatgcttactctaccccgaaaaaagtcaccagactcttacgtctctttagtatccttccgtcttatataaggtcagtcccccgtttcggtaccctggaatttactaagaataatgaaacagcccccaaggacgtacgtttacaaatgatagaccagatcgcctagcttattccgacgcatgttgcatagaattgaaccaacggaatgtgagagtaactagatgagccgaccacagcacccgtttgcgtcgcagaatacgcctgatagttcggccacgaaatcatatgtcctttgagtattaagtatttgtaatgatcaatcgagctcaagcaagcttacacttcctcggatattcagggaacttagtgcctttgaaagatacgttgatcaacgaaaaattgataatggctcatatggaatgcctacctcatagtgctgaattaacacagcactgcggacctaacttttcgaggtttcaagttcacgtctcaaaacctaataggctggaatatgtagggatcctcggtgaatttgtgattgggtttgttgtagtactgaccaagtgaatattctttttttctaaaagcagatctgctgccgggcactacgaaggagatctctgtgtatcattattgcttcttgacatgatgactcttaaatcactgtgggtgtgcaaaacgatagcacaacccaattcgatagtacatattgttgatacttcgcactaaaccgttcatatttaaaggttgtgctccttccttcgttaaatactggtgacttggtcctatctactattagctagacctctggggaaccacgcccccgtaaaacctgtgcaagagagggggtcatacatcttagacatcgcgcctccaccagggaagcattgggtgattgaccaggtgtgtaacaaatatgattattcttatactaatattagcaaagatgcataatgatttgtattaaatgtataattgaattgataagggtcttttagtcagtgatagagtagtataaggtagacattagaactcttaaccggacgcagatttttcggtcttagtaagccaattagtcgacaaaacaaggtaagagcggttactagtagtacctataatgcactgaatcttcggtcgaagtatagttctaatgctatgcagattgtgacggcgacaaatgttcagacttatatcatgaaacaagctcttgtaagtattgacaaatgaaaagattgaatatttttaaatacaaaatgcgcctacttattaggggaattaaccagattgaaggccaatcctcacatgtaatgagataatagacgataaatgaaattcttgtaatagttgaactgctacgtgatgggtattatatatgattgagatcctccaattgccgacgtcttgtcttgatgcccaaaagattgtcaacgaggagctccctcgcgtacctgtcgtccgtatcataaacgacgcgacatgtacagcactccgaagtataagcaataataatgcgggtaatccagactagatcttttcggactcaatgcggtttcacggtaaacatgattaataccggagagtagtcgagcttatcagcgatgcaagcgaattcattgtgccaggagatacgttgcagataaaaccggcaacgtatgtcaacaagttttggcgatctcgttgtttgtattcgacgaggcgcgggaacttcaagaactatcgtatattcaagtccattaccttttagtttcagactggtggagctgactaaagttatatcatcattttgtacactggtttagttaacgataatttcagatttaacatgaccagacgataatcgctgtatatccagttggaatgtggtttgccagaaaggttaacttataatcaagcctctcttcagtcttgattcgtcgtatcccatccattgcgctatacctcagtgtatttggagctgtagttataccgtgtgctaagatcagtagacatgacgagagcaatattatctaccttacaagcatcaacggacgtctagtcggaacaaaagactctaaaactcgaacttcaggttaatatactatagttctgtattcagcagttattcttatattcgatattatcttgcctattggatgtctgactttagtatattaatcatagtatctgccatgtaaaggtgccagtactaaatctgtttcacagtgcgaattataaacggttacaaccattaaagacaacaagaccctatagctttatttgaattttgtcaatgcgcaacttggagctcgcgatacatcccaattagtctatagggtcgggacgattctacggcatttctggttataatgacaacatggattgtggcccgagaatcgctctttcattaattaagcaatcattacagtcttataagcgctacttccgagtggtagcaggtaactcgatataaggtcgcatgagccgaatagcttaaaaaacaggccaccgaacattgatagagaataccgaccacagcgcaacctttgattactttcattaaattgtacggctcactcgacatcaagcttaagattgcgataatgtgaactcaaatggatcagtactgaagaaccgtaacccacttcgcagaaagcgtacccagagaagatacgctgttacaatatacagggtgaaattattgcctgttcttcgtaaccatttcgccaaacttggttagaaatgatagccattcatgatagaaataagctgaatgataccagtatctttaactatgtagtcagggggaagataacgatggtccatgtatgtttctgatatgtgacagtattggccgcgtaatttgctaacgaagctacttaatgcctttgagcttcatatagatttctttaatcaaaatcggcaaaaagatagtatgagctataatatatgctagtagagaactctggaccatcatctatatgaatactgattcgagcgtgcaattactttagcctgcgtactactgactctacaaaacactctgagataagtttgtagtcagtaagtcgctctctataaaccttttggatgaccattgtacagccacttatagatcccaataaatagcacaggagacagagtttttcaatgctcgatcatttgccgatagtattttcgtctaacctcagggcacctattatttgatacctaacctaacggccctttcacaatggagaaatatatgacatcgggacaaacacaaatggtgggtggccaggagatatgacatggtggcgtctctaagaaacacggactccctctaggcaaactcacgtaaccaattttaatgtcaaacaaaacgctcgaaaagattttgccgtgtaatgacctggtacattgactggtcaggaatacatcactgtagttgccgtagtgtcctgttggtgttccatcaagacacatcgtataacgcaatttacgacggacatcagatcaagttatacagattatttaagtatcacgtgtgcattgggacataagggatctcacacatgccttggaacatttttgctttgtgccgctttttcgctgcactaccaatccttacttaccagtatattcaaaggtcgttaacagaatgagaaaggttagggctctaagttatcgtcgattgggatagacgagacatttgcgagcgccctccacggatacgaatctcccatatcaatgtgaactggatgctatgcagtttagttcttacgtctcctagtggtaaaaatcaaagtagcactcgcatagcagttattcagaacctaatacacaaaaccgtcaaacattttctaattctaggtatgggccgatcataggagctaaggtgaaactcataaatgttttgttagatctagcatcctaaaaagatgcatatactgagtagctggcgtgcattctctcaattgtatcctttttaactgaactagtcggtcccatttcgtgactgagatctattaaccgataagattaataacactcgcattcgtatcagctcagagtgaagtttttcaataatttgactgatatattaacttctaaaataaccctttaagcctcggatccgtttcccaatcacatcaaaaattcttattccaactatctacggattaacaacgtgcatggggatcgtagtaagaacttgttccgatcactttgagtatatcaagttgacggcccggttattattgaatagaaacattcacctgctaaattaaataccgcacatcggatacccgatttcagagggccgtcttactaagggcaggctttgttcggtttaactgagatgttcattattttacagtatgcttcaactaatatgtaacgaaggacagtggatctgtctccatagtagatcttcagtcgtgaatttcataccgctcctatttaagttcgcgttcgagttgttgatcatggcacgtgaaagcaacccctagtattctagacgaaaattttttctagttcatctgataatttgccaattcaaaaacaaccgctggtttcccggcgcattctctaaaatggaagtcgaacctagagccattatttgtcggtaacccatgagttccttcttttcagaagttaatacactgtggtcctatacagaggaaaaacagcggttatatacgatcgtggcataacaacattggatcaagatagcaatttggctacctattctaattctcactagattcggtattccactacaatatcggcagattaggattggatgaataatcggtgtttaagtccggttgcgtctccaatctcctaatttttattaatattgatcttggtgacctattgtaaataaaaacttcaagactttgaataacggtgaaaagatagaagactcatttgaaaatggatcatccacagatccaaacattagcaagacactaatccccaactagctattctgatcgcgatcgtgctgcagtactcctgtcacaatagtctgttcatgatctaattctttttgggctttgttcgatggtgattcagaatctttatccggtcgcttccctgtagctactttgtggggatattgcccggggattatagggttgagatcgtttcctaaaagtatttaaaccaagtagacttcaactaaactacatcagaacatcgtgaagacaccatacgcggtacctttatttaccgataacatttcttcaagaaataccggtaagcagcataatgaccctaaacagctcggggtatcgtcgtagttttaaattttatttaggttactgctcaaggaataaaaactaactatttaatttataataatattacaaggctcacactgattagatttgtctataagacttcgcgatcccccattaccggattgtcttaagaataaactagataaaccatgcattttctagataaggcctttagtctaattagatacaaaaaacacgatagttgcatccttaatttattgtgtcaaacctggaaccttttaattacccgcaaatcactttatgtcgagactacctctgaaatttattatctacctaccgcatgaggacttgaaccatcttgtaggagttatgtttattagctaagattcgtttatcctgtagcggtccatgtatattcaacaagcaaaaagcactcagaattgtttttagttgagtcaagactgatatataaataagtttccctagttttttcgtggtgggacgatattgaattgaatcttaaccgaagagtttcccactctgtcgcacaataatacacgccaatatttccagccctgcttatgccttaatcggttactcaatctcccattgaagttcattttgatctgcatagaagtttcgggcccagccttttttctgccaccttcctccaagctctgtagacgcactctaagattgatgctcacatgtattaattctacattaacataaatatataagtcatgcatcttcgagtaaaatatctggttctccaacatgtcctggcacgtatcgttataatgcccatacatgtagtattaaaatgattgggttaactggatattaagatcatcgaaattgtaaagtcaaattaacaatactgtctcaagaccgtgtattcctcgtgctcggaagggctattacgcttacttccgttttggtatcttaatatgactttcaaaaattaagttgcagtgagtcctacctgcgtgcatcggttagcaagagtataaaagttgtttaaacgaactacttgctttacaataccggtcgtatatatcgccgtgaatccagaagattgtcttctttggattatcaaccgagatcctgtggaccgatgttttgggaccttcacagaggactccaggtagagctcgcttttgcattaatctaagaattgtacctctctaaaagatctaaaacagtgaatgtgtatttcatggaaaaacacagagaaacgtaaattactttaggccgaaaggcacatgagttattatacatatacgagatggtggtatacatcgaattcggggcatacactatagttgcattgtatttagctgctttaaataatatgatattaccttccttacataagacattaccggcataccctggttttcaacttgtggggctttttgacgatcgcactctcatttgatccgagtagggcggtgacccctgcttttcaaatacaaaaatttcgctatgaaggtaatagattacttttcgctgttatgatagaaacggtaaatttaaaattgaaacttctagaaaagtaaagtaacgagaaatgattttgtgaataatgcggtcatgattgcgcaagtaagaaaaaaaggcaaaaggatgcgcggaatagaaacttatcagtcacgggtatcttgatttcattcttcttgtcaattgccgacataggatgaaatcagattccaatgcaatacacagtaacccccacccttgattgtaatgtcgatttgaagttgtacgcgtcgacgaagtggatagtatacgggccttttgtacggtgcgatcaactatgaatctcggcgagttagatggtcgtacaatctcacacatagaggtcacttgcctgtaatgacgaattttcggctaggtactcgaactttattagaagtaaaaatgtgggcaaaagaaggattccattttacaagacgattacaatgagttacatgtctctcaacgtagtctttccctagtagtctttgaactatttaggtactccagaaaattttagcaaagggtttctgtgtgaatccgccattcatgtttatgatggaacaataagaataacgccctcgtatgttatcgacagtgaagtcagcagttcggccaaaaacatattcaatttagtacagatccccagaagttaagctaagtgctctaaaatggcctaaacggttatcaaagtaggtctaattactatactaacgggtgcatcgtaataactgctgtcgatgcaacactatatgatagtgtcgttttgctatatatgtacaatgtgacaaagaagccttagcgattcttgcaaacttaggacttcggattctcaatcttaaatgtccgaaaacgcaaagattcaaaaatttaatctatgagcagatatgcctgatggtgactacgcgtatgttaaggctaaatgttgacaaccgcacacataatcgaactattgatagtcgggagcataaccaggtgaacgtactttgttcacgacatttattgacatgttctaaatacgtctcaaaatcacggcgcactagaaaacgcaatcaaatcattgtcctggtttaagggccgtaatgccggtagtgtcaaacttcatgagaactttagctggcttttggccagtatttagggaccaagagcactagccttaagctgaatattttgccatttatctactgttataactttaaaacttggtggcaccagacttgtcgatacacacgcatcaatctgtaacgtaaaaggtttactaagaacaagcgtaggaattgagtttatattatatttaaactaaaagatgatattagcttctgagggcgatagggctccaaatcataaagaggaatatattattacacgattagaaacccacaacatacctcgaatcgcccaaaagtttgacgaaacttggcagtactccacatctcagtaatacagttgggagagtctcaaatgttgttttattactcaatgaaccaccctcataatttcactgctgttccattaaatttgcaaacgatcatttgctttgaagaaacgtaaaatcgacaaaattacagataagtagatgcataataaaaaaaactgctcgctataacacgatcatcgtgcattcttacttaggagcatcacccgcacaataacgtaccttaaactacaacactattagaccgagtactgtaattcacgaaagctcaagctcgcattgtaaagaacttgctctctcgtaaaatgtgataatagtttgcggagaggattcaattattttccattgcacctactccactagattcgataaaagaaggtggtcctcccttaaaaagaaatgttaagtaacatcggaaccataagcaaagcatgtaagtgaaccgtcatccttccctaagaaacataaaggtttttaataatgtcgactgtgaactataactgcatcctttcctgacctactccggttccttgttgttatttctgaacgagaccagtagataaacaatgtaaaccacagtgggtaccaatggtgcatgtgacgctaccgttgttttaagtgcccgtacaaacataagaagtcataatcttacttgaaattaattttgccttttattttttttcaggctcgaaattaatgatttgttttttttgaccttctagttacgctaatatgcggtcgcctgtggtttctattgagtcctataacgggatgggatctaatacgtttggttactagtaaacaaggtataaatttgataccggagtatcaactgtataacatcaagctttatgactcatacgcgaagtaatgacacaaggctttcaggagatcgcgagtacagagccactaaggggtgtattacgatagtgacaccaccgagcgcactcactccccaagtagatttatgatcctacgctaagtattagatatataaccaaagaggttctagtcagtgcaactcttagaataataattagccggttttgcctttttaggcctaatgcaatattcagctagcccttatgtatctcgcgttccacagcaccactcatggcacgcgtttaaactaatcaaatataatctatgaatgttatgccagtacttgaataaatcaggttttttataagtccttgcatactctcgttatatactgttagagtcttaccccatagaaattctttcatctgcaaacttagaagaattctcagctacggggagcataaagtccccaggatgttgacaaatacaacaaatgtggcttatacaaacactccatatgaaaatcgaaccctcgtggtagttttagccgaaccttgtacggataaatccctccattttccaatagcagatacctatcctactacctcgtggtattaaattaaagcttgaaatatagagctgcatagcttatccaattcccaagcacgagtctaccgtcgtaaccacgatttgatttacagacgctagagcaaacccatctttaaacatataagtaaaaattaaagggtgagtgcgtacgtgtttactagcaacttcgcttattaagacaattgtttataagccataattaaaaacatatgttcaacaggttcattgatatttgtaattgcacaggtttttaataaggatctacgtaagtataatgaacaaactttttaccagagttatattctgtactttgaaaatgctcctctaccgccttagagactttcaattagattttttgcagttaatctatgcgtaagtgaaccatgcaagggatgcgattcaaccgcctcgtgctaaccctatcgtctgtctcataactgtaggtctaatataattttcagttttcgaacacataaccctttgaaaatctgctatttaatgtctcacctgcatgcactatcttctatactgctcagaacggctatacgtcactatgctccaagtgacgatttaaacgaagcaaggaataataggtttattttagtgcaaaacaattaagtgcggactacgtgctctttacaataagccttgtgattgggctataggttaagtcccatattaacgatctccaatgtacaaaatcgacaatcgctttgcattacccggttactagtcgaattacagatagctgttagatactcactctaattttggacaacaatcccaatcttggggtcgtctatcgcctgaagctcgtaaatccttccatcttaaacgattacatattatagacttgttcggggtagagatatcacagttgtgcaaacattgtaaatcgatactagtttatgttggtagtctagttgcttttaccattccccgaaaaacttgatctactatttcgacaacagtaaacttgaactaggtaagtgaaaacagagaatgcctcatagtgccactatttgtccactatatgtaagtgtagctttacataatccactatgactgagatcattacggcctaggaaagcagcgtagaaaaaaagggcccggatattacgactgtaactataaaactagttactggtagcgcgccatgtatagatttgttttaccggttgtggttgcgttaacgaatttcagccgcgaaaattgatccgttaaccagtccatctcgacttctataaaacgataaagtaaagttgatgttcagcctccttcttatggttgcatcgagagtacactactcagtgggaaatagatcggggttcctacttcagattgtattatctaggcaattgccgattgtgccatacctggataaaataagctacctacatgtgatgcttatctattatcgtcatactaccttagggtgtcctgttgaacgctacattaatctttagccgtttgagatgttccaatggataggagtctaacgcatgatgaagtttaggaaggcagagcatcccactaagtatgtgacagtgtatttcgaaacgagacgttataaatagaaaaaaggtccttctggttctattctgctgaactattgaatggaaagattggttgacctacgtactatttgcttgaagtcatcaatttgacggggtgagagacatatggtgcatactttacggactctatattttagatcagaagcttagcagtcttctctacaccccctcacgacataattgcttttaagaatctatgtttgattcctctacgggaattcggatccgttcgcatgtgcggtttatctaaaccaggggacatatgttcagctaaagcatacgaacactttgctaactagacgtatgtatagtagctataaatcccgacgatatttacaaaaagaaatgagactcaaatatatacatagcgaccctacacttattcgcaccctgatctaggcgatcctagcacccacacccgaaagtgagcactagtgtcttccgtattaaatttactgcagttgagattttagttgtctactaaggattactctaacccgtaataaggatcaagactcggtactagctttactatcattccctatgtgttttcctaactcacaagggtacgtaccagcctatgtaattacaataatgataaagacacaaaggaagtaactttacaaatgagtctccagttacactagcttagtccctcccatcttgctttgaagtctaaatacgcaatctctgaggatatacagcagaagaacactcataacgttggagtccaagaattagactcatagggcccccaacatttaatatgtactgtgagtttgaaggtgttctattgttaattcctgctcttgatacatgacacgtactccgtgtttaaggcttcggactgactttctttcataagttgagcaacgaaaatttcagaatcgataagttggattcactaactaatacggctgattgaaaactccactccggacctatatggtcgacctttatacgtaaccgatataaaacttataggctggtatatcgagccttcctagcgcaatttcggatggggtttcttctactactcaacaacggaatagtctttgtttagtaaaccagagctcaggacgcccaatacgtaggagagcgctgtggagcatgtgtcattatggactggagcactcttaaatcactctgcgtgtgctaaacgatagatcataacatgtcctgagtaaattttcttgatacgtcgcaatataccgttattagttaaacgttctcatccgtcatgcgtgaaatacggctgtcgtgctcagatatactattagcgactcatctcgcctaacacgcacacgtataaactcggaatgactgccgctcttacatattagaaatacagactacaccacggaagcattgggtcattctcaaccgctgtataaaagatgattagtcttataataagattaccaaagaggcagaatcatgggtagtaaatctattattcaagtgattaccgtcgtgtaggcagggagtgaggacgagatggtactcaggacaaatattaaccggacgaagtggtttacgtcgtactttcactattagtagtaaatacaaggtaacaccggggaatagtactaaatataatgatatctatcttcgggagaacgagtcgtctattgctttgaacattctcaaggcgtaaaatgtgctgacttatagcatgatacaaccgattgttacttttgtctattcaaaagattgaatagttttttatacaaaagccgcatacttatgacggctagtatacagtttcatcccctagcatcaatgctatggacagtattgaacttataggaaattcttctaatagggcaaatccgtcgtgatgcctattttttttcagtcacatcctcaaatggcactagtattgtcgggatcccattaacaggctcaaccacgagctcacgcgaggacatgtagtccgtatctttaacgaagcgacagcgacagaactcccatggataaccaattataaggcccgtaatcctctagacatcgtttaccaataaatccgctttctccgtaatcatgttgaataccccagagtagtccagatgataaccgatgaaacacaagtctttctcaatgcacttacggtgaacttattaccgccaacgtagctcatcaaggttgcgacatctagttgtgtgtttgcgacgagcccagcgaacttcatcaactttcgtatattcaacgccttgtaattttactttaagacgcctggtgatgtagattcttagataatcagtttgttatcggctgtactttaccataatttcacaggtttcaggtcaagaagattatagctgtatatacagttccatgctcggtgcacagaaacgtgatcggataataatcaatcgcttatgtcgtctttaggcgtatccaatacatgccccgataccgcagtgtatttcgacatgtaggtataccgtcgcatttgagctcgagtcaggacgtcagctagattagattccttaatagaatataccgacctctagtccgaactaaactatagataacgccaacttcaggttaattgtctagtcgtctgtttgcagatgggattcttagatgagtgagtatcggccatattggttcgagcactttagtttttgatgcataggatatgcaatgtatagctgaaagtactttatctgtttcaaactcacattgattaaaccggtaaacctttaaagactacaagaaaatattcagtgagggcaattttgtcaatcacaatcttccagctagagatacttcacaatttgtcttgaggctacgcaacattagacggattttcgcgttttattgaaataatcgaggggcccaagagtatccatagttcattttgtaagatttctttacaggcttattacagcttcttcagactcctacatgcttacgagttatatgctagcatgtgaacaatagattaatatacaggaaaacgtacattgagagagatgaccctacacagcgcaaccgttgagtactttcattaaagggtaacgctctcgagacagcatccttaagatggccttattgtcaaatcatttgcagaagtacgcaagatccctaaccaacgtagaagaatccctacaaacacatgagacgcggtgaaaatagacagggtgttagtattcaatcttcggagtatcaatttcgccaatcttggtgagaaagcataccctttcttcagagaaagaagatcaatcataacactatctttaacgaggtacgcacgcgcatcattacctgcctccatggatctttaggatagcggaaagtattggcagcgtattgtgatttcgttcctactttatcaatttcacattcatatacatgtcttttatcaaaatcgccaataagataggatgagctatattagatgctagtagagttcgcgccaacatcatcgataggaatactcaggacagcgtgataggacttttcaatccctaatactctctataattataactctctcttaagtttggaggcagtaacgcgctctatataatcagtttgctgcaccattcttcagcctctgatacatacaaataaattccacagcagtaagagggtttaattgagacatcttgggaacttaggattttactctaacatcaccgaaacgattattggataccgtacctaaacgaactttctcaaggcagtaatataggacatccgcaataacacaaatgctgcctccccaggagttatgtcttcctggaggctatatcttacacccactcactataggcaaactaaagtttaaatgttgattgtctaaaaaaaagatagataagagttggccggcgtagcacatgcgaaagtgaatcgtaagctataattctctggacttgaagttctgtcctgttcctctgcaagaaacaaacttcctttaaagctatttacgacgcacatctcagcaagttataaacatgttggaagtttctagtcggaattcccaaagaacggatctatctaatgcattcctacatttttcctgtctgccgatggtgccatcctattcaaagaatttcttaaaagtagattaaatgggacttttaacaatgagtaaccttacgcctctaagggttcctcgagtgccatacaccagtcaggtccgagccacatacacggagaacattctaacatagcattctcaactcgatcatttgcaggttacttctttcctatcctagtgctaaaaatcatacttgcaatcccatagcacggattaagaacctaagaaacaattcagtaaaacatgttcgaattcttggtatgggaacatcattgcagctatggtctaacgcattaatgtttgggtacatcttccatcatataaacaggaagagtctgacgacagggagtgcttgcgatcatgtctatcattgtgaaatcaaattgtagctcacatgtcgtctatgagagcgtgtatccgataagatttagaaaaatagaagtcgtataagatctcactgaacttttgaatgaatgtgaagcatatatgatctgctttaataaaactttatccataggatacgtttccaaatcaattcaataattattagtcaaaatagataaggatgaacaacctgaaggccgatcggacgtagaaagtggtcccatcactttgagttgatattgttgaaccacacgttattatggttttcaaacagtctcaggatattgtatatacagataatccgataccagttgtctgacgcccctcttacgtaccccaccctttgtgacgtttaaagcagttgttcagtattttaaactaggcggcaactaatttggaaagaagcacagtggatatgtctaaattcttgttattcaggcctgaatttaatacaccgcatagttaacttcgcggtagagttgttcatcatgcctcctctaagctaccacttctatgatacaccaatagttgttctacggaatctgataattggccaagtcataaacttccgctgcgttcaacccccttgctcgaatatccaactcgaaaagacagccttttggtgtccggaacaaatcagttacttcttttctgatgttaattctctgtggtcagatacagaccaaaaactccgcggatttaccatcctccaagaacaaatttgcatcaacatagcattttggctacatattctaagtctcaatagtttaggttttcaactacattatcccaacattaggattggaggaataatagctgggtaagtccccttgcgtctacaatcgactattttttatgaatatgcttctgccgcacctatggttattaaaaaagtcatgactttgaagaaccctgaaaagatagatgaatcaggtgtaatggcagcagccaaagagcatataattagcaacactctaagaacattatagatatgatgatagcgatcgtcatgatgttatccggtcacaatagtagcttcatcagctaattcgttttgccagtggtgacttgcgctggaagaatcgttatacggtcccttccctcttgatacggtgggggcttattcaaccgcgtggattgggttgtcatacttgcattaaacgatgtaaaccatctagtagtcaactatactaaatcacaaaatagtgatcaatacatacccgcttcatggttttaaccatttaattgattaaagatattccgctaagaaccattatctacctaaactgatcgccgtatcctagtagtttgaaatttgatgtaccgtaatgatcaacgaagtaaaacgttatattgtatgtagaataataggtcttggagctaaatgatgtgattggtagtgaagacttacccttacaactttaccggtttctcggaagaatatactagagaatcaatgcatgggctacataagcactttagtctaatgagataaaaaatacacgagtcttccatcatgaattttttgtcgaaaaactcgaacctggtaatttaaaccatatatctttatgtcgtcaataactctcatatgttttatataacttcccaatcacgacttgtaactgcttgttcgactgagctgtttgagctatgaggccgggatccggttgagctacatctatttgctacaagaaaaatgaaagcacatttgttgggagttctggctacactcatagagaaataagtggcccgagtgggtgcggcctgcctccatattcaagtgtatcttaaaccaagtggttccaacgctcgcgctaaagaattaaagcctttatttcctccacggagtagcccgtaatccggttcgaaagagaccattgaagttaattttcatatccagtgaagtttaggcacaagcatgtgttctgccacatgcctcaaagcgctcttcaaccaagatatgattcatcctaacttcgatgaatgcgtctgtaacataaatatagaaggaatgattcggcgagttaattttcgccttctccaacatggcatccctacgttcgttataaggaccatacatgtaggttttaaaggtttgcggttaatcgatatttacatcatagaaattctatagtcaaatttacaagactctagatactcactcgttgcagccggctaggaagcgctttgtaccttacttcccttttcgttgcgtaatatgaatttcatatagtaagttcaaggcactcatacctccgtgaagagggtagatagactattaaagttgtttaatagtacgtattgatggaaatgacccgtaggagatttaccactcaatccacaagattcgctgctgtgcattatcaaaacagtgcatgtcgaaacatgggttgggtccttcaaacacgaatccaggtagagatacctttgcaatttttGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCcttBtatcatatgctaKggNcataaaSatgtaaaDcDRtBggDtctttataattcBgtcgtactDtDagcctatttSVHtHttKtgtHMaSattgWaHKHttttagacatWatgtRgaaaNtactMcSMtYtcMgRtacttctWBacgaaatatagScDtttgaagacacatagtVgYgtcattHWtMMWcStgttaggKtSgaYaaccWStcgBttgcgaMttBYatcWtgacaYcagagtaBDtRacttttcWatMttDBcatWtatcttactaBgaYtcttgttttttttYaaScYaHgtgttNtSatcMtcVaaaStccRcctDaataataStcYtRDSaMtDttgttSagtRRcatttHatSttMtWgtcgtatSSagactYaaattcaMtWatttaSgYttaRgKaRtccactttattRggaMcDaWaWagttttgacatgttctacaaaRaatataataaMttcgDacgaSStacaStYRctVaNMtMgtaggcKatcttttattaaaaagVWaHKYagtttttatttaaccttacgtVtcVaattVMBcttaMtttaStgacttagattWWacVtgWYagWVRctDattBYtgtttaagaagattattgacVatMaacattVctgtBSgaVtgWWggaKHaatKWcBScSWaaccRVacacaaactaccScattRatatKVtactatatttHttaagtttSKtRtacaaagtRDttcaaaaWgcacatWaDgtDKacgaacaattacaRNWaatHtttStgttattaaMtgttgDcgtMgcatBtgcttcgcgaDWgagctgcgaggggVtaaScNatttacttaatgacagcccccacatYScaMgtaggtYaNgttctgaMaacNaMRaacaaacaKctacatagYWctgttWaaataaaataRattagHacacaagcgKatacBttRttaagtatttccgatctHSaatactcNttMaagtattMtgRtgaMgcataatHcMtaBSaRattagttgatHtMttaaKaggYtaaBataSaVatactWtataVWgKgttaaaacagtgcgRatatacatVtHRtVYataSaKtWaStVcNKHKttactatccctcatgWHatWaRcttactaggatctataDtDHBttataaaaHgtacVtagaYttYaKcctattcttcttaataNDaaggaaaDYgcggctaaWSctBaaNtgctggMBaKctaMVKagBaactaWaDaMaccYVtNtaHtVWtKgRtcaaNtYaNacggtttNattgVtttctgtBaWgtaattcaagtcaVWtactNggattctttaYtaaagccgctcttagHVggaYtgtNcDaVagctctctKgacgtatagYcctRYHDtgBattDaaDgccKtcHaaStttMcctagtattgcRgWBaVatHaaaataYtgtttagMDMRtaataaggatMtttctWgtNtgtgaaaaMaatatRtttMtDgHHtgtcattttcWattRSHcVagaagtacgggtaKVattKYagactNaatgtttgKMMgYNtcccgSKttctaStatatNVataYHgtNaBKRgNacaactgatttcctttaNcgatttctctataScaHtataRagtcRVttacDSDttaRtSatacHgtSKacYagttMHtWataggatgactNtatSaNctataVtttRNKtgRacctttYtatgttactttttcctttaaacatacaHactMacacggtWataMtBVacRaSaatccgtaBVttccagccBcttaRKtgtgcctttttRtgtcagcRttKtaaacKtaaatctcacaattgcaNtSBaaccgggttattaaBcKatDagttactcttcattVtttHaaggctKKgatacatcBggScagtVcacattttgaHaDSgHatRMaHWggtatatRgccDttcgtatcgaaacaHtaagttaRatgaVacttagattVKtaaYttaaatcaNatccRttRRaMScNaaaDgttVHWgtcHaaHgacVaWtgttScactaagSgttatcttagggDtaccagWattWtRtgttHWHacgattBtgVcaYatcggttgagKcWtKKcaVtgaYgWctgYggVctgtHgaNcVtaBtWaaYatcDRaaRtSctgaHaYRttagatMatgcatttNattaDttaattgttctaaccctcccctagaWBtttHtBccttagaVaatMcBHagaVcWcagBVttcBtaYMccagatgaaaaHctctaacgttagNWRtcggattNatcRaNHttcagtKttttgWatWttcSaNgggaWtactKKMaacatKatacNattgctWtatctaVgagctatgtRaHtYcWcttagccaatYttWttaWSSttaHcaaaaagVacVgtaVaRMgattaVcDactttcHHggHRtgNcctttYatcatKgctcctctatVcaaaaKaaaagtatatctgMtWtaaaacaStttMtcgactttaSatcgDataaactaaacaagtaaVctaggaSccaatMVtaaSKNVattttgHccatcacBVctgcaVatVttRtactgtVcaattHgtaaattaaattttYtatattaaRSgYtgBagaHSBDgtagcacRHtYcBgtcacttacactaYcgctWtattgSHtSatcataaatataHtcgtYaaMNgBaatttaRgaMaatatttBtttaaaHHKaatctgatWatYaacttMctcttttVctagctDaaagtaVaKaKRtaacBgtatccaaccactHHaagaagaaggaNaaatBWattccgStaMSaMatBttgcatgRSacgttVVtaaDMtcSgVatWcaSatcttttVatagttactttacgatcaccNtaDVgSRcgVcgtgaacgaNtaNatatagtHtMgtHcMtagaaattBgtataRaaaacaYKgtRccYtatgaagtaataKgtaaMttgaaRVatgcagaKStctHNaaatctBBtcttaYaBWHgtVtgacagcaRcataWctcaBcYacYgatDgtDHcctaaagacYRcaggattHaYgtKtaatgcVcaataMYacccatatcacgWDBtgaatcBaatacKcttRaRtgatgaBDacggtaattaaYtataStgVHDtDctgactcaaatKtacaatgcgYatBtRaDatHaactgtttatatDttttaaaKVccYcaaccNcBcgHaaVcattHctcgattaaatBtatgcaaaaatYMctSactHatacgaWacattacMBgHttcgaatVaaaacaBatatVtctgaaaaWtctRacgBMaatSgRgtgtcgactatcRtattaScctaStagKgaDcWgtYtDDWKRgRtHatRtggtcgaHgggcgtattaMgtcagccaBggWVcWctVaaattcgNaatcKWagcNaHtgaaaSaaagctcYctttRVtaaaatNtataaccKtaRgtttaMtgtKaBtRtNaggaSattHatatWactcagtgtactaKctatttgRYYatKatgtccgtRtttttatttaatatVgKtttgtatgtNtataRatWYNgtRtHggtaaKaYtKSDcatcKgtaaYatcSRctaVtSMWtVtRWHatttagataDtVggacagVcgKWagBgatBtaaagNcaRtagcataBggactaacacRctKgttaatcctHgDgttKHHagttgttaatgHBtatHcDaagtVaBaRccctVgtgDtacRHSctaagagcggWYaBtSaKtHBtaaactYacgNKBaVYgtaacttagtVttcttaatgtBtatMtMtttaattaatBWccatRtttcatagVgMMtagctStKctaMactacDNYgKYHgaWcgaHgagattacVgtttgtRaSttaWaVgataatgtgtYtaStattattMtNgWtgttKaccaatagNYttattcgtatHcWtctaaaNVYKKttWtggcDtcgaagtNcagatacgcattaagaccWctgcagcttggNSgaNcHggatgtVtcatNtRaaBNcHVagagaaBtaaSggDaatWaatRccaVgggStctDaacataKttKatttggacYtattcSatcttagcaatgaVBMcttDattctYaaRgatgcattttNgVHtKcYRaatRKctgtaaacRatVSagctgtWacBtKVatctgttttKcgtctaaDcaagtatcSataWVgcKKataWaYttcccSaatgaaaacccWgcRctWatNcWtBRttYaattataaNgacacaatagtttVNtataNaYtaatRaVWKtBatKagtaatataDaNaaaaataMtaagaaStccBcaatNgaataWtHaNactgtcDtRcYaaVaaaaaDgtttRatctatgHtgttKtgaaNSgatactttcgagWaaatctKaaDaRttgtggKKagcDgataaattgSaacWaVtaNMacKtcaDaaatttctRaaVcagNacaScRBatatctRatcctaNatWgRtcDcSaWSgttRtKaRtMtKaatgttBHcYaaBtgatSgaSWaScMgatNtctcctatttctYtatMatMtRRtSaattaMtagaaaaStcgVgRttSVaScagtgDtttatcatcatacRcatatDcttatcatVRtttataaHtattcYtcaaaatactttgVctagtaaYttagatagtSYacKaaacgaaKtaaatagataatSatatgaaatSgKtaatVtttatcctgKHaatHattagaaccgtYaaHactRcggSBNgtgctaaBagBttgtRttaaattYtVRaaaattgtaatVatttctcttcatgBcVgtgKgaHaaatattYatagWacNctgaaMcgaattStagWaSgtaaKagttttaagaDgatKcctgtaHtcatggKttVDatcaaggtYcgccagNgtgcVttttagagatgctaccacggggtNttttaSHaNtatNcctcatSaaVgtactgBHtagcaYggYVKNgtaKBcRttgaWatgaatVtagtcgattYgatgtaatttacDacSctgctaaaStttaWMagDaaatcaVYctccgggcgaVtaaWtStaKMgDtttcaaMtVgBaatccagNaaatcYRMBggttWtaaScKttMWtYataRaDBMaDataatHBcacDaaKDactaMgagttDattaHatHtaYatDtattDcRNStgaatattSDttggtattaaNSYacttcDMgYgBatWtaMagactVWttctttgYMaYaacRgHWaattgRtaagcattctMKVStatactacHVtatgatcBtVNataaBttYtSttacKgggWgYDtgaVtYgatDaacattYgatggtRDaVDttNactaSaMtgNttaacaaSaBStcDctaccacagacgcaHatMataWKYtaYattMcaMtgSttDagcHacgatcaHttYaKHggagttccgatYcaatgatRaVRcaagatcagtatggScctatattaNtagcgacgtgKaaWaactSgagtMYtcttccaKtStaacggMtaagNttattatcgtctaRcactctctDtaacWYtgaYaSaagaWtNtatttRacatgNaatgttattgWDDcNaHcctgaaHacSgaataaRaataMHttatMtgaSDSKatatHHaNtacagtccaYatWtcactaactatKDacSaStcggataHgYatagKtaatKagStaNgtatactatggRHacttgtattatgtDVagDVaRctacMYattDgtttYgtctatggtKaRSttRccRtaaccttagagRatagSaaMaacgcaNtatgaaatcaRaagataatagatactcHaaYKBctccaagaRaBaStNagataggcgaatgaMtagaatgtcaKttaaatgtaWcaBttaatRcggtgNcacaaKtttScRtWtgcatagtttWYaagBttDKgcctttatMggNttattBtctagVtacataaaYttacacaaRttcYtWttgHcaYYtaMgBaBatctNgcDtNttacgacDcgataaSatYaSttWtcctatKaatgcagHaVaacgctgcatDtgttaSataaaaYSNttatagtaNYtaDaaaNtggggacttaBggcHgcgtNtaaMcctggtVtaKcgNacNtatVaSWctWtgaWcggNaBagctctgaYataMgaagatBSttctatacttgtgtKtaattttRagtDtacatatatatgatNHVgBMtKtaKaNttDHaagatactHaccHtcatttaaagttVaMcNgHatatKtaNtgYMccttatcaaNagctggacStttcNtggcaVtattactHaSttatgNMVattMMDtMactattattgWMSgtHBttStStgatatRaDaagattttctatMtaaaaaggtactaaVttaSacNaatactgMttgacHaHRttgMacaaaatagttaatatWKRgacDgaRtatatttattatcYttaWtgtBRtWatgHaaattHataagtVaDtWaVaWtgStcgtMSgaSRgMKtaaataVacataatgtaSaatttagtcgaaHtaKaatgcacatcggRaggSKctDcagtcSttcccStYtccRtctctYtcaaKcgagtaMttttcRaYDttgttatctaatcataNctctgctatcaMatactataggDaHaaSttMtaDtcNatataattctMcStaaBYtaNagatgtaatHagagSttgWHVcttatKaYgDctcttggtgttMcRaVgSgggtagacaataaDtaattSaDaNaHaBctattgNtaccaaRgaVtKNtaaYggHtaKKgHcatctWtctDtttctttggSDtNtaStagttataaacaattgcaBaBWggHgcaaaBtYgctaatgaaatWcDcttHtcMtWWattBHatcatcaaatctKMagtDNatttWaBtHaaaNgMttaaStagttctctaatDtcRVaYttgttMtRtgtcaSaaYVgSWDRtaatagctcagDgcWWaaaBaaRaBctgVgggNgDWStNaNBKcBctaaKtttDcttBaaggBttgaccatgaaaNgttttttttatctatgttataccaaDRaaSagtaVtDtcaWatBtacattaWacttaSgtattggDgKaaatScaattacgWcagKHaaccaYcRcaRttaDttRtttHgaHVggcttBaRgtccctDatKaVtKtcRgYtaKttacgtatBtStaagcaattaagaRgBagSaattccSWYtttattVaataNctgHgttaaNBgcVYgtRtcccagWNaaaacaDNaBcaaaaRVtcWMgBagMtttattacgDacttBtactatcattggaaatVccggttRttcatagttVYcatYaSHaHcttaaagcNWaHataaaRWtctVtRYtagHtaaaYMataHYtNBctNtKaatattStgaMcBtRgctaKtgcScSttDgYatcVtggaaKtaagatWccHccgKYctaNNctacaWcttttgcRtgtVcgaKttcMRHgctaHtVaataaDtatgKDcttatBtDttggNtacttttMtgaacRattaaNagaactcaaaBBVtcDtcgaStaDctgaaaSgttMaDtcgttcaccaaaaggWtcKcgSMtcDtatgtttStaaBtatagDcatYatWtaaaBacaKgcaDatgRggaaYctaRtccagattDaWtttggacBaVcHtHtaacDacYgtaatataMagaatgHMatcttatacgtatttttatattacHactgttataMgStYaattYaccaattgagtcaaattaYtgtatcatgMcaDcgggtcttDtKgcatgWRtataatatRacacNRBttcHtBgcRttgtgcgtcatacMtttBctatctBaatcattMttMYgattaaVYatgDaatVagtattDacaacDMatcMtHcccataagatgBggaccattVWtRtSacatgctcaaggggYtttDtaaNgNtaaBatggaatgtctRtaBgBtcNYatatNRtagaacMgagSaSDDSaDcctRagtVWSHtVSRggaacaBVaccgtttaStagaacaMtactccagtttVctaaRaaHttNcttagcaatttattaatRtaaaatctaacDaBttggSagagctacHtaaRWgattcaaBtctRtSHaNtgtacattVcaHaNaagtataccacaWtaRtaaVKgMYaWgttaKggKMtKcgWatcaDatYtKSttgtacgaccNctSaattcDcatcttcaaaDKttacHtggttHggRRaRcaWacaMtBWVHSHgaaMcKattgtaRWttScNattBBatYtaNRgcggaagacHSaattRtttcYgaccBRccMacccKgatgaacttcgDgHcaaaaaRtatatDtatYVtttttHgSHaSaatagctNYtaHYaVYttattNtttgaaaYtaKttWtctaNtgagaaaNctNDctaaHgttagDcRttatagccBaacgcaRBtRctRtggtaMYYttWtgataatcgaataattattataVaaaaattacNRVYcaaMacNatRttcKatMctgaagactaattataaYgcKcaSYaatMNctcaacgtgatttttBacNtgatDccaattattKWWcattttatatatgatBcDtaaaagttgaaVtaHtaHHtBtataRBgtgDtaataMttRtDgDcttattNtggtctatctaaBcatctaRatgNacWtaatgaagtcMNaacNgHttatactaWgcNtaStaRgttaaHacccgaYStacaaaatWggaYaWgaattattcMaactcBKaaaRVNcaNRDcYcgaBctKaacaaaaaSgctccYBBHYaVagaatagaaaacagYtctVccaMtcgtttVatcaatttDRtgWctagtacRttMctgtDctttcKtWttttataaatgVttgBKtgtKWDaWagMtaaagaaattDVtaggttacatcatttatgtcgMHaVcttaBtVRtcgtaYgBRHatttHgaBcKaYWaatcNSctagtaaaaatttacaatcactSWacgtaatgKttWattagttttNaggtctcaagtcactattcttctaagKggaataMgtttcataagataaaaatagattatDgcBVHWgaBKttDgcatRHaagcaYcRaattattatgtMatatattgHDtcaDtcaaaHctStattaatHaccgacNattgatatattttgtgtDtRatagSacaMtcRtcattcccgacacSattgttKaWattNHcaacttccgtttSRtgtctgDcgctcaaMagVtBctBMcMcWtgtaacgactctcttRggRKSttgYtYatDccagttDgaKccacgVatWcataVaaagaataMgtgataaKYaaatcHDaacgataYctRtcYatcgcaMgtNttaBttttgatttaRtStgcaacaaaataccVgaaDgtVgDcStctatatttattaaaaRKDatagaaagaKaaYYcaYSgKStctccSttacagtcNactttDVttagaaagMHttRaNcSaRaMgBttattggtttaRMggatggcKDgWRtNaataataWKKacttcKWaaagNaBttaBatMHtccattaacttccccYtcBcYRtagattaagctaaYBDttaNtgaaaccHcaRMtKtaaHMcNBttaNaNcVcgVttWNtDaBatgataaVtcWKcttRggWatcattgaRagHgaattNtatttctctattaattaatgaDaaMatacgttgggcHaYVaaNaDDttHtcaaHtcVVDgBVagcMacgtgttaaBRNtatRtcagtaagaggtttaagacaVaaggttaWatctccgtVtaDtcDatttccVatgtacNtttccgtHttatKgScBatgtVgHtYcWagcaKtaMYaaHgtaattaSaHcgcagtWNaatNccNNYcacgVaagaRacttctcattcccRtgtgtaattagcSttaaStWaMtctNNcSMacattataaactaDgtatWgtagtttaagaaaattgtagtNagtcaataaatttgatMMYactaatatcggBWDtVcYttcDHtVttatacYaRgaMaacaStaatcRttttVtagaDtcacWatttWtgaaaagaaagNRacDtttStVatBaDNtaactatatcBSMcccaSttccggaMatgattaaWatKMaBaBatttgataNctgttKtVaagtcagScgaaaDggaWgtgttttKtWtatttHaatgtagttcactaaKMagttSYBtKtaYgaactcagagRtatagtVtatcaaaWYagcgNtaDagtacNSaaYDgatBgtcgataacYDtaaactacagWDcYKaagtttattagcatcgagttKcatDaattgattatDtcagRtWSKtcgNtMaaaaacaMttKcaWcaaSVMaaaccagMVtaMaDtMaHaBgaacataBBVtaatVYaNSWcSgNtDNaaKacacBtttatKtgtttcaaHaMctcagtaacgtcgYtactDcgcctaNgagagcYgatattttaaatttccattttacatttDaaRctattttWctttacgtDatYtttcagacgcaaVttagtaaKaaaRtgVtccataBggacttatttgtttaWNtgttVWtaWNVDaattgtatttBaagcBtaaBttaaVatcHcaVgacattccNggtcgacKttaaaRtagRtctWagaYggtgMtataatMtgaaRttattttgWcttNtDRRgMDKacagaaaaggaaaRStcccagtYccVattaNaaKStNWtgacaVtagaagcttSaaDtcacaacgDYacWDYtgtttKatcVtgcMaDaSKStVcgtagaaWaKaagtttcHaHgMgMtctataagBtKaaaKKcactggagRRttaagaBaaNatVVcgRcKSttDaactagtSttSattgttgaaRYatggttVttaataaHttccaagDtgatNWtaagHtgcYtaactRgcaatgMgtgtRaatRaNaacHKtagactactggaatttcgccataacgMctRgatgttaccctaHgtgWaYcactcacYaattcttaBtgacttaaacctgYgaWatgBttcttVttcgttWttMcNYgtaaaatctYgMgaaattacNgaHgaacDVVMtttggtHtctaaRgtacagacgHtVtaBMNBgattagcttaRcttacaHcRctgttcaaDBggttKaacatgKtttYataVaNattccgMcgcgtagtRaVVaattaKaatggttRgaMcagtatcWBttNtHagctaatctagaaNaaacaYBctatcgcVctBtgcaaagDgttVtgaHtactSNYtaaNccatgtgDacgaVtDcgKaRtacDcttgctaagggcagMDagggtBWRtttSgccttttttaacgtcHctaVtVDtagatcaNMaVtcVacatHctDWNaataRgcgtaVHaggtaaaaSgtttMtattDgBtctgatSgtRagagYtctSaKWaataMgattRKtaacatttYcgtaacacattRWtBtcggtaaatMtaaacBatttctKagtcDtttgcBtKYYBaKttctVttgttaDtgattttcttccacttgSaaacggaaaNDaattcYNNaWcgaaYattttMgcBtcatRtgtaaagatgaWtgaccaYBHgaatagataVVtHtttVgYBtMctaMtcctgaDcYttgtccaaaRNtacagcMctKaaaggatttacatgtttaaWSaYaKttBtagDacactagctMtttNaKtctttcNcSattNacttggaacaatDagtattRtgSHaataatgccVgacccgatactatccctgtRctttgagaSgatcatatcgDcagWaaHSgctYYWtatHttggttctttatVattatcgactaagtgtagcatVgtgHMtttgtttcgttaKattcMatttgtttWcaaStNatgtHcaaaDtaagBaKBtRgaBgDtSagtatMtaacYaatYtVcKatgtgcaacVaaaatactKcRgtaYtgtNgBBNcKtcttaccttKgaRaYcaNKtactttgagSBtgtRagaNgcaaaNcacagtVtttHWatgttaNatBgtttaatNgVtctgaatatcaRtattcttttttttRaaKcRStctcggDgKagattaMaaaKtcaHacttaataataKtaRgDtKVBttttcgtKaggHHcatgttagHggttNctcgtatKKagVagRaaaggaaBtNatttVKcRttaHctaHtcaaatgtaggHccaBataNaNaggttgcWaatctgatYcaaaHaatWtaVgaaBttagtaagaKKtaaaKtRHatMaDBtBctagcatWtatttgWttVaaaScMNattRactttgtYtttaaaagtaagtMtaMaSttMBtatgaBtttaKtgaatgagYgtNNacMtcNRacMMHcttWtgtRtctttaacaacattattcYaMagBaacYttMatcttKcRMtgMNccattaRttNatHaHNaSaaHMacacaVaatacaKaSttHatattMtVatWgattttttaYctttKttHgScWaacgHtttcaVaaMgaacagNatcgttaacaaaaagtacaHBNaattgttKtcttVttaaBtctgctacgBgcWtttcaggacacatMgacatcccagcggMgaVKaBattgacttaatgacacacaaaaaatRKaaBctacgtRaDcgtagcVBaacDSBHaaaaSacatatacagacRNatcttNaaVtaaaataHattagtaaaaSWccgtatWatggDttaactattgcccatcttHaSgYataBttBaactattBtcHtgatcaataSttaBtatKSHYttWggtcYtttBttaataccRgVatStaHaKagaatNtagRMNgtcttYaaSaactcagDSgagaaYtMttDtMRVgWKWtgMaKtKaDttttgactatacataatcNtatNaHattVagacgYgatatatttttgtStWaaatctWaMgagaRttRatacgStgattcttaagaDtaWccaaatRcagcagaaNKagtaaDggcgccBtYtagSBMtactaaataMataBSacRMgDgattMMgtcHtcaYDtRaDaacggttDaggcMtttatgttaNctaattaVacgaaMMtaatDccSgtattgaRtWWaccaccgagtactMcgVNgctDctaMScatagcgtcaactatacRacgHRttgctatttaatgaattataYKttgtaagWgtYttgcHgMtaMattWaWVtaRgcttgYgttBHtYataSccStBtgtagMgtDtggcVaaSBaatagDttgBgtctttctcattttaNagtHKtaMWcYactVcgcgtatMVtttRacVagDaatcttgctBBcRDgcaacKttgatSKtYtagBMagaRtcgBattHcBWcaactgatttaatttWDccatttatcgagSKaWttataHactaHMttaatHtggaHtHagaatgtKtaaRactgtttMatacgatcaagDgatKaDctataMggtHDtggHacctttRtatcttYattttgacttgaaSaataaatYcgBaaaaccgNatVBttMacHaKaataagtatKgtcaagactcttaHttcggaattgttDtctaaccHttttWaaatgaaatataaaWattccYDtKtaaaacggtgaggWVtctattagtgactattaagtMgtttaagcatttgSgaaatatccHaaggMaaaattttcWtatKctagDtYtMcctagagHcactttactatacaaacattaacttaHatcVMYattYgVgtMttaaRtgaaataaDatcaHgtHHatKcDYaatcttMtNcgatYatgSaMaNtcttKcWataScKggtatcttacgcttWaaagNatgMgHtctttNtaacVtgttcMaaRatccggggactcMtttaYMtcWRgNctgNccKatcttgYDcMgattNYaRagatHaaHgKctcataRDttacatBatccattgDWttatttaWgtcggagaaaaatacaatacSNtgggtttccttacSMaagBattacaMaNcactMttatgaRBacYcYtcaaaWtagctSaacttWgDMHgaggatgBVgcHaDtggaactttggtcNatNgtaKaBcccaNtaagttBaacagtatacDYttcctNgWgcgSMcacatStctHatgRcNcgtacacaatRttMggaNKKggataaaSaYcMVcMgtaMaHtgattYMatYcggtcttcctHtcDccgtgRatcattgcgccgatatMaaYaataaYSggatagcgcBtNtaaaScaKgttBgagVagttaKagagtatVaactaSacWactSaKatWccaKaaaatBKgaaKtDMattttgtaaatcRctMatcaaMagMttDgVatggMaaWgttcgaWatgaaatttgRtYtattaWHKcRgctacatKttctaccaaHttRatctaYattaaWatVNccatNgagtcKttKataStRaatatattcctRWatDctVagttYDgSBaatYgttttgtVaatttaatagcagMatRaacttBctattgtMagagattaaactaMatVtHtaaatctRgaaaaaaaatttWacaacaYccYDSaattMatgaccKtaBKWBattgtcaagcHKaagttMMtaatttcKcMagNaaKagattggMagaggtaatttYacatcWaaDgatMgKHacMacgcVaacaDtaDatatYggttBcgtatgWgaSatttgtagaHYRVacaRtctHaaRtatgaactaatatctSSBgggaaHMWtcaagatKgagtDaSatagttgattVRatNtctMtcSaagaSHaataNataataRaaRgattctttaataaagWaRHcYgcatgtWRcttgaaggaMcaataBRaaccagStaaacNtttcaatataYtaatatgHaDgcStcWttaacctaRgtYaRtataKtgMttttatgactaaaatttacYatcccRWtttHRtattaaatgtttatatttgttYaatMcaRcSVaaDatcgtaYMcatgtagacatgaaattgRtcaaYaaYtRBatKacttataccaNaaattVaBtctggacaagKaaYaaatatWtMtatcYaaVNtcgHaactBaagKcHgtctacaatWtaDtSgtaHcataHtactgataNctRgttMtDcDttatHtcgtacatcccaggSttaBgtcacacWtccNMcNatMVaVgtccDYStatMaccDatggYaRKaaagataRatttHKtSaaatDgataaacttaHgttgVBtcttVttHgDacgaKatgtatatNYataactctSatatatattgcHRRYttStggaactHgttttYtttaWtatMcttttctatctDtagVHYgMRBgtHttcctaatYRttKtaagatggaVRataKDctaMtKBNtMtHNtWtttYcVtattMcgRaacMcctNSctcatttaaagDcaHtYccSgatgcaatYaaaaDcttcgtaWtaattctcgttttScttggtaatctttYgtctaactKataHacctMctcttacHtKataacacagcNRatgKatttttSaaatRYcgDttaMRcgaaattactMtgcgtaagcgttatBtttttaattaagtNacatHgttcRgacKcBBtVgatKttcgaBaatactDRgtRtgaNacWtcacYttaaKcgttctHaKttaNaMgWgWaggtctRgaKgWttSttBtDcNtgtttacaaatYcDRtgVtgcctattcNtctaaaDMNttttNtggctgagaVctDaacVtWccaagtaacacaNctgaScattccDHcVBatcgatgtMtaatBgHaatDctMYgagaatgYWKcctaatNaStHaaaKccgHgcgtYaaYtattgtStgtgcaaRtattaKatattagaWVtcaMtBagttattagNaWHcVgcaattttDcMtgtaRHVYtHtctgtaaaaHVtMKacatcgNaatttMatatgttgttactagWYtaRacgataKagYNKcattataNaRtgaacKaYgcaaYYacaNccHatMatDcNgtHttRaWttagaaDcaaaaaatagggtKDtStaDaRtaVtHWKNtgtattVctSVgRgataDaRaWataBgaagaaKtaataaYgDcaStaNgtaDaaggtattHaRaWMYaYaWtggttHYgagVtgtgcttttcaaDKcagVcgttagacNaaWtagtaataDttctggttVcatcataaagtgKaaaNaMtaBBaattaatWaattgctHaVKaSgDaaVKaHtatatatHatcatSBagNgHtatcHYMHgttDgtaHtBttWatcgtttaRaattgStKgSKNWKatcagDtctcagatttctRtYtBatBgHHtKaWtgYBgacVVWaKtacKcDttKMaKaVcggtgttataagaataaHaatattagtataatMHgttYgaRttagtaRtcaaVatacggtcMcgagtaaRttacWgactKRYataaaagSattYaWgagatYagKagatgSaagKgttaatMggtataatgttWYttatgagaaacctNVataatHcccKtDctcctaatactggctHggaSaggRtKHaWaattcgSatMatttagaggcYtctaMcgctcataSatatgRagacNaaDaggaVBagaYttKtacNaKgtSYtagttggaWcatcWttaatctatgaVtcgtgtMtatcaYcgtRccaaYgDctgcMgtgtWgacWtgataacacgcgctBtgttaKtYDtatDcatcagKaVMctaatcttgVcaaRgcRMtDcgattaHttcaNatgaatMtactacVgtRgatggaWtttactaaKatgagSaaKggtaNtactVaYtaaKRagaacccacaMtaaMtKtatBcttgtaaWBtMctaataaVcDaaYtcRHBtcgttNtaaHatttBNgRStVDattBatVtaagttaYatVattaagaBcacggtSgtVtatttaRattgatgtaHDKgcaatattKtggcctatgaWDKRYcggattgRctatNgatacaatMNttctgtcRBYRaaaHctNYattcHtaWcaattctBtMKtVgYataatMgYtcagcttMDataVtggRtKtgaatgccNcRttcaMtRgattaacattRcagcctHtWMtgtDRagaKaBtgDttYaaaaKatKgatctVaaYaacWcgcatagBVtaNtRtYRaggBaaBtgKgttacataagagcatgtRattccacttaccatRaaatgWgDaMHaYVgVtaSctatcgKaatatattaDgacccYagtgtaYNaaatKcagtBRgagtccatgKgaaaccBgaagBtgSttWtacgatWHaYatcgatttRaaNRgcaNaKVacaNtDgattgHVaatcDaagcgtatgcNttaDataatcSataaKcaataaHWataBtttatBtcaKtKtatagttaDgSaYctacaRatNtaWctSaatatttYaKaKtaccWtatcRagacttaYttVcKgSDcgagaagatccHtaattctSttatggtKYgtMaHagVaBRatttctgtRgtctatgggtaHKgtHacHtSYacgtacacHatacKaaBaVaccaDtatcSaataaHaagagaatScagactataaRttagcaaVcaHataKgDacatWccccaagcaBgagWatctaYttgaaatctVNcYtttWagHcgcgcDcVaaatgttKcHtNtcaatagtgtNRaactttttcaatggWgBcgDtgVgtttctacMtaaataaaRggaaacWaHttaRtNtgctaaRRtVBctYtVtatDcattDtgaccYatagatYRKatNYKttNgcctagtaWtgaactaMVaacctgaStttctgaKVtaaVaRKDttVtVctaDNtataaaDtccccaagtWtcgatcactDgYaBcatcctMtVtacDaaBtYtMaKNatNtcaNacgDatYcatcgcaRatWBgaacWttKttagYtaattcggttgSWttttDWctttacYtatatWtcatDtMgtBttgRtVDggttaacYtacgtacatgaattgaaWcttMStaDgtatattgaDtcRBcattSgaaVBRgagccaaKtttcDgcgaSMtatgWattaKttWtgDBMaggBBttBaatWttRtgcNtHcgttttHtKtcWtagHStaacagttgatatBtaWSaWggtaataaMttaKacDaatactcBttcaatatHttcBaaSaaatYggtaRtatNtHcaatcaHtagVtgtattataNggaMtcttHtNagctaaaggtagaYctMattNaMVNtcKtactBKcaHHcBttaSagaKacataYgctaKaYgttYcgacWVttWtSagcaacatcccHaccKtcttaacgaKttcacKtNtacHtatatRtaaatacactaBtttgaHaRttggttWtatYagcatYDatcggagagcWBataagRtacctataRKgtBgatgaDatataSttagBaHtaatNtaDWcWtgtaattacagKttcNtMagtattaNgtctcgtcctcttBaHaKcKccgtRcaaYagSattaagtKataDatatatagtcDtaacaWHcaKttDgaaRcgtgYttgtcatatNtatttttatggccHtgDtYHtWgttatYaacaattcaWtatNgctcaaaSttRgctaatcaaatNatcgtttaBtNNVtgttataagcaaagattBacgtDatttNatttaaaDcBgtaSKgacgtagataatttcHMVNttgttBtDtgtaWKaaRMcKMtHtaVtagataWctccNNaSWtVaHatctcMgggDgtNHtDaDttatatVWttgttatttaacctttcacaaggaSaDcggttttttatatVtctgVtaacaStDVaKactaMtttaSNagtgaaattaNacttSKctattcctctaSagKcaVttaagNaVcttaVaaRNaHaaHttatgtHttgtgatMccaggtaDcgaccgtWgtWMtttaHcRtattgScctatttKtaaccaagtYagaHgtWcHaatgccKNRtttagtMYSgaDatctgtgaWDtccMNcgHgcaaacNDaaaRaStDWtcaaaaHKtaNBctagBtgtattaactaattttVctagaatggcWSatMacccttHttaSgSgtgMRcatRVKtatctgaaaccDNatYgaaVHNgatMgHRtacttaaaRtatStRtDtatDttYatattHggaBcttHgcgattgaKcKtttcRataMtcgaVttWacatNcatacctRataDDatVaWNcggttgaHtgtMacVtttaBHtgagVttMaataattatgttcttagtttgtgcDtSatttgBtcaacHattaaBagVWcgcaSYttMgcttacYKtVtatcaYaKctgBatgcgggcYcaaaaacgNtctagKBtattatctttKtaVttatagtaYtRagNtaYataaVtgaatatcHgcaaRataHtacacatgtaNtgtcgYatWMatttgaactacRctaWtWtatacaatctBatatgYtaagtatgtgtatSttactVatcttYtaBcKgRaSggRaaaaatgcagtaaaWgtaRgcgataatcBaataccgtatttttccatcNHtatWYgatHSaaaDHttgctgtccHtggggcctaataatttttctatattYWtcattBtgBRcVttaVMRSgctaatMagtYtttaaaaatBRtcBttcaaVtaacagctccSaaSttKNtHtKYcagcagaaaccccRtttttaaDcDtaStatccaagcgctHtatcttaDRYgatDHtWcaaaBcWgKWHttHataagHacgMNKttMKHccaYcatMVaacgttaKgYcaVaaBtacgcaactttMctaaHaatgtBatgagaSatgtatgSRgHgWaVWgataaatatttccKagVgataattWaHNcYggaaatgctHtKtaDtctaaagtMaatVDVactWtSaaWaaMtaHtaSKtcBRaNcttStggtBttacNagcatagRgtKtgcgaacaacBcgKaatgataagatgaaaattgtactgcgggtccHHWHaaNacaBttNKtKtcaaBatatgctaHNgtKcDWgtttatNgVDHgaccaacWctKaaggHttgaRgYaatHcaBacaatgagcaaattactgtaVaaYaDtagattgagNKggtggtgKtWKaatacagDRtatRaMRtgattDggtcaaYRtatttNtagaDtcacaaSDctDtataatcgtactaHttatacaatYaacaaHttHatHtgcgatRRttNgcatSVtacWWgaaggagtatVMaVaaattScDDKNcaYBYaDatHgtctatBagcaacaagaatgagaaRcataaKNaRtBDatcaaacgcattttttaaBtcSgtacaRggatgtMNaattggatatWtgagtattaaaVctgcaYMtatgatttttYgaHtgtcttaagWBttHttgtcttattDtcgtatWtataataSgctaHagcDVcNtaatcaagtaBDaWaDgtttagYctaNccDtaKtaHcttaataacccaRKtacaVaatNgcWRaMgaattatgaBaaagattVYaHMDcaDHtcRcgYtcttaaaWaaaVKgatacRtttRRKYgaatacaWVacVcRtatMacaBtactggMataaattttHggNagSctacHgtBagcgtcgtgattNtttgatSaaggMttctttcttNtYNagBtaaacaaatttMgaccttacataattgYtcgacBtVMctgStgMDtagtaRctHtatgttcatatVRNWataDKatWcgaaaaagttaaaagcacgHNacgtaatctttMRtgacttttDacctataaacgaaatatgattagaactccSYtaBctttaataacWgaaaYatagatgWttcatKtNgatttttcaagHtaYgaaRaDaagtaggagcttatVtagtctttcattaaaatcgKtattaRttacagVaDatgcatVgattgggtctttHVtagKaaRBtaHtaaggccccaaaaKatggtttaMWgtBtaaacttcactttKHtcgatctccctaYaBacMgtcttBaBaNgcgaaacaatctagtHccHtKttcRtRVttccVctttcatacYagMVtMcagaMaaacaataBctgYtaatRaaagattaaccatVRatHtaRagcgcaBcgDttStttttcVtttaDtKgcaaWaaaaatSccMcVatgtKgtaKgcgatatgtagtSaaaDttatacaaacatYaRRcVRHctKtcgacKttaaVctaDaatgttMggRcWaacttttHaDaKaDaBctgtaggcgtttaHBccatccattcNHtDaYtaataMttacggctNVaacDattgatattttacVttSaattacaaRtataNDgacVtgaacataVRttttaDtcaaacataYDBtttaatBaDtttYDaDaMccMttNBttatatgagaaMgaNtattHccNataattcaHagtgaaggDgatgtatatatgYatgaStcataaBStWacgtcccataRMaaDattggttaaattcMKtctMacaBSactcggaatDDgatDgcWctaacaccgggaVcacWKVacggtaNatatacctMtatgatagtgcaKagggVaDtgtaacttggagtcKatatcgMcttRaMagcattaBRaStctYSggaHYtacaactMBaagDcaBDRaaacMYacaHaattagcattaaaHgcgctaaggSccKtgaaKtNaBtatDDcKBSaVtgatVYaagVtctSgMctacgttaacWaaattctSgtDactaaStaaattgcagBBRVctaatatacctNttMcRggctttMttagacRaHcaBaacVKgaataHttttMgYgattcYaNRgttMgcVaaacaVVcDHaatttgKtMYgtatBtVVctWgVtatHtacaaHttcacgatagcagtaaNattBatatatttcVgaDagcggttMaagtcScHagaaatgcYNggcgtttttMtStggtRatctacttaaatVVtBacttHNttttaRcaaatcacagHgagagtMgatcSWaNRacagDtatactaaDKaSRtgattctccatSaaRttaaYctacacNtaRtaactggatgaccYtacactttaattaattgattYgttcagDtNKttagDttaaaaaaaBtttaaNaYWKMBaaaacVcBMtatWtgBatatgaacVtattMtYatMNYDKNcKgDttDaVtaaaatgggatttctgtaaatWtctcWgtVVagtcgRgacttcccctaDcacagcRcagagtgtWSatgtacatgttaaSttgtaaHcgatgggMagtgaacttatRtttaVcaccaWaMgtactaatSSaHtcMgaaYtatcgaaggYgggcgtgaNDtgttMNgaNDMtaattcgVttttaacatgVatgtWVMatatcaKgaaattcaBcctccWcttgaaWHtWgHtcgNWgaRgctcBgSgaattgcaaHtgattgtgNagtDttHHgBttaaWcaaWagcaSaHHtaaaVctRaaMagtaDaatHtDMtcVaWMtagSagcttHSattaacaaagtRacMtRtctgttagcMtcaBatVKtKtKacgagaSNatSactgtatatcBctgagVtYactgtaaattaaaggcYgDHgtaacatSRDatMMccHatKgttaacgactKtgKagtcttcaaHRVtccttKgtSataatttacaactggatDNgaacttcaRtVaagDcaWatcBctctHYatHaDaaatttagYatSatccaWtttagaaatVaacBatHcatcgtacaatatcgcNYRcaataYaRaYtgattVttgaatgaVaactcRcaNStgtgtattMtgaggtNttBaDRcgaaaagctNgBcWaWgtSaDcVtgVaatMKBtttcgtttctaaHctaaagYactgMtatBDtcStgaccgtSDattYaataHctgggaYYttcggttaWaatctggtRagWMaDagtaacBccactacgHWMKaatgatWatcctgHcaBaSctVtcMtgtDttacctaVgatYcWaDRaaaaRtagatcgaMagtggaRaWctctgMgcWttaagKBRtaaDaaWtctgtaagYMttactaHtaatcttcataacggcacBtSgcgttNHtgtHccatgttttaaagtatcgaKtMttVcataYBBaKtaMVaVgtattNDSataHcagtWMtaggtaSaaKgttgBtVtttgttatcatKcgHacacRtctHatNVagSBgatgHtgaRaSgttRcctaacaaattDNttgacctaaYtBgaaaatagttattactcttttgatgtNNtVtgtatMgtcttRttcatttgatgacacttcHSaaaccaWWDtWagtaRDDVNacVaRatgttBccttaatHtgtaaacStcVNtcacaSRttcYagacagaMMttttgMcNttBcgWBtactgVtaRttctccaaYHBtaaagaBattaYacgatttacatctgtaaMKaRYtttttactaaVatWgctBtttDVttctggcDaHaggDaagtcgaWcaagtagtWttHtgKtVataStccaMcWcaagataagatcactctHatgtcYgaKcatcagatactaagNSStHcctRRNtattgtccttagttagMVgtatagactaactctVcaatMctgtttgtgttgccttatWgtaBVtttctggMcaaKgDWtcgtaaYStgSactatttHgatctgKagtagBtVacRaagRtMctatgggcaaaKaaaatacttcHctaRtgtDcttDattaggaaatttcYHaRaaBttaatggcacKtgctHVcaDcaaaVDaaaVcgMttgtNagcgtaDWgtcgttaatDgKgagcSatatcSHtagtagttggtgtHaWtaHKtatagctgtVgattaBVaatgaataagtaatVatSttaHctttKtttgtagttaccttaatcgtagtcctgBcgactatttVcMacHaaaggaatgDatggKtaHtgStatattaaSagctWcctccRtataBaDYcgttgcNaagaggatRaaaYtaWgNtSMcaatttactaacatttaaWttHtatBattgtcgacaatNgattgcNgtMaaaKaBDattHacttggtRtttaYaacgVactBtaBaKtgBttatgVttgtVttcaatcWcNctDBaaBgaDHacBttattNtgtDtatttVSaaacaggatgcRatSgtaSaNtgBatagttcHBgcBBaaattaHgtDattatDaKaatBaaYaaMaataaataKtttYtagtBgMatNcatgtttgaNagtgttgtgKaNaSagtttgaSMaYBcaaaacDStagttVacaaaaactaaWttBaagtctgtgcgtMgtaattctcctacctcaNtttaaccaaaaVtBcacataacaccccBcWMtatVtggaatgaWtcaaWaaaaaaaaWtDtaatatRcctDWtcctaccMtVVatKttaWaaKaaatataaagScHBagaggBaSMtaWaVtatattactSaaaKNaactatNatccttgaYctattcaaaVgatttYHcRagattttaSataggttattcVtaaagaKgtattattKtRttNcggcRgtgtgtWYtaacHgKatKgatYtacYagDtWcHBDctctgRaYKaYagcactKcacSaRtBttttBHKcMtNtcBatttatttttgSatVgaaagaWtcDtagDatatgMacaacRgatatatgtttgtKtNRaatatNatgYcaHtgHataacKtgagtagtaacYttaNccaaatHcacaacaVDtagtaYtccagcattNtacKtBtactaaagaBatVtKaaHBctgStgtBgtatgaSNtgDataaccctgtagcaBgtgatcttaDataStgaMaccaSBBgWagtacKcgattgaDgNNaaaacacagtSatBacKDgcgtataBKcatacactaSaatYtYcDaactHttcatRtttaatcaattataRtttgtaagMcgNttcatcBtYBagtNWNMtSHcattcRctttttRWgaKacKttgggagBcgttcgcMaWHtaatactgtctctatttataVgtttaBScttttaBMaNaatMacactYtBMggtHacMagtaRtctgcatttaHtcaaaatttgagKtgNtactBacaHtcgtatttctMaSRagcagttaatgtNtaaattgagagWcKtaNttagVtacgatttgaatttcgRtgtWcVatcgttaaDVctgtttBWgaccagaaagtcSgtVtatagaBccttttcctaaattgHtatcggRattttcaaggcYSKaagWaWtRactaaaacccBatMtttBaatYtaagaactSttcgaaScaatagtattgaccaagtgttttctaacatgtttNVaatcaaagagaaaNattaaRttttaVaaaccgcaggNMtatattVctcaagaggaacgBgtttaacaagttcKcYaatatactaaccBaaaSggttcNtattctagttRtBacgScVctcaatttaatYtaaaaaaatgSaatgatagaMBRatgRcMcgttgaWHtcaVYgaatYtaatctttYttatRaWtctgBtDcgatNatcKaBaDgatgtaNatWKctccgatattaacattNaaacDatgBgttctgtDtaaaMggtgaBaSHataacgccSctaBtttaRBtcNHcDatcDcctagagtcRtaBgWttDRVHagattYatgtatcWtaHtttYcattWtaaagtctNgtStggRNcgcggagSSaaagaaaatYcHDtcgctttaatgYcKBVSgtattRaYBaDaaatBgtatgaHtaaRaRgcaSWNtagatHaacttNctBtcaccatctMcatattccaSatttgcgaDagDgtatYtaaaVDtaagtttWVaagtagYatRttaagDcNgacKBcScagHtattatcDaDactaaaaaYgHttBcgaDttggataaaKSRcBMaBcgaBSttcWtgNBatRaccgattcatttataacggHVtaattcacaagagVttaaRaatVVRKcgWtVgacctgDgYaaHaWtctttcacMagggatVgactagMaaataKaaNWagKatagNaaWtaaaatttgaattttatttgctaaVgaHatBatcaaBWcBgttcMatcgBaaNgttcgSNaggSaRtttgHtRtattaNttcDcatSaVttttcgaaaaattgHatctaRaggSaNatMDaaatDcacgattttagaHgHaWtYgattaatHNSttatMSgggNtcKtYatRggtttgtMWVtttaYtagcagBagHaYagttatatggtBacYcattaRSataBatMtttaaatctHcaaaSaaaagttNSaaWcWRccRtKaagtBWtcaaattSttMtattggaaaccttaacgttBtWatttatatWcDaatagattcctScacctaagggRaaYtaNaatgVtBcttaaBaacaMVaaattatStYgRcctgtactatcMcVKatttcgSgatRHMaaaHtagtaaHtVgcaaataatatcgKKtgccaatBNgaaWcVttgagttaKatagttcaggKDatDtattgaKaVcaKtaataDataataHSaHcattagttaatRVYcNaHtaRcaaggtNHcgtcaaccaBaaagYtHWaaaRcKgaYaaDttgcWYtataRgaatatgtYtgcKtaNttWacatYHctRaDtYtattcBttttatcSataYaYgttWaRagcacHMgtttHtYttYaatcggtatStttcgtRSattaaDaKMaatatactaNBaWgctacacYtgaYVgtgHtaaaRaaRgHtagtWattataaaSDaaWtgMattatcgaaaagtaYRSaWtSgNtBgagcRYaMDtactaacttaWgtatctagacaagNtattHggataatYttYatcataDcgHgttBttctttVttgccgaaWtaaaacgKgtatctaaaaaNtccDtaDatBMaMggaatNKtatBaaatVtccRaHtaSacataHattgtttKVYattcataVaattWtcgtgMttcttKtgtctaacVtatctatatBRataactcgKatStatattcatHHRttKtccaacgtgggtgRgtgaMtattattggctatcgtgacMtRcBDtcttgtactaatRHttttaagatcgVMDStattatYBtttDttgtBtNttgRcMtYtgBacHaWaBaatDKctaagtgaaactaatgRaaKgatccaagNaaaatattaggWNtaagtatacttttKcgtcggSYtcttgRctataYcttatataaagtatattaatttataVaacacaDHatctatttttKYVatHRactttaBHccaWagtactBtcacgaVgcgttRtttttttSVgtSagtBaaattctgaHgactcttgMcattttagVtaagaattHctHtcaDaaNtaacRggWatagttcgtSttgaDatcNgNagctagDgatcNttKgttgtaDtctttRaaYStRatDtgMggactSttaDtagSaVtBDttgtDgccatcacaMattaaaMtNacaVcgSWcVaaDatcaHaatgaattaMtatccVtctBtaattgtWattatBRcWcaatgNNtactWYtDaKttaaatcactcagtRaaRgatggtKgcgccaaHgaggatStattYcaNMtcaBttacttatgagDaNtaMgaaWtgtttcttctaHtMNgttatctaWWatMtBtaaatagDVatgtBYtatcggcttaagacMRtaHScgatatYgRDtcattatSDaHggaaataNgaWSRRaaaBaatagBattaDctttgHWNttacaataaaaaaatacggtttgHgVtaHtWMttNtBtctagtMcgKMgHgYtataHaNagWtcaacYattaataYRgtaWKgaBctataaccgatttaHaNBRaRaMtccggtNgacMtctcatttgcaattcWgMacttacaaDaaNtactWatVtttagccttMaatcagVaagtctVaaDaBtattaattaYtNaYtggattaKtaKctYaMtattYgatattataatKtVgDcttatatNBtcgttgtStttttMagaggttaHYSttcKgtcKtDNtataagttataagSgttatDtRttattgttttSNggRtcaaKMNatgaatattgtBWtaMacctgggYgaSgaagYataagattacgagaatBtggtRcVHtgYggaDgaYaKagWagctatagacgaaHgtWaNgacttHRatVaWacKYtgRVNgVcSgRWctacatcKSactctgWYtBggtataagcttNRttVtgRcaWaaatDMatYattaactttcgaagRatSctgccttgcRKaccHtttSNVagtagHagBagttagaccaRtataBccataatSHatRtcHagacBWatagcaMtacaRtgtgaaBatctKRtScttccaNaatcNgtaatatWtcaMgactctBtWtaaNactHaaaaRctcgcatggctMcaaNtcagaaaaacacagtggggWttRttagtaagaVctVMtcgaatcttcMaaaHcaHBttcgattatgtcaDagcYRtBtYcgacMgtDcagcgaNgttaataatagcagKYYtcgtaBtYctMaRtaRtDagaaaacacatgYaBttgattattcgaaNttBctSataaMataWRgaHtttccgtDgaYtatggtDgHKgMtatttVtMtVagttaRatMattRagataaccctKctMtSttgaHagtcStctatttccSagatgttccacgaggYNttHRacgattcDatatDcataaaatBBttatcgaHtNHaaatatDNaggctgaNcaaggagttBttMgRagVatBcRtaWgatgBtSgaKtcgHtttgaatcaaDaHttcSBgHcagtVaaSttDcagccgttNBtgttHagYtattctttRWaaVtSttcatatKaaRaaaNacaVtVctMtSDtDtRHRcgtaatgctcttaaatSacacaatcgHattcaWcttaaaatHaaatcNctWttaNMcMtaKctVtcctaagYgatgatcYaaaRactctaRDaYagtaacgtDgaggaaatctcaaacatcaScttcKttNtaccatNtaNatacatttHaaDHgcaDatMWaaBttcRggctMaagctVYcacgatcaDttatYtaatcKatWatcaatVYtNagatttgattgaYttttYgacttVtcKaRagaaaHVgDtaMatKYagagttNatWttaccNtYtcDWgSatgaRgtMatgKtcgacaagWtacttaagtcgKtgatccttNcttatagMatHVggtagcgHctatagccctYttggtaattKNaacgaaYatatVctaataMaaaYtgVtcKaYtaataacagaatHcacVagatYWHttagaaSMaatWtYtgtaaagNaaacaVgaWtcacNWgataNttcaSagctMDaRttgNactaccgataMaaatgtttattDtcaagacgctDHYYatggttcaagccNctccttcMctttagacBtaaWtaWVHggaaaaNatttaDtDtgctaaHHtMtatNtMtagtcatttgcaaaRatacagRHtatDNtgtDgaatVgtVNtcaaatYBMaaaagcaKgtgatgatMgWWMaHttttMgMagatDtataaattaaccaactMtacataaattgRataatacgBtKtaataattRgtatDagDtcRDacctatRcagagcSHatNtcaScNtttggacNtaaggaccgtgKNttgttNcttgaaRgYgRtNtcagttBcttttcHtKtgcttYaaNgYagtaaatgaatggWaMattBHtatctatSgtcYtgcHtaattHgaaMtHcagaaSatggtatgccaHBtYtcNattWtgtNgctttaggtttgtWatNtgHtgcDttactttttttgcNtactKtWRaVcttcatagtgSNKaNccgaataaBttataataYtSagctttaaatSttggctaaKSaatRccgWHgagDttaaatcatgagMtcgagtVtaDggaBtatttgDacataaacgtagYRagBWtgDStKDgatgaagttcattatttaKWcataaatWRgatataRgttRacaaNKttNtKagaaYaStaactScattattaacgatttaaatgDtaattagatHgaYataaactatggggatVHtgccgtNgatNYcaStRtagaccacWcaMtatRagHgVactYtWHtcttcatgatWgagaKggagtatgaWtDtVtNaNtcgYYgtaaactttaDtBactagtaDctatagtaatatttatatataacgHaaaRagKattSagttYtStagagagacgatgaaaattaatcgtcaatacgctggcgaacactgagggggacccaatgctcttctcggtctaaaaaggaatgtgtcagaaattggtcagttcaaaagtagaccggatctttgcggagaacaattcacggaacgtagcgttgggaaatatcctttctaccacacatcggattttcgccctctcccattatttattgtgttctcacatagaattattgtttagacatccctcgttgtatggagagttgcccgagcgtaaaggcataatccatataccgccgggtgagtgacctgaaattgtttttagttgggatttcgctatggattagcttacacgaagagattctaatggtactataggataattataatgctgcgtggcgcagtacaccgttacaaacgtcgttcgcatatgtggctaacacggtgaaaatacctacatcgtatttgcaatttcggtcgtttcatagagcgcattgaattactcaaaaattatatatgttgattatttgattagactgcgtggaaagaaggggtactcaagccatttgtaaaagctgcatctcgcttaagtttgagagcttacattagtctatttcagtcttctaggaaatgtctgtgtgagtggttgtcgtccataggtcactggcatatgcgattcatgacatgctaaactaagaaagtagattactattaccggcatgcctaatgcgattgcactgctatgaaggtgcggacgtcgcgcccatgtagccctgataataccaatacttacatttggtcagcaattctgacattatacctagcacccataaatttactcagacttgaggacaggctcttggagtcgatcttctgtttgtatgcatgtgatcatatagatgaataagcgatgcgactagttagggcatagtatagatctgtgtatacagttcagctgaacgtccgcgagtggaagtacagctgagatctatcctaaaatgcaaccatatcgttcacacatgatatgaacccagggggaaacattgagttcagttaaattggcagcgaatcccccaagaagaaggcggagtgacgttgaacgggcttatggtttttcagtacttcctccgtataagttgagcgaaatgtaaacagaataatcgttgtgttaacaacattaaaatcgcggaatatgatgagaatacacagtgtgagcatttcacttgtaaaatatctttggtagaacttactttgctttaaatatgttaaaccgatctaataatctacaaaacggtagattttgcctagcacattgcgtccttctctattcagatagaggcaatactcagaaggttttatccaaagcactgtgttgactaacctaagttttagtctaataatcatgattgattataggtgccgtggactacatgactcgtccacaaataatacttagcagatcagcaattggccaagcacccgacttttatttaatggttgtgcaatagtccagattcgtattcgggactctttcaaataatagtttcctggcatctaagtaagaaaagctcataaggaagcgatattatgacacgctcttccgccgctgttttgaaacttgagtattgctcgtccgaaattgagggtcacttcaaaatttactgagaagacgaagatcgactaaagttaaaatgctagtccacagttggtcaagttgaattcatccacgagttatatagctattttaatttatagtcgagtgtacaaaaaacatccacaataagatttatcttagaataacaacccccgtatcatcgaaatcctccgttatggcctgactcctcgagcttatagcatttgtgctggcgctcttgccaggaacttgctcgcgaggtggtgacgagtgagatgatcagtttcattatgatgatacgattttatcgcgactagttaatcatcatagcaagtaaaatttgaattatgtcattatcatgctccattaacaggttatttaattgatactgacgaaattttttcacaatgggttttctagaatttaatatcagtaattgaagccttcataggggtcctactagtatcctacacgacgcaggtccgcagtatcctggagggacgtgttactgattaaaagggtcaaaggaatgaaggctcacaatgttacctgcttcaccatagtgagccgatgagttttacattagtactaaatcccaaatcatactttacgatgaggcttgctagcgctaaagagaatacatacaccaccacatagaattgttagcgatgatatcaaatagactcctggaagtgtcagggggaaactgttcaatatttcgtccacaggactgaccaggcatggaaaagactgacgttggaaactataccatctcacgcccgacgcttcactaattgatgatccaaaaaatatagcccggattcctgattagcaaagggttcacagagaaagatattatcgacgtatatcccaaaaaacagacgtaatgtgcatcttcgaatcgggatgaatacttgtatcataaaaatgtgacctctagtatacaggttaatgttagtgatacacaatactcgtgggccatgggttctcaaataaaatgtaatattgcgtcgatcactcacccacgtatttggtctaattatgttttatttagtgacaatccaatagataaccggtcctattaagggctatatttttagcgaccacgcgtttaaacaaaggattgtatgtagatggtaccagtttaattgccagtgggcaatcctaagcaaaatgagattctatcctaaagtttgggcttgatataagatttcggatgtatgggttttataatcgttggagagctcaatcatgagctaatacatggatttcgctacctcaccgagagaccttgcatgaagaattctaaccaaaagtttaataggccggattggattgagttaattaagaccttgttcagtcatagtaaaaacccttaaattttaccgattgacaaagtgagcagtcgcaataccctatgcgaaacgcctcgatagtgactaggtatacaaggtttttgagttcctttgaaatagttaactaatttaaaattaattaacgacatggaaatcacagaacctaatgctttgtaggagttatttatgctgtttactgcctctacaaccctaataaagcagtcctaagaatgaaacgcatcttttagttcagaaagtggtatccagggtggtcaatttaataaattcaacatcgggtctcaggatattcggtcatataatttattaagggctcttcgagtcttactctgagtgaaattggaaacagtcatccttttcgttgtgaggcatcttacaccgctatcgatatacaatgcattccaccgcggtgtcccgtacacaaggaaacttgttaccttggggatataagaaaactcacacgtctcattattaaactgagtacaatttttgcacgagaaagtaatgcaatacaatatgatgaaagccagctaatgaaaagggatggaacgcacctcggatctgttgcactggattaaaatccgattatttttaaaaatattcagtgctagagcatatcaggtctacttttttatctggtatgtaaagcccacggagcgatagtgagatccttacgactcaacgaaaagttataacataactcccgttagccaaagcccaatcccgattactgccctaccctaacgtctgccatctaaatatcgaacttgttatgatcaatgtgactacctcccaccctttccccttcatttgttccactggggataagctagcgttttcagaatcaatgcaataagaatagccaattgtctcacttcatcagagctcttggcaattccaggcgctacgtggttctggaatatattcatttttcaaatagtaatacgtttagtgttgctattgtctacacgtttggatattacgttatgtgagcggacatcaatagttgtctaactctttagtaagccagagatagcactcttagcgaatggataccatcttccataagtttagttaatagtccgaaacaactgcttcgagcatatttgaacctccttgtaggcaaatagcctcttcaaagcaatcttactaatagatagagtttgttttaagggactactagaaatgggacaatcttaatagtatgacctaaactgacatttaaagatatatccaggtggcaagcataaagatcattgcgccacctccaccgtgggattacttatcagtcgatatcctatatgctaagtttgcgacggcagaatacaaactaagctgagttgatgctaaccttacctatgataccccattggaccggttaacagccctacttattccaaataaaagaacttttatgctgtagaagctattatagtgatgcctggtaacttcagtatattaaaatgacacacatacgccatatagagctcctggaactttgaataatgagcgaacttcgaagttgaagagcaagaaaccatatgtcacggttgcctaaagcccggtaaccagacatgtgctatcattgatcattatcgaggttttcataaccttgacccattatcggctgtgcgcggacaagtacttaaatcactagtttcttcacctgcttatcggtaagaaataaggttggcaaagaatcgcataagacggacgtagagccgcagcgttgtgcgagtccaggtgcatgcgcagcaataggattttaaattttgttccatttttaatttagccgtaaggatgtccgtaaatgattgaaaattggattcaatctttgggcctatgctactggaacctgatcgacaaaatttcaaacatacgttaactccgaaagaccgtatttttgcggctagaatagtcagtcgcttggagccatataccttaccacttaaacgacgtgctcctgtagttgaaatataaacagaacacaaagactaccgatcatatcaactgaagatctttgtaactttgaggcgaagcaccctcttcgagacaactaagagtaaagtaccgggcgccgcaaggagtcgattgggaccctaaatcttgacgaattgctaagaggctcagagctaccactgtaatttctctagagcccataataaatgaacgatacatccgtaggtagcacctaagggattataatggaagccaaatgcagttaataatattatatactggcgtacacgattcgacggatctctcacatagtgattcacgacccccccctttgattgacacagcgtcagcattttgcaagaacgatcttctgcatagggtgcgccaccgtaaggatgacgtcgaagctacaactgggtataatttaccatgcttccctgatgctgagtgcaatacactaagaatgagtttttaccccatatcaccagtatttgttctgttattgcgaagaaatggctatgctgagttggcgactaaagtcacccatcctttttattaggtaaccccctcccttaaactaactgatttgctggagctgccctgcatacatatactttatcatttatggacgtccgtgacgcttattatccaccatagtcgatatgctacacggattcattaatggatcgtaggagtttaagttatatttactaagatcggtctcggctactatcccgccttacccggcgctatttacggccatttttaatatattgacggtaattattcctatggtttcgaccgcacgtccttggacaagaaagaatggcaaaaaaaatgtaaaagaaaaaaaatattgagtccctaccatcatataaaaaatatgtgatgagtaacttgacgaaatgttagtggttattaaagactatctattacaccttttgttttctgtcgtagtatattaaagtctagaagccttacaggaaaatcagggttatacagccgatactccgcagcatgaatcatcgaggaggtgtcctaccatcgcgccttgtaatcttgtctgtgtatactgtatttagaccttttatacaaagtaaatatctcggctttatgtgattgggaggggcctactcaaacatgatgacttgacctaataatcactgtgcgggcgtcttatgactagctattccttgaaatccaccaccaaatggttaatatgtaaaaactttgacgatgaaacaaggtgaatgtgtagttactttgtgtaattagctgcgtcgagcattgcttgtaaaaccgtcaatcgcacacgttacttccataaaatttctacgaatacacccttcttaaaaaaaacgtaggaattcacgagtttaacaaacgataactgtataaagtggaagtccgaagaaagcagatgcccgaactactcgaagatgtttcgttttcttaaccataggggcttcttaatggcccactacgcacattttgttcaagcccgagagggacatccccattacgggagtattactaaaactgttccgtaatacgttcagcaagggatgaaaaaggccactgctcaagttattgacgtgggagtattacatcggaagcctgaatcccacactatgatggtctgtacaggcctagggactgcgtctagacggtattaccggcttctaatcatacgatcgtgagtcttaacgggaagtaaggctcacacctaccccaaaccatttatctatgtaagtataaaattgtgcgtaagtgttcaaagtggacaataaagacgtggcaaaaacccccgcacataagccgctttagatttcacaaataccaatgcggttaaaaacatccttgagtcgtacatacaccatactcgcgttaaacggatataacagaagataataaatccggatgtggagtcggtgtaactatagaaagccaagtgaaataatgcttaccagtcatttagctatacggctttcatttcatgtcaagagggtggagtttgacctgtacagttgatatatcaccgatacttagaactcacctaaagctaaaattgctcgcagcgtgtaatccgcatattacaaacaatagatgggattcattatacataagacacgatgatctgctttttcaggttgcgagatgttgcctatcgtcaatcgagtcctgccttacaccacttaaacaaaagtattgacagggaacctattttcgaggtattatatagtccagcttgaatatcaatttgacagttaacctagtgaaaatcagtaagaggaaatacgccacattctccagtgaaattctacgggttatcgtctagtccaactatcaattataactcacgagatataagtaaattctcgtacttggcctgatttttattatactttggatccttagtaaacaggaagggagaaaccttcaacgaaaaacactggattttgttttactctcaaagctcttatatgacggaaataccctgtcaagtcttaactttattactagactaatgaaatgggcttggggtggccagaatcatagtacaatttagcggatacactattcggactttcctatcggctgtctggttggataagtatggggactaataggctagacatacctatacttaaactatacaggcgtcatctatctctgcaactttggagttccctgatgttctcccgccctttgggttcacatcttctataccgacacccctaataacgattagtttgtgggttagagtaaattaatacggttaatattaatgtatcgttgaaaagctggtgtcgccaataaggtaaccggctaggcagagtatatgtcacgaagtataactaccctaatgataagctgtaggaataaaattaatgctgtctctaagcgaagagatatttccgactctgttttaatgacgaatctcattacttctgacttgcaaatgttcaatatggcacggtttcacggcacctttgtgacgcatataatgaacttagaagattataacgacggaactttatatgataatccgttacgattaaagaatctgttaaatatcataatggcattcagttctagaccgtgcatcatggtaaacttactttctctgcatggcgacatacatttcgctattcaaattcgcgtgtggttacacccactcgcacctttggaatattaagagaagatgatcagaaaatccattcgctcaatttttctgacgtacgtctaatttatcctaggagacaaatcgttttatgtctctcacatttttgaagaaaggttcgagagacaatactcaggtcctgaactgctagaagatactcggtggagcgtggcaacaatgaaaaactcgtgacataaatgaatgatacttttccaagttcagttaagtgaatatgtttaacatacccggcttttcgatcttaagctgacgctggacgtgcgagtaatgtcagtctcttacatacactagtgactccaagtttcgtcaaaaacgccccctcccttctcgagcccactcacgctatgtattgacgcgaacttgttcgggatcagacttttcaggagttcggtcgcgtgtccctatgtgctaatatataagttagatcgcattagatgctaatctgaatacttatagacgaccttcaacgagaacgggtaccaccttgaggctagagttaggtgtgaaacgacaggtagggacatataaaatttgagtgcggctttagttaagggtttaattacctactcaaacatcacgctcgcgcccttcgtacgtaatcgaccatctagaggctaaggggactgtactaggtagtgattaatgatatcctagacgcacgtgccttagatcttcagactctgatggtccgcgatcaccgtaattgtagtcctccaactcgatcactttgttggcgtcaaagaaattacgatatctaaatacttataatacaataaccaaggatgagaatgactcatcgcgttggagttatattgcttgaagttctatggaatgaaagcacgttatctgccgtcccaatatctccagtgagctaattcattggacggtccactttgatcaatccccgaggagatgttcggacactttagtctgtaacacttagcgttgagaccacgaacaattgattactcagtcttgaaggtgttttccaaagttcattttaaataagactacgataggcctttcctattgatataaactacccggctctgttgttcgtgtgagtcgtacttctctgtgtttttctgattatagcaagattcgattcttagtgtaaacagcgatttttatttgacccgtcaatgagaagcgcataggatctaagcaaaattatcaagttgtgccacaaggtaagatctttccagttattgcaggtaggatgtatcccacgttgatagtatgaggtctgacgtcaactgtctaggagagttgaccgcgtgcgggtacaccggatttgcatcgatgttgagaacgcagaactcccactgtcgtggcggcgttcctgatatttagcaagaggcgttgataaagccctcatcatctagatctcgacctcatctgccctcttgctccatcattttctacacagactactttcctatctacgttagtataattgctttctatcttagtatcatttagagcttctccgtcaacaggttcgtgctattaaagttagtacgaaagggacaacttgtagcaacgcatttaatcggttttcgactacttcgcacaaaatcagataaagaagtttgtcattctattagacattgaattgcgcaattgacttgtaccacttatgatcgaacactgaatcaagactgtgattaactaaaatagacaagccactatatcaactaataaaaacgcccctggtggtcgaacatagttgactacaggataattaattggactggagccattacattctctacaatcgtatcacttcccaagtagacaactttgaccttgtagtttcatgtacaaaaaaatgctttcgcaggagcacattggtagttcaatagtttcatgggaacctcttgagccgtcttctgtgggtgtgttcggatagtaggtactgataaagtcgtgtcgctttcgatgagagggaattcaccggaaaacaccttggttaacaggatagtctatgtaaacttcgagacatgtttaagagttaccagcttaatccacggtgctctactagtatcatcagctgtcttgcctcgcctagaaatatgcattctatcgttatcctatcaacggttgccgtactgagcagccttattgtggaagagtaatatataaatgtagtcttgtctttacgaagcagacgtaagtaataatgacttggaataccaaaactaaacatagtggattatcatactcaagaactctccagataaataacagtttttacgatacgtcaccaatgagcttaaagattaggatcctcaaaactgatacaaacgctaattcatttgttattggatccagtatcagttaaactgaatggagtgaagattgtagaatgttgttctggcctcgcatggggtctaggtgatatacaatttctcatacttacacggtagtggaaatctgattctagcttcgtagctgactatactcaaggaaccactgctcaaggtaggagactagttccgaccctacagtcaaagtggccgaagcttaaactatagactagttgttaaatgctgatttcaagatatcatctatatacagtttggacaattatgtgtgcgaaactaaaattcatgctattcagatggatttcacttatgccttagaaacagatattgcccgagctcaatcaacagttttagccggaaacaatcgaagcatagggacaatgtatcttttcctaaattgccatgtgcagatttctgagtgtcacgaagcgcataatagaatcttgtgttgcctcaactcgttgaaaagtttaaaacaatcgcagcagtctttttggggtctactgtgtgtttgcaaaataactgaaagaaacgcttgaacaactctgaagtagctcgagtactcattaaagtgtaacacattagtgaatatcggccaatgaaccaaacgcttcccggtacgctatctctctcatcgggaggcgatgtgcaggttatctacgaaagcatccctttacgttgagagtgtcgatgcatgaacctcattgtaacaatagcccagcaaattctcatacgtgcctcagggtccgggcgtactcctccatggaagggcgcgcatctagtgttataccaactcgctttttaactactatgctgtagttctacaggcatagtggccagtattttctaacttctctggatagatgctctcactcctcatccatcacggcttcagtttacgtcttacttgcttgttcagcaacggatggaggcattaagtatcttcactgttccctaaaattgctgttcaatatcaaagtaaggacgatacagggaaagctcaagcacactcattgaatactgccccagttgcaacctcacttaatctgacaaaaataatgactactctaagtgttgcggaagcagtctcttccacgagcttgtctgtatcacttcgtataggcatgtaactcgatagacacgaacaccgagtgagaaactatattcttgcttccgtgtgtgtgacaccaggtaattgatgcggatataagctggagatcactcacgcccacacaaggcgctgctacctctttattccaatgtgtaagaatttgctaacttcatttctagaccgcagctttgcggtcataatttcacggtacggacccttgggttagagacttgataacacacttcgcagtttccaccgcgcacatgttttagtggcttctaacatagaatttttgttgtgacataaagagtgcgtgggagacttgcccgaccgttaagccataatcaattgaaagccccgtgagtcacatctaattggttgtactgcgcatttagctatcctttagctgactcgaagagattcgattcctaatataggttaattagatggctgccgcgcgaagtaaaacgtgaaaaacgtagtgcgcagatctgcataactcgcgcttaattacttatgagtagttccaagttcgctacgttatgagagagattggaattaagcaaatatgttttatggtgattttgggatgagaaggactgctaagtacggctactaaacaaatttctaaaaccgccatctaccttatcttggagacatttaagttgtatatgtcactagtctagcttttgtctgtgggacgcgttctcggaatgagggaaatgcaagagccgattcatcaaatgcttatctaagaaagtagtggactattacaccaagcacgaatgccagggaactgctttcttgctcaggacctcgcgacaaggtaccccgcataagtcctagaattacatttggtcagcaatgctgacatttgaccgtgaaaacataattttaatcagaaggcagctcacccgcttgctctagatcttatctttgtatgaatgtcagaatttactgcaatatccgttccgaatagtgagggcttagtatagttctctgtatacaggtcacatcaaactccccctgtcctagtacagctctgagctttaattaattgcatacatttccttcaatcatcagatgaaaacaccgcgaatcatgctcttctcgtatagggcaagagaagcaacaaacaactagcccgactcacgttcatccgccgtatccttgttcagttcttactccgtattaggtcagcgaaatctaatcagaataatcggtcgcgtatcaaaattaaaatcccgcttgaggttgacaattaaaacgctgagcagttatcggctattagatagtggggtgaaagtaattggctggaattatgttaaaacgtgatattaagctaaaatacgctacttgttgccgacctaattcagtcattcgatattcagttagagccaagaataacaagcttgtataaattgaacggggtgcactaaacgatgtgttactctaatattcagcttggagtatacctgaaggcgaattcatgtatcggccaataataagacgttgaagatcacaatttggactagcaaaagaaggtgatttatgcgtggggattgagtccactgtacgagtacggtctctggaaaattataggttcagggaatataaggaagtaaagataattaccaagagatttttggtatcgctatgacccagaggtgttctaacgtctgttttgatccgcagaatttctgcctcaatgcatatttgacggacttgaactagagcctctaaagttaaatggcgacgcaactgttcctaaacttcaattattactactctttttttcctagggtattgtagaggccagtggacaaaataaatcaaatttaagatgtttcggacattaacatcccccgtagcatagaaatcatcagttatccaatctctcatcgagcttttacaatttctgctggcgctatggacagcatatgccgcgagacctccgcaagactcacttgatcactgtaagtatcttcattagaggttagagcctatagttaagctgctgacctagtaaaattggtattttctaattttattgctcaagttaaaggttagtgaagggataatgacgttatttttgaacaatgggttgtattcaattttatatcacgaatggaacccttcattcccggcataatactagacgacacgaacaagctccgatctatcagccaggcacgtgttaaggtttaattccggcaaaccaatgaagcatcaaaaggtgacctgatgcaacttagggtcacgatgagtttttcaggactacttattacctattaataagttaacatgagccttcataccccgtaagacaatacatactccaccaattagaattctgagccatcttatctttttgtatcatcgaagggtatggccgaataggttaattagttactcctaacgtctctacaggcatgcatttgacgcaccttcgaaaatagtcaatctctcgccacacgcgtctagtatgcagcatcaaaaatatagtccacggtttccggattaccaaacgcggcaaagagaaacattgtatcgacggagataacttaatacagaaggaaggggcatcttcgaatacggatgaataattctatctgtttattctgacatcttgttttcaggttaatcttacgcattcaaatgacgcctgccccatgcgtgcgcaattattttctaatattgacgagagcaatctcactccttttgggtctatttatgttttattgaggcacaagcctatacagaacaggtactattaaggccgtgagtgtgagactcaaaccgtggaaacaaaggatgggttgttcttggtacaagttttagtgcatgtgggcaatccttaccaaaatcagatgctatccttaactttgggctgcatttaagatggcggttggaggcctgtgagaatcctgcgtgtcatctttaatgaccgaattcatccatgtagattcagatcacacactcattccttgatgttgtctaaacaaaagttgttgtggacgcattggagggagttaagtaacaacttgggatcgcatacttataaaaattatatgttaaactttcacaaacgctgaagtccaaagtaactagcccaaacgcctcgagagtcactaggtattaatggtgtttgagttcctgtgaaatagtgttcgaaggtaaaatttatgtaccaaatcgaaagaacacttaataaggcttgcttgcacggaggtatgatgtttactgactctacaaccctaattttccagtacgtacattcattccaataggttagttctcaaagtgctatacaggctcctcaattgatgatatgcttcagccgctctatggatattagctcattttatttaggaagcccgcttagaggcttactatgagggaaatgccaaaatgtcatacttttcggtgtgtcccatatgacaccgctttacatagaatttgaattaaaacgcgctctcccgttcactaccatacttggtaccgtgcgcatattacatatagatataggatcattttttaaagctgtactaggtttgatcgacaatcttatgctatactatatgatgtaaccctcataatcaataccgatcgtacgatcctagcataggtggcaagcgattttatgccgattattgtgttaaatagtctgtgagtgtgattatcagggctacgttggtagaggggttgtatagacctcgcacacattgtgacatacttaacaatatacgaaaactgatataataaatccccttacccaaacaccaatcccgttgaatcaactaccataacgtctcccatataaattgcctacttgtttgcataaatctgaatacataacaccattgcaccttcttgtgttccaatcccgttaagattgccttgtcagatgatatgcaagaacaatagcatttgctagcaattattaacagctcttcgaattgcctccacataacgcgggagggtatattttaatttggcaaatactaagtactgttggcgtcatatgctattaacggttggatattaagttatgtcagccgtaagcaagagtgggcgaaatattttgttacccagtgagagcactcttagagtttggatacaataggccatatgttgacttaagaggacgtaactacgccgtacaccattgttcaaccgacttcttggcaaatagaatcgtattagcaatcttaagaatagagacacgttcgtgttagggtatactacaaatccgaaaatcttaagaggatcacctaaactgaaatttatacatatttcaacgtggatagatttaacataattcagccacctccaacctgggagtaattttcagtagatttactagatgattagtggcccaacgcacttgactatataagatctggggatcctaacctgacctatgagacaaaattggaaacgttaacagcccttatgtgtacaaagaaaagtaagttgttgctgttcaacagatgatagtcatgacgcgtaacttcactatagtaaattgaaacaaatacgcaatttagacagaatggtacggtcatgaatgacagtaattcgaagtgctagaccaacttaaaataggtaaacgtgcccgaaaccccccttaacagaaagctgctatcatggtgcagtatcgacgtgttcagaaacttgtaacttttgagcaggtccgagcacatggaagtatatcacgtgtttctgaaccggcttatccctaagatatatccgtcgcaaactttcgatttagtcccacgtagagcccaagcgttgtgcgactccacgtgcatgcccagaaatacgagtttaaatttggttacatggttaattttgaccgaagcatcgcactttatgattgataattggattcaatatgtcgccctatgcgaatgcaacatgatccacaatttggctataagacgtttaatccgtatcacactttgtttgcggctagtatagtaacgcccgtgcaccaagagtcagtaacaattataagtactccgcaggtacttcaaatataaaaactaatcaaacacgacccatatgatcatctgaagatatttggaactttctcgacaaccaccctcgtactcaatacttacactaatcgacaggcacacgcaacgtgtacagtcgcaccatattgagtcaagatttgcttagtggcgatgagcgtacacgcttatttctctagtcacaattagttatctacgagacatcacgagggagcaaataagcgatgttatggctacacataggcacgtatgaatatgatataagccagttaaacagtcgaaccatcgagcaaattctcatgcaccaacccacacgttgaggcacaaagagtaagctgtttgaatgtaacttcttctgctgagcgggccccaacgtaaggatcaactagaagagaaaactcggtattagtttaaatgcgtcacggagcatgagtgcatttcactaagaatgtctgtgtaaccaatataacatctatttgttatctgattgcctacttatggctttgcggtcgtggcgactaatgtctccaatccttttgaggtcggtaccaactccctttaaattacgctgtgcaggctcatgcactgcatacatatacggtagcaggtagggacctcacgcacccttattataatcaatagtagttatcagtcaacgaggcaggaatgctgaggtcgaggtgttggtatattttctatgtgccgtctaggcgactatcacgcattaccaggcgagatttaagccaattttgaatatagtcaacgtaatttttactatgggttccaccgaaacgccttgcacaactaagaatcccataaaatatcgatatcaaataaaagattgtgtcaataccttcatatatattttttcggttgactaacgtgaactaaggttaggggttttgtatgtctatataggaaacagtttcttttctgtcctactttagtaaagtcttcaagccttactccaaaatcacggtgattaagccgttactcagcagcatgattctgcctgctcgggtcctaaaatccagccttgtaagagtcgctgtgtattagctagggagacctttgttaaaaaggatatatcgcggcgggatgtgagtgcgtggcgcatactcaatcttcagctcgtgtcattataatatctctcccccacgcttttcactagatatgccgtgtaagcaaacaccttatgcttaatttcgaaaatattggtacttgaaaaaagctgtaggggtacttaatgtctggtaggagatcaggagagaattgagtgtaaaaccgtaaagccctcacctgacttcatgtaaatggcttagaagactccatgatttaataaatactacgaaggaaagactggatctaaagataactctagtaaggccaactcccttcaatgctgttgccagttataatccaagagctgtccttttctgaaccatagcggcttctgaagcgaactagaagcaaagttggttctagccagacagccacataccctgtacgggtgtattactaaaactggtccggtattagttcaccaagggaggaattaggcaaaggatctaggtatgcaagtcggagtattacatccctaccctgaatccatcaataggttcctctgtactggccttcgcaatgagtattcaaggttgtacagccgtataataataagatagtgactatgaacgggaagtaacccgctcaccttccccaaaacattgttatatctaagtattaaagtctgccgtagtgttaatactcgaaaataaacaactggcaaattacaccgcacttaagccgcttttgatttatatttttccaatgcgcttttaaaaataattcagtcctacatactaattaagacccttaaacggagatatcacaagttaagttttaaccatctcgactaggtggaactatagatacccaactcaatttatcattacctgtaatgttcctagaaggattgcatttcatgtcaagacggtggagtttcacagcgaaacttcagtgtgaacagattctgagaaatcacctaaacctattagtcagagcacccggttagaaccagttgtcaaaaaatagagcggttgcatgagacagaagtaacgatgagatccgttgtaacgttgagacatctggcctatcgtcaatacagtcctcccttaaaaatatttttaaatactaggcaaacccaacataggttagtcctatgtgatacgccacatggtatatcattttgtaacgttacctagggataatcaggaagtggaattacgcaaaagtagacagtgaaatgcttagggttatagtctagtccaaagataaaggataaagcacgtcagagaactatattagccgaatgggaatcattgttaggagactgtggatcatgtctaaaaagcaacgcagaaacagtcatcgaaaaaatctcgtttttgtttgaatctaaaagagctttgatgaccgatagtacctgtatactagttactgtattacgtgtctaatgatttcggattggggtccccagaatcagacgtcattgtagacgattcaagtttaccaatttaatttcccagctctccttggagaactatcgccaataattgcagtcactttccttttctgaaacgataaagccgtcagagttctctgcaacgttggacttacctgaggttctaacccactttcggttctaatagtagttaacgacacaacgaataacctttactgtggggctttcacgatattttttcgcttattattaatggttacgtcataagctggtgtccaaattaaggttaccggcttcgcagagtagttgtatccaagtataacttccctaatcataagatcgaggtagaaaattaatgctgtctctaaccgaacagatatgtcccactatgtggtatggacgttgctaattacttctgaagggaaattggtcattatggatacgtgtctaccatcaggtcggacgcagatatggttctgtcttcagttgatccaccgttctttataggataataactgacgattaaagattatggtaaatagattaagccaattctcttcttgtcagtgaagcatccttaactgacttgctctgcagcccctcatacatttagctattcaaagtaccggctcgtttcaaactctcccacctttggaagaggttgtcaacttgataagtatatcatttacagcattttttcggacgtacctctaatgtttcattgcagaaaattagttttttctatcgcacattttgcaagtaacgttagagacacaattatctgcgaatgaactgctagatctgacgaccgggagcctcgcaaatatcaaaaaagactgacatatatcaaggagtcgttgacaagtgctggtaagtcaattggtttatctgtcccggcgtttcgatcttaagctgaccatgcacggcagagtaatgtcactctcgttcttacaagtctgtctccaagggtcggcaaaaaagacccctccattctcgagcccactcacgatatgtagggacgacaacttgtgcggcttatgaattgtctggactgcgggcgagggtccatatctccgaagttagaagggacatacctttagatgataagatcaattcttattgacgaaattcatccacaacggggaacaacttcaccctagacttacgtctgaaaagacacctagcgtcttataaaaggtcagtgccccgtttcgtaaggctggaattacctacgcaaacttaaacctcgcgcccttccttacgtatcgacaagatagaggctatcgcgaatgtactacggaggcatgaatcatatactagaaccaagtgcctgtgatattaacaagatgatccgacgcgagcaccgtaattctaggcataaaactccagcaatttgggggccgaaaacaaatgacgttagctaattaattatatgacatgatcaaaggaggtcaatcacgcatcgagttcgacgtatattcattgaacttcgtgcgtttgaaagaaacttttatgaaggcaaaattgatcctgtctcctatttcatgcgtacctcctagttgataattccccgagcagtggttaggacacttttgtcggtatcaagttccggtctcaaaacgtaaaattctgtaatctgtatggatggtctgtgaattagttaatttttatgaagtcgtcgagacgcagttcctattgatttattctaaacggagatgtgcttcgtgggactcggaagtagatctgtgtttatgattattgctactttagatgctgactgttaactccgtgttgtttttcaaccgtatatcacaaccgaattggatagaacctatagtttcaagttctgccacaaggtatcatatttacagttagtgctggttgcttctttcaaacgtggtgagtttgtgctatcacgtcaacggtagagctcagtggaccgagtgcgcgttcaaccctgttccagagagggtgtgatagcacatataccacgctcgtcgaggcgttcatgatagtttgcaagagccggtgttaaacacatattattattgttatccaactaatcggacctatgcataaagcattgtctaaacagaataattgcctatatacggtagttttagtgatttatatcttagtatcagttagagcttcgaactcttcaggttcctcatatttaacgttcttcgaaagcgaaaacttctacaaacgaatgtaagcggttttccaagtagtacctataaatcacagaaagatctgtctcagtatagttgaaatggtattcagctagtgacgtgtaccaattatcatagttcactcaagcaagacgctcattaacgaatatagacaagacactatatcatataataaaaaagaacatggtgctcgaacatagttgaattcaccatattgaaggggaatgctgacatgtaattcgctactagacgatcaattccctacttgtcaaagttgaactggtacgttcttggaattaaatatgattgcgctggaccaaattgcgacttcttgagtttcagggcaaacgattgagccggaggatgtccgtctcttacctttcttgcttatgataaacgacggtccctgtacatcactgggaattctcagcaaaaataattgggtaaatcgagactcgatgtattcggccacaaaggtgttagacgttaaagattattcaacggggcgataataggatcataaccggtatgcaagcgcattgaaagagccatgagatccttatccgataaacgctgcacggtatgtgcagccttattgtcgatcacgaatttataaatgtagtctgggctgtaagttgaagacctaagttataatgaagtgcaataccaaatcgattcatagtggattatcagactcaagatatctcctgataaattacagttgttaagatacggataaaatgagatttaagattagcagcctctaatctgtttcaatcccgttggaatgtggtatgcgatcaaggttaagttaaaatcaagcctgtcttcagtcttgattcttgttctgccatcgcatgcggtctacgtgagttaatatgtagcttacgttctagcttgtgctaatctgagtatagattcgtagaggaatattatcaagcttccacgcctcaacgtacgtgtattggtcacacaagacactaaaagtggaagtagcgtaaactatagtctagttgttaaatgctcagttcttgttatattcgatatactcttggctaatttatgtctgagtatataaaattaatgatattaacttgcatttcacggatcccttagaaaaagattttgaccgagcgcattataaacggttacaccgaatcaatagaagcatacccaatagctttctttgaatttattgcctgcgcaacttggctgactctctagatccgaataattctatatggtcgtgacgaaactagttcattactgtttaaaatgccaacatgtcttttgggccgataatggctctttgcaaaattactcaatgatacgattgatcaaagcggtagttgctagtggtagcatgtaagtctatcaaatgtctgattatccgaaaatcttccaaaagagtccacgtaccatatctatctcatagcgacgcgaggggaaccttatctaactatcattccatttaccgggtgactctcgatgcaggatccgattgggataaattgcccagaaatggctcattcctgactaagggtaaggccgttctcagcaagggaaccccgcgaatctaggcttataccatctagattgttaactacttgcctgtagttctacagccatactggacagttgtttctaaatgatcgggattcatgctagcactcctctgaatgcaccgcgtaagtttaactattacgtccgtgggcagataaggatggaggctgtatgtatcttaactgttacctaatatggctggtaattatcaaagtaaggaccttaatgccatagcgctagcaatcgctttgtatactgaccatgtgccaacctctcttaatctgtaaaatataatgtcttagctaactgtggacgatcatgtctctgcctagagcttcgctgtatcaattcctatagccagcgtactagtgacacaacaacaccgtgtgagaaaagatattagtccttacgtctgtctctctacagcttattgatgaggattgaacatggacatatagctccccctcaaaagcagatgctacctctttattccattctcgaacatttgccgaacttaatttcgacaaacctgaggtcacgtcttaatttatcggtaacgtcacgtccctttgagactggataaatatattaccaggggccaacgagcaattgttggaggcgcttctataatacaaggtgtcttgtcaaagaaagacggcgtgcgtctcgtgcaactcacttaaccaatattaatgtgaaacccccctctctcacatcttatgcggtgtactgccctggtacatttcctgtacaggactccaacagtgtagattcctaagatagctgttggagttgcctcacgccagatcgaaaaactgaataaactagtgagctgagctgcagaaataccgcttaattacttatgactagttcaaagggacctacgtgatgtcagacattgcaaggaagaaattaggtttgtgcgtcattttggctggactagcactccttacttcccctactattcaaatgtcgtaaacagcatgagacaggatcgtgctgacatttaaggtctattgggaacgaggctacctttggtcgcgcgctcgcgttctccgaatgaccgaaatgcatgagcacagtatgcaattgcttatagatctaaggtctggtcgttgaaaccaagcacgtaggcctgggaaatcagttcttcctcagcaactacacaaaagcgtccaagcattagtacttgtagtaaatgtccgaacctatgcgctcatttgaaagtcaaaaaatatttttaagcagtaggcacctaacccgattcctctacttagtagctttctttgattctcagaattgactgcaatatcactgcacaattctgtgccattactagacttctctgtattaacgtctcatcttactaacactcgcctaggacacatctgagagtgaagtatttcaatacatttactgaaatcttcagttctaaaatccccgaataaggctcttatcggtttggccaacacaagaaaaaaacttcttgcaccactcaccttcatacgcaggagcctggggaacttagtaataactatttcggcagacaaagcttataacaagttgccggcgcgtataatatttaaaagaccccttgagctgctcaattaaaacgctcacctggtataggctattagatagtgccgtcttagtaaggggcgggaattatcggataaactgatattttgataaaataaccgacttgttcacgacataagtcactaaggagattttatctttctccaaagtatatcttccttggataatttcaaagcgctgcaatttaagttctgttactagtttatgctgctgggaggtgaccggaaggcgtagtaatctagaggcaaattataagaagttcatcatatcattttcgactacaaaaacaaggtgttgtatgccggcgcattgtgtaaactggacgagtaccctagatggaaaattatacgttaagccaagatttcgatgtaatgataattacctacacatttttgctatccataggaacaagagctgttctataggctcgtggcatacgaacatttgctgccgctatgaatattggaagctcttcaactacagactctattcttaattgccgtcgaaaatgggccgaatcggctattattaatactcggtttttccgaggggattgttgtcgacagtcgtaattattattaatattgatgttggtgaggtcatttaaatacaaccttgcagacaatgaataagggatccaatctctcatactccttttacaattgctcatgcccctatgcaaaccttatgccgccacacctccgcaactctctcttctgaactgtaagtagcttcattactggtttgagactatactgaagctgatgacattctaaaatggctattttcgaatgtgattcataatgtttatcgtttgggatggcagaatcacgttatttttgatatagcccgggtattctattgtatagaacgtatgctacaagtcattccccgaagaagactagaagtaaacaacatgcgaccatcgttaagccacgcaaggctgtagctttatttcccgataacctatcttccataaatagcggacagcaggatactgacgctcaacatcagtggttatggtctaatttttaacttttaataaggtaacttcagcaggcatacacagtaactctttaatttataatcaaattagaagtctgacacttcttatatttttctatcatccaacgcgatcgcccattagcttattgtgttactaataacgtatctaaaccaatccttttcaagctactgcctatattgtcaatatatacaaacaacaggatagtaggctgcttaaaaaatattgtcaaccgtgtacgctttacaatacccggaaatcacaaactttgtagacaacgagtgaaatttatacactacgaagggccagcgtacaagacccatgaattaggcgatatgtttattctgacatattggtttatccttaatctgtcgctgtaaaatgaagccgcccccatccctgcgaattttttttcgaagattcacgactgaaatataaatacgtttggctatatttatgttggagggaggcaatagcctttactgttaaccgaagatttagccagtgagtgtgacactaaaacactggaataaatgcaggcgttcttctgggtaaaaggtttagtcaatctcgcctataagttcatatagctctggatataattatctggcccatgcatttatcatggcgcttggtgccctgtgtgaagccggcctctcatattgaaggtccgaagtattccatgtacattaagatcactctctcattcatgcatcttggcttaacaaatctggttgtccaagctttccaggcacgtatggtacaaattcggatcgaatacttataaaaatgatatgttaaactgtctaaaacgctcatctacaaagtaaagtgcactaaccaatagagtctcaagaccgtgtaatgctggtgcactgaatgtgtaatacggttagaagggattagttatgttacaaatccattgaaaacttaagaagcattgcgtgctcggagggtgcatcttttatcaagagactaacattattttcaacgacgtacatgctttacaatagggtacttatcaaacgccgagaaacgcgcctatagtgatgttatgattatgacccgatatccattggaccgaattttatgtaggttcccagcgtactcgcgtaatatctcggtattgccataatgtaatacttgtcggtctctcccagatgaaaaagcgttacagagtatttcaatgaaaaacagcgcgcaacgtcaatacctttaggggtaacggccgctgatttcatatagatatacgataagttggtatagctctactaggtggcatccacaatcgttgcatttactatagctggttacaatcataatctataccgttccttacatactaccatagcgggatagcgtttttttgccgttgattgggtttaagaggatgtcagtctcattatatccgattcggtgggagagccgttgttttcaaatcgcacactttgtgacataatgtacaagataacaaaactgatataagatataaactgtcaatatcaccttgacacttgaatcaaagtaaattaactcgcaaatataatttgactaattgggtgcagatttctcaattaataaaaaaatggcaccggatgggcttacaagccccttatcattcacttgtatcatgatttccaagaacaatagaatttgctagcaagtatgaacagagattcgaattgcatccacagtacgccggagcgtttattttaatgtggatatgacgatgtactgttggcggcatttgctagtaaccggtccttatttacgtagcgcacacgtaagcatgtctgggagaaatatggtggtacaatctcagagaaagattacagtttggtttaaataggacttatcgggtcggaagtggaacttaataagcagtacacaattgggcaacagacgtcttgcctattacaataggattacaatgcgttagatttcagacacgttcgtgtttggctattcgtcaattccctaaatagttagacgatcaactattatcaaagtgattctttgttcatcctccattcatgtaacagatggcacactacgcataacgccgaggaattttaacgagatttaagagagcagttcgggcacaacccacttgactttataacagctcggcagcataaacggtaatatgtgacaaatttccaaacgttataagaacgtatgtgtacttagaaaactaagtggttcatgttcaacagatgtgacgcagcaagcctaacttatctattggttttgctataaaagaacaaagttacacagaatcctaagggcttgtttcacacttatgcctagtgcttcaccatcttaaaatagcgaaaccggcacgaatcaaaccttaaaacaatgcgcagatattggtgatggtgactccgggtatgataatggtaactgttgaccagcgcccacctcatcgaagtatagaaagtggttaggataaggatgagaccgaacttatttccggccataactttagattttctacctagtacacaacatcagggcggacacgaaaccgccatcacatcatataccaggtttaatttgcttaatgggggaagtgtcaacgaaccttcgaactttagcaggcatatggccattatatatggccccagagcagaatgctacagcagacaaaatttggatttatgtagtttaatacctatcaaacttggtgtgaccatacttgtctaacgacagtgcacaaagtgtaagttacaattattactactcagcagcttctgcaatgataaaatcttatcatacacgtcacatatgataatatctacttagggggaacgggctccacaacctacatagtactcaatacttacactattcgacaggcacaccaaacctgtacagtcccaaaagattgagtcaactttgcagtactgcagatcacagtaatagcttagttagcgagtcaaaattagttttctacgagactgcacgaccgtgcaaatttccgatgtgttggctacaaatagcaacgtatgaatttgtttgaagccacgtaaactgtacaaccttagagataagtctcaggctactaaaaacacgttgtggcactaacaggatcatggttgattcttacttattcggctgaccggcccaataagtaaccttcaactagaacagaataatcgggagtagtttaattcagtcaaggtgcaggtctcattgtaactaacaagctctgtgtaaccaagttaaaatcgttttcttagcggattccctacttatggatttgagctcgtccacaatattcgatacaagaagtttgtggtccgtaacaacgaaattttaattacgctgtgcagcctcatccaaggaattaatagaaggttgatggtaggctccgaacgctccatgattataatcaagtggactgtgcagtaaacgaggaaggtatcctgacgtcgtggtgttcgtttttgttatttgtgccctatacgagtagataaaccatgaacagcacagtgtgaacccatggttgattttaggctaccttatttttaatttccgttacacagaaacgaattccacaactaacatgccattaatttttcgatatcttataaaagatggtcgaaattcattcatttattttttttcggttctcgaaagtcaactaagctgtcgcgttttgtttctctttagaggtaaaagtggctttgatctcctacgtttggatactagtcaaccattactccatttgatccgtgagtatcacctgtctaacatccagcattatgactcctcggcgaagaaaagacacacttcttagagtcgatgtgtattagctagggacacagttgtttaatacgatagtgagcccagggagggcagtgcgtcccccagtagatttattcagctagtgtaagtataagatatctcacccacgaggttcaagtgatatgcagtcttagaataatacttatcctgaatttcgatattatgggtacttcaataatccgctagcgctactttatgtctcgttggacagcaggacacatggcagtcttaaacactaaagacatcacctgaatgaatgtaatgggattacaagaatcaatgaggtattatatacgacgtaggaaactctggatatatacagtaatctagttacgccatcgcacttcattcctctggaaacttagaagacatcagctgtacgtggaggaaccagacccccgtatgtagccaaatagaaccaaagttgcttatacaaacacacccaatgacaatggaccgctggagttcgtaaactcggaacgtagtactgcacaaacccagcatttagcaataggagctacgtatgcaactcccacgtggtaataccttcaagctatcaatatataggtgcctagctaatcgcattcgcaagcagtattcaagcttgtaaaccagtataataattacagaggctctatgaaacccaactttccagctaaaagtcccaattaaatggttatttcgtacttttaaagtcgcccgttctgttattacgcgaattgattctactccaaaattaaacacaaattatcaaccgtttcatttatatttgtcaatgcagctgtttaaaataaggctctactaaattataattaagacacttattaccagatttctctagttaagtttgaaccagctcgactaccgcgaaagatacattcccttctctatttttcagttcatctatgggtcagagaagcattgaatttattctattcaccctcgtcgttcacagcgaatcgtcagtgtgatcagtgtatgagaaatatcctaaaccgtttagtcagaccacacgcttagaacaagtggtctaaaaagactgccctggaaggagtaagaagtatacagctgatccggtgtatccttcagtcatctgccctatactaattacacgacgcaaggaaaaataggtttattttctaggcaaacccttcataggtgactccgatgtgttacgaatcatgcttgagaatgtgctatcgttaccgacggataataacgatctccaatgaaccaaatgtagaatgtctattgattacccttttactattcgacttagagataggagatagaacctcagtgtacttttttagccgaatgggaatctttgggaggtgaatggccataaggtcgtaaatccaaccctcttaaagtcttccatattatatcgttgttcgtggaatcgataacagatttgttgacccatagtaaatgtatactagtttatgttgtaagtgtagattgttttccgattgccgtccaaactttatgtcgtaattgtagaccagtaaagttgaccaaggtaagtgcccagcgatcctgcgagatcgatcgccaatttttccagtcactgtaagtgtaggtttagataaagccgtatgagttatatcataagggcctcggaaagcagcttcgaaccaaagttcccttataatagtagtttaactataaaagtatatactggtctgtcgccctttcacgatttgttttaccggtttatgaagcgttacgtcattagagcggctccaatttaaggttaacggcttccatgtgtagttgtatacaaggataacttaaagtatctgttcagcgagctagttaagttatcctcgatagaacacaactcagaggtcccaagatcgggtttgcaacttgctaatttattctcaaggcaaattgggaattatcgatacctgtataccataaggtcgctcgatgtgatgcttatgtcttctggtgatcctaccttagttagtgctgattaacggaacattaatgtttatcgttttgagatttagccaattctctgattctaactcaagatgccttatctgacgtgctatgcagcccctaagtattttacattgtaataggacacgctcctttaaaactcgccaaaaggtcgttgtggttctctactggttaactatataatttacagctttgttgagctagttcctctttggtttaagtcctcaatattagttggttcgagcgataagttggctagttaccttagtcactatattagatccgaatgttatgcttcatctgaagaccgccaccctccaaaatttcttttaagactcacttattgcaaggtgtaggtgaattcggctcgtttctcaagtggtgtatctgtacacgagtttccatattttcatcaacagccaccgcacacttatgtcactctaggtattaaaagtcgctctacaaggggacgcaattaagaaacagacatgctagtcaaaaataaacatagcgaggcaccactaattcggccgcttatcaatgggatgctctgcgcgagacgcgccagagctcagtagttagttcggacatacatttacttcagatgatcaattagttttctacaaatgcttactctaccccgaaaaaagtcaccagactcttacgtctctttagtatccttccgtcttatataaggtcagtcccccgtttcggtaccctggaatttactaagaataatgaaacagcccccaaggacgtacgtttacaaatgatagaccagatcgcctagcttattccgacgcatgttgcatagaattgaaccaacggaatgtgagagtaactagatgagccgaccacagcacccgtttgcgtcgcagaatacgcctgatagttcggccacgaaatcatatgtcctttgagtattaagtatttgtaatgatcaatcgagctcaagcaagcttacacttcctcggatattcagggaacttagtgcctttgaaagatacgttgatcaacgaaaaattgataatggctcatatggaatgcctacctcatagtgctgaattaacacagcactgcggacctaacttttcgaggtttcaagttcacgtctcaaaacctaataggctggaatatgtagggatcctcggtgaatttgtgattgggtttgttgtagtactgaccaagtgaatattctttttttctaaaagcagatctgctgccgggcactacgaaggagatctctgtgtatcattattgcttcttgacatgatgactcttaaatcactgtgggtgtgcaaaacgatagcacaacccaattcgatagtacatattgttgatacttcgcactaaaccgttcatatttaaaggttgtgctccttccttcgttaaatactggtgacttggtcctatctactattagctagacctctggggaaccacgcccccgtaaaacctgtgcaagagagggggtcatacatcttagacatcgcgcctccaccagggaagcattgggtgattgaccaggtgtgtaacaaatatgattattcttatactaatattagcaaagatgcataatgatttgtattaaatgtataattgaattgataagggtcttttagtcagtgatagagtagtataaggtagacattagaactcttaaccggacgcagatttttcggtcttagtaagccaattagtcgacaaaacaaggtaagagcggttactagtagtacctataatgcactgaatcttcggtcgaagtatagttctaatgctatgcagattgtgacggcgacaaatgttcagacttatatcatgaaacaagctcttgtaagtattgacaaatgaaaagattgaatatttttaaatacaaaatgcgcctacttattaggggaattaaccagattgaaggccaatcctcacatgtaatgagataatagacgataaatgaaattcttgtaatagttgaactgctacgtgatgggtattatatatgattgagatcctccaattgccgacgtcttgtcttgatgcccaaaagattgtcaacgaggagctccctcgcgtacctgtcgtccgtatcataaacgacgcgacatgtacagcactccgaagtataagcaataataatgcgggtaatccagactagatcttttcggactcaatgcggtttcacggtaaacatgattaataccggagagtagtcgagcttatcagcgatgcaagcgaattcattgtgccaggagatacgttgcagataaaaccggcaacgtatgtcaacaagttttggcgatctcgttgtttgtattcgacgaggcgcgggaacttcaagaactatcgtatattcaagtccattaccttttagtttcagactggtggagctgactaaagttatatcatcattttgtacactggtttagttaacgataatttcagatttaacatgaccagacgataatcgctgtatatccagttggaatgtggtttgccagaaaggttaacttataatcaagcctctcttcagtcttgattcgtcgtatcccatccattgcgctatacctcagtgtatttggagctgtagttataccgtgtgctaagatcagtagacatgacgagagcaatattatctaccttacaagcatcaacggacgtctagtcggaacaaaagactctaaaactcgaacttcaggttaatatactatagttctgtattcagcagttattcttatattcgatattatcttgcctattggatgtctgactttagtatattaatcatagtatctgccatgtaaaggtgccagtactaaatctgtttcacagtgcgaattataaacggttacaaccattaaagacaacaagaccctatagctttatttgaattttgtcaatgcgcaacttggagctcgcgatacatcccaattagtctatagggtcgggacgattctacggcatttctggttataatgacaacatggattgtggcccgagaatcgctctttcattaattaagcaatcattacagtcttataagcgctacttccgagtggtagcaggtaactcgatataaggtcgcatgagccgaatagcttaaaaaacaggccaccgaacattgatagagaataccgaccacagcgcaacctttgattactttcattaaattgtacggctcactcgacatcaagcttaagattgcgataatgtgaactcaaatggatcagtactgaagaaccgtaacccacttcgcagaaagcgtacccagagaagatacgctgttacaatatacagggtgaaattattgcctgttcttcgtaaccatttcgccaaacttggttagaaatgatagccattcatgatagaaataagctgaatgataccagtatctttaactatgtagtcagggggaagataacgatggtccatgtatgtttctgatatgtgacagtattggccgcgtaatttgctaacgaagctacttaatgcctttgagcttcatatagatttctttaatcaaaatcggcaaaaagatagtatgagctataatatatgctagtagagaactctggaccatcatctatatgaatactgattcgagcgtgcaattactttagcctgcgtactactgactctacaaaacactctgagataagtttgtagtcagtaagtcgctctctataaaccttttggatgaccattgtacagccacttatagatcccaataaatagcacaggagacagagtttttcaatgctcgatcatttgccgatagtattttcgtctaacctcagggcacctattatttgatacctaacctaacggccctttcacaatggagaaatatatgacatcgggacaaacacaaatggtgggtggccaggagatatgacatggtggcgtctctaagaaacacggactccctctaggcaaactcacgtaaccaattttaatgtcaaacaaaacgctcgaaaagattttgccgtgtaatgacctggtacattgactggtcaggaatacatcactgtagttgccgtagtgtcctgttggtgttccatcaagacacatcgtataacgcaatttacgacggacatcagatcaagttatacagattatttaagtatcacgtgtgcattgggacataagggatctcacacatgccttggaacatttttgctttgtgccgctttttcgctgcactaccaatccttacttaccagtatattcaaaggtcgttaacagaatgagaaaggttagggctctaagttatcgtcgattgggatagacgagacatttgcgagcgccctccacggatacgaatctcccatatcaatgtgaactggatgctatgcagtttagttcttacgtctcctagtggtaaaaatcaaagtagcactcgcatagcagttattcagaacctaatacacaaaaccgtcaaacattttctaattctaggtatgggccgatcataggagctaaggtgaaactcataaatgttttgttagatctagcatcctaaaaagatgcatatactgagtagctggcgtgcattctctcaattgtatcctttttaactgaactagtcggtcccatttcgtgactgagatctattaaccgataagattaataacactcgcattcgtatcagctcagagtgaagtttttcaataatttgactgatatattaacttctaaaataaccctttaagcctcggatccgtttcccaatcacatcaaaaattcttattccaactatctacggattaacaacgtgcatggggatcgtagtaagaacttgttccgatcactttgagtatatcaagttgacggcccggttattattgaatagaaacattcacctgctaaattaaataccgcacatcggatacccgatttcagagggccgtcttactaagggcaggctttgttcggtttaactgagatgttcattattttacagtatgcttcaactaatatgtaacgaaggacagtggatctgtctccatagtagatcttcagtcgtgaatttcataccgctcctatttaagttcgcgttcgagttgttgatcatggcacgtgaaagcaacccctagtattctagacgaaaattttttctagttcatctgataatttgccaattcaaaaacaaccgctggtttcccggcgcattctctaaaatggaagtcgaacctagagccattatttgtcggtaacccatgagttccttcttttcagaagttaatacactgtggtcctatacagaggaaaaacagcggttatatacgatcgtggcataacaacattggatcaagatagcaatttggctacctattctaattctcactagattcggtattccactacaatatcggcagattaggattggatgaataatcggtgtttaagtccggttgcgtctccaatctcctaatttttattaatattgatcttggtgacctattgtaaataaaaacttcaagactttgaataacggtgaaaagatagaagactcatttgaaaatggatcatccacagatccaaacattagcaagacactaatccccaactagctattctgatcgcgatcgtgctgcagtactcctgtcacaatagtctgttcatgatctaattctttttgggctttgttcgatggtgattcagaatctttatccggtcgcttccctgtagctactttgtggggatattgcccggggattatagggttgagatcgtttcctaaaagtatttaaaccaagtagacttcaactaaactacatcagaacatcgtgaagacaccatacgcggtacctttatttaccgataacatttcttcaagaaataccggtaagcagcataatgaccctaaacagctcggggtatcgtcgtagttttaaattttatttaggttactgctcaaggaataaaaactaactatttaatttataataatattacaaggctcacactgattagatttgtctataagacttcgcgatcccccattaccggattgtcttaagaataaactagataaaccatgcattttctagataaggcctttagtctaattagatacaaaaaacacgatagttgcatccttaatttattgtgtcaaacctggaaccttttaattacccgcaaatcactttatgtcgagactacctctgaaatttattatctacctaccgcatgaggacttgaaccatcttgtaggagttatgtttattagctaagattcgtttatcctgtagcggtccatgtatattcaacaagcaaaaagcactcagaattgtttttagttgagtcaagactgatatataaataagtttccctagttttttcgtggtgggacgatattgaattgaatcttaaccgaagagtttcccactctgtcgcacaataatacacgccaatatttccagccctgcttatgccttaatcggttactcaatctcccattgaagttcattttgatctgcatagaagtttcgggcccagccttttttctgccaccttcctccaagctctgtagacgcactctaagattgatgctcacatgtattaattctacattaacataaatatataagtcatgcatcttcgagtaaaatatctggttctccaacatgtcctggcacgtatcgttataatgcccatacatgtagtattaaaatgattgggttaactggatattaagatcatcgaaattgtaaagtcaaattaacaatactgtctcaagaccgtgtattcctcgtgctcggaagggctattacgcttacttccgttttggtatcttaatatgactttcaaaaattaagttgcagtgagtcctacctgcgtgcatcggttagcaagagtataaaagttgtttaaacgaactacttgctttacaataccggtcgtatatatcgccgtgaatccagaagattgtcttctttggattatcaaccgagatcctgtggaccgatgttttgggaccttcacagaggactccaggtagagctcgcttttgcattaatctaagaattgtacctctctaaaagatctaaaacagtgaatgtgtatttcatggaaaaacacagagaaacgtaaattactttaggccgaaaggcacatgagttattatacatatacgagatggtggtatacatcgaattcggggcatacactatagttgcattgtatttagctgctttaaataatatgatattaccttccttacataagacattaccggcataccctggttttcaacttgtggggctttttgacgatcgcactctcatttgatccgagtagggcggtgacccctgcttttcaaatacaaaaatttcgctatgaaggtaatagattacttttcgctgttatgatagaaacggtaaatttaaaattgaaacttctagaaaagtaaagtaacgagaaatgattttgtgaataatgcggtcatgattgcgcaagtaagaaaaaaaggcaaaaggatgcgcggaatagaaacttatcagtcacgggtatcttgatttcattcttcttgtcaattgccgacataggatgaaatcagattccaatgcaatacacagtaacccccacccttgattgtaatgtcgatttgaagttgtacgcgtcgacgaagtggatagtatacgggccttttgtacggtgcgatcaactatgaatctcggcgagttagatggtcgtacaatctcacacatagaggtcacttgcctgtaatgacgaattttcggctaggtactcgaactttattagaagtaaaaatgtgggcaaaagaaggattccattttacaagacgattacaatgagttacatgtctctcaacgtagtctttccctagtagtctttgaactatttaggtactccagaaaattttagcaaagggtttctgtgtgaatccgccattcatgtttatgatggaacaataagaataacgccctcgtatgttatcgacagtgaagtcagcagttcggccaaaaacatattcaatttagtacagatccccagaagttaagctaagtgctctaaaatggcctaaacggttatcaaagtaggtctaattactatactaacgggtgcatcgtaataactgctgtcgatgcaacactatatgatagtgtcgttttgctatatatgtacaatgtgacaaagaagccttagcgattcttgcaaacttaggacttcggattctcaatcttaaatgtccgaaaacgcaaagattcaaaaatttaatctatgagcagatatgcctgatggtgactacgcgtatgttaaggctaaatgttgacaaccgcacacataatcgaactattgatagtcgggagcataaccaggtgaacgtactttgttcacgacatttattgacatgttctaaatacgtctcaaaatcacggcgcactagaaaacgcaatcaaatcattgtcctggtttaagggccgtaatgccggtagtgtcaaacttcatgagaactttagctggcttttggccagtatttagggaccaagagcactagccttaagctgaatattttgccatttatctactgttataactttaaaacttggtggcaccagacttgtcgatacacacgcatcaatctgtaacgtaaaaggtttactaagaacaagcgtaggaattgagtttatattatatttaaactaaaagatgatattagcttctgagggcgatagggctccaaatcataaagaggaatatattattacacgattagaaacccacaacatacctcgaatcgcccaaaagtttgacgaaacttggcagtactccacatctcagtaatacagttgggagagtctcaaatgttgttttattactcaatgaaccaccctcataatttcactgctgttccattaaatttgcaaacgatcatttgctttgaagaaacgtaaaatcgacaaaattacagataagtagatgcataataaaaaaaactgctcgctataacacgatcatcgtgcattcttacttaggagcatcacccgcacaataacgtaccttaaactacaacactattagaccgagtactgtaattcacgaaagctcaagctcgcattgtaaagaacttgctctctcgtaaaatgtgataatagtttgcggagaggattcaattattttccattgcacctactccactagattcgataaaagaaggtggtcctcccttaaaaagaaatgttaagtaacatcggaaccataagcaaagcatgtaagtgaaccgtcatccttccctaagaaacataaaggtttttaataatgtcgactgtgaactataactgcatcctttcctgacctactccggttccttgttgttatttctgaacgagaccagtagataaacaatgtaaaccacagtgggtaccaatggtgcatgtgacgctaccgttgttttaagtgcccgtacaaacataagaagtcataatcttacttgaaattaattttgccttttattttttttcaggctcgaaattaatgatttgttttttttgaccttctagttacgctaatatgcggtcgcctgtggtttctattgagtcctataacgggatgggatctaatacgtttggttactagtaaacaaggtataaatttgataccggagtatcaactgtataacatcaagctttatgactcatacgcgaagtaatgacacaaggctttcaggagatcgcgagtacagagccactaaggggtgtattacgatagtgacaccaccgagcgcactcactccccaagtagatttatgatcctacgctaagtattagatatataaccaaagaggttctagtcagtgcaactcttagaataataattagccggttttgcctttttaggcctaatgcaatattcagctagcccttatgtatctcgcgttccacagcaccactcatggcacgcgtttaaactaatcaaatataatctatgaatgttatgccagtacttgaataaatcaggttttttataagtccttgcatactctcgttatatactgttagagtcttaccccatagaaattctttcatctgcaaacttagaagaattctcagctacggggagcataaagtccccaggatgttgacaaatacaacaaatgtggcttatacaaacactccatatgaaaatcgaaccctcgtggtagttttagccgaaccttgtacggataaatccctccattttccaatagcagatacctatcctactacctcgtggtattaaattaaagcttgaaatatagagctgcatagcttatccaattcccaagcacgagtctaccgtcgtaaccacgatttgatttacagacgctagagcaaacccatctttaaacatataagtaaaaattaaagggtgagtgcgtacgtgtttactagcaacttcgcttattaagacaattgtttataagccataattaaaaacatatgttcaacaggttcattgatatttgtaattgcacaggtttttaataaggatctacgtaagtataatgaacaaactttttaccagagttatattctgtactttgaaaatgctcctctaccgccttagagactttcaattagattttttgcagttaatctatgcgtaagtgaaccatgcaagggatgcgattcaaccgcctcgtgctaaccctatcgtctgtctcataactgtaggtctaatataattttcagttttcgaacacataaccctttgaaaatctgctatttaatgtctcacctgcatgcactatcttctatactgctcagaacggctatacgtcactatgctccaagtgacgatttaaacgaagcaaggaataataggtttattttagtgcaaaacaattaagtgcggactacgtgctctttacaataagccttgtgattgggctataggttaagtcccatattaacgatctccaatgtacaaaatcgacaatcgctttgcattacccggttactagtcgaattacagatagctgttagatactcactctaattttggacaacaatcccaatcttggggtcgtctatcgcctgaagctcgtaaatccttccatcttaaacgattacatattatagacttgttcggggtagagatatcacagttgtgcaaacattgtaaatcgatactagtttatgttggtagtctagttgcttttaccattccccgaaaaacttgatctactatttcgacaacagtaaacttgaactaggtaagtgaaaacagagaatgcctcatagtgccactatttgtccactatatgtaagtgtagctttacataatccactatgactgagatcattacggcctaggaaagcagcgtagaaaaaaagggcccggatattacgactgtaactataaaactagttactggtagcgcgccatgtatagatttgttttaccggttgtggttgcgttaacgaatttcagccgcgaaaattgatccgttaaccagtccatctcgacttctataaaacgataaagtaaagttgatgttcagcctccttcttatggttgcatcgagagtacactactcagtgggaaatagatcggggttcctacttcagattgtattatctaggcaattgccgattgtgccatacctggataaaataagctacctacatgtgatgcttatctattatcgtcatactaccttagggtgtcctgttgaacgctacattaatctttagccgtttgagatgttccaatggataggagtctaacgcatgatgaagtttaggaaggcagagcatcccactaagtatgtgacagtgtatttcgaaacgagacgttataaatagaaaaaaggtccttctggttctattctgctgaactattgaatggaaagattggttgacctacgtactatttgcttgaagtcatcaatttgacggggtgagagacatatggtgcatactttacggactctatattttagatcagaagcttagcagtcttctctacaccccctcacgacataattgcttttaagaatctatgtttgattcctctacgggaattcggatccgttcgcatgtgcggtttatctaaaccaggggacatatgttcagctaaagcatacgaacactttgctaactagacgtatgtatagtagctataaatcccgacgatatttacaaaaagaaatgagactcaaatatatacatagcgaccctacacttattcgcaccctgatctaggcgatcctagcacccacacccgaaagtgagcactagtgtcttccgtattaaatttactgcagttgagattttagttgtctactaaggattactctaacccgtaataaggatcaagactcggtactagctttactatcattccctatgtgttttcctaactcacaagggtacgtaccagcctatgtaattacaataatgataaagacacaaaggaagtaactttacaaatgagtctccagttacactagcttagtccctcccatcttgctttgaagtctaaatacgcaatctctgaggatatacagcagaagaacactcataacgttggagtccaagaattagactcatagggcccccaacatttaatatgtactgtgagtttgaaggtgttctattgttaattcctgctcttgatacatgacacgtactccgtgtttaaggcttcggactgactttctttcataagttgagcaacgaaaatttcagaatcgataagttggattcactaactaatacggctgattgaaaactccactccggacctatatggtcgacctttatacgtaaccgatataaaacttataggctggtatatcgagccttcctagcgcaatttcggatggggtttcttctactactcaacaacggaatagtctttgtttagtaaaccagagctcaggacgcccaatacgtaggagagcgctgtggagcatgtgtcattatggactggagcactcttaaatcactctgcgtgtgctaaacgatagatcataacatgtcctgagtaaattttcttgatacgtcgcaatataccgttattagttaaacgttctcatccgtcatgcgtgaaatacggctgtcgtgctcagatatactattagcgactcatctcgcctaacacgcacacgtataaactcggaatgactgccgctcttacatattagaaatacagactacaccacggaagcattgggtcattctcaaccgctgtataaaagatgattagtcttataataagattaccaaagaggcagaatcatgggtagtaaatctattattcaagtgattaccgtcgtgtaggcagggagtgaggacgagatggtactcaggacaaatattaaccggacgaagtggtttacgtcgtactttcactattagtagtaaatacaaggtaacaccggggaatagtactaaatataatgatatctatcttcgggagaacgagtcgtctattgctttgaacattctcaaggcgtaaaatgtgctgacttatagcatgatacaaccgattgttacttttgtctattcaaaagattgaatagttttttatacaaaagccgcatacttatgacggctagtatacagtttcatcccctagcatcaatgctatggacagtattgaacttataggaaattcttctaatagggcaaatccgtcgtgatgcctattttttttcagtcacatcctcaaatggcactagtattgtcgggatcccattaacaggctcaaccacgagctcacgcgaggacatgtagtccgtatctttaacgaagcgacagcgacagaactcccatggataaccaattataaggcccgtaatcctctagacatcgtttaccaataaatccgctttctccgtaatcatgttgaataccccagagtagtccagatgataaccgatgaaacacaagtctttctcaatgcacttacggtgaacttattaccgccaacgtagctcatcaaggttgcgacatctagttgtgtgtttgcgacgagcccagcgaacttcatcaactttcgtatattcaacgccttgtaattttactttaagacgcctggtgatgtagattcttagataatcagtttgttatcggctgtactttaccataatttcacaggtttcaggtcaagaagattatagctgtatatacagttccatgctcggtgcacagaaacgtgatcggataataatcaatcgcttatgtcgtctttaggcgtatccaatacatgccccgataccgcagtgtatttcgacatgtaggtataccgtcgcatttgagctcgagtcaggacgtcagctagattagattccttaatagaatataccgacctctagtccgaactaaactatagataacgccaacttcaggttaattgtctagtcgtctgtttgcagatgggattcttagatgagtgagtatcggccatattggttcgagcactttagtttttgatgcataggatatgcaatgtatagctgaaagtactttatctgtttcaaactcacattgattaaaccggtaaacctttaaagactacaagaaaatattcagtgagggcaattttgtcaatcacaatcttccagctagagatacttcacaatttgtcttgaggctacgcaacattagacggattttcgcgttttattgaaataatcgaggggcccaagagtatccatagttcattttgtaagatttctttacaggcttattacagcttcttcagactcctacatgcttacgagttatatgctagcatgtgaacaatagattaatatacaggaaaacgtacattgagagagatgaccctacacagcgcaaccgttgagtactttcattaaagggtaacgctctcgagacagcatccttaagatggccttattgtcaaatcatttgcagaagtacgcaagatccctaaccaacgtagaagaatccctacaaacacatgagacgcggtgaaaatagacagggtgttagtattcaatcttcggagtatcaatttcgccaatcttggtgagaaagcataccctttcttcagagaaagaagatcaatcataacactatctttaacgaggtacgcacgcgcatcattacctgcctccatggatctttaggatagcggaaagtattggcagcgtattgtgatttcgttcctactttatcaatttcacattcatatacatgtcttttatcaaaatcgccaataagataggatgagctatattagatgctagtagagttcgcgccaacatcatcgataggaatactcaggacagcgtgataggacttttcaatccctaatactctctataattataactctctcttaagtttggaggcagtaacgcgctctatataatcagtttgctgcaccattcttcagcctctgatacatacaaataaattccacagcagtaagagggtttaattgagacatcttgggaacttaggattttactctaacatcaccgaaacgattattggataccgtacctaaacgaactttctcaaggcagtaatataggacatccgcaataacacaaatgctgcctccccaggagttatgtcttcctggaggctatatcttacacccactcactataggcaaactaaagtttaaatgttgattgtctaaaaaaaagatagataagagttggccggcgtagcacatgcgaaagtgaatcgtaagctataattctctggacttgaagttctgtcctgttcctctgcaagaaacaaacttcctttaaagctatttacgacgcacatctcagcaagttataaacatgttggaagtttctagtcggaattcccaaagaacggatctatctaatgcattcctacatttttcctgtctgccgatggtgccatcctattcaaagaatttcttaaaagtagattaaatgggacttttaacaatgagtaaccttacgcctctaagggttcctcgagtgccatacaccagtcaggtccgagccacatacacggagaacattctaacatagcattctcaactcgatcatttgcaggttacttctttcctatcctagtgctaaaaatcatacttgcaatcccatagcacggattaagaacctaagaaacaattcagtaaaacatgttcgaattcttggtatgggaacatcattgcagctatggtctaacgcattaatgtttgggtacatcttccatcatataaacaggaagagtctgacgacagggagtgcttgcgatcatgtctatcattgtgaaatcaaattgtagctcacatgtcgtctatgagagcgtgtatccgataagatttagaaaaatagaagtcgtataagatctcactgaacttttgaatgaatgtgaagcatatatgatctgctttaataaaactttatccataggatacgtttccaaatcaattcaataattattagtcaaaatagataaggatgaacaacctgaaggccgatcggacgtagaaagtggtcccatcactttgagttgatattgttgaaccacacgttattatggttttcaaacagtctcaggatattgtatatacagataatccgataccagttgtctgacgcccctcttacgtaccccaccctttgtgacgtttaaagcagttgttcagtattttaaactaggcggcaactaatttggaaagaagcacagtggatatgtctaaattcttgttattcaggcctgaatttaatacaccgcatagttaacttcgcggtagagttgttcatcatgcctcctctaagctaccacttctatgatacaccaatagttgttctacggaatctgataattggccaagtcataaacttccgctgcgttcaacccccttgctcgaatatccaactcgaaaagacagccttttggtgtccggaacaaatcagttacttcttttctgatgttaattctctgtggtcagatacagaccaaaaactccgcggatttaccatcctccaagaacaaatttgcatcaacatagcattttggctacatattctaagtctcaatagtttaggttttcaactacattatcccaacattaggattggaggaataatagctgggtaagtccccttgcgtctacaatcgactattttttatgaatatgcttctgccgcacctatggttattaaaaaagtcatgactttgaagaaccctgaaaagatagatgaatcaggtgtaatggcagcagccaaagagcatataattagcaacactctaagaacattatagatatgatgatagcgatcgtcatgatgttatccggtcacaatagtagcttcatcagctaattcgttttgccagtggtgacttgcgctggaagaatcgttatacggtcccttccctcttgatacggtgggggcttattcaaccgcgtggattgggttgtcatacttgcattaaacgatgtaaaccatctagtagtcaactatactaaatcacaaaatagtgatcaatacatacccgcttcatggttttaaccatttaattgattaaagatattccgctaagaaccattatctacctaaactgatcgccgtatcctagtagtttgaaatttgatgtaccgtaatgatcaacgaagtaaaacgttatattgtatgtagaataataggtcttggagctaaatgatgtgattggtagtgaagacttacccttacaactttaccggtttctcggaagaatatactagagaatcaatgcatgggctacataagcactttagtctaatgagataaaaaatacacgagtcttccatcatgaattttttgtcgaaaaactcgaacctggtaatttaaaccatatatctttatgtcgtcaataactctcatatgttttatataacttcccaatcacgacttgtaactgcttgttcgactgagctgtttgagctatgaggccgggatccggttgagctacatctatttgctacaagaaaaatgaaagcacatttgttgggagttctggctacactcatagagaaataagtggcccgagtgggtgcggcctgcctccatattcaagtgtatcttaaaccaagtggttccaacgctcgcgctaaagaattaaagcctttatttcctccacggagtagcccgtaatccggttcgaaagagaccattgaagttaattttcatatccagtgaagtttaggcacaagcatgtgttctgccacatgcctcaaagcgctcttcaaccaagatatgattcatcctaacttcgatgaatgcgtctgtaacataaatatagaaggaatgattcggcgagttaattttcgccttctccaacatggcatccctacgttcgttataaggaccatacatgtaggttttaaaggtttgcggttaatcgatatttacatcatagaaattctatagtcaaatttacaagactctagatactcactcgttgcagccggctaggaagcgctttgtaccttacttcccttttcgttgcgtaatatgaatttcatatagtaagttcaaggcactcatacctccgtgaagagggtagatagactattaaagttgtttaatagtacgtattgatggaaatgacccgtaggagatttaccactcaatccacaagattcgctgctgtgcattatcaaaacagtgcatgtcgaaacatgggttgggtccttcaaacacgaatccaggtagagatacctttgcaatttttGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCcttBtatcatatgctaKggNcataaaSatgtaaaDcDRtBggDtctttataattcBgtcgtactDtDagcctatttSVHtHttKtgtHMaSattgWaHKHttttagacatWatgtRgaaaNtactMcSMtYtcMgRtacttctWBacgaaatatagScDtttgaagacacatagtVgYgtcattHWtMMWcStgttaggKtSgaYaaccWStcgBttgcgaMttBYatcWtgacaYcagagtaBDtRacttttcWatMttDBcatWtatcttactaBgaYtcttgttttttttYaaScYaHgtgttNtSatcMtcVaaaStccRcctDaataataStcYtRDSaMtDttgttSagtRRcatttHatSttMtWgtcgtatSSagactYaaattcaMtWatttaSgYttaRgKaRtccactttattRggaMcDaWaWagttttgacatgttctacaaaRaatataataaMttcgDacgaSStacaStYRctVaNMtMgtaggcKatcttttattaaaaagVWaHKYagtttttatttaaccttacgtVtcVaattVMBcttaMtttaStgacttagattWWacVtgWYagWVRctDattBYtgtttaagaagattattgacVatMaacattVctgtBSgaVtgWWggaKHaatKWcBScSWaaccRVacacaaactaccScattRatatKVtactatatttHttaagtttSKtRtacaaagtRDttcaaaaWgcacatWaDgtDKacgaacaattacaRNWaatHtttStgttattaaMtgttgDcgtMgcatBtgcttcgcgaDWgagctgcgaggggVtaaScNatttacttaatgacagcccccacatYScaMgtaggtYaNgttctgaMaacNaMRaacaaacaKctacatagYWctgttWaaataaaataRattagHacacaagcgKatacBttRttaagtatttccgatctHSaatactcNttMaagtattMtgRtgaMgcataatHcMtaBSaRattagttgatHtMttaaKaggYtaaBataSaVatactWtataVWgKgttaaaacagtgcgRatatacatVtHRtVYataSaKtWaStVcNKHKttactatccctcatgWHatWaRcttactaggatctataDtDHBttataaaaHgtacVtagaYttYaKcctattcttcttaataNDaaggaaaDYgcggctaaWSctBaaNtgctggMBaKctaMVKagBaactaWaDaMaccYVtNtaHtVWtKgRtcaaNtYaNacggtttNattgVtttctgtBaWgtaattcaagtcaVWtactNggattctttaYtaaagccgctcttagHVggaYtgtNcDaVagctctctKgacgtatagYcctRYHDtgBattDaaDgccKtcHaaStttMcctagtattgcRgWBaVatHaaaataYtgtttagMDMRtaataaggatMtttctWgtNtgtgaaaaMaatatRtttMtDgHHtgtcattttcWattRSHcVagaagtacgggtaKVattKYagactNaatgtttgKMMgYNtcccgSKttctaStatatNVataYHgtNaBKRgNacaactgatttcctttaNcgatttctctataScaHtataRagtcRVttacDSDttaRtSatacHgtSKacYagttMHtWataggatgactNtatSaNctataVtttRNKtgRacctttYtatgttactttttcctttaaacatacaHactMacacggtWataMtBVacRaSaatccgtaBVttccagccBcttaRKtgtgcctttttRtgtcagcRttKtaaacKtaaatctcacaattgcaNtSBaaccgggttattaaBcKatDagttactcttcattVtttHaaggctKKgatacatcBggScagtVcacattttgaHaDSgHatRMaHWggtatatRgccDttcgtatcgaaacaHtaagttaRatgaVacttagattVKtaaYttaaatcaNatccRttRRaMScNaaaDgttVHWgtcHaaHgacVaWtgttScactaagSgttatcttagggDtaccagWattWtRtgttHWHacgattBtgVcaYatcggttgagKcWtKKcaVtgaYgWctgYggVctgtHgaNcVtaBtWaaYatcDRaaRtSctgaHaYRttagatMatgcatttNattaDttaattgttctaaccctcccctagaWBtttHtBccttagaVaatMcBHagaVcWcagBVttcBtaYMccagatgaaaaHctctaacgttagNWRtcggattNatcRaNHttcagtKttttgWatWttcSaNgggaWtactKKMaacatKatacNattgctWtatctaVgagctatgtRaHtYcWcttagccaatYttWttaWSSttaHcaaaaagVacVgtaVaRMgattaVcDactttcHHggHRtgNcctttYatcatKgctcctctatVcaaaaKaaaagtatatctgMtWtaaaacaStttMtcgactttaSatcgDataaactaaacaagtaaVctaggaSccaatMVtaaSKNVattttgHccatcacBVctgcaVatVttRtactgtVcaattHgtaaattaaattttYtatattaaRSgYtgBagaHSBDgtagcacRHtYcBgtcacttacactaYcgctWtattgSHtSatcataaatataHtcgtYaaMNgBaatttaRgaMaatatttBtttaaaHHKaatctgatWatYaacttMctcttttVctagctDaaagtaVaKaKRtaacBgtatccaaccactHHaagaagaaggaNaaatBWattccgStaMSaMatBttgcatgRSacgttVVtaaDMtcSgVatWcaSatcttttVatagttactttacgatcaccNtaDVgSRcgVcgtgaacgaNtaNatatagtHtMgtHcMtagaaattBgtataRaaaacaYKgtRccYtatgaagtaataKgtaaMttgaaRVatgcagaKStctHNaaatctBBtcttaYaBWHgtVtgacagcaRcataWctcaBcYacYgatDgtDHcctaaagacYRcaggattHaYgtKtaatgcVcaataMYacccatatcacgWDBtgaatcBaatacKcttRaRtgatgaBDacggtaattaaYtataStgVHDtDctgactcaaatKtacaatgcgYatBtRaDatHaactgtttatatDttttaaaKVccYcaaccNcBcgHaaVcattHctcgattaaatBtatgcaaaaatYMctSactHatacgaWacattacMBgHttcgaatVaaaacaBatatVtctgaaaaWtctRacgBMaatSgRgtgtcgactatcRtattaScctaStagKgaDcWgtYtDDWKRgRtHatRtggtcgaHgggcgtattaMgtcagccaBggWVcWctVaaattcgNaatcKWagcNaHtgaaaSaaagctcYctttRVtaaaatNtataaccKtaRgtttaMtgtKaBtRtNaggaSattHatatWactcagtgtactaKctatttgRYYatKatgtccgtRtttttatttaatatVgKtttgtatgtNtataRatWYNgtRtHggtaaKaYtKSDcatcKgtaaYatcSRctaVtSMWtVtRWHatttagataDtVggacagVcgKWagBgatBtaaagNcaRtagcataBggactaacacRctKgttaatcctHgDgttKHHagttgttaatgHBtatHcDaagtVaBaRccctVgtgDtacRHSctaagagcggWYaBtSaKtHBtaaactYacgNKBaVYgtaacttagtVttcttaatgtBtatMtMtttaattaatBWccatRtttcatagVgMMtagctStKctaMactacDNYgKYHgaWcgaHgagattacVgtttgtRaSttaWaVgataatgtgtYtaStattattMtNgWtgttKaccaatagNYttattcgtatHcWtctaaaNVYKKttWtggcDtcgaagtNcagatacgcattaagaccWctgcagcttggNSgaNcHggatgtVtcatNtRaaBNcHVagagaaBtaaSggDaatWaatRccaVgggStctDaacataKttKatttggacYtattcSatcttagcaatgaVBMcttDattctYaaRgatgcattttNgVHtKcYRaatRKctgtaaacRatVSagctgtWacBtKVatctgttttKcgtctaaDcaagtatcSataWVgcKKataWaYttcccSaatgaaaacccWgcRctWatNcWtBRttYaattataaNgacacaatagtttVNtataNaYtaatRaVWKtBatKagtaatataDaNaaaaataMtaagaaStccBcaatNgaataWtHaNactgtcDtRcYaaVaaaaaDgtttRatctatgHtgttKtgaaNSgatactttcgagWaaatctKaaDaRttgtggKKagcDgataaattgSaacWaVtaNMacKtcaDaaatttctRaaVcagNacaScRBatatctRatcctaNatWgRtcDcSaWSgttRtKaRtMtKaatgttBHcYaaBtgatSgaSWaScMgatNtctcctatttctYtatMatMtRRtSaattaMtagaaaaStcgVgRttSVaScagtgDtttatcatcatacRcatatDcttatcatVRtttataaHtattcYtcaaaatactttgVctagtaaYttagatagtSYacKaaacgaaKtaaatagataatSatatgaaatSgKtaatVtttatcctgKHaatHattagaaccgtYaaHactRcggSBNgtgctaaBagBttgtRttaaattYtVRaaaattgtaatVatttctcttcatgBcVgtgKgaHaaatattYatagWacNctgaaMcgaattStagWaSgtaaKagttttaagaDgatKcctgtaHtcatggKttVDatcaaggtYcgccagNgtgcVttttagagatgctaccacggggtNttttaSHaNtatNcctcatSaaVgtactgBHtagcaYggYVKNgtaKBcRttgaWatgaatVtagtcgattYgatgtaatttacDacSctgctaaaStttaWMagDaaatcaVYctccgggcgaVtaaWtStaKMgDtttcaaMtVgBaatccagNaaatcYRMBggttWtaaScKttMWtYataRaDBMaDataatHBcacDaaKDactaMgagttDattaHatHtaYatDtattDcRNStgaatattSDttggtattaaNSYacttcDMgYgBatWtaMagactVWttctttgYMaYaacRgHWaattgRtaagcattctMKVStatactacHVtatgatcBtVNataaBttYtSttacKgggWgYDtgaVtYgatDaacattYgatggtRDaVDttNactaSaMtgNttaacaaSaBStcDctaccacagacgcaHatMataWKYtaYattMcaMtgSttDagcHacgatcaHttYaKHggagttccgatYcaatgatRaVRcaagatcagtatggScctatattaNtagcgacgtgKaaWaactSgagtMYtcttccaKtStaacggMtaagNttattatcgtctaRcactctctDtaacWYtgaYaSaagaWtNtatttRacatgNaatgttattgWDDcNaHcctgaaHacSgaataaRaataMHttatMtgaSDSKatatHHaNtacagtccaYatWtcactaactatKDacSaStcggataHgYatagKtaatKagStaNgtatactatggRHacttgtattatgtDVagDVaRctacMYattDgtttYgtctatggtKaRSttRccRtaaccttagagRatagSaaMaacgcaNtatgaaatcaRaagataatagatactcHaaYKBctccaagaRaBaStNagataggcgaatgaMtagaatgtcaKttaaatgtaWcaBttaatRcggtgNcacaaKtttScRtWtgcatagtttWYaagBttDKgcctttatMggNttattBtctagVtacataaaYttacacaaRttcYtWttgHcaYYtaMgBaBatctNgcDtNttacgacDcgataaSatYaSttWtcctatKaatgcagHaVaacgctgcatDtgttaSataaaaYSNttatagtaNYtaDaaaNtggggacttaBggcHgcgtNtaaMcctggtVtaKcgNacNtatVaSWctWtgaWcggNaBagctctgaYataMgaagatBSttctatacttgtgtKtaattttRagtDtacatatatatgatNHVgBMtKtaKaNttDHaagatactHaccHtcatttaaagttVaMcNgHatatKtaNtgYMccttatcaaNagctggacStttcNtggcaVtattactHaSttatgNMVattMMDtMactattattgWMSgtHBttStStgatatRaDaagattttctatMtaaaaaggtactaaVttaSacNaatactgMttgacHaHRttgMacaaaatagttaatatWKRgacDgaRtatatttattatcYttaWtgtBRtWatgHaaattHataagtVaDtWaVaWtgStcgtMSgaSRgMKtaaataVacataatgtaSaatttagtcgaaHtaKaatgcacatcggRaggSKctDcagtcSttcccStYtccRtctctYtcaaKcgagtaMttttcRaYDttgttatctaatcataNctctgctatcaMatactataggDaHaaSttMtaDtcNatataattctMcStaaBYtaNagatgtaatHagagSttgWHVcttatKaYgDctcttggtgttMcRaVgSgggtagacaataaDtaattSaDaNaHaBctattgNtaccaaRgaVtKNtaaYggHtaKKgHcatctWtctDtttctttggSDtNtaStagttataaacaattgcaBaBWggHgcaaaBtYgctaatgaaatWcDcttHtcMtWWattBHatcatcaaatctKMagtDNatttWaBtHaaaNgMttaaStagttctctaatDtcRVaYttgttMtRtgtcaSaaYVgSWDRtaatagctcagDgcWWaaaBaaRaBctgVgggNgDWStNaNBKcBctaaKtttDcttBaaggBttgaccatgaaaNgttttttttatctatgttataccaaDRaaSagtaVtDtcaWatBtacattaWacttaSgtattggDgKaaatScaattacgWcagKHaaccaYcRcaRttaDttRtttHgaHVggcttBaRgtccctDatKaVtKtcRgYtaKttacgtatBtStaagcaattaagaRgBagSaattccSWYtttattVaataNctgHgttaaNBgcVYgtRtcccagWNaaaacaDNaBcaaaaRVtcWMgBagMtttattacgDacttBtactatcattggaaatVccggttRttcatagttVYcatYaSHaHcttaaagcNWaHataaaRWtctVtRYtagHtaaaYMataHYtNBctNtKaatattStgaMcBtRgctaKtgcScSttDgYatcVtggaaKtaagatWccHccgKYctaNNctacaWcttttgcRtgtVcgaKttcMRHgctaHtVaataaDtatgKDcttatBtDttggNtacttttMtgaacRattaaNagaactcaaaBBVtcDtcgaStaDctgaaaSgttMaDtcgttcaccaaaaggWtcKcgSMtcDtatgtttStaaBtatagDcatYatWtaaaBacaKgcaDatgRggaaYctaRtccagattDaWtttggacBaVcHtHtaacDacYgtaatataMagaatgHMatcttatacgtatttttatattacHactgttataMgStYaattYaccaattgagtcaaattaYtgtatcatgMcaDcgggtcttDtKgcatgWRtataatatRacacNRBttcHtBgcRttgtgcgtcatacMtttBctatctBaatcattMttMYgattaaVYatgDaatVagtattDacaacDMatcMtHcccataagatgBggaccattVWtRtSacatgctcaaggggYtttDtaaNgNtaaBatggaatgtctRtaBgBtcNYatatNRtagaacMgagSaSDDSaDcctRagtVWSHtVSRggaacaBVaccgtttaStagaacaMtactccagtttVctaaRaaHttNcttagcaatttattaatRtaaaatctaacDaBttggSagagctacHtaaRWgattcaaBtctRtSHaNtgtacattVcaHaNaagtataccacaWtaRtaaVKgMYaWgttaKggKMtKcgWatcaDatYtKSttgtacgaccNctSaattcDcatcttcaaaDKttacHtggttHggRRaRcaWacaMtBWVHSHgaaMcKattgtaRWttScNattBBatYtaNRgcggaagacHSaattRtttcYgaccBRccMacccKgatgaacttcgDgHcaaaaaRtatatDtatYVtttttHgSHaSaatagctNYtaHYaVYttattNtttgaaaYtaKttWtctaNtgagaaaNctNDctaaHgttagDcRttatagccBaacgcaRBtRctRtggtaMYYttWtgataatcgaataattattataVaaaaattacNRVYcaaMacNatRttcKatMctgaagactaattataaYgcKcaSYaatMNctcaacgtgatttttBacNtgatDccaattattKWWcattttatatatgatBcDtaaaagttgaaVtaHtaHHtBtataRBgtgDtaataMttRtDgDcttattNtggtctatctaaBcatctaRatgNacWtaatgaagtcMNaacNgHttatactaWgcNtaStaRgttaaHacccgaYStacaaaatWggaYaWgaattattcMaactcBKaaaRVNcaNRDcYcgaBctKaacaaaaaSgctccYBBHYaVagaatagaaaacagYtctVccaMtcgtttVatcaatttDRtgWctagtacRttMctgtDctttcKtWttttataaatgVttgBKtgtKWDaWagMtaaagaaattDVtaggttacatcatttatgtcgMHaVcttaBtVRtcgtaYgBRHatttHgaBcKaYWaatcNSctagtaaaaatttacaatcactSWacgtaatgKttWattagttttNaggtctcaagtcactattcttctaagKggaataMgtttcataagataaaaatagattatDgcBVHWgaBKttDgcatRHaagcaYcRaattattatgtMatatattgHDtcaDtcaaaHctStattaatHaccgacNattgatatattttgtgtDtRatagSacaMtcRtcattcccgacacSattgttKaWattNHcaacttccgtttSRtgtctgDcgctcaaMagVtBctBMcMcWtgtaacgactctcttRggRKSttgYtYatDccagttDgaKccacgVatWcataVaaagaataMgtgataaKYaaatcHDaacgataYctRtcYatcgcaMgtNttaBttttgatttaRtStgcaacaaaataccVgaaDgtVgDcStctatatttattaaaaRKDatagaaagaKaaYYcaYSgKStctccSttacagtcNactttDVttagaaagMHttRaNcSaRaMgBttattggtttaRMggatggcKDgWRtNaataataWKKacttcKWaaagNaBttaBatMHtccattaacttccccYtcBcYRtagattaagctaaYBDttaNtgaaaccHcaRMtKtaaHMcNBttaNaNcVcgVttWNtDaBatgataaVtcWKcttRggWatcattgaRagHgaattNtatttctctattaattaatgaDaaMatacgttgggcHaYVaaNaDDttHtcaaHtcVVDgBVagcMacgtgttaaBRNtatRtcagtaagaggtttaagacaVaaggttaWatctccgtVtaDtcDatttccVatgtacNtttccgtHttatKgScBatgtVgHtYcWagcaKtaMYaaHgtaattaSaHcgcagtWNaatNccNNYcacgVaagaRacttctcattcccRtgtgtaattagcSttaaStWaMtctNNcSMacattataaactaDgtatWgtagtttaagaaaattgtagtNagtcaataaatttgatMMYactaatatcggBWDtVcYttcDHtVttatacYaRgaMaacaStaatcRttttVtagaDtcacWatttWtgaaaagaaagNRacDtttStVatBaDNtaactatatcBSMcccaSttccggaMatgattaaWatKMaBaBatttgataNctgttKtVaagtcagScgaaaDggaWgtgttttKtWtatttHaatgtagttcactaaKMagttSYBtKtaYgaactcagagRtatagtVtatcaaaWYagcgNtaDagtacNSaaYDgatBgtcgataacYDtaaactacagWDcYKaagtttattagcatcgagttKcatDaattgattatDtcagRtWSKtcgNtMaaaaacaMttKcaWcaaSVMaaaccagMVtaMaDtMaHaBgaacataBBVtaatVYaNSWcSgNtDNaaKacacBtttatKtgtttcaaHaMctcagtaacgtcgYtactDcgcctaNgagagcYgatattttaaatttccattttacatttDaaRctattttWctttacgtDatYtttcagacgcaaVttagtaaKaaaRtgVtccataBggacttatttgtttaWNtgttVWtaWNVDaattgtatttBaagcBtaaBttaaVatcHcaVgacattccNggtcgacKttaaaRtagRtctWagaYggtgMtataatMtgaaRttattttgWcttNtDRRgMDKacagaaaaggaaaRStcccagtYccVattaNaaKStNWtgacaVtagaagcttSaaDtcacaacgDYacWDYtgtttKatcVtgcMaDaSKStVcgtagaaWaKaagtttcHaHgMgMtctataagBtKaaaKKcactggagRRttaagaBaaNatVVcgRcKSttDaactagtSttSattgttgaaRYatggttVttaataaHttccaagDtgatNWtaagHtgcYtaactRgcaatgMgtgtRaatRaNaacHKtagactactggaatttcgccataacgMctRgatgttaccctaHgtgWaYcactcacYaattcttaBtgacttaaacctgYgaWatgBttcttVttcgttWttMcNYgtaaaatctYgMgaaattacNgaHgaacDVVMtttggtHtctaaRgtacagacgHtVtaBMNBgattagcttaRcttacaHcRctgttcaaDBggttKaacatgKtttYataVaNattccgMcgcgtagtRaVVaattaKaatggttRgaMcagtatcWBttNtHagctaatctagaaNaaacaYBctatcgcVctBtgcaaagDgttVtgaHtactSNYtaaNccatgtgDacgaVtDcgKaRtacDcttgctaagggcagMDagggtBWRtttSgccttttttaacgtcHctaVtVDtagatcaNMaVtcVacatHctDWNaataRgcgtaVHaggtaaaaSgtttMtattDgBtctgatSgtRagagYtctSaKWaataMgattRKtaacatttYcgtaacacattRWtBtcggtaaatMtaaacBatttctKagtcDtttgcBtKYYBaKttctVttgttaDtgattttcttccacttgSaaacggaaaNDaattcYNNaWcgaaYattttMgcBtcatRtgtaaagatgaWtgaccaYBHgaatagataVVtHtttVgYBtMctaMtcctgaDcYttgtccaaaRNtacagcMctKaaaggatttacatgtttaaWSaYaKttBtagDacactagctMtttNaKtctttcNcSattNacttggaacaatDagtattRtgSHaataatgccVgacccgatactatccctgtRctttgagaSgatcatatcgDcagWaaHSgctYYWtatHttggttctttatVattatcgactaagtgtagcatVgtgHMtttgtttcgttaKattcMatttgtttWcaaStNatgtHcaaaDtaagBaKBtRgaBgDtSagtatMtaacYaatYtVcKatgtgcaacVaaaatactKcRgtaYtgtNgBBNcKtcttaccttKgaRaYcaNKtactttgagSBtgtRagaNgcaaaNcacagtVtttHWatgttaNatBgtttaatNgVtctgaatatcaRtattcttttttttRaaKcRStctcggDgKagattaMaaaKtcaHacttaataataKtaRgDtKVBttttcgtKaggHHcatgttagHggttNctcgtatKKagVagRaaaggaaBtNatttVKcRttaHctaHtcaaatgtaggHccaBataNaNaggttgcWaatctgatYcaaaHaatWtaVgaaBttagtaagaKKtaaaKtRHatMaDBtBctagcatWtatttgWttVaaaScMNattRactttgtYtttaaaagtaagtMtaMaSttMBtatgaBtttaKtgaatgagYgtNNacMtcNRacMMHcttWtgtRtctttaacaacattattcYaMagBaacYttMatcttKcRMtgMNccattaRttNatHaHNaSaaHMacacaVaatacaKaSttHatattMtVatWgattttttaYctttKttHgScWaacgHtttcaVaaMgaacagNatcgttaacaaaaagtacaHBNaattgttKtcttVttaaBtctgctacgBgcWtttcaggacacatMgacatcccagcggMgaVKaBattgacttaatgacacacaaaaaatRKaaBctacgtRaDcgtagcVBaacDSBHaaaaSacatatacagacRNatcttNaaVtaaaataHattagtaaaaSWccgtatWatggDttaactattgcccatcttHaSgYataBttBaactattBtcHtgatcaataSttaBtatKSHYttWggtcYtttBttaataccRgVatStaHaKagaatNtagRMNgtcttYaaSaactcagDSgagaaYtMttDtMRVgWKWtgMaKtKaDttttgactatacataatcNtatNaHattVagacgYgatatatttttgtStWaaatctWaMgagaRttRatacgStgattcttaagaDtaWccaaatRcagcagaaNKagtaaDggcgccBtYtagSBMtactaaataMataBSacRMgDgattMMgtcHtcaYDtRaDaacggttDaggcMtttatgttaNctaattaVacgaaMMtaatDccSgtattgaRtWWaccaccgagtactMcgVNgctDctaMScatagcgtcaactatacRacgHRttgctatttaatgaattataYKttgtaagWgtYttgcHgMtaMattWaWVtaRgcttgYgttBHtYataSccStBtgtagMgtDtggcVaaSBaatagDttgBgtctttctcattttaNagtHKtaMWcYactVcgcgtatMVtttRacVagDaatcttgctBBcRDgcaacKttgatSKtYtagBMagaRtcgBattHcBWcaactgatttaatttWDccatttatcgagSKaWttataHactaHMttaatHtggaHtHagaatgtKtaaRactgtttMatacgatcaagDgatKaDctataMggtHDtggHacctttRtatcttYattttgacttgaaSaataaatYcgBaaaaccgNatVBttMacHaKaataagtatKgtcaagactcttaHttcggaattgttDtctaaccHttttWaaatgaaatataaaWattccYDtKtaaaacggtgaggWVtctattagtgactattaagtMgtttaagcatttgSgaaatatccHaaggMaaaattttcWtatKctagDtYtMcctagagHcactttactatacaaacattaacttaHatcVMYattYgVgtMttaaRtgaaataaDatcaHgtHHatKcDYaatcttMtNcgatYatgSaMaNtcttKcWataScKggtatcttacgcttWaaagNatgMgHtctttNtaacVtgttcMaaRatccggggactcMtttaYMtcWRgNctgNccKatcttgYDcMgattNYaRagatHaaHgKctcataRDttacatBatccattgDWttatttaWgtcggagaaaaatacaatacSNtgggtttccttacSMaagBattacaMaNcactMttatgaRBacYcYtcaaaWtagctSaacttWgDMHgaggatgBVgcHaDtggaactttggtcNatNgtaKaBcccaNtaagttBaacagtatacDYttcctNgWgcgSMcacatStctHatgRcNcgtacacaatRttMggaNKKggataaaSaYcMVcMgtaMaHtgattYMatYcggtcttcctHtcDccgtgRatcattgcgccgatatMaaYaataaYSggatagcgcBtNtaaaScaKgttBgagVagttaKagagtatVaactaSacWactSaKatWccaKaaaatBKgaaKtDMattttgtaaatcRctMatcaaMagMttDgVatggMaaWgttcgaWatgaaatttgRtYtattaWHKcRgctacatKttctaccaaHttRatctaYattaaWatVNccatNgagtcKttKataStRaatatattcctRWatDctVagttYDgSBaatYgttttgtVaatttaatagcagMatRaacttBctattgtMagagattaaactaMatVtHtaaatctRgaaaaaaaatttWacaacaYccYDSaattMatgaccKtaBKWBattgtcaagcHKaagttMMtaatttcKcMagNaaKagattggMagaggtaatttYacatcWaaDgatMgKHacMacgcVaacaDtaDatatYggttBcgtatgWgaSatttgtagaHYRVacaRtctHaaRtatgaactaatatctSSBgggaaHMWtcaagatKgagtDaSatagttgattVRatNtctMtcSaagaSHaataNataataRaaRgattctttaataaagWaRHcYgcatgtWRcttgaaggaMcaataBRaaccagStaaacNtttcaatataYtaatatgHaDgcStcWttaacctaRgtYaRtataKtgMttttatgactaaaatttacYatcccRWtttHRtattaaatgtttatatttgttYaatMcaRcSVaaDatcgtaYMcatgtagacatgaaattgRtcaaYaaYtRBatKacttataccaNaaattVaBtctggacaagKaaYaaatatWtMtatcYaaVNtcgHaactBaagKcHgtctacaatWtaDtSgtaHcataHtactgataNctRgttMtDcDttatHtcgtacatcccaggSttaBgtcacacWtccNMcNatMVaVgtccDYStatMaccDatggYaRKaaagataRatttHKtSaaatDgataaacttaHgttgVBtcttVttHgDacgaKatgtatatNYataactctSatatatattgcHRRYttStggaactHgttttYtttaWtatMcttttctatctDtagVHYgMRBgtHttcctaatYRttKtaagatggaVRataKDctaMtKBNtMtHNtWtttYcVtattMcgRaacMcctNSctcatttaaagDcaHtYccSgatgcaatYaaaaDcttcgtaWtaattctcgttttScttggtaatctttYgtctaactKataHacctMctcttacHtKataacacagcNRatgKatttttSaaatRYcgDttaMRcgaaattactMtgcgtaagcgttatBtttttaattaagtNacatHgttcRgacKcBBtVgatKttcgaBaatactDRgtRtgaNacWtcacYttaaKcgttctHaKttaNaMgWgWaggtctRgaKgWttSttBtDcNtgtttacaaatYcDRtgVtgcctattcNtctaaaDMNttttNtggctgagaVctDaacVtWccaagtaacacaNctgaScattccDHcVBatcgatgtMtaatBgHaatDctMYgagaatgYWKcctaatNaStHaaaKccgHgcgtYaaYtattgtStgtgcaaRtattaKatattagaWVtcaMtBagttattagNaWHcVgcaattttDcMtgtaRHVYtHtctgtaaaaHVtMKacatcgNaatttMatatgttgttactagWYtaRacgataKagYNKcattataNaRtgaacKaYgcaaYYacaNccHatMatDcNgtHttRaWttagaaDcaaaaaatagggtKDtStaDaRtaVtHWKNtgtattVctSVgRgataDaRaWataBgaagaaKtaataaYgDcaStaNgtaDaaggtattHaRaWMYaYaWtggttHYgagVtgtgcttttcaaDKcagVcgttagacNaaWtagtaataDttctggttVcatcataaagtgKaaaNaMtaBBaattaatWaattgctHaVKaSgDaaVKaHtatatatHatcatSBagNgHtatcHYMHgttDgtaHtBttWatcgtttaRaattgStKgSKNWKatcagDtctcagatttctRtYtBatBgHHtKaWtgYBgacVVWaKtacKcDttKMaKaVcggtgttataagaataaHaatattagtataatMHgttYgaRttagtaRtcaaVatacggtcMcgagtaaRttacWgactKRYataaaagSattYaWgagatYagKagatgSaagKgttaatMggtataatgttWYttatgagaaacctNVataatHcccKtDctcctaatactggctHggaSaggRtKHaWaattcgSatMatttagaggcYtctaMcgctcataSatatgRagacNaaDaggaVBagaYttKtacNaKgtSYtagttggaWcatcWttaatctatgaVtcgtgtMtatcaYcgtRccaaYgDctgcMgtgtWgacWtgataacacgcgctBtgttaKtYDtatDcatcagKaVMctaatcttgVcaaRgcRMtDcgattaHttcaNatgaatMtactacVgtRgatggaWtttactaaKatgagSaaKggtaNtactVaYtaaKRagaacccacaMtaaMtKtatBcttgtaaWBtMctaataaVcDaaYtcRHBtcgttNtaaHatttBNgRStVDattBatVtaagttaYatVattaagaBcacggtSgtVtatttaRattgatgtaHDKgcaatattKtggcctatgaWDKRYcggattgRctatNgatacaatMNttctgtcRBYRaaaHctNYattcHtaWcaattctBtMKtVgYataatMgYtcagcttMDataVtggRtKtgaatgccNcRttcaMtRgattaacattRcagcctHtWMtgtDRagaKaBtgDttYaaaaKatKgatctVaaYaacWcgcatagBVtaNtRtYRaggBaaBtgKgttacataagagcatgtRattccacttaccatRaaatgWgDaMHaYVgVtaSctatcgKaatatattaDgacccYagtgtaYNaaatKcagtBRgagtccatgKgaaaccBgaagBtgSttWtacgatWHaYatcgatttRaaNRgcaNaKVacaNtDgattgHVaatcDaagcgtatgcNttaDataatcSataaKcaataaHWataBtttatBtcaKtKtatagttaDgSaYctacaRatNtaWctSaatatttYaKaKtaccWtatcRagacttaYttVcKgSDcgagaagatccHtaattctSttatggtKYgtMaHagVaBRatttctgtRgtctatgggtaHKgtHacHtSYacgtacacHatacKaaBaVaccaDtatcSaataaHaagagaatScagactataaRttagcaaVcaHataKgDacatWccccaagcaBgagWatctaYttgaaatctVNcYtttWagHcgcgcDcVaaatgttKcHtNtcaatagtgtNRaactttttcaatggWgBcgDtgVgtttctacMtaaataaaRggaaacWaHttaRtNtgctaaRRtVBctYtVtatDcattDtgaccYatagatYRKatNYKttNgcctagtaWtgaactaMVaacctgaStttctgaKVtaaVaRKDttVtVctaDNtataaaDtccccaagtWtcgatcactDgYaBcatcctMtVtacDaaBtYtMaKNatNtcaNacgDatYcatcgcaRatWBgaacWttKttagYtaattcggttgSWttttDWctttacYtatatWtcatDtMgtBttgRtVDggttaacYtacgtacatgaattgaaWcttMStaDgtatattgaDtcRBcattSgaaVBRgagccaaKtttcDgcgaSMtatgWattaKttWtgDBMaggBBttBaatWttRtgcNtHcgttttHtKtcWtagHStaacagttgatatBtaWSaWggtaataaMttaKacDaatactcBttcaatatHttcBaaSaaatYggtaRtatNtHcaatcaHtagVtgtattataNggaMtcttHtNagctaaaggtagaYctMattNaMVNtcKtactBKcaHHcBttaSagaKacataYgctaKaYgttYcgacWVttWtSagcaacatcccHaccKtcttaacgaKttcacKtNtacHtatatRtaaatacactaBtttgaHaRttggttWtatYagcatYDatcggagagcWBataagRtacctataRKgtBgatgaDatataSttagBaHtaatNtaDWcWtgtaattacagKttcNtMagtattaNgtctcgtcctcttBaHaKcKccgtRcaaYagSattaagtKataDatatatagtcDtaacaWHcaKttDgaaRcgtgYttgtcatatNtatttttatggccHtgDtYHtWgttatYaacaattcaWtatNgctcaaaSttRgctaatcaaatNatcgtttaBtNNVtgttataagcaaagattBacgtDatttNatttaaaDcBgtaSKgacgtagataatttcHMVNttgttBtDtgtaWKaaRMcKMtHtaVtagataWctccNNaSWtVaHatctcMgggDgtNHtDaDttatatVWttgttatttaacctttcacaaggaSaDcggttttttatatVtctgVtaacaStDVaKactaMtttaSNagtgaaattaNacttSKctattcctctaSagKcaVttaagNaVcttaVaaRNaHaaHttatgtHttgtgatMccaggtaDcgaccgtWgtWMtttaHcRtattgScctatttKtaaccaagtYagaHgtWcHaatgccKNRtttagtMYSgaDatctgtgaWDtccMNcgHgcaaacNDaaaRaStDWtcaaaaHKtaNBctagBtgtattaactaattttVctagaatggcWSatMacccttHttaSgSgtgMRcatRVKtatctgaaaccDNatYgaaVHNgatMgHRtacttaaaRtatStRtDtatDttYatattHggaBcttHgcgattgaKcKtttcRataMtcgaVttWacatNcatacctRataDDatVaWNcggttgaHtgtMacVtttaBHtgagVttMaataattatgttcttagtttgtgcDtSatttgBtcaacHattaaBagVWcgcaSYttMgcttacYKtVtatcaYaKctgBatgcgggcYcaaaaacgNtctagKBtattatctttKtaVttatagtaYtRagNtaYataaVtgaatatcHgcaaRataHtacacatgtaNtgtcgYatWMatttgaactacRctaWtWtatacaatctBatatgYtaagtatgtgtatSttactVatcttYtaBcKgRaSggRaaaaatgcagtaaaWgtaRgcgataatcBaataccgtatttttccatcNHtatWYgatHSaaaDHttgctgtccHtggggcctaataatttttctatattYWtcattBtgBRcVttaVMRSgctaatMagtYtttaaaaatBRtcBttcaaVtaacagctccSaaSttKNtHtKYcagcagaaaccccRtttttaaDcDtaStatccaagcgctHtatcttaDRYgatDHtWcaaaBcWgKWHttHataagHacgMNKttMKHccaYcatMVaacgttaKgYcaVaaBtacgcaactttMctaaHaatgtBatgagaSatgtatgSRgHgWaVWgataaatatttccKagVgataattWaHNcYggaaatgctHtKtaDtctaaagtMaatVDVactWtSaaWaaMtaHtaSKtcBRaNcttStggtBttacNagcatagRgtKtgcgaacaacBcgKaatgataagatgaaaattgtactgcgggtccHHWHaaNacaBttNKtKtcaaBatatgctaHNgtKcDWgtttatNgVDHgaccaacWctKaaggHttgaRgYaatHcaBacaatgagcaaattactgtaVaaYaDtagattgagNKggtggtgKtWKaatacagDRtatRaMRtgattDggtcaaYRtatttNtagaDtcacaaSDctDtataatcgtactaHttatacaatYaacaaHttHatHtgcgatRRttNgcatSVtacWWgaaggagtatVMaVaaattScDDKNcaYBYaDatHgtctatBagcaacaagaatgagaaRcataaKNaRtBDatcaaacgcattttttaaBtcSgtacaRggatgtMNaattggatatWtgagtattaaaVctgcaYMtatgatttttYgaHtgtcttaagWBttHttgtcttattDtcgtatWtataataSgctaHagcDVcNtaatcaagtaBDaWaDgtttagYctaNccDtaKtaHcttaataacccaRKtacaVaatNgcWRaMgaattatgaBaaagattVYaHMDcaDHtcRcgYtcttaaaWaaaVKgatacRtttRRKYgaatacaWVacVcRtatMacaBtactggMataaattttHggNagSctacHgtBagcgtcgtgattNtttgatSaaggMttctttcttNtYNagBtaaacaaatttMgaccttacataattgYtcgacBtVMctgStgMDtagtaRctHtatgttcatatVRNWataDKatWcgaaaaagttaaaagcacgHNacgtaatctttMRtgacttttDacctataaacgaaatatgattagaactccSYtaBctttaataacWgaaaYatagatgWttcatKtNgatttttcaagHtaYgaaRaDaagtaggagcttatVtagtctttcattaaaatcgKtattaRttacagVaDatgcatVgattgggtctttHVtagKaaRBtaHtaaggccccaaaaKatggtttaMWgtBtaaacttcactttKHtcgatctccctaYaBacMgtcttBaBaNgcgaaacaatctagtHccHtKttcRtRVttccVctttcatacYagMVtMcagaMaaacaataBctgYtaatRaaagattaaccatVRatHtaRagcgcaBcgDttStttttcVtttaDtKgcaaWaaaaatSccMcVatgtKgtaKgcgatatgtagtSaaaDttatacaaacatYaRRcVRHctKtcgacKttaaVctaDaatgttMggRcWaacttttHaDaKaDaBctgtaggcgtttaHBccatccattcNHtDaYtaataMttacggctNVaacDattgatattttacVttSaattacaaRtataNDgacVtgaacataVRttttaDtcaaacataYDBtttaatBaDtttYDaDaMccMttNBttatatgagaaMgaNtattHccNataattcaHagtgaaggDgatgtatatatgYatgaStcataaBStWacgtcccataRMaaDattggttaaattcMKtctMacaBSactcggaatDDgatDgcWctaacaccgggaVcacWKVacggtaNatatacctMtatgatagtgcaKagggVaDtgtaacttggagtcKatatcgMcttRaMagcattaBRaStctYSggaHYtacaactMBaagDcaBDRaaacMYacaHaattagcattaaaHgcgctaaggSccKtgaaKtNaBtatDDcKBSaVtgatVYaagVtctSgMctacgttaacWaaattctSgtDactaaStaaattgcagBBRVctaatatacctNttMcRggctttMttagacRaHcaBaacVKgaataHttttMgYgattcYaNRgttMgcVaaacaVVcDHaatttgKtMYgtatBtVVctWgVtatHtacaaHttcacgatagcagtaaNattBatatatttcVgaDagcggttMaagtcScHagaaatgcYNggcgtttttMtStggtRatctacttaaatVVtBacttHNttttaRcaaatcacagHgagagtMgatcSWaNRacagDtatactaaDKaSRtgattctccatSaaRttaaYctacacNtaRtaactggatgaccYtacactttaattaattgattYgttcagDtNKttagDttaaaaaaaBtttaaNaYWKMBaaaacVcBMtatWtgBatatgaacVtattMtYatMNYDKNcKgDttDaVtaaaatgggatttctgtaaatWtctcWgtVVagtcgRgacttcccctaDcacagcRcagagtgtWSatgtacatgttaaSttgtaaHcgatgggMagtgaacttatRtttaVcaccaWaMgtactaatSSaHtcMgaaYtatcgaaggYgggcgtgaNDtgttMNgaNDMtaattcgVttttaacatgVatgtWVMatatcaKgaaattcaBcctccWcttgaaWHtWgHtcgNWgaRgctcBgSgaattgcaaHtgattgtgNagtDttHHgBttaaWcaaWagcaSaHHtaaaVctRaaMagtaDaatHtDMtcVaWMtagSagcttHSattaacaaagtRacMtRtctgttagcMtcaBatVKtKtKacgagaSNatSactgtatatcBctgagVtYactgtaaattaaaggcYgDHgtaacatSRDatMMccHatKgttaacgactKtgKagtcttcaaHRVtccttKgtSataatttacaactggatDNgaacttcaRtVaagDcaWatcBctctHYatHaDaaatttagYatSatccaWtttagaaatVaacBatHcatcgtacaatatcgcNYRcaataYaRaYtgattVttgaatgaVaactcRcaNStgtgtattMtgaggtNttBaDRcgaaaagctNgBcWaWgtSaDcVtgVaatMKBtttcgtttctaaHctaaagYactgMtatBDtcStgaccgtSDattYaataHctgggaYYttcggttaWaatctggtRagWMaDagtaacBccactacgHWMKaatgatWatcctgHcaBaSctVtcMtgtDttacctaVgatYcWaDRaaaaRtagatcgaMagtggaRaWctctgMgcWttaagKBRtaaDaaWtctgtaagYMttactaHtaatcttcataacggcacBtSgcgttNHtgtHccatgttttaaagtatcgaKtMttVcataYBBaKtaMVaVgtattNDSataHcagtWMtaggtaSaaKgttgBtVtttgttatcatKcgHacacRtctHatNVagSBgatgHtgaRaSgttRcctaacaaattDNttgacctaaYtBgaaaatagttattactcttttgatgtNNtVtgtatMgtcttRttcatttgatgacacttcHSaaaccaWWDtWagtaRDDVNacVaRatgttBccttaatHtgtaaacStcVNtcacaSRttcYagacagaMMttttgMcNttBcgWBtactgVtaRttctccaaYHBtaaagaBattaYacgatttacatctgtaaMKaRYtttttactaaVatWgctBtttDVttctggcDaHaggDaagtcgaWcaagtagtWttHtgKtVataStccaMcWcaagataagatcactctHatgtcYgaKcatcagatactaagNSStHcctRRNtattgtccttagttagMVgtatagactaactctVcaatMctgtttgtgttgccttatWgtaBVtttctggMcaaKgDWtcgtaaYStgSactatttHgatctgKagtagBtVacRaagRtMctatgggcaaaKaaaatacttcHctaRtgtDcttDattaggaaatttcYHaRaaBttaatggcacKtgctHVcaDcaaaVDaaaVcgMttgtNagcgtaDWgtcgttaatDgKgagcSatatcSHtagtagttggtgtHaWtaHKtatagctgtVgattaBVaatgaataagtaatVatSttaHctttKtttgtagttaccttaatcgtagtcctgBcgactatttVcMacHaaaggaatgDatggKtaHtgStatattaaSagctWcctccRtataBaDYcgttgcNaagaggatRaaaYtaWgNtSMcaatttactaacatttaaWttHtatBattgtcgacaatNgattgcNgtMaaaKaBDattHacttggtRtttaYaacgVactBtaBaKtgBttatgVttgtVttcaatcWcNctDBaaBgaDHacBttattNtgtDtatttVSaaacaggatgcRatSgtaSaNtgBatagttcHBgcBBaaattaHgtDattatDaKaatBaaYaaMaataaataKtttYtagtBgMatNcatgtttgaNagtgttgtgKaNaSagtttgaSMaYBcaaaacDStagttVacaaaaactaaWttBaagtctgtgcgtMgtaattctcctacctcaNtttaaccaaaaVtBcacataacaccccBcWMtatVtggaatgaWtcaaWaaaaaaaaWtDtaatatRcctDWtcctaccMtVVatKttaWaaKaaatataaagScHBagaggBaSMtaWaVtatattactSaaaKNaactatNatccttgaYctattcaaaVgatttYHcRagattttaSataggttattcVtaaagaKgtattattKtRttNcggcRgtgtgtWYtaacHgKatKgatYtacYagDtWcHBDctctgRaYKaYagcactKcacSaRtBttttBHKcMtNtcBatttatttttgSatVgaaagaWtcDtagDatatgMacaacRgatatatgtttgtKtNRaatatNatgYcaHtgHataacKtgagtagtaacYttaNccaaatHcacaacaVDtagtaYtccagcattNtacKtBtactaaagaBatVtKaaHBctgStgtBgtatgaSNtgDataaccctgtagcaBgtgatcttaDataStgaMaccaSBBgWagtacKcgattgaDgNNaaaacacagtSatBacKDgcgtataBKcatacactaSaatYtYcDaactHttcatRtttaatcaattataRtttgtaagMcgNttcatcBtYBagtNWNMtSHcattcRctttttRWgaKacKttgggagBcgttcgcMaWHtaatactgtctctatttataVgtttaBScttttaBMaNaatMacactYtBMggtHacMagtaRtctgcatttaHtcaaaatttgagKtgNtactBacaHtcgtatttctMaSRagcagttaatgtNtaaattgagagWcKtaNttagVtacgatttgaatttcgRtgtWcVatcgttaaDVctgtttBWgaccagaaagtcSgtVtatagaBccttttcctaaattgHtatcggRattttcaaggcYSKaagWaWtRactaaaacccBatMtttBaatYtaagaactSttcgaaScaatagtattgaccaagtgttttctaacatgtttNVaatcaaagagaaaNattaaRttttaVaaaccgcaggNMtatattVctcaagaggaacgBgtttaacaagttcKcYaatatactaaccBaaaSggttcNtattctagttRtBacgScVctcaatttaatYtaaaaaaatgSaatgatagaMBRatgRcMcgttgaWHtcaVYgaatYtaatctttYttatRaWtctgBtDcgatNatcKaBaDgatgtaNatWKctccgatattaacattNaaacDatgBgttctgtDtaaaMggtgaBaSHataacgccSctaBtttaRBtcNHcDatcDcctagagtcRtaBgWttDRVHagattYatgtatcWtaHtttYcattWtaaagtctNgtStggRNcgcggagSSaaagaaaatYcHDtcgctttaatgYcKBVSgtattRaYBaDaaatBgtatgaHtaaRaRgcaSWNtagatHaacttNctBtcaccatctMcatattccaSatttgcgaDagDgtatYtaaaVDtaagtttWVaagtagYatRttaagDcNgacKBcScagHtattatcDaDactaaaaaYgHttBcgaDttggataaaKSRcBMaBcgaBSttcWtgNBatRaccgattcatttataacggHVtaattcacaagagVttaaRaatVVRKcgWtVgacctgDgYaaHaWtctttcacMagggatVgactagMaaataKaaNWagKatagNaaWtaaaatttgaattttatttgctaaVgaHatBatcaaBWcBgttcMatcgBaaNgttcgSNaggSaRtttgHtRtattaNttcDcatSaVttttcgaaaaattgHatctaRaggSaNatMDaaatDcacgattttagaHgHaWtYgattaatHNSttatMSgggNtcKtYatRggtttgtMWVtttaYtagcagBagHaYagttatatggtBacYcattaRSataBatMtttaaatctHcaaaSaaaagttNSaaWcWRccRtKaagtBWtcaaattSttMtattggaaaccttaacgttBtWatttatatWcDaatagattcctScacctaagggRaaYtaNaatgVtBcttaaBaacaMVaaattatStYgRcctgtactatcMcVKatttcgSgatRHMaaaHtagtaaHtVgcaaataatatcgKKtgccaatBNgaaWcVttgagttaKatagttcaggKDatDtattgaKaVcaKtaataDataataHSaHcattagttaatRVYcNaHtaRcaaggtNHcgtcaaccaBaaagYtHWaaaRcKgaYaaDttgcWYtataRgaatatgtYtgcKtaNttWacatYHctRaDtYtattcBttttatcSataYaYgttWaRagcacHMgtttHtYttYaatcggtatStttcgtRSattaaDaKMaatatactaNBaWgctacacYtgaYVgtgHtaaaRaaRgHtagtWattataaaSDaaWtgMattatcgaaaagtaYRSaWtSgNtBgagcRYaMDtactaacttaWgtatctagacaagNtattHggataatYttYatcataDcgHgttBttctttVttgccgaaWtaaaacgKgtatctaaaaaNtccDtaDatBMaMggaatNKtatBaaatVtccRaHtaSacataHattgtttKVYattcataVaattWtcgtgMttcttKtgtctaacVtatctatatBRataactcgKatStatattcatHHRttKtccaacgtgggtgRgtgaMtattattggctatcgtgacMtRcBDtcttgtactaatRHttttaagatcgVMDStattatYBtttDttgtBtNttgRcMtYtgBacHaWaBaatDKctaagtgaaactaatgRaaKgatccaagNaaaatattaggWNtaagtatacttttKcgtcggSYtcttgRctataYcttatataaagtatattaatttataVaacacaDHatctatttttKYVatHRactttaBHccaWagtactBtcacgaVgcgttRtttttttSVgtSagtBaaattctgaHgactcttgMcattttagVtaagaattHctHtcaDaaNtaacRggWatagttcgtSttgaDatcNgNagctagDgatcNttKgttgtaDtctttRaaYStRatDtgMggactSttaDtagSaVtBDttgtDgccatcacaMattaaaMtNacaVcgSWcVaaDatcaHaatgaattaMtatccVtctBtaattgtWattatBRcWcaatgNNtactWYtDaKttaaatcactcagtRaaRgatggtKgcgccaaHgaggatStattYcaNMtcaBttacttatgagDaNtaMgaaWtgtttcttctaHtMNgttatctaWWatMtBtaaatagDVatgtBYtatcggcttaagacMRtaHScgatatYgRDtcattatSDaHggaaataNgaWSRRaaaBaatagBattaDctttgHWNttacaataaaaaaatacggtttgHgVtaHtWMttNtBtctagtMcgKMgHgYtataHaNagWtcaacYattaataYRgtaWKgaBctataaccgatttaHaNBRaRaMtccggtNgacMtctcatttgcaattcWgMacttacaaDaaNtactWatVtttagccttMaatcagVaagtctVaaDaBtattaattaYtNaYtggattaKtaKctYaMtattYgatattataatKtVgDcttatatNBtcgttgtStttttMagaggttaHYSttcKgtcKtDNtataagttataagSgttatDtRttattgttttSNggRtcaaKMNatgaatattgtBWtaMacctgggYgaSgaagYataagattacgagaatBtggtRcVHtgYggaDgaYaKagWagctatagacgaaHgtWaNgacttHRatVaWacKYtgRVNgVcSgRWctacatcKSactctgWYtBggtataagcttNRttVtgRcaWaaatDMatYattaactttcgaagRatSctgccttgcRKaccHtttSNVagtagHagBagttagaccaRtataBccataatSHatRtcHagacBWatagcaMtacaRtgtgaaBatctKRtScttccaNaatcNgtaatatWtcaMgactctBtWtaaNactHaaaaRctcgcatggctMcaaNtcagaaaaacacagtggggWttRttagtaagaVctVMtcgaatcttcMaaaHcaHBttcgattatgtcaDagcYRtBtYcgacMgtDcagcgaNgttaataatagcagKYYtcgtaBtYctMaRtaRtDagaaaacacatgYaBttgattattcgaaNttBctSataaMataWRgaHtttccgtDgaYtatggtDgHKgMtatttVtMtVagttaRatMattRagataaccctKctMtSttgaHagtcStctatttccSagatgttccacgaggYNttHRacgattcDatatDcataaaatBBttatcgaHtNHaaatatDNaggctgaNcaaggagttBttMgRagVatBcRtaWgatgBtSgaKtcgHtttgaatcaaDaHttcSBgHcagtVaaSttDcagccgttNBtgttHagYtattctttRWaaVtSttcatatKaaRaaaNacaVtVctMtSDtDtRHRcgtaatgctcttaaatSacacaatcgHattcaWcttaaaatHaaatcNctWttaNMcMtaKctVtcctaagYgatgatcYaaaRactctaRDaYagtaacgtDgaggaaatctcaaacatcaScttcKttNtaccatNtaNatacatttHaaDHgcaDatMWaaBttcRggctMaagctVYcacgatcaDttatYtaatcKatWatcaatVYtNagatttgattgaYttttYgacttVtcKaRagaaaHVgDtaMatKYagagttNatWttaccNtYtcDWgSatgaRgtMatgKtcgacaagWtacttaagtcgKtgatccttNcttatagMatHVggtagcgHctatagccctYttggtaattKNaacgaaYatatVctaataMaaaYtgVtcKaYtaataacagaatHcacVagatYWHttagaaSMaatWtYtgtaaagNaaacaVgaWtcacNWgataNttcaSagctMDaRttgNactaccgataMaaatgtttattDtcaagacgctDHYYatggttcaagccNctccttcMctttagacBtaaWtaWVHggaaaaNatttaDtDtgctaaHHtMtatNtMtagtcatttgcaaaRatacagRHtatDNtgtDgaatVgtVNtcaaatYBMaaaagcaKgtgatgatMgWWMaHttttMgMagatDtataaattaaccaactMtacataaattgRataatacgBtKtaataattRgtatDagDtcRDacctatRcagagcSHatNtcaScNtttggacNtaaggaccgtgKNttgttNcttgaaRgYgRtNtcagttBcttttcHtKtgcttYaaNgYagtaaatgaatggWaMattBHtatctatSgtcYtgcHtaattHgaaMtHcagaaSatggtatgccaHBtYtcNattWtgtNgctttaggtttgtWatNtgHtgcDttactttttttgcNtactKtWRaVcttcatagtgSNKaNccgaataaBttataataYtSagctttaaatSttggctaaKSaatRccgWHgagDttaaatcatgagMtcgagtVtaDggaBtatttgDacataaacgtagYRagBWtgDStKDgatgaagttcattatttaKWcataaatWRgatataRgttRacaaNKttNtKagaaYaStaactScattattaacgatttaaatgDtaattagatHgaYataaactatggggatVHtgccgtNgatNYcaStRtagaccacWcaMtatRagHgVactYtWHtcttcatgatWgagaKggagtatgaWtDtVtNaNtcgYYgtaaactttaDtBactagtaDctatagtaatatttatatataacgHaaaRagKattSagttYtStagagagacgatgaaaattaatcgtcaatacgctggcgaacactgagggggacccaatgctcttctcggtctaaaaaggaatgtgtcagaaattggtcagttcaaaagtagaccggatctttgcggagaacaattcacggaacgtagcgttgggaaatatcctttctaccacacatcggattttcgccctctcccattatttattgtgttctcacatagaattattgtttagacatccctcgttgtatggagagttgcccgagcgtaaaggcataatccatataccgccgggtgagtgacctgaaattgtttttagttgggatttcgctatggattagcttacacgaagagattctaatggtactataggataattataatgctgcgtggcgcagtacaccgttacaaacgtcgttcgcatatgtggctaacacggtgaaaatacctacatcgtatttgcaatttcggtcgtttcatagagcgcattgaattactcaaaaattatatatgttgattatttgattagactgcgtggaaagaaggggtactcaagccatttgtaaaagctgcatctcgcttaagtttgagagcttacattagtctatttcagtcttctaggaaatgtctgtgtgagtggttgtcgtccataggtcactggcatatgcgattcatgacatgctaaactaagaaagtagattactattaccggcatgcctaatgcgattgcactgctatgaaggtgcggacgtcgcgcccatgtagccctgataataccaatacttacatttggtcagcaattctgacattatacctagcacccataaatttactcagacttgaggacaggctcttggagtcgatcttctgtttgtatgcatgtgatcatatagatgaataagcgatgcgactagttagggcatagtatagatctgtgtatacagttcagctgaacgtccgcgagtggaagtacagctgagatctatcctaaaatgcaaccatatcgttcacacatgatatgaacccagggggaaacattgagttcagttaaattggcagcgaatcccccaagaagaaggcggagtgacgttgaacgggcttatggtttttcagtacttcctccgtataagttgagcgaaatgtaaacagaataatcgttgtgttaacaacattaaaatcgcggaatatgatgagaatacacagtgtgagcatttcacttgtaaaatatctttggtagaacttactttgctttaaatatgttaaaccgatctaataatctacaaaacggtagattttgcctagcacattgcgtccttctctattcagatagaggcaatactcagaaggttttatccaaagcactgtgttgactaacctaagttttagtctaataatcatgattgattataggtgccgtggactacatgactcgtccacaaataatacttagcagatcagcaattggccaagcacccgacttttatttaatggttgtgcaatagtccagattcgtattcgggactctttcaaataatagtttcctggcatctaagtaagaaaagctcataaggaagcgatattatgacacgctcttccgccgctgttttgaaacttgagtattgctcgtccgaaattgagggtcacttcaaaatttactgagaagacgaagatcgactaaagttaaaatgctagtccacagttggtcaagttgaattcatccacgagttatatagctattttaatttatagtcgagtgtacaaaaaacatccacaataagatttatcttagaataacaacccccgtatcatcgaaatcctccgttatggcctgactcctcgagcttatagcatttgtgctggcgctcttgccaggaacttgctcgcgaggtggtgacgagtgagatgatcagtttcattatgatgatacgattttatcgcgactagttaatcatcatagcaagtaaaatttgaattatgtcattatcatgctccattaacaggttatttaattgatactgacgaaattttttcacaatgggttttctagaatttaatatcagtaattgaagccttcataggggtcctactagtatcctacacgacgcaggtccgcagtatcctggagggacgtgttactgattaaaagggtcaaaggaatgaaggctcacaatgttacctgcttcaccatagtgagccgatgagttttacattagtactaaatcccaaatcatactttacgatgaggcttgctagcgctaaagagaatacatacaccaccacatagaattgttagcgatgatatcaaatagactcctggaagtgtcagggggaaactgttcaatatttcgtccacaggactgaccaggcatggaaaagactgacgttggaaactataccatctcacgcccgacgcttcactaattgatgatccaaaaaatatagcccggattcctgattagcaaagggttcacagagaaagatattatcgacgtatatcccaaaaaacagacgtaatgtgcatcttcgaatcgggatgaatacttgtatcataaaaatgtgacctctagtatacaggttaatgttagtgatacacaatactcgtgggccatgggttctcaaataaaatgtaatattgcgtcgatcactcacccacgtatttggtctaattatgttttatttagtgacaatccaatagataaccggtcctattaagggctatatttttagcgaccacgcgtttaaacaaaggattgtatgtagatggtaccagtttaattgccagtgggcaatcctaagcaaaatgagattctatcctaaagtttgggcttgatataagatttcggatgtatgggttttataatcgttggagagctcaatcatgagctaatacatggatttcgctacctcaccgagagaccttgcatgaagaattctaaccaaaagtttaataggccggattggattgagttaattaagaccttgttcagtcatagtaaaaacccttaaattttaccgattgacaaagtgagcagtcgcaataccctatgcgaaacgcctcgatagtgactaggtatacaaggtttttgagttcctttgaaatagttaactaatttaaaattaattaacgacatggaaatcacagaacctaatgctttgtaggagttatttatgctgtttactgcctctacaaccctaataaagcagtcctaagaatgaaacgcatcttttagttcagaaagtggtatccagggtggtcaatttaataaattcaacatcgggtctcaggatattcggtcatataatttattaagggctcttcgagtcttactctgagtgaaattggaaacagtcatccttttcgttgtgaggcatcttacaccgctatcgatatacaatgcattccaccgcggtgtcccgtacacaaggaaacttgttaccttggggatataagaaaactcacacgtctcattattaaactgagtacaatttttgcacgagaaagtaatgcaatacaatatgatgaaagccagctaatgaaaagggatggaacgcacctcggatctgttgcactggattaaaatccgattatttttaaaaatattcagtgctagagcatatcaggtctacttttttatctggtatgtaaagcccacggagcgatagtgagatccttacgactcaacgaaaagttataacataactcccgttagccaaagcccaatcccgattactgccctaccctaacgtctgccatctaaatatcgaacttgttatgatcaatgtgactacctcccaccctttccccttcatttgttccactggggataagctagcgttttcagaatcaatgcaataagaatagccaattgtctcacttcatcagagctcttggcaattccaggcgctacgtggttctggaatatattcatttttcaaatagtaatacgtttagtgttgctattgtctacacgtttggatattacgttatgtgagcggacatcaatagttgtctaactctttagtaagccagagatagcactcttagcgaatggataccatcttccataagtttagttaatagtccgaaacaactgcttcgagcatatttgaacctccttgtaggcaaatagcctcttcaaagcaatcttactaatagatagagtttgttttaagggactactagaaatgggacaatcttaatagtatgacctaaactgacatttaaagatatatccaggtggcaagcataaagatcattgcgccacctccaccgtgggattacttatcagtcgatatcctatatgctaagtttgcgacggcagaatacaaactaagctgagttgatgctaaccttacctatgataccccattggaccggttaacagccctacttattccaaataaaagaacttttatgctgtagaagctattatagtgatgcctggtaacttcagtatattaaaatgacacacatacgccatatagagctcctggaactttgaataatgagcgaacttcgaagttgaagagcaagaaaccatatgtcacggttgcctaaagcccggtaaccagacatgtgctatcattgatcattatcgaggttttcataaccttgacccattatcggctgtgcgcggacaagtacttaaatcactagtttcttcacctgcttatcggtaagaaataaggttggcaaagaatcgcataagacggacgtagagccgcagcgttgtgcgagtccaggtgcatgcgcagcaataggattttaaattttgttccatttttaatttagccgtaaggatgtccgtaaatgattgaaaattggattcaatctttgggcctatgctactggaacctgatcgacaaaatttcaaacatacgttaactccgaaagaccgtatttttgcggctagaatagtcagtcgcttggagccatataccttaccacttaaacgacgtgctcctgtagttgaaatataaacagaacacaaagactaccgatcatatcaactgaagatctttgtaactttgaggcgaagcaccctcttcgagacaactaagagtaaagtaccgggcgccgcaaggagtcgattgggaccctaaatcttgacgaattgctaagaggctcagagctaccactgtaatttctctagagcccataataaatgaacgatacatccgtaggtagcacctaagggattataatggaagccaaatgcagttaataatattatatactggcgtacacgattcgacggatctctcacatagtgattcacgacccccccctttgattgacacagcgtcagcattttgcaagaacgatcttctgcatagggtgcgccaccgtaaggatgacgtcgaagctacaactgggtataatttaccatgcttccctgatgctgagtgcaatacactaagaatgagtttttaccccatatcaccagtatttgttctgttattgcgaagaaatggctatgctgagttggcgactaaagtcacccatcctttttattaggtaaccccctcccttaaactaactgatttgctggagctgccctgcatacatatactttatcatttatggacgtccgtgacgcttattatccaccatagtcgatatgctacacggattcattaatggatcgtaggagtttaagttatatttactaagatcggtctcggctactatcccgccttacccggcgctatttacggccatttttaatatattgacggtaattattcctatggtttcgaccgcacgtccttggacaagaaagaatggcaaaaaaaatgtaaaagaaaaaaaatattgagtccctaccatcatataaaaaatatgtgatgagtaacttgacgaaatgttagtggttattaaagactatctattacaccttttgttttctgtcgtagtatattaaagtctagaagccttacaggaaaatcagggttatacagccgatactccgcagcatgaatcatcgaggaggtgtcctaccatcgcgccttgtaatcttgtctgtgtatactgtatttagaccttttatacaaagtaaatatctcggctttatgtgattgggaggggcctactcaaacatgatgacttgacctaataatcactgtgcgggcgtcttatgactagctattccttgaaatccaccaccaaatggttaatatgtaaaaactttgacgatgaaacaaggtgaatgtgtagttactttgtgtaattagctgcgtcgagcattgcttgtaaaaccgtcaatcgcacacgttacttccataaaatttctacgaatacacccttcttaaaaaaaacgtaggaattcacgagtttaacaaacgataactgtataaagtggaagtccgaagaaagcagatgcccgaactactcgaagatgtttcgttttcttaaccataggggcttcttaatggcccactacgcacattttgttcaagcccgagagggacatccccattacgggagtattactaaaactgttccgtaatacgttcagcaagggatgaaaaaggccactgctcaagttattgacgtgggagtattacatcggaagcctgaatcccacactatgatggtctgtacaggcctagggactgcgtctagacggtattaccggcttctaatcatacgatcgtgagtcttaacgggaagtaaggctcacacctaccccaaaccatttatctatgtaagtataaaattgtgcgtaagtgttcaaagtggacaataaagacgtggcaaaaacccccgcacataagccgctttagatttcacaaataccaatgcggttaaaaacatccttgagtcgtacatacaccatactcgcgttaaacggatataacagaagataataaatccggatgtggagtcggtgtaactatagaaagccaagtgaaataatgcttaccagtcatttagctatacggctttcatttcatgtcaagagggtggagtttgacctgtacagttgatatatcaccgatacttagaactcacctaaagctaaaattgctcgcagcgtgtaatccgcatattacaaacaatagatgggattcattatacataagacacgatgatctgctttttcaggttgcgagatgttgcctatcgtcaatcgagtcctgccttacaccacttaaacaaaagtattgacagggaacctattttcgaggtattatatagtccagcttgaatatcaatttgacagttaacctagtgaaaatcagtaagaggaaatacgccacattctccagtgaaattctacgggttatcgtctagtccaactatcaattataactcacgagatataagtaaattctcgtacttggcctgatttttattatactttggatccttagtaaacaggaagggagaaaccttcaacgaaaaacactggattttgttttactctcaaagctcttatatgacggaaataccctgtcaagtcttaactttattactagactaatgaaatgggcttggggtggccagaatcatagtacaatttagcggatacactattcggactttcctatcggctgtctggttggataagtatggggactaataggctagacatacctatacttaaactatacaggcgtcatctatctctgcaactttggagttccctgatgttctcccgccctttgggttcacatcttctataccgacacccctaataacgattagtttgtgggttagagtaaattaatacggttaatattaatgtatcgttgaaaagctggtgtcgccaataaggtaaccggctaggcagagtatatgtcacgaagtataactaccctaatgataagctgtaggaataaaattaatgctgtctctaagcgaagagatatttccgactctgttttaatgacgaatctcattacttctgacttgcaaatgttcaatatggcacggtttcacggcacctttgtgacgcatataatgaacttagaagattataacgacggaactttatatgataatccgttacgattaaagaatctgttaaatatcataatggcattcagttctagaccgtgcatcatggtaaacttactttctctgcatggcgacatacatttcgctattcaaattcgcgtgtggttacacccactcgcacctttggaatattaagagaagatgatcagaaaatccattcgctcaatttttctgacgtacgtctaatttatcctaggagacaaatcgttttatgtctctcacatttttgaagaaaggttcgagagacaatactcaggtcctgaactgctagaagatactcggtggagcgtggcaacaatgaaaaactcgtgacataaatgaatgatacttttccaagttcagttaagtgaatatgtttaacatacccggcttttcgatcttaagctgacgctggacgtgcgagtaatgtcagtctcttacatacactagtgactccaagtttcgtcaaaaacgccccctcccttctcgagcccactcacgctatgtattgacgcgaacttgttcgggatcagacttttcaggagttcggtcgcgtgtccctatgtgctaatatataagttagatcgcattagatgctaatctgaatacttatagacgaccttcaacgagaacgggtaccaccttgaggctagagttaggtgtgaaacgacaggtagggacatataaaatttgagtgcggctttagttaagggtttaattacctactcaaacatcacgctcgcgcccttcgtacgtaatcgaccatctagaggctaaggggactgtactaggtagtgattaatgatatcctagacgcacgtgccttagatcttcagactctgatggtccgcgatcaccgtaattgtagtcctccaactcgatcactttgttggcgtcaaagaaattacgatatctaaatacttataatacaataaccaaggatgagaatgactcatcgcgttggagttatattgcttgaagttctatggaatgaaagcacgttatctgccgtcccaatatctccagtgagctaattcattggacggtccactttgatcaatccccgaggagatgttcggacactttagtctgtaacacttagcgttgagaccacgaacaattgattactcagtcttgaaggtgttttccaaagttcattttaaataagactacgataggcctttcctattgatataaactacccggctctgttgttcgtgtgagtcgtacttctctgtgtttttctgattatagcaagattcgattcttagtgtaaacagcgatttttatttgacccgtcaatgagaagcgcataggatctaagcaaaattatcaagttgtgccacaaggtaagatctttccagttattgcaggtaggatgtatcccacgttgatagtatgaggtctgacgtcaactgtctaggagagttgaccgcgtgcgggtacaccggatttgcatcgatgttgagaacgcagaactcccactgtcgtggcggcgttcctgatatttagcaagaggcgttgataaagccctcatcatctagatctcgacctcatctgccctcttgctccatcattttctacacagactactttcctatctacgttagtataattgctttctatcttagtatcatttagagcttctccgtcaacaggttcgtgctattaaagttagtacgaaagggacaacttgtagcaacgcatttaatcggttttcgactacttcgcacaaaatcagataaagaagtttgtcattctattagacattgaattgcgcaattgacttgtaccacttatgatcgaacactgaatcaagactgtgattaactaaaatagacaagccactatatcaactaataaaaacgcccctggtggtcgaacatagttgactacaggataattaattggactggagccattacattctctacaatcgtatcacttcccaagtagacaactttgaccttgtagtttcatgtacaaaaaaatgctttcgcaggagcacattggtagttcaatagtttcatgggaacctcttgagccgtcttctgtgggtgtgttcggatagtaggtactgataaagtcgtgtcgctttcgatgagagggaattcaccggaaaacaccttggttaacaggatagtctatgtaaacttcgagacatgtttaagagttaccagcttaatccacggtgctctactagtatcatcagctgtcttgcctcgcctagaaatatgcattctatcgttatcctatcaacggttgccgtactgagcagccttattgtggaagagtaatatataaatgtagtcttgtctttacgaagcagacgtaagtaataatgacttggaataccaaaactaaacatagtggattatcatactcaagaactctccagataaataacagtttttacgatacgtcaccaatgagcttaaagattaggatcctcaaaactgatacaaacgctaattcatttgttattggatccagtatcagttaaactgaatggagtgaagattgtagaatgttgttctggcctcgcatggggtctaggtgatatacaatttctcatacttacacggtagtggaaatctgattctagcttcgtagctgactatactcaaggaaccactgctcaaggtaggagactagttccgaccctacagtcaaagtggccgaagcttaaactatagactagttgttaaatgctgatttcaagatatcatctatatacagtttggacaattatgtgtgcgaaactaaaattcatgctattcagatggatttcacttatgccttagaaacagatattgcccgagctcaatcaacagttttagccggaaacaatcgaagcatagggacaatgtatcttttcctaaattgccatgtgcagatttctgagtgtcacgaagcgcataatagaatcttgtgttgcctcaactcgttgaaaagtttaaaacaatcgcagcagtctttttggggtctactgtgtgtttgcaaaataactgaaagaaacgcttgaacaactctgaagtagctcgagtactcattaaagtgtaacacattagtgaatatcggccaatgaaccaaacgcttcccggtacgctatctctctcatcgggaggcgatgtgcaggttatctacgaaagcatccctttacgttgagagtgtcgatgcatgaacctcattgtaacaatagcccagcaaattctcatacgtgcctcagggtccgggcgtactcctccatggaagggcgcgcatctagtgttataccaactcgctttttaactactatgctgtagttctacaggcatagtggccagtattttctaacttctctggatagatgctctcactcctcatccatcacggcttcagtttacgtcttacttgcttgttcagcaacggatggaggcattaagtatcttcactgttccctaaaattgctgttcaatatcaaagtaaggacgatacagggaaagctcaagcacactcattgaatactgccccagttgcaacctcacttaatctgacaaaaataatgactactctaagtgttgcggaagcagtctcttccacgagcttgtctgtatcacttcgtataggcatgtaactcgatagacacgaacaccgagtgagaaactatattcttgcttccgtgtgtgtgacaccaggtaattgatgcggatataagctggagatcactcacgcccacacaaggcgctgctacctctttattccaatgtgtaagaatttgctaacttcatttctagaccgcagctttgcggtcataatttcacggtacggacccttgggttagagacttgataacacacttcgcagtttccaccgcgcacatgttttagtggcttctaacatagaatttttgttgtgacataaagagtgcgtgggagacttgcccgaccgttaagccataatcaattgaaagccccgtgagtcacatctaattggttgtactgcgcatttagctatcctttagctgactcgaagagattcgattcctaatataggttaattagatggctgccgcgcgaagtaaaacgtgaaaaacgtagtgcgcagatctgcataactcgcgcttaattacttatgagtagttccaagttcgctacgttatgagagagattggaattaagcaaatatgttttatggtgattttgggatgagaaggactgctaagtacggctactaaacaaatttctaaaaccgccatctaccttatcttggagacatttaagttgtatatgtcactagtctagcttttgtctgtgggacgcgttctcggaatgagggaaatgcaagagccgattcatcaaatgcttatctaagaaagtagtggactattacaccaagcacgaatgccagggaactgctttcttgctcaggacctcgcgacaaggtaccccgcataagtcctagaattacatttggtcagcaatgctgacatttgaccgtgaaaacataattttaatcagaaggcagctcacccgcttgctctagatcttatctttgtatgaatgtcagaatttactgcaatatccgttccgaatagtgagggcttagtatagttctctgtatacaggtcacatcaaactccccctgtcctagtacagctctgagctttaattaattgcatacatttccttcaatcatcagatgaaaacaccgcgaatcatgctcttctcgtatagggcaagagaagcaacaaacaactagcccgactcacgttcatccgccgtatccttgttcagttcttactccgtattaggtcagcgaaatctaatcagaataatcggtcgcgtatcaaaattaaaatcccgcttgaggttgacaattaaaacgctgagcagttatcggctattagatagtggggtgaaagtaattggctggaattatgttaaaacgtgatattaagctaaaatacgctacttgttgccgacctaattcagtcattcgatattcagttagagccaagaataacaagcttgtataaattgaacggggtgcactaaacgatgtgttactctaatattcagcttggagtatacctgaaggcgaattcatgtatcggccaataataagacgttgaagatcacaatttggactagcaaaagaaggtgatttatgcgtggggattgagtccactgtacgagtacggtctctggaaaattataggttcagggaatataaggaagtaaagataattaccaagagatttttggtatcgctatgacccagaggtgttctaacgtctgttttgatccgcagaatttctgcctcaatgcatatttgacggacttgaactagagcctctaaagttaaatggcgacgcaactgttcctaaacttcaattattactactctttttttcctagggtattgtagaggccagtggacaaaataaatcaaatttaagatgtttcggacattaacatcccccgtagcatagaaatcatcagttatccaatctctcatcgagcttttacaatttctgctggcgctatggacagcatatgccgcgagacctccgcaagactcacttgatcactgtaagtatcttcattagaggttagagcctatagttaagctgctgacctagtaaaattggtattttctaattttattgctcaagttaaaggttagtgaagggataatgacgttatttttgaacaatgggttgtattcaattttatatcacgaatggaacccttcattcccggcataatactagacgacacgaacaagctccgatctatcagccaggcacgtgttaaggtttaattccggcaaaccaatgaagcatcaaaaggtgacctgatgcaacttagggtcacgatgagtttttcaggactacttattacctattaataagttaacatgagccttcataccccgtaagacaatacatactccaccaattagaattctgagccatcttatctttttgtatcatcgaagggtatggccgaataggttaattagttactcctaacgtctctacaggcatgcatttgacgcaccttcgaaaatagtcaatctctcgccacacgcgtctagtatgcagcatcaaaaatatagtccacggtttccggattaccaaacgcggcaaagagaaacattgtatcgacggagataacttaatacagaaggaaggggcatcttcgaatacggatgaataattctatctgtttattctgacatcttgttttcaggttaatcttacgcattcaaatgacgcctgccccatgcgtgcgcaattattttctaatattgacgagagcaatctcactccttttgggtctatttatgttttattgaggcacaagcctatacagaacaggtactattaaggccgtgagtgtgagactcaaaccgtggaaacaaaggatgggttgttcttggtacaagttttagtgcatgtgggcaatccttaccaaaatcagatgctatccttaactttgggctgcatttaagatggcggttggaggcctgtgagaatcctgcgtgtcatctttaatgaccgaattcatccatgtagattcagatcacacactcattccttgatgttgtctaaacaaaagttgttgtggacgcattggagggagttaagtaacaacttgggatcgcatacttataaaaattatatgttaaactttcacaaacgctgaagtccaaagtaactagcccaaacgcctcgagagtcactaggtattaatggtgtttgagttcctgtgaaatagtgttcgaaggtaaaatttatgtaccaaatcgaaagaacacttaataaggcttgcttgcacggaggtatgatgtttactgactctacaaccctaattttccagtacgtacattcattccaataggttagttctcaaagtgctatacaggctcctcaattgatgatatgcttcagccgctctatggatattagctcattttatttaggaagcccgcttagaggcttactatgagggaaatgccaaaatgtcatacttttcggtgtgtcccatatgacaccgctttacatagaatttgaattaaaacgcgctctcccgttcactaccatacttggtaccgtgcgcatattacatatagatataggatcattttttaaagctgtactaggtttgatcgacaatcttatgctatactatatgatgtaaccctcataatcaataccgatcgtacgatcctagcataggtggcaagcgattttatgccgattattgtgttaaatagtctgtgagtgtgattatcagggctacgttggtagaggggttgtatagacctcgcacacattgtgacatacttaacaatatacgaaaactgatataataaatccccttacccaaacaccaatcccgttgaatcaactaccataacgtctcccatataaattgcctacttgtttgcataaatctgaatacataacaccattgcaccttcttgtgttccaatcccgttaagattgccttgtcagatgatatgcaagaacaatagcatttgctagcaattattaacagctcttcgaattgcctccacataacgcgggagggtatattttaatttggcaaatactaagtactgttggcgtcatatgctattaacggttggatattaagttatgtcagccgtaagcaagagtgggcgaaatattttgttacccagtgagagcactcttagagtttggatacaataggccatatgttgacttaagaggacgtaactacgccgtacaccattgttcaaccgacttcttggcaaatagaatcgtattagcaatcttaagaatagagacacgttcgtgttagggtatactacaaatccgaaaatcttaagaggatcacctaaactgaaatttatacatatttcaacgtggatagatttaacataattcagccacctccaacctgggagtaattttcagtagatttactagatgattagtggcccaacgcacttgactatataagatctggggatcctaacctgacctatgagacaaaattggaaacgttaacagcccttatgtgtacaaagaaaagtaagttgttgctgttcaacagatgatagtcatgacgcgtaacttcactatagtaaattgaaacaaatacgcaatttagacagaatggtacggtcatgaatgacagtaattcgaagtgctagaccaacttaaaataggtaaacgtgcccgaaaccccccttaacagaaagctgctatcatggtgcagtatcgacgtgttcagaaacttgtaacttttgagcaggtccgagcacatggaagtatatcacgtgtttctgaaccggcttatccctaagatatatccgtcgcaaactttcgatttagtcccacgtagagcccaagcgttgtgcgactccacgtgcatgcccagaaatacgagtttaaatttggttacatggttaattttgaccgaagcatcgcactttatgattgataattggattcaatatgtcgccctatgcgaatgcaacatgatccacaatttggctataagacgtttaatccgtatcacactttgtttgcggctagtatagtaacgcccgtgcaccaagagtcagtaacaattataagtactccgcaggtacttcaaatataaaaactaatcaaacacgacccatatgatcatctgaagatatttggaactttctcgacaaccaccctcgtactcaatacttacactaatcgacaggcacacgcaacgtgtacagtcgcaccatattgagtcaagatttgcttagtggcgatgagcgtacacgcttatttctctagtcacaattagttatctacgagacatcacgagggagcaaataagcgatgttatggctacacataggcacgtatgaatatgatataagccagttaaacagtcgaaccatcgagcaaattctcatgcaccaacccacacgttgaggcacaaagagtaagctgtttgaatgtaacttcttctgctgagcgggccccaacgtaaggatcaactagaagagaaaactcggtattagtttaaatgcgtcacggagcatgagtgcatttcactaagaatgtctgtgtaaccaatataacatctatttgttatctgattgcctacttatggctttgcggtcgtggcgactaatgtctccaatccttttgaggtcggtaccaactccctttaaattacgctgtgcaggctcatgcactgcatacatatacggtagcaggtagggacctcacgcacccttattataatcaatagtagttatcagtcaacgaggcaggaatgctgaggtcgaggtgttggtatattttctatgtgccgtctaggcgactatcacgcattaccaggcgagatttaagccaattttgaatatagtcaacgtaatttttactatgggttccaccgaaacgccttgcacaactaagaatcccataaaatatcgatatcaaataaaagattgtgtcaataccttcatatatattttttcggttgactaacgtgaactaaggttaggggttttgtatgtctatataggaaacagtttcttttctgtcctactttagtaaagtcttcaagccttactccaaaatcacggtgattaagccgttactcagcagcatgattctgcctgctcgggtcctaaaatccagccttgtaagagtcgctgtgtattagctagggagacctttgttaaaaaggatatatcgcggcgggatgtgagtgcgtggcgcatactcaatcttcagctcgtgtcattataatatctctcccccacgcttttcactagatatgccgtgtaagcaaacaccttatgcttaatttcgaaaatattggtacttgaaaaaagctgtaggggtacttaatgtctggtaggagatcaggagagaattgagtgtaaaaccgtaaagccctcacctgacttcatgtaaatggcttagaagactccatgatttaataaatactacgaaggaaagactggatctaaagataactctagtaaggccaactcccttcaatgctgttgccagttataatccaagagctgtccttttctgaaccatagcggcttctgaagcgaactagaagcaaagttggttctagccagacagccacataccctgtacgggtgtattactaaaactggtccggtattagttcaccaagggaggaattaggcaaaggatctaggtatgcaagtcggagtattacatccctaccctgaatccatcaataggttcctctgtactggccttcgcaatgagtattcaaggttgtacagccgtataataataagatagtgactatgaacgggaagtaacccgctcaccttccccaaaacattgttatatctaagtattaaagtctgccgtagtgttaatactcgaaaataaacaactggcaaattacaccgcacttaagccgcttttgatttatatttttccaatgcgcttttaaaaataattcagtcctacatactaattaagacccttaaacggagatatcacaagttaagttttaaccatctcgactaggtggaactatagatacccaactcaatttatcattacctgtaatgttcctagaaggattgcatttcatgtcaagacggtggagtttcacagcgaaacttcagtgtgaacagattctgagaaatcacctaaacctattagtcagagcacccggttagaaccagttgtcaaaaaatagagcggttgcatgagacagaagtaacgatgagatccgttgtaacgttgagacatctggcctatcgtcaatacagtcctcccttaaaaatatttttaaatactaggcaaacccaacataggttagtcctatgtgatacgccacatggtatatcattttgtaacgttacctagggataatcaggaagtggaattacgcaaaagtagacagtgaaatgcttagggttatagtctagtccaaagataaaggataaagcacgtcagagaactatattagccgaatgggaatcattgttaggagactgtggatcatgtctaaaaagcaacgcagaaacagtcatcgaaaaaatctcgtttttgtttgaatctaaaagagctttgatgaccgatagtacctgtatactagttactgtattacgtgtctaatgatttcggattggggtccccagaatcagacgtcattgtagacgattcaagtttaccaatttaatttcccagctctccttggagaactatcgccaataattgcagtcactttccttttctgaaacgataaagccgtcagagttctctgcaacgttggacttacctgaggttctaacccactttcggttctaatagtagttaacgacacaacgaataacctttactgtggggctttcacgatattttttcgcttattattaatggttacgtcataagctggtgtccaaattaaggttaccggcttcgcagagtagttgtatccaagtataacttccctaatcataagatcgaggtagaaaattaatgctgtctctaaccgaacagatatgtcccactatgtggtatggacgttgctaattacttctgaagggaaattggtcattatggatacgtgtctaccatcaggtcggacgcagatatggttctgtcttcagttgatccaccgttctttataggataataactgacgattaaagattatggtaaatagattaagccaattctcttcttgtcagtgaagcatccttaactgacttgctctgcagcccctcatacatttagctattcaaagtaccggctcgtttcaaactctcccacctttggaagaggttgtcaacttgataagtatatcatttacagcattttttcggacgtacctctaatgtttcattgcagaaaattagttttttctatcgcacattttgcaagtaacgttagagacacaattatctgcgaatgaactgctagatctgacgaccgggagcctcgcaaatatcaaaaaagactgacatatatcaaggagtcgttgacaagtgctggtaagtcaattggtttatctgtcccggcgtttcgatcttaagctgaccatgcacggcagagtaatgtcactctcgttcttacaagtctgtctccaagggtcggcaaaaaagacccctccattctcgagcccactcacgatatgtagggacgacaacttgtgcggcttatgaattgtctggactgcgggcgagggtccatatctccgaagttagaagggacatacctttagatgataagatcaattcttattgacgaaattcatccacaacggggaacaacttcaccctagacttacgtctgaaaagacacctagcgtcttataaaaggtcagtgccccgtttcgtaaggctggaattacctacgcaaacttaaacctcgcgcccttccttacgtatcgacaagatagaggctatcgcgaatgtactacggaggcatgaatcatatactagaaccaagtgcctgtgatattaacaagatgatccgacgcgagcaccgtaattctaggcataaaactccagcaatttgggggccgaaaacaaatgacgttagctaattaattatatgacatgatcaaaggaggtcaatcacgcatcgagttcgacgtatattcattgaacttcgtgcgtttgaaagaaacttttatgaaggcaaaattgatcctgtctcctatttcatgcgtacctcctagttgataattccccgagcagtggttaggacacttttgtcggtatcaagttccggtctcaaaacgtaaaattctgtaatctgtatggatggtctgtgaattagttaatttttatgaagtcgtcgagacgcagttcctattgatttattctaaacggagatgtgcttcgtgggactcggaagtagatctgtgtttatgattattgctactttagatgctgactgttaactccgtgttgtttttcaaccgtatatcacaaccgaattggatagaacctatagtttcaagttctgccacaaggtatcatatttacagttagtgctggttgcttctttcaaacgtggtgagtttgtgctatcacgtcaacggtagagctcagtggaccgagtgcgcgttcaaccctgttccagagagggtgtgatagcacatataccacgctcgtcgaggcgttcatgatagtttgcaagagccggtgttaaacacatattattattgttatccaactaatcggacctatgcataaagcattgtctaaacagaataattgcctatatacggtagttttagtgatttatatcttagtatcagttagagcttcgaactcttcaggttcctcatatttaacgttcttcgaaagcgaaaacttctacaaacgaatgtaagcggttttccaagtagtacctataaatcacagaaagatctgtctcagtatagttgaaatggtattcagctagtgacgtgtaccaattatcatagttcactcaagcaagacgctcattaacgaatatagacaagacactatatcatataataaaaaagaacatggtgctcgaacatagttgaattcaccatattgaaggggaatgctgacatgtaattcgctactagacgatcaattccctacttgtcaaagttgaactggtacgttcttggaattaaatatgattgcgctggaccaaattgcgacttcttgagtttcagggcaaacgattgagccggaggatgtccgtctcttacctttcttgcttatgataaacgacggtccctgtacatcactgggaattctcagcaaaaataattgggtaaatcgagactcgatgtattcggccacaaaggtgttagacgttaaagattattcaacggggcgataataggatcataaccggtatgcaagcgcattgaaagagccatgagatccttatccgataaacgctgcacggtatgtgcagccttattgtcgatcacgaatttataaatgtagtctgggctgtaagttgaagacctaagttataatgaagtgcaataccaaatcgattcatagtggattatcagactcaagatatctcctgataaattacagttgttaagatacggataaaatgagatttaagattagcagcctctaatctgtttcaatcccgttggaatgtggtatgcgatcaaggttaagttaaaatcaagcctgtcttcagtcttgattcttgttctgccatcgcatgcggtctacgtgagttaatatgtagcttacgttctagcttgtgctaatctgagtatagattcgtagaggaatattatcaagcttccacgcctcaacgtacgtgtattggtcacacaagacactaaaagtggaagtagcgtaaactatagtctagttgttaaatgctcagttcttgttatattcgatatactcttggctaatttatgtctgagtatataaaattaatgatattaacttgcatttcacggatcccttagaaaaagattttgaccgagcgcattataaacggttacaccgaatcaatagaagcatacccaatagctttctttgaatttattgcctgcgcaacttggctgactctctagatccgaataattctatatggtcgtgacgaaactagttcattactgtttaaaatgccaacatgtcttttgggccgataatggctctttgcaaaattactcaatgatacgattgatcaaagcggtagttgctagtggtagcatgtaagtctatcaaatgtctgattatccgaaaatcttccaaaagagtccacgtaccatatctatctcatagcgacgcgaggggaaccttatctaactatcattccatttaccgggtgactctcgatgcaggatccgattgggataaattgcccagaaatggctcattcctgactaagggtaaggccgttctcagcaagggaaccccgcgaatctaggcttataccatctagattgttaactacttgcctgtagttctacagccatactggacagttgtttctaaatgatcgggattcatgctagcactcctctgaatgcaccgcgtaagtttaactattacgtccgtgggcagataaggatggaggctgtatgtatcttaactgttacctaatatggctggtaattatcaaagtaaggaccttaatgccatagcgctagcaatcgctttgtatactgaccatgtgccaacctctcttaatctgtaaaatataatgtcttagctaactgtggacgatcatgtctctgcctagagcttcgctgtatcaattcctatagccagcgtactagtgacacaacaacaccgtgtgagaaaagatattagtccttacgtctgtctctctacagcttattgatgaggattgaacatggacatatagctccccctcaaaagcagatgctacctctttattccattctcgaacatttgccgaacttaatttcgacaaacctgaggtcacgtcttaatttatcggtaacgtcacgtccctttgagactggataaatatattaccaggggccaacgagcaattgttggaggcgcttctataatacaaggtgtcttgtcaaagaaagacggcgtgcgtctcgtgcaactcacttaaccaatattaatgtgaaacccccctctctcacatcttatgcggtgtactgccctggtacatttcctgtacaggactccaacagtgtagattcctaagatagctgttggagttgcctcacgccagatcgaaaaactgaataaactagtgagctgagctgcagaaataccgcttaattacttatgactagttcaaagggacctacgtgatgtcagacattgcaaggaagaaattaggtttgtgcgtcattttggctggactagcactccttacttcccctactattcaaatgtcgtaaacagcatgagacaggatcgtgctgacatttaaggtctattgggaacgaggctacctttggtcgcgcgctcgcgttctccgaatgaccgaaatgcatgagcacagtatgcaattgcttatagatctaaggtctggtcgttgaaaccaagcacgtaggcctgggaaatcagttcttcctcagcaactacacaaaagcgtccaagcattagtacttgtagtaaatgtccgaacctatgcgctcatttgaaagtcaaaaaatatttttaagcagtaggcacctaacccgattcctctacttagtagctttctttgattctcagaattgactgcaatatcactgcacaattctgtgccattactagacttctctgtattaacgtctcatcttactaacactcgcctaggacacatctgagagtgaagtatttcaatacatttactgaaatcttcagttctaaaatccccgaataaggctcttatcggtttggccaacacaagaaaaaaacttcttgcaccactcaccttcatacgcaggagcctggggaacttagtaataactatttcggcagacaaagcttataacaagttgccggcgcgtataatatttaaaagaccccttgagctgctcaattaaaacgctcacctggtataggctattagatagtgccgtcttagtaaggggcgggaattatcggataaactgatattttgataaaataaccgacttgttcacgacataagtcactaaggagattttatctttctccaaagtatatcttccttggataatttcaaagcgctgcaatttaagttctgttactagtttatgctgctgggaggtgaccggaaggcgtagtaatctagaggcaaattataagaagttcatcatatcattttcgactacaaaaacaaggtgttgtatgccggcgcattgtgtaaactggacgagtaccctagatggaaaattatacgttaagccaagatttcgatgtaatgataattacctacacatttttgctatccataggaacaagagctgttctataggctcgtggcatacgaacatttgctgccgctatgaatattggaagctcttcaactacagactctattcttaattgccgtcgaaaatgggccgaatcggctattattaatactcggtttttccgaggggattgttgtcgacagtcgtaattattattaatattgatgttggtgaggtcatttaaatacaaccttgcagacaatgaataagggatccaatctctcatactccttttacaattgctcatgcccctatgcaaaccttatgccgccacacctccgcaactctctcttctgaactgtaagtagcttcattactggtttgagactatactgaagctgatgacattctaaaatggctattttcgaatgtgattcataatgtttatcgtttgggatggcagaatcacgttatttttgatatagcccgggtattctattgtatagaacgtatgctacaagtcattccccgaagaagactagaagtaaacaacatgcgaccatcgttaagccacgcaaggctgtagctttatttcccgataacctatcttccataaatagcggacagcaggatactgacgctcaacatcagtggttatggtctaatttttaacttttaataaggtaacttcagcaggcatacacagtaactctttaatttataatcaaattagaagtctgacacttcttatatttttctatcatccaacgcgatcgcccattagcttattgtgttactaataacgtatctaaaccaatccttttcaagctactgcctatattgtcaatatatacaaacaacaggatagtaggctgcttaaaaaatattgtcaaccgtgtacgctttacaatacccggaaatcacaaactttgtagacaacgagtgaaatttatacactacgaagggccagcgtacaagacccatgaattaggcgatatgtttattctgacatattggtttatccttaatctgtcgctgtaaaatgaagccgcccccatccctgcgaattttttttcgaagattcacgactgaaatataaatacgtttggctatatttatgttggagggaggcaatagcctttactgttaaccgaagatttagccagtgagtgtgacactaaaacactggaataaatgcaggcgttcttctgggtaaaaggtttagtcaatctcgcctataagttcatatagctctggatataattatctggcccatgcatttatcatggcgcttggtgccctgtgtgaagccggcctctcatattgaaggtccgaagtattccatgtacattaagatcactctctcattcatgcatcttggcttaacaaatctggttgtccaagctttccaggcacgtatggtacaaattcggatcgaatacttataaaaatgatatgttaaactgtctaaaacgctcatctacaaagtaaagtgcactaaccaatagagtctcaagaccgtgtaatgctggtgcactgaatgtgtaatacggttagaagggattagttatgttacaaatccattgaaaacttaagaagcattgcgtgctcggagggtgcatcttttatcaagagactaacattattttcaacgacgtacatgctttacaatagggtacttatcaaacgccgagaaacgcgcctatagtgatgttatgattatgacccgatatccattggaccgaattttatgtaggttcccagcgtactcgcgtaatatctcggtattgccataatgtaatacttgtcggtctctcccagatgaaaaagcgttacagagtatttcaatgaaaaacagcgcgcaacgtcaatacctttaggggtaacggccgctgatttcatatagatatacgataagttggtatagctctactaggtggcatccacaatcgttgcatttactatagctggttacaatcataatctataccgttccttacatactaccatagcgggatagcgtttttttgccgttgattgggtttaagaggatgtcagtctcattatatccgattcggtgggagagccgttgttttcaaatcgcacactttgtgacataatgtacaagataacaaaactgatataagatataaactgtcaatatcaccttgacacttgaatcaaagtaaattaactcgcaaatataatttgactaattgggtgcagatttctcaattaataaaaaaatggcaccggatgggcttacaagccccttatcattcacttgtatcatgatttccaagaacaatagaatttgctagcaagtatgaacagagattcgaattgcatccacagtacgccggagcgtttattttaatgtggatatgacgatgtactgttggcggcatttgctagtaaccggtccttatttacgtagcgcacacgtaagcatgtctgggagaaatatggtggtacaatctcagagaaagattacagtttggtttaaataggacttatcgggtcggaagtggaacttaataagcagtacacaattgggcaacagacgtcttgcctattacaataggattacaatgcgttagatttcagacacgttcgtgtttggctattcgtcaattccctaaatagttagacgatcaactattatcaaagtgattctttgttcatcctccattcatgtaacagatggcacactacgcataacgccgaggaattttaacgagatttaagagagcagttcgggcacaacccacttgactttataacagctcggcagcataaacggtaatatgtgacaaatttccaaacgttataagaacgtatgtgtacttagaaaactaagtggttcatgttcaacagatgtgacgcagcaagcctaacttatctattggttttgctataaaagaacaaagttacacagaatcctaagggcttgtttcacacttatgcctagtgcttcaccatcttaaaatagcgaaaccggcacgaatcaaaccttaaaacaatgcgcagatattggtgatggtgactccgggtatgataatggtaactgttgaccagcgcccacctcatcgaagtatagaaagtggttaggataaggatgagaccgaacttatttccggccataactttagattttctacctagtacacaacatcagggcggacacgaaaccgccatcacatcatataccaggtttaatttgcttaatgggggaagtgtcaacgaaccttcgaactttagcaggcatatggccattatatatggccccagagcagaatgctacagcagacaaaatttggatttatgtagtttaatacctatcaaacttggtgtgaccatacttgtctaacgacagtgcacaaagtgtaagttacaattattactactcagcagcttctgcaatgataaaatcttatcatacacgtcacatatgataatatctacttagggggaacgggctccacaacctacatagtactcaatacttacactattcgacaggcacaccaaacctgtacagtcccaaaagattgagtcaactttgcagtactgcagatcacagtaatagcttagttagcgagtcaaaattagttttctacgagactgcacgaccgtgcaaatttccgatgtgttggctacaaatagcaacgtatgaatttgtttgaagccacgtaaactgtacaaccttagagataagtctcaggctactaaaaacacgttgtggcactaacaggatcatggttgattcttacttattcggctgaccggcccaataagtaaccttcaactagaacagaataatcgggagtagtttaattcagtcaaggtgcaggtctcattgtaactaacaagctctgtgtaaccaagttaaaatcgttttcttagcggattccctacttatggatttgagctcgtccacaatattcgatacaagaagtttgtggtccgtaacaacgaaattttaattacgctgtgcagcctcatccaaggaattaatagaaggttgatggtaggctccgaacgctccatgattataatcaagtggactgtgcagtaaacgaggaaggtatcctgacgtcgtggtgttcgtttttgttatttgtgccctatacgagtagataaaccatgaacagcacagtgtgaacccatggttgattttaggctaccttatttttaatttccgttacacagaaacgaattccacaactaacatgccattaatttttcgatatcttataaaagatggtcgaaattcattcatttattttttttcggttctcgaaagtcaactaagctgtcgcgttttgtttctctttagaggtaaaagtggctttgatctcctacgtttggatactagtcaaccattactccatttgatccgtgagtatcacctgtctaacatccagcattatgactcctcggcgaagaaaagacacacttcttagagtcgatgtgtattagctagggacacagttgtttaatacgatagtgagcccagggagggcagtgcgtcccccagtagatttattcagctagtgtaagtataagatatctcacccacgaggttcaagtgatatgcagtcttagaataatacttatcctgaatttcgatattatgggtacttcaataatccgctagcgctactttatgtctcgttggacagcaggacacatggcagtcttaaacactaaagacatcacctgaatgaatgtaatgggattacaagaatcaatgaggtattatatacgacgtaggaaactctggatatatacagtaatctagttacgccatcgcacttcattcctctggaaacttagaagacatcagctgtacgtggaggaaccagacccccgtatgtagccaaatagaaccaaagttgcttatacaaacacacccaatgacaatggaccgctggagttcgtaaactcggaacgtagtactgcacaaacccagcatttagcaataggagctacgtatgcaactcccacgtggtaataccttcaagctatcaatatataggtgcctagctaatcgcattcgcaagcagtattcaagcttgtaaaccagtataataattacagaggctctatgaaacccaactttccagctaaaagtcccaattaaatggttatttcgtacttttaaagtcgcccgttctgttattacgcgaattgattctactccaaaattaaacacaaattatcaaccgtttcatttatatttgtcaatgcagctgtttaaaataaggctctactaaattataattaagacacttattaccagatttctctagttaagtttgaaccagctcgactaccgcgaaagatacattcccttctctatttttcagttcatctatgggtcagagaagcattgaatttattctattcaccctcgtcgttcacagcgaatcgtcagtgtgatcagtgtatgagaaatatcctaaaccgtttagtcagaccacacgcttagaacaagtggtctaaaaagactgccctggaaggagtaagaagtatacagctgatccggtgtatccttcagtcatctgccctatactaattacacgacgcaaggaaaaataggtttattttctaggcaaacccttcataggtgactccgatgtgttacgaatcatgcttgagaatgtgctatcgttaccgacggataataacgatctccaatgaaccaaatgtagaatgtctattgattacccttttactattcgacttagagataggagatagaacctcagtgtacttttttagccgaatgggaatctttgggaggtgaatggccataaggtcgtaaatccaaccctcttaaagtcttccatattatatcgttgttcgtggaatcgataacagatttgttgacccatagtaaatgtatactagtttatgttgtaagtgtagattgttttccgattgccgtccaaactttatgtcgtaattgtagaccagtaaagttgaccaaggtaagtgcccagcgatcctgcgagatcgatcgccaatttttccagtcactgtaagtgtaggtttagataaagccgtatgagttatatcataagggcctcggaaagcagcttcgaaccaaagttcccttataatagtagtttaactataaaagtatatactggtctgtcgccctttcacgatttgttttaccggtttatgaagcgttacgtcattagagcggctccaatttaaggttaacggcttccatgtgtagttgtatacaaggataacttaaagtatctgttcagcgagctagttaagttatcctcgatagaacacaactcagaggtcccaagatcgggtttgcaacttgctaatttattctcaaggcaaattgggaattatcgatacctgtataccataaggtcgctcgatgtgatgcttatgtcttctggtgatcctaccttagttagtgctgattaacggaacattaatgtttatcgttttgagatttagccaattctctgattctaactcaagatgccttatctgacgtgctatgcagcccctaagtattttacattgtaataggacacgctcctttaaaactcgccaaaaggtcgttgtggttctctactggttaactatataatttacagctttgttgagctagttcctctttggtttaagtcctcaatattagttggttcgagcgataagttggctagttaccttagtcactatattagatccgaatgttatgcttcatctgaagaccgccaccctccaaaatttcttttaagactcacttattgcaaggtgtaggtgaattcggctcgtttctcaagtggtgtatctgtacacgagtttccatattttcatcaacagccaccgcacacttatgtcactctaggtattaaaagtcgctctacaaggggacgcaattaagaaacagacatgctagtcaaaaataaacatagcgaggcaccactaattcggccgcttatcaatgggatgctctgcgcgagacgcgccagagctcagtagttagttcggacatacatttacttcagatgatcaattagttttctacaaatgcttactctaccccgaaaaaagtcaccagactcttacgtctctttagtatccttccgtcttatataaggtcagtcccccgtttcggtaccctggaatttactaagaataatgaaacagcccccaaggacgtacgtttacaaatgatagaccagatcgcctagcttattccgacgcatgttgcatagaattgaaccaacggaatgtgagagtaactagatgagccgaccacagcacccgtttgcgtcgcagaatacgcctgatagttcggccacgaaatcatatgtcctttgagtattaagtatttgtaatgatcaatcgagctcaagcaagcttacacttcctcggatattcagggaacttagtgcctttgaaagatacgttgatcaacgaaaaattgataatggctcatatggaatgcctacctcatagtgctgaattaacacagcactgcggacctaacttttcgaggtttcaagttcacgtctcaaaacctaataggctggaatatgtagggatcctcggtgaatttgtgattgggtttgttgtagtactgaccaagtgaatattctttttttctaaaagcagatctgctgccgggcactacgaaggagatctctgtgtatcattattgcttcttgacatgatgactcttaaatcactgtgggtgtgcaaaacgatagcacaacccaattcgatagtacatattgttgatacttcgcactaaaccgttcatatttaaaggttgtgctccttccttcgttaaatactggtgacttggtcctatctactattagctagacctctggggaaccacgcccccgtaaaacctgtgcaagagagggggtcatacatcttagacatcgcgcctccaccagggaagcattgggtgattgaccaggtgtgtaacaaatatgattattcttatactaatattagcaaagatgcataatgatttgtattaaatgtataattgaattgataagggtcttttagtcagtgatagagtagtataaggtagacattagaactcttaaccggacgcagatttttcggtcttagtaagccaattagtcgacaaaacaaggtaagagcggttactagtagtacctataatgcactgaatcttcggtcgaagtatagttctaatgctatgcagattgtgacggcgacaaatgttcagacttatatcatgaaacaagctcttgtaagtattgacaaatgaaaagattgaatatttttaaatacaaaatgcgcctacttattaggggaattaaccagattgaaggccaatcctcacatgtaatgagataatagacgataaatgaaattcttgtaatagttgaactgctacgtgatgggtattatatatgattgagatcctccaattgccgacgtcttgtcttgatgcccaaaagattgtcaacgaggagctccctcgcgtacctgtcgtccgtatcataaacgacgcgacatgtacagcactccgaagtataagcaataataatgcgggtaatccagactagatcttttcggactcaatgcggtttcacggtaaacatgattaataccggagagtagtcgagcttatcagcgatgcaagcgaattcattgtgccaggagatacgttgcagataaaaccggcaacgtatgtcaacaagttttggcgatctcgttgtttgtattcgacgaggcgcgggaacttcaagaactatcgtatattcaagtccattaccttttagtttcagactggtggagctgactaaagttatatcatcattttgtacactggtttagttaacgataatttcagatttaacatgaccagacgataatcgctgtatatccagttggaatgtggtttgccagaaaggttaacttataatcaagcctctcttcagtcttgattcgtcgtatcccatccattgcgctatacctcagtgtatttggagctgtagttataccgtgtgctaagatcagtagacatgacgagagcaatattatctaccttacaagcatcaacggacgtctagtcggaacaaaagactctaaaactcgaacttcaggttaatatactatagttctgtattcagcagttattcttatattcgatattatcttgcctattggatgtctgactttagtatattaatcatagtatctgccatgtaaaggtgccagtactaaatctgtttcacagtgcgaattataaacggttacaaccattaaagacaacaagaccctatagctttatttgaattttgtcaatgcgcaacttggagctcgcgatacatcccaattagtctatagggtcgggacgattctacggcatttctggttataatgacaacatggattgtggcccgagaatcgctctttcattaattaagcaatcattacagtcttataagcgctacttccgagtggtagcaggtaactcgatataaggtcgcatgagccgaatagcttaaaaaacaggccaccgaacattgatagagaataccgaccacagcgcaacctttgattactttcattaaattgtacggctcactcgacatcaagcttaagattgcgataatgtgaactcaaatggatcagtactgaagaaccgtaacccacttcgcagaaagcgtacccagagaagatacgctgttacaatatacagggtgaaattattgcctgttcttcgtaaccatttcgccaaacttggttagaaatgatagccattcatgatagaaataagctgaatgataccagtatctttaactatgtagtcagggggaagataacgatggtccatgtatgtttctgatatgtgacagtattggccgcgtaatttgctaacgaagctacttaatgcctttgagcttcatatagatttctttaatcaaaatcggcaaaaagatagtatgagctataatatatgctagtagagaactctggaccatcatctatatgaatactgattcgagcgtgcaattactttagcctgcgtactactgactctacaaaacactctgagataagtttgtagtcagtaagtcgctctctataaaccttttggatgaccattgtacagccacttatagatcccaataaatagcacaggagacagagtttttcaatgctcgatcatttgccgatagtattttcgtctaacctcagggcacctattatttgatacctaacctaacggccctttcacaatggagaaatatatgacatcgggacaaacacaaatggtgggtggccaggagatatgacatggtggcgtctctaagaaacacggactccctctaggcaaactcacgtaaccaattttaatgtcaaacaaaacgctcgaaaagattttgccgtgtaatgacctggtacattgactggtcaggaatacatcactgtagttgccgtagtgtcctgttggtgttccatcaagacacatcgtataacgcaatttacgacggacatcagatcaagttatacagattatttaagtatcacgtgtgcattgggacataagggatctcacacatgccttggaacatttttgctttgtgccgctttttcgctgcactaccaatccttacttaccagtatattcaaaggtcgttaacagaatgagaaaggttagggctctaagttatcgtcgattgggatagacgagacatttgcgagcgccctccacggatacgaatctcccatatcaatgtgaactggatgctatgcagtttagttcttacgtctcctagtggtaaaaatcaaagtagcactcgcatagcagttattcagaacctaatacacaaaaccgtcaaacattttctaattctaggtatgggccgatcataggagctaaggtgaaactcataaatgttttgttagatctagcatcctaaaaagatgcatatactgagtagctggcgtgcattctctcaattgtatcctttttaactgaactagtcggtcccatttcgtgactgagatctattaaccgataagattaataacactcgcattcgtatcagctcagagtgaagtttttcaataatttgactgatatattaacttctaaaataaccctttaagcctcggatccgtttcccaatcacatcaaaaattcttattccaactatctacggattaacaacgtgcatggggatcgtagtaagaacttgttccgatcactttgagtatatcaagttgacggcccggttattattgaatagaaacattcacctgctaaattaaataccgcacatcggatacccgatttcagagggccgtcttactaagggcaggctttgttcggtttaactgagatgttcattattttacagtatgcttcaactaatatgtaacgaaggacagtggatctgtctccatagtagatcttcagtcgtgaatttcataccgctcctatttaagttcgcgttcgagttgttgatcatggcacgtgaaagcaacccctagtattctagacgaaaattttttctagttcatctgataatttgccaattcaaaaacaaccgctggtttcccggcgcattctctaaaatggaagtcgaacctagagccattatttgtcggtaacccatgagttccttcttttcagaagttaatacactgtggtcctatacagaggaaaaacagcggttatatacgatcgtggcataacaacattggatcaagatagcaatttggctacctattctaattctcactagattcggtattccactacaatatcggcagattaggattggatgaataatcggtgtttaagtccggttgcgtctccaatctcctaatttttattaatattgatcttggtgacctattgtaaataaaaacttcaagactttgaataacggtgaaaagatagaagactcatttgaaaatggatcatccacagatccaaacattagcaagacactaatccccaactagctattctgatcgcgatcgtgctgcagtactcctgtcacaatagtctgttcatgatctaattctttttgggctttgttcgatggtgattcagaatctttatccggtcgcttccctgtagctactttgtggggatattgcccggggattatagggttgagatcgtttcctaaaagtatttaaaccaagtagacttcaactaaactacatcagaacatcgtgaagacaccatacgcggtacctttatttaccgataacatttcttcaagaaataccggtaagcagcataatgaccctaaacagctcggggtatcgtcgtagttttaaattttatttaggttactgctcaaggaataaaaactaactatttaatttataataatattacaaggctcacactgattagatttgtctataagacttcgcgatcccccattaccggattgtcttaagaataaactagataaaccatgcattttctagataaggcctttagtctaattagatacaaaaaacacgatagttgcatccttaatttattgtgtcaaacctggaaccttttaattacccgcaaatcactttatgtcgagactacctctgaaatttattatctacctaccgcatgaggacttgaaccatcttgtaggagttatgtttattagctaagattcgtttatcctgtagcggtccatgtatattcaacaagcaaaaagcactcagaattgtttttagttgagtcaagactgatatataaataagtttccctagttttttcgtggtgggacgatattgaattgaatcttaaccgaagagtttcccactctgtcgcacaataatacacgccaatatttccagccctgcttatgccttaatcggttactcaatctcccattgaagttcattttgatctgcatagaagtttcgggcccagccttttttctgccaccttcctccaagctctgtagacgcactctaagattgatgctcacatgtattaattctacattaacataaatatataagtcatgcatcttcgagtaaaatatctggttctccaacatgtcctggcacgtatcgttataatgcccatacatgtagtattaaaatgattgggttaactggatattaagatcatcgaaattgtaaagtcaaattaacaatactgtctcaagaccgtgtattcctcgtgctcggaagggctattacgcttacttccgttttggtatcttaatatgactttcaaaaattaagttgcagtgagtcctacctgcgtgcatcggttagcaagagtataaaagttgtttaaacgaactacttgctttacaataccggtcgtatatatcgccgtgaatccagaagattgtcttctttggattatcaaccgagatcctgtggaccgatgttttgggaccttcacagaggactccaggtagagctcgcttttgcattaatctaagaattgtacctctctaaaagatctaaaacagtgaatgtgtatttcatggaaaaacacagagaaacgtaaattactttaggccgaaaggcacatgagttattatacatatacgagatggtggtatacatcgaattcggggcatacactatagttgcattgtatttagctgctttaaataatatgatattaccttccttacataagacattaccggcataccctggttttcaacttgtggggctttttgacgatcgcactctcatttgatccgagtagggcggtgacccctgcttttcaaatacaaaaatttcgctatgaaggtaatagattacttttcgctgttatgatagaaacggtaaatttaaaattgaaacttctagaaaagtaaagtaacgagaaatgattttgtgaataatgcggtcatgattgcgcaagtaagaaaaaaaggcaaaaggatgcgcggaatagaaacttatcagtcacgggtatcttgatttcattcttcttgtcaattgccgacataggatgaaatcagattccaatgcaatacacagtaacccccacccttgattgtaatgtcgatttgaagttgtacgcgtcgacgaagtggatagtatacgggccttttgtacggtgcgatcaactatgaatctcggcgagttagatggtcgtacaatctcacacatagaggtcacttgcctgtaatgacgaattttcggctaggtactcgaactttattagaagtaaaaatgtgggcaaaagaaggattccattttacaagacgattacaatgagttacatgtctctcaacgtagtctttccctagtagtctttgaactatttaggtactccagaaaattttagcaaagggtttctgtgtgaatccgccattcatgtttatgatggaacaataagaataacgccctcgtatgttatcgacagtgaagtcagcagttcggccaaaaacatattcaatttagtacagatccccagaagttaagctaagtgctctaaaatggcctaaacggttatcaaagtaggtctaattactatactaacgggtgcatcgtaataactgctgtcgatgcaacactatatgatagtgtcgttttgctatatatgtacaatgtgacaaagaagccttagcgattcttgcaaacttaggacttcggattctcaatcttaaatgtccgaaaacgcaaagattcaaaaatttaatctatgagcagatatgcctgatggtgactacgcgtatgttaaggctaaatgttgacaaccgcacacataatcgaactattgatagtcgggagcataaccaggtgaacgtactttgttcacgacatttattgacatgttctaaatacgtctcaaaatcacggcgcactagaaaacgcaatcaaatcattgtcctggtttaagggccgtaatgccggtagtgtcaaacttcatgagaactttagctggcttttggccagtatttagggaccaagagcactagccttaagctgaatattttgccatttatctactgttataactttaaaacttggtggcaccagacttgtcgatacacacgcatcaatctgtaacgtaaaaggtttactaagaacaagcgtaggaattgagtttatattatatttaaactaaaagatgatattagcttctgagggcgatagggctccaaatcataaagaggaatatattattacacgattagaaacccacaacatacctcgaatcgcccaaaagtttgacgaaacttggcagtactccacatctcagtaatacagttgggagagtctcaaatgttgttttattactcaatgaaccaccctcataatttcactgctgttccattaaatttgcaaacgatcatttgctttgaagaaacgtaaaatcgacaaaattacagataagtagatgcataataaaaaaaactgctcgctataacacgatcatcgtgcattcttacttaggagcatcacccgcacaataacgtaccttaaactacaacactattagaccgagtactgtaattcacgaaagctcaagctcgcattgtaaagaacttgctctctcgtaaaatgtgataatagtttgcggagaggattcaattattttccattgcacctactccactagattcgataaaagaaggtggtcctcccttaaaaagaaatgttaagtaacatcggaaccataagcaaagcatgtaagtgaaccgtcatccttccctaagaaacataaaggtttttaataatgtcgactgtgaactataactgcatcctttcctgacctactccggttccttgttgttatttctgaacgagaccagtagataaacaatgtaaaccacagtgggtaccaatggtgcatgtgacgctaccgttgttttaagtgcccgtacaaacataagaagtcataatcttacttgaaattaattttgccttttattttttttcaggctcgaaattaatgatttgttttttttgaccttctagttacgctaatatgcggtcgcctgtggtttctattgagtcctataacgggatgggatctaatacgtttggttactagtaaacaaggtataaatttgataccggagtatcaactgtataacatcaagctttatgactcatacgcgaagtaatgacacaaggctttcaggagatcgcgagtacagagccactaaggggtgtattacgatagtgacaccaccgagcgcactcactccccaagtagatttatgatcctacgctaagtattagatatataaccaaagaggttctagtcagtgcaactcttagaataataattagccggttttgcctttttaggcctaatgcaatattcagctagcccttatgtatctcgcgttccacagcaccactcatggcacgcgtttaaactaatcaaatataatctatgaatgttatgccagtacttgaataaatcaggttttttataagtccttgcatactctcgttatatactgttagagtcttaccccatagaaattctttcatctgcaaacttagaagaattctcagctacggggagcataaagtccccaggatgttgacaaatacaacaaatgtggcttatacaaacactccatatgaaaatcgaaccctcgtggtagttttagccgaaccttgtacggataaatccctccattttccaatagcagatacctatcctactacctcgtggtattaaattaaagcttgaaatatagagctgcatagcttatccaattcccaagcacgagtctaccgtcgtaaccacgatttgatttacagacgctagagcaaacccatctttaaacatataagtaaaaattaaagggtgagtgcgtacgtgtttactagcaacttcgcttattaagacaattgtttataagccataattaaaaacatatgttcaacaggttcattgatatttgtaattgcacaggtttttaataaggatctacgtaagtataatgaacaaactttttaccagagttatattctgtactttgaaaatgctcctctaccgccttagagactttcaattagattttttgcagttaatctatgcgtaagtgaaccatgcaagggatgcgattcaaccgcctcgtgctaaccctatcgtctgtctcataactgtaggtctaatataattttcagttttcgaacacataaccctttgaaaatctgctatttaatgtctcacctgcatgcactatcttctatactgctcagaacggctatacgtcactatgctccaagtgacgatttaaacgaagcaaggaataataggtttattttagtgcaaaacaattaagtgcggactacgtgctctttacaataagccttgtgattgggctataggttaagtcccatattaacgatctccaatgtacaaaatcgacaatcgctttgcattacccggttactagtcgaattacagatagctgttagatactcactctaattttggacaacaatcccaatcttggggtcgtctatcgcctgaagctcgtaaatccttccatcttaaacgattacatattatagacttgttcggggtagagatatcacagttgtgcaaacattgtaaatcgatactagtttatgttggtagtctagttgcttttaccattccccgaaaaacttgatctactatttcgacaacagtaaacttgaactaggtaagtgaaaacagagaatgcctcatagtgccactatttgtccactatatgtaagtgtagctttacataatccactatgactgagatcattacggcctaggaaagcagcgtagaaaaaaagggcccggatattacgactgtaactataaaactagttactggtagcgcgccatgtatagatttgttttaccggttgtggttgcgttaacgaatttcagccgcgaaaattgatccgttaaccagtccatctcgacttctataaaacgataaagtaaagttgatgttcagcctccttcttatggttgcatcgagagtacactactcagtgggaaatagatcggggttcctacttcagattgtattatctaggcaattgccgattgtgccatacctggataaaataagctacctacatgtgatgcttatctattatcgtcatactaccttagggtgtcctgttgaacgctacattaatctttagccgtttgagatgttccaatggataggagtctaacgcatgatgaagtttaggaaggcagagcatcccactaagtatgtgacagtgtatttcgaaacgagacgttataaatagaaaaaaggtccttctggttctattctgctgaactattgaatggaaagattggttgacctacgtactatttgcttgaagtcatcaatttgacggggtgagagacatatggtgcatactttacggactctatattttagatcagaagcttagcagtcttctctacaccccctcacgacataattgcttttaagaatctatgtttgattcctctacgggaattcggatccgttcgcatgtgcggtttatctaaaccaggggacatatgttcagctaaagcatacgaacactttgctaactagacgtatgtatagtagctataaatcccgacgatatttacaaaaagaaatgagactcaaatatatacatagcgaccctacacttattcgcaccctgatctaggcgatcctagcacccacacccgaaagtgagcactagtgtcttccgtattaaatttactgcagttgagattttagttgtctactaaggattactctaacccgtaataaggatcaagactcggtactagctttactatcattccctatgtgttttcctaactcacaagggtacgtaccagcctatgtaattacaataatgataaagacacaaaggaagtaactttacaaatgagtctccagttacactagcttagtccctcccatcttgctttgaagtctaaatacgcaatctctgaggatatacagcagaagaacactcataacgttggagtccaagaattagactcatagggcccccaacatttaatatgtactgtgagtttgaaggtgttctattgttaattcctgctcttgatacatgacacgtactccgtgtttaaggcttcggactgactttctttcataagttgagcaacgaaaatttcagaatcgataagttggattcactaactaatacggctgattgaaaactccactccggacctatatggtcgacctttatacgtaaccgatataaaacttataggctggtatatcgagccttcctagcgcaatttcggatggggtttcttctactactcaacaacggaatagtctttgtttagtaaaccagagctcaggacgcccaatacgtaggagagcgctgtggagcatgtgtcattatggactggagcactcttaaatcactctgcgtgtgctaaacgatagatcataacatgtcctgagtaaattttcttgatacgtcgcaatataccgttattagttaaacgttctcatccgtcatgcgtgaaatacggctgtcgtgctcagatatactattagcgactcatctcgcctaacacgcacacgtataaactcggaatgactgccgctcttacatattagaaatacagactacaccacggaagcattgggtcattctcaaccgctgtataaaagatgattagtcttataataagattaccaaagaggcagaatcatgggtagtaaatctattattcaagtgattaccgtcgtgtaggcagggagtgaggacgagatggtactcaggacaaatattaaccggacgaagtggtttacgtcgtactttcactattagtagtaaatacaaggtaacaccggggaatagtactaaatataatgatatctatcttcgggagaacgagtcgtctattgctttgaacattctcaaggcgtaaaatgtgctgacttatagcatgatacaaccgattgttacttttgtctattcaaaagattgaatagttttttatacaaaagccgcatacttatgacggctagtatacagtttcatcccctagcatcaatgctatggacagtattgaacttataggaaattcttctaatagggcaaatccgtcgtgatgcctattttttttcagtcacatcctcaaatggcactagtattgtcgggatcccattaacaggctcaaccacgagctcacgcgaggacatgtagtccgtatctttaacgaagcgacagcgacagaactcccatggataaccaattataaggcccgtaatcctctagacatcgtttaccaataaatccgctttctccgtaatcatgttgaataccccagagtagtccagatgataaccgatgaaacacaagtctttctcaatgcacttacggtgaacttattaccgccaacgtagctcatcaaggttgcgacatctagttgtgtgtttgcgacgagcccagcgaacttcatcaactttcgtatattcaacgccttgtaattttactttaagacgcctggtgatgtagattcttagataatcagtttgttatcggctgtactttaccataatttcacaggtttcaggtcaagaagattatagctgtatatacagttccatgctcggtgcacagaaacgtgatcggataataatcaatcgcttatgtcgtctttaggcgtatccaatacatgccccgataccgcagtgtatttcgacatgtaggtataccgtcgcatttgagctcgagtcaggacgtcagctagattagattccttaatagaatataccgacctctagtccgaactaaactatagataacgccaacttcaggttaattgtctagtcgtctgtttgcagatgggattcttagatgagtgagtatcggccatattggttcgagcactttagtttttgatgcataggatatgcaatgtatagctgaaagtactttatctgtttcaaactcacattgattaaaccggtaaacctttaaagactacaagaaaatattcagtgagggcaattttgtcaatcacaatcttccagctagagatacttcacaatttgtcttgaggctacgcaacattagacggattttcgcgttttattgaaataatcgaggggcccaagagtatccatagttcattttgtaagatttctttacaggcttattacagcttcttcagactcctacatgcttacgagttatatgctagcatgtgaacaatagattaatatacaggaaaacgtacattgagagagatgaccctacacagcgcaaccgttgagtactttcattaaagggtaacgctctcgagacagcatccttaagatggccttattgtcaaatcatttgcagaagtacgcaagatccctaaccaacgtagaagaatccctacaaacacatgagacgcggtgaaaatagacagggtgttagtattcaatcttcggagtatcaatttcgccaatcttggtgagaaagcataccctttcttcagagaaagaagatcaatcataacactatctttaacgaggtacgcacgcgcatcattacctgcctccatggatctttaggatagcggaaagtattggcagcgtattgtgatttcgttcctactttatcaatttcacattcatatacatgtcttttatcaaaatcgccaataagataggatgagctatattagatgctagtagagttcgcgccaacatcatcgataggaatactcaggacagcgtgataggacttttcaatccctaatactctctataattataactctctcttaagtttggaggcagtaacgcgctctatataatcagtttgctgcaccattcttcagcctctgatacatacaaataaattccacagcagtaagagggtttaattgagacatcttgggaacttaggattttactctaacatcaccgaaacgattattggataccgtacctaaacgaactttctcaaggcagtaatataggacatccgcaataacacaaatgctgcctccccaggagttatgtcttcctggaggctatatcttacacccactcactataggcaaactaaagtttaaatgttgattgtctaaaaaaaagatagataagagttggccggcgtagcacatgcgaaagtgaatcgtaagctataattctctggacttgaagttctgtcctgttcctctgcaagaaacaaacttcctttaaagctatttacgacgcacatctcagcaagttataaacatgttggaagtttctagtcggaattcccaaagaacggatctatctaatgcattcctacatttttcctgtctgccgatggtgccatcctattcaaagaatttcttaaaagtagattaaatgggacttttaacaatgagtaaccttacgcctctaagggttcctcgagtgccatacaccagtcaggtccgagccacatacacggagaacattctaacatagcattctcaactcgatcatttgcaggttacttctttcctatcctagtgctaaaaatcatacttgcaatcccatagcacggattaagaacctaagaaacaattcagtaaaacatgttcgaattcttggtatgggaacatcattgcagctatggtctaacgcattaatgtttgggtacatcttccatcatataaacaggaagagtctgacgacagggagtgcttgcgatcatgtctatcattgtgaaatcaaattgtagctcacatgtcgtctatgagagcgtgtatccgataagatttagaaaaatagaagtcgtataagatctcactgaacttttgaatgaatgtgaagcatatatgatctgctttaataaaactttatccataggatacgtttccaaatcaattcaataattattagtcaaaatagataaggatgaacaacctgaaggccgatcggacgtagaaagtggtcccatcactttgagttgatattgttgaaccacacgttattatggttttcaaacagtctcaggatattgtatatacagataatccgataccagttgtctgacgcccctcttacgtaccccaccctttgtgacgtttaaagcagttgttcagtattttaaactaggcggcaactaatttggaaagaagcacagtggatatgtctaaattcttgttattcaggcctgaatttaatacaccgcatagttaacttcgcggtagagttgttcatcatgcctcctctaagctaccacttctatgatacaccaatagttgttctacggaatctgataattggccaagtcataaacttccgctgcgttcaacccccttgctcgaatatccaactcgaaaagacagccttttggtgtccggaacaaatcagttacttcttttctgatgttaattctctgtggtcagatacagaccaaaaactccgcggatttaccatcctccaagaacaaatttgcatcaacatagcattttggctacatattctaagtctcaatagtttaggttttcaactacattatcccaacattaggattggaggaataatagctgggtaagtccccttgcgtctacaatcgactattttttatgaatatgcttctgccgcacctatggttattaaaaaagtcatgactttgaagaaccctgaaaagatagatgaatcaggtgtaatggcagcagccaaagagcatataattagcaacactctaagaacattatagatatgatgatagcgatcgtcatgatgttatccggtcacaatagtagcttcatcagctaattcgttttgccagtggtgacttgcgctggaagaatcgttatacggtcccttccctcttgatacggtgggggcttattcaaccgcgtggattgggttgtcatacttgcattaaacgatgtaaaccatctagtagtcaactatactaaatcacaaaatagtgatcaatacatacccgcttcatggttttaaccatttaattgattaaagatattccgctaagaaccattatctacctaaactgatcgccgtatcctagtagtttgaaatttgatgtaccgtaatgatcaacgaagtaaaacgttatattgtatgtagaataataggtcttggagctaaatgatgtgattggtagtgaagacttacccttacaactttaccggtttctcggaagaatatactagagaatcaatgcatgggctacataagcactttagtctaatgagataaaaaatacacgagtcttccatcatgaattttttgtcgaaaaactcgaacctggtaatttaaaccatatatctttatgtcgtcaataactctcatatgttttatataacttcccaatcacgacttgtaactgcttgttcgactgagctgtttgagctatgaggccgggatccggttgagctacatctatttgctacaagaaaaatgaaagcacatttgttgggagttctggctacactcatagagaaataagtggcccgagtgggtgcggcctgcctccatattcaagtgtatcttaaaccaagtggttccaacgctcgcgctaaagaattaaagcctttatttcctccacggagtagcccgtaatccggttcgaaagagaccattgaagttaattttcatatccagtgaagtttaggcacaagcatgtgttctgccacatgcctcaaagcgctcttcaaccaagatatgattcatcctaacttcgatgaatgcgtctgtaacataaatatagaaggaatgattcggcgagttaattttcgccttctccaacatggcatccctacgttcgttataaggaccatacatgtaggttttaaaggtttgcggttaatcgatatttacatcatagaaattctatagtcaaatttacaagactctagatactcactcgttgcagccggctaggaagcgctttgtaccttacttcccttttcgttgcgtaatatgaatttcatatagtaagttcaaggcactcatacctccgtgaagagggtagatagactattaaagttgtttaatagtacgtattgatggaaatgacccgtaggagatttaccactcaatccacaagattcgctgctgtgcattatcaaaacagtgcatgtcgaaacatgggttgggtccttcaaacacgaatccaggtagagatacctttgcaattttt"; + +if (dnaOutputString != expectedDNAOutputString) + throw "ERROR: bad result: expected " + JSON.stringify(expectedDNAOutputString) + " but got " + JSON.stringify(dnaOutputString); + +if (dnaInput != expectedDNAInput) + throw "ERROR: bad result: expected " + JSON.stringify(expectedDNAInput) + " but got " + JSON.stringify(dnaInput); diff --git a/Jint.Tests.CommonScripts/Scripts/string-base64.js b/Jint.Tests.CommonScripts/Scripts/string-base64.js new file mode 100644 index 0000000000..3125258964 --- /dev/null +++ b/Jint.Tests.CommonScripts/Scripts/string-base64.js @@ -0,0 +1,137 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla XML-RPC Client component. + * + * The Initial Developer of the Original Code is + * Digital Creations 2, Inc. + * Portions created by the Initial Developer are Copyright (C) 2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Martijn Pieters (original author) + * Samuel Sieb + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// From: http://lxr.mozilla.org/mozilla/source/extensions/xml-rpc/src/nsXmlRpcClient.js#956 + +/* Convert data (an array of integers) to a Base64 string. */ +var toBase64Table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; +var base64Pad = '='; + +function toBase64(data) { + var result = ''; + var length = data.length; + var i; + // Convert every three bytes to 4 ascii characters. + for (i = 0; i < (length - 2); i += 3) { + result += toBase64Table[data.charCodeAt(i) >> 2]; + result += toBase64Table[((data.charCodeAt(i) & 0x03) << 4) + (data.charCodeAt(i+1) >> 4)]; + result += toBase64Table[((data.charCodeAt(i+1) & 0x0f) << 2) + (data.charCodeAt(i+2) >> 6)]; + result += toBase64Table[data.charCodeAt(i+2) & 0x3f]; + } + + // Convert the remaining 1 or 2 bytes, pad out to 4 characters. + if (length%3) { + i = length - (length%3); + result += toBase64Table[data.charCodeAt(i) >> 2]; + if ((length%3) == 2) { + result += toBase64Table[((data.charCodeAt(i) & 0x03) << 4) + (data.charCodeAt(i+1) >> 4)]; + result += toBase64Table[(data.charCodeAt(i+1) & 0x0f) << 2]; + result += base64Pad; + } else { + result += toBase64Table[(data.charCodeAt(i) & 0x03) << 4]; + result += base64Pad + base64Pad; + } + } + + return result; +} + +/* Convert Base64 data to a string */ +var toBinaryTable = [ + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, + 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, + 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, + -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, + 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 +]; + +function base64ToString(data) { + var result = ''; + var leftbits = 0; // number of bits decoded, but yet to be appended + var leftdata = 0; // bits decoded, but yet to be appended + + // Convert one by one. + for (var i = 0; i < data.length; i++) { + var c = toBinaryTable[data.charCodeAt(i) & 0x7f]; + var padding = (data.charCodeAt(i) == base64Pad.charCodeAt(0)); + // Skip illegal characters and whitespace + if (c == -1) continue; + + // Collect data into leftdata, update bitcount + leftdata = (leftdata << 6) | c; + leftbits += 6; + + // If we have 8 or more bits, append 8 bits to the result + if (leftbits >= 8) { + leftbits -= 8; + // Append if not padding. + if (!padding) + result += String.fromCharCode((leftdata >> leftbits) & 0xff); + leftdata &= (1 << leftbits) - 1; + } + } + + // If there are any bits left, the base64 string was corrupted + if (leftbits) + throw Components.Exception('Corrupted base64 string'); + + return result; +} + +var str = ""; + +for ( var i = 0; i < 8192; i++ ) + str += String.fromCharCode( (25 * Math.random()) + 97 ); + +for ( var i = 8192; i <= 16384; i *= 2 ) { + + var base64; + + base64 = toBase64(str); + var encoded = base64ToString(base64); + if (encoded != str) + throw "ERROR: bad result: expected " + str + " but got " + encoded; + + // Double the string + str += str; +} + +toBinaryTable = null; diff --git a/Jint.Tests.CommonScripts/Scripts/string-fasta.js b/Jint.Tests.CommonScripts/Scripts/string-fasta.js new file mode 100644 index 0000000000..c8a1ccb1b7 --- /dev/null +++ b/Jint.Tests.CommonScripts/Scripts/string-fasta.js @@ -0,0 +1,90 @@ +// The Great Computer Language Shootout +// http://shootout.alioth.debian.org +// +// Contributed by Ian Osgood + +var last = 42, A = 3877, C = 29573, M = 139968; + +function rand(max) { + last = (last * A + C) % M; + return max * last / M; +} + +var ALU = + "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG" + + "GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA" + + "CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT" + + "ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA" + + "GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG" + + "AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC" + + "AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA"; + +var IUB = { + a:0.27, c:0.12, g:0.12, t:0.27, + B:0.02, D:0.02, H:0.02, K:0.02, + M:0.02, N:0.02, R:0.02, S:0.02, + V:0.02, W:0.02, Y:0.02 +} + +var HomoSap = { + a: 0.3029549426680, + c: 0.1979883004921, + g: 0.1975473066391, + t: 0.3015094502008 +} + +function makeCumulative(table) { + var last = null; + for (var c in table) { + if (last) table[c] += table[last]; + last = c; + } +} + +function fastaRepeat(n, seq) { + var seqi = 0, lenOut = 60; + while (n>0) { + if (n0) { + if (n= 0x7f) { + validates = false; + break; + } + } + + if (!validates) + continue; + + var url = "http://example.com/tag/" + tag.replace(" ", "").toLowerCase(); + var popularity = tagInfo[i].popularity; + var color = 'rgb(' + Math.floor(255 * (popularity - 12) / 20) + ', 0, 255)'; + output += ' ' + tag + ' \n'; + } + + output += ''; + output.replace(" ", " "); + + return output; +} + +var tagcloud = makeTagCloud(tagInfo); + +var expectedMinLength = 315000; + +if (tagcloud.length < expectedMinLength) + throw "ERROR: bad result: expected length at least " + expectedMinLength + " but got " + tagcloud.length; + +tagInfo = null; diff --git a/Jint.Tests.CommonScripts/Scripts/string-unpack-code.js b/Jint.Tests.CommonScripts/Scripts/string-unpack-code.js new file mode 100644 index 0000000000..0447c1807c --- /dev/null +++ b/Jint.Tests.CommonScripts/Scripts/string-unpack-code.js @@ -0,0 +1,81 @@ +// This test case unpacks the compressed code for the MochiKit, +// jQuery, Dojo and Prototype JavaScript libraries. + +/*** + MochiKit.MochiKit 1.3.1 : PACKED VERSION + THIS FILE IS AUTOMATICALLY GENERATED. If creating patches, please + diff against the source tree, not this file. + + See for documentation, downloads, license, etc. + + (c) 2005 Bob Ippolito. All rights Reserved. +***/ + +var result = 0; + +for (var i = 0; i < 2; i++) { + +var decompressedMochiKit = function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('if(H(1q)!="L"){1q.2X("B.J")}if(H(B)=="L"){B={}}if(H(B.J)=="L"){B.J={}}B.J.1Y="1.3.1";B.J.1r="B.J";B.J.2l=G(7V,vR){if(7V===O){7V={}}R(u i=1;i=0;i--){aw.e9(o[i])}}N{X.1c(o)}}F X},1R:G(7U,1i,av){if(!av){av=0}if(1i){u l=1i.K;if(H(l)!="2y"){if(H(B.15)!="L"){1i=B.15.2G(1i);l=1i.K}N{14 Y 3p("au 2E an at-as 3W B.15 2E ar")}}if(!7U){7U=[]}R(u i=av;i>b},vG:G(a,b){F a>>>b},eq:G(a,b){F a==b},ne:G(a,b){F a!=b},gt:G(a,b){F a>b},ge:G(a,b){F a>=b},lt:G(a,b){F al){7T=l}}69=[];R(i=0;i<7T;i++){u fa=[];R(u j=1;j0){ap=m.2o(me.am,ap)}u 4o=me.f7;if(!4o){4o=D}F me.f5.1w(4o,ap)};7Q.f7=f6;7Q.f5=ao;7Q.am=5f;F 7Q},lF:G(7P){u mp=B.J.1O;R(u k in 7P){u f4=7P[k];if(H(f4)=="G"){7P[k]=mp(f4,7P)}}},5u:G(mo,mn,ml,mk){B.J.ae.5M(mo,mn,ml,mk)},mj:{"5L":1h,"1n":1h,"2y":1h},2f:G(a,b){if(a==b){F 0}u f3=(H(a)=="L"||a===O);u f2=(H(b)=="L"||b===O);if(f3&&f2){F 0}N{if(f3){F-1}N{if(f2){F 1}}}u m=B.J;u f1=m.mj;if(!(H(a)in f1&&H(b)in f1)){1f{F m.ae.3C(a,b)}1e(e){if(e!=m.4d){14 e}}}if(ab){F 1}}u f0=m.U;14 Y 3p(f0(a)+" 3W "+f0(b)+" 9v 2E be vv")},eM:G(a,b){F B.J.2f(a.9P(),b.9P())},eL:G(a,b){u mi=B.J.2f;u 7O=a.K;u al=0;if(7O>b.K){al=1;7O=b.K}N{if(7O0))){u kv=B.S.d5(3s);3s=kv[0];68=kv[1]}N{if(M.K==1){u o=3s;3s=[];68=[];R(u k in o){u v=o[k];if(H(v)!="G"){3s.1c(k);68.1c(v)}}}}u W=[];u lT=28.2a(3s.K,68.K);u eT=B.J.af;R(u i=0;i=2J){14 I.25}5c+=3a;F W}}},4c:G(aa,p,q){u m=B.J;u I=B.15;u lb=m.2r(I.1Q,m.1R(O,M,1));u 2r=m.2r;u 1a=I.1a;F{U:G(){F"4c(...)"},1l:m.24("U"),1a:G(){F aa.1w(D,2r(1a,lb))}}},ep:G(aa,1V,I){1V=B.15.1Q(1V);u m=B.J;F{U:G(){F"ep(...)"},1l:m.24("U"),1a:G(){F aa.1w(I,1V.1a())}}},55:G(p,q){u I=B.15;u m=B.J;if(M.K==1){F I.1Q(M[0])}u 64=m.2r(I.1Q,M);F{U:G(){F"55(...)"},1l:m.24("U"),1a:G(){1M(64.K>1){1f{F 64[0].1a()}1e(e){if(e!=I.25){14 e}64.2P()}}if(64.K==1){u a9=64.2P();D.1a=m.1O("1a",a9);F D.1a()}14 I.25}}},9Z:G(3b,1V){u I=B.15;1V=I.1Q(1V);F{U:G(){F"9Z(...)"},1l:B.J.24("U"),1a:G(){u W=1V.1a();if(!3b(W)){D.1a=G(){14 I.25};D.1a()}F W}}},eo:G(3b,1V){1V=B.15.1Q(1V);u m=B.J;u 1O=m.1O;F{"U":G(){F"eo(...)"},"1l":m.24("U"),"1a":G(){1M(1h){u W=1V.1a();if(!3b(W)){2K}}D.1a=1O("1a",1V);F W}}},a7:G(63,2u,la){2u.62[63]=-1;u m=B.J;u l9=m.eI;F{U:G(){F"en("+63+", ...)"},1l:m.24("U"),1a:G(){u W;u i=2u.62[63];if(i==2u.29){W=la.1a();2u.a8.1c(W);2u.29+=1;2u.62[63]+=1}N{W=2u.a8[i-2u.2a];2u.62[63]+=1;if(i==2u.2a&&l9(2u.62)!=2u.2a){2u.2a+=1;2u.a8.2P()}}F W}}},en:G(a6,n){u W=[];u 2u={"62":[],"a8":[],"29":-1,"2a":-1};if(M.K==1){n=2}u I=B.15;a6=I.1Q(a6);u a7=I.a7;R(u i=0;i0&&4k>=2J)||(3a<0&&4k<=2J)){14 B.15.25}u W=4k;4k+=3a;F W},U:G(){F"7I("+[4k,2J,3a].2b(", ")+")"},1l:B.J.24("U")}},l0:G(a5,l7){u x=l7||0;u I=B.15;a5=I.1Q(a5);1f{1M(1h){x+=a5.1a()}}1e(e){if(e!=I.25){14 e}}F x},em:G(a4){u I=B.15;a4=I.1Q(a4);1f{1M(1h){a4.1a()}}1e(e){if(e!=I.25){14 e}}},9a:G(7J,1A,I){u m=B.J;if(M.K>2){1A=m.1O(1A,I)}if(m.3A(7J)){1f{R(u i=0;i<7J.K;i++){1A(7J[i])}}1e(e){if(e!=B.15.25){14 e}}}N{I=B.15;I.em(I.4c(1A,7J))}},kZ:G(l6,1A){u I=B.15;1f{I.a0(1A,l6).1a();F 1m}1e(e){if(e!=I.25){14 e}F 1h}},kY:G(l5,4j){u W=B.15.2G(l5);if(M.K==1){4j=B.J.2f}W.iz(4j);F W},kX:G(l4){u W=B.15.2G(l4);W.vg();F W},kW:G(l3,1A){u I=B.15;1f{I.a1(1A,l3).1a();F 1h}1e(e){if(e!=I.25){14 e}F 1m}},kV:G(1g,5b){if(B.J.3A(5b)){R(u i=0;i<5b.K;i++){1g.1c(5b[i])}}N{u I=B.15;5b=I.1Q(5b);1f{1M(1h){1g.1c(5b.1a())}}1e(e){if(e!=I.25){14 e}}}F 1g},ek:G(a3,eH){u m=B.J;u I=B.15;if(M.K<2){eH=m.4i.eE}a3=I.1Q(a3);u pk=L;u k=L;u v;G eF(){v=a3.1a();k=eH(v)}G l2(){u 7j=v;v=L;F 7j}u eG=1h;F{U:G(){F"ek(...)"},1a:G(){1M(k==pk){eF();if(eG){eG=1m;2K}}pk=k;F[k,{1a:G(){if(v==L){eF()}if(k!=pk){14 I.25}F l2()}}]}}},kU:G(a2,eD){u m=B.J;u I=B.15;if(M.K<2){eD=m.4i.eE}a2=I.1Q(a2);u ey=[];u eA=1h;u ez;1M(1h){1f{u eB=a2.1a();u 2h=eD(eB)}1e(e){if(e==I.25){2K}14 e}if(eA||2h!=ez){u eC=[];ey.1c([2h,eC])}eC.1c(eB);eA=1m;ez=2h}F ey},9X:G(ex){u i=0;F{U:G(){F"9X(...)"},1l:B.J.24("U"),1a:G(){if(i>=ex.K){14 B.15.25}F ex[i++]}}},eh:G(ew){F(ew&&H(ew.ei)=="G")},9V:G(l1){F{U:G(){F"9V(...)"},1l:B.J.24("U"),1a:G(){u W=l1.ei();if(W===O||W===L){14 B.15.25}F W}}}});B.15.1W=["9Y","9X","eh","9V",];B.15.1z=["25","9W","1Q","eu","et","7b","1a","es","a1","a0","er","4c","ep","55","9Z","eo","en","2G","7H","7I","l0","em","9a","kZ","kY","kX","kW","kV","ek","kU"];B.15.2d=G(){u m=B.J;D.25=Y m.5a("25");D.9Y=Y m.4a();D.9W("ej",m.3A,D.9X);D.9W("ei",D.eh,D.9V);D.2k={":3e":D.1z,":1p":m.2o(D.1z,D.1W)};m.3f(D)};B.15.2d();if(!B.3d){7H=B.15.7H}B.J.2Y(D,B.15);if(H(1q)!="L"){1q.2X("B.1H");1q.2M("B.J")}if(H(1x)!="L"){1x.26("B.J",[])}1f{if(H(B.J)=="L"){14""}}1e(e){14"B.1H 3F on B.J!"}if(H(B.1H)=="L"){B.1H={}}B.1H.1r="B.1H";B.1H.1Y="1.3.1";B.1H.1K=G(){F"["+D.1r+" "+D.1Y+"]"};B.1H.1l=G(){F D.1K()};B.1H.1z=["5C","49","7A","kR","2L","5Z","kG","ch","kE","kC"];B.1H.1W=["ef","e8","e7"];B.1H.49=G(1P,kT,3z){D.1P=1P;D.3N=kT;D.3z=3z;D.vf=Y 3Q()};B.1H.49.1U={U:G(){u m=B.J;F"49("+m.2r(m.U,[D.1P,D.3N,D.3z]).2b(", ")+")"},1l:B.J.24("U")};B.J.2l(B.1H,{ef:G(7F){u I=B.1H;if(H(7F)=="1n"){7F=I.5C[7F]}F G(1t){u 7G=1t.3N;if(H(7G)=="1n"){7G=I.5C[7G]}F 7G>=7F}},e8:G(){u kS=B.1H.49;R(u i=0;i=0&&D.4h.K>D.ec){D.4h.2P()}},c8:G(9U){u ea=0;if(!(H(9U)=="L"||9U===O)){ea=28.29(0,D.4h.K-9U)}F D.4h.9T(ea)},kJ:G(7B){if(H(7B)=="L"||7B===O){7B=30}u 9S=D.c8(7B);if(9S.K){u 1g=2r(G(m){F"\\n ["+m.1P+"] "+m.3N+": "+m.3z.2b(" ")},9S);1g.e9("va "+9S.K+" v9:");F 1g.2b("")}F""},v8:G(kI){if(H(B.1I)=="L"){cq(D.kJ())}N{B.1I.bY(kI||1m)}}};B.1H.2d=G(){D.5C={8M:40,8L:50,8K:30,8J:20,8I:10};u m=B.J;m.5u("49",D.e8,D.e7);u 61=m.2z;u e6=D.7A;u 60=e6.1U.kH;m.2l(D.7A.1U,{kF:61(60,"8I"),5Z:61(60,"8J"),dE:61(60,"8M"),kD:61(60,"8L"),kB:61(60,"8K")});u I=D;u 5Y=G(1b){F G(){I.2L[1b].1w(I.2L,M)}};D.5Z=5Y("5Z");D.kG=5Y("dE");D.ch=5Y("kF");D.kE=5Y("kD");D.kC=5Y("kB");D.2L=Y e6();D.2L.e5=1h;D.2k={":3e":D.1z,":1p":m.2o(D.1z,D.1W)};m.3f(D)};if(H(5X)=="L"&&H(2v)!="L"&&2v.kA&&H(kz)!="L"){5X=G(){5X.3G=M;u ev=2v.kA("v7");ev.v6("5X",1m,1h);kz(ev)}}B.1H.2d();B.J.2Y(D,B.1H);if(H(1q)!="L"){1q.2X("B.1D")}if(H(B)=="L"){B={}}if(H(B.1D)=="L"){B.1D={}}B.1D.1r="B.1D";B.1D.1Y="1.3.1";B.1D.1K=G(){F"["+D.1r+" "+D.1Y+"]"};B.1D.1l=G(){F D.1K()};B.1D.ks=G(1y){1y=1y+"";if(H(1y)!="1n"||1y.K===0){F O}u 7z=1y.2R("-");if(7z.K===0){F O}F Y 3Q(7z[0],7z[1]-1,7z[2])};B.1D.ky=/(\\d{4,})(?:-(\\d{1,2})(?:-(\\d{1,2})(?:[T ](\\d{1,2}):(\\d{1,2})(?::(\\d{1,2})(?:\\.(\\d+))?)?(?:(Z)|([+-])(\\d{1,2})(?::(\\d{1,2}))?)?)?)?)?/;B.1D.kr=G(1y){1y=1y+"";if(H(1y)!="1n"||1y.K===0){F O}u X=1y.3C(B.1D.ky);if(H(X)=="L"||X===O){F O}u 5W,7y,7x,9R,2a,9Q,7w;5W=3w(X[1],10);if(H(X[2])=="L"||X[2]===""){F Y 3Q(5W)}7y=3w(X[2],10)-1;7x=3w(X[3],10);if(H(X[4])=="L"||X[4]===""){F Y 3Q(5W,7y,7x)}9R=3w(X[4],10);2a=3w(X[5],10);9Q=(H(X[6])!="L"&&X[6]!=="")?3w(X[6],10):0;if(H(X[7])!="L"&&X[7]!==""){7w=28.ha(c5*4M("0."+X[7]))}N{7w=0}if((H(X[8])=="L"||X[8]==="")&&(H(X[9])=="L"||X[9]==="")){F Y 3Q(5W,7y,7x,9R,2a,9Q,7w)}u 58;if(H(X[9])!="L"&&X[9]!==""){58=3w(X[10],10)*v5;if(H(X[11])!="L"&&X[11]!==""){58+=3w(X[11],10)*kw}if(X[9]=="-"){58=-58}}N{58=0}F Y 3Q(3Q.v4(5W,7y,7x,9R,2a,9Q,7w)-58)};B.1D.dY=G(2g,kx){if(H(2g)=="L"||2g===O){F O}u hh=2g.v3();u mm=2g.v2();u ss=2g.v1();u 1g=[((kx&&(hh<10))?"0"+hh:hh),((mm<10)?"0"+mm:mm),((ss<10)?"0"+ss:ss)];F 1g.2b(":")};B.1D.kq=G(2g,7v){if(H(2g)=="L"||2g===O){F O}u ku=7v?"T":" ";u kt=7v?"Z":"";if(7v){2g=Y 3Q(2g.9P()+(2g.v0()*kw))}F B.1D.dX(2g)+ku+B.1D.dY(2g,7v)+kt};B.1D.dX=G(2g){if(H(2g)=="L"||2g===O){F O}u e4=B.1D.e3;F[2g.dZ(),e4(2g.e1()+1),e4(2g.e0())].2b("-")};B.1D.kp=G(d){d=d+"";if(H(d)!="1n"||d.K===0){F O}u a=d.2R("/");F Y 3Q(a[2],a[0]-1,a[1])};B.1D.e3=G(n){F(n>9)?n:"0"+n};B.1D.ko=G(d){if(H(d)=="L"||d===O){F O}u e2=B.1D.e3;F[e2(d.e1()+1),e2(d.e0()),d.dZ()].2b("/")};B.1D.kn=G(d){if(H(d)=="L"||d===O){F O}F[d.e1()+1,d.e0(),d.dZ()].2b("/")};B.1D.1z=["ks","kr","dY","kq","dX","kp","ko","kn"];B.1D.1W=[];B.1D.2k={":3e":B.1D.1z,":1p":B.1D.1z};B.1D.2d=G(){u 2w=D.1r+".";R(u k in D){u o=D[k];if(H(o)=="G"&&H(o.1r)=="L"){1f{o.1r=2w+k}1e(e){}}}};B.1D.2d();if(H(B.J)!="L"){B.J.2Y(D,B.1D)}N{(G(km,dW){if((H(1x)=="L"&&H(1q)=="L")||(H(B.3d)=="5L"&&B.3d)){u 1p=dW.2k[":1p"];R(u i=0;i<1p.K;i++){km[1p[i]]=dW[1p[i]]}}})(D,B.1D)}if(H(1q)!="L"){1q.2X("B.1s")}if(H(B)=="L"){B={}}if(H(B.1s)=="L"){B.1s={}}B.1s.1r="B.1s";B.1s.1Y="1.3.1";B.1s.1K=G(){F"["+D.1r+" "+D.1Y+"]"};B.1s.1l=G(){F D.1K()};B.1s.ke=G(kl,kk,kj,ki,kh,dV,kg,9N,kf){F G(1P){1P=4M(1P);if(H(1P)=="L"||1P===O||k8(1P)){F kl}u 9L=kk;u 9K=kj;if(1P<0){1P=-1P}N{9L=9L.23(/-/,"")}u me=M.2U;u 9M=B.1s.dJ(ki);if(kh){1P=1P*3k;9K=9M.9y+9K}1P=B.1s.dK(1P,dV);u 9O=1P.2R(/\\./);u 3r=9O[0];u 3P=(9O.K==1)?"":9O[1];u X="";1M(3r.K9N){u i=3r.K-9N;X=9M.9A+3r.2W(i,3r.K)+X;3r=3r.2W(0,i)}}X=3r+X;if(dV>0){1M(3P.K=0)){D.9u()}},jR:G(X){D.9x(X);D.jX()},9x:G(X){D.2H=((X 2C 2x)?1:0);D.53[D.2H]=X;D.9u()},dD:G(){if(D.2H!=-1){if(!D.7l){14 Y B.1k.dj(D)}D.7l=1m;F}},3o:G(X){D.dD();if(X 2C B.1k.2t){14 Y 2x("2t jW 9v aB be 7r if jV jU jT jS of a 3o")}D.9x(X)},52:G(X){D.dD();u I=B.1k;if(X 2C I.2t){14 Y 2x("2t jW 9v aB be 7r if jV jU jT jS of a 3o")}if(!(X 2C 2x)){X=Y I.9p(X)}D.9x(X)},jP:G(fn){if(M.K>1){fn=B.J.2z.1w(O,M)}F D.9w(fn,fn)},5Q:G(fn){if(M.K>1){fn=B.J.2z.1w(O,M)}F D.9w(fn,O)},jA:G(fn){if(M.K>1){fn=B.J.2z.1w(O,M)}F D.9w(O,fn)},9w:G(cb,eb){if(D.7r){14 Y 2x("uQ uP 9v 2E be re-uO")}D.55.1c([cb,eb]);if(D.2H>=0){D.9u()}F D},9u:G(){u dC=D.55;u 56=D.2H;u X=D.53[56];u I=D;u cb=O;1M(dC.K>0&&D.54===0){u 2n=dC.2P();u f=2n[56];if(f===O){2V}1f{X=f(X);56=((X 2C 2x)?1:0);if(X 2C B.1k.2t){cb=G(X){I.jR(X)};D.jQ()}}1e(3O){56=1;if(!(3O 2C 2x)){3O=Y B.1k.9p(3O)}X=3O}}D.2H=56;D.53[56]=X;if(cb&&D.54){X.jP(cb);X.7r=1h}}};B.J.2l(B.1k,{dk:G(){F dB("("+M[0].jN+")")},dp:G(uN){u d=Y B.1k.2t();d.3o.1w(d,M);F d},9q:G(uM){u d=Y B.1k.2t();d.52.1w(d,M);F d},do:G(){u I=M.2U;if(!I.7q){u dy=[G(){F Y 7q()},G(){F Y dA("jO.dz")},G(){F Y dA("uL.dz")},G(){F Y dA("jO.dz.4.0")},G(){14 Y B.1k.dh("uK uJ 2E uI 7q")}];R(u i=0;i1){u m=B.J;u qs=m.dw.1w(O,m.1R(O,M,1));if(qs){5F+="?"+qs}}2s.cp("uB",5F,1h);F I.dl(2s)},jv:G(5F){u I=B.1k;u d=I.dn.1w(I,M);d=d.5Q(I.dk);F d},dm:G(jJ,dv){u d=Y B.1k.2t();u m=B.J;if(H(dv)!="L"){d.5Q(G(){F dv})}u jI=uA(m.1O("3o",d),28.8B(jJ*c5));d.7m=G(){1f{uz(jI)}1e(e){}};F d},ju:G(jH,1A){u m=B.J;u jG=m.2z.1w(m,m.1R(O,M,1));F B.1k.dm(jH).5Q(G(X){F jG()})}});B.1k.5O=G(){D.5S=[];D.4e=1m;D.id=D.7n()};B.1k.5O.1U={bX:B.1k.5O,uy:G(){d=Y B.1k.2t();if(D.4e){D.5S.1c(d)}N{D.4e=1h;d.3o(D)}F d},jF:G(){if(!D.4e){14 3p("ux to jF an jE 5O")}D.4e=1m;if(D.5S.K>0){D.4e=1h;D.5S.2P().3o(D)}},7n:B.J.4f(),U:G(){u 9t;if(D.4e){9t="4e, "+D.5S.K+" 5S"}N{9t="jE"}F"5O("+D.id+", "+9t+")"},1l:B.J.24("U")};B.1k.7i=G(2G,du,jC,jB,jD){D.2G=2G;D.9r=Y 7o(D.2G.K);D.55=[];D.id=D.7n();D.2H=-1;D.54=0;D.53=[O,O];D.7m=jD;D.7l=1m;if(D.2G.K===0&&!du){D.3o(D.9r)}D.dr=0;D.jz=du;D.jy=jC;D.jx=jB;u 9s=0;B.J.2r(B.J.1O(G(d){d.5Q(B.J.1O(D.dt,D),9s,1h);d.jA(B.J.1O(D.dt,D),9s,1m);9s+=1},D),D.2G)};B.J.2l(B.1k.7i.1U,B.1k.2t.1U);B.J.2l(B.1k.7i.1U,{dt:G(ds,7k,5R){D.9r[ds]=[7k,5R];D.dr+=1;if(D.2H!==0){if(7k&&D.jz){D.3o([ds,5R])}N{if(!7k&&D.jy){D.52(5R)}N{if(D.dr==D.2G.K){D.3o(D.9r)}}}}if(!7k&&D.jx){5R=O}F 5R}});B.1k.jt=G(jw){u d=Y B.1k.7i(jw,1m,1h,1m);d.5Q(G(dq){u 7j=[];R(u i=0;i=0){u 9m=Q.1S[Q.j4];7d.1c(1b);7c.1c((9m.3m)?9m.3m:9m.7X);F O}7d.1c(1b);7c.1c("");F O}if(4Y=="cu"||4Y=="P"||4Y=="8d"||4Y=="6m"){F Q.5h}7d.1c(1b);7c.1c(Q.3m||"");F O}F Q.5h});F[7d,7c]},94:G(1N,1A){u I=B.S;u d3=I.1Z;u W;1f{I.1Z=1N;W=1A()}1e(e){I.1Z=d3;14 e}I.1Z=d3;F W},j3:G(1b,j2,3y,j1){B.S.9b.5M(1b,j2,3y,j1)},9k:G(1j,7a){u im=B.15;u I=B.S;u 1Q=im.1Q;u iY=im.7b;u 4c=im.4c;u iX=I.9b;u iZ=I.9k;u iW=B.J.4d;1M(1h){if(H(1j)=="L"||1j===O){F O}if(H(1j.3T)!="L"&&1j.3T>0){F 1j}if(H(1j)=="2y"||H(1j)=="5L"){1j=1j.1l()}if(H(1j)=="1n"){F I.1Z.4S(1j)}if(H(1j.j0)=="G"){1j=1j.j0(7a);2V}if(H(1j)=="G"){1j=1j(7a);2V}u 9l=O;1f{9l=1Q(1j)}1e(e){}if(9l){F 4c(iZ,9l,iY(7a))}1f{1j=iX.3C(1j,7a);2V}1e(e){if(e!=iW){14 e}}F I.1Z.4S(1j.1l())}F L},iV:G(1j,79,iU){u o={};o[79]=iU;1f{F B.S.4X(1j,o)}1e(e){}F O},iT:G(1j,79){u I=B.S;u d2=I.4U.99[79];1j=I.1E(1j);1f{if(d2){F 1j[d2]}F 1j.fm(79)}1e(e){}F O},4X:G(1j,5K){u Q=1j;u I=B.S;if(H(1j)=="1n"){Q=I.1E(1j)}if(5K){u d0=B.J.8Z;if(I.4U.6X){R(u k in 5K){u v=5K[k];if(H(v)=="3n"&&H(Q[k])=="3n"){d0(Q[k],v)}N{if(k.2W(0,2)=="on"){if(H(v)=="1n"){v=Y cZ(v)}Q[k]=v}N{Q.4p(k,v)}}}}N{u iS=I.4U.99;R(k in 5K){v=5K[k];u d1=iS[k];if(k=="1T"&&H(v)=="1n"){Q.1T.3x=v}N{if(H(d1)=="1n"){Q[d1]=v}N{if(H(Q[k])=="3n"&&H(v)=="3n"){d0(Q[k],v)}N{if(k.2W(0,2)=="on"){if(H(v)=="1n"){v=Y cZ(v)}Q[k]=v}N{Q.4p(k,v)}}}}}}}F Q},9j:G(1j){u Q=1j;u I=B.S;if(H(1j)=="1n"){Q=I.1E(1j)}u 78=[I.9k(B.J.1R(O,M,1),Q)];u iR=B.J.2o;1M(78.K){u n=78.2P();if(H(n)=="L"||n===O){}N{if(H(n.3T)=="2y"){Q.2c(n)}N{78=iR(n,78)}}}F Q},iQ:G(1j){u Q=1j;u I=B.S;if(H(1j)=="1n"){Q=I.1E(1j);M[0]=Q}u cY;1M((cY=Q.6n)){Q.6S(cY)}if(M.K<2){F Q}N{F I.9j.1w(D,M)}},cX:G(1b,4b){u Q;u I=B.S;u m=B.J;if(H(4b)=="1n"||H(4b)=="2y"){u 3G=m.1R([1b,O],M,1);F M.2U.1w(D,3G)}if(H(1b)=="1n"){if(4b&&"1b"in 4b&&!I.4U.6X){1b=("<"+1b+" 1b=\\""+I.9c(4b.1b)+"\\">")}Q=I.1Z.2S(1b)}N{Q=1b}if(4b){I.4X(Q,4b)}if(M.K<=2){F Q}N{u 3G=m.1R([Q],M,2);F I.9j.1w(D,3G)}},cw:G(){u m=B.J;F m.2z.1w(D,m.1R([B.S.cX],M))},cs:G(5J,1d){u I=B.S;5J=I.1E(5J);u cW=5J.3t;if(1d){1d=I.1E(1d);cW.uj(1d,5J)}N{cW.6S(5J)}F 1d},1E:G(id){u I=B.S;if(M.K==1){F((H(id)=="1n")?I.1Z.hN(id):id)}N{F B.J.2r(I.1E,M)}},4q:G(iP,cV,cU){if(M.K==2){cU=cV}u I=B.S;u el=I.1E(iP);u 77=I.1Z;if(!el||el==77){F L}if(el.iO){F el.iO[cV]}if(H(77.5k)=="L"){F L}if(77.5k===O){F L}u 9i=77.5k.g4(el,O);if(H(9i)=="L"||9i===O){F L}F 9i.6q(cU)},aH:G(76,9g,4W){u I=B.S;if(H(76)=="L"||76===O){76="*"}if(H(4W)=="L"||4W===O){4W=I.1Z}4W=I.1E(4W);u 9h=(4W.fr(76)||I.1Z.1p);if(H(9g)=="L"||9g===O){F B.J.1R(O,9h)}u cR=[];R(u i=0;i<9h.K;i++){u cS=9h[i];u cT=cS.3M.2R(" ");R(u j=0;j/g,">")},iB:G(2q){F B.S.cG(2q).2b("")},cG:G(2q,1g){if(H(1g)=="L"||1g===O){1g=[]}u 70=[2q];u I=B.S;u cB=I.9c;u iA=I.4U;1M(70.K){2q=70.hP();if(H(2q)=="1n"){1g.1c(2q)}N{if(2q.3T==1){1g.1c("<"+2q.cD.8G());u 71=[];u cF=iA(2q);R(u i=0;i");70.1c("");u cC=2q.5h;R(i=cC.K-1;i>=0;i--){70.1c(cC[i])}}N{1g.1c("/>")}}N{if(2q.3T==3){1g.1c(cB(2q.iv))}}}}F 1g},97:G(ix,cA){u m=B.J;u iy=m.1R(O,M,1);B.15.9a(m.47(O,m.2r(B.S.1E,iy)),G(cA){cA.1T.3u=ix})},iw:G(1j,iu){u W=[];(G(1j){u cn=1j.5h;if(cn){R(u i=0;i0){u it=m.47;2T=G(1j){F it(2T.ir,1j.6Y)};2T.cx={};B.15.9a(6Z.6Y,G(a){2T.cx[a.1b]=a.3m});2T.ir=G(a){F(2T.cx[a.1b]!=a.3m)};2T.6X=1m;2T.99={"iq":"3M","ip":"ud","uc":"ub","R":"u9"}}N{2T=G(1j){F 1j.6Y};2T.6X=1h;2T.99={}}D.4U=2T;u 1C=D.cw;D.io=1C("ul");D.il=1C("ol");D.ik=1C("li");D.ij=1C("td");D.cm=1C("tr");D.ii=1C("u8");D.ih=1C("u7");D.ig=1C("u6");D.ie=1C("u5");D.ic=1C("th");D.cv=1C("ck");D.8d=1C("cj");D.A=1C("a");D.6m=1C("4u");D.ib=1C("u4");D.ia=1C("2e");D.i9=1C("tt");D.i8=1C("4O");D.i7=1C("h1");D.i6=1C("h2");D.i5=1C("h3");D.i4=1C("br");D.i3=1C("hr");D.i2=1C("u3");D.i1=1C("u2");D.cu=1C("u1");D.P=1C("p");D.ct=1C("u0");D.i0=1C("hJ");D.hZ=1C("tZ");D.hY=1C("tY");D.hX=1C("tX");D.hW=1C("tW");D.hV=1C("tV");D.hU=m.2z(D.97,"98");D.hT=m.2z(D.97,"8c");D.hS=D.cs;D.$=D.1E;D.2k={":3e":D.1z,":1p":m.2o(D.1z,D.1W)};m.3f(D)}});B.S.2d(((H(2O)=="L")?D:2O));if(!B.3d){95=B.S.95;94=B.S.94}B.J.2Y(D,B.S);if(H(1q)!="L"){1q.2X("B.1I");1q.2M("B.1H");1q.2M("B.J")}if(H(1x)!="L"){1x.26("B.1H",[]);1x.26("B.J",[])}1f{if(H(B.J)=="L"||H(B.1H)=="L"){14""}}1e(e){14"B.1I 3F on B.J 3W B.1H!"}if(H(B.1I)=="L"){B.1I={}}B.1I.1r="B.1I";B.1I.1Y="1.3.1";B.1I.1K=G(){F"["+D.1r+" "+D.1Y+"]"};B.1I.1l=G(){F D.1K()};B.1I.bY=G(6W){u m=B.1I;6W=!(!6W);if(m.3l&&m.3l.8Q!=6W){m.3l.hA();m.3l=O}if(!m.3l||m.3l.8P){m.3l=Y m.1I(6W,B.1H.2L)}F m.3l};B.1I.1I=G(4R,6V){if(H(6V)=="L"||6V===O){6V=B.1H.2L}D.2L=6V;u tU=B.J.2l;u c3=B.J.8Z;u 1O=B.J.1O;u hM=B.J.4L;u 2m=2O;u 6U="tT";if(H(B.S)!="L"){2m=B.S.cr()}if(!4R){u 5F=2m.tS.tR.2R("?")[0].23(/[:\\/.><&]/g,"hR");u 1b=6U+"hR"+5F;u 5D=2m.cp("",1b,"tQ,tP,3V=hQ");if(!5D){cq("tO tN to cp tM 2O tL to hP-up tK.");F L}5D.2v.fl(""+"<5E><8Y>[B.1I]"+"<5s>");5D.2v.hG();5D.2v.8Y+=" "+2m.2v.8Y;2m=5D}u 1N=2m.2v;D.1N=1N;u 21=1N.hN(6U);u c4=!!21;if(21&&H(21.5B)!="L"){21.5B.2L=D.2L;21.5B.6K();F 21.5B}if(c4){u cl;1M((cl=21.6n)){21.6S(cl)}}N{21=1N.2S("4u");21.id=6U}21.5B=D;u 8T=1N.2S("ck");u 8S=1N.2S("ck");u 6O=1N.2S("2e");u 6N=1N.2S("2e");u 6M=1N.2S("2e");u 6L=1N.2S("2e");u 3L=1N.2S("4u");u 42=1N.2S("4u");u 8U=6U+"tz";D.8N=hM(D.8N);u 4T=[];u 6R=O;u cf=G(1t){u 6T=1t.3N;if(H(6T)=="2y"){6T=B.1H.5C[6T]}F 6T};u cd=G(1t){F 1t.3z.2b(" ")};u ca=1O(G(1t){u 8W=cf(1t);u 7X=cd(1t);u c=D.8N[8W];u p=1N.2S("cj");p.3M="B-49 B-5C-"+8W;p.1T.3x="ty: 2N; 4F-8X: -hL-4O-3y; 4F-8X: -o-4O-3y; 4F-8X: 4O-3y; 4F-8X: 4O-tx; hK-3y: 2K-hK; 3y-hJ: tw; 3U: "+c;p.2c(1N.4S(8W+": "+7X));42.2c(p);42.2c(1N.2S("br"));if(3L.ci>3L.hI){3L.4C=0}N{3L.4C=3L.hI}},D);u hD=G(1t){4T[4T.K]=1t;ca(1t)};u hF=G(){u cg,ce;1f{cg=Y 8V(8T.3m);ce=Y 8V(8S.3m)}1e(e){ch("2x in 47 tv: "+e.43);F O}F G(1t){F(cg.hH(cf(1t))&&ce.hH(cd(1t)))}};u cc=G(){1M(42.6n){42.6S(42.6n)}};u hB=G(){4T=[];cc()};u bZ=1O(G(){if(D.8P){F}D.8P=1h;if(B.1I.3l==D){B.1I.3l=O}D.2L.c9(8U);21.5B=O;if(4R){21.3t.6S(21)}N{D.2m.hG()}},D);u c7=G(){cc();R(u i=0;i<4T.K;i++){u 1t=4T[i];if(6R===O||6R(1t)){ca(1t)}}};D.6K=G(){6R=hF();c7();D.2L.c9(8U);D.2L.hE(8U,6R,hD)};u c0=1O(G(){4T=D.2L.c8();c7()},D);u c2=1O(G(6Q){6Q=6Q||2O.6D;2h=6Q.6w||6Q.8t;if(2h==13){D.6K()}},D);u 31="3u: 8c; z-c6: c5; 2I: 2N; 6f: 2N; 6P: tu; 5A: 3k%; he-3U: 4F; c1: "+D.8O;if(4R){31+="; 3V: ts; 3E-3D: fO 8a 8y"}N{31+="; 3V: 3k%;"}21.1T.3x=31;if(!c4){1N.5s.2c(21)}31={"3x":"5A: 33%; 3u: 8Q; c1: "+D.8O};c3(8T,{"3m":"8L|8M|8K|8J|8I","hC":c2,"1T":31});21.2c(8T);c3(8S,{"3m":".*","hC":c2,"1T":31});21.2c(8S);31="5A: 8%; 3u:8Q; c1: "+D.8O;6O.2c(1N.4S("tq"));6O.8R=1O("6K",D);6O.1T.3x=31;21.2c(6O);6N.2c(1N.4S("tp"));6N.8R=c0;6N.1T.3x=31;21.2c(6N);6M.2c(1N.4S("tn"));6M.8R=hB;6M.1T.3x=31;21.2c(6M);6L.2c(1N.4S("tm"));6L.8R=bZ;6L.1T.3x=31;21.2c(6L);3L.1T.3x="fS: tk; 5A: 3k%";42.1T.3x="5A: 3k%; 3V: "+(4R?"tj":"3k%");3L.2c(42);21.2c(3L);D.6K();c0();if(4R){D.2m=L}N{D.2m=2m}D.8Q=4R;D.hA=bZ;D.8P=1m;F D};B.1I.1I.1U={"8O":"ti tg,tf-te","8N":{"8M":"1v","8L":"gU","8K":"1F","8J":"8y","8I":"bx"}};B.1I.1W=["1I"];B.1I.1z=["bY"];B.1I.2d=G(){D.2k={":3e":D.1z,":1p":B.J.2o(D.1z,D.1W)};B.J.3f(D);B.1I.3l=O};B.1I.2d();B.J.2Y(D,B.1I);if(H(1q)!="L"){1q.2X("B.V");1q.2M("B.J")}if(H(1x)!="L"){1x.26("B.J",[])}1f{if(H(B.J)=="L"){14""}}1e(e){14"B.V 3F on B.J"}if(H(B.V)=="L"){B.V={}}B.V.1r="B.V";B.V.1Y="1.3.1";B.V.1K=G(){F"["+D.1r+" "+D.1Y+"]"};B.V.1l=G(){F D.1K()};B.V.V=G(1v,hz,1F,6J){if(H(6J)=="L"||6J===O){6J=1}D.1B={r:1v,g:hz,b:1F,a:6J}};B.V.V.1U={bX:B.V.V,tc:G(hy){u 1B=D.1B;u m=B.V;F m.V.3Y(1B.r,1B.g,1B.b,hy)},tb:G(1o){u 1G=D.41();1G.h=1o;u m=B.V;F m.V.4H(1G)},ta:G(hx){u 1G=D.41();1G.s=hx;u m=B.V;F m.V.4H(1G)},t9:G(hw){u 1G=D.41();1G.l=hw;u m=B.V;F m.V.4H(1G)},t8:G(hv){u 1G=D.41();1G.l=28.29(1G.l-hv,0);u m=B.V;F m.V.4H(1G)},t7:G(hu){u 1G=D.41();1G.l=28.2a(1G.l+hu,1);u m=B.V;F m.V.4H(1G)},fJ:G(ht,5z){if(H(5z)=="L"||5z===O){5z=0.5}u sf=1-5z;u s=D.1B;u d=ht.1B;u df=5z;F B.V.V.3Y((s.r*sf)+(d.r*df),(s.g*sf)+(d.g*df),(s.b*sf)+(d.b*df),(s.a*sf)+(d.a*df))},h4:G(hs){u a=D.6r();u b=hs.6r();F B.J.2f([a.r,a.g,a.b,a.a],[b.r,b.g,b.b,b.a])},hq:G(){F D.41().b>0.5},t6:G(){F(!D.hq())},t5:G(){u c=D.41();u 2Z=B.V.6F;u W=D.ho;if(!W){u 5y=(2Z(c.h,bF).6I(0)+","+2Z(c.s,3k).hp(4)+"%"+","+2Z(c.l,3k).hp(4)+"%");u a=c.a;if(a>=1){a=1;W="1G("+5y+")"}N{if(a<=0){a=0}W="t4("+5y+","+a+")"}D.ho=W}F W},hl:G(){u c=D.1B;u 2Z=B.V.6F;u W=D.hn;if(!W){u 5y=(2Z(c.r,3h).6I(0)+","+2Z(c.g,3h).6I(0)+","+2Z(c.b,3h).6I(0));if(c.a!=1){W="t3("+5y+","+c.a+")"}N{W="1B("+5y+")"}D.hn=W}F W},6r:G(){F B.J.4L(D.1B)},t2:G(){u m=B.V;u c=D.1B;u 2Z=B.V.6F;u W=D.hm;if(!W){W=("#"+m.6E(2Z(c.r,3h))+m.6E(2Z(c.g,3h))+m.6E(2Z(c.b,3h)));D.hm=W}F W},t1:G(){u 2Q=D.2Q;u c=D.1B;if(H(2Q)=="L"||2Q===O){2Q=B.V.bA(D.1B);D.2Q=2Q}F B.J.4L(2Q)},41:G(){u 1G=D.1G;u c=D.1B;if(H(1G)=="L"||1G===O){1G=B.V.bC(D.1B);D.1G=1G}F B.J.4L(1G)},1l:G(){F D.hl()},U:G(){u c=D.1B;u hk=[c.r,c.g,c.b,c.a];F D.bX.1r+"("+hk.2b(", ")+")"}};B.J.2l(B.V.V,{3Y:G(1v,bW,1F,8H){u hj=B.V.V;if(M.K==1){u 1B=1v;1v=1B.r;bW=1B.g;1F=1B.b;if(H(1B.a)=="L"){8H=L}N{8H=1B.a}}F Y hj(1v,bW,1F,8H)},4H:G(1o,t0,sZ,sY){u m=B.V;F m.V.3Y(m.bB.1w(m,M))},sX:G(1o,sW,sV,sU){u m=B.V;F m.V.3Y(m.bz.1w(m,M))},hi:G(1b){u 8F=B.V.V;if(1b.3Z(0)=="\\""){1b=1b.3H(1,1b.K-2)}u bV=8F.by[1b.8G()];if(H(bV)=="1n"){F 8F.bT(bV)}N{if(1b=="aP"){F 8F.sT()}}F O},8f:G(4Q){u I=B.V.V;u bU=4Q.3H(0,3);if(bU=="1B"){F I.h9(4Q)}N{if(bU=="1G"){F I.h8(4Q)}N{if(4Q.3Z(0)=="#"){F I.bT(4Q)}}}F I.hi(4Q)},bT:G(4P){if(4P.3Z(0)=="#"){4P=4P.2W(1)}u 8E=[];u i,5x;if(4P.K==3){R(i=0;i<3;i++){5x=4P.3H(i,1);8E.1c(3w(5x+5x,16)/3h)}}N{R(i=0;i<6;i+=2){5x=4P.3H(i,2);8E.1c(3w(5x,16)/3h)}}u bS=B.V.V;F bS.3Y.1w(bS,8E)},bG:G(4O,hf,hg,4N){if(4N.2A(4O)===0){4N=4N.2W(4N.2A("(",3)+1,4N.K-1)}u bR=4N.2R(/\\s*,\\s*/);u bP=[];R(u i=0;i0){F 8D}}F O},ba:G(Q){u 2F=B.V.V;F 2F.bN(Q,"aZ","he-3U")||2F.sN()},sM:G(Q){u 2F=B.V.V;F 2F.bN(Q,"3U","3U")||2F.sL()},sK:G(){F B.J.4L(B.V.V.by)}});B.J.2l(B.V,{6F:G(v,8C){v*=8C;if(v<0){F 0}N{if(v>8C){F 8C}N{F v}}},hc:G(n1,n2,1o){if(1o>6){1o-=6}N{if(1o<0){1o+=6}}u 2i;if(1o<1){2i=n1+(n2-n1)*1o}N{if(1o<3){2i=n2}N{if(1o<4){2i=n1+(n2-n1)*(4-1o)}N{2i=n1}}}F 2i},bz:G(1o,5w,3i,bM){if(M.K==1){u 2Q=1o;1o=2Q.h;5w=2Q.s;3i=2Q.v;bM=2Q.a}u 1v;u 3K;u 1F;if(5w===0){1v=0;3K=0;1F=0}N{u i=28.8B(1o*6);u f=(1o*6)-i;u p=3i*(1-5w);u q=3i*(1-(5w*f));u t=3i*(1-(5w*(1-f)));hd(i){3j 1:1v=q;3K=3i;1F=p;2K;3j 2:1v=p;3K=3i;1F=t;2K;3j 3:1v=p;3K=q;1F=3i;2K;3j 4:1v=t;3K=p;1F=3i;2K;3j 5:1v=3i;3K=p;1F=q;2K;3j 6:3j 0:1v=3i;3K=t;1F=p;2K}}F{r:1v,g:3K,b:1F,a:bM}},bB:G(1o,5v,3v,bL){if(M.K==1){u 1G=1o;1o=1G.h;5v=1G.s;3v=1G.l;bL=1G.a}u 1v;u 8A;u 1F;if(5v===0){1v=3v;8A=3v;1F=3v}N{u m2;if(3v<=0.5){m2=3v*(1+5v)}N{m2=3v+5v-(3v*5v)}u m1=(2*3v)-m2;u f=B.V.hc;u h6=1o*6;1v=f(m1,m2,h6+2);8A=f(m1,m2,h6);1F=f(m1,m2,h6-2)}F{r:1v,g:8A,b:1F,a:bL}},bA:G(1v,4K,1F,bK){if(M.K==1){u 1B=1v;1v=1B.r;4K=1B.g;1F=1B.b;bK=1B.a}u 29=28.29(28.29(1v,4K),1F);u 2a=28.2a(28.2a(1v,4K),1F);u 1o;u 8z;u hb=29;if(2a==29){1o=0;8z=0}N{u 6H=(29-2a);8z=6H/29;if(1v==29){1o=(4K-1F)/6H}N{if(4K==29){1o=2+((1F-1v)/6H)}N{1o=4+((1v-4K)/6H)}}1o/=6;if(1o<0){1o+=1}if(1o>1){1o-=1}}F{h:1o,s:8z,v:hb,a:bK}},bC:G(1v,4J,1F,bI){if(M.K==1){u 1B=1v;1v=1B.r;4J=1B.g;1F=1B.b;bI=1B.a}u 29=28.29(1v,28.29(4J,1F));u 2a=28.2a(1v,28.2a(4J,1F));u 1o;u 6G;u bJ=(29+2a)/2;u 4I=29-2a;if(4I===0){1o=0;6G=0}N{if(bJ<=0.5){6G=4I/(29+2a)}N{6G=4I/(2-29-2a)}if(1v==29){1o=(4J-1F)/4I}N{if(4J==29){1o=2+((1F-1v)/4I)}N{1o=4+((1v-4J)/4I)}}1o/=6;if(1o<0){1o+=1}if(1o>1){1o-=1}}F{h:1o,s:6G,l:bJ,a:bI}},6E:G(1P){1P=28.ha(1P);u bH=1P.1l(16);if(1P<16){F"0"+bH}F bH},2d:G(){u m=B.J;D.V.h9=m.1O(D.V.bG,D.V,"1B","3Y",[1/3h,1/3h,1/3h,1]);D.V.h8=m.1O(D.V.bG,D.V,"1G","4H",[1/bF,0.bE,0.bE,1]);u 4G=1/3;u bD={8y:[0,0,0],1F:[0,0,1],gY:[0.6,0.4,0.2],gX:[0,1,1],sJ:[4G,4G,4G],gR:[0.5,0.5,0.5],bx:[0,1,0],sI:[2*4G,2*4G,2*4G],gN:[1,0,1],gL:[1,0.5,0],gK:[0.5,0,0.5],1v:[1,0,0],aP:[0,0,0,0],4F:[1,1,1],gI:[1,1,0]};u h7=G(1b,r,g,b,a){u W=D.3Y(r,g,b,a);D[1b]=G(){F W};F W};R(u k in bD){u 1b=k+"V";u h5=m.2o([h7,D.V,1b],bD[k]);D.V[1b]=m.1O.1w(O,h5)}u h0=G(){R(u i=0;i1){u 1d=B.S.1E(M[0]);u 2D=M[1];u 1i=M[2];u 1A=M[3];R(u i=5o.K-1;i>=0;i--){u o=5o[i];if(o[0]===1d&&o[1]===2D&&o[4]===1i&&o[5]===1A){I.6t(o);5o.4y(i,1);F 1h}}}N{u 5n=m.bi(5o,bh);if(5n>=0){I.6t(bh);5o.4y(5n,1);F 1h}}F 1m},8i:G(1d,2D){1d=B.S.1E(1d);u m=B.J;u 8l=m.bg(m.1R(O,M,1));u I=B.1u;u bd=I.6t;u 4z=I.4x;if(8l.K===0){R(u i=4z.K-1;i>=0;i--){u 4A=4z[i];if(4A[0]===1d){bd(4A);4z.4y(i,1)}}}N{u bf={};R(u i=0;i<8l.K;i++){bf[8l[i]]=1h}R(u i=4z.K-1;i>=0;i--){u 4A=4z[i];if(4A[0]===1d&&4A[1]in bf){bd(4A);4z.4y(i,1)}}}},8h:G(1d,2D){u bc=B.1u.4x;1d=B.S.1E(1d);u 3G=B.J.1R(O,M,2);u 5m=[];R(u i=0;i1){u e=Y 2x("mZ bb mY in mX \'2D\', mW bb mV");e.bb=5m;14 e}}}});B.1u.1W=[];B.1u.1z=["6s","8j","8h","8i"];B.1u.2d=G(2m){u m=B.J;D.1Z=2v;D.3X=2m;1f{D.6s(2O,"g8",D.g7)}1e(e){}D.2k={":3e":D.1z,":1p":m.2o(D.1z,D.1W)};m.3f(D)};B.1u.2d(D);if(!B.3d){6s=B.1u.6s;8j=B.1u.8j;8i=B.1u.8i;8h=B.1u.8h}B.J.2Y(D,B.1u);if(H(1q)!="L"){1q.2X("B.1X");1q.2M("B.J");1q.2M("B.S");1q.2M("B.V")}if(H(1x)!="L"){1x.26("B.J",[]);1x.26("B.S",[]);1x.26("B.V",[])}1f{if(H(B.J)=="L"||H(B.S)=="L"||H(B.V)=="L"){14""}}1e(e){14"B.1X 3F on B.J, B.S 3W B.V!"}if(H(B.1X)=="L"){B.1X={}}B.1X.1r="B.1X";B.1X.1Y="1.3.1";B.1X.1K=G(){F"["+D.1r+" "+D.1Y+"]"};B.1X.1l=G(){F D.1K()};B.1X.aI=G(e,g6){e=B.S.1E(e);D.fN(g6);if(D.1S.fL){e=D.g5(e)}u 4w=D.1S.3U;u C=B.V.V;if(D.1S.3U=="aW"){4w=C.ba(e)}N{if(!(4w 2C C)){4w=C.8f(4w)}}D.82=(4w.6r().a<=0);u 5l=D.1S.aV;if(D.1S.aV=="fM"){5l=C.ba(e.8g)}N{if(!(5l 2C C)){5l=C.8f(5l)}}D.g3(e,4w,5l)};B.1X.aI.1U={g5:G(e){u mU=e.3t;u 1N=B.S.b9();if(H(1N.5k)=="L"||1N.5k===O){F e}u 4v=1N.5k.g4(e,O);if(H(4v)=="L"||4v===O){F e}u b8=B.S.6m({"1T":{3u:"8c",mT:4v.6q("6p-3D"),85:4v.6q("6p-3g"),mS:4v.6q("6p-6f"),86:4v.6q("6p-2I"),6p:"2N"}});b8.6o=e.6o;e.6o="";e.2c(b8);F e},g3:G(e,b7,8e){if(D.1S.3E){D.g2(e,8e)}if(D.fy()){D.fX(e,b7,8e)}if(D.fx()){D.fV(e,b7,8e)}},g2:G(el,g1){u b6="6l 8a "+D.aQ(g1);u g0="3E-2I: "+b6;u fZ="3E-3g: "+b6;u fY="1T=\'"+g0+";"+fZ+"\'";el.6o="<4u "+fY+">"+el.6o+""},fX:G(el,fW,b5){u b4=D.b1(b5);R(u i=0;i=0;i--){b2.2c(D.b0(fU,b3,i,"6f"))}el.1T.mP=0;el.2c(b2)},b1:G(fT){u 2q=B.S;F 2q.6m({1T:{aZ:fT.1l()}})},b0:G(aY,fQ,n,aX){u 6k=B.S.8d();u 2p=6k.1T;2p.aZ=aY.1l();2p.3u="8c";2p.3V="6l";2p.fS="fR";2p.mO="6l";u 8b=D.aQ(aY,fQ);if(D.1S.3E&&n===0){2p.mN="8a";2p.mM="6l";2p.84="2N";2p.83="2N";2p.mL="2N";2p.3V="2N";2p.fP=8b.1l()}N{if(8b){2p.fP=8b.1l();2p.mK="8a";2p.mJ="2N 6l"}}if(!D.1S.4r&&(n==(D.1S.89-1))){2p.3V="fO"}D.fI(6k,n,aX);D.fG(6k,n,aX);F 6k},fN:G(fK){D.1S={6g:"1p",3U:"aW",aV:"fM",5j:1h,3E:1m,4r:1m,fL:1m};B.J.2l(D.1S,fK);D.1S.89=(D.1S.4r?2:4)},aL:G(){u 88=D.1S.6g;if(D.6h(88,"1p","3D")){F""}u aU=(88.2A("tl")!=-1);u aT=(88.2A("tr")!=-1);if(aU&&aT){F""}if(aU){F"2I"}if(aT){F"3g"}F""},aK:G(){u 87=D.1S.6g;if(D.6h(87,"1p","6f")){F""}u aS=(87.2A("bl")!=-1);u aR=(87.2A("br")!=-1);if(aS&&aR){F""}if(aS){F"2I"}if(aR){F"3g"}F""},aQ:G(aN,aO){if(aN=="aP"){F aO}N{if(D.1S.3E){F D.1S.3E}N{if(D.1S.5j){F aO.fJ(aN)}}}F""},fI:G(el,n,fH){u 6j=D.fE(n)+"px";u aM=(fH=="3D"?D.aL():D.aK());u 4t=el.1T;if(aM=="2I"){4t.86=6j;4t.85="2N"}N{if(aM=="3g"){4t.85=6j;4t.86="2N"}N{4t.86=6j;4t.85=6j}}},fG:G(el,n,fF){u 6i=D.fz(n)+"px";u aJ=(fF=="3D"?D.aL():D.aK());u 4s=el.1T;if(aJ=="2I"){4s.84=6i;4s.83="2N"}N{if(aJ=="3g"){4s.83=6i;4s.84="2N"}N{4s.84=6i;4s.83=6i}}},fE:G(n){if(D.82){F 0}u o=D.1S;if(o.4r&&o.5j){u fD=[1,0];F fD[n]}N{if(o.4r){u fC=[2,1];F fC[n]}N{if(o.5j){u fB=[3,2,1,0];F fB[n]}N{u fA=[5,3,2,1];F fA[n]}}}},fz:G(n){u o=D.1S;u 5i;if(o.4r&&(o.5j||D.82)){F 1}N{if(o.4r){5i=[1,0]}N{if(o.5j){5i=[2,1,1,1]}N{if(o.3E){5i=[0,2,0,0]}N{if(D.82){5i=[5,3,2,1]}N{F 0}}}}}F 5i[n]},6h:G(1y){R(u i=1;i")}}})()}',62,1976,'||||||||||||||||||||||||||||||var|||||||MochiKit||this||return|function|typeof|self|Base|length|undefined|arguments|else|null||elem|for|DOM||repr|Color|rval|res|new||||||throw|Iter|||||next|name|push|src|catch|try|lst|true|obj|node|Async|toString|false|string|hue|all|dojo|NAME|Format|msg|Signal|red|apply|JSAN|str|EXPORT|func|rgb|_425|DateTime|getElement|blue|hsl|Logging|LoggingPane|type|__repr__|_event|while|doc|bind|num|iter|extend|options|style|prototype|seq|EXPORT_OK|Visual|VERSION|_document||_434||replace|forwardCall|StopIteration|use||Math|max|min|join|appendChild|__new__|button|compare|date|key|val|_329|EXPORT_TAGS|update|win|pair|concat|_596|dom|map|req|Deferred|sync|document|base|Error|number|partial|indexOf||instanceof|sig|not|cls|list|fired|left|stop|break|logger|require|0px|window|shift|hsv|split|createElement|_423|callee|continue|substring|provide|_exportSymbols|ccc||_464|||||||||step|pred|_51|__compat__|common|nameFunctions|right|255|_517|case|100|_loggingPane|value|object|callback|TypeError|_251|_246|_113|parentNode|display|_522|parseInt|cssText|wrap|info|isArrayLike|end|match|top|border|depends|args|substr|mouse|code|_519|_443|className|level|err|frac|Date|_135|_85|nodeType|color|height|and|_window|fromRGB|charAt||asHSL|_444|message||||filter||LogMessage|AdapterRegistry|_366|imap|NotFound|locked|counter|_262|_messages|operator|cmp|_165|_161|pairs|arr|_52|setAttribute|computedStyle|compact|_614|_610|div|_576|_572|_observers|splice|_565|_566|_555|scrollTop|page|modifier|white|_541|fromHSL|_539|_535|_528|clone|parseFloat|_505|pre|_499|_497|_427|createTextNode|_446|attributeArray|_388|_379|updateNodeAttributes|_341|_326||box|errback|results|paused|chain|_285||ofs||NamedError|_175|_147|_122|_83|_54|_17|childNodes|_619|blend|defaultView|_574|_569|idx|_562|must|_554|_specialKeys|body|Coordinates|registerComparator|_521|_516|hex|mid|_478|width|loggingPane|LogLevel|nwin|head|url|setElementClass|callStack|path|dest|_359|boolean|register|Dimensions|DeferredLock|_313|addCallback|_310|waiting|onreadystatechange|_290|LOCALE|year|printfire|_214|log|_213|_211|pos|_155|_153||typeMatcher|listMinMax|_114|_40|itr|typ|_19|_634|_625|bottom|corners|_hasString|_612|_608|_595|1px|DIV|firstChild|innerHTML|padding|getPropertyValue|asRGB|connect|_disconnect|_559|middle|which|clientY|scrollLeft|clientX|client|charCode|relatedTarget|event|toColorPart|clampColorComponent|_537|_534|toFixed|_468|buildAndApplyFilter|_442|_441|_440|_439|position|_463|_447|removeChild|_449|uid|_428|_426|compliant|attributes|_422|_409|_412|_400|_395|_390|_389|_377|_375|_363|attr|ctx|repeat|_340|_339|isNotEmpty|_335|_333|opera|DeferredList|ret|_309|silentlyCancelled|canceller|_nextId|Array|_293|XMLHttpRequest|chained|_281|tail|_252|_225|msec|day|month|iso|Logger|_208|listeners|_200|_198|_194|_196|reduce|range|_169|_162|truth|registerRepr|_121|_70|_58|_56|_47|_45|_41|_13|_1|script|text|uri|documentElement|_630|_629|isTransparent|borderRightWidth|borderLeftWidth|marginRight|marginLeft|_602|_599|numSlices|solid|_597|block|SPAN|_579|fromString|offsetParent|signal|disconnectAll|disconnect|_570|_563|_557|preventDefault|stopPropagation|clientTop|clientLeft|pageY|pageX|keyCode|meta|ctrl|alt|target|black|_532|_524|floor|_513|_512|_500|_495|toLowerCase|_487|DEBUG|INFO|WARNING|FATAL|ERROR|colorTable|logFont|closed|inline|onclick|_438|_437|_445|RegExp|_452|space|title|updatetree|||||withDocument|withWindow||setDisplayForElement|none|renames|forEach|domConverters|escapeHTML|addElementClass|removeElementClass|once|_378|_380|_376|appendChildNodes|coerceToDOM|_355|opt|clientWidth|opacity|GenericError|fail|resultList|_307|_301|_fire|can|addCallbacks|_resback|percent|decimal|separator|twoDigitFloat|_274|_273|_264|_257|_250|_249|_254|_248|_243|_242|fmt|_240|_245|getTime|sec|hour|_209|slice|_206|iterateNextIter|registerIteratorFactory|arrayLikeIter|iteratorRegistry|takewhile|ifilterfalse|ifilter|_181|_176|_168|_166|_159|_tee|deque|arg|fun|jsonRegistry|reprString|reprRegistry|comparatorRegistry|urlEncode|_110|_108|cur|_95|_87|_71|im_preargs||_53|_57|_46|present|like|array|Argument|_15|_12|_632|_631|_633|SUBMODULES|only|_628|_627|_626|roundElement|_624|getElementsByTagAndClassName|_RoundCorners|_613|_whichSideBottom|_whichSideTop|_609|_605|_606|transparent|_borderColor|_604|_603|_601|_600|bgColor|fromElement|_594|_592|backgroundColor|_createCornerSlice|_createCorner|_590|_589|_587|_586|_581|_578|_577|currentDocument|fromBackground|errors|_568|_564||sigs|flattenArguments|_561|findIdentical|_560|_558||_556|attachEvent|addEventListener|funcOrStr|Event||_548|fromCharCode|String|_specialMacKeys|any|green|_namedColors|hsvToRGB|rgbToHSV|hslToRGB|rgbToHSL|_542|01|360|_fromColorString|_540|_536|_538|_529|_523|_518|fromComputedStyle|_511|_507|_508|_506|_501|fromHexString|_498|_496|_486|__class__|createLoggingPane|_459|_461|font|_462|_430|_435|1000|index|_460|getMessages|removeListener|_451||_457|_450|infore|_448|_456|logDebug|offsetHeight|span|input|_436|TR||HTML|open|alert|currentWindow|swapDOM|SELECT|FORM|INPUT|createDOMFunc|ignoreAttr|_421|call|_417|_410|_415|nodeName|_414|_413|emitHTML|good|_406|_399|_397|_393|_392|addLoadEvent|addToCallStack|_387|_386|_381|_382|_383|_373|_372|_369|createDOM|_365|Function|_360|_362|_358|_344|nodeWalk|formContents|_337|_338|_334|_332|offsetTop|offsetLeft|visibility|parentElement|||XMLHttpRequestError|BrowserComplianceError|CancelledError|AlreadyCalledError|evalJSONRequest|sendXMLHttpRequest|wait|doSimpleXMLHttpRequest|getXMLHttpRequest|succeed|_312|finishedCount|_308|_cbDeferred|_303|_297|queryString|_nothing|_289|XMLHTTP|ActiveXObject|eval|_284|_check|error|_279|default|rstrip|lstrip|formatLocale|roundToFixed|truncToFixed|_276|pow|_272|_271|_270|sign|_265|_263|tmp|_238|_232|toISODate|toISOTime|getFullYear|getDate|getMonth|_230|_padTwo|_228|useNativeConsole|_212|compareLogMessage|isLogMessage|unshift|_207||maxSize|_202|_199|logLevelAtLeast|console|hasIterateNext|iterateNext|arrayLike|groupby||exhaust|tee|dropwhile|applymap||islice|izip|cycle|count||_189|_188|_183|_185|_184|_186|_187|_182|identity|fetch|_180|_177|listMin|reprNumber|reprArrayLike|compareArrayLike|compareDateLike|isDateLike|findValue|_128|__export__|keyComparator|_124|_118|_93|_94|_90|_88|_84|_77|_68|_67|_66|_65|_60|im_func|_55|im_self|_48|_44|_42|_39|_36|_33|_27|_26|_25|_22|_24|_20|javascript|write|getAttribute||org|www|http|getElementsByTagName|roundClass|_623|_622|_621|_620|_isBottomRounded|_isTopRounded|_borderSize|_618|_617|_616|_615|_marginSize|_611|_setBorder|_607|_setMargin|blendedColor|_598|__unstable__wrapElement|fromParent|_setOptions|2px|borderColor|_593|hidden|overflow|_591|_588|_roundBottomCorners|_585|_roundTopCorners|_584|_583|_582|_580|_renderBorder|_roundCornersImpl|getComputedStyle|_doWrap|_571|_unloadCache|onunload|detachEvent|removeEventListener|_listener|objOrFunc|_552||_551|_549|onload|delete|112|KEY_F|KEY_|MINUS|KEY_SEMICOLON|KEY_DELETE|KEY_INSERT|KEY_ARROW_DOWN|KEY_ARROW_RIGHT|KEY_ARROW_UP||KEY_ARROW_LEFT|KEY_HOME|KEY_END|KEY_PAGE_DOWN|KEY_PAGE_UP|KEY_ENTER|KEY_NUM_PAD_CLEAR|63236|mousemove|contextmenu|click|mouseout|mouseover|_src|yellow|708090|purple|orange|ff00ff|magenta|778899|d3d3d3|808080|gray|696969|2f4f4f|darkred|a9a9a9|00ffff|cyan|brown|_547|_546||||compareRGB|_545||_543|fromHSLString|fromRGBString|round|_533|_hslValue|switch|background|_503|_504||fromName|_488|col|toRGBString|_hexString|_rgbString|_hslString|toPrecision|isLight||_481|_477|_476|_475|_474|_473|_469|_466|closePane|_458|onkeypress|_454|addListener|_455|close|test|scrollHeight|option|word|moz|_431|getElementById|html|pop|200|_|removeElement|showElement|hideElement|CANVAS|STRONG|FIELDSET|LEGEND|OPTGROUP|OPTION|TEXTAREA|LABEL|HR|BR|H3|H2|H1|PRE|TT|BUTTON|IMG|TH||TABLE||TFOOT|THEAD|TBODY|TD|LI|OL|||UL|checked|class|ignoreAttrFilter||_424|_419|nodeValue|scrapeText|_416|_418|sort|_411|toHTML|_404|hasElementClass|_403|_402|_401|swapElementClass|_398|_394|toggleElementClass|_391|focusOnLoad|_newCallStack|currentStyle|_371|replaceChildNodes|_364|_361|getNodeAttribute|_357|setNodeAttribute|_354|_352|_350|_353|toDOM|_346|_345|registerDOMConverter|selectedIndex|setElementPosition|setElementDimensions|tagName|absolute|getBoxObjectFor|getBoundingClientRect|elementPosition|_325|_324|_322|_323|offsetWidth|elementDimensions|clientHeight|innerWidth|getViewportDimensions|setOpacity|status|_317|deferred|_316|_newNamedError|maybeDeferred||gatherResults|callLater|loadJSONDoc|_311|consumeErrors|fireOnOneErrback|fireOnOneCallback|addErrback|_305|_304|_306|unlocked|release|_300|_299|_298|_296|_xhr_onreadystatechange|_xhr_canceller|304|responseText|Msxml2|addBoth|_pause|_continue|result|the|are|they|instances|_unpause|cancel|_280|_278|en_US|strip|percentFormat|twoDigitAverage|numberFormatter|_277|_275|isNaN|_259|_258|_260|_255|_253|_numberFormatter|_241|_239|_237|_236|_235|_234|_233|_231|toAmericanDate|toPaddedAmericanDate|americanDate|toISOTimestamp|isoTimestamp|isoDate|foot|sep||60000|_221|_isoRegexp|dispatchEvent|createEvent|warning|logWarning|fatal|logFatal|debug|logError|baseLog|_210|getMessageText|logToConsole|dispatchListeners|_204|_203|ident|_201|postError|alertListener|_197|_192|groupby_as_array|iextend|some|reversed|sorted|every|sum|_190|eat|_174|_173|_172|_171|_167|_163|_158|_157|_151|_144|_141||_139|_136|_134||_133|_132|zip|merge|isUndefined|isCallable|listMax|_131|_130|encodeURIComponent||_127|method|parseQueryString|evalJSON|registerJSON|serializeJSON|objMin|objMax|reverseKeyComparator|arrayEqual|objEqual|bindMethods|xfilter|xmap|isEmpty|isNull|isUndefinedOrNull|itemgetter|items|keys|setdefault|_126|_120|decodeURIComponent|_119|len|_109|_107|_104|_105|_101|_102|_98|||_100|_97|_96|_91|json|__json__|_82|_81|_80|_79|_76||_75|_74|_73|_69|_primitives|_64|_63||_62|_61|_59|_wrapDumbFunction|_49|_50|_31|_30|_21|_7|application|MochiKit_|createElementNS|namespaceURI|lastIndexOf|xul|there|gatekeeper|keymaster|mozilla|getElementsComputedStyle|_hasSingleTextChild|borderWidth|borderStyle|borderBottomWidth|borderTopWidth|borderTopStyle|fontSize|paddingBottom|insertBefore|paddingTop|marginBottom|marginTop|_575|property|see|handling|thrown|Multiple|element|||given|123|KEY_NUM_PAD_|105|KEY_APOSTROPHE|222|KEY_RIGHT_SQUARE_BRACKET|221|KEY_REVERSE_SOLIDUS|220|KEY_LEFT_SQUARE_BRACKET||219|KEY_GRAVE_ACCENT|192|KEY_SOLIDUS|191|KEY_FULL_STOP|190|KEY_HYPHEN|189||KEY_COMMA|188|KEY_EQUALS_SIGN|187|186|KEY_SCROLL_LOCK|145|KEY_NUM_LOCK|144|KEY_NUM_PAD_SOLIDUS|111|KEY_NUM_PAD_FULL_STOP|110|KEY_NUM_PAD_HYPHEN|109|KEY_NUM_PAD_PLUS_SIGN|107|KEY_NUM_PAD_ASTERISK|106|KEY_SELECT|KEY_WINDOWS_RIGHT|KEY_WINDOWS_LEFT|KEY_PRINT_SCREEN|KEY_SPACEBAR|KEY_ESCAPE|KEY_CAPS_LOCK|KEY_PAUSE|KEY_ALT|KEY_CTRL|KEY_SHIFT|KEY_TAB|KEY_BACKSPACE|63242|63272|63302|63233|63235|63232|63234|63273|63275|63277|63276|63289|returnValue|cancelBubble|keypress|KEY_UNKNOWN|keyup|keydown|shiftKey|metaKey||ctrlKey|altKey|toElement|srcElement|9acd32||yellowgreen||ffff00|f5f5f5|whitesmoke||ffffff|f5deb3|wheat|ee82ee|violet|40e0d0|turquoise|ff6347|tomato|d8bfd8|thistle|008080|teal|d2b48c|tan|4682b4|steelblue|00ff7f|springgreen|fffafa|snow|slategrey|slategray|6a5acd|slateblue|87ceeb|skyblue|c0c0c0|silver|a0522d|sienna|fff5ee|seashell|2e8b57|seagreen|f4a460|sandybrown|fa8072|salmon|8b4513|saddlebrown|4169e1|royalblue|bc8f8f|rosybrown|ff0000|800080|b0e0e6|powderblue|dda0dd|plum|ffc0cb|pink|cd853f||peru|ffdab9|peachpuff|ffefd5|papayawhip|db7093|palevioletred|afeeee|paleturquoise|98fb98|palegreen|eee8aa||palegoldenrod|da70d6|orchid|ff4500|orangered|ffa500|6b8e23|olivedrab|808000|olive|fdf5e6|oldlace|000080|navy|ffdead|navajowhite|ffe4b5|moccasin|ffe4e1|mistyrose|f5fffa|mintcream|191970|midnightblue|c71585|mediumvioletred|48d1cc|mediumturquoise|00fa9a|mediumspringgreen|7b68ee|mediumslateblue|3cb371|mediumseagreen|9370db|mediumpurple|ba55d3|mediumorchid|0000cd|mediumblue|66cdaa|mediumaquamarine|800000|maroon|faf0e6|linen|32cd32|limegreen|00ff00|lime|ffffe0|lightyellow|b0c4de|lightsteelblue|lightslategrey|lightslategray||87cefa|lightskyblue|20b2aa|lightseagreen|ffa07a|lightsalmon|ffb6c1|lightpink|lightgrey|90ee90|lightgreen|lightgray|fafad2|lightgoldenrodyellow|e0ffff|lightcyan|f08080|lightcoral|add8e6|lightblue|fffacd|lemonchiffon|7cfc00|lawngreen|fff0f5|lavenderblush|e6e6fa|lavender|f0e68c|khaki|fffff0|ivory|4b0082|indigo|cd5c5c|indianred|ff69b4|hotpink|f0fff0|honeydew|grey|adff2f|greenyellow|008000|daa520|goldenrod|ffd700||gold|f8f8ff|ghostwhite|dcdcdc|gainsboro|fuchsia|228b22|forestgreen|fffaf0|floralwhite|b22222|firebrick|1e90ff|dodgerblue|dimgrey|dimgray|00bfff|deepskyblue|ff1493|deeppink|9400d3|darkviolet|00ced1|darkturquoise|darkslategrey|darkslategray|483d8b|darkslateblue|8fbc8f|darkseagreen|e9967a|darksalmon|8b0000|9932cc|darkorchid|ff8c00|darkorange|556b2f|darkolivegreen|8b008b|darkmagenta|bdb76b|darkkhaki|darkgrey|006400|darkgreen|darkgray|b8860b|darkgoldenrod|008b8b|darkcyan|00008b|darkblue|dc143c|crimson|fff8dc|cornsilk|6495ed|cornflowerblue|ff7f50|coral|d2691e||chocolate|7fff00|chartreuse|5f9ea0|cadetblue|deb887|burlywood|a52a2a|8a2be2|blueviolet|0000ff|ffebcd||blanchedalmond|000000|ffe4c4|bisque|f5f5dc|beige|f0ffff|azure|7fffd4|aquamarine|aqua|faebd7|antiquewhite|f0f8ff|aliceblue|lightGray|darkGray|namedColors|blackColor|fromText|whiteColor|_510|_509|PI|rad|deg|transparentColor|_494|_493|_492|fromHSV|_491|_490|_489|asHSV|toHexString|rgba|hsla|toHSLString|isDark|lighterColorWithLevel|darkerColorWithLevel|colorWithLightness|colorWithSaturation|colorWithHue|colorWithAlpha||serif|sans|Verdana||8pt|8em|auto||Close|Clear||Load|Filter||10em||fixed|regex|emergency|line|margin|_Listener|dtd|loose|html4|w3|EN|Transitional|DTD|W3C|PUBLIC|DOCTYPE|blocking|due|debugging|able|Not|resizable|dependent|href|location|_MochiKit_LoggingPane|_429|canvas|strong|fieldset|legend|optgroup|select|form|textarea|label|img|table|tfoot|thead|tbody|htmlFor||useMap|usemap|defaultChecked|hasChildNodes|quot|amp|_405|focus|replaceChild|checkbox||radio|_win|BODY||safari|version|userAgent|navigator|innerHeight|alpha|khtml|Tried|acquire|clearTimeout|setTimeout|GET|ignore|send|abort|failed|Request|readyState|support|does|Browser|Microsoft|_288|_287|used|Deferreds|Chained|success|unfired|fr_FR|de_DE|00|abs|search|pattern|Invalid|getTimezoneOffset|getSeconds|getMinutes|getHours|UTC|3600000|initEvent|Events|debuggingBookmarklet|MESSAGES|LAST|_205|clear|ninfo|nlevel|timestamp|reverse|takes|initial|with|sequence|empty|iterable|numbers|dateLike|escape|find|forward|unregister|unescape|Object|compared|item|contains|logor|logand|cle|clt|cge|cgt|cne|ceq|zrshift|rshift|lshift|xor|mul|mod|sub|add|neg|lognot|_9|_2'.split('|'),0,{}) + +result += decompressedMochiKit.length; + +/* + * jQuery 1.2.1 - New Wave Javascript + * + * Copyright (c) 2007 John Resig (jquery.com) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * $Date: 2007-09-16 23:42:06 -0400 (Sun, 16 Sep 2007) $ + * $Rev: 3353 $ + */ + +var decompressedJQuery = function(p,a,c,k,e,r){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(G(){9(1m E!="W")H w=E;H E=18.15=G(a,b){I 6 7u E?6.5N(a,b):1u E(a,b)};9(1m $!="W")H D=$;18.$=E;H u=/^[^<]*(<(.|\\s)+>)[^>]*$|^#(\\w+)$/;E.1b=E.3A={5N:G(c,a){c=c||U;9(1m c=="1M"){H m=u.2S(c);9(m&&(m[1]||!a)){9(m[1])c=E.4D([m[1]],a);J{H b=U.3S(m[3]);9(b)9(b.22!=m[3])I E().1Y(c);J{6[0]=b;6.K=1;I 6}J c=[]}}J I 1u E(a).1Y(c)}J 9(E.1n(c))I 1u E(U)[E.1b.2d?"2d":"39"](c);I 6.6v(c.1c==1B&&c||(c.4c||c.K&&c!=18&&!c.1y&&c[0]!=W&&c[0].1y)&&E.2h(c)||[c])},4c:"1.2.1",7Y:G(){I 6.K},K:0,21:G(a){I a==W?E.2h(6):6[a]},2o:G(a){H b=E(a);b.4Y=6;I b},6v:G(a){6.K=0;1B.3A.1a.16(6,a);I 6},N:G(a,b){I E.N(6,a,b)},4I:G(a){H b=-1;6.N(G(i){9(6==a)b=i});I b},1x:G(f,d,e){H c=f;9(f.1c==3X)9(d==W)I 6.K&&E[e||"1x"](6[0],f)||W;J{c={};c[f]=d}I 6.N(G(a){L(H b 1i c)E.1x(e?6.R:6,b,E.1e(6,c[b],e,a,b))})},17:G(b,a){I 6.1x(b,a,"3C")},2g:G(e){9(1m e!="5i"&&e!=S)I 6.4n().3g(U.6F(e));H t="";E.N(e||6,G(){E.N(6.3j,G(){9(6.1y!=8)t+=6.1y!=1?6.6x:E.1b.2g([6])})});I t},5m:G(b){9(6[0])E(b,6[0].3H).6u().3d(6[0]).1X(G(){H a=6;1W(a.1w)a=a.1w;I a}).3g(6);I 6},8m:G(a){I 6.N(G(){E(6).6q().5m(a)})},8d:G(a){I 6.N(G(){E(6).5m(a)})},3g:G(){I 6.3z(1q,Q,1,G(a){6.58(a)})},6j:G(){I 6.3z(1q,Q,-1,G(a){6.3d(a,6.1w)})},6g:G(){I 6.3z(1q,P,1,G(a){6.12.3d(a,6)})},50:G(){I 6.3z(1q,P,-1,G(a){6.12.3d(a,6.2q)})},2D:G(){I 6.4Y||E([])},1Y:G(t){H b=E.1X(6,G(a){I E.1Y(t,a)});I 6.2o(/[^+>] [^+>]/.14(t)||t.1g("..")>-1?E.4V(b):b)},6u:G(e){H f=6.1X(G(){I 6.67?E(6.67)[0]:6.4R(Q)});H d=f.1Y("*").4O().N(G(){9(6[F]!=W)6[F]=S});9(e===Q)6.1Y("*").4O().N(G(i){H c=E.M(6,"2P");L(H a 1i c)L(H b 1i c[a])E.1j.1f(d[i],a,c[a][b],c[a][b].M)});I f},1E:G(t){I 6.2o(E.1n(t)&&E.2W(6,G(b,a){I t.16(b,[a])})||E.3m(t,6))},5V:G(t){I 6.2o(t.1c==3X&&E.3m(t,6,Q)||E.2W(6,G(a){I(t.1c==1B||t.4c)?E.2A(a,t)<0:a!=t}))},1f:G(t){I 6.2o(E.1R(6.21(),t.1c==3X?E(t).21():t.K!=W&&(!t.11||E.11(t,"2Y"))?t:[t]))},3t:G(a){I a?E.3m(a,6).K>0:P},7c:G(a){I 6.3t("."+a)},3i:G(b){9(b==W){9(6.K){H c=6[0];9(E.11(c,"24")){H e=c.4Z,a=[],Y=c.Y,2G=c.O=="24-2G";9(e<0)I S;L(H i=2G?e:0,33=2G?e+1:Y.K;i<33;i++){H d=Y[i];9(d.26){H b=E.V.1h&&!d.9V["1Q"].9L?d.2g:d.1Q;9(2G)I b;a.1a(b)}}I a}J I 6[0].1Q.1p(/\\r/g,"")}}J I 6.N(G(){9(b.1c==1B&&/4k|5j/.14(6.O))6.2Q=(E.2A(6.1Q,b)>=0||E.2A(6.2H,b)>=0);J 9(E.11(6,"24")){H a=b.1c==1B?b:[b];E("9h",6).N(G(){6.26=(E.2A(6.1Q,a)>=0||E.2A(6.2g,a)>=0)});9(!a.K)6.4Z=-1}J 6.1Q=b})},4o:G(a){I a==W?(6.K?6[0].3O:S):6.4n().3g(a)},6H:G(a){I 6.50(a).28()},6E:G(i){I 6.2J(i,i+1)},2J:G(){I 6.2o(1B.3A.2J.16(6,1q))},1X:G(b){I 6.2o(E.1X(6,G(a,i){I b.2O(a,i,a)}))},4O:G(){I 6.1f(6.4Y)},3z:G(f,d,g,e){H c=6.K>1,a;I 6.N(G(){9(!a){a=E.4D(f,6.3H);9(g<0)a.8U()}H b=6;9(d&&E.11(6,"1I")&&E.11(a[0],"4m"))b=6.4l("1K")[0]||6.58(U.5B("1K"));E.N(a,G(){H a=c?6.4R(Q):6;9(!5A(0,a))e.2O(b,a)})})}};G 5A(i,b){H a=E.11(b,"1J");9(a){9(b.3k)E.3G({1d:b.3k,3e:P,1V:"1J"});J E.5f(b.2g||b.6s||b.3O||"");9(b.12)b.12.3b(b)}J 9(b.1y==1)E("1J",b).N(5A);I a}E.1k=E.1b.1k=G(){H c=1q[0]||{},a=1,2c=1q.K,5e=P;9(c.1c==8o){5e=c;c=1q[1]||{}}9(2c==1){c=6;a=0}H b;L(;a<2c;a++)9((b=1q[a])!=S)L(H i 1i b){9(c==b[i])6r;9(5e&&1m b[i]==\'5i\'&&c[i])E.1k(c[i],b[i]);J 9(b[i]!=W)c[i]=b[i]}I c};H F="15"+(1u 3D()).3B(),6p=0,5c={};E.1k({8a:G(a){18.$=D;9(a)18.15=w;I E},1n:G(a){I!!a&&1m a!="1M"&&!a.11&&a.1c!=1B&&/G/i.14(a+"")},4a:G(a){I a.2V&&!a.1G||a.37&&a.3H&&!a.3H.1G},5f:G(a){a=E.36(a);9(a){9(18.6l)18.6l(a);J 9(E.V.1N)18.56(a,0);J 3w.2O(18,a)}},11:G(b,a){I b.11&&b.11.27()==a.27()},1L:{},M:G(c,d,b){c=c==18?5c:c;H a=c[F];9(!a)a=c[F]=++6p;9(d&&!E.1L[a])E.1L[a]={};9(b!=W)E.1L[a][d]=b;I d?E.1L[a][d]:a},30:G(c,b){c=c==18?5c:c;H a=c[F];9(b){9(E.1L[a]){2E E.1L[a][b];b="";L(b 1i E.1L[a])1T;9(!b)E.30(c)}}J{2a{2E c[F]}29(e){9(c.53)c.53(F)}2E E.1L[a]}},N:G(a,b,c){9(c){9(a.K==W)L(H i 1i a)b.16(a[i],c);J L(H i=0,48=a.K;i<48;i++)9(b.16(a[i],c)===P)1T}J{9(a.K==W)L(H i 1i a)b.2O(a[i],i,a[i]);J L(H i=0,48=a.K,3i=a[0];i<48&&b.2O(3i,i,3i)!==P;3i=a[++i]){}}I a},1e:G(c,b,d,e,a){9(E.1n(b))b=b.2O(c,[e]);H f=/z-?4I|7T-?7Q|1r|69|7P-?1H/i;I b&&b.1c==4W&&d=="3C"&&!f.14(a)?b+"2T":b},1o:{1f:G(b,c){E.N((c||"").2l(/\\s+/),G(i,a){9(!E.1o.3K(b.1o,a))b.1o+=(b.1o?" ":"")+a})},28:G(b,c){b.1o=c!=W?E.2W(b.1o.2l(/\\s+/),G(a){I!E.1o.3K(c,a)}).66(" "):""},3K:G(t,c){I E.2A(c,(t.1o||t).3s().2l(/\\s+/))>-1}},2k:G(e,o,f){L(H i 1i o){e.R["3r"+i]=e.R[i];e.R[i]=o[i]}f.16(e,[]);L(H i 1i o)e.R[i]=e.R["3r"+i]},17:G(e,p){9(p=="1H"||p=="2N"){H b={},42,41,d=["7J","7I","7G","7F"];E.N(d,G(){b["7C"+6]=0;b["7B"+6+"5Z"]=0});E.2k(e,b,G(){9(E(e).3t(\':3R\')){42=e.7A;41=e.7w}J{e=E(e.4R(Q)).1Y(":4k").5W("2Q").2D().17({4C:"1P",2X:"4F",19:"2Z",7o:"0",1S:"0"}).5R(e.12)[0];H a=E.17(e.12,"2X")||"3V";9(a=="3V")e.12.R.2X="7g";42=e.7e;41=e.7b;9(a=="3V")e.12.R.2X="3V";e.12.3b(e)}});I p=="1H"?42:41}I E.3C(e,p)},3C:G(h,j,i){H g,2w=[],2k=[];G 3n(a){9(!E.V.1N)I P;H b=U.3o.3Z(a,S);I!b||b.4y("3n")==""}9(j=="1r"&&E.V.1h){g=E.1x(h.R,"1r");I g==""?"1":g}9(j.1t(/4u/i))j=y;9(!i&&h.R[j])g=h.R[j];J 9(U.3o&&U.3o.3Z){9(j.1t(/4u/i))j="4u";j=j.1p(/([A-Z])/g,"-$1").2p();H d=U.3o.3Z(h,S);9(d&&!3n(h))g=d.4y(j);J{L(H a=h;a&&3n(a);a=a.12)2w.4w(a);L(a=0;a<2w.K;a++)9(3n(2w[a])){2k[a]=2w[a].R.19;2w[a].R.19="2Z"}g=j=="19"&&2k[2w.K-1]!=S?"2s":U.3o.3Z(h,S).4y(j)||"";L(a=0;a<2k.K;a++)9(2k[a]!=S)2w[a].R.19=2k[a]}9(j=="1r"&&g=="")g="1"}J 9(h.3Q){H f=j.1p(/\\-(\\w)/g,G(m,c){I c.27()});g=h.3Q[j]||h.3Q[f];9(!/^\\d+(2T)?$/i.14(g)&&/^\\d/.14(g)){H k=h.R.1S;H e=h.4v.1S;h.4v.1S=h.3Q.1S;h.R.1S=g||0;g=h.R.71+"2T";h.R.1S=k;h.4v.1S=e}}I g},4D:G(a,e){H r=[];e=e||U;E.N(a,G(i,d){9(!d)I;9(d.1c==4W)d=d.3s();9(1m d=="1M"){d=d.1p(/(<(\\w+)[^>]*?)\\/>/g,G(m,a,b){I b.1t(/^(70|6Z|6Y|9Q|4t|9N|9K|3a|9G|9E)$/i)?m:a+">"});H s=E.36(d).2p(),1s=e.5B("1s"),2x=[];H c=!s.1g("<9y")&&[1,"<24>",""]||!s.1g("<9w")&&[1,"<6T>",""]||s.1t(/^<(9u|1K|9t|9r|9p)/)&&[1,"<1I>",""]||!s.1g("<4m")&&[2,"<1I><1K>",""]||(!s.1g("<9m")||!s.1g("<9k"))&&[3,"<1I><1K><4m>",""]||!s.1g("<6Y")&&[2,"<1I><1K><6L>",""]||E.V.1h&&[1,"1s<1s>",""]||[0,"",""];1s.3O=c[1]+d+c[2];1W(c[0]--)1s=1s.5p;9(E.V.1h){9(!s.1g("<1I")&&s.1g("<1K")<0)2x=1s.1w&&1s.1w.3j;J 9(c[1]=="<1I>"&&s.1g("<1K")<0)2x=1s.3j;L(H n=2x.K-1;n>=0;--n)9(E.11(2x[n],"1K")&&!2x[n].3j.K)2x[n].12.3b(2x[n]);9(/^\\s/.14(d))1s.3d(e.6F(d.1t(/^\\s*/)[0]),1s.1w)}d=E.2h(1s.3j)}9(0===d.K&&(!E.11(d,"2Y")&&!E.11(d,"24")))I;9(d[0]==W||E.11(d,"2Y")||d.Y)r.1a(d);J r=E.1R(r,d)});I r},1x:G(c,d,a){H e=E.4a(c)?{}:E.5o;9(d=="26"&&E.V.1N)c.12.4Z;9(e[d]){9(a!=W)c[e[d]]=a;I c[e[d]]}J 9(E.V.1h&&d=="R")I E.1x(c.R,"9e",a);J 9(a==W&&E.V.1h&&E.11(c,"2Y")&&(d=="9d"||d=="9a"))I c.97(d).6x;J 9(c.37){9(a!=W){9(d=="O"&&E.11(c,"4t")&&c.12)6G"O 94 93\'t 92 91";c.90(d,a)}9(E.V.1h&&/6C|3k/.14(d)&&!E.4a(c))I c.4p(d,2);I c.4p(d)}J{9(d=="1r"&&E.V.1h){9(a!=W){c.69=1;c.1E=(c.1E||"").1p(/6O\\([^)]*\\)/,"")+(3I(a).3s()=="8S"?"":"6O(1r="+a*6A+")")}I c.1E?(3I(c.1E.1t(/1r=([^)]*)/)[1])/6A).3s():""}d=d.1p(/-([a-z])/8Q,G(z,b){I b.27()});9(a!=W)c[d]=a;I c[d]}},36:G(t){I(t||"").1p(/^\\s+|\\s+$/g,"")},2h:G(a){H r=[];9(1m a!="8P")L(H i=0,2c=a.K;i<2c;i++)r.1a(a[i]);J r=a.2J(0);I r},2A:G(b,a){L(H i=0,2c=a.K;i<2c;i++)9(a[i]==b)I i;I-1},1R:G(a,b){9(E.V.1h){L(H i=0;b[i];i++)9(b[i].1y!=8)a.1a(b[i])}J L(H i=0;b[i];i++)a.1a(b[i]);I a},4V:G(b){H r=[],2f={};2a{L(H i=0,6y=b.K;i<6y;i++){H a=E.M(b[i]);9(!2f[a]){2f[a]=Q;r.1a(b[i])}}}29(e){r=b}I r},2W:G(b,a,c){9(1m a=="1M")a=3w("P||G(a,i){I "+a+"}");H d=[];L(H i=0,4g=b.K;i<4g;i++)9(!c&&a(b[i],i)||c&&!a(b[i],i))d.1a(b[i]);I d},1X:G(c,b){9(1m b=="1M")b=3w("P||G(a){I "+b+"}");H d=[];L(H i=0,4g=c.K;i<4g;i++){H a=b(c[i],i);9(a!==S&&a!=W){9(a.1c!=1B)a=[a];d=d.8M(a)}}I d}});H v=8K.8I.2p();E.V={4s:(v.1t(/.+(?:8F|8E|8C|8B)[\\/: ]([\\d.]+)/)||[])[1],1N:/6w/.14(v),34:/34/.14(v),1h:/1h/.14(v)&&!/34/.14(v),35:/35/.14(v)&&!/(8z|6w)/.14(v)};H y=E.V.1h?"4h":"5h";E.1k({5g:!E.V.1h||U.8y=="8x",4h:E.V.1h?"4h":"5h",5o:{"L":"8w","8v":"1o","4u":y,5h:y,4h:y,3O:"3O",1o:"1o",1Q:"1Q",3c:"3c",2Q:"2Q",8u:"8t",26:"26",8s:"8r"}});E.N({1D:"a.12",8q:"15.4e(a,\'12\')",8p:"15.2I(a,2,\'2q\')",8n:"15.2I(a,2,\'4d\')",8l:"15.4e(a,\'2q\')",8k:"15.4e(a,\'4d\')",8j:"15.5d(a.12.1w,a)",8i:"15.5d(a.1w)",6q:"15.11(a,\'8h\')?a.8f||a.8e.U:15.2h(a.3j)"},G(i,n){E.1b[i]=G(a){H b=E.1X(6,n);9(a&&1m a=="1M")b=E.3m(a,b);I 6.2o(E.4V(b))}});E.N({5R:"3g",8c:"6j",3d:"6g",8b:"50",89:"6H"},G(i,n){E.1b[i]=G(){H a=1q;I 6.N(G(){L(H j=0,2c=a.K;j<2c;j++)E(a[j])[n](6)})}});E.N({5W:G(a){E.1x(6,a,"");6.53(a)},88:G(c){E.1o.1f(6,c)},87:G(c){E.1o.28(6,c)},86:G(c){E.1o[E.1o.3K(6,c)?"28":"1f"](6,c)},28:G(a){9(!a||E.1E(a,[6]).r.K){E.30(6);6.12.3b(6)}},4n:G(){E("*",6).N(G(){E.30(6)});1W(6.1w)6.3b(6.1w)}},G(i,n){E.1b[i]=G(){I 6.N(n,1q)}});E.N(["85","5Z"],G(i,a){H n=a.2p();E.1b[n]=G(h){I 6[0]==18?E.V.1N&&3y["84"+a]||E.5g&&38.33(U.2V["5a"+a],U.1G["5a"+a])||U.1G["5a"+a]:6[0]==U?38.33(U.1G["6n"+a],U.1G["6m"+a]):h==W?(6.K?E.17(6[0],n):S):6.17(n,h.1c==3X?h:h+"2T")}});H C=E.V.1N&&3x(E.V.4s)<83?"(?:[\\\\w*57-]|\\\\\\\\.)":"(?:[\\\\w\\82-\\81*57-]|\\\\\\\\.)",6k=1u 47("^>\\\\s*("+C+"+)"),6i=1u 47("^("+C+"+)(#)("+C+"+)"),6h=1u 47("^([#.]?)("+C+"*)");E.1k({55:{"":"m[2]==\'*\'||15.11(a,m[2])","#":"a.4p(\'22\')==m[2]",":":{80:"im[3]-0",2I:"m[3]-0==i",6E:"m[3]-0==i",3v:"i==0",3u:"i==r.K-1",6f:"i%2==0",6e:"i%2","3v-46":"a.12.4l(\'*\')[0]==a","3u-46":"15.2I(a.12.5p,1,\'4d\')==a","7X-46":"!15.2I(a.12.5p,2,\'4d\')",1D:"a.1w",4n:"!a.1w",7W:"(a.6s||a.7V||15(a).2g()||\'\').1g(m[3])>=0",3R:\'"1P"!=a.O&&15.17(a,"19")!="2s"&&15.17(a,"4C")!="1P"\',1P:\'"1P"==a.O||15.17(a,"19")=="2s"||15.17(a,"4C")=="1P"\',7U:"!a.3c",3c:"a.3c",2Q:"a.2Q",26:"a.26||15.1x(a,\'26\')",2g:"\'2g\'==a.O",4k:"\'4k\'==a.O",5j:"\'5j\'==a.O",54:"\'54\'==a.O",52:"\'52\'==a.O",51:"\'51\'==a.O",6d:"\'6d\'==a.O",6c:"\'6c\'==a.O",2r:\'"2r"==a.O||15.11(a,"2r")\',4t:"/4t|24|6b|2r/i.14(a.11)",3K:"15.1Y(m[3],a).K",7S:"/h\\\\d/i.14(a.11)",7R:"15.2W(15.32,G(1b){I a==1b.T;}).K"}},6a:[/^(\\[) *@?([\\w-]+) *([!*$^~=]*) *(\'?"?)(.*?)\\4 *\\]/,/^(:)([\\w-]+)\\("?\'?(.*?(\\(.*?\\))?[^(]*?)"?\'?\\)/,1u 47("^([:.#]*)("+C+"+)")],3m:G(a,c,b){H d,2b=[];1W(a&&a!=d){d=a;H f=E.1E(a,c,b);a=f.t.1p(/^\\s*,\\s*/,"");2b=b?c=f.r:E.1R(2b,f.r)}I 2b},1Y:G(t,o){9(1m t!="1M")I[t];9(o&&!o.1y)o=S;o=o||U;H d=[o],2f=[],3u;1W(t&&3u!=t){H r=[];3u=t;t=E.36(t);H l=P;H g=6k;H m=g.2S(t);9(m){H p=m[1].27();L(H i=0;d[i];i++)L(H c=d[i].1w;c;c=c.2q)9(c.1y==1&&(p=="*"||c.11.27()==p.27()))r.1a(c);d=r;t=t.1p(g,"");9(t.1g(" ")==0)6r;l=Q}J{g=/^([>+~])\\s*(\\w*)/i;9((m=g.2S(t))!=S){r=[];H p=m[2],1R={};m=m[1];L(H j=0,31=d.K;j<31;j++){H n=m=="~"||m=="+"?d[j].2q:d[j].1w;L(;n;n=n.2q)9(n.1y==1){H h=E.M(n);9(m=="~"&&1R[h])1T;9(!p||n.11.27()==p.27()){9(m=="~")1R[h]=Q;r.1a(n)}9(m=="+")1T}}d=r;t=E.36(t.1p(g,""));l=Q}}9(t&&!l){9(!t.1g(",")){9(o==d[0])d.44();2f=E.1R(2f,d);r=d=[o];t=" "+t.68(1,t.K)}J{H k=6i;H m=k.2S(t);9(m){m=[0,m[2],m[3],m[1]]}J{k=6h;m=k.2S(t)}m[2]=m[2].1p(/\\\\/g,"");H f=d[d.K-1];9(m[1]=="#"&&f&&f.3S&&!E.4a(f)){H q=f.3S(m[2]);9((E.V.1h||E.V.34)&&q&&1m q.22=="1M"&&q.22!=m[2])q=E(\'[@22="\'+m[2]+\'"]\',f)[0];d=r=q&&(!m[3]||E.11(q,m[3]))?[q]:[]}J{L(H i=0;d[i];i++){H a=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];9(a=="*"&&d[i].11.2p()=="5i")a="3a";r=E.1R(r,d[i].4l(a))}9(m[1]==".")r=E.4X(r,m[2]);9(m[1]=="#"){H e=[];L(H i=0;r[i];i++)9(r[i].4p("22")==m[2]){e=[r[i]];1T}r=e}d=r}t=t.1p(k,"")}}9(t){H b=E.1E(t,r);d=r=b.r;t=E.36(b.t)}}9(t)d=[];9(d&&o==d[0])d.44();2f=E.1R(2f,d);I 2f},4X:G(r,m,a){m=" "+m+" ";H c=[];L(H i=0;r[i];i++){H b=(" "+r[i].1o+" ").1g(m)>=0;9(!a&&b||a&&!b)c.1a(r[i])}I c},1E:G(t,r,h){H d;1W(t&&t!=d){d=t;H p=E.6a,m;L(H i=0;p[i];i++){m=p[i].2S(t);9(m){t=t.7O(m[0].K);m[2]=m[2].1p(/\\\\/g,"");1T}}9(!m)1T;9(m[1]==":"&&m[2]=="5V")r=E.1E(m[3],r,Q).r;J 9(m[1]==".")r=E.4X(r,m[2],h);J 9(m[1]=="["){H g=[],O=m[3];L(H i=0,31=r.K;i<31;i++){H a=r[i],z=a[E.5o[m[2]]||m[2]];9(z==S||/6C|3k|26/.14(m[2]))z=E.1x(a,m[2])||\'\';9((O==""&&!!z||O=="="&&z==m[5]||O=="!="&&z!=m[5]||O=="^="&&z&&!z.1g(m[5])||O=="$="&&z.68(z.K-m[5].K)==m[5]||(O=="*="||O=="~=")&&z.1g(m[5])>=0)^h)g.1a(a)}r=g}J 9(m[1]==":"&&m[2]=="2I-46"){H e={},g=[],14=/(\\d*)n\\+?(\\d*)/.2S(m[3]=="6f"&&"2n"||m[3]=="6e"&&"2n+1"||!/\\D/.14(m[3])&&"n+"+m[3]||m[3]),3v=(14[1]||1)-0,d=14[2]-0;L(H i=0,31=r.K;i<31;i++){H j=r[i],12=j.12,22=E.M(12);9(!e[22]){H c=1;L(H n=12.1w;n;n=n.2q)9(n.1y==1)n.4U=c++;e[22]=Q}H b=P;9(3v==1){9(d==0||j.4U==d)b=Q}J 9((j.4U+d)%3v==0)b=Q;9(b^h)g.1a(j)}r=g}J{H f=E.55[m[1]];9(1m f!="1M")f=E.55[m[1]][m[2]];f=3w("P||G(a,i){I "+f+"}");r=E.2W(r,f,h)}}I{r:r,t:t}},4e:G(b,c){H d=[];H a=b[c];1W(a&&a!=U){9(a.1y==1)d.1a(a);a=a[c]}I d},2I:G(a,e,c,b){e=e||1;H d=0;L(;a;a=a[c])9(a.1y==1&&++d==e)1T;I a},5d:G(n,a){H r=[];L(;n;n=n.2q){9(n.1y==1&&(!a||n!=a))r.1a(n)}I r}});E.1j={1f:G(g,e,c,h){9(E.V.1h&&g.4j!=W)g=18;9(!c.2u)c.2u=6.2u++;9(h!=W){H d=c;c=G(){I d.16(6,1q)};c.M=h;c.2u=d.2u}H i=e.2l(".");e=i[0];c.O=i[1];H b=E.M(g,"2P")||E.M(g,"2P",{});H f=E.M(g,"2t",G(){H a;9(1m E=="W"||E.1j.4T)I a;a=E.1j.2t.16(g,1q);I a});H j=b[e];9(!j){j=b[e]={};9(g.4S)g.4S(e,f,P);J g.7N("43"+e,f)}j[c.2u]=c;6.1Z[e]=Q},2u:1,1Z:{},28:G(d,c,b){H e=E.M(d,"2P"),2L,4I;9(1m c=="1M"){H a=c.2l(".");c=a[0]}9(e){9(c&&c.O){b=c.4Q;c=c.O}9(!c){L(c 1i e)6.28(d,c)}J 9(e[c]){9(b)2E e[c][b.2u];J L(b 1i e[c])9(!a[1]||e[c][b].O==a[1])2E e[c][b];L(2L 1i e[c])1T;9(!2L){9(d.4P)d.4P(c,E.M(d,"2t"),P);J d.7M("43"+c,E.M(d,"2t"));2L=S;2E e[c]}}L(2L 1i e)1T;9(!2L){E.30(d,"2P");E.30(d,"2t")}}},1F:G(d,b,e,c,f){b=E.2h(b||[]);9(!e){9(6.1Z[d])E("*").1f([18,U]).1F(d,b)}J{H a,2L,1b=E.1n(e[d]||S),4N=!b[0]||!b[0].2M;9(4N)b.4w(6.4M({O:d,2m:e}));b[0].O=d;9(E.1n(E.M(e,"2t")))a=E.M(e,"2t").16(e,b);9(!1b&&e["43"+d]&&e["43"+d].16(e,b)===P)a=P;9(4N)b.44();9(f&&f.16(e,b)===P)a=P;9(1b&&c!==P&&a!==P&&!(E.11(e,\'a\')&&d=="4L")){6.4T=Q;e[d]()}6.4T=P}I a},2t:G(d){H a;d=E.1j.4M(d||18.1j||{});H b=d.O.2l(".");d.O=b[0];H c=E.M(6,"2P")&&E.M(6,"2P")[d.O],3q=1B.3A.2J.2O(1q,1);3q.4w(d);L(H j 1i c){3q[0].4Q=c[j];3q[0].M=c[j].M;9(!b[1]||c[j].O==b[1]){H e=c[j].16(6,3q);9(a!==P)a=e;9(e===P){d.2M();d.3p()}}}9(E.V.1h)d.2m=d.2M=d.3p=d.4Q=d.M=S;I a},4M:G(c){H a=c;c=E.1k({},a);c.2M=G(){9(a.2M)a.2M();a.7L=P};c.3p=G(){9(a.3p)a.3p();a.7K=Q};9(!c.2m&&c.65)c.2m=c.65;9(E.V.1N&&c.2m.1y==3)c.2m=a.2m.12;9(!c.4K&&c.4J)c.4K=c.4J==c.2m?c.7H:c.4J;9(c.64==S&&c.63!=S){H e=U.2V,b=U.1G;c.64=c.63+(e&&e.2R||b.2R||0);c.7E=c.7D+(e&&e.2B||b.2B||0)}9(!c.3Y&&(c.61||c.60))c.3Y=c.61||c.60;9(!c.5F&&c.5D)c.5F=c.5D;9(!c.3Y&&c.2r)c.3Y=(c.2r&1?1:(c.2r&2?3:(c.2r&4?2:0)));I c}};E.1b.1k({3W:G(c,a,b){I c=="5Y"?6.2G(c,a,b):6.N(G(){E.1j.1f(6,c,b||a,b&&a)})},2G:G(d,b,c){I 6.N(G(){E.1j.1f(6,d,G(a){E(6).5X(a);I(c||b).16(6,1q)},c&&b)})},5X:G(a,b){I 6.N(G(){E.1j.28(6,a,b)})},1F:G(c,a,b){I 6.N(G(){E.1j.1F(c,a,6,Q,b)})},7x:G(c,a,b){9(6[0])I E.1j.1F(c,a,6[0],P,b)},25:G(){H a=1q;I 6.4L(G(e){6.4H=0==6.4H?1:0;e.2M();I a[6.4H].16(6,[e])||P})},7v:G(f,g){G 4G(e){H p=e.4K;1W(p&&p!=6)2a{p=p.12}29(e){p=6};9(p==6)I P;I(e.O=="4x"?f:g).16(6,[e])}I 6.4x(4G).5U(4G)},2d:G(f){5T();9(E.3T)f.16(U,[E]);J E.3l.1a(G(){I f.16(6,[E])});I 6}});E.1k({3T:P,3l:[],2d:G(){9(!E.3T){E.3T=Q;9(E.3l){E.N(E.3l,G(){6.16(U)});E.3l=S}9(E.V.35||E.V.34)U.4P("5S",E.2d,P);9(!18.7t.K)E(18).39(G(){E("#4E").28()})}}});E.N(("7s,7r,39,7q,6n,5Y,4L,7p,"+"7n,7m,7l,4x,5U,7k,24,"+"51,7j,7i,7h,3U").2l(","),G(i,o){E.1b[o]=G(f){I f?6.3W(o,f):6.1F(o)}});H x=P;G 5T(){9(x)I;x=Q;9(E.V.35||E.V.34)U.4S("5S",E.2d,P);J 9(E.V.1h){U.7f("<7d"+"7y 22=4E 7z=Q "+"3k=//:><\\/1J>");H a=U.3S("4E");9(a)a.62=G(){9(6.2C!="1l")I;E.2d()};a=S}J 9(E.V.1N)E.4B=4j(G(){9(U.2C=="5Q"||U.2C=="1l"){4A(E.4B);E.4B=S;E.2d()}},10);E.1j.1f(18,"39",E.2d)}E.1b.1k({39:G(g,d,c){9(E.1n(g))I 6.3W("39",g);H e=g.1g(" ");9(e>=0){H i=g.2J(e,g.K);g=g.2J(0,e)}c=c||G(){};H f="4z";9(d)9(E.1n(d)){c=d;d=S}J{d=E.3a(d);f="5P"}H h=6;E.3G({1d:g,O:f,M:d,1l:G(a,b){9(b=="1C"||b=="5O")h.4o(i?E("<1s/>").3g(a.40.1p(/<1J(.|\\s)*?\\/1J>/g,"")).1Y(i):a.40);56(G(){h.N(c,[a.40,b,a])},13)}});I 6},7a:G(){I E.3a(6.5M())},5M:G(){I 6.1X(G(){I E.11(6,"2Y")?E.2h(6.79):6}).1E(G(){I 6.2H&&!6.3c&&(6.2Q||/24|6b/i.14(6.11)||/2g|1P|52/i.14(6.O))}).1X(G(i,c){H b=E(6).3i();I b==S?S:b.1c==1B?E.1X(b,G(a,i){I{2H:c.2H,1Q:a}}):{2H:c.2H,1Q:b}}).21()}});E.N("5L,5K,6t,5J,5I,5H".2l(","),G(i,o){E.1b[o]=G(f){I 6.3W(o,f)}});H B=(1u 3D).3B();E.1k({21:G(d,b,a,c){9(E.1n(b)){a=b;b=S}I E.3G({O:"4z",1d:d,M:b,1C:a,1V:c})},78:G(b,a){I E.21(b,S,a,"1J")},77:G(c,b,a){I E.21(c,b,a,"45")},76:G(d,b,a,c){9(E.1n(b)){a=b;b={}}I E.3G({O:"5P",1d:d,M:b,1C:a,1V:c})},75:G(a){E.1k(E.59,a)},59:{1Z:Q,O:"4z",2z:0,5G:"74/x-73-2Y-72",6o:Q,3e:Q,M:S},49:{},3G:G(s){H f,2y=/=(\\?|%3F)/g,1v,M;s=E.1k(Q,s,E.1k(Q,{},E.59,s));9(s.M&&s.6o&&1m s.M!="1M")s.M=E.3a(s.M);9(s.1V=="4b"){9(s.O.2p()=="21"){9(!s.1d.1t(2y))s.1d+=(s.1d.1t(/\\?/)?"&":"?")+(s.4b||"5E")+"=?"}J 9(!s.M||!s.M.1t(2y))s.M=(s.M?s.M+"&":"")+(s.4b||"5E")+"=?";s.1V="45"}9(s.1V=="45"&&(s.M&&s.M.1t(2y)||s.1d.1t(2y))){f="4b"+B++;9(s.M)s.M=s.M.1p(2y,"="+f);s.1d=s.1d.1p(2y,"="+f);s.1V="1J";18[f]=G(a){M=a;1C();1l();18[f]=W;2a{2E 18[f]}29(e){}}}9(s.1V=="1J"&&s.1L==S)s.1L=P;9(s.1L===P&&s.O.2p()=="21")s.1d+=(s.1d.1t(/\\?/)?"&":"?")+"57="+(1u 3D()).3B();9(s.M&&s.O.2p()=="21"){s.1d+=(s.1d.1t(/\\?/)?"&":"?")+s.M;s.M=S}9(s.1Z&&!E.5b++)E.1j.1F("5L");9(!s.1d.1g("8g")&&s.1V=="1J"){H h=U.4l("9U")[0];H g=U.5B("1J");g.3k=s.1d;9(!f&&(s.1C||s.1l)){H j=P;g.9R=g.62=G(){9(!j&&(!6.2C||6.2C=="5Q"||6.2C=="1l")){j=Q;1C();1l();h.3b(g)}}}h.58(g);I}H k=P;H i=18.6X?1u 6X("9P.9O"):1u 6W();i.9M(s.O,s.1d,s.3e);9(s.M)i.5C("9J-9I",s.5G);9(s.5y)i.5C("9H-5x-9F",E.49[s.1d]||"9D, 9C 9B 9A 5v:5v:5v 9z");i.5C("X-9x-9v","6W");9(s.6U)s.6U(i);9(s.1Z)E.1j.1F("5H",[i,s]);H c=G(a){9(!k&&i&&(i.2C==4||a=="2z")){k=Q;9(d){4A(d);d=S}1v=a=="2z"&&"2z"||!E.6S(i)&&"3U"||s.5y&&E.6R(i,s.1d)&&"5O"||"1C";9(1v=="1C"){2a{M=E.6Q(i,s.1V)}29(e){1v="5k"}}9(1v=="1C"){H b;2a{b=i.5s("6P-5x")}29(e){}9(s.5y&&b)E.49[s.1d]=b;9(!f)1C()}J E.5r(s,i,1v);1l();9(s.3e)i=S}};9(s.3e){H d=4j(c,13);9(s.2z>0)56(G(){9(i){i.9q();9(!k)c("2z")}},s.2z)}2a{i.9o(s.M)}29(e){E.5r(s,i,S,e)}9(!s.3e)c();I i;G 1C(){9(s.1C)s.1C(M,1v);9(s.1Z)E.1j.1F("5I",[i,s])}G 1l(){9(s.1l)s.1l(i,1v);9(s.1Z)E.1j.1F("6t",[i,s]);9(s.1Z&&!--E.5b)E.1j.1F("5K")}},5r:G(s,a,b,e){9(s.3U)s.3U(a,b,e);9(s.1Z)E.1j.1F("5J",[a,s,e])},5b:0,6S:G(r){2a{I!r.1v&&9n.9l=="54:"||(r.1v>=6N&&r.1v<9j)||r.1v==6M||E.V.1N&&r.1v==W}29(e){}I P},6R:G(a,c){2a{H b=a.5s("6P-5x");I a.1v==6M||b==E.49[c]||E.V.1N&&a.1v==W}29(e){}I P},6Q:G(r,b){H c=r.5s("9i-O");H d=b=="6K"||!b&&c&&c.1g("6K")>=0;H a=d?r.9g:r.40;9(d&&a.2V.37=="5k")6G"5k";9(b=="1J")E.5f(a);9(b=="45")a=3w("("+a+")");I a},3a:G(a){H s=[];9(a.1c==1B||a.4c)E.N(a,G(){s.1a(3f(6.2H)+"="+3f(6.1Q))});J L(H j 1i a)9(a[j]&&a[j].1c==1B)E.N(a[j],G(){s.1a(3f(j)+"="+3f(6))});J s.1a(3f(j)+"="+3f(a[j]));I s.66("&").1p(/%20/g,"+")}});E.1b.1k({1A:G(b,a){I b?6.1U({1H:"1A",2N:"1A",1r:"1A"},b,a):6.1E(":1P").N(G(){6.R.19=6.3h?6.3h:"";9(E.17(6,"19")=="2s")6.R.19="2Z"}).2D()},1z:G(b,a){I b?6.1U({1H:"1z",2N:"1z",1r:"1z"},b,a):6.1E(":3R").N(G(){6.3h=6.3h||E.17(6,"19");9(6.3h=="2s")6.3h="2Z";6.R.19="2s"}).2D()},6J:E.1b.25,25:G(a,b){I E.1n(a)&&E.1n(b)?6.6J(a,b):a?6.1U({1H:"25",2N:"25",1r:"25"},a,b):6.N(G(){E(6)[E(6).3t(":1P")?"1A":"1z"]()})},9c:G(b,a){I 6.1U({1H:"1A"},b,a)},9b:G(b,a){I 6.1U({1H:"1z"},b,a)},99:G(b,a){I 6.1U({1H:"25"},b,a)},98:G(b,a){I 6.1U({1r:"1A"},b,a)},96:G(b,a){I 6.1U({1r:"1z"},b,a)},95:G(c,a,b){I 6.1U({1r:a},c,b)},1U:G(k,i,h,g){H j=E.6D(i,h,g);I 6[j.3L===P?"N":"3L"](G(){j=E.1k({},j);H f=E(6).3t(":1P"),3y=6;L(H p 1i k){9(k[p]=="1z"&&f||k[p]=="1A"&&!f)I E.1n(j.1l)&&j.1l.16(6);9(p=="1H"||p=="2N"){j.19=E.17(6,"19");j.2U=6.R.2U}}9(j.2U!=S)6.R.2U="1P";j.3M=E.1k({},k);E.N(k,G(c,a){H e=1u E.2j(3y,j,c);9(/25|1A|1z/.14(a))e[a=="25"?f?"1A":"1z":a](k);J{H b=a.3s().1t(/^([+-]=)?([\\d+-.]+)(.*)$/),1O=e.2b(Q)||0;9(b){H d=3I(b[2]),2i=b[3]||"2T";9(2i!="2T"){3y.R[c]=(d||1)+2i;1O=((d||1)/e.2b(Q))*1O;3y.R[c]=1O+2i}9(b[1])d=((b[1]=="-="?-1:1)*d)+1O;e.3N(1O,d,2i)}J e.3N(1O,a,"")}});I Q})},3L:G(a,b){9(E.1n(a)){b=a;a="2j"}9(!a||(1m a=="1M"&&!b))I A(6[0],a);I 6.N(G(){9(b.1c==1B)A(6,a,b);J{A(6,a).1a(b);9(A(6,a).K==1)b.16(6)}})},9f:G(){H a=E.32;I 6.N(G(){L(H i=0;i-8O?r:3I(E.17(6.T,6.1e))||0},3N:G(c,b,e){6.5u=(1u 3D()).3B();6.1O=c;6.2D=b;6.2i=e||6.2i||"2T";6.2v=6.1O;6.4q=6.4i=0;6.4r();H f=6;G t(){I f.2F()}t.T=6.T;E.32.1a(t);9(E.32.K==1){H d=4j(G(){H a=E.32;L(H i=0;i6.Y.2e+6.5u){6.2v=6.2D;6.4q=6.4i=1;6.4r();6.Y.3M[6.1e]=Q;H a=Q;L(H i 1i 6.Y.3M)9(6.Y.3M[i]!==Q)a=P;9(a){9(6.Y.19!=S){6.T.R.2U=6.Y.2U;6.T.R.19=6.Y.19;9(E.17(6.T,"19")=="2s")6.T.R.19="2Z"}9(6.Y.1z)6.T.R.19="2s";9(6.Y.1z||6.Y.1A)L(H p 1i 6.Y.3M)E.1x(6.T.R,p,6.Y.3P[p])}9(a&&E.1n(6.Y.1l))6.Y.1l.16(6.T);I P}J{H n=t-6.5u;6.4i=n/6.Y.2e;6.4q=E.3J[6.Y.3J||(E.3J.5q?"5q":"6B")](6.4i,n,0,1,6.Y.2e);6.2v=6.1O+((6.2D-6.1O)*6.4q);6.4r()}I Q}};E.2j.2F={2R:G(a){a.T.2R=a.2v},2B:G(a){a.T.2B=a.2v},1r:G(a){E.1x(a.T.R,"1r",a.2v)},6z:G(a){a.T.R[a.1e]=a.2v+a.2i}};E.1b.6m=G(){H c=0,3E=0,T=6[0],5t;9(T)8L(E.V){H b=E.17(T,"2X")=="4F",1D=T.12,23=T.23,2K=T.3H,4f=1N&&3x(4s)<8J;9(T.6V){5w=T.6V();1f(5w.1S+38.33(2K.2V.2R,2K.1G.2R),5w.3E+38.33(2K.2V.2B,2K.1G.2B));9(1h){H d=E("4o").17("8H");d=(d=="8G"||E.5g&&3x(4s)>=7)&&2||d;1f(-d,-d)}}J{1f(T.5l,T.5z);1W(23){1f(23.5l,23.5z);9(35&&/^t[d|h]$/i.14(1D.37)||!4f)d(23);9(4f&&!b&&E.17(23,"2X")=="4F")b=Q;23=23.23}1W(1D.37&&!/^1G|4o$/i.14(1D.37)){9(!/^8D|1I-9S.*$/i.14(E.17(1D,"19")))1f(-1D.2R,-1D.2B);9(35&&E.17(1D,"2U")!="3R")d(1D);1D=1D.12}9(4f&&b)1f(-2K.1G.5l,-2K.1G.5z)}5t={3E:3E,1S:c}}I 5t;G d(a){1f(E.17(a,"9T"),E.17(a,"8A"))}G 1f(l,t){c+=3x(l)||0;3E+=3x(t)||0}}})();',62,616,'||||||this|||if|||||||||||||||||||||||||||||||||function|var|return|else|length|for|data|each|type|false|true|style|null|elem|document|browser|undefined||options|||nodeName|parentNode||test|jQuery|apply|css|window|display|push|fn|constructor|url|prop|add|indexOf|msie|in|event|extend|complete|typeof|isFunction|className|replace|arguments|opacity|div|match|new|status|firstChild|attr|nodeType|hide|show|Array|success|parent|filter|trigger|body|height|table|script|tbody|cache|string|safari|start|hidden|value|merge|left|break|animate|dataType|while|map|find|global||get|id|offsetParent|select|toggle|selected|toUpperCase|remove|catch|try|cur|al|ready|duration|done|text|makeArray|unit|fx|swap|split|target||pushStack|toLowerCase|nextSibling|button|none|handle|guid|now|stack|tb|jsre|timeout|inArray|scrollTop|readyState|end|delete|step|one|name|nth|slice|doc|ret|preventDefault|width|call|events|checked|scrollLeft|exec|px|overflow|documentElement|grep|position|form|block|removeData|rl|timers|max|opera|mozilla|trim|tagName|Math|load|param|removeChild|disabled|insertBefore|async|encodeURIComponent|append|oldblock|val|childNodes|src|readyList|multiFilter|color|defaultView|stopPropagation|args|old|toString|is|last|first|eval|parseInt|self|domManip|prototype|getTime|curCSS|Date|top||ajax|ownerDocument|parseFloat|easing|has|queue|curAnim|custom|innerHTML|orig|currentStyle|visible|getElementById|isReady|error|static|bind|String|which|getComputedStyle|responseText|oWidth|oHeight|on|shift|json|child|RegExp|ol|lastModified|isXMLDoc|jsonp|jquery|previousSibling|dir|safari2|el|styleFloat|state|setInterval|radio|getElementsByTagName|tr|empty|html|getAttribute|pos|update|version|input|float|runtimeStyle|unshift|mouseover|getPropertyValue|GET|clearInterval|safariTimer|visibility|clean|__ie_init|absolute|handleHover|lastToggle|index|fromElement|relatedTarget|click|fix|evt|andSelf|removeEventListener|handler|cloneNode|addEventListener|triggered|nodeIndex|unique|Number|classFilter|prevObject|selectedIndex|after|submit|password|removeAttribute|file|expr|setTimeout|_|appendChild|ajaxSettings|client|active|win|sibling|deep|globalEval|boxModel|cssFloat|object|checkbox|parsererror|offsetLeft|wrapAll|dequeue|props|lastChild|swing|handleError|getResponseHeader|results|startTime|00|box|Modified|ifModified|offsetTop|evalScript|createElement|setRequestHeader|ctrlKey|callback|metaKey|contentType|ajaxSend|ajaxSuccess|ajaxError|ajaxStop|ajaxStart|serializeArray|init|notmodified|POST|loaded|appendTo|DOMContentLoaded|bindReady|mouseout|not|removeAttr|unbind|unload|Width|keyCode|charCode|onreadystatechange|clientX|pageX|srcElement|join|outerHTML|substr|zoom|parse|textarea|reset|image|odd|even|before|quickClass|quickID|prepend|quickChild|execScript|offset|scroll|processData|uuid|contents|continue|textContent|ajaxComplete|clone|setArray|webkit|nodeValue|fl|_default|100|linear|href|speed|eq|createTextNode|throw|replaceWith|splice|_toggle|xml|colgroup|304|200|alpha|Last|httpData|httpNotModified|httpSuccess|fieldset|beforeSend|getBoundingClientRect|XMLHttpRequest|ActiveXObject|col|br|abbr|pixelLeft|urlencoded|www|application|ajaxSetup|post|getJSON|getScript|elements|serialize|clientWidth|hasClass|scr|clientHeight|write|relative|keyup|keypress|keydown|change|mousemove|mouseup|mousedown|right|dblclick|resize|focus|blur|frames|instanceof|hover|offsetWidth|triggerHandler|ipt|defer|offsetHeight|border|padding|clientY|pageY|Left|Right|toElement|Bottom|Top|cancelBubble|returnValue|detachEvent|attachEvent|substring|line|weight|animated|header|font|enabled|innerText|contains|only|size|gt|lt|uFFFF|u0128|417|inner|Height|toggleClass|removeClass|addClass|replaceAll|noConflict|insertAfter|prependTo|wrap|contentWindow|contentDocument|http|iframe|children|siblings|prevAll|nextAll|wrapInner|prev|Boolean|next|parents|maxLength|maxlength|readOnly|readonly|class|htmlFor|CSS1Compat|compatMode|compatible|borderTopWidth|ie|ra|inline|it|rv|medium|borderWidth|userAgent|522|navigator|with|concat|1px|10000|array|ig|PI|NaN|400|reverse|fast|600|slow|Function|Object|setAttribute|changed|be|can|property|fadeTo|fadeOut|getAttributeNode|fadeIn|slideToggle|method|slideUp|slideDown|action|cssText|stop|responseXML|option|content|300|th|protocol|td|location|send|cap|abort|colg|cos|tfoot|thead|With|leg|Requested|opt|GMT|1970|Jan|01|Thu|area|Since|hr|If|Type|Content|meta|specified|open|link|XMLHTTP|Microsoft|img|onload|row|borderLeftWidth|head|attributes'.split('|'),0,{}); + +result += decompressedJQuery.length; + +/* + Copyright (c) 2004-2007, The Dojo Foundation + All Rights Reserved. + + Licensed under the Academic Free License version 2.1 or above OR the + modified BSD license. For more information on Dojo licensing, see: + + http://dojotoolkit.org/community/licensing.shtml +*/ + +/* + This is a compiled version of Dojo, built for deployment and not for + development. To get an editable version, please visit: + + http://dojotoolkit.org + + for documentation and information on getting the source. +*/ + +var decompressedDojo = function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('if(V z=="1k"){(B(){if(V D["1o"]=="1k"){D.1o={}}if((!D["1z"])||(!1z["ca"])){D.1z={}}A cn=["rA","rz","1K","ry","rx","9f","rw","rv","ru","rt","rs","rr","rq","ro","rn","rm"];A i=0,24;1s(24=cn[i++]){if(!1z[24]){1z[24]=B(){}}}if(V D["z"]=="1k"){D.z={}}z.1W=D;A d3={im:U,rl:U,rk:"",rj:"",ri:"",rh:K,rg:U};R(A 8z in d3){if(V 1o[8z]=="1k"){1o[8z]=d3[8z]}}A jK=["rf","rd","rc","rb"];A t;1s(t=jK.3a()){z["is"+t]=U}})();z.8h=1o.8h;z.cY={jJ:0,jI:9,jH:0,jG:"",jF:2V("$ra: r9 $".1f(/[0-9]+/)[0]),2i:B(){4G(z.cY){C jJ+"."+jI+"."+jH+jG+" ("+jF+")"}}};z.d1=B(jE,jD,1V){A 2h=1V||z.1W;R(A i=0,p;2h&&(p=jE[i]);i++){2h=(p in 2h?2h[p]:(jD?2h[p]={}:1k))}C 2h};z.88=B(jC,jA,jB){A d2=jC.1A("."),p=d2.8q(),M=z.d1(d2,K,jB);C(M&&p?(M[p]=jA):1k)};z.6q=B(jz,jy,jx){C z.d1(jz.1A("."),jy,jx)};z.r8=B(jw,M){C!!z.6q(jw,U,M)};z["3u"]=B(d0){C z.1W.3u?z.1W.3u(d0):3u(d0)};z.ia=B(jv,cZ,cX){A 8y="r7: "+jv;if(cZ){8y+=" "+cZ}if(cX){8y+=" -- r6 be r5 in cY: "+cX}1z.1K(8y)};z.r4=B(ju,cW){A cV="r3: "+ju+" -- r2 r1 4F r0 qZ qY.";if(cW){cV+=" "+cW}1z.1K(cV)};(B(){A cR={53:{},6p:0,1h:{},8k:{z:{1p:"z",1Z:"."},cU:{1p:"cU",1Z:"../qX/cU"},cT:{1p:"cT",1Z:"cT"}},cN:B(cS){A mp=D.8k;C jp(mp[cS]&&mp[cS].1Z)},jk:B(8x){A mp=D.8k;if(D.cN(8x)){C mp[8x].1Z}C 8x},8v:[],6t:U,56:[],8t:[],8u:U};R(A cQ in cR){z[cQ]=cR[cQ]}})();z.jg=B(8w,cP,cb){A 1g=(((8w.2s(0)=="/"||8w.1f(/^\\w+:/)))?"":D.51)+8w;if(1o.jt&&z.c8){1g+="?"+67(1o.jt).2f(/\\W+/g,"")}1u{C!cP?D.cO(1g,cb):D.jq(1g,cP,cb)}1y(e){1z.1K(e);C U}};z.cO=B(1g,cb){if(D.8v[1g]){C K}A 6u=D.iR(1g,K);if(!6u){C U}D.8v[1g]=K;D.8v.Y(1g);if(cb){6u="("+6u+")"}A jr=z["3u"](6u+"\\r\\n//@ qW="+1g);if(cb){cb(jr)}C K};z.jq=B(1g,jo,cb){A ok=U;1u{ok=D.cO(1g,cb)}1y(e){1z.1K("qV je ",1g," 4G 9f: ",e)}C jp(ok&&D.53[jo])};z.6m=B(){D.8u=K;D.6t=K;A 57=D.56;D.56=[];R(A x=0;x<57.G;x++){57[x]()}D.8u=U;if(z.6t&&z.6p==0&&D.56.G>0){z.8s()}};z.ck=B(){A 57=D.8t;1s(57.G){(57.8q())()}};z.qU=B(M,jn){A d=z;if(P.G==1){d.56.Y(M)}I{if(P.G>1){d.56.Y(B(){M[jn]()})}}if(d.6t&&d.6p==0&&!d.8u){d.8s()}};z.dW=B(M,jm){A d=z;if(P.G==1){d.8t.Y(M)}I{if(P.G>1){d.8t.Y(B(){M[jm]()})}}};z.iM=B(){if(D.6t){C}if(D.6p>0){1z.1K("qT qS in qR!");C}z.8s()};z.8s=B(){if(V 5c=="8b"||(1o["qQ"]&&z.2M)){5c("z.6m();",0)}I{z.6m()}};z.cF=B(jl){A 4v=jl.1A(".");R(A i=4v.G;i>0;i--){A 8r=4v.2w(0,i).22(".");if((i==1)&&!D.cN(8r)){4v[0]="../"+4v[0]}I{A cM=D.jk(8r);if(cM!=8r){4v.3S(0,i,cM);3f}}}C 4v};z.jj=U;z.8m=B(2T,qP,55){55=D.jj||55;A 54=D.53[2T];if(54){C 54}A cL=2T.1A(".");A 3L=D.cF(2T);A jh=((3L[0].2s(0)!="/")&&!3L[0].1f(/^\\w+:/));A ji=3L[3L.G-1];A 3m;if(ji=="*"){2T=cL.2w(0,-1).22(".");3L.8q();3m=3L.22("/")+"/"+(1o["qO"]||"qN")+".js";if(jh&&3m.2s(0)=="/"){3m=3m.2w(1)}}I{3m=3L.22("/")+".js";2T=cL.22(".")}A jf=(!55)?2T:L;A ok=D.jg(3m,jf);if((!ok)&&(!55)){2m S 1O("qM 3O 4E \'"+2T+"\'; 72 qL \'"+3m+"\'")}if((!55)&&(!D["qK"])){54=D.53[2T];if(!54){2m S 1O("qJ \'"+2T+"\' is 3O qI a8 je \'"+3m+"\'")}}C 54};z.8c=z.8m;z.1Q=B(cK){A cJ=cK+"";A 8p=cJ;A 6s=cK.1A(/\\./);if(6s[6s.G-1]=="*"){6s.8q();8p=6s.22(".")}A 8o=z.6q(8p,K);D.53[cJ]=8o;D.53[8p]=8o;C 8o};z.qH=B(8n){A jd=8n["qG"]||[];A cI=jd.3U(8n[z.j4]||8n["aY"]||[]);R(A x=0;x0&&!(j==1&&1X[0]=="")&&1X[j]==".."&&1X[j-1]!=".."){if(j==(1X.G-1)){1X.3S(j,1);1X[j-1]=""}I{1X.3S(j-1,2);j-=2}}}}1t.28=1X.22("/")}}}}1g="";if(1t.4t){1g+=1t.4t+":"}if(1t.3l){1g+="//"+1t.3l}1g+=1t.28;if(1t.1r){1g+="?"+1t.1r}if(1t.52){1g+="#"+1t.52}}D.1g=1g.2i();A r=D.1g.1f(j7);D.4t=r[2]||(r[1]?"":n);D.3l=r[4]||(r[3]?"":n);D.28=r[5];D.1r=r[7]||(r[6]?"":n);D.52=r[9]||(r[8]?"":n);if(D.3l!=n){r=D.3l.1f(j6);D.8X=r[3]||n;D.8W=r[4]||n;D.qw=r[5];D.qv=r[7]||n}};z.4r.1C.2i=B(){C D.1g}})();z.qu=B(j5,2E){A 2B=z.cF(j5).22("/");if(!2B){C L}if(2B.31("/")!=2B.G-1){2B+="/"}A cE=2B.T(":");if(2B.2s(0)!="/"&&(cE==-1||cE>2B.T("/"))){2B=z.51+2B}C S z.4r(2B,2E)};if(V 26!="1k"){z.c8=K;z.j4="qt";(B(){A d=z;if(1q&&1q.4I){A 8j=1q.4I("ak");A j3=/z(\\.qs)?\\.js([\\?\\.]|$)/i;R(A i=0;i<8j.G;i++){A 4X=8j[i].5t("4X");if(!4X){6c}A m=4X.1f(j3);if(m){if(!1o["51"]){1o["51"]=4X.21(0,m.hK)}A cD=8j[i].5t("1o");if(cD){A cC=3u("({ "+cD+" })");R(A x in cC){1o[x]=cC[x]}}3f}}}d.51=1o["51"];A n=cq;A 8i=n.iL;A 4Z=n.qr;A 6r=2k(4Z);d.2M=(8i.T("qq")>=0)?6r:0;d.6B=(4Z.T("qo")>=0)||(4Z.T("j2")>=0)?6r:0;d.3o=(4Z.T("j2")>=0)?6r:0;A j1=8i.T("qn");d.gu=d.7B=((j1>=0)&&(!d.6B))?6r:0;d.j0=0;d.1l=0;d.iV=0;1u{if(d.7B){d.j0=2k(8i.1A("qm/")[1].1A(" ")[0])}if((1q.gx)&&(!d.2M)){d.1l=2k(4Z.1A("qk ")[1].1A(";")[0])}}1y(e){}if(z.1l&&(26.8f.cu==="9q:")){1o.iT=K}d.iX=B(){A 2A;A qj;A cB=d.6q("cz.cy");if(cB){C cB}if(V iZ!="1k"){2A=S iZ()}I{if(d.1l){1u{2A=S 9j("qi.qh")}1y(e){}}I{if(cq.qg["8Z/x-iY"]){2A=1q.a9("8b");2A.cA("Z","8Z/x-iY");2A.cA("3n",0);2A.cA("58",0);2A.1c.gq="7C";1q.5K.4c(2A)}}}if(!2A){C L}z.88("cz.cy.qf",2A);C z.6q("cz.cy")};A iW=d.iX();if(iW){d.iV=K}A cm=1q["aX"];d.qe=(cm=="aW")||(cm=="gr")||(d.1l<6);d.8h=1o.8h||(d.1l?n.qd:n.qc).1M();d.qb=1z.1K;d.cx=["iU.8g","em.8g","iU.8g.4.0"];d.9b=B(){A 4s=L;A cv=L;if(!z.1l||!1o.iT){1u{4s=S qa()}1y(e){}}if(!4s){R(A i=0;i<3;++i){A cw=z.cx[i];1u{4s=S 9j(cw)}1y(e){cv=e}if(4s){z.cx=[cw];3f}}}if(!4s){2m S 1O("8g 3O q9: "+cv)}C 4s};d.8Y=B(iS){A 4Y=iS.3N||0;C((4Y>=q8)&&(4Y0);d.iR=B(1g,iP){A 3K=D.9b();if(!iQ&&z.4r){1g=(S z.4r(26.8f,1g)).2i()}3K.dL("dD",1g,U);1u{3K.dI(L);if(!d.8Y(3K)){A 1G=1O("q2 4F 4E "+1g+" 3N:"+3K.3N);1G.3N=3K.3N;1G.2G=3K.2G;2m 1G}}1y(e){if(iP){C L}2m e}C 3K.2G}})();z.iO=U;z.6o=B(e){z.iO=K;A cr=(e&&e.Z)?e.Z.1M():"4E";if(P.2O.iN||(cr!="q1"&&cr!="4E")){C}P.2O.iN=K;if(V z["8e"]!="1k"){dX(z.8e);63 z.8e}if(z.6p==0){z.iM()}};if(1q.66){if(z.2M||(z.7B&&(1o["q0"]===K))){1q.66("pZ",z.6o,L)}26.66("4E",z.6o,L)}if(/(pY|pX)/i.6Z(cq.iL)){z.8e=dN(B(){if(/6m|iJ/.6Z(1q.6F)){z.6o()}},10)}(B(){A 3g=26;A 8d=B(cp,fp){A iK=3g[cp]||B(){};3g[cp]=B(){fp.14(3g,P);iK.14(3g,P)}};if(z.1l){1q.fJ(""+"");A co=K;8d("iG",B(){3g.5c(B(){co=U},0)});8d("pU",B(){if(co){z.ck()}});1u{1q.pT.2P("v","pS:pR-pQ-pP:pO");1q.pN().pM("v\\\\:*","pL:2E(#aY#pK)")}1y(e){}}I{8d("iG",B(){z.ck()})}})();z.pJ=B(){};z.1e=26["1q"]||L;z.3E=B(){C z.1e.3E||z.1e.4I("3E")[0]};z.ch=B(iF,iE){z.1W=iF;z.1e=iE};z.cf=B(4q,6n,iD){if((6n)&&((V 4q=="3c")||(4q 1N 67))){4q=6n[4q]}C(6n?4q.14(6n,iD||[]):4q())};z.pI=B(cj,iC,iB,iA){A cg;A iz=z.1W;A iy=z.1e;1u{z.ch(cj,cj.1q);cg=z.cf(iC,iB,iA)}ir{z.ch(iz,iy)}C cg};z.pH=B(ix,iw,iv,iu){A ce;A ip=z.1e;1u{z.1e=ix;ce=z.cf(iw,iv,iu)}ir{z.1e=ip}C ce};if(1o["cd"]){R(A cc in 1o["cd"]){z.io(cc,1o["cd"][cc])}}}if(1o.im){if(!1z.ca){z.8c("z.pG.ca")}}}if(!z.1h["z.X.c9"]){z.1h["z.X.c9"]=K;z.1Q("z.X.c9");z.1R=B(it){C(V it=="3c"||it 1N 67)};z.2l=B(it){C(it&&it 1N 4e||V it=="6a"||((V z["1H"]!="1k")&&(it 1N z.1H)))};if(z.c8&&z.3o){z.1Y=B(it){if((V(it)=="B")&&(it=="[8b 1H]")){C U}C(V it=="B"||it 1N bI)}}I{z.1Y=B(it){C(V it=="B"||it 1N bI)}}z.ib=B(it){if(V it=="1k"){C U}C(it===L||V it=="8b"||z.2l(it)||z.1Y(it))};z.pF=B(it){A d=z;if((!it)||(V it=="1k")){C U}if(d.1R(it)){C U}if(d.1Y(it)){C U}if(d.2l(it)){C K}if((it.5w)&&(it.5w.1M()=="3R")){C U}if(pE(it.G)){C K}C U};z.pD=B(it){if(!it){C U}C!z.1Y(it)&&/\\{\\s*\\[il 5h\\]\\s*\\}/.6Z(67(it))};z.c7=B(M,4W){A 8a={};R(A x in 4W){if((V 8a[x]=="1k")||(8a[x]!=4W[x])){M[x]=4W[x]}}if(z.1l){A p=4W.2i;if((V(p)=="B")&&(p!=M.2i)&&(p!=8a.2i)&&(p!="\\pC 2i() {\\n [il 5h]\\n}\\n")){M.2i=4W.2i}}C M};z.1x=B(M,pB){R(A i=1,l=P.G;i2){C z.ig.14(z,P)}if(!3k){3k=2z;2z=L}if(z.1R(3k)){2z=2z||z.1W;if(!2z[3k]){2m(["z.2p: ie[\\"",3k,"\\"] is L (ie=\\"",2z,"\\")"].22(""))}C B(){C 2z[3k].14(2z,P||[])}}I{C(!2z?3k:B(){C 3k.14(2z,P||[])})}};z.6j=B(M,c3){B c4(){};c4.1C=M;A c2=S c4();if(c3){z.1x(c2,c3)}C c2};z.7X=B(pz){A Q=[L];C z.2p.14(z,Q.3U(z.4d(P)))};z.4d=B(M,ic){A Q=[];R(A x=ic||0;x3)){z.ia("z.2r: R 9P \'"+6l+"\' py pw B as \'1P\' pv pu of as a pt i3.","","1.0");A c=3j;3j=P[3]||{};3j.1P=c}A dd=P.2O,4V=L;if(z.2l(4p)){4V=4p;4p=4V.3a()}if(4V){R(A i=0,m;i<4V.G;i++){m=4V[i];if(!m){2m("ps #"+i+" 4F pr of "+6l+" is L. pq\'s pp a po pl is 3O 6m.")}4p=dd.6j(4p,m)}}A i9=(3j||0).1P,6k=dd.6j(4p),fn;R(A i in 3j){if(z.1Y(fn=3j[i])&&(!0[i])){fn.i4=i}}z.4M(6k,{4o:6l,bY:i9,bZ:L},3j||0);6k.1C.1P=6k;C z.88(6l,6k)};z.1x(z.2r,{6j:B(c0,i8){A bp=(c0||0).1C,mp=(i8||0).1C;A 2S=z.2r.i7();z.1x(2S,{84:bp,1x:mp});if(c0){2S.1C=z.6j(bp)}z.4M(2S,z.2r.i6,mp||0,{bY:L});2S.1C.1P=2S;2S.1C.4o=(bp||0).4o+"pk"+(mp||0).4o;z.88(2S.1C.4o,2S);C 2S},i7:B(){C B(){D.i5(P)}},i6:{i5:B(86){A c=86.2O,s=c.84,ct=s&&s.1P,m=c.1x,87=m&&m.1P,a=86,ii,fn;if(a[0]){if((fn=a[0]["bZ"])){a=fn.14(D,a)||a}}if(fn=c.1C.bZ){a=fn.14(D,a)||a}if(ct&&ct.14){ct.14(D,a)}if(87&&87.14){87.14(D,a)}if(ii=c.1C.bY){ii.14(D,86)}},bX:B(85){A c=D.1P,p,m;1s(c){p=c.84;m=c.1x;if(m==85||(m 1N 85.1P)){C p}if(m&&(m=m.bX(85))){C m}c=p&&p.1P}},6h:B(83,82,bW,6i){A p=bW,c,m,f;do{c=p.1P;m=c.1x;if(m&&(m=D.6h(83,82,m,6i))){C m}if((f=p[83])&&(6i==(f==82))){C p}p=c.84}1s(p);C!6i&&(p=D.bX(bW))&&D.6h(83,82,p,6i)},bU:B(2R,4U,bV){A a=P;if(!z.1R(a[0])){bV=4U;4U=2R;2R=4U.2O.i4}A c=4U.2O,p=D.1P.1C,a=bV||4U,fn,mp;if(D[2R]!=c||p[2R]==c){mp=D.6h(2R,c,p,K);if(!mp){2m(D.4o+": 1p i3 (\\""+2R+"\\") 4F bU pj 1f 2O (2r.js)")}p=D.6h(2R,c,mp,U)}fn=p&&p[2R];if(!fn){1z.1K(mp.4o+": no bU \\""+2R+"\\" ph pg (2r.js)");C}C fn.14(D,a)}}})}if(!z.1h["z.X.2c"]){z.1h["z.X.2c"]=K;z.1Q("z.X.2c");z.3i={i2:B(){C B(){A ap=4e.1C,c=P.2O,ls=c.2b,t=c.5V;A r=t&&t.14(D,P);R(A i in ls){if(!(i in ap)){ls[i].14(D,P)}}C r}},2P:B(6g,bT,i1){6g=6g||z.1W;A f=6g[bT];if(!f||!f.2b){A d=z.3i.i2();d.5V=f;d.2b=[];f=6g[bT]=d}C f.2b.Y(i1)},3J:B(i0,hZ,bS){A f=(i0||z.1W)[hZ];if(f&&f.2b&&bS--){63 f.2b[bS]}}};z.2c=B(M,pd,pc,pa,p9){A a=P,F=[],i=0;F.Y(z.1R(a[0])?L:a[i++],a[i++]);A a1=a[i+1];F.Y(z.1R(a1)||z.1Y(a1)?a[i++]:L,a[i++]);R(A l=a.G;i2){6e=z.7X(6e,P,2)}C D.5k(6e,6e)},ef:B(cb,4T){A 7Y=z.2p(cb,4T);if(P.G>2){7Y=z.7X(7Y,P,2)}C D.5k(7Y,L)},ed:B(cb,4T){A 7W=z.2p(cb,4T);if(P.G>2){7W=z.7X(7W,P,2)}C D.5k(L,7W)},5k:B(cb,eb){D.bM.Y([cb,eb]);if(D.2y>=0){D.7U()}C D},7U:B(){A bL=D.bM;A 4n=D.2y;A 1v=D.4R[4n];A 4S=D;A cb=L;1s((bL.G>0)&&(D.3M==0)){A f=bL.3a()[4n];if(!f){6c}1u{1v=f(1v);4n=((1v 1N 1O)?1:0);if(1v 1N z.30){cb=B(1v){4S.7V(1v);4S.3M--;if((4S.3M==0)&&(4S.2y>=0)){4S.7U()}};D.3M++}}1y(1G){1z.1K(1G);4n=1;1v=1G}}D.2y=4n;D.4R[4n]=1v;if((cb)&&(D.3M)){1v.9e(cb)}}})}if(!z.1h["z.X.2e"]){z.1h["z.X.2e"]=K;z.1Q("z.X.2e");z.5m=B(2e){1u{C 3u("("+2e+")")}1y(e){1z.1K(e);C 2e}};z.bK=B(2H){C("\\""+2H.2f(/(["\\\\])/g,"\\\\$1")+"\\"").2f(/[\\f]/g,"\\\\f").2f(/[\\b]/g,"\\\\b").2f(/[\\n]/g,"\\\\n").2f(/[\\t]/g,"\\\\t").2f(/[\\r]/g,"\\\\r")};z.hM="\\t";z.eq=B(it,4l,4P){4P=4P||"";A 4k=(4l?4P+z.hM:"");A 6b=(4l?"\\n":"");A 4Q=V(it);if(4Q=="1k"){C"1k"}I{if((4Q=="4J")||(4Q=="p1")){C it+""}I{if(it===L){C"L"}}}if(4Q=="3c"){C z.bK(it)}A 6d=P.2O;A 4m;if(V it.hL=="B"){4m=it.hL();if(it!==4m){C 6d(4m,4l,4k)}}if(V it.2e=="B"){4m=it.2e();if(it!==4m){C 6d(4m,4l,4k)}}if(z.2l(it)){A 1v=[];R(A i=0;i>=7R;t[x]=7R==4?17*c:c});t.a=1;C t};z.7P=B(a,M){A t=M||S z.1J();t.bz(2V(a[0]),2V(a[1]),2V(a[2]),2V(a[3]));if(2L(t.a)){t.a=1}C t.7Q()};z.hq=B(2H,M){A a=z.1J.hp[2H];C a&&z.7P(a,M)||z.ho(2H,M)||z.hn(2H,M)}}if(!z.1h["z.X"]){z.1h["z.X"]=K;z.1Q("z.X")}if(!z.1h["z.X.5Z"]){z.1h["z.X.5Z"]=K;z.1Q("z.X.5Z");(B(){A 1j=z.b2={2P:B(E,68,fp){if(!E){C}68=1j.4O(68);fp=1j.7G(68,fp);E.66(68,fp,U);C fp},3J:B(E,hm,hl){(E)&&(E.oF(1j.4O(hm),hl,U))},4O:B(1p){C(1p.2w(0,2)=="on"?1p.2w(2):1p)},7G:B(1p,fp){C(1p!="4b"?fp:B(e){C fp.2d(D,1j.4i(e,D))})},4i:B(H,oE){4w(H.Z){2X"4b":1j.7K(H);3f}C H},7K:B(H){H.oD=(H.3h?67.oC(H.3h):"")}};z.oB=B(H,hk){C 1j.4i(H,hk)};z.gY=B(H){H.7J();H.7I()};A 7O=z.3i;z.by=B(M,bx,hh,hg,hi){A hj=M&&(M.2t||M.oA||M.66);A bw=!hj?0:(!hi?1:2),l=[z.3i,1j,7O][bw];A h=l.2P(M,bx,z.2p(hh,hg));C[M,bx,h,bw]};z.bv=B(M,he,hd,hf){([z.3i,1j,7O][hf]).3J(M,he,hd)};z.5W={oz:8,gV:9,oy:12,ox:13,ow:16,ov:17,ou:18,gG:19,ot:20,os:27,or:32,b5:33,b4:34,gE:35,gF:36,b7:37,b9:38,b6:39,b8:40,gD:45,8S:46,oq:47,oo:91,om:92,ol:93,oj:96,oi:97,oh:98,og:99,oe:6D,od:oc,ob:oa,o9:o8,o7:o6,o5:o4,o3:bi,o2:o1,o0:nZ,nY:nX,nW:nV,nU:bk,gS:nT,gR:nS,gQ:nR,gP:nQ,gO:nP,gN:nO,gM:nN,gL:nM,gK:nL,gJ:nK,gI:nJ,gH:nI,nH:nG,nF:nE,nD:nC,gB:nB,gC:nA};if(z.1l){bf=B(e,5h){1u{C(e.3I=5h)}1y(e){C 0}};A 61=z.3i;if(!1o.nz){7O=61=z.gy={b3:[],2P:B(64,bu,hc){64=64||z.1W;A f=64[bu];if(!f||!f.2b){A d=z.gz();d.5V=f&&(7M.Y(f)-1);d.2b=[];f=64[bu]=d}C f.2b.Y(7M.Y(hc)-1)},3J:B(hb,ha,7N){A f=(hb||z.1W)[ha],l=f&&f.2b;if(f&&l&&7N--){63 7M[l[7N]];63 l[7N]}}};A 7M=61.b3}z.1x(1j,{2P:B(E,62,fp){if(!E){C}62=1j.4O(62);if(62=="h3"){A kd=E.bs;if(!kd||!kd.2b||!kd.h9){1j.2P(E,"bs",1j.h4);E.bs.h9=K}}C 61.2P(E,62,1j.7G(fp))},3J:B(E,h8,h7){61.3J(E,1j.4O(h8),h7)},4O:B(7L){C(7L.2w(0,2)!="on"?"on"+7L:7L)},ny:B(){},4i:B(H,4N){if(!H){A w=(4N)&&((4N.aD||4N.1q||4N).nx)||26;H=w.5Z}if(!H){C(H)}H.5V=H.br;H.bh=(4N||H.br);H.nw=H.nv;H.nu=H.nr;A bq=H.br,1e=(bq&&bq.aD)||1q;A bn=((z.1l<6)||(1e["aX"]=="aW"))?1e.3E:1e.5K;A bm=z.aB();H.nq=H.np+z.aH(bn.5I||0)-bm.x;H.nn=H.nm+(bn.5G||0)-bm.y;if(H.Z=="fk"){H.h6=H.nl}if(H.Z=="fj"){H.h6=H.nk}H.7I=1j.bc;H.7J=1j.ba;C 1j.h5(H)},h5:B(H){4w(H.Z){2X"4b":A c=("3h"in H?H.3h:H.3I);if(c==10){c=0;H.3I=13}I{if(c==13||c==27){c=0}I{if(c==3){c=99}}}H.3h=c;1j.7K(H);3f}C H},gZ:{bi:42,bk:47,h2:59,nj:43,ni:44,nh:45,ng:46,nf:47,60:96,h1:91,nb:92,na:93,h0:39},h4:B(H){A kp=H.bh.h3;if(!kp||!kp.2b){C}A k=H.3I;A bj=(k!=13)&&(k!=32)&&(k!=27)&&(k<48||k>90)&&(k<96||k>bk)&&(k60)&&(kh0);if(bj||H.5Y){A c=(bj?0:k);if(H.5Y){if(k==3||k==13){C}I{if(c>95&&c=65&&c<=90)){c+=32}I{c=1j.gZ[c]||c}}}}A 2x=1j.7H(H,{Z:"4b",2x:K,3h:c});kp.2d(H.bh,2x);H.bg=2x.bg;H.bd=2x.bd;bf(H,2x.3I)}},bc:B(){D.bg=K},ba:B(){D.n9=D.3I;if(D.5Y){bf(D,0)}D.bd=U}});z.gY=B(H){H=H||26.5Z;1j.bc.2d(H);1j.ba.2d(H)}}1j.7H=B(H,gX){A 2x=z.1x({},H,gX);1j.7K(2x);2x.7J=B(){H.7J()};2x.7I=B(){H.7I()};C 2x};if(z.2M){z.1x(1j,{4i:B(H,n8){4w(H.Z){2X"4b":A c=H.n7;if(c==3){c=99}c=((c<41)&&(!H.5X)?0:c);if((H.5Y)&&(!H.5X)&&(c>=65)&&(c<=90)){c+=32}C 1j.7H(H,{3h:c})}C H}})}if(z.3o){z.1x(1j,{4i:B(H,n6){4w(H.Z){2X"4b":A c=H.3h,s=H.5X,k=H.3I;k=k||gA[H.gW]||0;if(H.gW=="n5"){c=0}I{if((H.5Y)&&(c>0)&&(c<27)){c+=96}I{if(c==z.5W.gU){c=z.5W.gV;s=K}I{c=(c>=32&&c gh",E).1n(B(i){i.1c.7E=i.1c.7E.2f(/gk:[^;]*;/i,"")})}}I{A o="mh(mg="+(7D*6D)+")";E.1c.3T=o}if(E.gj.1M()=="gi"){z.1r("> gh",E).1n(B(i){i.1c.3T=o})}C 7D}:B(E,gg){C E.1c.2W=gg});A 5Q={3n:K,58:K,2g:K,5J:K};A gd=B(E,Z,5P){Z=Z.1M();if(5Q[Z]===K){C z.4g(E,5P)}I{if(5Q[Z]===U){C 5P}I{if((Z.T("mf")>=0)||(Z.T("md")>=0)||(Z.T("3n")>=0)||(Z.T("58")>=0)||(Z.T("5q")>=0)||(Z.T("mc")>=0)||(Z.T("ma")>=0)){5Q[Z]=K;C z.4g(E,5P)}I{5Q[Z]=U;C 5P}}}};z.1c=B(E,5O,aT){A n=z.1D(E),F=P.G,op=(5O=="2W");if(F==3){C op?z.gf(n,aT):n.1c[5O]=aT}if(F==2&&op){C z.ge(n)}A s=z.3F(n);C(F==1)?s:gd(n,5O,s[5O])};z.7A=B(n,gc){A s=gc||1E(n),px=z.4g,l=px(n,s.m9),t=px(n,s.m8);C{l:l,t:t,w:l+px(n,s.m7),h:t+px(n,s.m6)}};z.5N=B(n,gb){A ne="7C",px=z.4g,s=gb||1E(n),bl=(s.m5!=ne?px(n,s.m4):0),bt=(s.m3!=ne?px(n,s.m2):0);C{l:bl,t:bt,w:bl+(s.m1!=ne?px(n,s.m0):0),h:bt+(s.lZ!=ne?px(n,s.lY):0)}};z.aN=B(n,ga){A s=ga||1E(n),p=z.7A(n,s),b=z.5N(n,s);C{l:p.l+b.l,t:p.t+b.t,w:p.w+b.w,h:p.h+b.h}};z.aM=B(n,g9){A s=g9||1E(n),px=z.4g,l=px(n,s.lX),t=px(n,s.lW),r=px(n,s.lV),b=px(n,s.lU);if(z.3o&&(s.ax!="fU")){r=l}C{l:l,t:t,w:l+r,h:t+b}};z.au=B(E,g8){A s=g8||1E(E),me=z.aM(E,s);A l=E.fT-me.l,t=E.fS-me.t;if(z.7B){A aS=2k(s.2g),aR=2k(s.5J);if(!2L(aS)&&!2L(aR)){l=aS,t=aR}I{A p=E.1L;if(p&&p.1c){A aQ=1E(p);if(aQ.lT!="lS"){A be=z.5N(p,aQ);l+=be.l,t+=be.t}}}}I{if(z.2M){A p=E.1L;if(p){A be=z.5N(p);l-=be.l,t-=be.t}}}C{l:l,t:t,w:E.6v+me.w,h:E.8D+me.h}};z.aK=B(E,g7){A s=g7||1E(E),pe=z.7A(E,s),be=z.5N(E,s),w=E.aF,h;if(!w){w=E.6v,h=E.8D}I{h=E.lR,be.w=be.h=0}if(z.2M){pe.l+=be.l;pe.t+=be.t}C{l:pe.l,t:pe.t,w:w-pe.w-be.w,h:h-pe.h-be.h}};z.lQ=B(E,g6){A s=g6||1E(E),pe=z.7A(E,s),cb=z.aK(E,s);C{l:cb.l-pe.l,t:cb.t-pe.t,w:cb.w+pe.w,h:cb.h+pe.h}};z.aL=B(E,l,t,w,h,u){u=u||"px";4G(E.1c){if(!2L(l)){2g=l+u}if(!2L(t)){5J=t+u}if(w>=0){3n=w+u}if(h>=0){58=h+u}}};z.aO=B(E){A n=E.5w;C(z.aP=="g5-3G")||(n=="lP")||(n=="lO")};z.fX=B(E,7z,7y,g4){A bb=z.aO(E);if(bb){A pb=z.aN(E,g4);if(7z>=0){7z+=pb.w}if(7y>=0){7y+=pb.h}}z.aL(E,g3,g3,7z,7y)};z.fY=B(E,g1,g0,5M,5L,g2){A s=g2||z.3F(E);A bb=z.aO(E),pb=bb?fZ:z.aN(E,s),mb=z.aM(E,s);if(5M>=0){5M=2Y.5q(5M-pb.w-mb.w,0)}if(5L>=0){5L=2Y.5q(5L-pb.h-mb.h,0)}z.aL(E,g1,g0,5M,5L)};A fZ={l:0,t:0,w:0,h:0};z.lN=B(E,3G){A n=z.1D(E),s=1E(n),b=3G;C!b?z.au(n,s):z.fY(n,b.l,b.t,b.w,b.h,s)};z.lM=B(E,3G){A n=z.1D(E),s=1E(n),b=3G;C!b?z.aK(n,s):z.fX(n,b.w,b.h,s)};A 5H=B(E,1a){if(!(E=(E||0).1L)){C 0}A 1U,aJ=0,2h=z.3E();1s(E&&E.1c){if(1E(E).ax=="lL"){C 0}1U=E[1a];if(1U){aJ+=1U-0;if(E==2h){3f}}E=E.1L}C aJ};z.fQ=B(){A 2h=z.3E();A 3g=z.1W;A de=z.1e.5K;C{y:(3g.lK||de.5G||2h.5G||0),x:(3g.lJ||z.aH(de.5I)||2h.5I||0)}};z.aG=B(){C V z.aI=="1k"?(z.aI=z.3F(z.3E()).lI=="lH"):z.aI};z.aB=B(){A de=z.1e.5K;if(z.1l>=7){C{x:de.aC().2g,y:de.aC().5J}}I{C{x:z.aG()||26.am==26?de.fW:de.6v-de.aF-de.fW,y:de.lG}}};z.aH=B(aE){if(z.1l&&!z.aG()){A de=z.1e.5K;C aE+de.aF-de.lF}C aE};z.fP=B(E,aw){A ay=E.aD;A J={x:0,y:0};A 7w=U;A db=z.3E();if(z.1l){A aA=E.aC();A az=z.aB();J.x=aA.2g-az.x;J.y=aA.5J-az.y}I{if(ay["fV"]){A bo=ay.fV(E);J.x=bo.x-5H(E,"5I");J.y=bo.y-5H(E,"5G")}I{if(E["fR"]){7w=K;A 7x;if(z.3o&&(1E(E).ax=="fU")&&(E.1L==db)){7x=db}I{7x=db.1L}if(E.1L!=db){A nd=E;if(z.2M){nd=db}J.x-=5H(nd,"5I");J.y-=5H(nd,"5G")}A 4f=E;do{A n=4f["fT"];if(!z.2M||n>0){J.x+=2L(n)?0:n}A m=4f["fS"];J.y+=2L(m)?0:m;4f=4f.fR}1s((4f!=7x)&&4f)}I{if(E["x"]&&E["y"]){J.x+=2L(E.x)?0:E.x;J.y+=2L(E.y)?0:E.y}}}}if(7w||aw){A av=z.fQ();A m=7w?(!aw?-1:0):1;J.y+=m*av.y;J.x+=m*av.x}C J};z.af=B(E,fO){A n=z.1D(E),s=1E(n),mb=z.au(n,s);A at=z.fP(n,fO);mb.x=at.x;mb.y=at.y;C mb}})();z.fL=B(E,fN){C((" "+E.3A+" ").T(" "+fN+" ")>=0)};z.7s=B(E,ar){A 7v=E.3A;if((" "+7v+" ").T(" "+ar+" ")<0){E.3A=7v+(7v?" ":"")+ar}};z.7r=B(E,fM){A t=z.7g((" "+E.3A+" ").2f(" "+fM+" "," "));if(E.3A!=t){E.3A=t}};z.lE=B(E,aq,7u){if(V 7u=="1k"){7u=!z.fL(E,aq)}z[7u?"7s":"7r"](E,aq)}}if(!z.1h["z.X.1H"]){z.1h["z.X.1H"]=K;z.1Q("z.X.1H");(B(){A d=z;z.1H=B(){A F=P;if((F.G==1)&&(V F[0]=="4J")){D.G=eK(F[0])}I{if(F.G){d.1n(F,B(i){D.Y(i)},D)}}};z.1H.1C=S 4e;if(d.1l){A fK=B(al){C("A a2 = am."+al+"; "+"A ap = 4e.1C; "+"A ao = a2.1C; "+"R(A x in ao){ ap[x] = ao[x]; } "+"am."+al+" = 4e; ")};A fI=fK("z.1H");A aj=26.lD();aj.1q.fJ(""+fI+"");aj.lC(1,1,1,1)}z.4M(z.1H,{T:B(fH,fG){C d.T(D,fH,fG)},31:B(lB,lA){A aa=d.4d(P);aa.ae(D);C d.31.14(d,aa)},ah:B(fF,fE){C d.ah(D,fF,fE)},ag:B(fD,fC){C d.ag(D,fD,fC)},1n:B(fB,fA){d.1n(D,fB,fA);C D},23:B(7t,M){C d.23(D,7t,M,d.1H)},af:B(){C d.23(D,d.af)},1c:B(lz,ly){A aa=d.4d(P);aa.ae(D[0]);A s=d.1c.14(d,aa);C(P.G>1)?D:s},lx:B(lw,lv){A aa=d.4d(P);aa.ae(L);A s=D.23(B(i){aa[0]=i;C d.1c.14(d,aa)});C(P.G>1)?D:s},7s:B(fz){C D.1n(B(i){z.7s(i,fz)})},7r:B(fy){C D.1n(B(i){z.7r(i,fy)})},5E:B(fw,7q){A 1m=d.1r(fw)[0];7q=7q||"72";R(A x=0;x=0){if(i[x]<1d){1d=i[x]}}}C(1d<0)?ql:1d};A 6X=B(7l){A i=2I(7l);if(i[0]!=-1){C 7l.21(i[0]+1,a0(7l,1))}I{C""}};A 5r=B(7k){A 5D;A i=2I(7k);if((i[0]==0)||(i[1]==0)){5D=0}I{5D=a0(7k,0)}C((5D>0)?7k.3b(0,5D).1M():"*")};A fg=B(Q){A J=-1;R(A x=0;x=0){if((1S>J)||(J==-1)){J=1S}}}C J};A 9H=B(7i){A i=2I(7i);if(-1==i[1]){C""}A di=i[1]+1;A 7j=fg(i.2w(2));if(di<7j){C 7i.21(di,7j)}I{if(-1==7j){C 7i.3b(di)}I{C""}}};A f3=[{1i:"|=",1f:B(15,fe){C"[5z(3U(\' \',@"+15+",\' \'), \' "+fe+"-\')]"}},{1i:"~=",1f:B(15,fd){C"[5z(3U(\' \',@"+15+",\' \'), \' "+fd+" \')]"}},{1i:"^=",1f:B(15,fb){C"[li-4G(@"+15+", \'"+fb+"\')]"}},{1i:"*=",1f:B(15,fa){C"[5z(@"+15+", \'"+fa+"\')]"}},{1i:"$=",1f:B(15,9Z){C"[21(@"+15+", 3c-G(@"+15+")-"+(9Z.G-1)+")=\'"+9Z+"\']"}},{1i:"!=",1f:B(15,f9){C"[3O(@"+15+"=\'"+f9+"\')]"}},{1i:"=",1f:B(15,f8){C"[@"+15+"=\'"+f8+"\']"}}];A 9C=B(9Y,3Z,f7,f6){A 49;A i=2I(3Z);if(i[2]>=0){A 4L=3Z.T("]",i[2]);A 29=3Z.21(i[2]+1,4L);1s(29&&29.G){if(29.2s(0)=="@"){29=29.2w(1)}49=L;R(A x=0;x<9Y.G;x++){A 1S=9Y[x];A 7h=29.T(1S.1i);if(7h>=0){A 15=29.21(0,7h);A 4a=29.21(7h+1S.1i.G);if((4a.2s(0)=="\\"")||(4a.2s(0)=="\'")){4a=4a.21(1,4a.G-1)}49=1S.1f(d.7g(15),d.7g(4a));3f}}if((!49)&&(29.G)){49=f7(29)}if(49){f6(49)}29=L;A 7f=3Z.T("[",4L);if(0<=7f){4L=3Z.T("]",7f);if(0<=4L){29=3Z.21(7f+1,4L)}}}}};A f0=B(f5){A 4K=".";A 7e=f5.1A(" ");1s(7e.G){A 2K=7e.3a();A 7d;if(2K==">"){7d="/";2K=7e.3a()}I{7d="//"}A f4=5r(2K);4K+=7d+f4;A id=6X(2K);if(id.G){4K+="[@id=\'"+id+"\'][1]"}A cn=9H(2K);if(cn.G){A 9X=" ";if(cn.2s(cn.G-1)=="*"){9X="";cn=cn.3b(0,cn.G-1)}4K+="[5z(3U(\' \',@9P,\' \'), \' "+cn+9X+"\')]"}9C(f3,2K,B(f2){C"[@"+f2+"]"},B(f1){4K+=f1})}C 4K};A 7a={};A eC=B(28){if(7a[28]){C 7a[28]}A 1e=d.1e;A 9W=f0(28);A 4H=B(9V){A J=[];A 7b;1u{7b=1e.9x(9W,9V,L,lh.lg,L)}1y(e){1z.1K("lf in le:",9W,"lc:",9V);1z.1K(e)}A 7c=7b.eZ();1s(7c){J.Y(7c);7c=7b.eZ()}C J};C 7a[28]=4H};A 5x={};A 9B={};A 3y=B(79,78){if(!79){C 78}if(!78){C 79}C B(){C 79.14(26,P)&&78.14(26,P)}};A 75=B(9U,3Y,5B,2J){A 2v=2J+1;A 76=(3Y.G==2v);A 2K=3Y[2J];if(2K==">"){A 77=9U.3W;if(!77.G){C}2v++;76=(3Y.G==2v);A 4H=6O(3Y[2J+1]);R(A x=0,11;x<77.G,11=77[x];x++){if(4H(11)){if(76){5B.Y(11)}I{75(11,3Y,5B,2v)}}}}A 5C=6U(2K)(9U);if(76){1s(5C.G){5B.Y(5C.3a())}}I{1s(5C.G){75(5C.3a(),3Y,5B,2v)}}};A eE=B(9T,eY){A J=[];A x=9T.G-1,11;1s(11=9T[x--]){75(11,eY,J,0)}C J};A 6O=B(3D){if(5x[3D]){C 5x[3D]}A ff=L;A 9S=5r(3D);if(9S!="*"){ff=3y(ff,B(N){C((N.2t==1)&&(9S==N.5w.1M()))})}A 9R=6X(3D);if(9R.G){ff=3y(ff,B(N){C((N.2t==1)&&(N.id==9R))})}if(2Y.5q.14(D,2I(3D).2w(1))>=0){ff=3y(ff,9z(3D))}C 5x[3D]=ff};A 5y=B(E){A pn=E.1L;A 9Q=pn.3W;A 2v=-1;A 3C=pn.5A;if(!3C){C 2v}A ci=E["eW"];A cl=pn["eX"];if(((V cl=="4J")&&(cl!=9Q.G))||(V ci!="4J")){pn["eX"]=9Q.G;A 2J=1;do{if(3C===E){2v=2J}if(3C.2t==1){3C["eW"]=2J;2J++}3C=3C.71}1s(3C)}I{2v=ci}C 2v};A lb=0;A 3X=B(N,15){A 74="";if(15=="9P"){C N.3A||74}if(15=="R"){C N.la||74}C N.5t(15,2)||74};A eH=[{1i:"|=",1f:B(15,9O){A eV=" "+9O+"-";C B(N){A ea=" "+(N.5t(15,2)||"");C((ea==9O)||(ea.T(eV)==0))}}},{1i:"^=",1f:B(15,eU){C B(N){C(3X(N,15).T(eU)==0)}}},{1i:"*=",1f:B(15,eT){C B(N){C(3X(N,15).T(eT)>=0)}}},{1i:"~=",1f:B(15,eS){A 9N=" "+eS+" ";C B(N){A ea=" "+3X(N,15)+" ";C(ea.T(9N)>=0)}}},{1i:"$=",1f:B(15,73){A 9N=" "+73;C B(N){A ea=" "+3X(N,15);C(ea.31(73)==(ea.G-73.G))}}},{1i:"!=",1f:B(15,eR){C B(N){C(3X(N,15)!=eR)}}},{1i:"=",1f:B(15,eQ){C B(N){C(3X(N,15)==eQ)}}}];A 9E=[{1i:"9M-9K",1f:B(1p,l9){C B(N){if(N.2t!=1){C U}A fc=N.eP;1s(fc&&(fc.2t!=1)){fc=fc.eP}C(!fc)}}},{1i:"72-9K",1f:B(1p,l8){C B(N){if(N.2t!=1){C U}A nc=N.71;1s(nc&&(nc.2t!=1)){nc=nc.71}C(!nc)}}},{1i:"l7",1f:B(1p,l6){C B(N){A cn=N.3W;A eO=N.3W.G;R(A x=eO-1;x>=0;x--){A nt=cn[x].2t;if((nt==1)||(nt==3)){C U}}C K}}},{1i:"5z",1f:B(1p,eN){C B(N){C(N.9L.T(eN)>=0)}}},{1i:"3O",1f:B(1p,eM){A eL=6O(eM);C B(N){C(!eL(N))}}},{1i:"l5-9K",1f:B(1p,2u){A pi=eK;if(2u=="l4"){C B(N){C(((5y(N))%2)==1)}}I{if((2u=="2n")||(2u=="l3")){C B(N){C((5y(N)%2)==0)}}I{if(2u.T("l2+")==0){A 70=pi(2u.3b(3));C B(N){C(N.1L.3W[70-1]===N)}}I{if((2u.T("n+")>0)&&(2u.G>3)){A 9J=2u.1A("n+",2);A eJ=pi(9J[0]);A 2J=pi(9J[1]);C B(N){C((5y(N)%eJ)==2J)}}I{if(2u.T("n")==-1){A 70=pi(2u);C B(N){C(5y(N)==70)}}}}}}}}];A 9z=B(3e){A 9I=(9B[3e]||5x[3e]);if(9I){C 9I}A ff=L;A i=2I(3e);if(i[0]>=0){A 24=5r(3e);if(24!="*"){ff=3y(ff,B(N){C(N.5w.1M()==24)})}}A 5u;A 3B=9H(3e);if(3B.G){A 9F=3B.2s(3B.G-1)=="*";if(9F){3B=3B.3b(0,3B.G-1)}A re=S 9G("(?:^|\\\\s)"+3B+(9F?".*":"")+"(?:\\\\s|$)");ff=3y(ff,B(N){C re.6Z(N.3A)})}if(i[3]>=0){A 3z=3e.3b(i[3]+1);A 9D="";A 5v=3z.T("(");A 6Y=3z.31(")");if((0<=5v)&&(0<=6Y)&&(6Y>5v)){9D=3z.21(5v+1,6Y);3z=3z.3b(0,5v)}5u=L;R(A x=0;x<9E.G;x++){A 1S=9E[x];if(1S.1i==3z){5u=1S.1f(3z,9D);3f}}if(5u){ff=3y(ff,5u)}}A eG=(d.1l)?B(5s){A eI=5s.1M();C B(N){C N[5s]||N[eI]}}:B(5s){C B(N){C(N&&N.5t&&N.l1(5s))}};9C(eH,3e,eG,B(eF){ff=3y(ff,eF)});if(!ff){ff=B(){C K}}C 9B[3e]=ff};A 6W={};A 6U=B(3d,1B){A 9A=6W[3d];if(9A){C 9A}A i=2I(3d);A id=6X(3d);if(i[0]==0){C 6W[3d]=B(1B){C[d.1D(id)]}}A 9y=9z(3d);A 5p;if(i[0]>=0){5p=B(1B){A 11=d.1D(id);if(9y(11)){C[11]}}}I{A 3V;A 24=5r(3d);if(2Y.5q.14(D,2I(3d))==-1){5p=B(1B){A J=[];A 11,x=0,3V=1B.4I(24);1s(11=3V[x++]){J.Y(11)}C J}}I{5p=B(1B){A J=[];A 11,x=0,3V=1B.4I(24);1s(11=3V[x++]){if(9y(11)){J.Y(11)}}C J}}}C 6W[3d]=5p};A l0={};A 5o={">":B(1B){A J=[];A 11,x=0,3V=1B.3W;1s(11=3V[x++]){if(11.2t==1){J.Y(11)}}C J}};A 9w=B(6V){if(0>6V.T(" ")){C 6U(6V)}A eD=B(1B){A 6S=6V.1A(" ");A 6T;if(6S[0]==">"){6T=[1B]}I{6T=6U(6S.3a())(1B)}C eE(6T,6S)};C eD};A 9v=((1q["9x"]&&!d.3o)?B(3x){A 6R=3x.1A(" ");if((1q["9x"])&&(3x.T(":")==-1)&&((K))){if(((6R.G>2)&&(3x.T(">")==-1))||(6R.G>3)||(3x.T("[")>=0)||((1==6R.G)&&(0<=3x.T(".")))){C eC(3x)}}C 9w(3x)}:9w);A ey=B(3w){if(5o[3w]){C 5o[3w]}if(0>3w.T(",")){C 5o[3w]=9v(3w)}I{A eB=3w.1A(/\\s*,\\s*/);A 4H=B(1B){A eA=0;A J=[];A 6Q;1s(6Q=eB[eA++]){J=J.3U(9v(6Q,6Q.T(" "))(1B))}C J};C 5o[3w]=4H}};A 5n=0;A ez=B(Q){A J=S d.1H();if(!Q){C J}if(Q[0]){J.Y(Q[0])}if(Q.G<2){C J}5n++;Q[0]["9u"]=5n;R(A x=1,11;11=Q[x];x++){if(Q[x]["9u"]!=5n){J.Y(11)}11["9u"]=5n}C J};d.1r=B(6P,1B){if(V 6P!="3c"){C S d.1H(6P)}if(V 1B=="3c"){1B=d.1D(1B)}C ez(ey(6P)(1B||d.1e))};d.9t=B(ex,9s){A 9r=S d.1H();A ff=(9s)?6O(9s):B(){C K};R(A x=0,11;11=ex[x];x++){if(ff(11)){9r.Y(11)}}C 9r}})()}if(!z.1h["z.X.1b"]){z.1h["z.X.1b"]=K;z.1Q("z.X.1b");z.6K=B(ew){A J={};A iq="kZ[Z!=9q][Z!=kY][Z!=et][Z!=kX][Z!=kW], kV, kU";z.1r(iq,ew).3T(B(E){C(!E.kT)}).1n(B(1m){A 3v=1m.1p;A Z=(1m.Z||"").1M();if((Z=="kS")||(Z=="kR")){if(1m.kQ){J[3v]=1m.1Z}}I{if(1m.kP){A ev=J[3v]=[];z.1r("kO[kN]",1m).1n(B(eu){ev.Y(eu.1Z)})}I{J[3v]=1m.1Z;if(Z=="et"){J[3v+".x"]=J[3v+".y"]=J[3v].x=J[3v].y=0}}}});C J};z.9h=B(23){A ec=kM;A J="";A es={};R(A x in 23){if(23[x]!=es[x]){if(z.2l(23[x])){R(A y=0;y<23[x].G;y++){J+=ec(x)+"="+ec(23[x][y])+"&"}}I{J+=ec(x)+"="+ec(23[x])+"&"}}}if((J.G)&&(J.2s(J.G-1)=="&")){J=J.3b(0,J.G-1)}C J};z.kL=B(er){C z.9h(z.6K(er))};z.kK=B(ep){C z.eq(z.6K(ep))};z.kJ=B(2H){A J={};A qp=2H.1A("&");A dc=kI;z.1n(qp,B(1m){if(1m.G){A 9p=1m.1A("=");A 1p=dc(9p.3a());A 1U=dc(9p.22("="));if(z.1R(J[1p])){J[1p]=[J[1p]]}if(z.2l(J[1p])){J[1p].Y(1U)}I{J[1p]=1U}}});C J};z.e1=U;z.e6={"9g":B(1b){C 1b.2G},"2e":B(1b){if(!1o.eo){1z.1K("kH kG kF a kE of 9g/2e-6M-9m"+" 4F kD kC kB kA 4G en kz"+" (ky 1o.eo=K 4F kx kw D kv)")}C z.5m(1b.2G)},"2e-6M-ku":B(1b){A 6N=1b.2G;A 9o=6N.T("/*");A 9n=6N.31("*/");if((9o==-1)||(9n==-1)){C z.5m(1b.2G)}C z.5m(6N.21(9o+2,9n))},"2e-6M-9m":B(1b){A 6L=1b.2G;A 9l=6L.T("/*");A 9k=6L.31("*/");if((9l==-1)||(9k==-1)){1z.1K("kt en ks\'t 6M 9m!");C""}C z.5m(6L.21(9l+2,9k))},"kr":B(1b){C z.3u(1b.2G)},"kq":B(1b){if(z.1l&&!1b.el){z.1n(["ko","em","kn","km"],B(i){1u{A 1e=S 9j(kl[i]+".kk");1e.kj=U;1e.ki(1b.2G);C 1e}1y(e){}})}I{C 1b.el}}};(B(){z.e5=B(F,ej,ei,eh){A 2F={};2F.F=F;A 6J=L;if(F.3R){A 3R=z.1D(F.3R);A 9i=3R.kh("kg");2F.2E=F.2E||(9i?9i.1Z:L);6J=z.6K(3R)}I{2F.2E=F.2E}A 5l=[{}];if(6J){5l.Y(6J)}if(F.5g){5l.Y(F.5g)}if(F.ek){5l.Y({"z.ek":S 5d().8O()})}2F.1r=z.9h(z.1x.14(L,5l));2F.9d=F.9d||"9g";A d=S z.30(ej);d.5k(ei,B(eg){C eh(eg,d)});A ld=F.4E;if(ld&&z.1Y(ld)){d.ef(B(ee){C ld.2d(F,ee,2F)})}A 1G=F.9f;if(1G&&z.1Y(1G)){d.ed(B(e9){C 1G.2d(F,e9,2F)})}A 6I=F.kf;if(6I&&z.1Y(6I)){d.9e(B(e8){C 6I.2d(F,e8,2F)})}d.1F=2F;C d};A e4=B(O){O.e0=K;A 1b=O.1F.1b;if(V 1b.e7=="B"){1b.e7()}};A e3=B(O){C z.e6[O.1F.9d](O.1F.1b)};A e2=B(9c,O){1z.1K(9c);C 9c};A 3Q=B(F){A O=z.e5(F,e4,e3,e2);O.1F.1b=z.9b(O.1F.F);C O};A 5j=L;A 3t=[];A 94=B(){A dZ=(S 5d()).dU();if(!z.e1){z.1n(3t,B(4D,6H){if(!4D){C}A O=4D.O;1u{if(!O||O.e0||!4D.dT(O)){3t.3S(6H,1);C}if(4D.dR(O)){3t.3S(6H,1);4D.dP(O)}I{if(O.9a){if(O.9a+(O.1F.F.6G||0)0){5c(z.2p(D,B(){D.5b(L,8R)}),d);C D}D.4A=S 5d().8O();if(D.2Z){D.4A-=D.8Q*D.2o}D.8N=D.4A+D.8Q;D.2D=K;D.2Z=U;A 8P=D.2C.4x(D.2o);if(!D.2o){if(!D.4y){D.4y=D.4z}D.3q("dt",[8P])}D.3q("ds",[8P]);D.8M();C D},jS:B(){5e(D.3r);if(!D.2D){C D}D.2Z=K;D.3q("dr",[D.2C.4x(D.2o)]);C D},jR:B(dq,dp){5e(D.3r);D.2D=D.2Z=K;D.2o=dq*6D;if(dp){D.5b()}C D},jQ:B(dn){if(!D.3r){C}5e(D.3r);if(dn){D.2o=1}D.3q("dm",[D.2C.4x(D.2o)]);D.2D=D.2Z=U;C D},3N:B(){if(D.2D){C D.2Z?"3M":"jP"}C"jO"},8M:B(){5e(D.3r);if(D.2D){A dl=S 5d().8O();A 2q=(dl-D.4A)/(D.8N-D.4A);if(2q>=1){2q=1}D.2o=2q;if(D.5a){2q=D.5a(2q)}D.3q("8B",[D.2C.4x(2q)]);if(2q<1){D.3r=5c(z.2p(D,"8M"),D.dj)}I{D.2D=U;if(D.4z>0){D.4z--;D.5b(L,K)}I{if(D.4z==-1){D.5b(L,K)}I{if(D.4y){D.4z=D.4y;D.4y=0}}}D.2o=0;D.3q("dh")}}C D}});(B(){A df=B(E){if(z.1l){A ns=E.1c;if(!ns.8L.G&&z.1c(E,"8L")=="dg"){ns.8L="1"}if(!ns.3n.G&&z.1c(E,"3n")=="8K"){ns.3n="8K"}}};z.6C=B(F){if(V F.1d=="1k"){2m S 1O("z.6C jN an 1d 1Z")}F.E=z.1D(F.E);A 3p=z.1x({6w:{}},F);A 8J=(3p.6w.2W={});8J.1w=(V 3p.1w=="1k")?B(){C 2V(z.1c(3p.E,"2W"))}:3p.1w;8J.1d=3p.1d;A 2U=z.6y(3p);z.2c(2U,"6x",L,B(){df(3p.E)});C 2U};z.8I=B(F){C z.6C(z.1x({1d:1},F))};z.8H=B(F){C z.6C(z.1x({1d:0},F))};if(z.6B&&!z.3o){z.8E=B(n){C 2k("0.5")+((2Y.da((n+2k("1.5"))*2Y.d9))/2)}}I{z.8E=B(n){C 0.5+((2Y.da((n+1.5)*2Y.d9))/2)}}A d4=B(6A){D.8G=6A;R(A p in 6A){A 1a=6A[p];if(1a.1w 1N z.1J){1a.d7=S z.1J()}}D.4x=B(r){A J={};R(A p in D.8G){A 1a=D.8G[p];A 6z=L;if(1a.1w 1N z.1J){6z=z.d8(1a.1w,1a.1d,r,1a.d7).8F()}I{if(!z.2l(1a.1w)){6z=((1a.1d-1a.1w)*r)+1a.1w+(p!="2W"?1a.jM||"px":"")}}J[p]=6z}C J}};z.6y=B(F){F.E=z.1D(F.E);if(!F.5a){F.5a=z.8E}A 2U=S z.d6(F);z.2c(2U,"6x",2U,B(){A pm={};R(A p in D.6w){A 1a=pm[p]=z.1x({},D.6w[p]);if(z.1Y(1a.1w)){1a.1w=1a.1w()}if(z.1Y(1a.1d)){1a.1d=1a.1d()}A d5=(p.1M().T("jL")>=0);B 8C(E,p){4w(p){2X"58":C E.8D;2X"3n":C E.6v}A v=z.1c(E,p);C(p=="2W")?2V(v):2k(v)};if(V 1a.1d=="1k"){1a.1d=8C(D.E,p)}I{if(V 1a.1w=="1k"){1a.1w=8C(D.E,p)}}if(d5){1a.1w=S z.1J(1a.1w);1a.1d=S z.1J(1a.1d)}I{1a.1w=(p=="2W")?2V(1a.1w):2k(1a.1w)}}D.2C=S d4(pm)});z.2c(2U,"8B",2U,B(8A){R(A s in 8A){z.1c(D.E,s,8A[s])}});C 2U}})()}',62,1711,'|||||||||||||||||||||||||||||||||||dojo|var|function|return|this|node|args|length|evt|else|ret|true|null|obj|elem|dfd|arguments|arr|for|new|indexOf|false|typeof||_base|push|type||te|||apply|attr|||||prop|xhr|style|end|doc|match|uri|_hasResource|key|del|undefined|isIE|item|forEach|djConfig|name|document|query|while|_66|try|res|start|mixin|catch|console|split|root|prototype|byId|gcs|ioArgs|err|NodeList|_p|Color|debug|parentNode|toLowerCase|instanceof|Error|constructor|provide|isString|ta|255|val|_a|global|_69|isFunction|value||substring|join|map|tn||window||path|_343|_220|_listeners|connect|call|json|replace|left|_b|toString|128|parseFloat|isArray|throw||_percent|hitch|step|declare|charAt|nodeType|_3c3|nidx|slice|faux|fired|_c4|_7e|loc|curve|_active|url|_44c|responseText|str|_312|idx|tqp|isNaN|isOpera|_22d|callee|add|_18b|_f8|_e2|_41|anim|Number|opacity|case|Math|_paused|Deferred|lastIndexOf|||||||||shift|substr|string|_3e7|_3ce|break|_w|charCode|_listener|_d5|_c5|authority|_49|width|isSafari|_49e|fire|_timer|_47b|_465|eval|_in|_40c|_409|_362|_3d9|className|_3d5|_386|_37a|body|getComputedStyle|box|_221|keyCode|remove|_8d|_46|paused|status|not|_478|_461|form|splice|filter|concat|tret|childNodes|_38b|_367|_33d||||||||||_340|_348|keypress|appendChild|_toArray|Array|_2b0|_toPixelValue|ref|_fixEvent|_19f|_14c|_14a|_150|_141|declaredClass|_d4|_99|_Url|_83|scheme|_67|_3d|switch|getValue|_startRepeatCount|repeat|_startTime|_47e|cancel|tif|load|to|with|tf|getElementsByTagName|number|_34c|_342|extend|_1e3|_normalizeEventName|_14b|_14e|results|self|cbfn|_f9|_d8|_b2|src|_88|dav||baseUrl|fragment|_loadedModules|_44|_43|_loaders|mll|height||easing|play|setTimeout|Date|clearTimeout|hdr|content|code|errback|_464|addCallbacks|_450|fromJson|_413|_3fc|_3ee|max|_31e|cond|getAttribute|_3d4|obi|tagName|_360|_381|contains|firstChild|_368|_372|_320|place|_2fa|scrollTop|_299|scrollLeft|top|documentElement|_288|_287|_getBorderExtents|_23f|_23d|_239|_218|_216|_211|eles|target|keys|shiftKey|ctrlKey|event|192|iel|_1db|delete|_1cf||addEventListener|String|_1af|_157|array|_14d|continue|_14f|_137|_11f|_106|_findMethod|has|_delegate|_dc|_d3|loaded|_9a|_loadInit|_inFlightCount|getObject|tv|_4f|_postLoad|_2d|offsetWidth|properties|beforeBegin|animateProperty|_4ad|_4a6|isKhtml|_fade|100|headers|readyState|timeout|_469|_457|_44d|formToObject|_441|comment|_43d|_36f|_419|tp|_40a|_406|_407|_373|_403|_3e6|_31b|cbi|test|_3c7|nextSibling|last|_3a1|_38e|_365|_36b|ecn|_364|_363|_356|_35e|_35f|_34f|_34d|_349|trim|tci|_328|_32b|_31f|_31c|_anim|_300|_2ff|_2f5|_2e7|removeClass|addClass|func|_2c4|cls|_2a9|_2ae|_280|_27f|_getPadExtents|isMoz|none|_233|cssText|_214|_fixCallback|_synthesizeEvent|stopPropagation|preventDefault|_setKeyChar|_1e1|ieh|_1d7|_1be|colorFromArray|sanitize|bits|rgb|_156|_fire|_resback|_13d|partial|_13a|silentlyCancelled|_topics|_127|_f1|_f0|superclass|_ec|_e3|mct|setObject|_bf|_b3|object|require|_92|_khtmlTimer|location|XMLHTTP|locale|dua|_71|_modulePrefixes|_55|_loadModule|_51|_50|_4e|pop|_3f|_callLoaded|_unloaders|_loadNotifying|_loadedUrls|_27|_24|_1d|_5|_4b7|onAnimate|getStyle|offsetHeight|_defaultEasing|toCss|_properties|fadeOut|fadeIn|_49f|auto|zoom|_cycle|_endTime|valueOf|_494|duration|_492|DELETE|_ioAddQueryToUrl|putData|contentType|password|user|_isDocumentOk|application|||||_466||||||startTime|_xhrObj|_45f|handleAs|addBoth|error|text|objectToQuery|_44f|ActiveXObject|_443|_442|filtered|_43f|_43e|_437|file|tnl|_41c|_filterQueryResult|_zipIdx|_408|_402|evaluate|_3ed|_380|fHit|_361|_33b|_3da|_3ab|_3d6|RegExp|_327|_3cf|_3c9|child|innerHTML|first|tval|_391|class|pnc|_37e|_37c|_375|_366|_35c|_35a|_353|_33c|_336|_314|||_315|_oe|_307|_309|cloneNode|after|createElement||_2f8|_2ef|_2ee|unshift|coords|some|every||_2cb|script|_2c9|parent||a2p||_2c3|_2bd||abs|_getMarginBox|_2b3|_2a6|position|_2a7|_2ac|_2ab|_getIeDocumentElementOffset|getBoundingClientRect|ownerDocument|_2a3|clientWidth|_isBodyLtr|_fixIeBiDiScrollLeft|_bodyLtr|_29d|_getContentBox|_setBox|_getMarginExtents|_getPadBorderExtents|_usesBorderBox|boxModel|pcs|st|sl|_240|runtimeStyle|_dcm|BackCompat|compatMode|default|_21b|_d|html|_event_listener|handlers|PAGE_DOWN|PAGE_UP|RIGHT_ARROW|LEFT_ARROW|DOWN_ARROW|UP_ARROW|_preventDefault||_stopPropagation|returnValue||_trySetKeyCode|cancelBubble|currentTarget|106|_1ee|111||_1e8|_1e7|||se|srcElement|onkeydown||_1d0|_disconnect|lid|_1c0|_connect|_set|_195|_185|_183|_17d|_everyOrSome|_16b|_172|_15b|Function|_154|_escapeString|_140|chain|_check|canceller|_12d|_124|_11a|_10d|_107|inherited|_fa|_f2|_findMixin|_constructor|preamble|_de|clone|tmp|_c7|TMP|_be|_ba|_mixin|isBrowser|lang|firebug||param|modulePaths|_a7|_fireCallback|_a0|setContext||_9c|unloaded||||_96|_93|navigator|_90|_89||protocol|_84|_86|_XMLHTTP_PROGIDS|gears|google|setAttribute|_80|_77|cfg|_6f|_getModuleSymbols|_5a|_58|_53|_4d|_4c|_45|_40|_moduleHasPrefix|_loadUri|_28|_26|_21|_22|tests|doh|_20|_1f|_1c|version|_1b|_19|_getProp|_11|_4|_4a5|_4b3|_Animation|tempColor|blendColors|PI|sin|||||_49a|normal|onEnd||rate||curr|onStop|_497||_496|pct|onPause|onPlay|onBegin|delay||_491|_Line|_48b|wrapForm|PUT|_487|POST|GET|_476|_474|_472|_ioWatch|send|_471|setRequestHeader|open|callback|setInterval|_470|resHandle|_46f|ioCheck|_46e|validCheck|getTime|_ioCancelAll|addOnUnload|clearInterval|dojoType|now|canceled|_blockAsync|_45e|_45c|_459|_ioSetArgs|_contentHandlers|abort|_458|_456||||addErrback|_454|addCallback|_452|_44b|_44a|_449|preventCache|responseXML|Microsoft|JSON|usePlainJson|_431|toJson|_430|_42d|image|opt|ria|_421|_41b|_40b|_zip|_410|_40d|_357|sqf|_374|_3e5|_3df|_38f|clc|pred|parseInt|ntf|_3bf|_3bc|cnl|previousSibling|_3a9|_3a6|_39c|_399|_396|_392|__cachedIndex|__cachedLength|_376|iterateNext|_34a|_355|_354|_32c|_350|_34b|_33f|_33e|_33a|_338|_334|_332||_330|_32e||_322|_316|mousemove|mouseout|mouseover|_305|lastChild||_2f9||_2f2|_2f1|removeChild|_2ec|_2eb|_2ea|_2e6||_2e4|_2e2|_2d6|_2d5|_2d4|_2d3|_2d2|_2d1|_2cd|_2cc|scs|write|_2c8|hasClass|_2c0|_2bb|_2b5|_abs|_docScroll|offsetParent|offsetTop|offsetLeft|absolute|getBoxObjectFor|clientLeft|_setContentSize|_setMarginBox|_28d|_286|_285|_289|NaN|_281|border|_272|_26b|_260|_258|_253|_24c|_246|_23a|_getOpacity|_setOpacity|_238|td|tr|nodeName|FILTER|_22f|_22e|currentStyle|_22c|_22b|display|QuirksMode|unselectable|_217|isMozilla|getElementById|attributes|all|_ie_listener|_getIeDispatcher|_1fd|NUM_LOCK|SCROLL_LOCK|INSERT|END|HOME|PAUSE|F12|F11|F10|F9|F8|F7|F6|F5|F4|F3|F2|F1|63232|SHIFT_TAB|TAB|keyIdentifier|_1f3|stopEvent|_punctMap|222|219|186|onkeypress|_stealthKeyDown|_fixKeys|relatedTarget|_1e0|_1df|_stealthKeydown|_1d6|_1d5|_1d1|_1ca|_1c9|_1cb|_1c2|_1c1|_1c3|_1c4|_1bc|_1b3|_1b2|colorFromHex|colorFromRgb|named|colorFromString|mask|rgba|_19c|_197|_192|setColor|_180|_178|_177|_175|_174|_16d|_166|_164|_163|_162|_15c|_15d|_15e|index|__json__|toJsonIndentStr|_nextId|_12f|_12b|publish|_128|_126|_125|_122|_121|_123|_11c|_11b|_10c|_10b|_108|getDispatcher|argument|nom|_construct|_core|_makeCtor|_df|_db|deprecated|isObject|_cc||scope||_hitchArgs|_c2||pre|_c1|native|isDebug||registerModulePath|_a8||finally|||_a6|_a5|_a4|_a3|_a2|_a1|_9f|_9e|_9d|_9b|_98|_97|onbeforeunload|ipt|scr|complete|_95|userAgent|_modulesLoaded|initialized|_initFired|_8c|_8a|_getText|_87|ieForceActiveXXhr|Msxml2|isGears|_81|_gearsObject|googlegears|GearsFactory|isFF|_7d|Safari|_72|_name|_6c|ire|ore|_68|i18n|_5b|requireIf|_56|_52|loading|_4a|_loadPath|_47|_48|_global_omit_module_check|_getModulePrefix|_3c|_3a|_37|_30|Boolean|_loadUriAndCheck|_2e||cacheBust|_1e|_1a|_17|_16|_15|_14|_f|_10|_e|_9|_8|revision|flag|patch|minor|major|_6|color|units|needs|stopped|playing|stop|gotoPercent|pause|1000|implemented|yet|_48a|xhrDelete|rawXhrPut|xhrPut|postData|rawXhrPost|xhrPost|xhrGet|Type|Content|sync|response|http|bad|urlencoded|www|_watchInFlightError||exceeded|handle|action|getAttributeNode|loadXML|async|XMLDOM|prefixes|MSXML3|MSXML|MSXML2||xml|javascript|wasn|your|optional|message|off|turn|use|endpoints|issues|security|potential|avoid|mimetype|using|consider|please|decodeURIComponent|queryToObject|formToJson|formToQuery|encodeURIComponent|selected|option|multiple|checked|checkbox|radio|disabled|textarea|select|button|reset|submit|input|_3fb|hasAttribute|0n|even|odd|nth|_3b5|empty|_3b1|_3ad|htmlFor|_38a|under||exprssion|failure|ANY_TYPE|XPathResult|starts|keyup|keydown|mouseup|mousedown|blur|click|combine|span|addContent||adopt|orphan|_2de|_2dd|styles|_2da|_2d9|_2cf|_2ce|show|createPopup|toggleClass|scrollWidth|clientTop|ltr|direction|pageXOffset|pageYOffset|fixed|contentBox|marginBox|BUTTON|TABLE|_getBorderBox|clientHeight|visible|overflow|marginBottom|marginRight|marginTop|marginLeft|borderBottomWidth|borderBottomStyle|borderRightWidth|borderRightStyle|borderTopWidth|borderTopStyle|borderLeftWidth|borderLeftStyle|paddingBottom|paddingRight|paddingTop|paddingLeft|offset||min|padding||margin|Opacity|Alpha|alpha|filters|pixelLeft|medium|_22a|defaultView|before||insertBefore|KhtmlUserSelect|MozUserSelect|setSelectable|isDescendant|div|_destroyElement|BackgroundImageCache|execCommand|PageDown|PageUp|Right|Left|Down|Up|63289|63249|63248|PRINT_SCREEN|63302|63277|63276|63275|63273|63272|63250|63247|63246|63245|63244|63243|63242|63241|63240|63239|63238|63237|63236|63235|63234|63233|Enter|_1f9|which|_1f6|bubbledKeyCode|221|220||||191|190|189|188|187|toElement|fromElement|clientY|pageY||clientX|pageX|offsetY|||layerY|offsetX|layerX|parentWindow|_nop|_allow_leaks|145|144|126|F15|125|F14|124|F13|123|122|121|120|119|118|117|116|115|114|113|112|NUMPAD_DIVIDE|110|NUMPAD_PERIOD|109|NUMPAD_MINUS|108|NUMPAD_ENTER|107|NUMPAD_PLUS|NUMPAD_MULTIPLY|105|NUMPAD_9|104|NUMPAD_8|103|NUMPAD_7|102|NUMPAD_6|101|NUMPAD_5|NUMPAD_4||NUMPAD_3|NUMPAD_2|NUMPAD_1|NUMPAD_0||SELECT|RIGHT_WINDOW||LEFT_WINDOW||HELP|SPACE|ESCAPE|CAPS_LOCK|ALT|CTRL|SHIFT|ENTER|CLEAR|BACKSPACE|attachEvent|fixEvent|fromCharCode|keyChar|_1b9|removeEventListener|0x|round|toHex|toRgba|toRgb|aqua|teal|blue|navy|yellow|olive|lime|green|fuchsia|purple|red|maroon|white|gray|silver|black|boolean|called|already|Cancelled|connectPublisher|unsubscribe|subscribe|disconnect|_113|_112||_111|_110|||found|was||must|_|module|||required|likely|It|declaration|Mixin|separate|instead|property|initializer||pass|_c9|_bb|_b7|nfunction|isAlien|isFinite|isArrayLike|_firebug|withDoc|withGlobal|_writeIncludes|VML|behavior|addRule|createStyleSheet|vml|com|microsoft|schemas|urn|namespaces|onunload|onreadystatechange|defer|khtml|WebKit|DOMContentLoaded|enableMozDomContentLoaded|domcontentloaded|Unable|base|chrome|1223|304|300|200|available|XMLHttpRequest|_println|language|userLanguage|isQuirks|factory|mimeTypes|Factory|Gears|_7f|MSIE||Firefox|Gecko|Konqueror||Opera|appVersion|xd|browser|moduleUrl|port|host|hostenv|_requireLocalization|_5f|_5e|_5d|_5c|requireLocalization|requireAfterIf|_57|common|platformRequire|defined|symbol|_isXDomain|tried|Could|__package__|packageFileName|_42|useXDomain|flight|still|files|addOnLoad|failed|sourceURL|util|notice|without|change|subject|APIs|EXPERIMENTAL|experimental|removed|will|DEPRECATED|exists|10315|Rev|Mobile|Spidermonkey|Rhino||Browser|delayMozLoadingFix|preventBackButtonFix|libraryScriptUri|baseRelativePath|baseScriptUri|allowQueryConfig|warn|trace|timeEnd||time|profileEnd|profile|log|info|groupEnd|group|dirxml|dir|count|assert'.split('|'),0,{}); + +result += decompressedDojo.length; + +/* + +Prototype 1.5 rc0 + - Adapted from Ruby on Rails - http://dev.rubyonrails.org/browser/spinoffs/prototype/src + - By Lunarmedia, 06 August, 2006 + - Available at (and packed with) JavascriptCompressor.com + +Please note this version is missing the selector.js component of the full Prototype library. +You can get the compressed version of selector at JavascriptCompressor.com + +*/ + +var decompressedPrototype = function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[(function(e){return d[e]})];e=(function(){return'\\w+'});c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('d T={4l:\'1.5.8P\',3E:\'(?:<3G.*?>)((\\n|\\r|.)*?)(?:<\\/3G>)\',2v:7(){},K:7(x){c x}};d 1b={17:7(){c 7(){6.1I.2n(6,N)}}};d 1e=z q();q.u=7(5d,O){G(d 1G 2M O){5d[1G]=O[1G]}c 5d};q.1U=7(U){1j{f(U==1v)c\'1v\';f(U==1L)c\'1L\';c U.1U?U.1U():U.2C()}1s(e){f(e 8R 9l)c\'...\';25 e}};7j.v.1d=7(){d 43=6,23=$A(N),U=23.8S();c 7(){c 43.2n(U,23.3s($A(N)))}};7j.v.8U=7(U){d 43=6;c 7(C){c 43.8V(U,C||1W.C)}};q.u(8Q.v,{8W:7(){d 4Z=6.2C(16);f(6<16)c\'0\'+4Z;c 4Z},5j:7(){c 6+1},8Y:7(o){$R(0,6,11).V(o);c 6}});d 6s={6j:7(){d 48;G(d i=0;i0){f(I=O.I(1A)){L+=O.47(0,I.w);L+=(1z(I)||\'\').2C();O=O.47(I.w+I[0].t)}1D{L+=O,O=\'\'}}c L},92:7(1A,1z,3i){1z=6.2T.52(1z);3i=3i===1v?1:3i;c 6.2T(1A,7(I){f(--3i<0)c I[0];c 1z(I)})},93:7(1A,o){6.2T(1A,o);c 6},94:7(t,2S){t=t||30;2S=2S===1v?\'...\':2S;c 6.t>t?6.47(0,t-2S.t)+2S:6},9F:7(){c 6.2y(/^\\s+/,\'\').2y(/\\s+$/,\'\')},71:7(){c 6.2y(/<\\/?[^>]+>/7Y,\'\')},2Q:7(){c 6.2y(z 3O(T.3E,\'5P\'),\'\')},70:7(){d 6Y=z 3O(T.3E,\'5P\');d 5p=z 3O(T.3E,\'98\');c(6.I(6Y)||[]).1C(7(5o){c(5o.I(5p)||[\'\',\'\'])[1]})},3q:7(){c 6.70().1C(7(3G){c 4q(3G)})},9E:7(){d 1q=J.4Y(\'1q\');d 1Y=J.9D(6);1q.75(1Y);c 1q.3h},9c:7(){d 1q=J.4Y(\'1q\');1q.3h=6.71();c 1q.2z[0]?1q.2z[0].6q:\'\'},78:7(){d 7i=6.I(/^\\??(.*)$/)[1].3j(\'&\');c 7i.36({},7(5b,72){d 1i=72.3j(\'=\');5b[1i[0]]=1i[1];c 5b})},1Z:7(){c 6.3j(\'\')},3P:7(){d 2l=6.3j(\'-\');f(2l.t==1)c 2l[0];d 54=6.5g(\'-\')==0?2l[0].7e(0).3Y()+2l[0].7g(1):2l[0];G(d i=1,73=2l.t;i<73;i++){d s=2l[i];54+=s.7e(0).3Y()+s.7g(1)}c 54},1U:7(){c"\'"+6.2y(/\\\\/g,\'\\\\\\\\\').2y(/\'/g,\'\\\\\\\'\')+"\'"}});4b.v.2T.52=7(1z){f(2i 1z==\'7\')c 1z;d 2U=z 3n(1z);c 7(I){c 2U.7a(I)}};4b.v.9h=4b.v.78;d 3n=1b.17();3n.79=/(^|.|\\r|\\n)(#\\{(.*?)\\})/;3n.v={1I:7(2U,1A){6.2U=2U.2C();6.1A=1A||3n.79},7a:7(U){c 6.2U.2T(6.1A,7(I){d 53=I[1];f(53==\'\\\\\')c I[2];c 53+(U[I[3]]||\'\').2C()})}};d $1y=z q();d $49=z q();d 1p={V:7(o){d w=0;1j{6.2m(7(h){1j{o(h,w++)}1s(e){f(e!=$49)25 e}})}1s(e){f(e!=$1y)25 e}},9n:7(o){d L=11;6.V(7(h,w){L=L&&!!(o||T.K)(h,w);f(!L)25 $1y});c L},9o:7(o){d L=11;6.V(7(h,w){f(L=!!(o||T.K)(h,w))25 $1y});c L},3e:7(o){d P=[];6.V(7(h,w){P.W(o(h,w))});c P},7n:7(o){d L;6.V(7(h,w){f(o(h,w)){L=h;25 $1y}});c L},7o:7(o){d P=[];6.V(7(h,w){f(o(h,w))P.W(h)});c P},9p:7(1A,o){d P=[];6.V(7(h,w){d 7c=h.2C();f(7c.I(1A))P.W((o||T.K)(h,w))});c P},1M:7(U){d 51=Y;6.V(7(h){f(h==U){51=11;25 $1y}});c 51},36:7(45,o){6.V(7(h,w){45=o(45,h,w)});c 45},9q:7(1F){d 23=$A(N).47(1);c 6.3e(7(h){c h[1F].2n(h,23)})},9s:7(o){d L;6.V(7(h,w){h=(o||T.K)(h,w);f(L==1v||h>=L)L=h});c L},9u:7(o){d L;6.V(7(h,w){h=(o||T.K)(h,w);f(L==1v||hb?1:0}).3r(\'h\')},1Z:7(){c 6.3e(T.K)},9B:7(){d o=T.K,23=$A(N);f(2i 23.5e()==\'7\')o=23.9C();d 7l=[6].3s(23).1C($A);c 6.1C(7(h,w){c o(7l.3r(w))})},1U:7(){c\'#<1p:\'+6.1Z().1U()+\'>\'}};q.u(1p,{1C:1p.3e,5v:1p.7n,1k:1p.7o,8M:1p.1M,7p:1p.1Z});d $A=1E.7q=7(2R){f(!2R)c[];f(2R.1Z){c 2R.1Z()}1D{d P=[];G(d i=0;i<2R.t;i++)P.W(2R[i]);c P}};q.u(1E.v,1p);f(!1E.v.4d)1E.v.4d=1E.v.4m;q.u(1E.v,{2m:7(o){G(d i=0;i<6.t;i++)o(6[i])},5i:7(){6.t=0;c 6},7r:7(){c 6[0]},5e:7(){c 6[6.t-1]},7s:7(){c 6.1k(7(h){c h!=1v||h!=1L})},6J:7(){c 6.36([],7(6H,h){c 6H.3s(h&&h.5D==1E?h.6J():[h])})},5s:7(){d 4N=$A(N);c 6.1k(7(h){c!4N.1M(h)})},5g:7(U){G(d i=0;i<6.t;i++)f(6[i]==U)c i;c-1},4m:7(5h){c(5h!==Y?6:6.1Z()).4d()},1U:7(){c\'[\'+6.1C(q.1U).1N(\', \')+\']\'}});d 4h={2m:7(o){G(d 1O 2M 6){d h=6[1O];f(2i h==\'7\')49;d 1i=[1O,h];1i.1O=1O;1i.h=h;o(1i)}},7t:7(){c 6.3r(\'1O\')},4N:7(){c 6.3r(\'h\')},7u:7(2N){c $H(2N).36($H(6),7(4Q,1i){4Q[1i.1O]=1i.h;c 4Q})},7w:7(){c 6.1C(7(1i){c 1i.1C(4n).1N(\'=\')}).1N(\'&\')},1U:7(){c\'#<4h:{\'+6.1C(7(1i){c 1i.1C(q.1U).1N(\': \')}).1N(\', \')+\'}>\'}};7 $H(U){d 2N=q.u({},U||{});q.u(2N,1p);q.u(2N,4h);c 2N};3L=1b.17();q.u(3L.v,1p);q.u(3L.v,{1I:7(22,2x,2H){6.22=22;6.2x=2x;6.2H=2H},2m:7(o){d h=6.22;2q{o(h);h=h.5j()}1H(6.1M(h))},1M:7(h){f(h<6.22)c Y;f(6.2H)c h<6.2x;c h<=6.2x}});d $R=7(22,2x,2H){c z 3L(22,2x,2H)};d M={4w:7(){c 6s.6j(7(){c z 5C()},7(){c z 5n(\'7y.6d\')},7(){c z 5n(\'7z.6d\')})||Y},4s:0};M.2W={3b:[],2m:7(o){6.3b.2m(o)},69:7(4F){f(!6.1M(4F))6.3b.W(4F)},7A:7(5t){6.3b=6.3b.5s(5t)},3y:7(1a,26,E,2Z){6.V(7(3o){f(3o[1a]&&2i 3o[1a]==\'7\'){1j{3o[1a].2n(3o,[26,E,2Z])}1s(e){}}})}};q.u(M.2W,1p);M.2W.69({5G:7(){M.4s++},1B:7(){M.4s--}});M.44=7(){};M.44.v={4a:7(m){6.m={1F:\'4j\',4p:11,5H:\'5E/x-86-Q-7C\',28:\'\'};q.u(6.m,m||{})},3l:7(){c 6.E.32==1v||6.E.32==0||(6.E.32>=84&&6.E.32<7E)},7G:7(){c!6.3l()}};M.3t=1b.17();M.3t.5L=[\'7H\',\'80\',\'7I\',\'7J\',\'4t\'];M.3t.v=q.u(z M.44(),{1I:7(1l,m){6.E=M.4w();6.4a(m);6.26(1l)},26:7(1l){d 28=6.m.28||\'\';f(28.t>0)28+=\'&7K=\';1j{6.1l=1l;f(6.m.1F==\'7L\'&&28.t>0)6.1l+=(6.1l.I(/\\?/)?\'&\':\'?\')+28;M.2W.3y(\'5G\',6,6.E);6.E.7N(6.m.1F,6.1l,6.m.4p);f(6.m.4p){6.E.5T=6.5J.1d(6);2Y((7(){6.4r(1)}).1d(6),10)}6.5A();d 1c=6.m.5V?6.m.5V:28;6.E.7O(6.m.1F==\'4j\'?1c:1L)}1s(e){6.3p(e)}},5A:7(){d 1P=[\'X-7P-7Q\',\'5C\',\'X-T-4l\',T.4l,\'7R\',\'1Y/7m, 1Y/2e, 5E/5F, 1Y/5F, */*\'];f(6.m.1F==\'4j\'){1P.W(\'5Q-2g\',6.m.5H);f(6.E.7S)1P.W(\'7T\',\'7U\')}f(6.m.1P)1P.W.2n(1P,6.m.1P);G(d i=0;i<1P.t;i+=2)6.E.7V(1P[i],1P[i+1])},5J:7(){d 2F=6.E.2F;f(2F!=1)6.4r(6.E.2F)},4A:7(B){1j{c 6.E.7W(B)}1s(e){}},5M:7(){1j{c 4q(\'(\'+6.4A(\'X-7X\')+\')\')}1s(e){}},5R:7(){1j{c 4q(6.E.3F)}1s(e){6.3p(e)}},4r:7(2F){d C=M.3t.5L[2F];d E=6.E,2Z=6.5M();f(C==\'4t\'){1j{(6.m[\'2I\'+6.E.32]||6.m[\'2I\'+(6.3l()?\'81\':\'82\')]||T.2v)(E,2Z)}1s(e){6.3p(e)}f((6.4A(\'5Q-2g\')||\'\').I(/^1Y\\/7m/i))6.5R()}1j{(6.m[\'2I\'+C]||T.2v)(E,2Z);M.2W.3y(\'2I\'+C,6,E,2Z)}1s(e){6.3p(e)}f(C==\'4t\')6.E.5T=T.2v},3p:7(57){(6.m.5W||T.2v)(6,57);M.2W.3y(\'5W\',6,57)}});M.4C=1b.17();q.u(q.u(M.4C.v,M.3t.v),{1I:7(1w,1l,m){6.4x={3m:1w.3m?$(1w.3m):$(1w),3z:1w.3z?$(1w.3z):(1w.3m?1L:$(1w))};6.E=M.4w();6.4a(m);d 1B=6.m.1B||T.2v;6.m.1B=(7(E,U){6.5Y();1B(E,U)}).1d(6);6.26(1l)},5Y:7(){d 3A=6.3l()?6.4x.3m:6.4x.3z;d 3k=6.E.3F;f(!6.m.3q)3k=3k.2Q();f(3A){f(6.m.60){z 6.m.60(3A,3k)}1D{k.6h(3A,3k)}}f(6.3l()){f(6.1B)2Y(6.1B.1d(6),10)}}});M.61=1b.17();M.61.v=q.u(z M.44(),{1I:7(1w,1l,m){6.4a(m);6.1B=6.m.1B;6.1J=(6.m.1J||2);6.2s=(6.m.2s||1);6.4B={};6.1w=1w;6.1l=1l;6.22()},22:7(){6.m.1B=6.63.1d(6);6.2D()},7b:7(){6.4B.1B=1v;89(6.65);(6.1B||T.2v).2n(6,N)},63:7(26){f(6.m.2s){6.2s=(26.3F==6.64?6.2s*6.m.2s:1);6.64=26.3F}6.65=2Y(6.2D.1d(6),6.2s*6.1J*4z)},2D:7(){6.4B=z M.4C(6.1w,6.1l,6.m)}});7 $(){d P=[],4;G(d i=0;i<4V>\'+6.2t+\'\';c $A(1q.2z[0].2z[0].2z)}};d 1g=z q();1g.6W=1b.17();1g.6W.v=q.u(z 1e.1g(\'96\'),{2V:7(){6.1K.97(6.4)},2X:7(2h){2h.V((7(2j){6.4.1X.55(2j,6.4)}).1d(6))}});1g.5m=1b.17();1g.5m.v=q.u(z 1e.1g(\'99\'),{2V:7(){6.1K.56(6.4);6.1K.74(11)},2X:7(2h){2h.4m(Y).V((7(2j){6.4.55(2j,6.4.9a)}).1d(6))}});1g.7h=1b.17();1g.7h.v=q.u(z 1e.1g(\'9d\'),{2V:7(){6.1K.56(6.4);6.1K.74(6.4)},2X:7(2h){2h.V((7(2j){6.4.75(2j)}).1d(6))}});1g.76=1b.17();1g.76.v=q.u(z 1e.1g(\'9i\'),{2V:7(){6.1K.9m(6.4)},2X:7(2h){2h.V((7(2j){6.4.1X.55(2j,6.4.9t)}).1d(6))}});k.3S=1b.17();k.3S.v={1I:7(4){6.4=$(4)},2m:7(o){6.4.1f.3j(/\\s+/).1k(7(B){c B.t>0}).2m(o)},5c:7(1f){6.4.1f=1f},7k:7(5a){f(6.1M(5a))c;6.5c(6.1Z().3s(5a).1N(\' \'))},42:7(4c){f(!6.1M(4c))c;6.5c(6.1k(7(1f){c 1f!=4c}).1N(\' \'))},2C:7(){c 6.1Z().1N(\' \')}};q.u(k.3S.v,1p);d 5I={5i:7(){G(d i=0;i=0){2b=4.m[w];h=2b.h||2b.1Y}c[4.B,h]},5X:7(4){d h=[];G(d i=0;i<4.t;i++){d 2b=4.m[i];f(2b.87)h.W(2b.h||2b.1Y)}c[4.B,h]}};d $F=D.k.1x;1e.3D=7(){};1e.3D.v={1I:7(4,1J,1a){6.1J=1J;6.4=$(4);6.1a=1a;6.2K=6.1x();6.2A()},2A:7(){5Z(6.2D.1d(6),6.1J*4z)},2D:7(){d h=6.1x();f(6.2K!=h){6.1a(6.4,h);6.2K=h}}};D.k.3C=1b.17();D.k.3C.v=q.u(z 1e.3D(),{1x:7(){c D.k.1x(6.4)}});D.3C=1b.17();D.3C.v=q.u(z 1e.3D(),{1x:7(){c D.3a(6.4)}});1e.2c=7(){};1e.2c.v={1I:7(4,1a){6.4=$(4);6.1a=1a;6.2K=6.1x();f(6.4.1h.2w()==\'Q\')6.67();1D 6.2A(6.4)},4K:7(){d h=6.1x();f(6.2K!=h){6.1a(6.4,h);6.2K=h}},67:7(){d 12=D.2L(6.4);G(d i=0;i<12.t;i++)6.2A(12[i])},2A:7(4){f(4.2g){6c(4.2g.2w()){1r\'6g\':1r\'6i\':1o.3B(4,\'8j\',6.4K.1d(6));1y;1r\'6l\':1r\'1Y\':1r\'3J\':1r\'1k-6n\':1r\'1k-8t\':1o.3B(4,\'8u\',6.4K.1d(6));1y}}}};D.k.2c=1b.17();D.k.2c.v=q.u(z 1e.2c(),{1x:7(){c D.k.1x(6.4)}});D.2c=1b.17();D.2c.v=q.u(z 1e.2c(),{1x:7(){c D.3a(6.4)}});f(!1W.1o){d 1o=z q()}q.u(1o,{8C:8,8F:9,8H:13,8I:27,8J:37,8L:38,8O:39,8T:40,8X:46,4:7(C){c C.Z||C.91},95:7(C){c(((C.6X)&&(C.6X==1))||((C.6Z)&&(C.6Z==1)))},9b:7(C){c C.9e||(C.9f+(J.3R.2G||J.1c.2G))},9g:7(C){c C.9j||(C.9k+(J.3R.2O||J.1c.2O))},7b:7(C){f(C.7d){C.7d();C.9r()}1D{C.48=Y;C.9w=11}},9A:7(C,1h){d 4=1o.4(C);1H(4.1X&&(!4.1h||(4.1h.3Y()!=1h.3Y())))4=4.1X;c 4},1T:Y,5u:7(4,B,1V,1u){f(!6.1T)6.1T=[];f(4.5f){6.1T.W([4,B,1V,1u]);4.5f(B,1V,1u)}1D f(4.4i){6.1T.W([4,B,1V,1u]);4.4i(\'2I\'+B,1V)}},66:7(){f(!1o.1T)c;G(d i=0;i<1o.1T.t;i++){1o.5N.2n(6,1o.1T[i]);1o.1T[i][0]=1L}1o.1T=Y},3B:7(4,B,1V,1u){d 4=$(4);1u=1u||Y;f(B==\'5U\'&&(33.4u.I(/3x|3w|3u/)||4.4i))B=\'5K\';6.5u(4,B,1V,1u)},5N:7(4,B,1V,1u){d 4=$(4);1u=1u||Y;f(B==\'5U\'&&(33.4u.I(/3x|3w|3u/)||4.4k))B=\'5K\';f(4.5x){4.5x(B,1V,1u)}1D f(4.4k){1j{4.4k(\'2I\'+B,1V)}1s(e){}}}});f(33.4u.I(/\\88\\b/))1o.3B(1W,\'8a\',1o.66,Y);d 2d={6o:Y,4P:7(){6.6z=1W.8e||J.3R.2G||J.1c.2G||0;6.6F=1W.8g||J.3R.2O||J.1c.2O||0},6u:7(4){d 19=0,15=0;2q{19+=4.2O||0;15+=4.2G||0;4=4.1X}1H(4);c[15,19]},35:7(4){d 19=0,15=0;2q{19+=4.29||0;15+=4.2f||0;4=4.1Q}1H(4);c[15,19]},68:7(4){d 19=0,15=0;2q{19+=4.29||0;15+=4.2f||0;4=4.1Q;f(4){p=k.1R(4,\'14\');f(p==\'3T\'||p==\'2o\')1y}}1H(4);c[15,19]},1Q:7(4){f(4.1Q)c 4.1Q;f(4==J.1c)c 4;1H((4=4.1X)&&4!=J.1c)f(k.1R(4,\'14\')!=\'4G\')c 4;c J.1c},8o:7(4,x,y){f(6.6o)c 6.6r(4,x,y);6.3g=x;6.34=y;6.1t=6.35(4);c(y>=6.1t[1]&&y<6.1t[1]+4.2k&&x>=6.1t[0]&&x<6.1t[0]+4.2p)},6r:7(4,x,y){d 4S=6.6u(4);6.3g=x+4S[0]-6.6z;6.34=y+4S[1]-6.6F;6.1t=6.35(4);c(6.34>=6.1t[1]&&6.34<6.1t[1]+4.2k&&6.3g>=6.1t[0]&&6.3g<6.1t[0]+4.2p)},8E:7(3Z,4){f(!3Z)c 0;f(3Z==\'8G\')c((6.1t[1]+4.2k)-6.34)/4.2k;f(3Z==\'8K\')c((6.1t[0]+4.2p)-6.3g)/4.2p},77:7(O,Z){O=$(O);Z=$(Z);Z.l.14=\'2o\';d 2P=6.35(O);Z.l.1n=2P[1]+\'1m\';Z.l.18=2P[0]+\'1m\';Z.l.21=O.2p+\'1m\';Z.l.24=O.2k+\'1m\'},4e:7(4M){d 19=0,15=0;d 4=4M;2q{19+=4.29||0;15+=4.2f||0;f(4.1Q==J.1c)f(k.1R(4,\'14\')==\'2o\')1y}1H(4=4.1Q);4=4M;2q{19-=4.2O||0;15-=4.2G||0}1H(4=4.1X);c[15,19]},77:7(O,Z){d m=q.u({5l:11,5r:11,5B:11,5q:11,29:0,2f:0},N[2]||{});O=$(O);d p=2d.4e(O);Z=$(Z);d 2J=[0,0];d 3v=1L;f(k.1R(Z,\'14\')==\'2o\'){3v=2d.1Q(Z);2J=2d.4e(3v)}f(3v==J.1c){2J[0]-=J.1c.2f;2J[1]-=J.1c.29}f(m.5l)Z.l.18=(p[0]-2J[0]+m.2f)+\'1m\';f(m.5r)Z.l.1n=(p[1]-2J[1]+m.29)+\'1m\';f(m.5B)Z.l.21=O.2p+\'1m\';f(m.5q)Z.l.24=O.2k+\'1m\'},8b:7(4){4=$(4);f(4.l.14==\'2o\')c;2d.4P();d 2P=2d.68(4);d 1n=2P[1];d 18=2P[0];d 21=4.6m;d 24=4.6p;4.6P=18-3X(4.l.18||0);4.6I=1n-3X(4.l.1n||0);4.5k=4.l.21;4.7f=4.l.24;4.l.14=\'2o\';4.l.1n=1n+\'1m\';4.l.18=18+\'1m\';4.l.21=21+\'1m\';4.l.24=24+\'1m\'},8w:7(4){4=$(4);f(4.l.14==\'3T\')c;2d.4P();4.l.14=\'3T\';d 1n=3X(4.l.1n||0)-(4.6I||0);d 18=3X(4.l.18||0)-(4.6P||0);4.l.1n=1n+\'1m\';4.l.18=18+\'1m\';4.l.24=4.7f;4.l.21=4.5k}};f(/3x|3w|3u/.4v(33.62)){2d.35=7(4){d 19=0,15=0;2q{19+=4.29||0;15+=4.2f||0;f(4.1Q==J.1c)f(k.1R(4,\'14\')==\'2o\')1y;4=4.1Q}1H(4);c[15,19]}};',62,600,'||||element||this|function|||||return|var||if||value|||Element|style|options||iterator||Object|||length|extend|prototype|index|||new||name|event|Form|transport||for||match|document||result|Ajax|arguments|source|results|form|||Prototype|object|each|push||false|target||true|elements||position|valueL||create|left|valueT|callback|Class|body|bind|Abstract|className|Insertion|tagName|pair|try|select|url|px|top|Event|Enumerable|div|case|catch|offset|useCapture|undefined|container|getValue|break|replacement|pattern|onComplete|map|else|Array|method|property|while|initialize|frequency|range|null|include|join|key|requestHeaders|offsetParent|getStyle|parameter|observers|inspect|observer|window|parentNode|text|toArray|els|width|start|args|height|throw|request||parameters|offsetTop|methods|opt|EventObserver|Position|html|offsetLeft|type|fragments|typeof|fragment|offsetHeight|oStringList|_each|apply|absolute|offsetWidth|do|cache|decay|content|input|emptyFunction|toLowerCase|end|replace|childNodes|registerCallback|display|toString|onTimerEvent|Serializers|readyState|scrollLeft|exclusive|on|delta|lastValue|getElements|in|hash|scrollTop|offsets|stripScripts|iterable|truncation|gsub|template|initializeRange|Responders|insertContent|setTimeout|json||hidden|status|navigator|ycomp|cumulativeOffset|inject||||serialize|responders|_overflow|Methods|collect|adjacency|xcomp|innerHTML|count|split|response|responseIsSuccess|success|Template|responder|dispatchException|evalScripts|pluck|concat|Request|KHTML|parent|Safari|Konqueror|dispatch|failure|receiver|observe|Observer|TimedObserver|ScriptFragment|responseText|script|inputs|ancestor|textarea|classNames|ObjectRange|node|typeName|RegExp|camelize|none|documentElement|ClassNames|relative|right|overflow|HTMLElement|parseFloat|toUpperCase|mode||currentlyExecuting|remove|__method|Base|memo||slice|returnValue|continue|setOptions|String|classNameToRemove|_reverse|page|focus|queryComponent|Hash|attachEvent|post|detachEvent|Version|reverse|encodeURIComponent|disabled|asynchronous|eval|respondToReadyState|activeRequestCount|Complete|appVersion|test|getTransport|containers|matchingInputs|1000|header|updater|Updater|getElementsByTagName|child|responderToAdd|static|tagElements|queryComponents|defaultView|onElementEvent|css|forElement|values|visibility|prepare|mergedHash|pos|offsetcache|_madePositioned|visible|tbody|findOrStore|_nativeExtensions|createElement|digits|trues|found|prepareReplacement|before|camelizedString|insertBefore|selectNodeContents|exception|falses|criteria|classNameToAdd|params|set|destination|last|addEventListener|indexOf|inline|clear|succ|_originalWidth|setLeft|Top|ActiveXObject|scriptTag|matchOne|setHeight|setTop|without|responderToRemove|_observeAndCache|find|reset|removeEventListener|activate|findFirstElement|setRequestHeaders|setWidth|XMLHttpRequest|constructor|application|xml|onCreate|contentType|Field|onStateChange|keydown|Events|evalJSON|stopObserving|inputSelector|img|Content|evalResponse|selectOne|onreadystatechange|keypress|postBody|onException|selectMany|updateContent|setInterval|insertion|PeriodicalUpdater|userAgent|updateComplete|lastText|timer|unloadCache|registerFormCallbacks|positionedOffset|register|parentElement|children|switch|XMLHTTP|_extended|hide|checkbox|update|radio|these|outerHTML|password|clientWidth|one|includeScrollOffsets|clientHeight|nodeValue|withinIncludingScrolloffsets|Try|scrollTo|realOffset|getComputedStyle|show|currentStyle|auto|deltaX|originalPosition|originalVisibility|originalWidth|originalHeight|opera|deltaY|bottom|array|_originalTop|flatten|addMethods|lambda|Toggle|toggle|insertAdjacentHTML|_originalLeft|PeriodicalExecuter|ownerDocument|createRange|createContextualFragment|contentFromAnonymousTable|table|Before|which|matchAll|button|extractScripts|stripTags|pairString|len|collapse|appendChild|After|clone|toQueryParams|Pattern|evaluate|stop|stringValue|preventDefault|charAt|_originalHeight|substring|Bottom|pairs|Function|add|collections|javascript|detect|findAll|entries|from|first|compact|keys|merge|present|toQueryString|getInputs|Msxml2|Microsoft|unregister|disable|urlencoded|blur|300|enable|responseIsFailure|Uninitialized|Loaded|Interactive|_|get|focusFirstElement|open|send|Requested|With|Accept|overrideMimeType|Connection|close|setRequestHeader|getResponseHeader|JSON|gi|submit|Loading|Success|Failure|checked|200|selectedIndex|www|selected|bMSIE|clearTimeout|unload|absolutize|string|getElementById|pageXOffset|getElementsByClassName|pageYOffset|removeChild|replaceChild|click|getHeight|hasClassName|addClassName|removeClassName|within|cleanWhitespace|nodeType|empty|childOf|multiple|change|getPropertyValue|relativize|setStyle|getDimensions|makePositioned|undoPositioned|makeClipping|KEY_BACKSPACE|undoClipping|overlap|KEY_TAB|vertical|KEY_RETURN|KEY_ESC|KEY_LEFT|horizontal|KEY_UP|member|tr|KEY_RIGHT|0_RC_0|Number|instanceof|shift|KEY_DOWN|bindAsEventListener|call|toColorPart|KEY_DELETE|times|finally|callee|srcElement|sub|scan|truncate|isLeftClick|beforeBegin|setStartBefore|im|afterBegin|firstChild|pointerX|unescapeHTML|beforeEnd|pageX|clientX|pointerY|parseQuery|afterEnd|pageY|clientY|RangeError|setStartAfter|all|any|grep|invoke|stopPropagation|max|nextSibling|min|partition|cancelBubble|reject|sortBy|sort|findElement|zip|pop|createTextNode|escapeHTML|strip'.split('|'),0,{}) + +result += decompressedPrototype.length; + +} + +var expected = 511508; +if (result != expected) + throw "ERROR: bad result: expected " + expected + " but got " + result; + diff --git a/Jint.Tests.CommonScripts/Scripts/string-validate-input.js b/Jint.Tests.CommonScripts/Scripts/string-validate-input.js new file mode 100644 index 0000000000..f5dab777dd --- /dev/null +++ b/Jint.Tests.CommonScripts/Scripts/string-validate-input.js @@ -0,0 +1,92 @@ +letters = new Array("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"); +numbers = new Array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26); +colors = new Array("FF","CC","99","66","33","00"); + +var endResult; + +function doTest() +{ + endResult = ""; + + // make up email address + for (var k=0;k<4000;k++) + { + username = makeName(6); + (k%2)?email=username+"@mac.com":email=username+"(at)mac.com"; + + // validate the email address + var pattern = /^[a-zA-Z0-9\-\._]+@[a-zA-Z0-9\-_]+(\.?[a-zA-Z0-9\-_]*)\.[a-zA-Z]{2,3}$/; + + if(pattern.test(email)) + { + var r = email + " appears to be a valid email address."; + addResult(r); + } + else + { + r = email + " does NOT appear to be a valid email address."; + addResult(r); + } + } + + // make up ZIP codes + for (var s=0;s<4000;s++) + { + var zipGood = true; + var zip = makeNumber(4); + (s%2)?zip=zip+"xyz":zip=zip.concat("7"); + + // validate the zip code + for (var i = 0; i < zip.length; i++) { + var ch = zip.charAt(i); + if (ch < "0" || ch > "9") { + zipGood = false; + r = zip + " contains letters."; + addResult(r); + } + } + if (zipGood && zip.length>5) + { + zipGood = false; + r = zip + " is longer than five characters."; + addResult(r); + } + if (zipGood) + { + r = zip + " appears to be a valid ZIP code."; + addResult(r); + } + } +} + +function makeName(n) +{ + var tmp = ""; + for (var i=0;i + [Theory(DisplayName = "Sunspider")] + [InlineData("3d-cube", "3d-cube.js")] + [InlineData("3d-morph", "3d-morph.js")] + [InlineData("3d-raytrace", "3d-raytrace.js")] + [InlineData("access-binary-trees", "access-binary-trees.js")] + [InlineData("access-fannkuch", "access-fannkuch.js")] + [InlineData("access-nbody", "access-nbody.js")] + [InlineData("access-nsieve", "access-nsieve.js")] + [InlineData("bitops-3bit-bits-in-byte", "bitops-3bit-bits-in-byte.js")] + [InlineData("bitops-bits-in-byte", "bitops-bits-in-byte.js")] + [InlineData("bitops-bitwise-and", "bitops-bitwise-and.js")] + [InlineData("bitops-nsieve-bits", "bitops-nsieve-bits.js")] + [InlineData("controlflow-recursive", "controlflow-recursive.js")] + [InlineData("crypto-aes", "crypto-aes.js")] + [InlineData("crypto-md5", "crypto-md5.js")] + [InlineData("crypto-sha1", "crypto-sha1.js")] + [InlineData("date-format-tofte", "date-format-tofte.js")] + [InlineData("date-format-xparb", "date-format-xparb.js")] + [InlineData("math-cordic", "math-cordic.js")] + [InlineData("math-partial-sums", "math-partial-sums.js")] + [InlineData("math-spectral-norm", "math-spectral-norm.js")] + [InlineData("regexp-dna", "regexp-dna.js")] + [InlineData("string-base64", "string-base64.js")] + [InlineData("string-fasta", "string-fasta.js")] + [InlineData("string-tagcloud", "string-tagcloud.js")] + [InlineData("string-unpack-code", "string-unpack-code.js")] + [InlineData("string-validate-input", "string-validate-input.js")] + public void RunScript(string name, string url) + { + var content = GetEmbeddedFile(url); + RunTest(content); + } + + private string GetEmbeddedFile(string filename) + { + const string prefix = "Jint.Tests.CommonScripts.Scripts."; + + var assembly = typeof(SunSpiderTests).GetTypeInfo().Assembly; + var scriptPath = prefix + filename; + + using (var stream = assembly.GetManifestResourceStream(scriptPath)) { - var content = new WebClient().DownloadString(url); - RunTest(content); - }, 1000000000); - - t.Start(); - t.Join(); - } - - [Theory] - [InlineData("crypto-aes", "https://raw.github.com/WebKit/webkit/master/PerformanceTests/SunSpider/tests/sunspider-1.0.1/crypto-aes.js")] - public void CryptoAES(string name, string url) - { - var content = new WebClient().DownloadString(url); - RunTest(content); - } - - [Theory] - [InlineData("crypto-md5", "https://raw.github.com/WebKit/webkit/master/PerformanceTests/SunSpider/tests/sunspider-1.0.1/crypto-md5.js")] - public void CryptoMD5(string name, string url) - { - var content = new WebClient().DownloadString(url); - RunTest(content); - } - - [InlineData("crypto-sha1", "https://raw.github.com/WebKit/webkit/master/PerformanceTests/SunSpider/tests/sunspider-1.0.1/crypto-sha1.js")] - public void CryptoSha1(string name, string url) - { - var content = new WebClient().DownloadString(url); - RunTest(content); - } - - [Theory] - [InlineData("date-format-tofte", "https://raw.github.com/WebKit/webkit/master/PerformanceTests/SunSpider/tests/sunspider-1.0.1/date-format-tofte.js")] - public void DateFormatTofte(string name, string url) - { - var content = new WebClient().DownloadString(url); - RunTest(content); - } - - [Theory] - [InlineData("date-format-xparb", "https://raw.github.com/WebKit/webkit/master/PerformanceTests/SunSpider/tests/sunspider-1.0.1/date-format-xparb.js")] - public void DateFormatXParb(string name, string url) - { - var content = new WebClient().DownloadString(url); - RunTest(content); - } - - [InlineData("math-cordic", "https://raw.github.com/WebKit/webkit/master/PerformanceTests/SunSpider/tests/sunspider-1.0.1/math-cordic.js")] - public void MathCordic(string name, string url) - { - var content = new WebClient().DownloadString(url); - RunTest(content); - } - - [Theory] - [InlineData("math-partial-sums", "https://raw.github.com/WebKit/webkit/master/PerformanceTests/SunSpider/tests/sunspider-1.0.1/math-partial-sums.js")] - public void MathPartialSums(string name, string url) - { - var content = new WebClient().DownloadString(url); - RunTest(content); - } - - [Theory] - [InlineData("math-spectral-norm", "https://raw.github.com/WebKit/webkit/master/PerformanceTests/SunSpider/tests/sunspider-1.0.1/math-spectral-norm.js")] - public void MathSpectralNorm(string name, string url) - { - var content = new WebClient().DownloadString(url); - RunTest(content); - } - - [Theory] - [InlineData("regexp-dna", "https://raw.github.com/WebKit/webkit/master/PerformanceTests/SunSpider/tests/sunspider-1.0.1/regexp-dna.js")] - public void RegexpDna(string name, string url) - { - var content = new WebClient().DownloadString(url); - RunTest(content); - } - - [Theory] - [InlineData("string-base64", "https://raw.github.com/WebKit/webkit/master/PerformanceTests/SunSpider/tests/sunspider-1.0.1/string-base64.js")] - public void StringBase64(string name, string url) - { - var content = new WebClient().DownloadString(url); - RunTest(content); - } - - [InlineData("string-fasta", "https://raw.github.com/WebKit/webkit/master/PerformanceTests/SunSpider/tests/sunspider-1.0.1/string-fasta.js")] - public void StringFasta(string name, string url) - { - var content = new WebClient().DownloadString(url); - RunTest(content); - } - - [Theory] - [InlineData("string-tagcloud", "https://raw.github.com/WebKit/webkit/master/PerformanceTests/SunSpider/tests/sunspider-1.0.1/string-tagcloud.js")] - public void StringTagCloud(string name, string url) - { - var content = new WebClient().DownloadString(url); - RunTest(content); - } - - [Theory] - [InlineData("string-unpack-code", "https://raw.github.com/WebKit/webkit/master/PerformanceTests/SunSpider/tests/sunspider-1.0.1/string-unpack-code.js")] - public void StringUnpackCode(string name, string url) - { - var content = new WebClient().DownloadString(url); - RunTest(content); + using (var sr = new StreamReader(stream)) + { + return sr.ReadToEnd(); + } + } } - [Theory] - [InlineData("string-validate-input", "https://raw.github.com/WebKit/webkit/master/PerformanceTests/SunSpider/tests/sunspider-1.0.1/string-validate-input.js")] - public void StringValidateInput(string name, string url) - { - var content = new WebClient().DownloadString(url); - RunTest(content); - } } } diff --git a/Jint.Tests.CommonScripts/packages.config b/Jint.Tests.CommonScripts/packages.config index 67a23e70da..6f1fb7f5fb 100644 --- a/Jint.Tests.CommonScripts/packages.config +++ b/Jint.Tests.CommonScripts/packages.config @@ -1,5 +1,9 @@  - - + + + + + + \ No newline at end of file diff --git a/Jint.Tests.Ecma/EcmaTest.cs b/Jint.Tests.Ecma/EcmaTest.cs index 1e99330934..641b4e49d6 100644 --- a/Jint.Tests.Ecma/EcmaTest.cs +++ b/Jint.Tests.Ecma/EcmaTest.cs @@ -14,19 +14,23 @@ public class EcmaTest public EcmaTest() { - var assemblyPath = new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath; + var assemblyPath = new Uri(typeof(EcmaTest).GetTypeInfo().Assembly.CodeBase).LocalPath; var assemblyDirectory = new FileInfo(assemblyPath).Directory; - BasePath = assemblyDirectory.Parent.Parent.FullName; - +#if NET451 + BasePath = assemblyDirectory.Parent.Parent.Parent.Parent.FullName; +#else + BasePath = assemblyDirectory.Parent.Parent.Parent.FullName; +#endif } protected void RunTestCode(string code, bool negative) { _lastError = null; - var engine = new Engine(); - + //NOTE: The Date tests in test262 assume the local timezone is Pacific Standard Time + var pacificTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"); + var engine = new Engine(cfg => cfg.LocalTimeZone(pacificTimeZone)); // loading driver @@ -45,7 +49,7 @@ protected void RunTestCode(string code, bool negative) { // exception is expected } - + } else { @@ -73,11 +77,11 @@ protected void RunTest(string sourceFilename, bool negative) { throw new ArgumentException("Could not find source file: " + fullName); } - + string code = File.ReadAllText(fullName); RunTestCode(code, negative); - + } } diff --git a/Jint.Tests.Ecma/GlobalSuppressions.cs b/Jint.Tests.Ecma/GlobalSuppressions.cs new file mode 100644 index 0000000000..73968b2e45 --- /dev/null +++ b/Jint.Tests.Ecma/GlobalSuppressions.cs @@ -0,0 +1,8 @@ + +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1004:Test methods should not be skipped", Justification = "", Scope = "module")] + diff --git a/Jint.Tests.Ecma/Jint.Tests.Ecma.csproj b/Jint.Tests.Ecma/Jint.Tests.Ecma.csproj index 5754f07f68..12c475409f 100644 --- a/Jint.Tests.Ecma/Jint.Tests.Ecma.csproj +++ b/Jint.Tests.Ecma/Jint.Tests.Ecma.csproj @@ -1,12050 +1,35 @@ - - - + + - Debug - AnyCPU - {201EB165-EE2D-45F1-AF0E-75F1CD1A20EE} - Library - Properties - Jint.Tests.Ecma + netcoreapp1.0;net451 Jint.Tests.Ecma - v4.5 - 512 - ..\ - true + Jint.Tests.Ecma + true + 1.0.4 + false + false + false + false + false + false + false + false - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - False - ..\packages\xunit.1.9.2\lib\net20\xunit.dll - - - False - ..\packages\xunit.extensions.1.9.2\lib\net20\xunit.extensions.dll - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - {a2707cfd-e37d-4b88-8fc2-238d4c1dfd01} - Jint - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - \ No newline at end of file + + diff --git a/Jint.Tests.Ecma/packages.config b/Jint.Tests.Ecma/packages.config index 67a23e70da..6f1fb7f5fb 100644 --- a/Jint.Tests.Ecma/packages.config +++ b/Jint.Tests.Ecma/packages.config @@ -1,5 +1,9 @@  - - + + + + + + \ No newline at end of file diff --git a/Jint.Tests/GlobalSuppressions.cs b/Jint.Tests/GlobalSuppressions.cs new file mode 100644 index 0000000000..0466353809 --- /dev/null +++ b/Jint.Tests/GlobalSuppressions.cs @@ -0,0 +1,13 @@ + +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Assertions", "xUnit2003:Do not use equality check to test for null value", Justification = "", Scope = "module")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Assertions", "xUnit2004:Do not use equality check to test for boolean conditions", Justification = "", Scope = "module")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1004:Test methods should not be skipped", Justification = "", Scope = "module")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Assertions", "xUnit2000:Expected value should be first", Justification = "", Scope = "module")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Assertions", "xUnit2007:Do not use typeof expression to check the type", Justification = "", Scope = "module")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1014:MemberData should use nameof operator for member name", Justification = "", Scope = "module")] + diff --git a/Jint.Tests/Jint.Tests.csproj b/Jint.Tests/Jint.Tests.csproj index 997bc88621..80b3afe99e 100644 --- a/Jint.Tests/Jint.Tests.csproj +++ b/Jint.Tests/Jint.Tests.csproj @@ -1,108 +1,34 @@ - - - + - Debug - AnyCPU - {37C7D4E0-8770-4E2A-8B6D-E53087868354} - Library - Properties - Jint.Tests + netcoreapp1.0;net451 Jint.Tests - v4.5 - 512 - ..\ - true + Jint.Tests + true + 1.0.4 + false + false + false + false + false + false + false + false - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Newtonsoft.Json.5.0.6\lib\net45\Newtonsoft.Json.dll - - - - - - - - - - False - ..\packages\xunit.1.9.2\lib\net20\xunit.dll - - - False - ..\packages\xunit.extensions.1.9.2\lib\net20\xunit.extensions.dll - - - - - - - - - - - - - - - + - + - + + + + + - - - - - - {678738da-f723-4920-b9e5-cad667104bda} - Jint - - - - - - - - - - - - - - - - + + + - - - \ No newline at end of file diff --git a/Jint.Tests/Parser/JavascriptParserTests.cs b/Jint.Tests/Parser/JavascriptParserTests.cs index 49c753a852..285d73128a 100644 --- a/Jint.Tests/Parser/JavascriptParserTests.cs +++ b/Jint.Tests/Parser/JavascriptParserTests.cs @@ -14,6 +14,22 @@ public class JavascriptParserTests { private readonly JavaScriptParser _parser = new JavaScriptParser(); + private string GetEmbeddedFile(string filename) + { + const string prefix = "Jint.Tests.Parser.Scripts."; + + var assembly = typeof(JavascriptParserTests).GetTypeInfo().Assembly; + var scriptPath = prefix + filename; + + using (var stream = assembly.GetManifestResourceStream(scriptPath)) + { + using (var sr = new StreamReader(stream)) + { + return sr.ReadToEnd(); + } + } + } + [Theory] [InlineData("jQuery.js", "1.9.1")] [InlineData("underscore.js", "1.5.2")] @@ -21,31 +37,18 @@ public class JavascriptParserTests [InlineData("mootools.js", "1.4.5")] [InlineData("angular.js", "1.2.5")] [InlineData("JSXTransformer.js", "0.10.0")] + [InlineData("handlebars.js", "2.0.0")] public void ShouldParseScriptFile(string file, string version) { - const string prefix = "Jint.Tests.Parser.Scripts."; - var assembly = Assembly.GetExecutingAssembly(); - var scriptPath = prefix + file; + var parser = new JavaScriptParser(); + var source = GetEmbeddedFile(file); var sw = new Stopwatch(); - - using (var stream = assembly.GetManifestResourceStream(scriptPath)) - { - if (stream != null) - { - using (var sr = new StreamReader(stream)) - { - var source = sr.ReadToEnd(); - sw.Restart(); - var parser = new JavaScriptParser(); - var program = parser.Parse(source); - Console.WriteLine("Parsed {0} {1} ({3} KB) in {2} ms", file, version, sw.ElapsedMilliseconds, (int)source.Length/1024); - Assert.NotNull(program); - } - } - } + var program = parser.Parse(source); + Console.WriteLine("Parsed {0} {1} ({3} KB) in {2} ms", file, version, sw.ElapsedMilliseconds, (int)source.Length/1024); + Assert.NotNull(program); } - + [Fact] public void ShouldParseThis() { @@ -53,7 +56,7 @@ public void ShouldParseThis() var body = program.Body; Assert.NotNull(body); - Assert.Equal(1, body.Count()); + Assert.Single(body); Assert.Equal(SyntaxNodes.ThisExpression, body.First().As().Expression.Type); } @@ -64,7 +67,7 @@ public void ShouldParseNull() var body = program.Body; Assert.NotNull(body); - Assert.Equal(1, body.Count()); + Assert.Single(body); Assert.Equal(SyntaxNodes.Literal, body.First().As().Expression.Type); Assert.Equal(null, body.First().As().Expression.As().Value); Assert.Equal("null", body.First().As().Expression.As().Raw); @@ -80,7 +83,7 @@ public void ShouldParseNumeric() var body = program.Body; Assert.NotNull(body); - Assert.Equal(1, body.Count()); + Assert.Single(body); Assert.Equal(SyntaxNodes.Literal, body.First().As().Expression.Type); Assert.Equal(42d, body.First().As().Expression.As().Value); Assert.Equal("42", body.First().As().Expression.As().Raw); @@ -95,7 +98,7 @@ public void ShouldParseBinaryExpression() var body = program.Body; Assert.NotNull(body); - Assert.Equal(1, body.Count()); + Assert.Single(body); Assert.NotNull(binary = body.First().As().Expression.As()); Assert.Equal(3d, binary.Right.As().Value); Assert.Equal(BinaryOperator.Times, binary.Operator); @@ -122,6 +125,8 @@ public void ShouldParseBinaryExpression() [InlineData(02, "02")] [InlineData(10, "012")] [InlineData(10, "0012")] + [InlineData(1.189008226412092e+38, "0x5973772948c653ac1971f1576e03c4d4")] + [InlineData(18446744073709552000d, "0xffffffffffffffff")] public void ShouldParseNumericLiterals(object expected, string source) { Literal literal; @@ -130,7 +135,7 @@ public void ShouldParseNumericLiterals(object expected, string source) var body = program.Body; Assert.NotNull(body); - Assert.Equal(1, body.Count()); + Assert.Single(body); Assert.NotNull(literal = body.First().As().Expression.As()); Assert.Equal(Convert.ToDouble(expected), Convert.ToDouble(literal.Value)); } @@ -150,7 +155,7 @@ public void ShouldParseStringLiterals(string expected, string source) var body = program.Body; Assert.NotNull(body); - Assert.Equal(1, body.Count()); + Assert.Single(body); Assert.NotNull(literal = body.First().As().Expression.As()); Assert.Equal(expected, literal.Value); } @@ -196,5 +201,20 @@ public void ShouldInsertSemicolons(string source) Assert.NotNull(body); } + [Fact] + public void ShouldProvideLocationForMultiLinesStringLiterals() + { + var source = @"'\ +\ +' +"; + var program = _parser.Parse(source); + var expr = program.Body.First().As().Expression; + Assert.Equal(1, expr.Location.Start.Line); + Assert.Equal(0, expr.Location.Start.Column); + Assert.Equal(3, expr.Location.End.Line); + Assert.Equal(1, expr.Location.End.Column); + } + } } diff --git a/Jint.Tests/Parser/Scripts/handlebars.js b/Jint.Tests/Parser/Scripts/handlebars.js new file mode 100644 index 0000000000..f826bbfd38 --- /dev/null +++ b/Jint.Tests/Parser/Scripts/handlebars.js @@ -0,0 +1,3079 @@ +/*! + + handlebars v2.0.0 + +Copyright (C) 2011-2014 by Yehuda Katz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +@license +*/ +/* exported Handlebars */ +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + define([], factory); + } else if (typeof exports === 'object') { + module.exports = factory(); + } else { + root.Handlebars = root.Handlebars || factory(); + } +}(this, function () { +// handlebars/safe-string.js +var __module4__ = (function() { + "use strict"; + var __exports__; + // Build out our basic SafeString type + function SafeString(string) { + this.string = string; + } + + SafeString.prototype.toString = function() { + return "" + this.string; + }; + + __exports__ = SafeString; + return __exports__; +})(); + +// handlebars/utils.js +var __module3__ = (function(__dependency1__) { + "use strict"; + var __exports__ = {}; + /*jshint -W004 */ + var SafeString = __dependency1__; + + var escape = { + "&": "&", + "<": "<", + ">": ">", + '"': """, + "'": "'", + "`": "`" + }; + + var badChars = /[&<>"'`]/g; + var possible = /[&<>"'`]/; + + function escapeChar(chr) { + return escape[chr]; + } + + function extend(obj /* , ...source */) { + for (var i = 1; i < arguments.length; i++) { + for (var key in arguments[i]) { + if (Object.prototype.hasOwnProperty.call(arguments[i], key)) { + obj[key] = arguments[i][key]; + } + } + } + + return obj; + } + + __exports__.extend = extend;var toString = Object.prototype.toString; + __exports__.toString = toString; + // Sourced from lodash + // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt + var isFunction = function(value) { + return typeof value === 'function'; + }; + // fallback for older versions of Chrome and Safari + /* istanbul ignore next */ + if (isFunction(/x/)) { + isFunction = function(value) { + return typeof value === 'function' && toString.call(value) === '[object Function]'; + }; + } + var isFunction; + __exports__.isFunction = isFunction; + /* istanbul ignore next */ + var isArray = Array.isArray || function(value) { + return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false; + }; + __exports__.isArray = isArray; + + function escapeExpression(string) { + // don't escape SafeStrings, since they're already safe + if (string instanceof SafeString) { + return string.toString(); + } else if (string == null) { + return ""; + } else if (!string) { + return string + ''; + } + + // Force a string conversion as this will be done by the append regardless and + // the regex test will do this transparently behind the scenes, causing issues if + // an object's to string has escaped characters in it. + string = "" + string; + + if(!possible.test(string)) { return string; } + return string.replace(badChars, escapeChar); + } + + __exports__.escapeExpression = escapeExpression;function isEmpty(value) { + if (!value && value !== 0) { + return true; + } else if (isArray(value) && value.length === 0) { + return true; + } else { + return false; + } + } + + __exports__.isEmpty = isEmpty;function appendContextPath(contextPath, id) { + return (contextPath ? contextPath + '.' : '') + id; + } + + __exports__.appendContextPath = appendContextPath; + return __exports__; +})(__module4__); + +// handlebars/exception.js +var __module5__ = (function() { + "use strict"; + var __exports__; + + var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack']; + + function Exception(message, node) { + var line; + if (node && node.firstLine) { + line = node.firstLine; + + message += ' - ' + line + ':' + node.firstColumn; + } + + var tmp = Error.prototype.constructor.call(this, message); + + // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work. + for (var idx = 0; idx < errorProps.length; idx++) { + this[errorProps[idx]] = tmp[errorProps[idx]]; + } + + if (line) { + this.lineNumber = line; + this.column = node.firstColumn; + } + } + + Exception.prototype = new Error(); + + __exports__ = Exception; + return __exports__; +})(); + +// handlebars/base.js +var __module2__ = (function(__dependency1__, __dependency2__) { + "use strict"; + var __exports__ = {}; + var Utils = __dependency1__; + var Exception = __dependency2__; + + var VERSION = "2.0.0"; + __exports__.VERSION = VERSION;var COMPILER_REVISION = 6; + __exports__.COMPILER_REVISION = COMPILER_REVISION; + var REVISION_CHANGES = { + 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it + 2: '== 1.0.0-rc.3', + 3: '== 1.0.0-rc.4', + 4: '== 1.x.x', + 5: '== 2.0.0-alpha.x', + 6: '>= 2.0.0-beta.1' + }; + __exports__.REVISION_CHANGES = REVISION_CHANGES; + var isArray = Utils.isArray, + isFunction = Utils.isFunction, + toString = Utils.toString, + objectType = '[object Object]'; + + function HandlebarsEnvironment(helpers, partials) { + this.helpers = helpers || {}; + this.partials = partials || {}; + + registerDefaultHelpers(this); + } + + __exports__.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = { + constructor: HandlebarsEnvironment, + + logger: logger, + log: log, + + registerHelper: function(name, fn) { + if (toString.call(name) === objectType) { + if (fn) { throw new Exception('Arg not supported with multiple helpers'); } + Utils.extend(this.helpers, name); + } else { + this.helpers[name] = fn; + } + }, + unregisterHelper: function(name) { + delete this.helpers[name]; + }, + + registerPartial: function(name, partial) { + if (toString.call(name) === objectType) { + Utils.extend(this.partials, name); + } else { + this.partials[name] = partial; + } + }, + unregisterPartial: function(name) { + delete this.partials[name]; + } + }; + + function registerDefaultHelpers(instance) { + instance.registerHelper('helperMissing', function(/* [args, ]options */) { + if(arguments.length === 1) { + // A missing field in a {{foo}} constuct. + return undefined; + } else { + // Someone is actually trying to call something, blow up. + throw new Exception("Missing helper: '" + arguments[arguments.length-1].name + "'"); + } + }); + + instance.registerHelper('blockHelperMissing', function(context, options) { + var inverse = options.inverse, + fn = options.fn; + + if(context === true) { + return fn(this); + } else if(context === false || context == null) { + return inverse(this); + } else if (isArray(context)) { + if(context.length > 0) { + if (options.ids) { + options.ids = [options.name]; + } + + return instance.helpers.each(context, options); + } else { + return inverse(this); + } + } else { + if (options.data && options.ids) { + var data = createFrame(options.data); + data.contextPath = Utils.appendContextPath(options.data.contextPath, options.name); + options = {data: data}; + } + + return fn(context, options); + } + }); + + instance.registerHelper('each', function(context, options) { + if (!options) { + throw new Exception('Must pass iterator to #each'); + } + + var fn = options.fn, inverse = options.inverse; + var i = 0, ret = "", data; + + var contextPath; + if (options.data && options.ids) { + contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.'; + } + + if (isFunction(context)) { context = context.call(this); } + + if (options.data) { + data = createFrame(options.data); + } + + if(context && typeof context === 'object') { + if (isArray(context)) { + for(var j = context.length; i 0) { + throw new Exception("Invalid path: " + original, this); + } else if (part === "..") { + depth++; + depthString += '../'; + } else { + this.isScoped = true; + } + } else { + dig.push(part); + } + } + + this.original = original; + this.parts = dig; + this.string = dig.join('.'); + this.depth = depth; + this.idName = depthString + this.string; + + // an ID is simple if it only has one part, and that part is not + // `..` or `this`. + this.isSimple = parts.length === 1 && !this.isScoped && depth === 0; + + this.stringModeValue = this.string; + }, + + PartialNameNode: function(name, locInfo) { + LocationInfo.call(this, locInfo); + this.type = "PARTIAL_NAME"; + this.name = name.original; + }, + + DataNode: function(id, locInfo) { + LocationInfo.call(this, locInfo); + this.type = "DATA"; + this.id = id; + this.stringModeValue = id.stringModeValue; + this.idName = '@' + id.stringModeValue; + }, + + StringNode: function(string, locInfo) { + LocationInfo.call(this, locInfo); + this.type = "STRING"; + this.original = + this.string = + this.stringModeValue = string; + }, + + NumberNode: function(number, locInfo) { + LocationInfo.call(this, locInfo); + this.type = "NUMBER"; + this.original = + this.number = number; + this.stringModeValue = Number(number); + }, + + BooleanNode: function(bool, locInfo) { + LocationInfo.call(this, locInfo); + this.type = "BOOLEAN"; + this.bool = bool; + this.stringModeValue = bool === "true"; + }, + + CommentNode: function(comment, locInfo) { + LocationInfo.call(this, locInfo); + this.type = "comment"; + this.comment = comment; + + this.strip = { + inlineStandalone: true + }; + } + }; + + + // Must be exported as an object rather than the root of the module as the jison lexer + // most modify the object to operate properly. + __exports__ = AST; + return __exports__; +})(__module5__); + +// handlebars/compiler/parser.js +var __module9__ = (function() { + "use strict"; + var __exports__; + /* jshint ignore:start */ + /* istanbul ignore next */ + /* Jison generated parser */ + var handlebars = (function(){ + var parser = {trace: function trace() { }, + yy: {}, + symbols_: {"error":2,"root":3,"program":4,"EOF":5,"program_repetition0":6,"statement":7,"mustache":8,"block":9,"rawBlock":10,"partial":11,"CONTENT":12,"COMMENT":13,"openRawBlock":14,"END_RAW_BLOCK":15,"OPEN_RAW_BLOCK":16,"sexpr":17,"CLOSE_RAW_BLOCK":18,"openBlock":19,"block_option0":20,"closeBlock":21,"openInverse":22,"block_option1":23,"OPEN_BLOCK":24,"CLOSE":25,"OPEN_INVERSE":26,"inverseAndProgram":27,"INVERSE":28,"OPEN_ENDBLOCK":29,"path":30,"OPEN":31,"OPEN_UNESCAPED":32,"CLOSE_UNESCAPED":33,"OPEN_PARTIAL":34,"partialName":35,"param":36,"partial_option0":37,"partial_option1":38,"sexpr_repetition0":39,"sexpr_option0":40,"dataName":41,"STRING":42,"NUMBER":43,"BOOLEAN":44,"OPEN_SEXPR":45,"CLOSE_SEXPR":46,"hash":47,"hash_repetition_plus0":48,"hashSegment":49,"ID":50,"EQUALS":51,"DATA":52,"pathSegments":53,"SEP":54,"$accept":0,"$end":1}, + terminals_: {2:"error",5:"EOF",12:"CONTENT",13:"COMMENT",15:"END_RAW_BLOCK",16:"OPEN_RAW_BLOCK",18:"CLOSE_RAW_BLOCK",24:"OPEN_BLOCK",25:"CLOSE",26:"OPEN_INVERSE",28:"INVERSE",29:"OPEN_ENDBLOCK",31:"OPEN",32:"OPEN_UNESCAPED",33:"CLOSE_UNESCAPED",34:"OPEN_PARTIAL",42:"STRING",43:"NUMBER",44:"BOOLEAN",45:"OPEN_SEXPR",46:"CLOSE_SEXPR",50:"ID",51:"EQUALS",52:"DATA",54:"SEP"}, + productions_: [0,[3,2],[4,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[10,3],[14,3],[9,4],[9,4],[19,3],[22,3],[27,2],[21,3],[8,3],[8,3],[11,5],[11,4],[17,3],[17,1],[36,1],[36,1],[36,1],[36,1],[36,1],[36,3],[47,1],[49,3],[35,1],[35,1],[35,1],[41,2],[30,1],[53,3],[53,1],[6,0],[6,2],[20,0],[20,1],[23,0],[23,1],[37,0],[37,1],[38,0],[38,1],[39,0],[39,2],[40,0],[40,1],[48,1],[48,2]], + performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) { + + var $0 = $$.length - 1; + switch (yystate) { + case 1: yy.prepareProgram($$[$0-1].statements, true); return $$[$0-1]; + break; + case 2:this.$ = new yy.ProgramNode(yy.prepareProgram($$[$0]), {}, this._$); + break; + case 3:this.$ = $$[$0]; + break; + case 4:this.$ = $$[$0]; + break; + case 5:this.$ = $$[$0]; + break; + case 6:this.$ = $$[$0]; + break; + case 7:this.$ = new yy.ContentNode($$[$0], this._$); + break; + case 8:this.$ = new yy.CommentNode($$[$0], this._$); + break; + case 9:this.$ = new yy.RawBlockNode($$[$0-2], $$[$0-1], $$[$0], this._$); + break; + case 10:this.$ = new yy.MustacheNode($$[$0-1], null, '', '', this._$); + break; + case 11:this.$ = yy.prepareBlock($$[$0-3], $$[$0-2], $$[$0-1], $$[$0], false, this._$); + break; + case 12:this.$ = yy.prepareBlock($$[$0-3], $$[$0-2], $$[$0-1], $$[$0], true, this._$); + break; + case 13:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$); + break; + case 14:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$); + break; + case 15:this.$ = { strip: yy.stripFlags($$[$0-1], $$[$0-1]), program: $$[$0] }; + break; + case 16:this.$ = {path: $$[$0-1], strip: yy.stripFlags($$[$0-2], $$[$0])}; + break; + case 17:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$); + break; + case 18:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$); + break; + case 19:this.$ = new yy.PartialNode($$[$0-3], $$[$0-2], $$[$0-1], yy.stripFlags($$[$0-4], $$[$0]), this._$); + break; + case 20:this.$ = new yy.PartialNode($$[$0-2], undefined, $$[$0-1], yy.stripFlags($$[$0-3], $$[$0]), this._$); + break; + case 21:this.$ = new yy.SexprNode([$$[$0-2]].concat($$[$0-1]), $$[$0], this._$); + break; + case 22:this.$ = new yy.SexprNode([$$[$0]], null, this._$); + break; + case 23:this.$ = $$[$0]; + break; + case 24:this.$ = new yy.StringNode($$[$0], this._$); + break; + case 25:this.$ = new yy.NumberNode($$[$0], this._$); + break; + case 26:this.$ = new yy.BooleanNode($$[$0], this._$); + break; + case 27:this.$ = $$[$0]; + break; + case 28:$$[$0-1].isHelper = true; this.$ = $$[$0-1]; + break; + case 29:this.$ = new yy.HashNode($$[$0], this._$); + break; + case 30:this.$ = [$$[$0-2], $$[$0]]; + break; + case 31:this.$ = new yy.PartialNameNode($$[$0], this._$); + break; + case 32:this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0], this._$), this._$); + break; + case 33:this.$ = new yy.PartialNameNode(new yy.NumberNode($$[$0], this._$)); + break; + case 34:this.$ = new yy.DataNode($$[$0], this._$); + break; + case 35:this.$ = new yy.IdNode($$[$0], this._$); + break; + case 36: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2]; + break; + case 37:this.$ = [{part: $$[$0]}]; + break; + case 38:this.$ = []; + break; + case 39:$$[$0-1].push($$[$0]); + break; + case 48:this.$ = []; + break; + case 49:$$[$0-1].push($$[$0]); + break; + case 52:this.$ = [$$[$0]]; + break; + case 53:$$[$0-1].push($$[$0]); + break; + } + }, + table: [{3:1,4:2,5:[2,38],6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],31:[2,38],32:[2,38],34:[2,38]},{1:[3]},{5:[1,4]},{5:[2,2],7:5,8:6,9:7,10:8,11:9,12:[1,10],13:[1,11],14:16,16:[1,20],19:14,22:15,24:[1,18],26:[1,19],28:[2,2],29:[2,2],31:[1,12],32:[1,13],34:[1,17]},{1:[2,1]},{5:[2,39],12:[2,39],13:[2,39],16:[2,39],24:[2,39],26:[2,39],28:[2,39],29:[2,39],31:[2,39],32:[2,39],34:[2,39]},{5:[2,3],12:[2,3],13:[2,3],16:[2,3],24:[2,3],26:[2,3],28:[2,3],29:[2,3],31:[2,3],32:[2,3],34:[2,3]},{5:[2,4],12:[2,4],13:[2,4],16:[2,4],24:[2,4],26:[2,4],28:[2,4],29:[2,4],31:[2,4],32:[2,4],34:[2,4]},{5:[2,5],12:[2,5],13:[2,5],16:[2,5],24:[2,5],26:[2,5],28:[2,5],29:[2,5],31:[2,5],32:[2,5],34:[2,5]},{5:[2,6],12:[2,6],13:[2,6],16:[2,6],24:[2,6],26:[2,6],28:[2,6],29:[2,6],31:[2,6],32:[2,6],34:[2,6]},{5:[2,7],12:[2,7],13:[2,7],16:[2,7],24:[2,7],26:[2,7],28:[2,7],29:[2,7],31:[2,7],32:[2,7],34:[2,7]},{5:[2,8],12:[2,8],13:[2,8],16:[2,8],24:[2,8],26:[2,8],28:[2,8],29:[2,8],31:[2,8],32:[2,8],34:[2,8]},{17:21,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:27,30:22,41:23,50:[1,26],52:[1,25],53:24},{4:28,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],28:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{4:29,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],28:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{12:[1,30]},{30:32,35:31,42:[1,33],43:[1,34],50:[1,26],53:24},{17:35,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:36,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:37,30:22,41:23,50:[1,26],52:[1,25],53:24},{25:[1,38]},{18:[2,48],25:[2,48],33:[2,48],39:39,42:[2,48],43:[2,48],44:[2,48],45:[2,48],46:[2,48],50:[2,48],52:[2,48]},{18:[2,22],25:[2,22],33:[2,22],46:[2,22]},{18:[2,35],25:[2,35],33:[2,35],42:[2,35],43:[2,35],44:[2,35],45:[2,35],46:[2,35],50:[2,35],52:[2,35],54:[1,40]},{30:41,50:[1,26],53:24},{18:[2,37],25:[2,37],33:[2,37],42:[2,37],43:[2,37],44:[2,37],45:[2,37],46:[2,37],50:[2,37],52:[2,37],54:[2,37]},{33:[1,42]},{20:43,27:44,28:[1,45],29:[2,40]},{23:46,27:47,28:[1,45],29:[2,42]},{15:[1,48]},{25:[2,46],30:51,36:49,38:50,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],47:57,48:58,49:60,50:[1,59],52:[1,25],53:24},{25:[2,31],42:[2,31],43:[2,31],44:[2,31],45:[2,31],50:[2,31],52:[2,31]},{25:[2,32],42:[2,32],43:[2,32],44:[2,32],45:[2,32],50:[2,32],52:[2,32]},{25:[2,33],42:[2,33],43:[2,33],44:[2,33],45:[2,33],50:[2,33],52:[2,33]},{25:[1,61]},{25:[1,62]},{18:[1,63]},{5:[2,17],12:[2,17],13:[2,17],16:[2,17],24:[2,17],26:[2,17],28:[2,17],29:[2,17],31:[2,17],32:[2,17],34:[2,17]},{18:[2,50],25:[2,50],30:51,33:[2,50],36:65,40:64,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],46:[2,50],47:66,48:58,49:60,50:[1,59],52:[1,25],53:24},{50:[1,67]},{18:[2,34],25:[2,34],33:[2,34],42:[2,34],43:[2,34],44:[2,34],45:[2,34],46:[2,34],50:[2,34],52:[2,34]},{5:[2,18],12:[2,18],13:[2,18],16:[2,18],24:[2,18],26:[2,18],28:[2,18],29:[2,18],31:[2,18],32:[2,18],34:[2,18]},{21:68,29:[1,69]},{29:[2,41]},{4:70,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{21:71,29:[1,69]},{29:[2,43]},{5:[2,9],12:[2,9],13:[2,9],16:[2,9],24:[2,9],26:[2,9],28:[2,9],29:[2,9],31:[2,9],32:[2,9],34:[2,9]},{25:[2,44],37:72,47:73,48:58,49:60,50:[1,74]},{25:[1,75]},{18:[2,23],25:[2,23],33:[2,23],42:[2,23],43:[2,23],44:[2,23],45:[2,23],46:[2,23],50:[2,23],52:[2,23]},{18:[2,24],25:[2,24],33:[2,24],42:[2,24],43:[2,24],44:[2,24],45:[2,24],46:[2,24],50:[2,24],52:[2,24]},{18:[2,25],25:[2,25],33:[2,25],42:[2,25],43:[2,25],44:[2,25],45:[2,25],46:[2,25],50:[2,25],52:[2,25]},{18:[2,26],25:[2,26],33:[2,26],42:[2,26],43:[2,26],44:[2,26],45:[2,26],46:[2,26],50:[2,26],52:[2,26]},{18:[2,27],25:[2,27],33:[2,27],42:[2,27],43:[2,27],44:[2,27],45:[2,27],46:[2,27],50:[2,27],52:[2,27]},{17:76,30:22,41:23,50:[1,26],52:[1,25],53:24},{25:[2,47]},{18:[2,29],25:[2,29],33:[2,29],46:[2,29],49:77,50:[1,74]},{18:[2,37],25:[2,37],33:[2,37],42:[2,37],43:[2,37],44:[2,37],45:[2,37],46:[2,37],50:[2,37],51:[1,78],52:[2,37],54:[2,37]},{18:[2,52],25:[2,52],33:[2,52],46:[2,52],50:[2,52]},{12:[2,13],13:[2,13],16:[2,13],24:[2,13],26:[2,13],28:[2,13],29:[2,13],31:[2,13],32:[2,13],34:[2,13]},{12:[2,14],13:[2,14],16:[2,14],24:[2,14],26:[2,14],28:[2,14],29:[2,14],31:[2,14],32:[2,14],34:[2,14]},{12:[2,10]},{18:[2,21],25:[2,21],33:[2,21],46:[2,21]},{18:[2,49],25:[2,49],33:[2,49],42:[2,49],43:[2,49],44:[2,49],45:[2,49],46:[2,49],50:[2,49],52:[2,49]},{18:[2,51],25:[2,51],33:[2,51],46:[2,51]},{18:[2,36],25:[2,36],33:[2,36],42:[2,36],43:[2,36],44:[2,36],45:[2,36],46:[2,36],50:[2,36],52:[2,36],54:[2,36]},{5:[2,11],12:[2,11],13:[2,11],16:[2,11],24:[2,11],26:[2,11],28:[2,11],29:[2,11],31:[2,11],32:[2,11],34:[2,11]},{30:79,50:[1,26],53:24},{29:[2,15]},{5:[2,12],12:[2,12],13:[2,12],16:[2,12],24:[2,12],26:[2,12],28:[2,12],29:[2,12],31:[2,12],32:[2,12],34:[2,12]},{25:[1,80]},{25:[2,45]},{51:[1,78]},{5:[2,20],12:[2,20],13:[2,20],16:[2,20],24:[2,20],26:[2,20],28:[2,20],29:[2,20],31:[2,20],32:[2,20],34:[2,20]},{46:[1,81]},{18:[2,53],25:[2,53],33:[2,53],46:[2,53],50:[2,53]},{30:51,36:82,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],50:[1,26],52:[1,25],53:24},{25:[1,83]},{5:[2,19],12:[2,19],13:[2,19],16:[2,19],24:[2,19],26:[2,19],28:[2,19],29:[2,19],31:[2,19],32:[2,19],34:[2,19]},{18:[2,28],25:[2,28],33:[2,28],42:[2,28],43:[2,28],44:[2,28],45:[2,28],46:[2,28],50:[2,28],52:[2,28]},{18:[2,30],25:[2,30],33:[2,30],46:[2,30],50:[2,30]},{5:[2,16],12:[2,16],13:[2,16],16:[2,16],24:[2,16],26:[2,16],28:[2,16],29:[2,16],31:[2,16],32:[2,16],34:[2,16]}], + defaultActions: {4:[2,1],44:[2,41],47:[2,43],57:[2,47],63:[2,10],70:[2,15],73:[2,45]}, + parseError: function parseError(str, hash) { + throw new Error(str); + }, + parse: function parse(input) { + var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1; + this.lexer.setInput(input); + this.lexer.yy = this.yy; + this.yy.lexer = this.lexer; + this.yy.parser = this; + if (typeof this.lexer.yylloc == "undefined") + this.lexer.yylloc = {}; + var yyloc = this.lexer.yylloc; + lstack.push(yyloc); + var ranges = this.lexer.options && this.lexer.options.ranges; + if (typeof this.yy.parseError === "function") + this.parseError = this.yy.parseError; + function popStack(n) { + stack.length = stack.length - 2 * n; + vstack.length = vstack.length - n; + lstack.length = lstack.length - n; + } + function lex() { + var token; + token = self.lexer.lex() || 1; + if (typeof token !== "number") { + token = self.symbols_[token] || token; + } + return token; + } + var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + if (!recovering) { + expected = []; + for (p in table[state]) + if (this.terminals_[p] && p > 2) { + expected.push("'" + this.terminals_[p] + "'"); + } + if (this.lexer.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected}); + } + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(this.lexer.yytext); + lstack.push(this.lexer.yylloc); + stack.push(action[1]); + symbol = null; + if (!preErrorSymbol) { + yyleng = this.lexer.yyleng; + yytext = this.lexer.yytext; + yylineno = this.lexer.yylineno; + yyloc = this.lexer.yylloc; + if (recovering > 0) + recovering--; + } else { + symbol = preErrorSymbol; + preErrorSymbol = null; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column}; + if (ranges) { + yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]]; + } + r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + /* Jison generated lexer */ + var lexer = (function(){ + var lexer = ({EOF:1, + parseError:function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + setInput:function (input) { + this._input = input; + this._more = this._less = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ''; + this.conditionStack = ['INITIAL']; + this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0}; + if (this.options.ranges) this.yylloc.range = [0,0]; + this.offset = 0; + return this; + }, + input:function () { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) this.yylloc.range[1]++; + + this._input = this._input.slice(1); + return ch; + }, + unput:function (ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length-len-1); + //this.yyleng -= len; + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length-1); + this.matched = this.matched.substr(0, this.matched.length-1); + + if (lines.length-1) this.yylineno -= lines.length-1; + var r = this.yylloc.range; + + this.yylloc = {first_line: this.yylloc.first_line, + last_line: this.yylineno+1, + first_column: this.yylloc.first_column, + last_column: lines ? + (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length: + this.yylloc.first_column - len + }; + + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + return this; + }, + more:function () { + this._more = true; + return this; + }, + less:function (n) { + this.unput(this.match.slice(n)); + }, + pastInput:function () { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, ""); + }, + upcomingInput:function () { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20-next.length); + } + return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, ""); + }, + showPosition:function () { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c+"^"; + }, + next:function () { + if (this.done) { + return this.EOF; + } + if (!this._input) this.done = true; + + var token, + match, + tempMatch, + index, + col, + lines; + if (!this._more) { + this.yytext = ''; + this.match = ''; + } + var rules = this._currentRules(); + for (var i=0;i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (!this.options.flex) break; + } + } + if (match) { + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) this.yylineno += lines.length; + this.yylloc = {first_line: this.yylloc.last_line, + last_line: this.yylineno+1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length}; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]); + if (this.done && this._input) this.done = false; + if (token) return token; + else return; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(), + {text: "", token: null, line: this.yylineno}); + } + }, + lex:function lex() { + var r = this.next(); + if (typeof r !== 'undefined') { + return r; + } else { + return this.lex(); + } + }, + begin:function begin(condition) { + this.conditionStack.push(condition); + }, + popState:function popState() { + return this.conditionStack.pop(); + }, + _currentRules:function _currentRules() { + return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules; + }, + topState:function () { + return this.conditionStack[this.conditionStack.length-2]; + }, + pushState:function begin(condition) { + this.begin(condition); + }}); + lexer.options = {}; + lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) { + + + function strip(start, end) { + return yy_.yytext = yy_.yytext.substr(start, yy_.yyleng-end); + } + + + var YYSTATE=YY_START + switch($avoiding_name_collisions) { + case 0: + if(yy_.yytext.slice(-2) === "\\\\") { + strip(0,1); + this.begin("mu"); + } else if(yy_.yytext.slice(-1) === "\\") { + strip(0,1); + this.begin("emu"); + } else { + this.begin("mu"); + } + if(yy_.yytext) return 12; + + break; + case 1:return 12; + break; + case 2: + this.popState(); + return 12; + + break; + case 3: + yy_.yytext = yy_.yytext.substr(5, yy_.yyleng-9); + this.popState(); + return 15; + + break; + case 4: return 12; + break; + case 5:strip(0,4); this.popState(); return 13; + break; + case 6:return 45; + break; + case 7:return 46; + break; + case 8: return 16; + break; + case 9: + this.popState(); + this.begin('raw'); + return 18; + + break; + case 10:return 34; + break; + case 11:return 24; + break; + case 12:return 29; + break; + case 13:this.popState(); return 28; + break; + case 14:this.popState(); return 28; + break; + case 15:return 26; + break; + case 16:return 26; + break; + case 17:return 32; + break; + case 18:return 31; + break; + case 19:this.popState(); this.begin('com'); + break; + case 20:strip(3,5); this.popState(); return 13; + break; + case 21:return 31; + break; + case 22:return 51; + break; + case 23:return 50; + break; + case 24:return 50; + break; + case 25:return 54; + break; + case 26:// ignore whitespace + break; + case 27:this.popState(); return 33; + break; + case 28:this.popState(); return 25; + break; + case 29:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 42; + break; + case 30:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 42; + break; + case 31:return 52; + break; + case 32:return 44; + break; + case 33:return 44; + break; + case 34:return 43; + break; + case 35:return 50; + break; + case 36:yy_.yytext = strip(1,2); return 50; + break; + case 37:return 'INVALID'; + break; + case 38:return 5; + break; + } + }; + lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/,/^(?:[^\x00]*?(?=(\{\{\{\{\/)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{\{\{)/,/^(?:\}\}\}\})/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^\s*(~)?\}\})/,/^(?:\{\{(~)?\s*else\s*(~)?\}\})/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/]; + lexer.conditions = {"mu":{"rules":[6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[5],"inclusive":false},"raw":{"rules":[3,4],"inclusive":false},"INITIAL":{"rules":[0,1,38],"inclusive":true}}; + return lexer;})() + parser.lexer = lexer; + function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser; + return new Parser; + })();__exports__ = handlebars; + /* jshint ignore:end */ + return __exports__; +})(); + +// handlebars/compiler/helpers.js +var __module10__ = (function(__dependency1__) { + "use strict"; + var __exports__ = {}; + var Exception = __dependency1__; + + function stripFlags(open, close) { + return { + left: open.charAt(2) === '~', + right: close.charAt(close.length-3) === '~' + }; + } + + __exports__.stripFlags = stripFlags; + function prepareBlock(mustache, program, inverseAndProgram, close, inverted, locInfo) { + /*jshint -W040 */ + if (mustache.sexpr.id.original !== close.path.original) { + throw new Exception(mustache.sexpr.id.original + ' doesn\'t match ' + close.path.original, mustache); + } + + var inverse = inverseAndProgram && inverseAndProgram.program; + + var strip = { + left: mustache.strip.left, + right: close.strip.right, + + // Determine the standalone candiacy. Basically flag our content as being possibly standalone + // so our parent can determine if we actually are standalone + openStandalone: isNextWhitespace(program.statements), + closeStandalone: isPrevWhitespace((inverse || program).statements) + }; + + if (mustache.strip.right) { + omitRight(program.statements, null, true); + } + + if (inverse) { + var inverseStrip = inverseAndProgram.strip; + + if (inverseStrip.left) { + omitLeft(program.statements, null, true); + } + if (inverseStrip.right) { + omitRight(inverse.statements, null, true); + } + if (close.strip.left) { + omitLeft(inverse.statements, null, true); + } + + // Find standalone else statments + if (isPrevWhitespace(program.statements) + && isNextWhitespace(inverse.statements)) { + + omitLeft(program.statements); + omitRight(inverse.statements); + } + } else { + if (close.strip.left) { + omitLeft(program.statements, null, true); + } + } + + if (inverted) { + return new this.BlockNode(mustache, inverse, program, strip, locInfo); + } else { + return new this.BlockNode(mustache, program, inverse, strip, locInfo); + } + } + + __exports__.prepareBlock = prepareBlock; + function prepareProgram(statements, isRoot) { + for (var i = 0, l = statements.length; i < l; i++) { + var current = statements[i], + strip = current.strip; + + if (!strip) { + continue; + } + + var _isPrevWhitespace = isPrevWhitespace(statements, i, isRoot, current.type === 'partial'), + _isNextWhitespace = isNextWhitespace(statements, i, isRoot), + + openStandalone = strip.openStandalone && _isPrevWhitespace, + closeStandalone = strip.closeStandalone && _isNextWhitespace, + inlineStandalone = strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace; + + if (strip.right) { + omitRight(statements, i, true); + } + if (strip.left) { + omitLeft(statements, i, true); + } + + if (inlineStandalone) { + omitRight(statements, i); + + if (omitLeft(statements, i)) { + // If we are on a standalone node, save the indent info for partials + if (current.type === 'partial') { + current.indent = (/([ \t]+$)/).exec(statements[i-1].original) ? RegExp.$1 : ''; + } + } + } + if (openStandalone) { + omitRight((current.program || current.inverse).statements); + + // Strip out the previous content node if it's whitespace only + omitLeft(statements, i); + } + if (closeStandalone) { + // Always strip the next node + omitRight(statements, i); + + omitLeft((current.inverse || current.program).statements); + } + } + + return statements; + } + + __exports__.prepareProgram = prepareProgram;function isPrevWhitespace(statements, i, isRoot) { + if (i === undefined) { + i = statements.length; + } + + // Nodes that end with newlines are considered whitespace (but are special + // cased for strip operations) + var prev = statements[i-1], + sibling = statements[i-2]; + if (!prev) { + return isRoot; + } + + if (prev.type === 'content') { + return (sibling || !isRoot ? (/\r?\n\s*?$/) : (/(^|\r?\n)\s*?$/)).test(prev.original); + } + } + function isNextWhitespace(statements, i, isRoot) { + if (i === undefined) { + i = -1; + } + + var next = statements[i+1], + sibling = statements[i+2]; + if (!next) { + return isRoot; + } + + if (next.type === 'content') { + return (sibling || !isRoot ? (/^\s*?\r?\n/) : (/^\s*?(\r?\n|$)/)).test(next.original); + } + } + + // Marks the node to the right of the position as omitted. + // I.e. {{foo}}' ' will mark the ' ' node as omitted. + // + // If i is undefined, then the first child will be marked as such. + // + // If mulitple is truthy then all whitespace will be stripped out until non-whitespace + // content is met. + function omitRight(statements, i, multiple) { + var current = statements[i == null ? 0 : i + 1]; + if (!current || current.type !== 'content' || (!multiple && current.rightStripped)) { + return; + } + + var original = current.string; + current.string = current.string.replace(multiple ? (/^\s+/) : (/^[ \t]*\r?\n?/), ''); + current.rightStripped = current.string !== original; + } + + // Marks the node to the left of the position as omitted. + // I.e. ' '{{foo}} will mark the ' ' node as omitted. + // + // If i is undefined then the last child will be marked as such. + // + // If mulitple is truthy then all whitespace will be stripped out until non-whitespace + // content is met. + function omitLeft(statements, i, multiple) { + var current = statements[i == null ? statements.length - 1 : i - 1]; + if (!current || current.type !== 'content' || (!multiple && current.leftStripped)) { + return; + } + + // We omit the last node if it's whitespace only and not preceeded by a non-content node. + var original = current.string; + current.string = current.string.replace(multiple ? (/\s+$/) : (/[ \t]+$/), ''); + current.leftStripped = current.string !== original; + return current.leftStripped; + } + return __exports__; +})(__module5__); + +// handlebars/compiler/base.js +var __module8__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__) { + "use strict"; + var __exports__ = {}; + var parser = __dependency1__; + var AST = __dependency2__; + var Helpers = __dependency3__; + var extend = __dependency4__.extend; + + __exports__.parser = parser; + + var yy = {}; + extend(yy, Helpers, AST); + + function parse(input) { + // Just return if an already-compile AST was passed in. + if (input.constructor === AST.ProgramNode) { return input; } + + parser.yy = yy; + + return parser.parse(input); + } + + __exports__.parse = parse; + return __exports__; +})(__module9__, __module7__, __module10__, __module3__); + +// handlebars/compiler/compiler.js +var __module11__ = (function(__dependency1__, __dependency2__) { + "use strict"; + var __exports__ = {}; + var Exception = __dependency1__; + var isArray = __dependency2__.isArray; + + var slice = [].slice; + + function Compiler() {} + + __exports__.Compiler = Compiler;// the foundHelper register will disambiguate helper lookup from finding a + // function in a context. This is necessary for mustache compatibility, which + // requires that context functions in blocks are evaluated by blockHelperMissing, + // and then proceed as if the resulting value was provided to blockHelperMissing. + + Compiler.prototype = { + compiler: Compiler, + + equals: function(other) { + var len = this.opcodes.length; + if (other.opcodes.length !== len) { + return false; + } + + for (var i = 0; i < len; i++) { + var opcode = this.opcodes[i], + otherOpcode = other.opcodes[i]; + if (opcode.opcode !== otherOpcode.opcode || !argEquals(opcode.args, otherOpcode.args)) { + return false; + } + } + + // We know that length is the same between the two arrays because they are directly tied + // to the opcode behavior above. + len = this.children.length; + for (i = 0; i < len; i++) { + if (!this.children[i].equals(other.children[i])) { + return false; + } + } + + return true; + }, + + guid: 0, + + compile: function(program, options) { + this.opcodes = []; + this.children = []; + this.depths = {list: []}; + this.options = options; + this.stringParams = options.stringParams; + this.trackIds = options.trackIds; + + // These changes will propagate to the other compiler components + var knownHelpers = this.options.knownHelpers; + this.options.knownHelpers = { + 'helperMissing': true, + 'blockHelperMissing': true, + 'each': true, + 'if': true, + 'unless': true, + 'with': true, + 'log': true, + 'lookup': true + }; + if (knownHelpers) { + for (var name in knownHelpers) { + this.options.knownHelpers[name] = knownHelpers[name]; + } + } + + return this.accept(program); + }, + + accept: function(node) { + return this[node.type](node); + }, + + program: function(program) { + var statements = program.statements; + + for(var i=0, l=statements.length; i 0) { + varDeclarations += ", " + locals.join(", "); + } + + // Generate minimizer alias mappings + for (var alias in this.aliases) { + if (this.aliases.hasOwnProperty(alias)) { + varDeclarations += ', ' + alias + '=' + this.aliases[alias]; + } + } + + var params = ["depth0", "helpers", "partials", "data"]; + + if (this.useDepths) { + params.push('depths'); + } + + // Perform a second pass over the output to merge content when possible + var source = this.mergeSource(varDeclarations); + + if (asObject) { + params.push(source); + + return Function.apply(this, params); + } else { + return 'function(' + params.join(',') + ') {\n ' + source + '}'; + } + }, + mergeSource: function(varDeclarations) { + var source = '', + buffer, + appendOnly = !this.forceBuffer, + appendFirst; + + for (var i = 0, len = this.source.length; i < len; i++) { + var line = this.source[i]; + if (line.appendToBuffer) { + if (buffer) { + buffer = buffer + '\n + ' + line.content; + } else { + buffer = line.content; + } + } else { + if (buffer) { + if (!source) { + appendFirst = true; + source = buffer + ';\n '; + } else { + source += 'buffer += ' + buffer + ';\n '; + } + buffer = undefined; + } + source += line + '\n '; + + if (!this.environment.isSimple) { + appendOnly = false; + } + } + } + + if (appendOnly) { + if (buffer || !source) { + source += 'return ' + (buffer || '""') + ';\n'; + } + } else { + varDeclarations += ", buffer = " + (appendFirst ? '' : this.initializeBuffer()); + if (buffer) { + source += 'return buffer + ' + buffer + ';\n'; + } else { + source += 'return buffer;\n'; + } + } + + if (varDeclarations) { + source = 'var ' + varDeclarations.substring(2) + (appendFirst ? '' : ';\n ') + source; + } + + return source; + }, + + // [blockValue] + // + // On stack, before: hash, inverse, program, value + // On stack, after: return value of blockHelperMissing + // + // The purpose of this opcode is to take a block of the form + // `{{#this.foo}}...{{/this.foo}}`, resolve the value of `foo`, and + // replace it on the stack with the result of properly + // invoking blockHelperMissing. + blockValue: function(name) { + this.aliases.blockHelperMissing = 'helpers.blockHelperMissing'; + + var params = [this.contextName(0)]; + this.setupParams(name, 0, params); + + var blockName = this.popStack(); + params.splice(1, 0, blockName); + + this.push('blockHelperMissing.call(' + params.join(', ') + ')'); + }, + + // [ambiguousBlockValue] + // + // On stack, before: hash, inverse, program, value + // Compiler value, before: lastHelper=value of last found helper, if any + // On stack, after, if no lastHelper: same as [blockValue] + // On stack, after, if lastHelper: value + ambiguousBlockValue: function() { + this.aliases.blockHelperMissing = 'helpers.blockHelperMissing'; + + // We're being a bit cheeky and reusing the options value from the prior exec + var params = [this.contextName(0)]; + this.setupParams('', 0, params, true); + + this.flushInline(); + + var current = this.topStack(); + params.splice(1, 0, current); + + this.pushSource("if (!" + this.lastHelper + ") { " + current + " = blockHelperMissing.call(" + params.join(", ") + "); }"); + }, + + // [appendContent] + // + // On stack, before: ... + // On stack, after: ... + // + // Appends the string value of `content` to the current buffer + appendContent: function(content) { + if (this.pendingContent) { + content = this.pendingContent + content; + } + + this.pendingContent = content; + }, + + // [append] + // + // On stack, before: value, ... + // On stack, after: ... + // + // Coerces `value` to a String and appends it to the current buffer. + // + // If `value` is truthy, or 0, it is coerced into a string and appended + // Otherwise, the empty string is appended + append: function() { + // Force anything that is inlined onto the stack so we don't have duplication + // when we examine local + this.flushInline(); + var local = this.popStack(); + this.pushSource('if (' + local + ' != null) { ' + this.appendToBuffer(local) + ' }'); + if (this.environment.isSimple) { + this.pushSource("else { " + this.appendToBuffer("''") + " }"); + } + }, + + // [appendEscaped] + // + // On stack, before: value, ... + // On stack, after: ... + // + // Escape `value` and append it to the buffer + appendEscaped: function() { + this.aliases.escapeExpression = 'this.escapeExpression'; + + this.pushSource(this.appendToBuffer("escapeExpression(" + this.popStack() + ")")); + }, + + // [getContext] + // + // On stack, before: ... + // On stack, after: ... + // Compiler value, after: lastContext=depth + // + // Set the value of the `lastContext` compiler value to the depth + getContext: function(depth) { + this.lastContext = depth; + }, + + // [pushContext] + // + // On stack, before: ... + // On stack, after: currentContext, ... + // + // Pushes the value of the current context onto the stack. + pushContext: function() { + this.pushStackLiteral(this.contextName(this.lastContext)); + }, + + // [lookupOnContext] + // + // On stack, before: ... + // On stack, after: currentContext[name], ... + // + // Looks up the value of `name` on the current context and pushes + // it onto the stack. + lookupOnContext: function(parts, falsy, scoped) { + /*jshint -W083 */ + var i = 0, + len = parts.length; + + if (!scoped && this.options.compat && !this.lastContext) { + // The depthed query is expected to handle the undefined logic for the root level that + // is implemented below, so we evaluate that directly in compat mode + this.push(this.depthedLookup(parts[i++])); + } else { + this.pushContext(); + } + + for (; i < len; i++) { + this.replaceStack(function(current) { + var lookup = this.nameLookup(current, parts[i], 'context'); + // We want to ensure that zero and false are handled properly if the context (falsy flag) + // needs to have the special handling for these values. + if (!falsy) { + return ' != null ? ' + lookup + ' : ' + current; + } else { + // Otherwise we can use generic falsy handling + return ' && ' + lookup; + } + }); + } + }, + + // [lookupData] + // + // On stack, before: ... + // On stack, after: data, ... + // + // Push the data lookup operator + lookupData: function(depth, parts) { + /*jshint -W083 */ + if (!depth) { + this.pushStackLiteral('data'); + } else { + this.pushStackLiteral('this.data(data, ' + depth + ')'); + } + + var len = parts.length; + for (var i = 0; i < len; i++) { + this.replaceStack(function(current) { + return ' && ' + this.nameLookup(current, parts[i], 'data'); + }); + } + }, + + // [resolvePossibleLambda] + // + // On stack, before: value, ... + // On stack, after: resolved value, ... + // + // If the `value` is a lambda, replace it on the stack by + // the return value of the lambda + resolvePossibleLambda: function() { + this.aliases.lambda = 'this.lambda'; + + this.push('lambda(' + this.popStack() + ', ' + this.contextName(0) + ')'); + }, + + // [pushStringParam] + // + // On stack, before: ... + // On stack, after: string, currentContext, ... + // + // This opcode is designed for use in string mode, which + // provides the string value of a parameter along with its + // depth rather than resolving it immediately. + pushStringParam: function(string, type) { + this.pushContext(); + this.pushString(type); + + // If it's a subexpression, the string result + // will be pushed after this opcode. + if (type !== 'sexpr') { + if (typeof string === 'string') { + this.pushString(string); + } else { + this.pushStackLiteral(string); + } + } + }, + + emptyHash: function() { + this.pushStackLiteral('{}'); + + if (this.trackIds) { + this.push('{}'); // hashIds + } + if (this.stringParams) { + this.push('{}'); // hashContexts + this.push('{}'); // hashTypes + } + }, + pushHash: function() { + if (this.hash) { + this.hashes.push(this.hash); + } + this.hash = {values: [], types: [], contexts: [], ids: []}; + }, + popHash: function() { + var hash = this.hash; + this.hash = this.hashes.pop(); + + if (this.trackIds) { + this.push('{' + hash.ids.join(',') + '}'); + } + if (this.stringParams) { + this.push('{' + hash.contexts.join(',') + '}'); + this.push('{' + hash.types.join(',') + '}'); + } + + this.push('{\n ' + hash.values.join(',\n ') + '\n }'); + }, + + // [pushString] + // + // On stack, before: ... + // On stack, after: quotedString(string), ... + // + // Push a quoted version of `string` onto the stack + pushString: function(string) { + this.pushStackLiteral(this.quotedString(string)); + }, + + // [push] + // + // On stack, before: ... + // On stack, after: expr, ... + // + // Push an expression onto the stack + push: function(expr) { + this.inlineStack.push(expr); + return expr; + }, + + // [pushLiteral] + // + // On stack, before: ... + // On stack, after: value, ... + // + // Pushes a value onto the stack. This operation prevents + // the compiler from creating a temporary variable to hold + // it. + pushLiteral: function(value) { + this.pushStackLiteral(value); + }, + + // [pushProgram] + // + // On stack, before: ... + // On stack, after: program(guid), ... + // + // Push a program expression onto the stack. This takes + // a compile-time guid and converts it into a runtime-accessible + // expression. + pushProgram: function(guid) { + if (guid != null) { + this.pushStackLiteral(this.programExpression(guid)); + } else { + this.pushStackLiteral(null); + } + }, + + // [invokeHelper] + // + // On stack, before: hash, inverse, program, params..., ... + // On stack, after: result of helper invocation + // + // Pops off the helper's parameters, invokes the helper, + // and pushes the helper's return value onto the stack. + // + // If the helper is not found, `helperMissing` is called. + invokeHelper: function(paramSize, name, isSimple) { + this.aliases.helperMissing = 'helpers.helperMissing'; + + var nonHelper = this.popStack(); + var helper = this.setupHelper(paramSize, name); + + var lookup = (isSimple ? helper.name + ' || ' : '') + nonHelper + ' || helperMissing'; + this.push('((' + lookup + ').call(' + helper.callParams + '))'); + }, + + // [invokeKnownHelper] + // + // On stack, before: hash, inverse, program, params..., ... + // On stack, after: result of helper invocation + // + // This operation is used when the helper is known to exist, + // so a `helperMissing` fallback is not required. + invokeKnownHelper: function(paramSize, name) { + var helper = this.setupHelper(paramSize, name); + this.push(helper.name + ".call(" + helper.callParams + ")"); + }, + + // [invokeAmbiguous] + // + // On stack, before: hash, inverse, program, params..., ... + // On stack, after: result of disambiguation + // + // This operation is used when an expression like `{{foo}}` + // is provided, but we don't know at compile-time whether it + // is a helper or a path. + // + // This operation emits more code than the other options, + // and can be avoided by passing the `knownHelpers` and + // `knownHelpersOnly` flags at compile-time. + invokeAmbiguous: function(name, helperCall) { + this.aliases.functionType = '"function"'; + this.aliases.helperMissing = 'helpers.helperMissing'; + this.useRegister('helper'); + + var nonHelper = this.popStack(); + + this.emptyHash(); + var helper = this.setupHelper(0, name, helperCall); + + var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper'); + + this.push( + '((helper = (helper = ' + helperName + ' || ' + nonHelper + ') != null ? helper : helperMissing' + + (helper.paramsInit ? '),(' + helper.paramsInit : '') + '),' + + '(typeof helper === functionType ? helper.call(' + helper.callParams + ') : helper))'); + }, + + // [invokePartial] + // + // On stack, before: context, ... + // On stack after: result of partial invocation + // + // This operation pops off a context, invokes a partial with that context, + // and pushes the result of the invocation back. + invokePartial: function(name, indent) { + var params = [this.nameLookup('partials', name, 'partial'), "'" + indent + "'", "'" + name + "'", this.popStack(), this.popStack(), "helpers", "partials"]; + + if (this.options.data) { + params.push("data"); + } else if (this.options.compat) { + params.push('undefined'); + } + if (this.options.compat) { + params.push('depths'); + } + + this.push("this.invokePartial(" + params.join(", ") + ")"); + }, + + // [assignToHash] + // + // On stack, before: value, ..., hash, ... + // On stack, after: ..., hash, ... + // + // Pops a value off the stack and assigns it to the current hash + assignToHash: function(key) { + var value = this.popStack(), + context, + type, + id; + + if (this.trackIds) { + id = this.popStack(); + } + if (this.stringParams) { + type = this.popStack(); + context = this.popStack(); + } + + var hash = this.hash; + if (context) { + hash.contexts.push("'" + key + "': " + context); + } + if (type) { + hash.types.push("'" + key + "': " + type); + } + if (id) { + hash.ids.push("'" + key + "': " + id); + } + hash.values.push("'" + key + "': (" + value + ")"); + }, + + pushId: function(type, name) { + if (type === 'ID' || type === 'DATA') { + this.pushString(name); + } else if (type === 'sexpr') { + this.pushStackLiteral('true'); + } else { + this.pushStackLiteral('null'); + } + }, + + // HELPERS + + compiler: JavaScriptCompiler, + + compileChildren: function(environment, options) { + var children = environment.children, child, compiler; + + for(var i=0, l=children.length; i this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); } + return this.topStackName(); + }, + topStackName: function() { + return "stack" + this.stackSlot; + }, + flushInline: function() { + var inlineStack = this.inlineStack; + if (inlineStack.length) { + this.inlineStack = []; + for (var i = 0, len = inlineStack.length; i < len; i++) { + var entry = inlineStack[i]; + if (entry instanceof Literal) { + this.compileStack.push(entry); + } else { + this.pushStack(entry); + } + } + } + }, + isInline: function() { + return this.inlineStack.length; + }, + + popStack: function(wrapped) { + var inline = this.isInline(), + item = (inline ? this.inlineStack : this.compileStack).pop(); + + if (!wrapped && (item instanceof Literal)) { + return item.value; + } else { + if (!inline) { + /* istanbul ignore next */ + if (!this.stackSlot) { + throw new Exception('Invalid stack pop'); + } + this.stackSlot--; + } + return item; + } + }, + + topStack: function() { + var stack = (this.isInline() ? this.inlineStack : this.compileStack), + item = stack[stack.length - 1]; + + if (item instanceof Literal) { + return item.value; + } else { + return item; + } + }, + + contextName: function(context) { + if (this.useDepths && context) { + return 'depths[' + context + ']'; + } else { + return 'depth' + context; + } + }, + + quotedString: function(str) { + return '"' + str + .replace(/\\/g, '\\\\') + .replace(/"/g, '\\"') + .replace(/\n/g, '\\n') + .replace(/\r/g, '\\r') + .replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4 + .replace(/\u2029/g, '\\u2029') + '"'; + }, + + objectLiteral: function(obj) { + var pairs = []; + + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + pairs.push(this.quotedString(key) + ':' + obj[key]); + } + } + + return '{' + pairs.join(',') + '}'; + }, + + setupHelper: function(paramSize, name, blockHelper) { + var params = [], + paramsInit = this.setupParams(name, paramSize, params, blockHelper); + var foundHelper = this.nameLookup('helpers', name, 'helper'); + + return { + params: params, + paramsInit: paramsInit, + name: foundHelper, + callParams: [this.contextName(0)].concat(params).join(", ") + }; + }, + + setupOptions: function(helper, paramSize, params) { + var options = {}, contexts = [], types = [], ids = [], param, inverse, program; + + options.name = this.quotedString(helper); + options.hash = this.popStack(); + + if (this.trackIds) { + options.hashIds = this.popStack(); + } + if (this.stringParams) { + options.hashTypes = this.popStack(); + options.hashContexts = this.popStack(); + } + + inverse = this.popStack(); + program = this.popStack(); + + // Avoid setting fn and inverse if neither are set. This allows + // helpers to do a check for `if (options.fn)` + if (program || inverse) { + if (!program) { + program = 'this.noop'; + } + + if (!inverse) { + inverse = 'this.noop'; + } + + options.fn = program; + options.inverse = inverse; + } + + // The parameters go on to the stack in order (making sure that they are evaluated in order) + // so we need to pop them off the stack in reverse order + var i = paramSize; + while (i--) { + param = this.popStack(); + params[i] = param; + + if (this.trackIds) { + ids[i] = this.popStack(); + } + if (this.stringParams) { + types[i] = this.popStack(); + contexts[i] = this.popStack(); + } + } + + if (this.trackIds) { + options.ids = "[" + ids.join(",") + "]"; + } + if (this.stringParams) { + options.types = "[" + types.join(",") + "]"; + options.contexts = "[" + contexts.join(",") + "]"; + } + + if (this.options.data) { + options.data = "data"; + } + + return options; + }, + + // the params and contexts arguments are passed in arrays + // to fill in + setupParams: function(helperName, paramSize, params, useRegister) { + var options = this.objectLiteral(this.setupOptions(helperName, paramSize, params)); + + if (useRegister) { + this.useRegister('options'); + params.push('options'); + return 'options=' + options; + } else { + params.push(options); + return ''; + } + } + }; + + var reservedWords = ( + "break else new var" + + " case finally return void" + + " catch for switch while" + + " continue function this with" + + " default if throw" + + " delete in try" + + " do instanceof typeof" + + " abstract enum int short" + + " boolean export interface static" + + " byte extends long super" + + " char final native synchronized" + + " class float package throws" + + " const goto private transient" + + " debugger implements protected volatile" + + " double import public let yield" + ).split(" "); + + var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {}; + + for(var i=0, l=reservedWords.length; i + /// Replaces the current culture and UI culture for the test. + /// + [AttributeUsage(AttributeTargets.Method)] + public class ReplaceCultureAttribute : BeforeAfterTestAttribute + { + private CultureInfo _originalCulture; + private CultureInfo _originalUICulture; + + /// + /// Replaces the current culture and UI culture based on specified value. + /// + public ReplaceCultureAttribute(string currentCulture) : this(currentCulture, currentCulture) + { + } + + /// + /// Replaces the current culture and UI culture based on specified values. + /// + public ReplaceCultureAttribute(string currentCulture, string currentUICulture) + { + Culture = new CultureInfo(currentCulture); + UICulture = new CultureInfo(currentUICulture); + } + +#if NET451 + /// + /// The for the test. Defaults to en-GB. + /// + /// + /// en-GB is used here as the default because en-US is equivalent to the InvariantCulture. We + /// want to be able to find bugs where we're accidentally relying on the Invariant instead of the + /// user's culture. + /// +#else + /// + /// The for the test. Defaults to en-GB. + /// + /// + /// en-GB is used here as the default because en-US is equivalent to the InvariantCulture. We + /// want to be able to find bugs where we're accidentally relying on the Invariant instead of the + /// user's culture. + /// +#endif + public CultureInfo Culture { get; } + +#if NET451 + /// + /// The for the test. Defaults to en-US. + /// +#else + /// + /// The for the test. Defaults to en-US. + /// +#endif + public CultureInfo UICulture { get; } + + public override void Before(MethodInfo methodUnderTest) + { + _originalCulture = CultureInfo.CurrentCulture; + _originalUICulture = CultureInfo.CurrentUICulture; + +#if NET451 + Thread.CurrentThread.CurrentCulture = Culture; + Thread.CurrentThread.CurrentUICulture = UICulture; +#else + CultureInfo.CurrentCulture = Culture; + CultureInfo.CurrentUICulture = UICulture; +#endif + + } + + public override void After(MethodInfo methodUnderTest) + { +#if NET451 + Thread.CurrentThread.CurrentCulture = _originalCulture; + Thread.CurrentThread.CurrentUICulture = _originalUICulture; +#else + CultureInfo.CurrentCulture = _originalCulture; + CultureInfo.CurrentUICulture = _originalUICulture; +#endif + } + } +} diff --git a/Jint.Tests/Runtime/Converters/EnumsToStringConverter.cs b/Jint.Tests/Runtime/Converters/EnumsToStringConverter.cs new file mode 100644 index 0000000000..bd49ce506c --- /dev/null +++ b/Jint.Tests/Runtime/Converters/EnumsToStringConverter.cs @@ -0,0 +1,21 @@ +using Jint.Native; +using Jint.Runtime.Interop; +using System; + +namespace Jint.Tests.Runtime.Converters +{ + public class EnumsToStringConverter : IObjectConverter + { + public bool TryConvert(object value, out JsValue result) + { + if (value is Enum) + { + result = value.ToString(); + return true; + } + + result = JsValue.Null; + return false; + } + } +} diff --git a/Jint.Tests/Runtime/Domain/A.cs b/Jint.Tests/Runtime/Domain/A.cs index cd78b4dfaa..cb3eb0a567 100644 --- a/Jint.Tests/Runtime/Domain/A.cs +++ b/Jint.Tests/Runtime/Domain/A.cs @@ -45,5 +45,64 @@ public string Call6(Func callback) return callback(thisArg, arguments).ToString(); } + + public bool Call7(string str, Func predicate) + { + return predicate(str); + } + + public string Call8(Func predicate) + { + return predicate(); + } + + public void Call9(Action predicate) + { + predicate(); + } + + public void Call10(string str, Action predicate) + { + predicate(str); + } + + public void Call11(string str, string str2, Action predicate) + { + predicate(str, str2); + } + + public int Call12(int value, Func map) + { + return map(value); + } + + public string Call13(params object[] values) + { + return String.Join(",", values); + } + + public string Call14(string firstParam, params object[] values) + { + return String.Format("{0}:{1}", firstParam, String.Join(",", values)); + } + + public void Call15(string x) + { + + } + public string Call16(params JsValue[] values) + { + return String.Join(",", (System.Collections.Generic.IEnumerable)values); + } + + public int Call17(Func callback) + { + return callback(17); + } + + public void Call18(Action callback) + { + callback(18); + } } } diff --git a/Jint.Tests/Runtime/Domain/ArrayConverterTestClass.cs b/Jint.Tests/Runtime/Domain/ArrayConverterTestClass.cs new file mode 100644 index 0000000000..c7af8c6436 --- /dev/null +++ b/Jint.Tests/Runtime/Domain/ArrayConverterTestClass.cs @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; +using System.Globalization; + +namespace Jint.Tests.Runtime.Domain +{ + public class ArrayConverterTestClass + { + public string MethodAcceptsArrayOfStrings(string[] arrayOfStrings) + { + return SerializeToString(arrayOfStrings); + } + + public string MethodAcceptsArrayOfInt(int[] arrayOfInt) + { + return SerializeToString(arrayOfInt); + } + + public string MethodAcceptsArrayOfBool(int[] arrayOfBool) + { + return SerializeToString(arrayOfBool); + } + + private static string SerializeToString(IEnumerable array) + { + return String.Join(",", array); + } + } + + public class ArrayConverterItem : IConvertible + { + private readonly int _value; + + public ArrayConverterItem(int value) + { + _value = value; + } + + public override string ToString() + { + return ToString(CultureInfo.InvariantCulture); + } + + public string ToString(IFormatProvider provider) + { + return _value.ToString(provider); + } + + public int ToInt32(IFormatProvider provider) + { + return Convert.ToInt32(_value, provider); + } + + #region NotImplemented + public TypeCode GetTypeCode() + { + throw new NotImplementedException(); + } + + public bool ToBoolean(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public char ToChar(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public sbyte ToSByte(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public byte ToByte(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public short ToInt16(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public ushort ToUInt16(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public uint ToUInt32(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public long ToInt64(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public ulong ToUInt64(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public float ToSingle(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public double ToDouble(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public decimal ToDecimal(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public DateTime ToDateTime(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public object ToType(Type conversionType, IFormatProvider provider) + { + throw new NotImplementedException(); + } + #endregion + + + } +} diff --git a/Jint.Tests/Runtime/Domain/ClassWithStaticFields.cs b/Jint.Tests/Runtime/Domain/ClassWithStaticFields.cs index a71e2a07dc..fb8e082c4e 100644 --- a/Jint.Tests/Runtime/Domain/ClassWithStaticFields.cs +++ b/Jint.Tests/Runtime/Domain/ClassWithStaticFields.cs @@ -14,5 +14,39 @@ static ClassWithStaticFields() { Setter = "Setter"; } - } + } + + public class Nested + { + public class ClassWithStaticFields + { + public static string Get = "Get"; + public static string Set = "Set"; + + public static string Getter + { + get { return "Getter"; } + } + + public static string Setter + { + get + { + return _setter; + } + set + { + _setter = value; + } + } + + public static readonly string Readonly = "Readonly"; + private static string _setter; + + static ClassWithStaticFields() + { + Setter = "Setter"; + } + } + } } diff --git a/Jint.Tests/Runtime/Domain/Company.cs b/Jint.Tests/Runtime/Domain/Company.cs new file mode 100644 index 0000000000..af9204a2d2 --- /dev/null +++ b/Jint.Tests/Runtime/Domain/Company.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Jint.Tests.Runtime.Domain +{ + public class Company : ICompany, IComparable + { + private string _name; + private readonly Dictionary _dictionary = new Dictionary(); + + public Company(string name) + { + _name = name; + } + + string ICompany.Name + { + get { return _name; } + set { _name = value; } + } + + string ICompany.this[string key] + { + get { return _dictionary[key]; } + set { _dictionary[key] = value; } + } + + int IComparable.CompareTo(ICompany other) + { + return string.Compare(_name, other.Name, StringComparison.CurrentCulture); + } + } +} diff --git a/Jint.Tests/Runtime/Domain/ICompany.cs b/Jint.Tests/Runtime/Domain/ICompany.cs new file mode 100644 index 0000000000..af874e1476 --- /dev/null +++ b/Jint.Tests/Runtime/Domain/ICompany.cs @@ -0,0 +1,8 @@ +namespace Jint.Tests.Runtime.Domain +{ + public interface ICompany + { + string Name { get; set; } + string this[string key] { get; set; } + } +} \ No newline at end of file diff --git a/Jint.Tests/Runtime/Domain/Shape.cs b/Jint.Tests/Runtime/Domain/Shape.cs index ee4224a681..41166322d3 100644 --- a/Jint.Tests/Runtime/Domain/Shape.cs +++ b/Jint.Tests/Runtime/Domain/Shape.cs @@ -15,7 +15,42 @@ public abstract class Shape } public class Circle : Shape - { + { + public class Meta + { + public Meta() + { + _description = "descp"; + } + private string _description; + + public string Description + { + get + { + return _description; + } + set + { + _description = value; + } + } + + public enum Usage + { + Public, + Private, + Internal = 11 + } + } + + public enum Kind + { + Unit, + Ellipse, + Round = 5 + } + public Circle() { } diff --git a/Jint.Tests/Runtime/Domain/Thrower.cs b/Jint.Tests/Runtime/Domain/Thrower.cs new file mode 100644 index 0000000000..878a794ae4 --- /dev/null +++ b/Jint.Tests/Runtime/Domain/Thrower.cs @@ -0,0 +1,27 @@ +using System; + +namespace Jint.Tests.Runtime.Domain +{ + public class Thrower + { + public void ThrowArgumentNullException() + { + throw new ArgumentNullException(); + } + + public void ThrowExceptionWithMessage(string message) + { + throw new Exception(message); + } + + public void ThrowNotSupportedException() + { + throw new NotSupportedException(); + } + + public void ThrowNotSupportedExceptionWithMessage(string message) + { + throw new NotSupportedException(message); + } + } +} diff --git a/Jint.Tests/Runtime/EngineTests.cs b/Jint.Tests/Runtime/EngineTests.cs index 54ae12aa5c..066f9285e8 100644 --- a/Jint.Tests/Runtime/EngineTests.cs +++ b/Jint.Tests/Runtime/EngineTests.cs @@ -1,742 +1,2182 @@ -using System; -using System.Globalization; -using System.IO; -using System.Reflection; -using System.Threading; -using Jint.Native.Number; -using Jint.Parser; -using Jint.Parser.Ast; -using Jint.Runtime; -using Xunit; -using Xunit.Extensions; - -namespace Jint.Tests.Runtime -{ - public class EngineTests : IDisposable - { - private readonly Engine _engine; - - public EngineTests() - { - _engine = new Engine() - .SetValue("log", new Action(Console.WriteLine)) - .SetValue("assert", new Action(Assert.True)) - ; - } - - void IDisposable.Dispose() - { - } - - - private void RunTest(string source) - { - - _engine.Execute(source); - } - - [Theory] - [InlineData("Scratch.js")] - public void ShouldInterpretScriptFile(string file) - { - const string prefix = "Jint.Tests.Runtime.Scripts."; - - var assembly = Assembly.GetExecutingAssembly(); - var scriptPath = prefix + file; - - using (var stream = assembly.GetManifestResourceStream(scriptPath)) - if (stream != null) - using (var sr = new StreamReader(stream)) - { - var source = sr.ReadToEnd(); - RunTest(source); - } - } - - [Theory] - [InlineData(42d, "42")] - [InlineData("Hello", "'Hello'")] - public void ShouldInterpretLiterals(object expected, string source) - { - var engine = new Engine(); - var result = engine.Execute(source).GetCompletionValue().ToObject(); - - Assert.Equal(expected, result); - } - - [Fact] - public void ShouldInterpretVariableDeclaration() - { - var engine = new Engine(); - var result = engine - .Execute("var foo = 'bar'; foo;") - .GetCompletionValue() - .ToObject(); - - Assert.Equal("bar", result); - } - - [Theory] - [InlineData(4d, "1 + 3")] - [InlineData(-2d, "1 - 3")] - [InlineData(3d, "1 * 3")] - [InlineData(2d, "6 / 3")] - [InlineData(9d, "15 & 9")] - [InlineData(15d, "15 | 9")] - [InlineData(6d, "15 ^ 9")] - [InlineData(36d, "9 << 2")] - [InlineData(2d, "9 >> 2")] - [InlineData(4d, "19 >>> 2")] - public void ShouldInterpretBinaryExpression(object expected, string source) - { - var engine = new Engine(); - var result = engine.Execute(source).GetCompletionValue().ToObject(); - - Assert.Equal(expected, result); - } - - [Fact] - public void ShouldEvaluateHasOwnProperty() - { - RunTest(@" - var x = {}; - x.Bar = 42; - assert(x.hasOwnProperty('Bar')); - "); - } - - [Fact] - public void FunctionConstructorsShouldCreateNewObjects() - { - RunTest(@" - var Vehicle = function () {}; - var vehicle = new Vehicle(); - assert(vehicle != undefined); - "); - } - - [Fact] - public void NewObjectsInheritFunctionConstructorProperties() - { - RunTest(@" - var Vehicle = function () {}; - var vehicle = new Vehicle(); - Vehicle.prototype.wheelCount = 4; - assert(vehicle.wheelCount == 4); - assert((new Vehicle()).wheelCount == 4); - "); - } - - [Fact] - public void PrototypeFunctionIsInherited() - { - RunTest(@" - function Body(mass){ - this.mass = mass; - } - - Body.prototype.offsetMass = function(dm) { - this.mass += dm; - return this; - } - - var b = new Body(36); - b.offsetMass(6); - assert(b.mass == 42); - "); - - } - - [Fact] - public void FunctionConstructorCall() - { - RunTest(@" - function Body(mass){ - this.mass = mass; - } - - var john = new Body(36); - assert(john.mass == 36); - "); - } - - [Fact] - public void NewObjectsShouldUsePrivateProperties() - { - RunTest(@" - var Vehicle = function (color) { - this.color = color; - }; - var vehicle = new Vehicle('tan'); - assert(vehicle.color == 'tan'); - "); - } - - [Fact] - public void FunctionConstructorsShouldDefinePrototypeChain() - { - RunTest(@" - function Vehicle() {}; - var vehicle = new Vehicle(); - assert(vehicle.hasOwnProperty('constructor') == false); - "); - } - - [Fact] - public void NewObjectsConstructorIsObject() - { - RunTest(@" - var o = new Object(); - assert(o.constructor == Object); - "); - } - - [Fact] - public void NewObjectsIntanceOfConstructorObject() - { - RunTest(@" - var o = new Object(); - assert(o instanceof Object); - "); - } - - [Fact] - public void NewObjectsConstructorShouldBeConstructorObject() - { - RunTest(@" - var Vehicle = function () {}; - var vehicle = new Vehicle(); - assert(vehicle.constructor == Vehicle); - "); - } - - [Fact] - public void NewObjectsIntanceOfConstructorFunction() - { - RunTest(@" - var Vehicle = function () {}; - var vehicle = new Vehicle(); - assert(vehicle instanceof Vehicle); - "); - } - - [Fact] - public void ShouldEvaluateForLoops() - { - RunTest(@" - var foo = 0; - for (var i = 0; i < 5; i++) { - foo += i; - } - assert(foo == 10); - "); - } - - [Fact] - public void ShouldEvaluateRecursiveFunctions() - { - RunTest(@" - function fib(n) { - if (n < 2) { - return n; - } - return fib(n - 1) + fib(n - 2); - } - var result = fib(6); - assert(result == 8); - "); - } - - [Fact] - public void ShouldAccessObjectProperties() - { - RunTest(@" - var o = {}; - o.Foo = 'bar'; - o.Baz = 42; - o.Blah = o.Foo + o.Baz; - assert(o.Blah == 'bar42'); - "); - } - - - [Fact] - public void ShouldConstructArray() - { - RunTest(@" - var o = []; - assert(o.length == 0); - "); - } - - [Fact] - public void ArrayPushShouldIncrementLength() - { - RunTest(@" - var o = []; - o.push(1); - assert(o.length == 1); - "); - } - - [Fact] - public void ArrayFunctionInitializesLength() - { - RunTest(@" - assert(Array(3).length == 3); - assert(Array('3').length == 1); - "); - } - - [Fact] - public void ArrayIndexerIsAssigned() - { - RunTest(@" - var n = 8; - var o = Array(n); - for (var i = 0; i < n; i++) o[i] = i; - assert(o[0] == 0); - assert(o[7] == 7); - "); - } - - [Fact] - public void ArrayPopShouldDecrementLength() - { - RunTest(@" - var o = [42, 'foo']; - var pop = o.pop(); - assert(o.length == 1); - assert(pop == 'foo'); - "); - } - - [Fact] - public void ArrayConstructor() - { - RunTest(@" - var o = []; - assert(o.constructor == Array); - "); - } - - [Fact] - public void DateConstructor() - { - RunTest(@" - var o = new Date(); - assert(o.constructor == Date); - assert(o.hasOwnProperty('constructor') == false); - "); - } - - [Fact] - public void ShouldConvertDateToNumber() - { - RunTest(@" - assert(Number(new Date(0)) === 0); - "); - } - - [Fact] - public void DatePrimitiveValueShouldBeNaN() - { - RunTest(@" - assert(isNaN(Date.prototype.valueOf())); - "); - } - - [Fact] - public void MathObjectIsDefined() - { - RunTest(@" - var o = Math.abs(-1) - assert(o == 1); - "); - } - - [Fact] - public void VoidShouldReturnUndefined() - { - RunTest(@" - assert(void 0 === undefined); - var x = '1'; - assert(void x === undefined); - x = 'x'; - assert (isNaN(void x) === true); - x = new String('-1'); - assert (void x === undefined); - "); - } - - [Fact] - public void TypeofObjectShouldReturnString() - { - RunTest(@" - assert(typeof x === 'undefined'); - assert(typeof 0 === 'number'); - var x = 0; - assert (typeof x === 'number'); - var x = new Object(); - assert (typeof x === 'object'); - "); - } - - [Fact] - public void MathAbsReturnsAbsolute() - { - RunTest(@" - assert(1 == Math.abs(-1)); - "); - } - - [Fact] - public void NaNIsNan() - { - RunTest(@" - var x = NaN; - assert(isNaN(NaN)); - assert(isNaN(Math.abs(x))); - "); - } - - [Fact] - public void ToNumberHandlesStringObject() - { - RunTest(@" - x = new String('1'); - x *= undefined; - assert(isNaN(x)); - "); - } - - [Fact] - public void FunctionScopesAreChained() - { - RunTest(@" - var x = 0; - - function f1(){ - function f2(){ - return x; - }; - return f2(); - - var x = 1; - } - - assert(f1() === undefined); - "); - } - - [Fact] - public void EvalFunctionParseAndExecuteCode() - { - RunTest(@" - var x = 0; - eval('assert(x == 0)'); - "); - } - - [Fact] - public void ForInStatement() - { - RunTest(@" - var x, y, str = ''; - for(var z in this) { - str += z; - } - - assert(str == 'xystrz'); - "); - } - - [Fact] - public void WithStatement() - { - RunTest(@" - with (Math) { - assert(cos(0) == 1); - } - "); - } - - [Fact] - public void ObjectExpression() - { - RunTest(@" - var o = { x: 1 }; - assert(o.x == 1); - "); - } - - [Fact] - public void StringFunctionCreatesString() - { - RunTest(@" - assert(String(NaN) === 'NaN'); - "); - } - - [Fact] - public void ScopeChainInWithStatement() - { - RunTest(@" - var x = 0; - var myObj = {x : 'obj'}; - - function f1(){ - var x = 1; - function f2(){ - with(myObj){ - return x; - } - }; - return f2(); - } - - assert(f1() === 'obj'); - "); - } - - [Fact] - public void TryCatchBlockStatement() - { - RunTest(@" - var x, y, z; - try { - x = 1; - throw new TypeError(); - x = 2; - } - catch(e) { - assert(x == 1); - assert(e instanceof TypeError); - y = 1; - } - finally { - assert(x == 1); - z = 1; - } - - assert(x == 1); - assert(y == 1); - assert(z == 1); - "); - } - - [Fact] - public void FunctionsCanBeAssigned() - { - RunTest(@" - var sin = Math.sin; - assert(sin(0) == 0); - "); - } - - [Fact] - public void FunctionArgumentsIsDefined() - { - RunTest(@" - function f() { - assert(arguments.length > 0); - } - - f(42); - "); - } - - [Fact] - public void PrimitiveValueFunctions() - { - RunTest(@" - var s = (1).toString(); - assert(s == '1'); - "); - } - - [Theory] - [InlineData(true, "'ab' == 'a' + 'b'")] - public void OperatorsPrecedence(object expected, string source) - { - var engine = new Engine(); - var result = engine.Execute(source).GetCompletionValue().ToObject(); - - Assert.Equal(expected, result); - } - - [Fact] - public void FunctionPrototypeShouldHaveApplyMethod() - { - RunTest(@" - var numbers = [5, 6, 2, 3, 7]; - var max = Math.max.apply(null, numbers); - assert(max == 7); - "); - } - - [Theory] - [InlineData(double.NaN, "parseInt(NaN)")] - [InlineData(double.NaN, "parseInt(null)")] - [InlineData(double.NaN, "parseInt(undefined)")] - [InlineData(double.NaN, "parseInt(new Boolean(true))")] - [InlineData(double.NaN, "parseInt(Infinity)")] - [InlineData(-1d, "parseInt(-1)")] - [InlineData(-1d, "parseInt('-1')")] - public void ShouldEvaluateParseInt(object expected, string source) - { - var engine = new Engine(); - var result = engine.Execute(source).GetCompletionValue().ToObject(); - - Assert.Equal(expected, result); - } - - [Fact] - public void ShouldNotExecuteDebuggerStatement() - { - new Engine().Execute("debugger"); - } - - [Fact] - public void ShouldThrowStatementCountOverflow() - { - Assert.Throws( - () => new Engine(cfg => cfg.MaxStatements(100)).Execute("while(true);") - ); - } - - [Fact] - public void ShouldConvertDoubleToStringWithoutLosingPrecision() - { - RunTest(@" - assert(String(14.915832707045631) === '14.915832707045631'); - assert(String(-14.915832707045631) === '-14.915832707045631'); - assert(String(0.5) === '0.5'); - assert(String(0.00000001) === '1e-8'); - assert(String(0.000001) === '0.000001'); - assert(String(-1.0) === '-1'); - assert(String(30.0) === '30'); - assert(String(0.2388906159889881) === '0.2388906159889881'); - "); - } - - [Fact] - public void ShouldWriteNumbersUsingBases() - { - RunTest(@" - assert(15.0.toString() === '15'); - assert(15.0.toString(2) === '1111'); - assert(15.0.toString(8) === '17'); - assert(15.0.toString(16) === 'f'); - assert(15.0.toString(17) === 'f'); - assert(15.0.toString(36) === 'f'); - assert(15.1.toString(36) === 'f.3llllllllkau6snqkpygsc3di'); - "); - } - - [Fact] - public void ShouldNotAlterSlashesInRegex() - { - RunTest(@" - assert(new RegExp('/').toString() === '///'); - "); - } - - [Fact] - public void ShouldHandleEscapedSlashesInRegex() - { - RunTest(@" - var regex = /[a-z]\/[a-z]/; - assert(regex.test('a/b') === true); - assert(regex.test('a\\/b') === false); - "); - } - - [Fact] - public void ShouldComputeFractionInBase() - { - Assert.Equal("011", NumberPrototype.ToFractionBase(0.375, 2)); - Assert.Equal("14141414141414141414141414141414141414141414141414", NumberPrototype.ToFractionBase(0.375, 5)); - } - - [Fact] - public void ShouldInvokeAFunctionValue() - { - RunTest(@" - function add(x, y) { return x + y; } - "); - - var add = _engine.GetValue("add"); - - Assert.Equal(3, add.Invoke(1, 2)); - } - - - [Fact] - public void ShouldNotInvokeNonFunctionValue() - { - RunTest(@" - var x= 10; - "); - - var x = _engine.GetValue("x"); - - Assert.Throws(() => x.Invoke(1, 2)); - } - - [Theory] - [InlineData("0", 0, 16)] - [InlineData("1", 1, 16)] - [InlineData("100", 100, 10)] - [InlineData("1100100", 100, 2)] - [InlineData("2s", 100, 36)] - [InlineData("2qgpckvng1s", 10000000000000000L, 36)] - public void ShouldConvertNumbersToDifferentBase(string expected, long number, int radix) - { - var result = NumberPrototype.ToBase(number, radix); - Assert.Equal(expected, result); - } - - [Fact] - public void ShouldBeCultureInvariant() - { - // decimals in french are separated by commas - Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("fr-FR"); - - var engine = new Engine(); - - var result = engine.Execute("1.2 + 2.1").GetCompletionValue().AsNumber(); - Assert.Equal(3.3d, result); - - result = engine.Execute("JSON.parse('{\"x\" : 3.3}').x").GetCompletionValue().AsNumber(); - Assert.Equal(3.3d, result); - } - - [Fact] - public void ShouldGetTheLastSyntaxNode() - { - var engine = new Engine(); - engine.Execute("1.2"); - - var result = engine.GetLastSyntaxNode(); - Assert.Equal(SyntaxNodes.Literal, result.Type); - } - - [Fact] - public void ShouldGetParseErrorLocation() - { - var engine = new Engine(); - try - { - engine.Execute("1.2+ new", new ParserOptions { Source = "jQuery.js" }); - } - catch (ParserException e) - { - Assert.Equal(1, e.LineNumber); - Assert.Equal(9, e.Column); - Assert.Equal("jQuery.js", e.Source); - } - } - - } -} +using System; +using System.Globalization; +using System.IO; +using System.Reflection; +using Jint.Native.Number; +using Jint.Parser; +using Jint.Parser.Ast; +using Jint.Runtime; +using Jint.Runtime.Debugger; +using Xunit; + +namespace Jint.Tests.Runtime +{ + public class EngineTests : IDisposable + { + private readonly Engine _engine; + private int countBreak = 0; + private StepMode stepMode; + + public EngineTests() + { + _engine = new Engine() + .SetValue("log", new Action(Console.WriteLine)) + .SetValue("assert", new Action(Assert.True)) + .SetValue("equal", new Action(Assert.Equal)) + ; + } + + void IDisposable.Dispose() + { + } + + + private void RunTest(string source) + { + _engine.Execute(source); + } + + private string GetEmbeddedFile(string filename) + { + const string prefix = "Jint.Tests.Runtime.Scripts."; + + var assembly = typeof(EngineTests).GetTypeInfo().Assembly; + var scriptPath = prefix + filename; + + using (var stream = assembly.GetManifestResourceStream(scriptPath)) + { + using (var sr = new StreamReader(stream)) + { + return sr.ReadToEnd(); + } + } + } + + [Theory] + [InlineData(42d, "42")] + [InlineData("Hello", "'Hello'")] + public void ShouldInterpretLiterals(object expected, string source) + { + var engine = new Engine(); + var result = engine.Execute(source).GetCompletionValue().ToObject(); + + Assert.Equal(expected, result); + } + + [Fact] + public void ShouldInterpretVariableDeclaration() + { + var engine = new Engine(); + var result = engine + .Execute("var foo = 'bar'; foo;") + .GetCompletionValue() + .ToObject(); + + Assert.Equal("bar", result); + } + + [Theory] + [InlineData(4d, "1 + 3")] + [InlineData(-2d, "1 - 3")] + [InlineData(3d, "1 * 3")] + [InlineData(2d, "6 / 3")] + [InlineData(9d, "15 & 9")] + [InlineData(15d, "15 | 9")] + [InlineData(6d, "15 ^ 9")] + [InlineData(36d, "9 << 2")] + [InlineData(2d, "9 >> 2")] + [InlineData(4d, "19 >>> 2")] + public void ShouldInterpretBinaryExpression(object expected, string source) + { + var engine = new Engine(); + var result = engine.Execute(source).GetCompletionValue().ToObject(); + + Assert.Equal(expected, result); + } + + [Theory] + [InlineData(-59d, "~58")] + [InlineData(58d, "~~58")] + public void ShouldInterpretUnaryExpression(object expected, string source) + { + var engine = new Engine(); + var result = engine.Execute(source).GetCompletionValue().ToObject(); + + Assert.Equal(expected, result); + } + + [Fact] + public void ShouldEvaluateHasOwnProperty() + { + RunTest(@" + var x = {}; + x.Bar = 42; + assert(x.hasOwnProperty('Bar')); + "); + } + + [Fact] + public void FunctionConstructorsShouldCreateNewObjects() + { + RunTest(@" + var Vehicle = function () {}; + var vehicle = new Vehicle(); + assert(vehicle != undefined); + "); + } + + [Fact] + public void NewObjectsInheritFunctionConstructorProperties() + { + RunTest(@" + var Vehicle = function () {}; + var vehicle = new Vehicle(); + Vehicle.prototype.wheelCount = 4; + assert(vehicle.wheelCount == 4); + assert((new Vehicle()).wheelCount == 4); + "); + } + + [Fact] + public void PrototypeFunctionIsInherited() + { + RunTest(@" + function Body(mass){ + this.mass = mass; + } + + Body.prototype.offsetMass = function(dm) { + this.mass += dm; + return this; + } + + var b = new Body(36); + b.offsetMass(6); + assert(b.mass == 42); + "); + + } + + [Fact] + public void FunctionConstructorCall() + { + RunTest(@" + function Body(mass){ + this.mass = mass; + } + + var john = new Body(36); + assert(john.mass == 36); + "); + } + + [Fact] + public void NewObjectsShouldUsePrivateProperties() + { + RunTest(@" + var Vehicle = function (color) { + this.color = color; + }; + var vehicle = new Vehicle('tan'); + assert(vehicle.color == 'tan'); + "); + } + + [Fact] + public void FunctionConstructorsShouldDefinePrototypeChain() + { + RunTest(@" + function Vehicle() {}; + var vehicle = new Vehicle(); + assert(vehicle.hasOwnProperty('constructor') == false); + "); + } + + [Fact] + public void NewObjectsConstructorIsObject() + { + RunTest(@" + var o = new Object(); + assert(o.constructor == Object); + "); + } + + [Fact] + public void NewObjectsIntanceOfConstructorObject() + { + RunTest(@" + var o = new Object(); + assert(o instanceof Object); + "); + } + + [Fact] + public void NewObjectsConstructorShouldBeConstructorObject() + { + RunTest(@" + var Vehicle = function () {}; + var vehicle = new Vehicle(); + assert(vehicle.constructor == Vehicle); + "); + } + + [Fact] + public void NewObjectsIntanceOfConstructorFunction() + { + RunTest(@" + var Vehicle = function () {}; + var vehicle = new Vehicle(); + assert(vehicle instanceof Vehicle); + "); + } + + [Fact] + public void ShouldEvaluateForLoops() + { + RunTest(@" + var foo = 0; + for (var i = 0; i < 5; i++) { + foo += i; + } + assert(foo == 10); + "); + } + + [Fact] + public void ShouldEvaluateRecursiveFunctions() + { + RunTest(@" + function fib(n) { + if (n < 2) { + return n; + } + return fib(n - 1) + fib(n - 2); + } + var result = fib(6); + assert(result == 8); + "); + } + + [Fact] + public void ShouldAccessObjectProperties() + { + RunTest(@" + var o = {}; + o.Foo = 'bar'; + o.Baz = 42; + o.Blah = o.Foo + o.Baz; + assert(o.Blah == 'bar42'); + "); + } + + + [Fact] + public void ShouldConstructArray() + { + RunTest(@" + var o = []; + assert(o.length == 0); + "); + } + + [Fact] + public void ArrayPushShouldIncrementLength() + { + RunTest(@" + var o = []; + o.push(1); + assert(o.length == 1); + "); + } + + [Fact] + public void ArrayFunctionInitializesLength() + { + RunTest(@" + assert(Array(3).length == 3); + assert(Array('3').length == 1); + "); + } + + [Fact] + public void ArrayIndexerIsAssigned() + { + RunTest(@" + var n = 8; + var o = Array(n); + for (var i = 0; i < n; i++) o[i] = i; + assert(o[0] == 0); + assert(o[7] == 7); + "); + } + + [Fact] + public void ArrayPopShouldDecrementLength() + { + RunTest(@" + var o = [42, 'foo']; + var pop = o.pop(); + assert(o.length == 1); + assert(pop == 'foo'); + "); + } + + [Fact] + public void ArrayConstructor() + { + RunTest(@" + var o = []; + assert(o.constructor == Array); + "); + } + + [Fact] + public void DateConstructor() + { + RunTest(@" + var o = new Date(); + assert(o.constructor == Date); + assert(o.hasOwnProperty('constructor') == false); + "); + } + + [Fact] + public void ShouldConvertDateToNumber() + { + RunTest(@" + assert(Number(new Date(0)) === 0); + "); + } + + [Fact] + public void DatePrimitiveValueShouldBeNaN() + { + RunTest(@" + assert(isNaN(Date.prototype.valueOf())); + "); + } + + [Fact] + public void MathObjectIsDefined() + { + RunTest(@" + var o = Math.abs(-1) + assert(o == 1); + "); + } + + [Fact] + public void VoidShouldReturnUndefined() + { + RunTest(@" + assert(void 0 === undefined); + var x = '1'; + assert(void x === undefined); + x = 'x'; + assert (isNaN(void x) === true); + x = new String('-1'); + assert (void x === undefined); + "); + } + + [Fact] + public void TypeofObjectShouldReturnString() + { + RunTest(@" + assert(typeof x === 'undefined'); + assert(typeof 0 === 'number'); + var x = 0; + assert (typeof x === 'number'); + var x = new Object(); + assert (typeof x === 'object'); + "); + } + + [Fact] + public void MathAbsReturnsAbsolute() + { + RunTest(@" + assert(1 == Math.abs(-1)); + "); + } + + [Fact] + public void NaNIsNan() + { + RunTest(@" + var x = NaN; + assert(isNaN(NaN)); + assert(isNaN(Math.abs(x))); + "); + } + + [Fact] + public void ToNumberHandlesStringObject() + { + RunTest(@" + x = new String('1'); + x *= undefined; + assert(isNaN(x)); + "); + } + + [Fact] + public void FunctionScopesAreChained() + { + RunTest(@" + var x = 0; + + function f1(){ + function f2(){ + return x; + }; + return f2(); + + var x = 1; + } + + assert(f1() === undefined); + "); + } + + [Fact] + public void EvalFunctionParseAndExecuteCode() + { + RunTest(@" + var x = 0; + eval('assert(x == 0)'); + "); + } + + [Fact] + public void ForInStatement() + { + RunTest(@" + var x, y, str = ''; + for(var z in this) { + str += z; + } + + assert(str == 'xystrz'); + "); + } + + [Fact] + public void ForInStatementEnumeratesKeys() + { + RunTest(@" + for(var i in 'abc'); + log(i); + assert(i === '2'); + "); + } + + [Fact] + public void WithStatement() + { + RunTest(@" + with (Math) { + assert(cos(0) == 1); + } + "); + } + + [Fact] + public void ObjectExpression() + { + RunTest(@" + var o = { x: 1 }; + assert(o.x == 1); + "); + } + + [Fact] + public void StringFunctionCreatesString() + { + RunTest(@" + assert(String(NaN) === 'NaN'); + "); + } + + [Fact] + public void ScopeChainInWithStatement() + { + RunTest(@" + var x = 0; + var myObj = {x : 'obj'}; + + function f1(){ + var x = 1; + function f2(){ + with(myObj){ + return x; + } + }; + return f2(); + } + + assert(f1() === 'obj'); + "); + } + + [Fact] + public void TryCatchBlockStatement() + { + RunTest(@" + var x, y, z; + try { + x = 1; + throw new TypeError(); + x = 2; + } + catch(e) { + assert(x == 1); + assert(e instanceof TypeError); + y = 1; + } + finally { + assert(x == 1); + z = 1; + } + + assert(x == 1); + assert(y == 1); + assert(z == 1); + "); + } + + [Fact] + public void FunctionsCanBeAssigned() + { + RunTest(@" + var sin = Math.sin; + assert(sin(0) == 0); + "); + } + + [Fact] + public void FunctionArgumentsIsDefined() + { + RunTest(@" + function f() { + assert(arguments.length > 0); + } + + f(42); + "); + } + + [Fact] + public void PrimitiveValueFunctions() + { + RunTest(@" + var s = (1).toString(); + assert(s == '1'); + "); + } + + [Theory] + [InlineData(true, "'ab' == 'a' + 'b'")] + public void OperatorsPrecedence(object expected, string source) + { + var engine = new Engine(); + var result = engine.Execute(source).GetCompletionValue().ToObject(); + + Assert.Equal(expected, result); + } + + [Fact] + public void FunctionPrototypeShouldHaveApplyMethod() + { + RunTest(@" + var numbers = [5, 6, 2, 3, 7]; + var max = Math.max.apply(null, numbers); + assert(max == 7); + "); + } + + [Theory] + [InlineData(double.NaN, "parseInt(NaN)")] + [InlineData(double.NaN, "parseInt(null)")] + [InlineData(double.NaN, "parseInt(undefined)")] + [InlineData(double.NaN, "parseInt(new Boolean(true))")] + [InlineData(double.NaN, "parseInt(Infinity)")] + [InlineData(-1d, "parseInt(-1)")] + [InlineData(-1d, "parseInt('-1')")] + public void ShouldEvaluateParseInt(object expected, string source) + { + var engine = new Engine(); + var result = engine.Execute(source).GetCompletionValue().ToObject(); + + Assert.Equal(expected, result); + } + + [Fact] + public void ShouldNotExecuteDebuggerStatement() + { + new Engine().Execute("debugger"); + } + + [Fact] + public void ShouldThrowStatementCountOverflow() + { + Assert.Throws( + () => new Engine(cfg => cfg.MaxStatements(100)).Execute("while(true);") + ); + } + + [Fact] + public void ShouldThrowTimeout() + { + Assert.Throws( + () => new Engine(cfg => cfg.TimeoutInterval(new TimeSpan(0, 0, 0, 0, 500))).Execute("while(true);") + ); + } + + + [Fact] + public void CanDiscardRecursion() + { + var script = @"var factorial = function(n) { + if (n>1) { + return n * factorial(n - 1); + } + }; + + var result = factorial(500); + "; + + Assert.Throws( + () => new Engine(cfg => cfg.LimitRecursion()).Execute(script) + ); + } + + [Fact] + public void ShouldDiscardHiddenRecursion() + { + var script = @"var renamedFunc; + var exec = function(callback) { + renamedFunc = callback; + callback(); + }; + + var result = exec(function() { + renamedFunc(); + }); + "; + + Assert.Throws( + () => new Engine(cfg => cfg.LimitRecursion()).Execute(script) + ); + } + + [Fact] + public void ShouldRecognizeAndDiscardChainedRecursion() + { + var script = @" var funcRoot, funcA, funcB, funcC, funcD; + + var funcRoot = function() { + funcA(); + }; + + var funcA = function() { + funcB(); + }; + + var funcB = function() { + funcC(); + }; + + var funcC = function() { + funcD(); + }; + + var funcD = function() { + funcRoot(); + }; + + funcRoot(); + "; + + Assert.Throws( + () => new Engine(cfg => cfg.LimitRecursion()).Execute(script) + ); + } + + [Fact] + public void ShouldProvideCallChainWhenDiscardRecursion() + { + var script = @" var funcRoot, funcA, funcB, funcC, funcD; + + var funcRoot = function() { + funcA(); + }; + + var funcA = function() { + funcB(); + }; + + var funcB = function() { + funcC(); + }; + + var funcC = function() { + funcD(); + }; + + var funcD = function() { + funcRoot(); + }; + + funcRoot(); + "; + + RecursionDepthOverflowException exception = null; + + try + { + new Engine(cfg => cfg.LimitRecursion()).Execute(script); + } + catch (RecursionDepthOverflowException ex) + { + exception = ex; + } + + Assert.NotNull(exception); + Assert.Equal("funcRoot->funcA->funcB->funcC->funcD", exception.CallChain); + Assert.Equal("funcRoot", exception.CallExpressionReference); + } + + [Fact] + public void ShouldAllowShallowRecursion() + { + var script = @"var factorial = function(n) { + if (n>1) { + return n * factorial(n - 1); + } + }; + + var result = factorial(8); + "; + + new Engine(cfg => cfg.LimitRecursion(20)).Execute(script); + } + + [Fact] + public void ShouldDiscardDeepRecursion() + { + var script = @"var factorial = function(n) { + if (n>1) { + return n * factorial(n - 1); + } + }; + + var result = factorial(38); + "; + + Assert.Throws( + () => new Engine(cfg => cfg.LimitRecursion(20)).Execute(script) + ); + } + + [Fact] + public void ShouldConvertDoubleToStringWithoutLosingPrecision() + { + RunTest(@" + assert(String(14.915832707045631) === '14.915832707045631'); + assert(String(-14.915832707045631) === '-14.915832707045631'); + assert(String(0.5) === '0.5'); + assert(String(0.00000001) === '1e-8'); + assert(String(0.000001) === '0.000001'); + assert(String(-1.0) === '-1'); + assert(String(30.0) === '30'); + assert(String(0.2388906159889881) === '0.2388906159889881'); + "); + } + + [Fact] + public void ShouldWriteNumbersUsingBases() + { + RunTest(@" + assert(15.0.toString() === '15'); + assert(15.0.toString(2) === '1111'); + assert(15.0.toString(8) === '17'); + assert(15.0.toString(16) === 'f'); + assert(15.0.toString(17) === 'f'); + assert(15.0.toString(36) === 'f'); + assert(15.1.toString(36) === 'f.3llllllllkau6snqkpygsc3di'); + "); + } + + [Fact] + public void ShouldNotAlterSlashesInRegex() + { + RunTest(@" + assert(new RegExp('/').toString() === '///'); + "); + } + + [Fact] + public void ShouldHandleEscapedSlashesInRegex() + { + RunTest(@" + var regex = /[a-z]\/[a-z]/; + assert(regex.test('a/b') === true); + assert(regex.test('a\\/b') === false); + "); + } + + [Fact] + public void ShouldComputeFractionInBase() + { + Assert.Equal("011", NumberPrototype.ToFractionBase(0.375, 2)); + Assert.Equal("14141414141414141414141414141414141414141414141414", NumberPrototype.ToFractionBase(0.375, 5)); + } + + [Fact] + public void ShouldInvokeAFunctionValue() + { + RunTest(@" + function add(x, y) { return x + y; } + "); + + var add = _engine.GetValue("add"); + + Assert.Equal(3, add.Invoke(1, 2)); + } + + + [Fact] + public void ShouldNotInvokeNonFunctionValue() + { + RunTest(@" + var x= 10; + "); + + var x = _engine.GetValue("x"); + + Assert.Throws(() => x.Invoke(1, 2)); + } + + [Fact] + public void ShouldInvokeAFunctionValueThatBelongsToAnObject() + { + RunTest(@" + var obj = { foo: 5, getFoo: function (bar) { return 'foo is ' + this.foo + ', bar is ' + bar; } }; + "); + + var obj = _engine.GetValue("obj").AsObject(); + var getFoo = obj.Get("getFoo"); + + Assert.Equal("foo is 5, bar is 7", _engine.Invoke(getFoo, obj, new object[] { 7 }).AsString()); + } + + [Fact] + public void ShouldNotInvokeNonFunctionValueThatBelongsToAnObject() + { + RunTest(@" + var obj = { foo: 2 }; + "); + + var obj = _engine.GetValue("obj").AsObject(); + var foo = obj.Get("foo"); + + Assert.Throws(() => _engine.Invoke(foo, obj, new object[] { })); + } + + [Theory] + [InlineData("0", 0, 16)] + [InlineData("1", 1, 16)] + [InlineData("100", 100, 10)] + [InlineData("1100100", 100, 2)] + [InlineData("2s", 100, 36)] + [InlineData("2qgpckvng1s", 10000000000000000L, 36)] + public void ShouldConvertNumbersToDifferentBase(string expected, long number, int radix) + { + var result = NumberPrototype.ToBase(number, radix); + Assert.Equal(expected, result); + } + + [Fact] + public void JsonParserShouldParseNegativeNumber() + { + RunTest(@" + var a = JSON.parse('{ ""x"":-1 }'); + assert(a.x === -1); + + var b = JSON.parse('{ ""x"": -1 }'); + assert(b.x === -1); + "); + } + + [Fact] + public void JsonParserShouldUseToString() + { + RunTest(@" + var a = JSON.parse(null); // Equivalent to JSON.parse('null') + assert(a === null); + "); + + RunTest(@" + var a = JSON.parse(true); // Equivalent to JSON.parse('true') + assert(a === true); + "); + + RunTest(@" + var a = JSON.parse(false); // Equivalent to JSON.parse('false') + assert(a === false); + "); + + RunTest(@" + try { + JSON.parse(undefined); // Equivalent to JSON.parse('undefined') + assert(false); + } + catch(ex) { + assert(ex instanceof SyntaxError); + } + "); + + RunTest(@" + try { + JSON.parse({}); // Equivalent to JSON.parse('[object Object]') + assert(false); + } + catch(ex) { + assert(ex instanceof SyntaxError); + } + "); + + RunTest(@" + try { + JSON.parse(function() { }); // Equivalent to JSON.parse('function () {}') + assert(false); + } + catch(ex) { + assert(ex instanceof SyntaxError); + } + "); + } + + [Fact] + public void JsonParserShouldDetectInvalidNegativeNumberSyntax() + { + RunTest(@" + try { + JSON.parse('{ ""x"": -.1 }'); // Not allowed + assert(false); + } + catch(ex) { + assert(ex instanceof SyntaxError); + } + "); + + RunTest(@" + try { + JSON.parse('{ ""x"": - 1 }'); // Not allowed + assert(false); + } + catch(ex) { + assert(ex instanceof SyntaxError); + } + "); + } + + [Fact] + [ReplaceCulture("fr-FR")] + public void ShouldBeCultureInvariant() + { + // decimals in french are separated by commas + var engine = new Engine(); + + var result = engine.Execute("1.2 + 2.1").GetCompletionValue().AsNumber(); + Assert.Equal(3.3d, result); + + result = engine.Execute("JSON.parse('{\"x\" : 3.3}').x").GetCompletionValue().AsNumber(); + Assert.Equal(3.3d, result); + } + + [Fact] + public void ShouldGetTheLastSyntaxNode() + { + var engine = new Engine(); + engine.Execute("1.2"); + + var result = engine.GetLastSyntaxNode(); + Assert.Equal(SyntaxNodes.Literal, result.Type); + } + + [Fact] + public void ShouldGetParseErrorLocation() + { + var engine = new Engine(); + try + { + engine.Execute("1.2+ new", new ParserOptions { Source = "jQuery.js" }); + } + catch (ParserException e) + { + Assert.Equal(1, e.LineNumber); + Assert.Equal(9, e.Column); + Assert.Equal("jQuery.js", e.Source); + } + } + #region DateParsingAndStrings + [Fact] + public void ParseShouldReturnNumber() + { + var engine = new Engine(); + + var result = engine.Execute("Date.parse('1970-01-01');").GetCompletionValue().AsNumber(); + Assert.Equal(0, result); + } + + [Fact] + public void LocalDateTimeShouldNotLoseTimezone() + { + var date = new DateTime(2016, 1, 1, 13, 0, 0, DateTimeKind.Local); + var engine = new Engine().SetValue("localDate", date); + engine.Execute(@"localDate"); + var actual = engine.GetCompletionValue().AsDate().ToDateTime(); + Assert.Equal(date.ToUniversalTime(), actual.ToUniversalTime()); + Assert.Equal(date.ToLocalTime(), actual.ToLocalTime()); + } + + [Fact] + public void UtcShouldUseUtc() + { + var customTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Central Europe Standard Time"); + + var engine = new Engine(cfg => cfg.LocalTimeZone(customTimeZone)); + + var result = engine.Execute("Date.UTC(1970,0,1)").GetCompletionValue().AsNumber(); + Assert.Equal(0, result); + } + +#if NET451 + [Fact] +#else + [Fact(Skip = "CreateCustomTimeZone not available on netstandard")] +#endif + public void ShouldUseLocalTimeZoneOverride() + { +#if NET451 + const string customName = "Custom Time"; + var customTimeZone = TimeZoneInfo.CreateCustomTimeZone(customName, new TimeSpan(0, 11, 0), customName, customName, customName, null, false); +#else + var customTimeZone = TimeZoneInfo.Utc; +#endif + + var engine = new Engine(cfg => cfg.LocalTimeZone(customTimeZone)); + + var epochGetLocalMinutes = engine.Execute("var d = new Date(0); d.getMinutes();").GetCompletionValue().AsNumber(); + Assert.Equal(11, epochGetLocalMinutes); + + var localEpochGetUtcMinutes = engine.Execute("var d = new Date(1970,0,1); d.getUTCMinutes();").GetCompletionValue().AsNumber(); + Assert.Equal(-11, localEpochGetUtcMinutes); + + var parseLocalEpoch = engine.Execute("Date.parse('January 1, 1970');").GetCompletionValue().AsNumber(); + Assert.Equal(-11 * 60 * 1000, parseLocalEpoch); + + var epochToLocalString = engine.Execute("var d = new Date(0); d.toString();").GetCompletionValue().AsString(); + Assert.Equal("Thu Jan 01 1970 00:11:00 GMT+00:11", epochToLocalString); + + var epochToUTCString = engine.Execute("var d = new Date(0); d.toUTCString();").GetCompletionValue().AsString(); + Assert.Equal("Thu Jan 01 1970 00:00:00 GMT", epochToUTCString); + } + + [Theory] + [InlineData("1970")] + [InlineData("1970-01")] + [InlineData("1970-01-01")] + [InlineData("1970-01-01T00:00")] + [InlineData("1970-01-01T00:00:00")] + [InlineData("1970-01-01T00:00:00.000")] + [InlineData("1970Z")] + [InlineData("1970-1Z")] + [InlineData("1970-1-1Z")] + [InlineData("1970-1-1T0:0Z")] + [InlineData("1970-1-1T0:0:0Z")] + [InlineData("1970-1-1T0:0:0.0Z")] + [InlineData("1970/1Z")] + [InlineData("1970/1/1Z")] + [InlineData("1970/1/1 0:0Z")] + [InlineData("1970/1/1 0:0:0Z")] + [InlineData("1970/1/1 0:0:0.0Z")] + [InlineData("January 1, 1970 GMT")] + [InlineData("1970-01-01T00:00:00.000-00:00")] + public void ShouldParseAsUtc(string date) + { +#if NET451 + const string customName = "Custom Time"; + var customTimeZone = TimeZoneInfo.CreateCustomTimeZone(customName, new TimeSpan(7, 11, 0), customName, customName, customName, null, false); +#else + var customTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Tonga Standard Time"); +#endif + var engine = new Engine(cfg => cfg.LocalTimeZone(customTimeZone)); + + engine.SetValue("d", date); + var result = engine.Execute("Date.parse(d);").GetCompletionValue().AsNumber(); + + Assert.Equal(0, result); + } + +#if NET451 + [Theory] +#else + [Theory(Skip = "CreateCustomTimeZone not available on netstandard")] +#endif + [InlineData("1970/01")] + [InlineData("1970/01/01")] + [InlineData("1970/01/01T00:00")] + [InlineData("1970/01/01 00:00")] + [InlineData("1970-1")] + [InlineData("1970-1-1")] + [InlineData("1970-1-1T0:0")] + [InlineData("1970-1-1 0:0")] + [InlineData("1970/1")] + [InlineData("1970/1/1")] + [InlineData("1970/1/1T0:0")] + [InlineData("1970/1/1 0:0")] + [InlineData("01-1970")] + [InlineData("01-01-1970")] + [InlineData("January 1, 1970")] + [InlineData("1970-01-01T00:00:00.000+00:11")] + public void ShouldParseAsLocalTime(string date) + { + const int timespanMinutes = 11; + const int msPriorMidnight = -timespanMinutes * 60 * 1000; +#if NET451 + const string customName = "Custom Time"; + var customTimeZone = TimeZoneInfo.CreateCustomTimeZone(customName, new TimeSpan(0, timespanMinutes, 0), customName, customName, customName, null, false); +#else + var customTimeZone = TimeZoneInfo.Utc; +#endif + var engine = new Engine(cfg => cfg.LocalTimeZone(customTimeZone)).SetValue("d", date); + + var result = engine.Execute("Date.parse(d);").GetCompletionValue().AsNumber(); + + Assert.Equal(msPriorMidnight, result); + } + + public static System.Collections.Generic.IEnumerable TestDates + { + get + { + yield return new object[] { new DateTime(2000, 1, 1) }; + yield return new object[] { new DateTime(2000, 1, 1, 0, 15, 15, 15) }; + yield return new object[] { new DateTime(2000, 6, 1, 0, 15, 15, 15) }; + yield return new object[] { new DateTime(1900, 1, 1) }; + yield return new object[] { new DateTime(1900, 1, 1, 0, 15, 15, 15) }; + yield return new object[] { new DateTime(1900, 6, 1, 0, 15, 15, 15) }; + } + } + + [Theory, MemberData("TestDates")] + public void TestDateToISOStringFormat(DateTime testDate) + { + var customTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Tonga Standard Time"); + + var engine = new Engine(ctx => ctx.LocalTimeZone(customTimeZone)); + var testDateTimeOffset = new DateTimeOffset(testDate, customTimeZone.GetUtcOffset(testDate)); + engine.Execute( + string.Format("var d = new Date({0},{1},{2},{3},{4},{5},{6});", testDateTimeOffset.Year, testDateTimeOffset.Month - 1, testDateTimeOffset.Day, testDateTimeOffset.Hour, testDateTimeOffset.Minute, testDateTimeOffset.Second, testDateTimeOffset.Millisecond)); + Assert.Equal(testDateTimeOffset.UtcDateTime.ToString("yyyy-MM-dd'T'HH:mm:ss.fff'Z'"), engine.Execute("d.toISOString();").GetCompletionValue().ToString()); + } + + [Theory, MemberData("TestDates")] + public void TestDateToStringFormat(DateTime testDate) + { + var customTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Tonga Standard Time"); + + var engine = new Engine(ctx => ctx.LocalTimeZone(customTimeZone)); + var testDateTimeOffset = new DateTimeOffset(testDate, customTimeZone.GetUtcOffset(testDate)); + engine.Execute( + string.Format("var d = new Date({0},{1},{2},{3},{4},{5},{6});", testDateTimeOffset.Year, testDateTimeOffset.Month - 1, testDateTimeOffset.Day, testDateTimeOffset.Hour, testDateTimeOffset.Minute, testDateTimeOffset.Second, testDateTimeOffset.Millisecond)); + + var expected = testDateTimeOffset.ToString("ddd MMM dd yyyy HH:mm:ss 'GMT'zzz"); + var actual = engine.Execute("d.toString();").GetCompletionValue().ToString(); + + Assert.Equal(expected, actual); + } + + #endregion + + //DateParsingAndStrings + [Fact] + public void EmptyStringShouldMatchRegex() + { + RunTest(@" + var regex = /^(?:$)/g; + assert(''.match(regex) instanceof Array); + "); + } + + [Fact] + public void ShouldExecuteHandlebars() + { + var content = GetEmbeddedFile("handlebars.js"); + + RunTest(content); + + RunTest(@" + var source = 'Hello {{name}}'; + var template = Handlebars.compile(source); + var context = {name: 'Paul'}; + var html = template(context); + + assert('Hello Paul' == html); + "); + } + + [Fact] + public void DateParseReturnsNaN() + { + RunTest(@" + var d = Date.parse('not a date'); + assert(isNaN(d)); + "); + } + + [Fact] + public void ShouldIgnoreHtmlComments() + { + RunTest(@" + var d = Date.parse('not a date'); + assert(isNaN(d)); + "); + } + + [Fact] + public void DateShouldAllowEntireDotNetDateRange() + { + var engine = new Engine(); + + var minValue = engine.Execute("new Date('0001-01-01T00:00:00.000')").GetCompletionValue().ToObject(); + Assert.Equal(new DateTime(1, 1, 1, 0, 0, 0, DateTimeKind.Utc), minValue); + + var maxValue = engine.Execute("new Date('9999-12-31T23:59:59.999')").GetCompletionValue().ToObject(); + Assert.Equal(new DateTime(9999, 12, 31, 23, 59, 59, 999, DateTimeKind.Utc), maxValue); + } + + [Fact] + public void ShouldConstructNewArrayWithInteger() + { + RunTest(@" + var a = new Array(3); + assert(a.length === 3); + assert(a[0] == undefined); + assert(a[1] == undefined); + assert(a[2] == undefined); + "); + } + + [Fact] + public void ShouldConstructNewArrayWithString() + { + RunTest(@" + var a = new Array('foo'); + assert(a.length === 1); + assert(a[0] === 'foo'); + "); + } + + [Fact] + public void ShouldThrowRangeExceptionWhenConstructedWithNonInteger() + { + RunTest(@" + var result = false; + try { + var a = new Array(3.4); + } + catch(e) { + result = e instanceof RangeError; + } + + assert(result); + "); + } + + [Fact] + public void ShouldInitializeArrayWithSingleIngegerValue() + { + RunTest(@" + var a = [3]; + assert(a.length === 1); + assert(a[0] === 3); + "); + } + + [Fact] + public void ShouldInitializeJsonObjectArrayWithSingleIntegerValue() + { + RunTest(@" + var x = JSON.parse('{ ""a"": [3] }'); + assert(x.a.length === 1); + assert(x.a[0] === 3); + "); + } + + [Fact] + public void ShouldInitializeJsonArrayWithSingleIntegerValue() + { + RunTest(@" + var a = JSON.parse('[3]'); + assert(a.length === 1); + assert(a[0] === 3); + "); + } + + [Fact] + public void ShouldReturnTrueForEmptyIsNaNStatement() + { + RunTest(@" + assert(true === isNaN()); + "); + } + + [Theory] + [InlineData(4d, 0, "4")] + [InlineData(4d, 1, "4.0")] + [InlineData(4d, 2, "4.00")] + [InlineData(28.995, 2, "29.00")] + [InlineData(-28.995, 2, "-29.00")] + [InlineData(-28.495, 2, "-28.50")] + [InlineData(-28.445, 2, "-28.45")] + [InlineData(28.445, 2, "28.45")] + [InlineData(10.995, 0, "11")] + public void ShouldRoundToFixedDecimal(double number, int fractionDigits, string result) + { + var engine = new Engine(); + var value = engine.Execute( + String.Format("new Number({0}).toFixed({1})", + number.ToString(CultureInfo.InvariantCulture), + fractionDigits.ToString(CultureInfo.InvariantCulture))) + .GetCompletionValue().ToObject(); + + Assert.Equal(value, result); + } + + + + [Fact] + public void ShouldSortArrayWhenCompareFunctionReturnsFloatingPointNumber() + { + RunTest(@" + var nums = [1, 1.1, 1.2, 2, 2, 2.1, 2.2]; + nums.sort(function(a,b){return b-a;}); + assert(nums[0] === 2.2); + assert(nums[1] === 2.1); + assert(nums[2] === 2); + assert(nums[3] === 2); + assert(nums[4] === 1.2); + assert(nums[5] === 1.1); + assert(nums[6] === 1); + "); + } + + [Fact] + public void ShouldBreakWhenBreakpointIsReached() + { + countBreak = 0; + stepMode = StepMode.None; + + var engine = new Engine(options => options.DebugMode()); + + engine.Break += EngineStep; + + engine.BreakPoints.Add(new BreakPoint(1, 1)); + + engine.Execute(@"var local = true; + if (local === true) + {}"); + + engine.Break -= EngineStep; + + Assert.Equal(1, countBreak); + } + + [Fact] + public void ShouldExecuteStepByStep() + { + countBreak = 0; + stepMode = StepMode.Into; + + var engine = new Engine(options => options.DebugMode()); + + engine.Step += EngineStep; + + engine.Execute(@"var local = true; + var creatingSomeOtherLine = 0; + var lastOneIPromise = true"); + + engine.Step -= EngineStep; + + Assert.Equal(3, countBreak); + } + + [Fact] + public void ShouldNotBreakTwiceIfSteppingOverBreakpoint() + { + countBreak = 0; + stepMode = StepMode.Into; + + var engine = new Engine(options => options.DebugMode()); + engine.BreakPoints.Add(new BreakPoint(1, 1)); + engine.Step += EngineStep; + engine.Break += EngineStep; + + engine.Execute(@"var local = true;"); + + engine.Step -= EngineStep; + engine.Break -= EngineStep; + + Assert.Equal(1, countBreak); + } + + private StepMode EngineStep(object sender, DebugInformation debugInfo) + { + Assert.NotNull(sender); + Assert.IsType(typeof(Engine), sender); + Assert.NotNull(debugInfo); + + countBreak++; + return stepMode; + } + + [Fact] + public void ShouldShowProperDebugInformation() + { + countBreak = 0; + stepMode = StepMode.None; + + var engine = new Engine(options => options.DebugMode()); + engine.BreakPoints.Add(new BreakPoint(5, 0)); + engine.Break += EngineStepVerifyDebugInfo; + + engine.Execute(@"var global = true; + function func1() + { + var local = false; +; + } + func1();"); + + engine.Break -= EngineStepVerifyDebugInfo; + + Assert.Equal(1, countBreak); + } + + private StepMode EngineStepVerifyDebugInfo(object sender, DebugInformation debugInfo) + { + Assert.NotNull(sender); + Assert.IsType(typeof(Engine), sender); + Assert.NotNull(debugInfo); + + Assert.NotNull(debugInfo.CallStack); + Assert.NotNull(debugInfo.CurrentStatement); + Assert.NotNull(debugInfo.Locals); + + Assert.Single(debugInfo.CallStack); + Assert.Equal("func1()", debugInfo.CallStack.Peek()); + Assert.Contains(debugInfo.Globals, kvp => kvp.Key.Equals("global", StringComparison.Ordinal) && kvp.Value.AsBoolean() == true); + Assert.Contains(debugInfo.Globals, kvp => kvp.Key.Equals("local", StringComparison.Ordinal) && kvp.Value.AsBoolean() == false); + Assert.Contains(debugInfo.Locals, kvp => kvp.Key.Equals("local", StringComparison.Ordinal) && kvp.Value.AsBoolean() == false); + Assert.DoesNotContain(debugInfo.Locals, kvp => kvp.Key.Equals("global", StringComparison.Ordinal)); + + countBreak++; + return stepMode; + } + + [Fact] + public void ShouldBreakWhenConditionIsMatched() + { + countBreak = 0; + stepMode = StepMode.None; + + var engine = new Engine(options => options.DebugMode()); + + engine.Break += EngineStep; + + engine.BreakPoints.Add(new BreakPoint(5, 16, "condition === true")); + engine.BreakPoints.Add(new BreakPoint(6, 16, "condition === false")); + + engine.Execute(@"var local = true; + var condition = true; + if (local === true) + { + ; + ; + }"); + + engine.Break -= EngineStep; + + Assert.Equal(1, countBreak); + } + + [Fact] + public void ShouldNotStepInSameLevelStatementsWhenStepOut() + { + countBreak = 0; + stepMode = StepMode.Out; + + var engine = new Engine(options => options.DebugMode()); + + engine.Step += EngineStep; + + engine.Execute(@"function func() // first step - then stepping out + { + ; // shall not step + ; // not even here + } + func(); // shall not step + ; // shall not step "); + + engine.Step -= EngineStep; + + Assert.Equal(1, countBreak); + } + + [Fact] + public void ShouldNotStepInIfRequiredToStepOut() + { + countBreak = 0; + + var engine = new Engine(options => options.DebugMode()); + + engine.Step += EngineStepOutWhenInsideFunction; + + engine.Execute(@"function func() // first step + { + ; // third step - now stepping out + ; // it should not step here + } + func(); // second step + ; // fourth step "); + + engine.Step -= EngineStepOutWhenInsideFunction; + + Assert.Equal(4, countBreak); + } + + private StepMode EngineStepOutWhenInsideFunction(object sender, DebugInformation debugInfo) + { + Assert.NotNull(sender); + Assert.IsType(typeof(Engine), sender); + Assert.NotNull(debugInfo); + + countBreak++; + if (debugInfo.CallStack.Count > 0) + return StepMode.Out; + + return StepMode.Into; + } + + [Fact] + public void ShouldBreakWhenStatementIsMultiLine() + { + countBreak = 0; + stepMode = StepMode.None; + + var engine = new Engine(options => options.DebugMode()); + engine.BreakPoints.Add(new BreakPoint(4, 33)); + engine.Break += EngineStep; + + engine.Execute(@"var global = true; + function func1() + { + var local = + false; + } + func1();"); + + engine.Break -= EngineStep; + + Assert.Equal(1, countBreak); + } + + [Fact] + public void ShouldNotStepInsideIfRequiredToStepOver() + { + countBreak = 0; + + var engine = new Engine(options => options.DebugMode()); + + stepMode = StepMode.Over; + engine.Step += EngineStep; + + engine.Execute(@"function func() // first step + { + ; // third step - it shall not step here + ; // it shall not step here + } + func(); // second step + ; // third step "); + + engine.Step -= EngineStep; + + Assert.Equal(3, countBreak); + } + + [Fact] + public void ShouldStepAllStatementsWithoutInvocationsIfStepOver() + { + countBreak = 0; + + var engine = new Engine(options => options.DebugMode()); + + stepMode = StepMode.Over; + engine.Step += EngineStep; + + engine.Execute(@"var step1 = 1; // first step + var step2 = 2; // second step + if (step1 !== step2) // third step + { // fourth step + ; // fifth step + }"); + + engine.Step -= EngineStep; + + Assert.Equal(5, countBreak); + } + + [Fact] + public void ShouldEvaluateVariableAssignmentFromLeftToRight() + { + RunTest(@" + var keys = ['a'] + , source = { a: 3} + , target = {} + , key + , i = 0; + target[key = keys[i++]] = source[key]; + assert(i == 1); + assert(key == 'a'); + assert(target[key] == 3); + "); + } + + [Fact] + public void ObjectShouldBeExtensible() + { + RunTest(@" + try { + Object.defineProperty(Object.defineProperty, 'foo', { value: 1 }); + } + catch(e) { + assert(false); + } + "); + } + + [Fact] + public void ArrayIndexShouldBeConvertedToUint32() + { + // This is missing from ECMA tests suite + // http://www.ecma-international.org/ecma-262/5.1/#sec-15.4 + + RunTest(@" + var a = [ 'foo' ]; + assert(a[0] === 'foo'); + assert(a['0'] === 'foo'); + assert(a['00'] === undefined); + "); + } + + [Fact] + public void DatePrototypeFunctionWorkOnDateOnly() + { + RunTest(@" + try { + var myObj = Object.create(Date.prototype); + myObj.toDateString(); + } catch (e) { + assert(e instanceof TypeError); + } + "); + } + + [Fact] + public void DateToStringMethodsShouldUseCurrentTimeZoneAndCulture() + { + // Forcing to PDT and FR for tests + // var PDT = TimeZoneInfo.CreateCustomTimeZone("Pacific Daylight Time", new TimeSpan(-7, 0, 0), "Pacific Daylight Time", "Pacific Daylight Time"); + var PDT = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"); + var FR = new CultureInfo("fr-FR"); + + var engine = new Engine(options => options.LocalTimeZone(PDT).Culture(FR)) + .SetValue("log", new Action(Console.WriteLine)) + .SetValue("assert", new Action(Assert.True)) + .SetValue("equal", new Action(Assert.Equal)) + ; + + engine.Execute(@" + var d = new Date(1433160000000); + + equal('Mon Jun 01 2015 05:00:00 GMT-07:00', d.toString()); + equal('Mon Jun 01 2015', d.toDateString()); + equal('05:00:00 GMT-07:00', d.toTimeString()); + equal('lundi 1 juin 2015 05:00:00', d.toLocaleString()); + equal('lundi 1 juin 2015', d.toLocaleDateString()); + equal('05:00:00', d.toLocaleTimeString()); + "); + } + + [Fact] + public void DateShouldHonorTimezoneDaylightSavingRules() + { + var EST = TimeZoneInfo.FindSystemTimeZoneById("US Eastern Standard Time"); + var engine = new Engine(options => options.LocalTimeZone(EST)) + .SetValue("log", new Action(Console.WriteLine)) + .SetValue("assert", new Action(Assert.True)) + .SetValue("equal", new Action(Assert.Equal)) + ; + + engine.Execute(@" + var d = new Date(2016, 8, 1); + + equal('Thu Sep 01 2016 00:00:00 GMT-04:00', d.toString()); + equal('Thu Sep 01 2016', d.toDateString()); + "); + } + + [Fact] + public void DateShouldParseToString() + { + // Forcing to PDT and FR for tests + // var PDT = TimeZoneInfo.CreateCustomTimeZone("Pacific Daylight Time", new TimeSpan(-7, 0, 0), "Pacific Daylight Time", "Pacific Daylight Time"); + var PDT = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"); + var FR = new CultureInfo("fr-FR"); + + new Engine(options => options.LocalTimeZone(PDT).Culture(FR)) + .SetValue("log", new Action(Console.WriteLine)) + .SetValue("assert", new Action(Assert.True)) + .SetValue("equal", new Action(Assert.Equal)) + .Execute(@" + var d = new Date(1433160000000); + equal(Date.parse(d.toString()), d.valueOf()); + equal(Date.parse(d.toLocaleString()), d.valueOf()); + "); + } + + [Fact] + public void LocaleNumberShouldUseLocalCulture() + { + // Forcing to PDT and FR for tests + // var PDT = TimeZoneInfo.CreateCustomTimeZone("Pacific Daylight Time", new TimeSpan(-7, 0, 0), "Pacific Daylight Time", "Pacific Daylight Time"); + var PDT = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"); + var FR = new CultureInfo("fr-FR"); + + new Engine(options => options.LocalTimeZone(PDT).Culture(FR)) + .SetValue("log", new Action(Console.WriteLine)) + .SetValue("assert", new Action(Assert.True)) + .SetValue("equal", new Action(Assert.Equal)) + .Execute(@" + var d = new Number(-1.23); + equal('-1.23', d.toString()); + equal('-1,23', d.toLocaleString()); + "); + } + + [Fact] + public void DateCtorShouldAcceptDate() + { + RunTest(@" + var a = new Date(); + var b = new Date(a); + assert(String(a) === String(b)); + "); + } + + [Fact] + public void RegExpResultIsMutable() + { + RunTest(@" + var match = /quick\s(brown).+?(jumps)/ig.exec('The Quick Brown Fox Jumps Over The Lazy Dog'); + var result = match.shift(); + assert(result === 'Quick Brown Fox Jumps'); + "); + } + + [Fact] + public void RegExpSupportsMultiline() + { + RunTest(@" + var rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg; + var headersString = 'X-AspNetMvc-Version: 4.0\r\nX-Powered-By: ASP.NET\r\n\r\n'; + match = rheaders.exec(headersString); + assert('X-AspNetMvc-Version' === match[1]); + assert('4.0' === match[2]); + "); + + RunTest(@" + var rheaders = /^(.*?):[ \t]*(.*?)$/mg; + var headersString = 'X-AspNetMvc-Version: 4.0\r\nX-Powered-By: ASP.NET\r\n\r\n'; + match = rheaders.exec(headersString); + assert('X-AspNetMvc-Version' === match[1]); + assert('4.0' === match[2]); + "); + + RunTest(@" + var rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg; + var headersString = 'X-AspNetMvc-Version: 4.0\nX-Powered-By: ASP.NET\n\n'; + match = rheaders.exec(headersString); + assert('X-AspNetMvc-Version' === match[1]); + assert('4.0' === match[2]); + "); + } + + [Fact] + public void ShouldSetYearBefore1970() + { + + RunTest(@" + var d = new Date('1969-01-01T08:17:00'); + d.setYear(2015); + equal('2015-01-01T08:17:00.000Z', d.toISOString()); + "); + } + + [Fact] + public void ExceptionShouldHaveLocationOfInnerFunction() + { + try + { + new Engine() + .Execute(@" + function test(s) { + o.boom(); + } + test('arg'); + "); + } + catch (JavaScriptException ex) + { + Assert.Equal(3, ex.LineNumber); + } + } + + [Fact] + public void GlobalRegexLiteralShouldNotKeepState() + { + RunTest(@" + var url = 'https://www.example.com'; + + assert(isAbsolutePath(url)); + assert(isAbsolutePath(url)); + assert(isAbsolutePath(url)); + + function isAbsolutePath(path) { + return /\.+/g.test(path); + } + "); + } + + [Fact] + public void ShouldCompareInnerValueOfClrInstances() + { + var engine = new Engine(); + + // Create two separate Guid with identical inner values. + var guid1 = Guid.NewGuid(); + var guid2 = new Guid(guid1.ToString()); + + engine.SetValue("guid1", guid1); + engine.SetValue("guid2", guid2); + + var result = engine.Execute("guid1 == guid2").GetCompletionValue().AsBoolean(); + + Assert.True(result); + } + + [Fact] + public void ShouldStringifyNumWithoutV8DToA() + { + // 53.6841659 cannot be converted by V8's DToA => "old" DToA code will be used. + + var engine = new Engine(); + Native.JsValue val = engine.Execute("JSON.stringify(53.6841659)").GetCompletionValue(); + + Assert.True(val.AsString() == "53.6841659"); + } + + [Theory] + [InlineData("", "escape('')")] + [InlineData("%u0100%u0101%u0102", "escape('\u0100\u0101\u0102')")] + [InlineData("%uFFFD%uFFFE%uFFFF", "escape('\ufffd\ufffe\uffff')")] + [InlineData("%uD834%uDF06", "escape('\ud834\udf06')")] + [InlineData("%00%01%02%03", "escape('\x00\x01\x02\x03')")] + [InlineData("%2C", "escape(',')")] + [InlineData("%3A%3B%3C%3D%3E%3F", "escape(':;<=>?')")] + [InlineData("%60", "escape('`')")] + [InlineData("%7B%7C%7D%7E%7F%80", "escape('{|}~\x7f\x80')")] + [InlineData("%FD%FE%FF", "escape('\xfd\xfe\xff')")] + [InlineData("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_+-./", "escape('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_+-./')")] + public void ShouldEvaluateEscape(object expected, string source) + { + var engine = new Engine(); + var result = engine.Execute(source).GetCompletionValue().ToObject(); + + Assert.Equal(expected, result); + } + + [Theory] + //https://github.com/tc39/test262/blob/master/test/annexB/built-ins/unescape/empty-string.js + [InlineData("", "unescape('')")] + //https://github.com/tc39/test262/blob/master/test/annexB/built-ins/unescape/four-ignore-bad-u.js + [InlineData("%U0000", "unescape('%U0000')")] + [InlineData("%t0000", "unescape('%t0000')")] + [InlineData("%v0000", "unescape('%v0000')")] + [InlineData("%" + "\x00" + "00", "unescape('%%0000')")] + //https://github.com/tc39/test262/blob/master/test/annexB/built-ins/unescape/four-ignore-end-str.js + [InlineData("%u", "unescape('%u')")] + [InlineData("%u0", "unescape('%u0')")] + [InlineData("%u1", "unescape('%u1')")] + [InlineData("%u2", "unescape('%u2')")] + [InlineData("%u3", "unescape('%u3')")] + [InlineData("%u4", "unescape('%u4')")] + [InlineData("%u5", "unescape('%u5')")] + [InlineData("%u6", "unescape('%u6')")] + [InlineData("%u7", "unescape('%u7')")] + [InlineData("%u8", "unescape('%u8')")] + [InlineData("%u9", "unescape('%u9')")] + [InlineData("%ua", "unescape('%ua')")] + [InlineData("%uA", "unescape('%uA')")] + [InlineData("%ub", "unescape('%ub')")] + [InlineData("%uB", "unescape('%uB')")] + [InlineData("%uc", "unescape('%uc')")] + [InlineData("%uC", "unescape('%uC')")] + [InlineData("%ud", "unescape('%ud')")] + [InlineData("%uD", "unescape('%uD')")] + [InlineData("%ue", "unescape('%ue')")] + [InlineData("%uE", "unescape('%uE')")] + [InlineData("%uf", "unescape('%uf')")] + [InlineData("%uF", "unescape('%uF')")] + [InlineData("%u01", "unescape('%u01')")] + [InlineData("%u02", "unescape('%u02')")] + [InlineData("%u03", "unescape('%u03')")] + [InlineData("%u04", "unescape('%u04')")] + [InlineData("%u05", "unescape('%u05')")] + [InlineData("%u06", "unescape('%u06')")] + [InlineData("%u07", "unescape('%u07')")] + [InlineData("%u08", "unescape('%u08')")] + [InlineData("%u09", "unescape('%u09')")] + [InlineData("%u0a", "unescape('%u0a')")] + [InlineData("%u0A", "unescape('%u0A')")] + [InlineData("%u0b", "unescape('%u0b')")] + [InlineData("%u0B", "unescape('%u0B')")] + [InlineData("%u0c", "unescape('%u0c')")] + [InlineData("%u0C", "unescape('%u0C')")] + [InlineData("%u0d", "unescape('%u0d')")] + [InlineData("%u0D", "unescape('%u0D')")] + [InlineData("%u0e", "unescape('%u0e')")] + [InlineData("%u0E", "unescape('%u0E')")] + [InlineData("%u0f", "unescape('%u0f')")] + [InlineData("%u0F", "unescape('%u0F')")] + [InlineData("%u000", "unescape('%u000')")] + [InlineData("%u001", "unescape('%u001')")] + [InlineData("%u002", "unescape('%u002')")] + [InlineData("%u003", "unescape('%u003')")] + [InlineData("%u004", "unescape('%u004')")] + [InlineData("%u005", "unescape('%u005')")] + [InlineData("%u006", "unescape('%u006')")] + [InlineData("%u007", "unescape('%u007')")] + [InlineData("%u008", "unescape('%u008')")] + [InlineData("%u009", "unescape('%u009')")] + [InlineData("%u00a", "unescape('%u00a')")] + [InlineData("%u00A", "unescape('%u00A')")] + [InlineData("%u00b", "unescape('%u00b')")] + [InlineData("%u00B", "unescape('%u00B')")] + [InlineData("%u00c", "unescape('%u00c')")] + [InlineData("%u00C", "unescape('%u00C')")] + [InlineData("%u00d", "unescape('%u00d')")] + [InlineData("%u00D", "unescape('%u00D')")] + [InlineData("%u00e", "unescape('%u00e')")] + [InlineData("%u00E", "unescape('%u00E')")] + [InlineData("%u00f", "unescape('%u00f')")] + [InlineData("%u00F", "unescape('%u00F')")] + //https://github.com/tc39/test262/blob/master/test/annexB/built-ins/unescape/four-ignore-non-hex.js + [InlineData("%u000%0", "unescape('%u000%0')")] + [InlineData("%u000g0", "unescape('%u000g0')")] + [InlineData("%u000G0", "unescape('%u000G0')")] + [InlineData("%u00g00", "unescape('%u00g00')")] + [InlineData("%u00G00", "unescape('%u00G00')")] + [InlineData("%u0g000", "unescape('%u0g000')")] + [InlineData("%u0G000", "unescape('%u0G000')")] + [InlineData("%ug0000", "unescape('%ug0000')")] + [InlineData("%uG0000", "unescape('%uG0000')")] + [InlineData("%u000u0", "unescape('%u000u0')")] + [InlineData("%u000U0", "unescape('%u000U0')")] + [InlineData("%u00u00", "unescape('%u00u00')")] + [InlineData("%u00U00", "unescape('%u00U00')")] + [InlineData("%u0u000", "unescape('%u0u000')")] + [InlineData("%u0U000", "unescape('%u0U000')")] + [InlineData("%uu0000", "unescape('%uu0000')")] + [InlineData("%uU0000", "unescape('%uU0000')")] + //https://github.com/tc39/test262/blob/master/test/annexB/built-ins/unescape/four.js + [InlineData("%0" + "\x00" + "0", "unescape('%0%u00000')")] + [InlineData("%0" + "\x01" + "0", "unescape('%0%u00010')")] + [InlineData("%0)0", "unescape('%0%u00290')")] + [InlineData("%0*0", "unescape('%0%u002a0')")] + [InlineData("%0*0", "unescape('%0%u002A0')")] + [InlineData("%0+0", "unescape('%0%u002b0')")] + [InlineData("%0+0", "unescape('%0%u002B0')")] + [InlineData("%0,0", "unescape('%0%u002c0')")] + [InlineData("%0,0", "unescape('%0%u002C0')")] + [InlineData("%0-0", "unescape('%0%u002d0')")] + [InlineData("%0-0", "unescape('%0%u002D0')")] + [InlineData("%090", "unescape('%0%u00390')")] + [InlineData("%0:0", "unescape('%0%u003a0')")] + [InlineData("%0:0", "unescape('%0%u003A0')")] + [InlineData("%0?0", "unescape('%0%u003f0')")] + [InlineData("%0?0", "unescape('%0%u003F0')")] + [InlineData("%0@0", "unescape('%0%u00400')")] + [InlineData("%0Z0", "unescape('%0%u005a0')")] + [InlineData("%0Z0", "unescape('%0%u005A0')")] + [InlineData("%0[0", "unescape('%0%u005b0')")] + [InlineData("%0[0", "unescape('%0%u005B0')")] + [InlineData("%0^0", "unescape('%0%u005e0')")] + [InlineData("%0^0", "unescape('%0%u005E0')")] + [InlineData("%0_0", "unescape('%0%u005f0')")] + [InlineData("%0_0", "unescape('%0%u005F0')")] + [InlineData("%0`0", "unescape('%0%u00600')")] + [InlineData("%0a0", "unescape('%0%u00610')")] + [InlineData("%0z0", "unescape('%0%u007a0')")] + [InlineData("%0z0", "unescape('%0%u007A0')")] + [InlineData("%0{0", "unescape('%0%u007b0')")] + [InlineData("%0{0", "unescape('%0%u007B0')")] + [InlineData("%0" + "\ufffe" + "0", "unescape('%0%ufffe0')")] + [InlineData("%0" + "\ufffe" + "0", "unescape('%0%uFffe0')")] + [InlineData("%0" + "\ufffe" + "0", "unescape('%0%ufFfe0')")] + [InlineData("%0" + "\ufffe" + "0", "unescape('%0%uffFe0')")] + [InlineData("%0" + "\ufffe" + "0", "unescape('%0%ufffE0')")] + [InlineData("%0" + "\ufffe" + "0", "unescape('%0%uFFFE0')")] + [InlineData("%0" + "\uffff" + "0", "unescape('%0%uffff0')")] + [InlineData("%0" + "\uffff" + "0", "unescape('%0%uFfff0')")] + [InlineData("%0" + "\uffff" + "0", "unescape('%0%ufFff0')")] + [InlineData("%0" + "\uffff" + "0", "unescape('%0%uffFf0')")] + [InlineData("%0" + "\uffff" + "0", "unescape('%0%ufffF0')")] + [InlineData("%0" + "\uffff" + "0", "unescape('%0%uFFFF0')")] + //https://github.com/tc39/test262/blob/master/test/annexB/built-ins/unescape/two-ignore-end-str.js + [InlineData("%", "unescape('%')")] + [InlineData("%0", "unescape('%0')")] + [InlineData("%1", "unescape('%1')")] + [InlineData("%2", "unescape('%2')")] + [InlineData("%3", "unescape('%3')")] + [InlineData("%4", "unescape('%4')")] + [InlineData("%5", "unescape('%5')")] + [InlineData("%6", "unescape('%6')")] + [InlineData("%7", "unescape('%7')")] + [InlineData("%8", "unescape('%8')")] + [InlineData("%9", "unescape('%9')")] + [InlineData("%a", "unescape('%a')")] + [InlineData("%A", "unescape('%A')")] + [InlineData("%b", "unescape('%b')")] + [InlineData("%B", "unescape('%B')")] + [InlineData("%c", "unescape('%c')")] + [InlineData("%C", "unescape('%C')")] + [InlineData("%d", "unescape('%d')")] + [InlineData("%D", "unescape('%D')")] + [InlineData("%e", "unescape('%e')")] + [InlineData("%E", "unescape('%E')")] + [InlineData("%f", "unescape('%f')")] + [InlineData("%F", "unescape('%F')")] + //https://github.com/tc39/test262/blob/master/test/annexB/built-ins/unescape/two-ignore-non-hex.js + [InlineData("%0%0", "unescape('%0%0')")] + [InlineData("%0g0", "unescape('%0g0')")] + [InlineData("%0G0", "unescape('%0G0')")] + [InlineData("%g00", "unescape('%g00')")] + [InlineData("%G00", "unescape('%G00')")] + [InlineData("%0u0", "unescape('%0u0')")] + [InlineData("%0U0", "unescape('%0U0')")] + [InlineData("%u00", "unescape('%u00')")] + [InlineData("%U00", "unescape('%U00')")] + //https://github.com/tc39/test262/blob/master/test/annexB/built-ins/unescape/two.js + [InlineData("%0" + "\x00" + "00", "unescape('%0%0000')")] + [InlineData("%0" + "\x01" + "00", "unescape('%0%0100')")] + [InlineData("%0)00", "unescape('%0%2900')")] + [InlineData("%0*00", "unescape('%0%2a00')")] + [InlineData("%0*00", "unescape('%0%2A00')")] + [InlineData("%0+00", "unescape('%0%2b00')")] + [InlineData("%0+00", "unescape('%0%2B00')")] + [InlineData("%0,00", "unescape('%0%2c00')")] + [InlineData("%0,00", "unescape('%0%2C00')")] + [InlineData("%0-00", "unescape('%0%2d00')")] + [InlineData("%0-00", "unescape('%0%2D00')")] + [InlineData("%0900", "unescape('%0%3900')")] + [InlineData("%0:00", "unescape('%0%3a00')")] + [InlineData("%0:00", "unescape('%0%3A00')")] + [InlineData("%0?00", "unescape('%0%3f00')")] + [InlineData("%0?00", "unescape('%0%3F00')")] + [InlineData("%0@00", "unescape('%0%4000')")] + [InlineData("%0Z00", "unescape('%0%5a00')")] + [InlineData("%0Z00", "unescape('%0%5A00')")] + [InlineData("%0[00", "unescape('%0%5b00')")] + [InlineData("%0[00", "unescape('%0%5B00')")] + [InlineData("%0^00", "unescape('%0%5e00')")] + [InlineData("%0^00", "unescape('%0%5E00')")] + [InlineData("%0_00", "unescape('%0%5f00')")] + [InlineData("%0_00", "unescape('%0%5F00')")] + [InlineData("%0`00", "unescape('%0%6000')")] + [InlineData("%0a00", "unescape('%0%6100')")] + [InlineData("%0z00", "unescape('%0%7a00')")] + [InlineData("%0z00", "unescape('%0%7A00')")] + [InlineData("%0{00", "unescape('%0%7b00')")] + [InlineData("%0{00", "unescape('%0%7B00')")] + public void ShouldEvaluateUnescape(object expected, string source) + { + var engine = new Engine(); + var result = engine.Execute(source).GetCompletionValue().ToObject(); + + Assert.Equal(expected, result); + } + + [Theory] + [InlineData("new Date(1969,0,1,19,45,30,500).getHours()", 19)] + [InlineData("new Date(1970,0,1,19,45,30,500).getHours()", 19)] + [InlineData("new Date(1971,0,1,19,45,30,500).getHours()", 19)] + [InlineData("new Date(1969,0,1,19,45,30,500).getMinutes()", 45)] + [InlineData("new Date(1970,0,1,19,45,30,500).getMinutes()", 45)] + [InlineData("new Date(1971,0,1,19,45,30,500).getMinutes()", 45)] + [InlineData("new Date(1969,0,1,19,45,30,500).getSeconds()", 30)] + [InlineData("new Date(1970,0,1,19,45,30,500).getSeconds()", 30)] + [InlineData("new Date(1971,0,1,19,45,30,500).getSeconds()", 30)] + //[InlineData("new Date(1969,0,1,19,45,30,500).getMilliseconds()", 500)] + //[InlineData("new Date(1970,0,1,19,45,30,500).getMilliseconds()", 500)] + //[InlineData("new Date(1971,0,1,19,45,30,500).getMilliseconds()", 500)] + public void ShouldExtractDateParts(string source, double expected) + { + var engine = new Engine(); + var result = engine.Execute(source).GetCompletionValue().ToObject(); + + Assert.Equal(expected, result); + } + + [Theory] + [InlineData("'abc'.padStart(10)", " abc")] + [InlineData("'abc'.padStart(10, \"foo\")", "foofoofabc")] + [InlineData("'abc'.padStart(6, \"123456\")", "123abc")] + [InlineData("'abc'.padStart(8, \"0\")", "00000abc")] + [InlineData("'abc'.padStart(1)", "abc")] + public void ShouldPadStart(string source, object expected) + { + var engine = new Engine(); + var result = engine.Execute(source).GetCompletionValue().ToObject(); + + Assert.Equal(expected, result); + } + + [Theory] + [InlineData("'abc'.padEnd(10)", "abc ")] + [InlineData("'abc'.padEnd(10, \"foo\")", "abcfoofoof")] + [InlineData("'abc'.padEnd(6, \"123456\")", "abc123")] + [InlineData("'abc'.padEnd(1)", "abc")] + public void ShouldPadEnd(string source, object expected) + { + var engine = new Engine(); + var result = engine.Execute(source).GetCompletionValue().ToObject(); + + Assert.Equal(expected, result); + } + } +} diff --git a/Jint.Tests/Runtime/ErrorTests.cs b/Jint.Tests/Runtime/ErrorTests.cs new file mode 100644 index 0000000000..0024769b2a --- /dev/null +++ b/Jint.Tests/Runtime/ErrorTests.cs @@ -0,0 +1,68 @@ +using System; +using Jint.Parser; +using Jint.Runtime; +using Xunit; + +namespace Jint.Tests.Runtime +{ + public class ErrorTests + { + [Fact] + public void CanReturnCorrectErrorMessageAndLocation1() + { + var script = @" +var a = {}; + +var b = a.user.name; +"; + + var engine = new Engine(); + var e = Assert.Throws(() => engine.Execute(script)); + Assert.Equal("user is undefined", e.Message); + Assert.Equal(4, e.Location.Start.Line); + Assert.Equal(8, e.Location.Start.Column); + } + + [Fact] + public void CanReturnCorrectErrorMessageAndLocation2() + { + var script = @" + test(); +"; + + var engine = new Engine(); + var e = Assert.Throws(() => engine.Execute(script)); + Assert.Equal("test is not defined", e.Message); + Assert.Equal(2, e.Location.Start.Line); + Assert.Equal(1, e.Location.Start.Column); + } + + [Fact] + public void CanProduceCorrectStackTrace() + { + var engine = new Engine(options => options.LimitRecursion(1000)); + + engine.Execute(@"var a = function(v) { + return v.xxx.yyy; +} + +var b = function(v) { + return a(v); +}", new ParserOptions + { + Source = "custom.js" + }); + + var e = Assert.Throws(() => engine.Execute("var x = b(7);", new ParserOptions { Source = "main.js"})); + Assert.Equal("xxx is undefined", e.Message); + Assert.Equal(2, e.Location.Start.Line); + Assert.Equal(8, e.Location.Start.Column); + Assert.Equal("custom.js", e.Location.Source); + + var stack = e.CallStack; + Assert.Equal(@" at a(v) @ custom.js 8:6 + at b(7) @ main.js 8:1 +".Replace("\r\n", "\n"), stack.Replace("\r\n", "\n")); + } + } +} \ No newline at end of file diff --git a/Jint.Tests/Runtime/InteropTests.cs b/Jint.Tests/Runtime/InteropTests.cs index e5f9ec0879..6e67fb6f4f 100644 --- a/Jint.Tests/Runtime/InteropTests.cs +++ b/Jint.Tests/Runtime/InteropTests.cs @@ -1,104 +1,216 @@ -using System; -using System.Collections.Generic; -using Jint.Native; -using Jint.Native.Object; -using Jint.Tests.Runtime.Converters; -using Jint.Tests.Runtime.Domain; -using Shapes; -using Xunit; - -namespace Jint.Tests.Runtime -{ - public class InteropTests : IDisposable - { - private readonly Engine _engine; - - public InteropTests() - { - _engine = new Engine(cfg => cfg.AllowClr(typeof(Shape).Assembly)) - .SetValue("log", new Action(Console.WriteLine)) - .SetValue("assert", new Action(Assert.True)) - ; - } - - void IDisposable.Dispose() - { - } - - private void RunTest(string source) - { - _engine.Execute(source); - } - - [Fact] - public void PrimitiveTypesCanBeSet() - { - _engine.SetValue("x", 10); - _engine.SetValue("y", true); - _engine.SetValue("z", "foo"); - - RunTest(@" - assert(x === 10); - assert(y === true); - assert(z === 'foo'); - "); - } - - [Fact] - public void DelegatesCanBeSet() - { - _engine.SetValue("square", new Func(x => x * x)); - - RunTest(@" - assert(square(10) === 100); - "); - } - - [Fact] - public void CanGetObjectProperties() - { - var p = new Person - { - Name = "Mickey Mouse" - }; - - _engine.SetValue("p", p); - - RunTest(@" - assert(p.Name === 'Mickey Mouse'); - "); - } - - [Fact] - public void CanInvokeObjectMethods() - { - var p = new Person - { - Name = "Mickey Mouse" - }; - - _engine.SetValue("p", p); - - RunTest(@" - assert(p.ToString() === 'Mickey Mouse'); - "); - } - - [Fact] - public void CanSetObjectProperties() - { - var p = new Person - { - Name = "Mickey Mouse" - }; - - _engine.SetValue("p", p); - - RunTest(@" - p.Name = 'Donald Duck'; - assert(p.Name === 'Donald Duck'); - "); - +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Reflection; +using Jint.Native; +using Jint.Native.Object; +using Jint.Tests.Runtime.Converters; +using Jint.Tests.Runtime.Domain; +using Shapes; +using Xunit; + +namespace Jint.Tests.Runtime +{ + public class InteropTests : IDisposable + { + private readonly Engine _engine; + + public InteropTests() + { + _engine = new Engine(cfg => cfg.AllowClr( + typeof(Shape).GetTypeInfo().Assembly, + typeof(System.IO.File).GetTypeInfo().Assembly)) + .SetValue("log", new Action(Console.WriteLine)) + .SetValue("assert", new Action(Assert.True)) + .SetValue("equal", new Action(Assert.Equal)) + ; + } + + void IDisposable.Dispose() + { + } + + private void RunTest(string source) + { + _engine.Execute(source); + } + + [Fact] + public void PrimitiveTypesCanBeSet() + { + _engine.SetValue("x", 10); + _engine.SetValue("y", true); + _engine.SetValue("z", "foo"); + + RunTest(@" + assert(x === 10); + assert(y === true); + assert(z === 'foo'); + "); + } + + [Fact] + public void DelegatesCanBeSet() + { + _engine.SetValue("square", new Func(x => x * x)); + + RunTest(@" + assert(square(10) === 100); + "); + } + + [Fact] + public void DelegateWithNullableParameterCanBePassedANull() + { + _engine.SetValue("isnull", new Func(x => x == null)); + + RunTest(@" + assert(isnull(null) === true); + "); + } + + [Fact] + public void DelegateWithObjectParameterCanBePassedANull() + { + _engine.SetValue("isnull", new Func(x => x == null)); + + RunTest(@" + assert(isnull(null) === true); + "); + } + + [Fact] + public void DelegateWithNullableParameterCanBePassedAnUndefined() + { + _engine.SetValue("isnull", new Func(x => x == null)); + + RunTest(@" + assert(isnull(undefined) === true); + "); + } + + [Fact] + public void DelegateWithObjectParameterCanBePassedAnUndefined() + { + _engine.SetValue("isnull", new Func(x => x == null)); + + RunTest(@" + assert(isnull(undefined) === true); + "); + } + + [Fact] + public void DelegateWithNullableParameterCanBeExcluded() + { + _engine.SetValue("isnull", new Func(x => x == null)); + + RunTest(@" + assert(isnull() === true); + "); + } + + [Fact] + public void DelegateWithObjectParameterCanBeExcluded() + { + _engine.SetValue("isnull", new Func(x => x == null)); + + RunTest(@" + assert(isnull() === true); + "); + } + + [Fact] + public void ExtraParametersAreIgnored() + { + _engine.SetValue("passNumber", new Func(x => x)); + + RunTest(@" + assert(passNumber(123,'test',{},[],null) === 123); + "); + } + + private delegate string callParams(params object[] values); + private delegate string callArgumentAndParams(string firstParam, params object[] values); + + [Fact] + public void DelegatesWithParamsParameterCanBeInvoked() + { + var a = new A(); + _engine.SetValue("callParams", new callParams(a.Call13)); + _engine.SetValue("callArgumentAndParams", new callArgumentAndParams(a.Call14)); + + RunTest(@" + assert(callParams('1','2','3') === '1,2,3'); + assert(callParams('1') === '1'); + assert(callParams() === ''); + + assert(callArgumentAndParams('a','1','2','3') === 'a:1,2,3'); + assert(callArgumentAndParams('a','1') === 'a:1'); + assert(callArgumentAndParams('a') === 'a:'); + assert(callArgumentAndParams() === ':'); + "); + } + + [Fact] + public void CanGetObjectProperties() + { + var p = new Person + { + Name = "Mickey Mouse" + }; + + _engine.SetValue("p", p); + + RunTest(@" + assert(p.Name === 'Mickey Mouse'); + "); + } + + [Fact] + public void CanInvokeObjectMethods() + { + var p = new Person + { + Name = "Mickey Mouse" + }; + + _engine.SetValue("p", p); + + RunTest(@" + assert(p.ToString() === 'Mickey Mouse'); + "); + } + + [Fact] + public void CanInvokeObjectMethodsWithPascalCase() + { + var p = new Person + { + Name = "Mickey Mouse" + }; + + _engine.SetValue("p", p); + + RunTest(@" + assert(p.toString() === 'Mickey Mouse'); + "); + } + + [Fact] + public void CanSetObjectProperties() + { + var p = new Person + { + Name = "Mickey Mouse" + }; + + _engine.SetValue("p", p); + + RunTest(@" + p.Name = 'Donald Duck'; + assert(p.Name === 'Donald Duck'); + "); + Assert.Equal("Donald Duck", p.Name); } @@ -111,9 +223,9 @@ public void CanGetIndexUsingStringKey() _engine.SetValue("dictionary", dictionary); - RunTest(@" - assert(dictionary['person1'].Name === 'Mickey Mouse'); - assert(dictionary['person2'].Name === 'Goofy'); + RunTest(@" + assert(dictionary['person1'].Name === 'Mickey Mouse'); + assert(dictionary['person2'].Name === 'Goofy'); "); } @@ -126,9 +238,9 @@ public void CanSetIndexUsingStringKey() _engine.SetValue("dictionary", dictionary); - RunTest(@" - dictionary['person2'].Name = 'Donald Duck'; - assert(dictionary['person2'].Name === 'Donald Duck'); + RunTest(@" + dictionary['person2'].Name = 'Donald Duck'; + assert(dictionary['person2'].Name === 'Donald Duck'); "); Assert.Equal("Donald Duck", dictionary["person2"].Name); @@ -143,9 +255,9 @@ public void CanGetIndexUsingIntegerKey() _engine.SetValue("dictionary", dictionary); - RunTest(@" - assert(dictionary[1] === 'Mickey Mouse'); - assert(dictionary[2] === 'Goofy'); + RunTest(@" + assert(dictionary[1] === 'Mickey Mouse'); + assert(dictionary[2] === 'Goofy'); "); } @@ -158,15 +270,72 @@ public void CanSetIndexUsingIntegerKey() _engine.SetValue("dictionary", dictionary); - RunTest(@" - dictionary[2] = 'Donald Duck'; - assert(dictionary[2] === 'Donald Duck'); + RunTest(@" + dictionary[2] = 'Donald Duck'; + assert(dictionary[2] === 'Donald Duck'); "); Assert.Equal("Mickey Mouse", dictionary[1]); Assert.Equal("Donald Duck", dictionary[2]); } + private class DoubleIndexedClass + { + public int this[int index] + { + get { return index; } + } + + public string this[string index] + { + get { return index; } + } + } + + [Fact] + public void CanGetIndexUsingBothIntAndStringIndex() + { + var dictionary = new DoubleIndexedClass(); + + _engine.SetValue("dictionary", dictionary); + + RunTest(@" + assert(dictionary[1] === 1); + assert(dictionary['test'] === 'test'); + "); + } + + [Fact] + public void CanUseGenericMethods() + { + var dictionary = new Dictionary(); + dictionary.Add(1, "Mickey Mouse"); + + + _engine.SetValue("dictionary", dictionary); + + RunTest(@" + dictionary.Add(2, 'Goofy'); + assert(dictionary[2] === 'Goofy'); + "); + + Assert.Equal("Mickey Mouse", dictionary[1]); + Assert.Equal("Goofy", dictionary[2]); + } + + [Fact] + public void CanUseMultiGenericTypes() + { + + RunTest(@" + var type = System.Collections.Generic.Dictionary(System.Int32, System.String); + var dictionary = new type(); + dictionary.Add(1, 'Mickey Mouse'); + dictionary.Add(2, 'Goofy'); + assert(dictionary[2] === 'Goofy'); + "); + } + [Fact] public void CanUseIndexOnCollection() { @@ -176,9 +345,9 @@ public void CanUseIndexOnCollection() _engine.SetValue("dictionary", collection); - RunTest(@" - dictionary[1] = 'Donald Duck'; - assert(dictionary[1] === 'Donald Duck'); + RunTest(@" + dictionary[1] = 'Donald Duck'; + assert(dictionary[1] === 'Donald Duck'); "); Assert.Equal("Mickey Mouse", collection[0]); @@ -188,678 +357,1245 @@ public void CanUseIndexOnCollection() [Fact] public void CanUseIndexOnList() { - var arrayList = new System.Collections.ArrayList(2); - arrayList.Add("Mickey Mouse"); - arrayList.Add("Goofy"); - - _engine.SetValue("dictionary", arrayList); - - RunTest(@" - dictionary[1] = 'Donald Duck'; - assert(dictionary[1] === 'Donald Duck'); - "); - - Assert.Equal("Mickey Mouse", arrayList[0]); - Assert.Equal("Donald Duck", arrayList[1]); - } - - [Fact] - public void CanAccessAnonymousObject() - { - var p = new - { - Name = "Mickey Mouse", - }; - - _engine.SetValue("p", p); - - RunTest(@" - assert(p.Name === 'Mickey Mouse'); - "); - } - - [Fact] - public void CanAccessAnonymousObjectProperties() - { - var p = new - { - Address = new - { - City = "Mouseton" - } - }; - - _engine.SetValue("p", p); - - RunTest(@" - assert(p.Address.City === 'Mouseton'); - "); - } - - [Fact] - public void PocosCanReturnJsValueDirectly() - { - var o = new - { - x = new JsValue(1), - y = new JsValue("string"), - }; - - _engine.SetValue("o", o); - - RunTest(@" - assert(o.x === 1); - assert(o.y === 'string'); - "); - } - - [Fact] - public void PocosCanReturnObjectInstanceDirectly() - { - var x = new ObjectInstance(_engine) { Extensible = true}; - x.Put("foo", new JsValue("bar"), false); - - var o = new - { - x - }; - - _engine.SetValue("o", o); - - RunTest(@" - assert(o.x.foo === 'bar'); - "); - } - - [Fact] - public void DateTimeIsConvertedToDate() - { - var o = new - { - z = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc) - }; - - _engine.SetValue("o", o); - - RunTest(@" - assert(o.z.valueOf() === 0); - "); - } - - [Fact] - public void DateTimeOffsetIsConvertedToDate() - { - var o = new - { - z = new DateTimeOffset(1970, 1, 1, 0, 0, 0, new TimeSpan()) - }; - - _engine.SetValue("o", o); - - RunTest(@" - assert(o.z.valueOf() === 0); - "); - } - - [Fact] - public void EcmaValuesAreAutomaticallyConvertedWhenSetInPoco() - { - var p = new Person - { - Name = "foo", - }; - - _engine.SetValue("p", p); - - RunTest(@" - assert(p.Name === 'foo'); - assert(p.Age === 0); - p.Name = 'bar'; - p.Age = 10; - "); - - Assert.Equal("bar", p.Name); - Assert.Equal(10, p.Age); - } - - [Fact] - public void EcmaValuesAreAutomaticallyConvertedToBestMatchWhenSetInPoco() - { - var p = new Person - { - Name = "foo", - }; - - _engine.SetValue("p", p); - - RunTest(@" - p.Name = 10; - p.Age = '20'; - "); - - Assert.Equal("10", p.Name); - Assert.Equal(20, p.Age); - } - - [Fact] - public void ShouldCallInstanceMethodWithoutArgument() - { - _engine.SetValue("a", new A()); - - RunTest(@" - assert(a.Call1() === 0); - "); - } - - [Fact] - public void ShouldCallInstanceMethodOverloadArgument() - { - _engine.SetValue("a", new A()); - - RunTest(@" - assert(a.Call1(1) === 1); - "); - } - - [Fact] - public void ShouldCallInstanceMethodWithString() - { - var p = new Person(); - _engine.SetValue("a", new A()); - _engine.SetValue("p", p); - - RunTest(@" - p.Name = a.Call2('foo'); - assert(p.Name === 'foo'); - "); - - Assert.Equal("foo", p.Name); - } - - [Fact] - public void CanUseTrim() - { - var p = new Person { Name = "Mickey Mouse "}; - _engine.SetValue("p", p); - - RunTest(@" - assert(p.Name === 'Mickey Mouse '); - p.Name = p.Name.trim(); - assert(p.Name === 'Mickey Mouse'); - "); - - Assert.Equal("Mickey Mouse", p.Name); - } - - [Fact] - public void CanUseMathFloor() - { - var p = new Person(); - _engine.SetValue("p", p); - - RunTest(@" - p.Age = Math.floor(1.6);p - assert(p.Age === 1); - "); - - Assert.Equal(1, p.Age); - } - - [Fact] - public void CanUseDelegateAsFunction() - { - var even = new Func(x => x % 2 == 0); - _engine.SetValue("even", even); - - RunTest(@" - assert(even(2) === true); - "); - } - - [Fact] - public void ShouldConvertArrayToArrayInstance() - { - var result = _engine - .SetValue("values", new[] { 1, 2, 3, 4, 5, 6 }) - .Execute("values.filter(function(x){ return x % 2 == 0; })"); - - var parts = result.GetCompletionValue().ToObject(); - - Assert.True(parts.GetType().IsArray); - Assert.Equal(3, ((object[])parts).Length); - Assert.Equal(2d, ((object[])parts)[0]); - Assert.Equal(4d, ((object[])parts)[1]); - Assert.Equal(6d, ((object[])parts)[2]); - } - - [Fact] - public void ShouldConvertListsToArrayInstance() - { - var result = _engine - .SetValue("values", new List { 1, 2, 3, 4, 5, 6 }) - .Execute("new Array(values).filter(function(x){ return x % 2 == 0; })"); - - var parts = result.GetCompletionValue().ToObject(); - - Assert.True(parts.GetType().IsArray); - Assert.Equal(3, ((object[])parts).Length); - Assert.Equal(2d, ((object[])parts)[0]); - Assert.Equal(4d, ((object[])parts)[1]); - Assert.Equal(6d, ((object[])parts)[2]); - } - - [Fact] - public void ShouldConvertArrayInstanceToArray() - { - var result = _engine.Execute("'foo@bar.com'.split('@');"); - var parts = result.GetCompletionValue().ToObject(); - - Assert.True(parts.GetType().IsArray); - Assert.Equal(2, ((object[])parts).Length); - Assert.Equal("foo", ((object[])parts)[0]); - Assert.Equal("bar.com", ((object[])parts)[1]); - } - - [Fact] - public void ShouldConvertBooleanInstanceToBool() - { - var result = _engine.Execute("new Boolean(true)"); - var value = result.GetCompletionValue().ToObject(); - - Assert.Equal(typeof(bool), value.GetType()); - Assert.Equal(true, value); - } - - [Fact] - public void ShouldConvertDateInstanceToDateTime() - { - var result = _engine.Execute("new Date(0)"); - var value = result.GetCompletionValue().ToObject(); - - Assert.Equal(typeof(DateTime), value.GetType()); - Assert.Equal(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), value); - } - - [Fact] - public void ShouldConvertNumberInstanceToDouble() - { - var result = _engine.Execute("new Number(10)"); - var value = result.GetCompletionValue().ToObject(); - - Assert.Equal(typeof(double), value.GetType()); - Assert.Equal(10d, value); - } - - [Fact] - public void ShouldConvertStringInstanceToString() - { - var result = _engine.Execute("new String('foo')"); - var value = result.GetCompletionValue().ToObject(); - - Assert.Equal(typeof(string), value.GetType()); - Assert.Equal("foo", value); - } - - [Fact] - public void ShouldConvertObjectInstanceToExpando() - { - _engine.Execute("var o = {a: 1, b: 'foo'}"); - var result = _engine.GetValue("o"); - - dynamic value = result.ToObject(); - - Assert.Equal(1, value.a); - Assert.Equal("foo", value.b); - - var dic = (IDictionary)result.ToObject(); - - Assert.Equal(1d, dic["a"]); - Assert.Equal("foo", dic["b"]); - - } - - [Fact] - public void ShouldNotTryToConvertCompatibleTypes() - { - _engine.SetValue("a", new A()); - - RunTest(@" - assert(a.Call3('foo') === 'foo'); - assert(a.Call3(1) === '1'); - "); - } - - [Fact] - public void ShouldNotTryToConvertDerivedTypes() - { - _engine.SetValue("a", new A()); - _engine.SetValue("p", new Person { Name = "Mickey" }); - - RunTest(@" - assert(a.Call4(p) === 'Mickey'); - "); - } - - [Fact] - public void ShouldExecuteFunctionCallBackAsDelegate() - { - _engine.SetValue("a", new A()); - - RunTest(@" - assert(a.Call5(function(a,b){ return a+b }) === '1foo'); - "); - } - - [Fact] - public void ShouldExecuteFunctionCallBackAsFuncAndThisCanBeAssigned() - { - _engine.SetValue("a", new A()); - - RunTest(@" - assert(a.Call6(function(a,b){ return this+a+b }) === 'bar1foo'); - "); - } - - [Fact] - public void ShouldUseSystemIO() - { - RunTest(@" - var filename = System.IO.Path.GetTempFileName(); - var sw = System.IO.File.CreateText(filename); - sw.Write('Hello World'); - sw.Dispose(); - - var content = System.IO.File.ReadAllText(filename); - System.Console.WriteLine(content); - - assert(content === 'Hello World'); - "); - } - - [Fact] - public void ShouldImportNamespace() - { - RunTest(@" - var Shapes = importNamespace('Shapes'); - var circle = new Shapes.Circle(); - assert(circle.Radius === 0); - assert(circle.Perimeter() === 0); - "); - } - - [Fact] - public void ShouldConstructWithParameters() - { - RunTest(@" - var Shapes = importNamespace('Shapes'); - var circle = new Shapes.Circle(1); - assert(circle.Radius === 1); - assert(circle.Perimeter() === Math.PI); - "); - } - - [Fact] - public void ShouldInvokeAFunctionByName() - { - RunTest(@" - function add(x, y) { return x + y; } - "); - - Assert.Equal(3, _engine.Invoke("add", 1, 2)); - } - - [Fact] - public void ShouldNotInvokeNonFunctionValue() - { - RunTest(@" - var x= 10; - "); - - Assert.Throws(() => _engine.Invoke("x", 1, 2)); - } - - [Fact] - public void CanGetField() - { - var o = new ClassWithField - { - Field = "Mickey Mouse" - }; - - _engine.SetValue("o", o); - - RunTest(@" - assert(o.Field === 'Mickey Mouse'); - "); - } - - [Fact] - public void CanSetField() - { - var o = new ClassWithField(); - - _engine.SetValue("o", o); - - RunTest(@" - o.Field = 'Mickey Mouse'; - assert(o.Field === 'Mickey Mouse'); - "); - - Assert.Equal("Mickey Mouse", o.Field); - } - - [Fact] - public void CanGetStaticField() - { - RunTest(@" - var domain = importNamespace('Jint.Tests.Runtime.Domain'); - var statics = domain.ClassWithStaticFields; - assert(statics.Get == 'Get'); - "); - } - - [Fact] - public void CanSetStaticField() - { - RunTest(@" - var domain = importNamespace('Jint.Tests.Runtime.Domain'); - var statics = domain.ClassWithStaticFields; - statics.Set = 'hello'; - assert(statics.Set == 'hello'); - "); - - Assert.Equal(ClassWithStaticFields.Set, "hello"); - } - - [Fact] - public void CanGetStaticAccessor() - { - RunTest(@" - var domain = importNamespace('Jint.Tests.Runtime.Domain'); - var statics = domain.ClassWithStaticFields; - assert(statics.Getter == 'Getter'); - "); - } - - [Fact] - public void CanSetStaticAccessor() - { - RunTest(@" - var domain = importNamespace('Jint.Tests.Runtime.Domain'); - var statics = domain.ClassWithStaticFields; - statics.Setter = 'hello'; - assert(statics.Setter == 'hello'); - "); - - Assert.Equal(ClassWithStaticFields.Setter, "hello"); - } - - [Fact] - public void CantSetStaticReadonly() - { - RunTest(@" - var domain = importNamespace('Jint.Tests.Runtime.Domain'); - var statics = domain.ClassWithStaticFields; - statics.Readonly = 'hello'; - assert(statics.Readonly == 'Readonly'); - "); - - Assert.Equal(ClassWithStaticFields.Readonly, "Readonly"); - } - - [Fact] - public void CanSetCustomConverters() - { - - var engine1 = new Engine(); - engine1.SetValue("p", new { Test = true }); - engine1.Execute("var result = p.Test;"); - Assert.True((bool)engine1.GetValue("result").ToObject()); - - var engine2 = new Engine(o => o.AddObjectConverter(new NegateBoolConverter())); - engine2.SetValue("p", new { Test = true }); - engine2.Execute("var result = p.Test;"); - Assert.False((bool)engine2.GetValue("result").ToObject()); - - } - - [Fact] - public void CanUserIncrementOperator() - { - var p = new Person - { - Age = 1, - }; - - _engine.SetValue("p", p); - - RunTest(@" - assert(++p.Age === 2); - "); - - Assert.Equal(2, p.Age); - } - - [Fact] - public void CanOverwriteValues() - { - _engine.SetValue("x", 3); - _engine.SetValue("x", 4); - - RunTest(@" - assert(x === 4); - "); - } - - [Fact] - public void ShouldCreateGenericType() - { - RunTest(@" - var ListOfString = System.Collections.Generic.List(System.String); - var list = new ListOfString(); - list.Add('foo'); - list.Add(1); - assert(2 === list.Count); - "); + var list = new List(2); + list.Add("Mickey Mouse"); + list.Add("Goofy"); + + _engine.SetValue("list", list); + + RunTest(@" + list[1] = 'Donald Duck'; + assert(list[1] === 'Donald Duck'); + "); + + Assert.Equal("Mickey Mouse", list[0]); + Assert.Equal("Donald Duck", list[1]); + } + + [Fact] + public void CanAccessAnonymousObject() + { + var p = new + { + Name = "Mickey Mouse", + }; + + _engine.SetValue("p", p); + + RunTest(@" + assert(p.Name === 'Mickey Mouse'); + "); } [Fact] - public void EnumComparesByName() + public void CanAccessAnonymousObjectProperties() + { + var p = new + { + Address = new + { + City = "Mouseton" + } + }; + + _engine.SetValue("p", p); + + RunTest(@" + assert(p.Address.City === 'Mouseton'); + "); + } + + [Fact] + public void PocosCanReturnJsValueDirectly() { var o = new { - r = Colors.Red, - b = Colors.Blue, - g = Colors.Green, - b2 = Colors.Red + x = new JsValue(1), + y = new JsValue("string"), }; _engine.SetValue("o", o); - _engine.SetValue("assertFalse", new Action(Assert.False)); - RunTest(@" - var domain = importNamespace('Jint.Tests.Runtime.Domain'); - var colors = domain.Colors; - assert(o.r === colors.Red); - assert(o.g === colors.Green); - assert(o.b === colors.Blue); - assertFalse(o.b2 === colors.Blue); + RunTest(@" + assert(o.x === 1); + assert(o.y === 'string'); "); } [Fact] - public void ShouldSetEnumProperty() + public void PocosCanReturnObjectInstanceDirectly() { - var s = new Circle + var x = new ObjectInstance(_engine) { Extensible = true}; + x.Put("foo", new JsValue("bar"), false); + + var o = new { - Color = Colors.Red, + x }; - _engine.SetValue("s", s); + _engine.SetValue("o", o); - RunTest(@" - var domain = importNamespace('Jint.Tests.Runtime.Domain'); - var colors = domain.Colors; - - s.Color = colors.Blue; - assert(s.Color === colors.Blue); + RunTest(@" + assert(o.x.foo === 'bar'); "); + } - _engine.SetValue("s", s); + [Fact] + public void DateTimeIsConvertedToDate() + { + var o = new + { + z = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc) + }; + + _engine.SetValue("o", o); - RunTest(@" - s.Color = colors.Blue | colors.Green; - assert(s.Color === colors.Blue | colors.Green); + RunTest(@" + assert(o.z.valueOf() === 0); "); + } - Assert.Equal(Colors.Blue | Colors.Green, s.Color); - } - - [Fact] - public void EnumIsConvertedToNumber() - { - var o = new - { - r = Colors.Red, - b = Colors.Blue, - g = Colors.Green - }; - - _engine.SetValue("o", o); - - RunTest(@" - assert(o.r === 0); - assert(o.g === 1); - assert(o.b === 10); - "); - } - - - [Fact] - public void ShouldConvertToEnum() - { - var s = new Circle - { - Color = Colors.Red, - }; - - _engine.SetValue("s", s); - - RunTest(@" - assert(s.Color === 0); - s.Color = 10; - assert(s.Color === 10); - "); - - _engine.SetValue("s", s); - - RunTest(@" - s.Color = 11; - assert(s.Color === 11); - "); - - Assert.Equal(Colors.Blue | Colors.Green, s.Color); - } - - } -} + [Fact] + public void DateTimeOffsetIsConvertedToDate() + { + var o = new + { + z = new DateTimeOffset(1970, 1, 1, 0, 0, 0, new TimeSpan()) + }; + + _engine.SetValue("o", o); + + RunTest(@" + assert(o.z.valueOf() === 0); + "); + } + + [Fact] + public void EcmaValuesAreAutomaticallyConvertedWhenSetInPoco() + { + var p = new Person + { + Name = "foo", + }; + + _engine.SetValue("p", p); + + RunTest(@" + assert(p.Name === 'foo'); + assert(p.Age === 0); + p.Name = 'bar'; + p.Age = 10; + "); + + Assert.Equal("bar", p.Name); + Assert.Equal(10, p.Age); + } + + [Fact] + public void EcmaValuesAreAutomaticallyConvertedToBestMatchWhenSetInPoco() + { + var p = new Person + { + Name = "foo", + }; + + _engine.SetValue("p", p); + + RunTest(@" + p.Name = 10; + p.Age = '20'; + "); + + Assert.Equal("10", p.Name); + Assert.Equal(20, p.Age); + } + + [Fact] + public void ShouldCallInstanceMethodWithoutArgument() + { + _engine.SetValue("a", new A()); + + RunTest(@" + assert(a.Call1() === 0); + "); + } + + [Fact] + public void ShouldCallInstanceMethodOverloadArgument() + { + _engine.SetValue("a", new A()); + + RunTest(@" + assert(a.Call1(1) === 1); + "); + } + + [Fact] + public void ShouldCallInstanceMethodWithString() + { + var p = new Person(); + _engine.SetValue("a", new A()); + _engine.SetValue("p", p); + + RunTest(@" + p.Name = a.Call2('foo'); + assert(p.Name === 'foo'); + "); + + Assert.Equal("foo", p.Name); + } + + [Fact] + public void CanUseTrim() + { + var p = new Person { Name = "Mickey Mouse "}; + _engine.SetValue("p", p); + + RunTest(@" + assert(p.Name === 'Mickey Mouse '); + p.Name = p.Name.trim(); + assert(p.Name === 'Mickey Mouse'); + "); + + Assert.Equal("Mickey Mouse", p.Name); + } + + [Fact] + public void CanUseMathFloor() + { + var p = new Person(); + _engine.SetValue("p", p); + + RunTest(@" + p.Age = Math.floor(1.6);p + assert(p.Age === 1); + "); + + Assert.Equal(1, p.Age); + } + + [Fact] + public void CanUseDelegateAsFunction() + { + var even = new Func(x => x % 2 == 0); + _engine.SetValue("even", even); + + RunTest(@" + assert(even(2) === true); + "); + } + + private class TestClass + { + public int? NullableInt { get; set; } + public DateTime? NullableDate { get; set; } + public bool? NullableBool { get; set; } + } + + [Fact] + public void CanSetNullablePropertiesOnPocos() + { + var instance = new TestClass(); + _engine.SetValue("instance", instance); + + RunTest(@" + instance.NullableInt = 2; + instance.NullableDate = new Date(); + instance.NullableBool = true; + + assert(instance.NullableInt===2); + assert(instance.NullableDate!=null); + assert(instance.NullableBool===true); + "); + } + + [Fact] + public void ShouldConvertArrayToArrayInstance() + { + var result = _engine + .SetValue("values", new[] { 1, 2, 3, 4, 5, 6 }) + .Execute("values.filter(function(x){ return x % 2 == 0; })"); + + var parts = result.GetCompletionValue().ToObject(); + + Assert.True(parts.GetType().IsArray); + Assert.Equal(3, ((object[])parts).Length); + Assert.Equal(2d, ((object[])parts)[0]); + Assert.Equal(4d, ((object[])parts)[1]); + Assert.Equal(6d, ((object[])parts)[2]); + } + + [Fact] + public void ShouldConvertListsToArrayInstance() + { + var result = _engine + .SetValue("values", new List { 1, 2, 3, 4, 5, 6 }) + .Execute("new Array(values).filter(function(x){ return x % 2 == 0; })"); + + var parts = result.GetCompletionValue().ToObject(); + + Assert.True(parts.GetType().IsArray); + Assert.Equal(3, ((object[])parts).Length); + Assert.Equal(2d, ((object[])parts)[0]); + Assert.Equal(4d, ((object[])parts)[1]); + Assert.Equal(6d, ((object[])parts)[2]); + } + + [Fact] + public void ShouldConvertArrayInstanceToArray() + { + var result = _engine.Execute("'foo@bar.com'.split('@');"); + var parts = result.GetCompletionValue().ToObject(); + + Assert.True(parts.GetType().IsArray); + Assert.Equal(2, ((object[])parts).Length); + Assert.Equal("foo", ((object[])parts)[0]); + Assert.Equal("bar.com", ((object[])parts)[1]); + } + + [Fact] + public void ShouldConvertBooleanInstanceToBool() + { + var result = _engine.Execute("new Boolean(true)"); + var value = result.GetCompletionValue().ToObject(); + + Assert.Equal(typeof(bool), value.GetType()); + Assert.Equal(true, value); + } + + [Fact] + public void ShouldConvertDateInstanceToDateTime() + { + var result = _engine.Execute("new Date(0)"); + var value = result.GetCompletionValue().ToObject(); + + Assert.Equal(typeof(DateTime), value.GetType()); + Assert.Equal(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), value); + } + + [Fact] + public void ShouldConvertNumberInstanceToDouble() + { + var result = _engine.Execute("new Number(10)"); + var value = result.GetCompletionValue().ToObject(); + + Assert.Equal(typeof(double), value.GetType()); + Assert.Equal(10d, value); + } + + [Fact] + public void ShouldConvertStringInstanceToString() + { + var result = _engine.Execute("new String('foo')"); + var value = result.GetCompletionValue().ToObject(); + + Assert.Equal(typeof(string), value.GetType()); + Assert.Equal("foo", value); + } + + [Fact] + public void ShouldConvertObjectInstanceToExpando() + { + _engine.Execute("var o = {a: 1, b: 'foo'}"); + var result = _engine.GetValue("o"); + + dynamic value = result.ToObject(); + + Assert.Equal(1, value.a); + Assert.Equal("foo", value.b); + + var dic = (IDictionary)result.ToObject(); + + Assert.Equal(1d, dic["a"]); + Assert.Equal("foo", dic["b"]); + + } + + [Fact] + public void ShouldNotTryToConvertCompatibleTypes() + { + _engine.SetValue("a", new A()); + + RunTest(@" + assert(a.Call3('foo') === 'foo'); + assert(a.Call3(1) === '1'); + "); + } + + [Fact] + public void ShouldNotTryToConvertDerivedTypes() + { + _engine.SetValue("a", new A()); + _engine.SetValue("p", new Person { Name = "Mickey" }); + + RunTest(@" + assert(a.Call4(p) === 'Mickey'); + "); + } + + [Fact] + public void ShouldExecuteFunctionCallBackAsDelegate() + { + _engine.SetValue("a", new A()); + + RunTest(@" + assert(a.Call5(function(a,b){ return a+b }) === '1foo'); + "); + } + + [Fact] + public void ShouldExecuteFunctionCallBackAsFuncAndThisCanBeAssigned() + { + _engine.SetValue("a", new A()); + + RunTest(@" + assert(a.Call6(function(a,b){ return this+a+b }) === 'bar1foo'); + "); + } + + [Fact] + public void ShouldExecuteFunctionCallBackAsPredicate() + { + _engine.SetValue("a", new A()); + + // Func<> + RunTest(@" + assert(a.Call8(function(){ return 'foo'; }) === 'foo'); + "); + } + + [Fact] + public void ShouldExecuteFunctionWithParameterCallBackAsPredicate() + { + _engine.SetValue("a", new A()); + + // Func<,> + RunTest(@" + assert(a.Call7('foo', function(a){ return a === 'foo'; }) === true); + "); + } + + [Fact] + public void ShouldExecuteActionCallBackAsPredicate() + { + _engine.SetValue("a", new A()); + + // Action + RunTest(@" + var value; + a.Call9(function(){ value = 'foo'; }); + assert(value === 'foo'); + "); + } + + [Fact] + public void ShouldExecuteActionWithParameterCallBackAsPredicate() + { + _engine.SetValue("a", new A()); + + // Action<> + RunTest(@" + var value; + a.Call10('foo', function(b){ value = b; }); + assert(value === 'foo'); + "); + } + + [Fact] + public void ShouldExecuteActionWithMultipleParametersCallBackAsPredicate() + { + _engine.SetValue("a", new A()); + + // Action<,> + RunTest(@" + var value; + a.Call11('foo', 'bar', function(a,b){ value = a + b; }); + assert(value === 'foobar'); + "); + } + + [Fact] + public void ShouldExecuteFunc() + { + _engine.SetValue("a", new A()); + + // Func + RunTest(@" + var result = a.Call12(42, function(a){ return a + a; }); + assert(result === 84); + "); + } + + [Fact] + public void ShouldExecuteActionCallbackOnEventChanged() + { + var collection = new System.Collections.ObjectModel.ObservableCollection(); + Assert.True(collection.Count == 0); + + _engine.SetValue("collection", collection); + + RunTest(@" + var eventAction; + collection.add_CollectionChanged(function(sender, eventArgs) { eventAction = eventArgs.Action; } ); + collection.Add('test'); + "); + + var eventAction = _engine.GetValue("eventAction").AsNumber(); + Assert.True(eventAction == 0); + Assert.True(collection.Count == 1); + } + + [Fact] + public void ShouldUseSystemIO() + { + RunTest(@" + var filename = System.IO.Path.GetTempFileName(); + var sw = System.IO.File.CreateText(filename); + sw.Write('Hello World'); + sw.Dispose(); + + var content = System.IO.File.ReadAllText(filename); + System.Console.WriteLine(content); + + assert(content === 'Hello World'); + "); + } + + [Fact] + public void ShouldBeInstanceOfTypeReferenceType() + { + _engine.SetValue("A", typeof(A)); + RunTest(@" + var a = new A(); + assert(a instanceof A); + "); + } + + [Fact] + public void ShouldImportNamespace() + { + RunTest(@" + var Shapes = importNamespace('Shapes'); + var circle = new Shapes.Circle(); + assert(circle.Radius === 0); + assert(circle.Perimeter() === 0); + "); + } + + [Fact] + public void ShouldConstructReferenceTypeWithParameters() + { + RunTest(@" + var Shapes = importNamespace('Shapes'); + var circle = new Shapes.Circle(1); + assert(circle.Radius === 1); + assert(circle.Perimeter() === Math.PI); + "); + } + + [Fact] + public void ShouldConstructValueTypeWithoutParameters() + { + RunTest(@" + var guid = new System.Guid(); + assert('00000000-0000-0000-0000-000000000000' === guid.ToString()); + "); + } + + [Fact] + public void ShouldInvokeAFunctionByName() + { + RunTest(@" + function add(x, y) { return x + y; } + "); + + Assert.Equal(3, _engine.Invoke("add", 1, 2)); + } + + [Fact] + public void ShouldNotInvokeNonFunctionValue() + { + RunTest(@" + var x= 10; + "); + + Assert.Throws(() => _engine.Invoke("x", 1, 2)); + } + + [Fact] + public void CanGetField() + { + var o = new ClassWithField + { + Field = "Mickey Mouse" + }; + + _engine.SetValue("o", o); + + RunTest(@" + assert(o.Field === 'Mickey Mouse'); + "); + } + + [Fact] + public void CanSetField() + { + var o = new ClassWithField(); + + _engine.SetValue("o", o); + + RunTest(@" + o.Field = 'Mickey Mouse'; + assert(o.Field === 'Mickey Mouse'); + "); + + Assert.Equal("Mickey Mouse", o.Field); + } + + [Fact] + public void CanGetStaticField() + { + RunTest(@" + var domain = importNamespace('Jint.Tests.Runtime.Domain'); + var statics = domain.ClassWithStaticFields; + assert(statics.Get == 'Get'); + "); + } + + [Fact] + public void CanSetStaticField() + { + RunTest(@" + var domain = importNamespace('Jint.Tests.Runtime.Domain'); + var statics = domain.ClassWithStaticFields; + statics.Set = 'hello'; + assert(statics.Set == 'hello'); + "); + + Assert.Equal(ClassWithStaticFields.Set, "hello"); + } + + [Fact] + public void CanGetStaticAccessor() + { + RunTest(@" + var domain = importNamespace('Jint.Tests.Runtime.Domain'); + var statics = domain.ClassWithStaticFields; + assert(statics.Getter == 'Getter'); + "); + } + + [Fact] + public void CanSetStaticAccessor() + { + RunTest(@" + var domain = importNamespace('Jint.Tests.Runtime.Domain'); + var statics = domain.ClassWithStaticFields; + statics.Setter = 'hello'; + assert(statics.Setter == 'hello'); + "); + + Assert.Equal(ClassWithStaticFields.Setter, "hello"); + } + + [Fact] + public void CantSetStaticReadonly() + { + RunTest(@" + var domain = importNamespace('Jint.Tests.Runtime.Domain'); + var statics = domain.ClassWithStaticFields; + statics.Readonly = 'hello'; + assert(statics.Readonly == 'Readonly'); + "); + + Assert.Equal(ClassWithStaticFields.Readonly, "Readonly"); + } + + [Fact] + public void CanSetCustomConverters() + { + + var engine1 = new Engine(); + engine1.SetValue("p", new { Test = true }); + engine1.Execute("var result = p.Test;"); + Assert.True((bool)engine1.GetValue("result").ToObject()); + + var engine2 = new Engine(o => o.AddObjectConverter(new NegateBoolConverter())); + engine2.SetValue("p", new { Test = true }); + engine2.Execute("var result = p.Test;"); + Assert.False((bool)engine2.GetValue("result").ToObject()); + + } + + [Fact] + public void CanConvertEnumsToString() + { + var engine1 = new Engine(o => o.AddObjectConverter(new EnumsToStringConverter())) + .SetValue("assert", new Action(Assert.True)); + engine1.SetValue("p", new { Comparison = StringComparison.CurrentCulture }); + engine1.Execute("assert(p.Comparison === 'CurrentCulture');"); + engine1.Execute("var result = p.Comparison;"); + Assert.Equal("CurrentCulture", (string)engine1.GetValue("result").ToObject()); + } + + [Fact] + public void CanUserIncrementOperator() + { + var p = new Person + { + Age = 1, + }; + + _engine.SetValue("p", p); + + RunTest(@" + assert(++p.Age === 2); + "); + + Assert.Equal(2, p.Age); + } + + [Fact] + public void CanOverwriteValues() + { + _engine.SetValue("x", 3); + _engine.SetValue("x", 4); + + RunTest(@" + assert(x === 4); + "); + } + + [Fact] + public void ShouldCreateGenericType() + { + RunTest(@" + var ListOfString = System.Collections.Generic.List(System.String); + var list = new ListOfString(); + list.Add('foo'); + list.Add(1); + assert(2 === list.Count); + "); + } + + [Fact] + public void EnumComparesByName() + { + var o = new + { + r = Colors.Red, + b = Colors.Blue, + g = Colors.Green, + b2 = Colors.Red + }; + + _engine.SetValue("o", o); + _engine.SetValue("assertFalse", new Action(Assert.False)); + + RunTest(@" + var domain = importNamespace('Jint.Tests.Runtime.Domain'); + var colors = domain.Colors; + assert(o.r === colors.Red); + assert(o.g === colors.Green); + assert(o.b === colors.Blue); + assertFalse(o.b2 === colors.Blue); + "); + } + + [Fact] + public void ShouldSetEnumProperty() + { + var s = new Circle + { + Color = Colors.Red, + }; + + _engine.SetValue("s", s); + + RunTest(@" + var domain = importNamespace('Jint.Tests.Runtime.Domain'); + var colors = domain.Colors; + + s.Color = colors.Blue; + assert(s.Color === colors.Blue); + "); + + _engine.SetValue("s", s); + + RunTest(@" + s.Color = colors.Blue | colors.Green; + assert(s.Color === colors.Blue | colors.Green); + "); + + Assert.Equal(Colors.Blue | Colors.Green, s.Color); + } + + [Fact] + public void EnumIsConvertedToNumber() + { + var o = new + { + r = Colors.Red, + b = Colors.Blue, + g = Colors.Green + }; + + _engine.SetValue("o", o); + + RunTest(@" + assert(o.r === 0); + assert(o.g === 1); + assert(o.b === 10); + "); + } + + + [Fact] + public void ShouldConvertToEnum() + { + var s = new Circle + { + Color = Colors.Red, + }; + + _engine.SetValue("s", s); + + RunTest(@" + assert(s.Color === 0); + s.Color = 10; + assert(s.Color === 10); + "); + + _engine.SetValue("s", s); + + RunTest(@" + s.Color = 11; + assert(s.Color === 11); + "); + + Assert.Equal(Colors.Blue | Colors.Green, s.Color); + } + + [Fact] + public void ShouldUseExplicitPropertyGetter() + { + _engine.SetValue("c", new Company("ACME")); + + RunTest(@" + assert(c.Name === 'ACME'); + "); + } + + [Fact] + public void ShouldUseExplicitIndexerPropertyGetter() + { + var company = new Company("ACME"); + ((ICompany)company)["Foo"] = "Bar"; + _engine.SetValue("c", company); + + RunTest(@" + assert(c.Foo === 'Bar'); + "); + } + + + [Fact] + public void ShouldUseExplicitPropertySetter() + { + _engine.SetValue("c", new Company("ACME")); + + RunTest(@" + c.Name = 'Foo'; + assert(c.Name === 'Foo'); + "); + } + + [Fact] + public void ShouldUseExplicitIndexerPropertySetter() + { + var company = new Company("ACME"); + ((ICompany)company)["Foo"] = "Bar"; + _engine.SetValue("c", company); + + RunTest(@" + c.Foo = 'Baz'; + assert(c.Foo === 'Baz'); + "); + } + + + [Fact] + public void ShouldUseExplicitMethod() + { + _engine.SetValue("c", new Company("ACME")); + + RunTest(@" + assert(0 === c.CompareTo(c)); + "); + } + + [Fact] + public void ShouldCallInstanceMethodWithParams() + { + _engine.SetValue("a", new A()); + + RunTest(@" + assert(a.Call13('1','2','3') === '1,2,3'); + assert(a.Call13('1') === '1'); + assert(a.Call13(1) === '1'); + assert(a.Call13() === ''); + + assert(a.Call14('a','1','2','3') === 'a:1,2,3'); + assert(a.Call14('a','1') === 'a:1'); + assert(a.Call14('a') === 'a:'); + + function call13wrapper(){ return a.Call13.apply(a, Array.prototype.slice.call(arguments)); } + assert(call13wrapper('1','2','3') === '1,2,3'); + + assert(a.Call13('1','2','3') === a.Call13(['1','2','3'])); + "); + } + + [Fact] + public void ShouldCallInstanceMethodWithJsValueParams() + { + _engine.SetValue("a", new A()); + + RunTest(@" + assert(a.Call16('1','2','3') === '1,2,3'); + assert(a.Call16('1') === '1'); + assert(a.Call16(1) === '1'); + assert(a.Call16() === ''); + assert(a.Call16('1','2','3') === a.Call16(['1','2','3'])); + "); + } + + [Fact] + public void NullValueAsArgumentShouldWork() + { + _engine.SetValue("a", new A()); + + RunTest(@" + var x = a.Call2(null); + assert(x === null); + "); + } + + [Fact] + public void ShouldSetPropertyToNull() + { + var p = new Person { Name = "Mickey" }; + _engine.SetValue("p", p); + + RunTest(@" + assert(p.Name != null); + p.Name = null; + assert(p.Name == null); + "); + + Assert.True(p.Name == null); + } + + [Fact] + public void ShouldCallMethodWithNull() + { + _engine.SetValue("a", new A()); + + RunTest(@" + a.Call15(null); + var result = a.Call2(null); + assert(result == null); + "); + } + + [Fact] + public void ShouldReturnUndefinedProperty() + { + _engine.SetValue("uo", new { foo = "bar" }); + _engine.SetValue("ud", new Dictionary() { {"foo", "bar"} }); + _engine.SetValue("ul", new List() { "foo", "bar" }); + + RunTest(@" + assert(!uo.undefinedProperty); + assert(!ul[5]); + assert(!ud.undefinedProperty); + "); + } + + [Fact] + public void ShouldAutomaticallyConvertArraysToFindBestInteropResulution() + { + _engine.SetValue("a", new ArrayConverterTestClass()); + _engine.SetValue("item1", new ArrayConverterItem(1)); + _engine.SetValue("item2", new ArrayConverterItem(2)); + + RunTest(@" + assert(a.MethodAcceptsArrayOfInt([false, '1', 2]) === a.MethodAcceptsArrayOfInt([0, 1, 2])); + assert(a.MethodAcceptsArrayOfStrings(['1', 2]) === a.MethodAcceptsArrayOfStrings([1, 2])); + assert(a.MethodAcceptsArrayOfBool(['1', 0]) === a.MethodAcceptsArrayOfBool([true, false])); + + assert(a.MethodAcceptsArrayOfStrings([item1, item2]) === a.MethodAcceptsArrayOfStrings(['1', '2'])); + assert(a.MethodAcceptsArrayOfInt([item1, item2]) === a.MethodAcceptsArrayOfInt([1, 2])); + "); + } + + [Fact] + public void ShouldImportNamespaceNestedType() + { + RunTest(@" + var shapes = importNamespace('Shapes.Circle'); + var kinds = shapes.Kind; + assert(kinds.Unit === 0); + assert(kinds.Ellipse === 1); + assert(kinds.Round === 5); + "); + } + + [Fact] + public void ShouldImportNamespaceNestedNestedType() + { + RunTest(@" + var meta = importNamespace('Shapes.Circle.Meta'); + var usages = meta.Usage; + assert(usages.Public === 0); + assert(usages.Private === 1); + assert(usages.Internal === 11); + "); + } + + [Fact] + public void ShouldGetNestedNestedProp() + { + RunTest(@" + var meta = importNamespace('Shapes.Circle'); + var m = new meta.Meta(); + assert(m.Description === 'descp'); + "); + } + + [Fact] + public void ShouldSetNestedNestedProp() + { + RunTest(@" + var meta = importNamespace('Shapes.Circle'); + var m = new meta.Meta(); + m.Description = 'hello'; + assert(m.Description === 'hello'); + "); + } + + [Fact] + public void CanGetStaticNestedField() + { + RunTest(@" + var domain = importNamespace('Jint.Tests.Runtime.Domain.Nested'); + var statics = domain.ClassWithStaticFields; + assert(statics.Get == 'Get'); + "); + } + + [Fact] + public void CanSetStaticNestedField() + { + RunTest(@" + var domain = importNamespace('Jint.Tests.Runtime.Domain.Nested'); + var statics = domain.ClassWithStaticFields; + statics.Set = 'hello'; + assert(statics.Set == 'hello'); + "); + + Assert.Equal(Nested.ClassWithStaticFields.Set, "hello"); + } + + [Fact] + public void CanGetStaticNestedAccessor() + { + RunTest(@" + var domain = importNamespace('Jint.Tests.Runtime.Domain.Nested'); + var statics = domain.ClassWithStaticFields; + assert(statics.Getter == 'Getter'); + "); + } + + [Fact] + public void CanSetStaticNestedAccessor() + { + RunTest(@" + var domain = importNamespace('Jint.Tests.Runtime.Domain.Nested'); + var statics = domain.ClassWithStaticFields; + statics.Setter = 'hello'; + assert(statics.Setter == 'hello'); + "); + + Assert.Equal(Nested.ClassWithStaticFields.Setter, "hello"); + } + + [Fact] + public void CantSetStaticNestedReadonly() + { + RunTest(@" + var domain = importNamespace('Jint.Tests.Runtime.Domain.Nested'); + var statics = domain.ClassWithStaticFields; + statics.Readonly = 'hello'; + assert(statics.Readonly == 'Readonly'); + "); + + Assert.Equal(Nested.ClassWithStaticFields.Readonly, "Readonly"); + } + + [Fact] + public void ShouldExecuteFunctionWithValueTypeParameterCorrectly() + { + _engine.SetValue("a", new A()); + // Func + RunTest(@" + assert(a.Call17(function(value){ return value; }) === 17); + "); + } + + [Fact] + public void ShouldExecuteActionWithValueTypeParameterCorrectly() + { + _engine.SetValue("a", new A()); + // Action + RunTest(@" + a.Call18(function(value){ assert(value === 18); }); + "); + } + + [Fact] + public void ShouldConvertToJsValue() + { + RunTest(@" + var now = System.DateTime.Now; + assert(new String(now) == now.toString()); + + var zero = System.Int32.MaxValue; + assert(new String(zero) == zero.toString()); + "); + } + + [Fact] + public void ShouldNotCatchClrExceptions() + { + var engine = new Engine() + .SetValue("throwMyException", new Action(() => { throw new NotSupportedException(); })) + .SetValue("Thrower", typeof(Thrower)) + .Execute(@" + function throwException1(){ + try { + throwMyException(); + return; + } + catch(e) { + return; + } + } + + function throwException2(){ + try { + new Thrower().ThrowNotSupportedException(); + return; + } + catch(e) { + return; + } + } + "); + + Assert.ThrowsAny(() => engine.Invoke("throwException1")); + Assert.ThrowsAny(() => engine.Invoke("throwException2")); + } + + [Fact] + public void ShouldCatchAllClrExceptions() + { + string exceptionMessage = "myExceptionMessage"; + + var engine = new Engine(o => o.CatchClrExceptions()) + .SetValue("throwMyException", new Action(() => { throw new Exception(exceptionMessage); })) + .SetValue("Thrower", typeof(Thrower)) + .Execute(@" + function throwException1(){ + try { + throwMyException(); + return ''; + } + catch(e) { + return e.message; + } + } + + function throwException2(){ + try { + new Thrower().ThrowExceptionWithMessage('myExceptionMessage'); + return; + } + catch(e) { + return e.message; + } + } + "); + + Assert.Equal(engine.Invoke("throwException1").AsString(), exceptionMessage); + Assert.Equal(engine.Invoke("throwException2").AsString(), exceptionMessage); + } + + [Fact] + public void ShouldCatchSomeExceptions() + { + string exceptionMessage = "myExceptionMessage"; + + var engine = new Engine(o => o.CatchClrExceptions(e => e is NotSupportedException)) + .SetValue("throwMyException1", new Action(() => { throw new NotSupportedException(exceptionMessage); })) + .SetValue("throwMyException2", new Action(() => { throw new ArgumentNullException(); })) + .SetValue("Thrower", typeof(Thrower)) + .Execute(@" + function throwException1(){ + try { + throwMyException1(); + return ''; + } + catch(e) { + return e.message; + } + } + + function throwException2(){ + try { + throwMyException2(); + return ''; + } + catch(e) { + return e.message; + } + } + + function throwException3(){ + try { + new Thrower().ThrowNotSupportedExceptionWithMessage('myExceptionMessage'); + return ''; + } + catch(e) { + return e.message; + } + } + + function throwException4(){ + try { + new Thrower().ThrowArgumentNullException(); + return ''; + } + catch(e) { + return e.message; + } + } + "); + + Assert.Equal(engine.Invoke("throwException1").AsString(), exceptionMessage); + Assert.Throws(() => engine.Invoke("throwException2")); + Assert.Equal(engine.Invoke("throwException3").AsString(), exceptionMessage); + Assert.Throws(() => engine.Invoke("throwException4")); + } + } +} diff --git a/Jint.Tests/Runtime/JsValueConversionTests.cs b/Jint.Tests/Runtime/JsValueConversionTests.cs new file mode 100644 index 0000000000..b1306b4f16 --- /dev/null +++ b/Jint.Tests/Runtime/JsValueConversionTests.cs @@ -0,0 +1,171 @@ +using Jint.Native; +using Jint.Native.Array; +using Jint.Native.Date; +using Jint.Native.Object; +using Jint.Native.RegExp; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace Jint.Tests.Runtime +{ + public class JsValueConversionTests + { + [Fact] + public void ShouldBeAnArray() + { + var value = new JsValue(new ArrayInstance(null)); + Assert.Equal(false, value.IsBoolean()); + Assert.Equal(true, value.IsArray()); + Assert.Equal(false, value.IsDate()); + Assert.Equal(false, value.IsNull()); + Assert.Equal(false, value.IsNumber()); + Assert.Equal(true, value.IsObject()); + Assert.Equal(false, value.IsPrimitive()); + Assert.Equal(false, value.IsRegExp()); + Assert.Equal(false, value.IsString()); + Assert.Equal(false, value.IsUndefined()); + + Assert.Equal(true, value.AsArray() != null); + } + + [Fact] + public void ShouldBeABoolean() + { + var value = new JsValue(true); + Assert.Equal(true, value.IsBoolean()); + Assert.Equal(false, value.IsArray()); + Assert.Equal(false, value.IsDate()); + Assert.Equal(false, value.IsNull()); + Assert.Equal(false, value.IsNumber()); + Assert.Equal(false, value.IsObject()); + Assert.Equal(true, value.IsPrimitive()); + Assert.Equal(false, value.IsRegExp()); + Assert.Equal(false, value.IsString()); + Assert.Equal(false, value.IsUndefined()); + + Assert.Equal(true, value.AsBoolean()); + } + + [Fact] + public void ShouldBeADate() + { + var value = new JsValue(new DateInstance(null)); + Assert.Equal(false, value.IsBoolean()); + Assert.Equal(false, value.IsArray()); + Assert.Equal(true, value.IsDate()); + Assert.Equal(false, value.IsNull()); + Assert.Equal(false, value.IsNumber()); + Assert.Equal(true, value.IsObject()); + Assert.Equal(false, value.IsPrimitive()); + Assert.Equal(false, value.IsRegExp()); + Assert.Equal(false, value.IsString()); + Assert.Equal(false, value.IsUndefined()); + + Assert.Equal(true, value.AsDate() != null); + } + + [Fact] + public void ShouldBeNull() + { + var value = Null.Instance; + Assert.Equal(false, value.IsBoolean()); + Assert.Equal(false, value.IsArray()); + Assert.Equal(false, value.IsDate()); + Assert.Equal(true, value.IsNull()); + Assert.Equal(false, value.IsNumber()); + Assert.Equal(false, value.IsObject()); + Assert.Equal(true, value.IsPrimitive()); + Assert.Equal(false, value.IsRegExp()); + Assert.Equal(false, value.IsString()); + Assert.Equal(false, value.IsUndefined()); + } + + [Fact] + public void ShouldBeANumber() + { + var value = new JsValue(2); + Assert.Equal(false, value.IsBoolean()); + Assert.Equal(false, value.IsArray()); + Assert.Equal(false, value.IsDate()); + Assert.Equal(false, value.IsNull()); + Assert.Equal(true, value.IsNumber()); + Assert.Equal(2, value.AsNumber()); + Assert.Equal(false, value.IsObject()); + Assert.Equal(true, value.IsPrimitive()); + Assert.Equal(false, value.IsRegExp()); + Assert.Equal(false, value.IsString()); + Assert.Equal(false, value.IsUndefined()); + } + + [Fact] + public void ShouldBeAnObject() + { + var value = new JsValue(new ObjectInstance(null)); + Assert.Equal(false, value.IsBoolean()); + Assert.Equal(false, value.IsArray()); + Assert.Equal(false, value.IsDate()); + Assert.Equal(false, value.IsNull()); + Assert.Equal(false, value.IsNumber()); + Assert.Equal(true, value.IsObject()); + Assert.Equal(true, value.AsObject() != null); + Assert.Equal(false, value.IsPrimitive()); + Assert.Equal(false, value.IsRegExp()); + Assert.Equal(false, value.IsString()); + Assert.Equal(false, value.IsUndefined()); + } + + [Fact] + public void ShouldBeARegExp() + { + var value = new JsValue(new RegExpInstance(null)); + Assert.Equal(false, value.IsBoolean()); + Assert.Equal(false, value.IsArray()); + Assert.Equal(false, value.IsDate()); + Assert.Equal(false, value.IsNull()); + Assert.Equal(false, value.IsNumber()); + Assert.Equal(true, value.IsObject()); + Assert.Equal(false, value.IsPrimitive()); + Assert.Equal(true, value.IsRegExp()); + Assert.Equal(true, value.AsRegExp() != null); + Assert.Equal(false, value.IsString()); + Assert.Equal(false, value.IsUndefined()); + } + + [Fact] + public void ShouldBeAString() + { + var value = new JsValue("a"); + Assert.Equal(false, value.IsBoolean()); + Assert.Equal(false, value.IsArray()); + Assert.Equal(false, value.IsDate()); + Assert.Equal(false, value.IsNull()); + Assert.Equal(false, value.IsNumber()); + Assert.Equal(false, value.IsObject()); + Assert.Equal(true, value.IsPrimitive()); + Assert.Equal(false, value.IsRegExp()); + Assert.Equal(true, value.IsString()); + Assert.Equal("a", value.AsString()); + Assert.Equal(false, value.IsUndefined()); + } + + [Fact] + public void ShouldBeUndefined() + { + var value = Undefined.Instance; + Assert.Equal(false, value.IsBoolean()); + Assert.Equal(false, value.IsArray()); + Assert.Equal(false, value.IsDate()); + Assert.Equal(false, value.IsNull()); + Assert.Equal(false, value.IsNumber()); + Assert.Equal(false, value.IsObject()); + Assert.Equal(true, value.IsPrimitive()); + Assert.Equal(false, value.IsRegExp()); + Assert.Equal(false, value.IsString()); + Assert.Equal(true, value.IsUndefined()); + } + } +} diff --git a/Jint.Tests/Runtime/NullPropagation.cs b/Jint.Tests/Runtime/NullPropagation.cs new file mode 100644 index 0000000000..7beb2af8c4 --- /dev/null +++ b/Jint.Tests/Runtime/NullPropagation.cs @@ -0,0 +1,128 @@ +using Jint.Native; +using Jint.Native.Object; +using Jint.Parser; +using Jint.Runtime; +using Jint.Runtime.Interop; +using Jint.Runtime.References; +using Xunit; + +namespace Jint.Tests.Runtime +{ + public class NullPropagation + { + public class NullPropagationReferenceResolver : IReferenceResolver + { + public bool TryUnresolvableReference(Engine engine, Reference reference, out JsValue value) + { + value = reference.GetBase(); + return true; + } + + public bool TryPropertyReference(Engine engine, Reference reference, ref JsValue value) + { + return value.IsNull() || value.IsUndefined(); + } + + public bool TryGetCallable(Engine engine, object reference, out JsValue value) + { + value = new JsValue( + new ClrFunctionInstance(engine, (thisObj, values) => thisObj) + ); + return true; + } + + public bool CheckCoercible(JsValue value) + { + return true; + } + } + + [Fact] + public void NullPropagationTest() + { + var engine = new Engine(cfg => cfg.SetReferencesResolver(new NullPropagationReferenceResolver())); + + const string Script = @" +var input = { + Address : null +}; + +var address = input.Address; +var city = input.Address.City; +var length = input.Address.City.length; + +var output = { + Count1 : input.Address.City.length, + Count2 : this.XYZ.length +}; +"; + + engine.Execute(Script); + + var address = engine.GetValue("address"); + var city = engine.GetValue("city"); + var length = engine.GetValue("length"); + var output = engine.GetValue("output").AsObject(); + + Assert.Equal(Null.Instance, address); + Assert.Equal(Null.Instance, city); + Assert.Equal(Null.Instance, length); + + Assert.Equal(Null.Instance, output.Get("Count1")); + Assert.Equal(Undefined.Instance, output.Get("Count2")); + } + + [Fact] + public void NullPropagationFromArg() + { + var engine = new Engine(cfg => cfg.SetReferencesResolver(new NullPropagationReferenceResolver())); + + + const string Script = @" +function test(arg) { + return arg.Name; +} + +function test2(arg) { + return arg.Name.toUpperCase(); +} +"; + engine.Execute(Script); + var result = engine.Invoke("test", Null.Instance); + + Assert.Equal(Null.Instance, result); + + result = engine.Invoke("test2", Null.Instance); + + Assert.Equal(Null.Instance, result); + } + + [Fact] + public void NullPropagationShouldNotAffectOperators() + { + var engine = new Engine(cfg => cfg.SetReferencesResolver(new NullPropagationReferenceResolver())); + + var jsObject = engine.Object.Construct(Arguments.Empty); + jsObject.Put("NullField", JsValue.Null, true); + + var script = @" +this.is_nullfield_not_null = this.NullField !== null; +this.is_notnullfield_not_null = this.NotNullField !== null; +this.has_emptyfield_not_null = this.EmptyField !== null; +"; + + var wrapperScript = string.Format(@"function ExecutePatchScript(docInner){{ (function(doc){{ {0} }}).apply(docInner); }};", script); + + engine.Execute(wrapperScript, new ParserOptions + { + Source = "main.js" + }); + + engine.Invoke("ExecutePatchScript", jsObject); + + Assert.False(jsObject.Get("is_nullfield_not_null").AsBoolean()); + Assert.True(jsObject.Get("is_notnullfield_not_null").AsBoolean()); + Assert.True(jsObject.Get("has_emptyfield_not_null").AsBoolean()); + } + } +} \ No newline at end of file diff --git a/Jint.Tests/Runtime/Scripts/Scratch.js b/Jint.Tests/Runtime/Scripts/Scratch.js deleted file mode 100644 index 47818ce668..0000000000 --- a/Jint.Tests/Runtime/Scripts/Scratch.js +++ /dev/null @@ -1,6 +0,0 @@ -(function () { - - - - -})(); \ No newline at end of file diff --git a/Jint.Tests/Runtime/Scripts/handlebars.js b/Jint.Tests/Runtime/Scripts/handlebars.js new file mode 100644 index 0000000000..9fc8f360b9 --- /dev/null +++ b/Jint.Tests/Runtime/Scripts/handlebars.js @@ -0,0 +1,3086 @@ +/*! + + handlebars v2.0.0 + +Copyright (C) 2011-2014 by Yehuda Katz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +@license +*/ +/* exported Handlebars */ +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + define([], factory); + } else if (typeof exports === 'object') { + module.exports = factory(); + } else { + root.Handlebars = root.Handlebars || factory(); + } +}(this, function () { + // handlebars/safe-string.js + var __module4__ = (function () { + "use strict"; + var __exports__; + // Build out our basic SafeString type + function SafeString(string) { + this.string = string; + } + + SafeString.prototype.toString = function () { + return "" + this.string; + }; + + __exports__ = SafeString; + return __exports__; + })(); + + // handlebars/utils.js + var __module3__ = (function (__dependency1__) { + "use strict"; + var __exports__ = {}; + /*jshint -W004 */ + var SafeString = __dependency1__; + + var escape = { + "&": "&", + "<": "<", + ">": ">", + '"': """, + "'": "'", + "`": "`" + }; + + var badChars = /[&<>"'`]/g; + var possible = /[&<>"'`]/; + + function escapeChar(chr) { + return escape[chr]; + } + + function extend(obj /* , ...source */) { + for (var i = 1; i < arguments.length; i++) { + for (var key in arguments[i]) { + if (Object.prototype.hasOwnProperty.call(arguments[i], key)) { + obj[key] = arguments[i][key]; + } + } + } + + return obj; + } + + __exports__.extend = extend; var toString = Object.prototype.toString; + __exports__.toString = toString; + // Sourced from lodash + // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt + var isFunction = function (value) { + return typeof value === 'function'; + }; + // fallback for older versions of Chrome and Safari + /* istanbul ignore next */ + if (isFunction(/x/)) { + isFunction = function (value) { + return typeof value === 'function' && toString.call(value) === '[object Function]'; + }; + } + var isFunction; + __exports__.isFunction = isFunction; + /* istanbul ignore next */ + var isArray = Array.isArray || function (value) { + return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false; + }; + __exports__.isArray = isArray; + + function escapeExpression(string) { + // don't escape SafeStrings, since they're already safe + if (string instanceof SafeString) { + return string.toString(); + } else if (string == null) { + return ""; + } else if (!string) { + return string + ''; + } + + // Force a string conversion as this will be done by the append regardless and + // the regex test will do this transparently behind the scenes, causing issues if + // an object's to string has escaped characters in it. + string = "" + string; + + if (!possible.test(string)) { return string; } + return string.replace(badChars, escapeChar); + } + + __exports__.escapeExpression = escapeExpression; function isEmpty(value) { + if (!value && value !== 0) { + return true; + } else if (isArray(value) && value.length === 0) { + return true; + } else { + return false; + } + } + + __exports__.isEmpty = isEmpty; function appendContextPath(contextPath, id) { + return (contextPath ? contextPath + '.' : '') + id; + } + + __exports__.appendContextPath = appendContextPath; + return __exports__; + })(__module4__); + + // handlebars/exception.js + var __module5__ = (function () { + "use strict"; + var __exports__; + + var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack']; + + function Exception(message, node) { + var line; + if (node && node.firstLine) { + line = node.firstLine; + + message += ' - ' + line + ':' + node.firstColumn; + } + + var tmp = Error.prototype.constructor.call(this, message); + + // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work. + for (var idx = 0; idx < errorProps.length; idx++) { + this[errorProps[idx]] = tmp[errorProps[idx]]; + } + + if (line) { + this.lineNumber = line; + this.column = node.firstColumn; + } + } + + Exception.prototype = new Error(); + + __exports__ = Exception; + return __exports__; + })(); + + // handlebars/base.js + var __module2__ = (function (__dependency1__, __dependency2__) { + "use strict"; + var __exports__ = {}; + var Utils = __dependency1__; + var Exception = __dependency2__; + + var VERSION = "2.0.0"; + __exports__.VERSION = VERSION; var COMPILER_REVISION = 6; + __exports__.COMPILER_REVISION = COMPILER_REVISION; + var REVISION_CHANGES = { + 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it + 2: '== 1.0.0-rc.3', + 3: '== 1.0.0-rc.4', + 4: '== 1.x.x', + 5: '== 2.0.0-alpha.x', + 6: '>= 2.0.0-beta.1' + }; + __exports__.REVISION_CHANGES = REVISION_CHANGES; + var isArray = Utils.isArray, + isFunction = Utils.isFunction, + toString = Utils.toString, + objectType = '[object Object]'; + + function HandlebarsEnvironment(helpers, partials) { + this.helpers = helpers || {}; + this.partials = partials || {}; + + registerDefaultHelpers(this); + } + + __exports__.HandlebarsEnvironment = HandlebarsEnvironment; HandlebarsEnvironment.prototype = { + constructor: HandlebarsEnvironment, + + logger: logger, + log: log, + + registerHelper: function (name, fn) { + if (toString.call(name) === objectType) { + if (fn) { throw new Exception('Arg not supported with multiple helpers'); } + Utils.extend(this.helpers, name); + } else { + this.helpers[name] = fn; + } + }, + unregisterHelper: function (name) { + delete this.helpers[name]; + }, + + registerPartial: function (name, partial) { + if (toString.call(name) === objectType) { + Utils.extend(this.partials, name); + } else { + this.partials[name] = partial; + } + }, + unregisterPartial: function (name) { + delete this.partials[name]; + } + }; + + function registerDefaultHelpers(instance) { + instance.registerHelper('helperMissing', function (/* [args, ]options */) { + if (arguments.length === 1) { + // A missing field in a {{foo}} constuct. + return undefined; + } else { + // Someone is actually trying to call something, blow up. + throw new Exception("Missing helper: '" + arguments[arguments.length - 1].name + "'"); + } + }); + + instance.registerHelper('blockHelperMissing', function (context, options) { + var inverse = options.inverse, + fn = options.fn; + + if (context === true) { + return fn(this); + } else if (context === false || context == null) { + return inverse(this); + } else if (isArray(context)) { + if (context.length > 0) { + if (options.ids) { + options.ids = [options.name]; + } + + return instance.helpers.each(context, options); + } else { + return inverse(this); + } + } else { + if (options.data && options.ids) { + var data = createFrame(options.data); + data.contextPath = Utils.appendContextPath(options.data.contextPath, options.name); + options = { data: data }; + } + + return fn(context, options); + } + }); + + instance.registerHelper('each', function (context, options) { + if (!options) { + throw new Exception('Must pass iterator to #each'); + } + + var fn = options.fn, inverse = options.inverse; + var i = 0, ret = "", data; + + var contextPath; + if (options.data && options.ids) { + contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.'; + } + + if (isFunction(context)) { context = context.call(this); } + + if (options.data) { + data = createFrame(options.data); + } + + if (context && typeof context === 'object') { + if (isArray(context)) { + for (var j = context.length; i < j; i++) { + if (data) { + data.index = i; + data.first = (i === 0); + data.last = (i === (context.length - 1)); + + if (contextPath) { + data.contextPath = contextPath + i; + } + } + ret = ret + fn(context[i], { data: data }); + } + } else { + for (var key in context) { + if (context.hasOwnProperty(key)) { + if (data) { + data.key = key; + data.index = i; + data.first = (i === 0); + + if (contextPath) { + data.contextPath = contextPath + key; + } + } + ret = ret + fn(context[key], { data: data }); + i++; + } + } + } + } + + if (i === 0) { + ret = inverse(this); + } + + return ret; + }); + + instance.registerHelper('if', function (conditional, options) { + if (isFunction(conditional)) { conditional = conditional.call(this); } + + // Default behavior is to render the positive path if the value is truthy and not empty. + // The `includeZero` option may be set to treat the condtional as purely not empty based on the + // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative. + if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) { + return options.inverse(this); + } else { + return options.fn(this); + } + }); + + instance.registerHelper('unless', function (conditional, options) { + return instance.helpers['if'].call(this, conditional, { fn: options.inverse, inverse: options.fn, hash: options.hash }); + }); + + instance.registerHelper('with', function (context, options) { + if (isFunction(context)) { context = context.call(this); } + + var fn = options.fn; + + if (!Utils.isEmpty(context)) { + if (options.data && options.ids) { + var data = createFrame(options.data); + data.contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]); + options = { data: data }; + } + + return fn(context, options); + } else { + return options.inverse(this); + } + }); + + instance.registerHelper('log', function (message, options) { + var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1; + instance.log(level, message); + }); + + instance.registerHelper('lookup', function (obj, field) { + return obj && obj[field]; + }); + } + + var logger = { + methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' }, + + // State enum + DEBUG: 0, + INFO: 1, + WARN: 2, + ERROR: 3, + level: 3, + + // can be overridden in the host environment + log: function (level, message) { + if (logger.level <= level) { + var method = logger.methodMap[level]; + if (typeof console !== 'undefined' && console[method]) { + console[method].call(console, message); + } + } + } + }; + __exports__.logger = logger; + var log = logger.log; + __exports__.log = log; + var createFrame = function (object) { + var frame = Utils.extend({}, object); + frame._parent = object; + return frame; + }; + __exports__.createFrame = createFrame; + return __exports__; + })(__module3__, __module5__); + + // handlebars/runtime.js + var __module6__ = (function (__dependency1__, __dependency2__, __dependency3__) { + "use strict"; + var __exports__ = {}; + var Utils = __dependency1__; + var Exception = __dependency2__; + var COMPILER_REVISION = __dependency3__.COMPILER_REVISION; + var REVISION_CHANGES = __dependency3__.REVISION_CHANGES; + var createFrame = __dependency3__.createFrame; + + function checkRevision(compilerInfo) { + var compilerRevision = compilerInfo && compilerInfo[0] || 1, + currentRevision = COMPILER_REVISION; + + if (compilerRevision !== currentRevision) { + if (compilerRevision < currentRevision) { + var runtimeVersions = REVISION_CHANGES[currentRevision], + compilerVersions = REVISION_CHANGES[compilerRevision]; + throw new Exception("Template was precompiled with an older version of Handlebars than the current runtime. " + + "Please update your precompiler to a newer version (" + runtimeVersions + ") or downgrade your runtime to an older version (" + compilerVersions + ")."); + } else { + // Use the embedded version info since the runtime doesn't know about this revision yet + throw new Exception("Template was precompiled with a newer version of Handlebars than the current runtime. " + + "Please update your runtime to a newer version (" + compilerInfo[1] + ")."); + } + } + } + + __exports__.checkRevision = checkRevision;// TODO: Remove this line and break up compilePartial + + function template(templateSpec, env) { + /* istanbul ignore next */ + if (!env) { + throw new Exception("No environment passed to template"); + } + if (!templateSpec || !templateSpec.main) { + throw new Exception('Unknown template object: ' + typeof templateSpec); + } + + // Note: Using env.VM references rather than local var references throughout this section to allow + // for external users to override these as psuedo-supported APIs. + env.VM.checkRevision(templateSpec.compiler); + + var invokePartialWrapper = function (partial, indent, name, context, hash, helpers, partials, data, depths) { + if (hash) { + context = Utils.extend({}, context, hash); + } + + var result = env.VM.invokePartial.call(this, partial, name, context, helpers, partials, data, depths); + + if (result == null && env.compile) { + var options = { helpers: helpers, partials: partials, data: data, depths: depths }; + partials[name] = env.compile(partial, { data: data !== undefined, compat: templateSpec.compat }, env); + result = partials[name](context, options); + } + if (result != null) { + if (indent) { + var lines = result.split('\n'); + for (var i = 0, l = lines.length; i < l; i++) { + if (!lines[i] && i + 1 === l) { + break; + } + + lines[i] = indent + lines[i]; + } + result = lines.join('\n'); + } + return result; + } else { + throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode"); + } + }; + + // Just add water + var container = { + lookup: function (depths, name) { + var len = depths.length; + for (var i = 0; i < len; i++) { + if (depths[i] && depths[i][name] != null) { + return depths[i][name]; + } + } + }, + lambda: function (current, context) { + return typeof current === 'function' ? current.call(context) : current; + }, + + escapeExpression: Utils.escapeExpression, + invokePartial: invokePartialWrapper, + + fn: function (i) { + return templateSpec[i]; + }, + + programs: [], + program: function (i, data, depths) { + var programWrapper = this.programs[i], + fn = this.fn(i); + if (data || depths) { + programWrapper = program(this, i, fn, data, depths); + } else if (!programWrapper) { + programWrapper = this.programs[i] = program(this, i, fn); + } + return programWrapper; + }, + + data: function (data, depth) { + while (data && depth--) { + data = data._parent; + } + return data; + }, + merge: function (param, common) { + var ret = param || common; + + if (param && common && (param !== common)) { + ret = Utils.extend({}, common, param); + } + + return ret; + }, + + noop: env.VM.noop, + compilerInfo: templateSpec.compiler + }; + + var ret = function (context, options) { + options = options || {}; + var data = options.data; + + ret._setup(options); + if (!options.partial && templateSpec.useData) { + data = initData(context, data); + } + var depths; + if (templateSpec.useDepths) { + depths = options.depths ? [context].concat(options.depths) : [context]; + } + + return templateSpec.main.call(container, context, container.helpers, container.partials, data, depths); + }; + ret.isTop = true; + + ret._setup = function (options) { + if (!options.partial) { + container.helpers = container.merge(options.helpers, env.helpers); + + if (templateSpec.usePartial) { + container.partials = container.merge(options.partials, env.partials); + } + } else { + container.helpers = options.helpers; + container.partials = options.partials; + } + }; + + ret._child = function (i, data, depths) { + if (templateSpec.useDepths && !depths) { + throw new Exception('must pass parent depths'); + } + + return program(container, i, templateSpec[i], data, depths); + }; + return ret; + } + + __exports__.template = template; function program(container, i, fn, data, depths) { + var prog = function (context, options) { + options = options || {}; + + return fn.call(container, context, container.helpers, container.partials, options.data || data, depths && [context].concat(depths)); + }; + prog.program = i; + prog.depth = depths ? depths.length : 0; + return prog; + } + + __exports__.program = program; function invokePartial(partial, name, context, helpers, partials, data, depths) { + var options = { partial: true, helpers: helpers, partials: partials, data: data, depths: depths }; + + if (partial === undefined) { + throw new Exception("The partial " + name + " could not be found"); + } else if (partial instanceof Function) { + return partial(context, options); + } + } + + __exports__.invokePartial = invokePartial; function noop() { return ""; } + + __exports__.noop = noop; function initData(context, data) { + if (!data || !('root' in data)) { + data = data ? createFrame(data) : {}; + data.root = context; + } + return data; + } + return __exports__; + })(__module3__, __module5__, __module2__); + + // handlebars.runtime.js + var __module1__ = (function (__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) { + "use strict"; + var __exports__; + /*globals Handlebars: true */ + var base = __dependency1__; + + // Each of these augment the Handlebars object. No need to setup here. + // (This is done to easily share code between commonjs and browse envs) + var SafeString = __dependency2__; + var Exception = __dependency3__; + var Utils = __dependency4__; + var runtime = __dependency5__; + + // For compatibility and usage outside of module systems, make the Handlebars object a namespace + var create = function () { + var hb = new base.HandlebarsEnvironment(); + + Utils.extend(hb, base); + hb.SafeString = SafeString; + hb.Exception = Exception; + hb.Utils = Utils; + hb.escapeExpression = Utils.escapeExpression; + + hb.VM = runtime; + hb.template = function (spec) { + return runtime.template(spec, hb); + }; + + return hb; + }; + + var Handlebars = create(); + Handlebars.create = create; + + Handlebars['default'] = Handlebars; + + __exports__ = Handlebars; + return __exports__; + })(__module2__, __module4__, __module5__, __module3__, __module6__); + + // handlebars/compiler/ast.js + var __module7__ = (function (__dependency1__) { + "use strict"; + var __exports__; + var Exception = __dependency1__; + + function LocationInfo(locInfo) { + locInfo = locInfo || {}; + this.firstLine = locInfo.first_line; + this.firstColumn = locInfo.first_column; + this.lastColumn = locInfo.last_column; + this.lastLine = locInfo.last_line; + } + + var AST = { + ProgramNode: function (statements, strip, locInfo) { + LocationInfo.call(this, locInfo); + this.type = "program"; + this.statements = statements; + this.strip = strip; + }, + + MustacheNode: function (rawParams, hash, open, strip, locInfo) { + LocationInfo.call(this, locInfo); + this.type = "mustache"; + this.strip = strip; + + // Open may be a string parsed from the parser or a passed boolean flag + if (open != null && open.charAt) { + // Must use charAt to support IE pre-10 + var escapeFlag = open.charAt(3) || open.charAt(2); + this.escaped = escapeFlag !== '{' && escapeFlag !== '&'; + } else { + this.escaped = !!open; + } + + if (rawParams instanceof AST.SexprNode) { + this.sexpr = rawParams; + } else { + // Support old AST API + this.sexpr = new AST.SexprNode(rawParams, hash); + } + + // Support old AST API that stored this info in MustacheNode + this.id = this.sexpr.id; + this.params = this.sexpr.params; + this.hash = this.sexpr.hash; + this.eligibleHelper = this.sexpr.eligibleHelper; + this.isHelper = this.sexpr.isHelper; + }, + + SexprNode: function (rawParams, hash, locInfo) { + LocationInfo.call(this, locInfo); + + this.type = "sexpr"; + this.hash = hash; + + var id = this.id = rawParams[0]; + var params = this.params = rawParams.slice(1); + + // a mustache is definitely a helper if: + // * it is an eligible helper, and + // * it has at least one parameter or hash segment + this.isHelper = !!(params.length || hash); + + // a mustache is an eligible helper if: + // * its id is simple (a single part, not `this` or `..`) + this.eligibleHelper = this.isHelper || id.isSimple; + + // if a mustache is an eligible helper but not a definite + // helper, it is ambiguous, and will be resolved in a later + // pass or at runtime. + }, + + PartialNode: function (partialName, context, hash, strip, locInfo) { + LocationInfo.call(this, locInfo); + this.type = "partial"; + this.partialName = partialName; + this.context = context; + this.hash = hash; + this.strip = strip; + + this.strip.inlineStandalone = true; + }, + + BlockNode: function (mustache, program, inverse, strip, locInfo) { + LocationInfo.call(this, locInfo); + + this.type = 'block'; + this.mustache = mustache; + this.program = program; + this.inverse = inverse; + this.strip = strip; + + if (inverse && !program) { + this.isInverse = true; + } + }, + + RawBlockNode: function (mustache, content, close, locInfo) { + LocationInfo.call(this, locInfo); + + if (mustache.sexpr.id.original !== close) { + throw new Exception(mustache.sexpr.id.original + " doesn't match " + close, this); + } + + content = new AST.ContentNode(content, locInfo); + + this.type = 'block'; + this.mustache = mustache; + this.program = new AST.ProgramNode([content], {}, locInfo); + }, + + ContentNode: function (string, locInfo) { + LocationInfo.call(this, locInfo); + this.type = "content"; + this.original = this.string = string; + }, + + HashNode: function (pairs, locInfo) { + LocationInfo.call(this, locInfo); + this.type = "hash"; + this.pairs = pairs; + }, + + IdNode: function (parts, locInfo) { + LocationInfo.call(this, locInfo); + this.type = "ID"; + + var original = "", + dig = [], + depth = 0, + depthString = ''; + + for (var i = 0, l = parts.length; i < l; i++) { + var part = parts[i].part; + original += (parts[i].separator || '') + part; + + if (part === ".." || part === "." || part === "this") { + if (dig.length > 0) { + throw new Exception("Invalid path: " + original, this); + } else if (part === "..") { + depth++; + depthString += '../'; + } else { + this.isScoped = true; + } + } else { + dig.push(part); + } + } + + this.original = original; + this.parts = dig; + this.string = dig.join('.'); + this.depth = depth; + this.idName = depthString + this.string; + + // an ID is simple if it only has one part, and that part is not + // `..` or `this`. + this.isSimple = parts.length === 1 && !this.isScoped && depth === 0; + + this.stringModeValue = this.string; + }, + + PartialNameNode: function (name, locInfo) { + LocationInfo.call(this, locInfo); + this.type = "PARTIAL_NAME"; + this.name = name.original; + }, + + DataNode: function (id, locInfo) { + LocationInfo.call(this, locInfo); + this.type = "DATA"; + this.id = id; + this.stringModeValue = id.stringModeValue; + this.idName = '@' + id.stringModeValue; + }, + + StringNode: function (string, locInfo) { + LocationInfo.call(this, locInfo); + this.type = "STRING"; + this.original = + this.string = + this.stringModeValue = string; + }, + + NumberNode: function (number, locInfo) { + LocationInfo.call(this, locInfo); + this.type = "NUMBER"; + this.original = + this.number = number; + this.stringModeValue = Number(number); + }, + + BooleanNode: function (bool, locInfo) { + LocationInfo.call(this, locInfo); + this.type = "BOOLEAN"; + this.bool = bool; + this.stringModeValue = bool === "true"; + }, + + CommentNode: function (comment, locInfo) { + LocationInfo.call(this, locInfo); + this.type = "comment"; + this.comment = comment; + + this.strip = { + inlineStandalone: true + }; + } + }; + + + // Must be exported as an object rather than the root of the module as the jison lexer + // most modify the object to operate properly. + __exports__ = AST; + return __exports__; + })(__module5__); + + // handlebars/compiler/parser.js + var __module9__ = (function () { + "use strict"; + var __exports__; + /* jshint ignore:start */ + /* istanbul ignore next */ + /* Jison generated parser */ + var handlebars = (function () { + var parser = { + trace: function trace() { }, + yy: {}, + symbols_: { "error": 2, "root": 3, "program": 4, "EOF": 5, "program_repetition0": 6, "statement": 7, "mustache": 8, "block": 9, "rawBlock": 10, "partial": 11, "CONTENT": 12, "COMMENT": 13, "openRawBlock": 14, "END_RAW_BLOCK": 15, "OPEN_RAW_BLOCK": 16, "sexpr": 17, "CLOSE_RAW_BLOCK": 18, "openBlock": 19, "block_option0": 20, "closeBlock": 21, "openInverse": 22, "block_option1": 23, "OPEN_BLOCK": 24, "CLOSE": 25, "OPEN_INVERSE": 26, "inverseAndProgram": 27, "INVERSE": 28, "OPEN_ENDBLOCK": 29, "path": 30, "OPEN": 31, "OPEN_UNESCAPED": 32, "CLOSE_UNESCAPED": 33, "OPEN_PARTIAL": 34, "partialName": 35, "param": 36, "partial_option0": 37, "partial_option1": 38, "sexpr_repetition0": 39, "sexpr_option0": 40, "dataName": 41, "STRING": 42, "NUMBER": 43, "BOOLEAN": 44, "OPEN_SEXPR": 45, "CLOSE_SEXPR": 46, "hash": 47, "hash_repetition_plus0": 48, "hashSegment": 49, "ID": 50, "EQUALS": 51, "DATA": 52, "pathSegments": 53, "SEP": 54, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 5: "EOF", 12: "CONTENT", 13: "COMMENT", 15: "END_RAW_BLOCK", 16: "OPEN_RAW_BLOCK", 18: "CLOSE_RAW_BLOCK", 24: "OPEN_BLOCK", 25: "CLOSE", 26: "OPEN_INVERSE", 28: "INVERSE", 29: "OPEN_ENDBLOCK", 31: "OPEN", 32: "OPEN_UNESCAPED", 33: "CLOSE_UNESCAPED", 34: "OPEN_PARTIAL", 42: "STRING", 43: "NUMBER", 44: "BOOLEAN", 45: "OPEN_SEXPR", 46: "CLOSE_SEXPR", 50: "ID", 51: "EQUALS", 52: "DATA", 54: "SEP" }, + productions_: [0, [3, 2], [4, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [10, 3], [14, 3], [9, 4], [9, 4], [19, 3], [22, 3], [27, 2], [21, 3], [8, 3], [8, 3], [11, 5], [11, 4], [17, 3], [17, 1], [36, 1], [36, 1], [36, 1], [36, 1], [36, 1], [36, 3], [47, 1], [49, 3], [35, 1], [35, 1], [35, 1], [41, 2], [30, 1], [53, 3], [53, 1], [6, 0], [6, 2], [20, 0], [20, 1], [23, 0], [23, 1], [37, 0], [37, 1], [38, 0], [38, 1], [39, 0], [39, 2], [40, 0], [40, 1], [48, 1], [48, 2]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + + var $0 = $$.length - 1; + switch (yystate) { + case 1: yy.prepareProgram($$[$0 - 1].statements, true); return $$[$0 - 1]; + break; + case 2: this.$ = new yy.ProgramNode(yy.prepareProgram($$[$0]), {}, this._$); + break; + case 3: this.$ = $$[$0]; + break; + case 4: this.$ = $$[$0]; + break; + case 5: this.$ = $$[$0]; + break; + case 6: this.$ = $$[$0]; + break; + case 7: this.$ = new yy.ContentNode($$[$0], this._$); + break; + case 8: this.$ = new yy.CommentNode($$[$0], this._$); + break; + case 9: this.$ = new yy.RawBlockNode($$[$0 - 2], $$[$0 - 1], $$[$0], this._$); + break; + case 10: this.$ = new yy.MustacheNode($$[$0 - 1], null, '', '', this._$); + break; + case 11: this.$ = yy.prepareBlock($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0], false, this._$); + break; + case 12: this.$ = yy.prepareBlock($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0], true, this._$); + break; + case 13: this.$ = new yy.MustacheNode($$[$0 - 1], null, $$[$0 - 2], yy.stripFlags($$[$0 - 2], $$[$0]), this._$); + break; + case 14: this.$ = new yy.MustacheNode($$[$0 - 1], null, $$[$0 - 2], yy.stripFlags($$[$0 - 2], $$[$0]), this._$); + break; + case 15: this.$ = { strip: yy.stripFlags($$[$0 - 1], $$[$0 - 1]), program: $$[$0] }; + break; + case 16: this.$ = { path: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 2], $$[$0]) }; + break; + case 17: this.$ = new yy.MustacheNode($$[$0 - 1], null, $$[$0 - 2], yy.stripFlags($$[$0 - 2], $$[$0]), this._$); + break; + case 18: this.$ = new yy.MustacheNode($$[$0 - 1], null, $$[$0 - 2], yy.stripFlags($$[$0 - 2], $$[$0]), this._$); + break; + case 19: this.$ = new yy.PartialNode($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], yy.stripFlags($$[$0 - 4], $$[$0]), this._$); + break; + case 20: this.$ = new yy.PartialNode($$[$0 - 2], undefined, $$[$0 - 1], yy.stripFlags($$[$0 - 3], $$[$0]), this._$); + break; + case 21: this.$ = new yy.SexprNode([$$[$0 - 2]].concat($$[$0 - 1]), $$[$0], this._$); + break; + case 22: this.$ = new yy.SexprNode([$$[$0]], null, this._$); + break; + case 23: this.$ = $$[$0]; + break; + case 24: this.$ = new yy.StringNode($$[$0], this._$); + break; + case 25: this.$ = new yy.NumberNode($$[$0], this._$); + break; + case 26: this.$ = new yy.BooleanNode($$[$0], this._$); + break; + case 27: this.$ = $$[$0]; + break; + case 28: $$[$0 - 1].isHelper = true; this.$ = $$[$0 - 1]; + break; + case 29: this.$ = new yy.HashNode($$[$0], this._$); + break; + case 30: this.$ = [$$[$0 - 2], $$[$0]]; + break; + case 31: this.$ = new yy.PartialNameNode($$[$0], this._$); + break; + case 32: this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0], this._$), this._$); + break; + case 33: this.$ = new yy.PartialNameNode(new yy.NumberNode($$[$0], this._$)); + break; + case 34: this.$ = new yy.DataNode($$[$0], this._$); + break; + case 35: this.$ = new yy.IdNode($$[$0], this._$); + break; + case 36: $$[$0 - 2].push({ part: $$[$0], separator: $$[$0 - 1] }); this.$ = $$[$0 - 2]; + break; + case 37: this.$ = [{ part: $$[$0] }]; + break; + case 38: this.$ = []; + break; + case 39: $$[$0 - 1].push($$[$0]); + break; + case 48: this.$ = []; + break; + case 49: $$[$0 - 1].push($$[$0]); + break; + case 52: this.$ = [$$[$0]]; + break; + case 53: $$[$0 - 1].push($$[$0]); + break; + } + }, + table: [{ 3: 1, 4: 2, 5: [2, 38], 6: 3, 12: [2, 38], 13: [2, 38], 16: [2, 38], 24: [2, 38], 26: [2, 38], 31: [2, 38], 32: [2, 38], 34: [2, 38] }, { 1: [3] }, { 5: [1, 4] }, { 5: [2, 2], 7: 5, 8: 6, 9: 7, 10: 8, 11: 9, 12: [1, 10], 13: [1, 11], 14: 16, 16: [1, 20], 19: 14, 22: 15, 24: [1, 18], 26: [1, 19], 28: [2, 2], 29: [2, 2], 31: [1, 12], 32: [1, 13], 34: [1, 17] }, { 1: [2, 1] }, { 5: [2, 39], 12: [2, 39], 13: [2, 39], 16: [2, 39], 24: [2, 39], 26: [2, 39], 28: [2, 39], 29: [2, 39], 31: [2, 39], 32: [2, 39], 34: [2, 39] }, { 5: [2, 3], 12: [2, 3], 13: [2, 3], 16: [2, 3], 24: [2, 3], 26: [2, 3], 28: [2, 3], 29: [2, 3], 31: [2, 3], 32: [2, 3], 34: [2, 3] }, { 5: [2, 4], 12: [2, 4], 13: [2, 4], 16: [2, 4], 24: [2, 4], 26: [2, 4], 28: [2, 4], 29: [2, 4], 31: [2, 4], 32: [2, 4], 34: [2, 4] }, { 5: [2, 5], 12: [2, 5], 13: [2, 5], 16: [2, 5], 24: [2, 5], 26: [2, 5], 28: [2, 5], 29: [2, 5], 31: [2, 5], 32: [2, 5], 34: [2, 5] }, { 5: [2, 6], 12: [2, 6], 13: [2, 6], 16: [2, 6], 24: [2, 6], 26: [2, 6], 28: [2, 6], 29: [2, 6], 31: [2, 6], 32: [2, 6], 34: [2, 6] }, { 5: [2, 7], 12: [2, 7], 13: [2, 7], 16: [2, 7], 24: [2, 7], 26: [2, 7], 28: [2, 7], 29: [2, 7], 31: [2, 7], 32: [2, 7], 34: [2, 7] }, { 5: [2, 8], 12: [2, 8], 13: [2, 8], 16: [2, 8], 24: [2, 8], 26: [2, 8], 28: [2, 8], 29: [2, 8], 31: [2, 8], 32: [2, 8], 34: [2, 8] }, { 17: 21, 30: 22, 41: 23, 50: [1, 26], 52: [1, 25], 53: 24 }, { 17: 27, 30: 22, 41: 23, 50: [1, 26], 52: [1, 25], 53: 24 }, { 4: 28, 6: 3, 12: [2, 38], 13: [2, 38], 16: [2, 38], 24: [2, 38], 26: [2, 38], 28: [2, 38], 29: [2, 38], 31: [2, 38], 32: [2, 38], 34: [2, 38] }, { 4: 29, 6: 3, 12: [2, 38], 13: [2, 38], 16: [2, 38], 24: [2, 38], 26: [2, 38], 28: [2, 38], 29: [2, 38], 31: [2, 38], 32: [2, 38], 34: [2, 38] }, { 12: [1, 30] }, { 30: 32, 35: 31, 42: [1, 33], 43: [1, 34], 50: [1, 26], 53: 24 }, { 17: 35, 30: 22, 41: 23, 50: [1, 26], 52: [1, 25], 53: 24 }, { 17: 36, 30: 22, 41: 23, 50: [1, 26], 52: [1, 25], 53: 24 }, { 17: 37, 30: 22, 41: 23, 50: [1, 26], 52: [1, 25], 53: 24 }, { 25: [1, 38] }, { 18: [2, 48], 25: [2, 48], 33: [2, 48], 39: 39, 42: [2, 48], 43: [2, 48], 44: [2, 48], 45: [2, 48], 46: [2, 48], 50: [2, 48], 52: [2, 48] }, { 18: [2, 22], 25: [2, 22], 33: [2, 22], 46: [2, 22] }, { 18: [2, 35], 25: [2, 35], 33: [2, 35], 42: [2, 35], 43: [2, 35], 44: [2, 35], 45: [2, 35], 46: [2, 35], 50: [2, 35], 52: [2, 35], 54: [1, 40] }, { 30: 41, 50: [1, 26], 53: 24 }, { 18: [2, 37], 25: [2, 37], 33: [2, 37], 42: [2, 37], 43: [2, 37], 44: [2, 37], 45: [2, 37], 46: [2, 37], 50: [2, 37], 52: [2, 37], 54: [2, 37] }, { 33: [1, 42] }, { 20: 43, 27: 44, 28: [1, 45], 29: [2, 40] }, { 23: 46, 27: 47, 28: [1, 45], 29: [2, 42] }, { 15: [1, 48] }, { 25: [2, 46], 30: 51, 36: 49, 38: 50, 41: 55, 42: [1, 52], 43: [1, 53], 44: [1, 54], 45: [1, 56], 47: 57, 48: 58, 49: 60, 50: [1, 59], 52: [1, 25], 53: 24 }, { 25: [2, 31], 42: [2, 31], 43: [2, 31], 44: [2, 31], 45: [2, 31], 50: [2, 31], 52: [2, 31] }, { 25: [2, 32], 42: [2, 32], 43: [2, 32], 44: [2, 32], 45: [2, 32], 50: [2, 32], 52: [2, 32] }, { 25: [2, 33], 42: [2, 33], 43: [2, 33], 44: [2, 33], 45: [2, 33], 50: [2, 33], 52: [2, 33] }, { 25: [1, 61] }, { 25: [1, 62] }, { 18: [1, 63] }, { 5: [2, 17], 12: [2, 17], 13: [2, 17], 16: [2, 17], 24: [2, 17], 26: [2, 17], 28: [2, 17], 29: [2, 17], 31: [2, 17], 32: [2, 17], 34: [2, 17] }, { 18: [2, 50], 25: [2, 50], 30: 51, 33: [2, 50], 36: 65, 40: 64, 41: 55, 42: [1, 52], 43: [1, 53], 44: [1, 54], 45: [1, 56], 46: [2, 50], 47: 66, 48: 58, 49: 60, 50: [1, 59], 52: [1, 25], 53: 24 }, { 50: [1, 67] }, { 18: [2, 34], 25: [2, 34], 33: [2, 34], 42: [2, 34], 43: [2, 34], 44: [2, 34], 45: [2, 34], 46: [2, 34], 50: [2, 34], 52: [2, 34] }, { 5: [2, 18], 12: [2, 18], 13: [2, 18], 16: [2, 18], 24: [2, 18], 26: [2, 18], 28: [2, 18], 29: [2, 18], 31: [2, 18], 32: [2, 18], 34: [2, 18] }, { 21: 68, 29: [1, 69] }, { 29: [2, 41] }, { 4: 70, 6: 3, 12: [2, 38], 13: [2, 38], 16: [2, 38], 24: [2, 38], 26: [2, 38], 29: [2, 38], 31: [2, 38], 32: [2, 38], 34: [2, 38] }, { 21: 71, 29: [1, 69] }, { 29: [2, 43] }, { 5: [2, 9], 12: [2, 9], 13: [2, 9], 16: [2, 9], 24: [2, 9], 26: [2, 9], 28: [2, 9], 29: [2, 9], 31: [2, 9], 32: [2, 9], 34: [2, 9] }, { 25: [2, 44], 37: 72, 47: 73, 48: 58, 49: 60, 50: [1, 74] }, { 25: [1, 75] }, { 18: [2, 23], 25: [2, 23], 33: [2, 23], 42: [2, 23], 43: [2, 23], 44: [2, 23], 45: [2, 23], 46: [2, 23], 50: [2, 23], 52: [2, 23] }, { 18: [2, 24], 25: [2, 24], 33: [2, 24], 42: [2, 24], 43: [2, 24], 44: [2, 24], 45: [2, 24], 46: [2, 24], 50: [2, 24], 52: [2, 24] }, { 18: [2, 25], 25: [2, 25], 33: [2, 25], 42: [2, 25], 43: [2, 25], 44: [2, 25], 45: [2, 25], 46: [2, 25], 50: [2, 25], 52: [2, 25] }, { 18: [2, 26], 25: [2, 26], 33: [2, 26], 42: [2, 26], 43: [2, 26], 44: [2, 26], 45: [2, 26], 46: [2, 26], 50: [2, 26], 52: [2, 26] }, { 18: [2, 27], 25: [2, 27], 33: [2, 27], 42: [2, 27], 43: [2, 27], 44: [2, 27], 45: [2, 27], 46: [2, 27], 50: [2, 27], 52: [2, 27] }, { 17: 76, 30: 22, 41: 23, 50: [1, 26], 52: [1, 25], 53: 24 }, { 25: [2, 47] }, { 18: [2, 29], 25: [2, 29], 33: [2, 29], 46: [2, 29], 49: 77, 50: [1, 74] }, { 18: [2, 37], 25: [2, 37], 33: [2, 37], 42: [2, 37], 43: [2, 37], 44: [2, 37], 45: [2, 37], 46: [2, 37], 50: [2, 37], 51: [1, 78], 52: [2, 37], 54: [2, 37] }, { 18: [2, 52], 25: [2, 52], 33: [2, 52], 46: [2, 52], 50: [2, 52] }, { 12: [2, 13], 13: [2, 13], 16: [2, 13], 24: [2, 13], 26: [2, 13], 28: [2, 13], 29: [2, 13], 31: [2, 13], 32: [2, 13], 34: [2, 13] }, { 12: [2, 14], 13: [2, 14], 16: [2, 14], 24: [2, 14], 26: [2, 14], 28: [2, 14], 29: [2, 14], 31: [2, 14], 32: [2, 14], 34: [2, 14] }, { 12: [2, 10] }, { 18: [2, 21], 25: [2, 21], 33: [2, 21], 46: [2, 21] }, { 18: [2, 49], 25: [2, 49], 33: [2, 49], 42: [2, 49], 43: [2, 49], 44: [2, 49], 45: [2, 49], 46: [2, 49], 50: [2, 49], 52: [2, 49] }, { 18: [2, 51], 25: [2, 51], 33: [2, 51], 46: [2, 51] }, { 18: [2, 36], 25: [2, 36], 33: [2, 36], 42: [2, 36], 43: [2, 36], 44: [2, 36], 45: [2, 36], 46: [2, 36], 50: [2, 36], 52: [2, 36], 54: [2, 36] }, { 5: [2, 11], 12: [2, 11], 13: [2, 11], 16: [2, 11], 24: [2, 11], 26: [2, 11], 28: [2, 11], 29: [2, 11], 31: [2, 11], 32: [2, 11], 34: [2, 11] }, { 30: 79, 50: [1, 26], 53: 24 }, { 29: [2, 15] }, { 5: [2, 12], 12: [2, 12], 13: [2, 12], 16: [2, 12], 24: [2, 12], 26: [2, 12], 28: [2, 12], 29: [2, 12], 31: [2, 12], 32: [2, 12], 34: [2, 12] }, { 25: [1, 80] }, { 25: [2, 45] }, { 51: [1, 78] }, { 5: [2, 20], 12: [2, 20], 13: [2, 20], 16: [2, 20], 24: [2, 20], 26: [2, 20], 28: [2, 20], 29: [2, 20], 31: [2, 20], 32: [2, 20], 34: [2, 20] }, { 46: [1, 81] }, { 18: [2, 53], 25: [2, 53], 33: [2, 53], 46: [2, 53], 50: [2, 53] }, { 30: 51, 36: 82, 41: 55, 42: [1, 52], 43: [1, 53], 44: [1, 54], 45: [1, 56], 50: [1, 26], 52: [1, 25], 53: 24 }, { 25: [1, 83] }, { 5: [2, 19], 12: [2, 19], 13: [2, 19], 16: [2, 19], 24: [2, 19], 26: [2, 19], 28: [2, 19], 29: [2, 19], 31: [2, 19], 32: [2, 19], 34: [2, 19] }, { 18: [2, 28], 25: [2, 28], 33: [2, 28], 42: [2, 28], 43: [2, 28], 44: [2, 28], 45: [2, 28], 46: [2, 28], 50: [2, 28], 52: [2, 28] }, { 18: [2, 30], 25: [2, 30], 33: [2, 30], 46: [2, 30], 50: [2, 30] }, { 5: [2, 16], 12: [2, 16], 13: [2, 16], 16: [2, 16], 24: [2, 16], 26: [2, 16], 28: [2, 16], 29: [2, 16], 31: [2, 16], 32: [2, 16], 34: [2, 16] }], + defaultActions: { 4: [2, 1], 44: [2, 41], 47: [2, 43], 57: [2, 47], 63: [2, 10], 70: [2, 15], 73: [2, 45] }, + parseError: function parseError(str, hash) { + throw new Error(str); + }, + parse: function parse(input) { + var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1; + this.lexer.setInput(input); + this.lexer.yy = this.yy; + this.yy.lexer = this.lexer; + this.yy.parser = this; + if (typeof this.lexer.yylloc == "undefined") + this.lexer.yylloc = {}; + var yyloc = this.lexer.yylloc; + lstack.push(yyloc); + var ranges = this.lexer.options && this.lexer.options.ranges; + if (typeof this.yy.parseError === "function") + this.parseError = this.yy.parseError; + function popStack(n) { + stack.length = stack.length - 2 * n; + vstack.length = vstack.length - n; + lstack.length = lstack.length - n; + } + function lex() { + var token; + token = self.lexer.lex() || 1; + if (typeof token !== "number") { + token = self.symbols_[token] || token; + } + return token; + } + var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + if (!recovering) { + expected = []; + for (p in table[state]) + if (this.terminals_[p] && p > 2) { + expected.push("'" + this.terminals_[p] + "'"); + } + if (this.lexer.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1 ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected }); + } + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(this.lexer.yytext); + lstack.push(this.lexer.yylloc); + stack.push(action[1]); + symbol = null; + if (!preErrorSymbol) { + yyleng = this.lexer.yyleng; + yytext = this.lexer.yytext; + yylineno = this.lexer.yylineno; + yyloc = this.lexer.yylloc; + if (recovering > 0) + recovering--; + } else { + symbol = preErrorSymbol; + preErrorSymbol = null; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column }; + if (ranges) { + yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]]; + } + r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + /* Jison generated lexer */ + var lexer = (function () { + var lexer = ({ + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + setInput: function (input) { + this._input = input; + this._more = this._less = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ''; + this.conditionStack = ['INITIAL']; + this.yylloc = { first_line: 1, first_column: 0, last_line: 1, last_column: 0 }; + if (this.options.ranges) this.yylloc.range = [0, 0]; + this.offset = 0; + return this; + }, + input: function () { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) this.yylloc.range[1]++; + + this._input = this._input.slice(1); + return ch; + }, + unput: function (ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len - 1); + //this.yyleng -= len; + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + + if (lines.length - 1) this.yylineno -= lines.length - 1; + var r = this.yylloc.range; + + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? + (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : + this.yylloc.first_column - len + }; + + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + return this; + }, + more: function () { + this._more = true; + return this; + }, + less: function (n) { + this.unput(this.match.slice(n)); + }, + pastInput: function () { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? '...' : '') + past.substr(-20).replace(/\n/g, ""); + }, + upcomingInput: function () { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? '...' : '')).replace(/\n/g, ""); + }, + showPosition: function () { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + next: function () { + if (this.done) { + return this.EOF; + } + if (!this._input) this.done = true; + + var token, + match, + tempMatch, + index, + col, + lines; + if (!this._more) { + this.yytext = ''; + this.match = ''; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (!this.options.flex) break; + } + } + if (match) { + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) this.yylineno += lines.length; + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, rules[index], this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) this.done = false; + if (token) return token; + else return; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), + { text: "", token: null, line: this.yylineno }); + } + }, + lex: function lex() { + var r = this.next(); + if (typeof r !== 'undefined') { + return r; + } else { + return this.lex(); + } + }, + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + popState: function popState() { + return this.conditionStack.pop(); + }, + _currentRules: function _currentRules() { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + }, + topState: function () { + return this.conditionStack[this.conditionStack.length - 2]; + }, + pushState: function begin(condition) { + this.begin(condition); + } + }); + lexer.options = {}; + lexer.performAction = function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + + + function strip(start, end) { + return yy_.yytext = yy_.yytext.substr(start, yy_.yyleng - end); + } + + + var YYSTATE = YY_START + switch ($avoiding_name_collisions) { + case 0: + if (yy_.yytext.slice(-2) === "\\\\") { + strip(0, 1); + this.begin("mu"); + } else if (yy_.yytext.slice(-1) === "\\") { + strip(0, 1); + this.begin("emu"); + } else { + this.begin("mu"); + } + if (yy_.yytext) return 12; + + break; + case 1: return 12; + break; + case 2: + this.popState(); + return 12; + + break; + case 3: + yy_.yytext = yy_.yytext.substr(5, yy_.yyleng - 9); + this.popState(); + return 15; + + break; + case 4: return 12; + break; + case 5: strip(0, 4); this.popState(); return 13; + break; + case 6: return 45; + break; + case 7: return 46; + break; + case 8: return 16; + break; + case 9: + this.popState(); + this.begin('raw'); + return 18; + + break; + case 10: return 34; + break; + case 11: return 24; + break; + case 12: return 29; + break; + case 13: this.popState(); return 28; + break; + case 14: this.popState(); return 28; + break; + case 15: return 26; + break; + case 16: return 26; + break; + case 17: return 32; + break; + case 18: return 31; + break; + case 19: this.popState(); this.begin('com'); + break; + case 20: strip(3, 5); this.popState(); return 13; + break; + case 21: return 31; + break; + case 22: return 51; + break; + case 23: return 50; + break; + case 24: return 50; + break; + case 25: return 54; + break; + case 26:// ignore whitespace + break; + case 27: this.popState(); return 33; + break; + case 28: this.popState(); return 25; + break; + case 29: yy_.yytext = strip(1, 2).replace(/\\"/g, '"'); return 42; + break; + case 30: yy_.yytext = strip(1, 2).replace(/\\'/g, "'"); return 42; + break; + case 31: return 52; + break; + case 32: return 44; + break; + case 33: return 44; + break; + case 34: return 43; + break; + case 35: return 50; + break; + case 36: yy_.yytext = strip(1, 2); return 50; + break; + case 37: return 'INVALID'; + break; + case 38: return 5; + break; + } + }; + lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/, /^(?:[^\x00]+)/, /^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/, /^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/, /^(?:[^\x00]*?(?=(\{\{\{\{\/)))/, /^(?:[\s\S]*?--\}\})/, /^(?:\()/, /^(?:\))/, /^(?:\{\{\{\{)/, /^(?:\}\}\}\})/, /^(?:\{\{(~)?>)/, /^(?:\{\{(~)?#)/, /^(?:\{\{(~)?\/)/, /^(?:\{\{(~)?\^\s*(~)?\}\})/, /^(?:\{\{(~)?\s*else\s*(~)?\}\})/, /^(?:\{\{(~)?\^)/, /^(?:\{\{(~)?\s*else\b)/, /^(?:\{\{(~)?\{)/, /^(?:\{\{(~)?&)/, /^(?:\{\{!--)/, /^(?:\{\{![\s\S]*?\}\})/, /^(?:\{\{(~)?)/, /^(?:=)/, /^(?:\.\.)/, /^(?:\.(?=([=~}\s\/.)])))/, /^(?:[\/.])/, /^(?:\s+)/, /^(?:\}(~)?\}\})/, /^(?:(~)?\}\})/, /^(?:"(\\["]|[^"])*")/, /^(?:'(\\[']|[^'])*')/, /^(?:@)/, /^(?:true(?=([~}\s)])))/, /^(?:false(?=([~}\s)])))/, /^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/, /^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/, /^(?:\[[^\]]*\])/, /^(?:.)/, /^(?:$)/]; + lexer.conditions = { "mu": { "rules": [6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38], "inclusive": false }, "emu": { "rules": [2], "inclusive": false }, "com": { "rules": [5], "inclusive": false }, "raw": { "rules": [3, 4], "inclusive": false }, "INITIAL": { "rules": [0, 1, 38], "inclusive": true } }; + return lexer; + })() + parser.lexer = lexer; + function Parser() { this.yy = {}; } Parser.prototype = parser; parser.Parser = Parser; + return new Parser; + })(); __exports__ = handlebars; + /* jshint ignore:end */ + return __exports__; + })(); + + // handlebars/compiler/helpers.js + var __module10__ = (function (__dependency1__) { + "use strict"; + var __exports__ = {}; + var Exception = __dependency1__; + + function stripFlags(open, close) { + return { + left: open.charAt(2) === '~', + right: close.charAt(close.length - 3) === '~' + }; + } + + __exports__.stripFlags = stripFlags; + function prepareBlock(mustache, program, inverseAndProgram, close, inverted, locInfo) { + /*jshint -W040 */ + if (mustache.sexpr.id.original !== close.path.original) { + throw new Exception(mustache.sexpr.id.original + ' doesn\'t match ' + close.path.original, mustache); + } + + var inverse = inverseAndProgram && inverseAndProgram.program; + + var strip = { + left: mustache.strip.left, + right: close.strip.right, + + // Determine the standalone candiacy. Basically flag our content as being possibly standalone + // so our parent can determine if we actually are standalone + openStandalone: isNextWhitespace(program.statements), + closeStandalone: isPrevWhitespace((inverse || program).statements) + }; + + if (mustache.strip.right) { + omitRight(program.statements, null, true); + } + + if (inverse) { + var inverseStrip = inverseAndProgram.strip; + + if (inverseStrip.left) { + omitLeft(program.statements, null, true); + } + if (inverseStrip.right) { + omitRight(inverse.statements, null, true); + } + if (close.strip.left) { + omitLeft(inverse.statements, null, true); + } + + // Find standalone else statments + if (isPrevWhitespace(program.statements) + && isNextWhitespace(inverse.statements)) { + + omitLeft(program.statements); + omitRight(inverse.statements); + } + } else { + if (close.strip.left) { + omitLeft(program.statements, null, true); + } + } + + if (inverted) { + return new this.BlockNode(mustache, inverse, program, strip, locInfo); + } else { + return new this.BlockNode(mustache, program, inverse, strip, locInfo); + } + } + + __exports__.prepareBlock = prepareBlock; + function prepareProgram(statements, isRoot) { + for (var i = 0, l = statements.length; i < l; i++) { + var current = statements[i], + strip = current.strip; + + if (!strip) { + continue; + } + + var _isPrevWhitespace = isPrevWhitespace(statements, i, isRoot, current.type === 'partial'), + _isNextWhitespace = isNextWhitespace(statements, i, isRoot), + + openStandalone = strip.openStandalone && _isPrevWhitespace, + closeStandalone = strip.closeStandalone && _isNextWhitespace, + inlineStandalone = strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace; + + if (strip.right) { + omitRight(statements, i, true); + } + if (strip.left) { + omitLeft(statements, i, true); + } + + if (inlineStandalone) { + omitRight(statements, i); + + if (omitLeft(statements, i)) { + // If we are on a standalone node, save the indent info for partials + if (current.type === 'partial') { + current.indent = (/([ \t]+$)/).exec(statements[i - 1].original) ? RegExp.$1 : ''; + } + } + } + if (openStandalone) { + omitRight((current.program || current.inverse).statements); + + // Strip out the previous content node if it's whitespace only + omitLeft(statements, i); + } + if (closeStandalone) { + // Always strip the next node + omitRight(statements, i); + + omitLeft((current.inverse || current.program).statements); + } + } + + return statements; + } + + __exports__.prepareProgram = prepareProgram; function isPrevWhitespace(statements, i, isRoot) { + if (i === undefined) { + i = statements.length; + } + + // Nodes that end with newlines are considered whitespace (but are special + // cased for strip operations) + var prev = statements[i - 1], + sibling = statements[i - 2]; + if (!prev) { + return isRoot; + } + + if (prev.type === 'content') { + return (sibling || !isRoot ? (/\r?\n\s*?$/) : (/(^|\r?\n)\s*?$/)).test(prev.original); + } + } + function isNextWhitespace(statements, i, isRoot) { + if (i === undefined) { + i = -1; + } + + var next = statements[i + 1], + sibling = statements[i + 2]; + if (!next) { + return isRoot; + } + + if (next.type === 'content') { + return (sibling || !isRoot ? (/^\s*?\r?\n/) : (/^\s*?(\r?\n|$)/)).test(next.original); + } + } + + // Marks the node to the right of the position as omitted. + // I.e. {{foo}}' ' will mark the ' ' node as omitted. + // + // If i is undefined, then the first child will be marked as such. + // + // If mulitple is truthy then all whitespace will be stripped out until non-whitespace + // content is met. + function omitRight(statements, i, multiple) { + var current = statements[i == null ? 0 : i + 1]; + if (!current || current.type !== 'content' || (!multiple && current.rightStripped)) { + return; + } + + var original = current.string; + current.string = current.string.replace(multiple ? (/^\s+/) : (/^[ \t]*\r?\n?/), ''); + current.rightStripped = current.string !== original; + } + + // Marks the node to the left of the position as omitted. + // I.e. ' '{{foo}} will mark the ' ' node as omitted. + // + // If i is undefined then the last child will be marked as such. + // + // If mulitple is truthy then all whitespace will be stripped out until non-whitespace + // content is met. + function omitLeft(statements, i, multiple) { + var current = statements[i == null ? statements.length - 1 : i - 1]; + if (!current || current.type !== 'content' || (!multiple && current.leftStripped)) { + return; + } + + // We omit the last node if it's whitespace only and not preceeded by a non-content node. + var original = current.string; + current.string = current.string.replace(multiple ? (/\s+$/) : (/[ \t]+$/), ''); + current.leftStripped = current.string !== original; + return current.leftStripped; + } + return __exports__; + })(__module5__); + + // handlebars/compiler/base.js + var __module8__ = (function (__dependency1__, __dependency2__, __dependency3__, __dependency4__) { + "use strict"; + var __exports__ = {}; + var parser = __dependency1__; + var AST = __dependency2__; + var Helpers = __dependency3__; + var extend = __dependency4__.extend; + + __exports__.parser = parser; + + var yy = {}; + extend(yy, Helpers, AST); + + function parse(input) { + // Just return if an already-compile AST was passed in. + if (input.constructor === AST.ProgramNode) { return input; } + + parser.yy = yy; + + return parser.parse(input); + } + + __exports__.parse = parse; + return __exports__; + })(__module9__, __module7__, __module10__, __module3__); + + // handlebars/compiler/compiler.js + var __module11__ = (function (__dependency1__, __dependency2__) { + "use strict"; + var __exports__ = {}; + var Exception = __dependency1__; + var isArray = __dependency2__.isArray; + + var slice = [].slice; + + function Compiler() { } + + __exports__.Compiler = Compiler;// the foundHelper register will disambiguate helper lookup from finding a + // function in a context. This is necessary for mustache compatibility, which + // requires that context functions in blocks are evaluated by blockHelperMissing, + // and then proceed as if the resulting value was provided to blockHelperMissing. + + Compiler.prototype = { + compiler: Compiler, + + equals: function (other) { + var len = this.opcodes.length; + if (other.opcodes.length !== len) { + return false; + } + + for (var i = 0; i < len; i++) { + var opcode = this.opcodes[i], + otherOpcode = other.opcodes[i]; + if (opcode.opcode !== otherOpcode.opcode || !argEquals(opcode.args, otherOpcode.args)) { + return false; + } + } + + // We know that length is the same between the two arrays because they are directly tied + // to the opcode behavior above. + len = this.children.length; + for (i = 0; i < len; i++) { + if (!this.children[i].equals(other.children[i])) { + return false; + } + } + + return true; + }, + + guid: 0, + + compile: function (program, options) { + this.opcodes = []; + this.children = []; + this.depths = { list: [] }; + this.options = options; + this.stringParams = options.stringParams; + this.trackIds = options.trackIds; + + // These changes will propagate to the other compiler components + var knownHelpers = this.options.knownHelpers; + this.options.knownHelpers = { + 'helperMissing': true, + 'blockHelperMissing': true, + 'each': true, + 'if': true, + 'unless': true, + 'with': true, + 'log': true, + 'lookup': true + }; + if (knownHelpers) { + for (var name in knownHelpers) { + this.options.knownHelpers[name] = knownHelpers[name]; + } + } + + return this.accept(program); + }, + + accept: function (node) { + return this[node.type](node); + }, + + program: function (program) { + var statements = program.statements; + + for (var i = 0, l = statements.length; i < l; i++) { + this.accept(statements[i]); + } + this.isSimple = l === 1; + + this.depths.list = this.depths.list.sort(function (a, b) { + return a - b; + }); + + return this; + }, + + compileProgram: function (program) { + var result = new this.compiler().compile(program, this.options); + var guid = this.guid++, depth; + + this.usePartial = this.usePartial || result.usePartial; + + this.children[guid] = result; + + for (var i = 0, l = result.depths.list.length; i < l; i++) { + depth = result.depths.list[i]; + + if (depth < 2) { continue; } + else { this.addDepth(depth - 1); } + } + + return guid; + }, + + block: function (block) { + var mustache = block.mustache, + program = block.program, + inverse = block.inverse; + + if (program) { + program = this.compileProgram(program); + } + + if (inverse) { + inverse = this.compileProgram(inverse); + } + + var sexpr = mustache.sexpr; + var type = this.classifySexpr(sexpr); + + if (type === "helper") { + this.helperSexpr(sexpr, program, inverse); + } else if (type === "simple") { + this.simpleSexpr(sexpr); + + // now that the simple mustache is resolved, we need to + // evaluate it by executing `blockHelperMissing` + this.opcode('pushProgram', program); + this.opcode('pushProgram', inverse); + this.opcode('emptyHash'); + this.opcode('blockValue', sexpr.id.original); + } else { + this.ambiguousSexpr(sexpr, program, inverse); + + // now that the simple mustache is resolved, we need to + // evaluate it by executing `blockHelperMissing` + this.opcode('pushProgram', program); + this.opcode('pushProgram', inverse); + this.opcode('emptyHash'); + this.opcode('ambiguousBlockValue'); + } + + this.opcode('append'); + }, + + hash: function (hash) { + var pairs = hash.pairs, i, l; + + this.opcode('pushHash'); + + for (i = 0, l = pairs.length; i < l; i++) { + this.pushParam(pairs[i][1]); + } + while (i--) { + this.opcode('assignToHash', pairs[i][0]); + } + this.opcode('popHash'); + }, + + partial: function (partial) { + var partialName = partial.partialName; + this.usePartial = true; + + if (partial.hash) { + this.accept(partial.hash); + } else { + this.opcode('push', 'undefined'); + } + + if (partial.context) { + this.accept(partial.context); + } else { + this.opcode('getContext', 0); + this.opcode('pushContext'); + } + + this.opcode('invokePartial', partialName.name, partial.indent || ''); + this.opcode('append'); + }, + + content: function (content) { + if (content.string) { + this.opcode('appendContent', content.string); + } + }, + + mustache: function (mustache) { + this.sexpr(mustache.sexpr); + + if (mustache.escaped && !this.options.noEscape) { + this.opcode('appendEscaped'); + } else { + this.opcode('append'); + } + }, + + ambiguousSexpr: function (sexpr, program, inverse) { + var id = sexpr.id, + name = id.parts[0], + isBlock = program != null || inverse != null; + + this.opcode('getContext', id.depth); + + this.opcode('pushProgram', program); + this.opcode('pushProgram', inverse); + + this.ID(id); + + this.opcode('invokeAmbiguous', name, isBlock); + }, + + simpleSexpr: function (sexpr) { + var id = sexpr.id; + + if (id.type === 'DATA') { + this.DATA(id); + } else if (id.parts.length) { + this.ID(id); + } else { + // Simplified ID for `this` + this.addDepth(id.depth); + this.opcode('getContext', id.depth); + this.opcode('pushContext'); + } + + this.opcode('resolvePossibleLambda'); + }, + + helperSexpr: function (sexpr, program, inverse) { + var params = this.setupFullMustacheParams(sexpr, program, inverse), + id = sexpr.id, + name = id.parts[0]; + + if (this.options.knownHelpers[name]) { + this.opcode('invokeKnownHelper', params.length, name); + } else if (this.options.knownHelpersOnly) { + throw new Exception("You specified knownHelpersOnly, but used the unknown helper " + name, sexpr); + } else { + id.falsy = true; + + this.ID(id); + this.opcode('invokeHelper', params.length, id.original, id.isSimple); + } + }, + + sexpr: function (sexpr) { + var type = this.classifySexpr(sexpr); + + if (type === "simple") { + this.simpleSexpr(sexpr); + } else if (type === "helper") { + this.helperSexpr(sexpr); + } else { + this.ambiguousSexpr(sexpr); + } + }, + + ID: function (id) { + this.addDepth(id.depth); + this.opcode('getContext', id.depth); + + var name = id.parts[0]; + if (!name) { + // Context reference, i.e. `{{foo .}}` or `{{foo ..}}` + this.opcode('pushContext'); + } else { + this.opcode('lookupOnContext', id.parts, id.falsy, id.isScoped); + } + }, + + DATA: function (data) { + this.options.data = true; + this.opcode('lookupData', data.id.depth, data.id.parts); + }, + + STRING: function (string) { + this.opcode('pushString', string.string); + }, + + NUMBER: function (number) { + this.opcode('pushLiteral', number.number); + }, + + BOOLEAN: function (bool) { + this.opcode('pushLiteral', bool.bool); + }, + + comment: function () { }, + + // HELPERS + opcode: function (name) { + this.opcodes.push({ opcode: name, args: slice.call(arguments, 1) }); + }, + + addDepth: function (depth) { + if (depth === 0) { return; } + + if (!this.depths[depth]) { + this.depths[depth] = true; + this.depths.list.push(depth); + } + }, + + classifySexpr: function (sexpr) { + var isHelper = sexpr.isHelper; + var isEligible = sexpr.eligibleHelper; + var options = this.options; + + // if ambiguous, we can possibly resolve the ambiguity now + // An eligible helper is one that does not have a complex path, i.e. `this.foo`, `../foo` etc. + if (isEligible && !isHelper) { + var name = sexpr.id.parts[0]; + + if (options.knownHelpers[name]) { + isHelper = true; + } else if (options.knownHelpersOnly) { + isEligible = false; + } + } + + if (isHelper) { return "helper"; } + else if (isEligible) { return "ambiguous"; } + else { return "simple"; } + }, + + pushParams: function (params) { + for (var i = 0, l = params.length; i < l; i++) { + this.pushParam(params[i]); + } + }, + + pushParam: function (val) { + if (this.stringParams) { + if (val.depth) { + this.addDepth(val.depth); + } + this.opcode('getContext', val.depth || 0); + this.opcode('pushStringParam', val.stringModeValue, val.type); + + if (val.type === 'sexpr') { + // Subexpressions get evaluated and passed in + // in string params mode. + this.sexpr(val); + } + } else { + if (this.trackIds) { + this.opcode('pushId', val.type, val.idName || val.stringModeValue); + } + this.accept(val); + } + }, + + setupFullMustacheParams: function (sexpr, program, inverse) { + var params = sexpr.params; + this.pushParams(params); + + this.opcode('pushProgram', program); + this.opcode('pushProgram', inverse); + + if (sexpr.hash) { + this.hash(sexpr.hash); + } else { + this.opcode('emptyHash'); + } + + return params; + } + }; + + function precompile(input, options, env) { + if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) { + throw new Exception("You must pass a string or Handlebars AST to Handlebars.precompile. You passed " + input); + } + + options = options || {}; + if (!('data' in options)) { + options.data = true; + } + if (options.compat) { + options.useDepths = true; + } + + var ast = env.parse(input); + var environment = new env.Compiler().compile(ast, options); + return new env.JavaScriptCompiler().compile(environment, options); + } + + __exports__.precompile = precompile; function compile(input, options, env) { + if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) { + throw new Exception("You must pass a string or Handlebars AST to Handlebars.compile. You passed " + input); + } + + options = options || {}; + + if (!('data' in options)) { + options.data = true; + } + if (options.compat) { + options.useDepths = true; + } + + var compiled; + + function compileInput() { + var ast = env.parse(input); + var environment = new env.Compiler().compile(ast, options); + var templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true); + return env.template(templateSpec); + } + + // Template is only compiled on first use and cached after that point. + var ret = function (context, options) { + if (!compiled) { + compiled = compileInput(); + } + return compiled.call(this, context, options); + }; + ret._setup = function (options) { + if (!compiled) { + compiled = compileInput(); + } + return compiled._setup(options); + }; + ret._child = function (i, data, depths) { + if (!compiled) { + compiled = compileInput(); + } + return compiled._child(i, data, depths); + }; + return ret; + } + + __exports__.compile = compile; function argEquals(a, b) { + if (a === b) { + return true; + } + + if (isArray(a) && isArray(b) && a.length === b.length) { + for (var i = 0; i < a.length; i++) { + if (!argEquals(a[i], b[i])) { + return false; + } + } + return true; + } + } + return __exports__; + })(__module5__, __module3__); + + // handlebars/compiler/javascript-compiler.js + var __module12__ = (function (__dependency1__, __dependency2__) { + "use strict"; + var __exports__; + var COMPILER_REVISION = __dependency1__.COMPILER_REVISION; + var REVISION_CHANGES = __dependency1__.REVISION_CHANGES; + var Exception = __dependency2__; + + function Literal(value) { + this.value = value; + } + + function JavaScriptCompiler() { } + + JavaScriptCompiler.prototype = { + // PUBLIC API: You can override these methods in a subclass to provide + // alternative compiled forms for name lookup and buffering semantics + nameLookup: function (parent, name /* , type*/) { + if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) { + return parent + "." + name; + } else { + return parent + "['" + name + "']"; + } + }, + depthedLookup: function (name) { + this.aliases.lookup = 'this.lookup'; + + return 'lookup(depths, "' + name + '")'; + }, + + compilerInfo: function () { + var revision = COMPILER_REVISION, + versions = REVISION_CHANGES[revision]; + return [revision, versions]; + }, + + appendToBuffer: function (string) { + if (this.environment.isSimple) { + return "return " + string + ";"; + } else { + return { + appendToBuffer: true, + content: string, + toString: function () { return "buffer += " + string + ";"; } + }; + } + }, + + initializeBuffer: function () { + return this.quotedString(""); + }, + + namespace: "Handlebars", + // END PUBLIC API + + compile: function (environment, options, context, asObject) { + this.environment = environment; + this.options = options; + this.stringParams = this.options.stringParams; + this.trackIds = this.options.trackIds; + this.precompile = !asObject; + + this.name = this.environment.name; + this.isChild = !!context; + this.context = context || { + programs: [], + environments: [] + }; + + this.preamble(); + + this.stackSlot = 0; + this.stackVars = []; + this.aliases = {}; + this.registers = { list: [] }; + this.hashes = []; + this.compileStack = []; + this.inlineStack = []; + + this.compileChildren(environment, options); + + this.useDepths = this.useDepths || environment.depths.list.length || this.options.compat; + + var opcodes = environment.opcodes, + opcode, + i, + l; + + for (i = 0, l = opcodes.length; i < l; i++) { + opcode = opcodes[i]; + + this[opcode.opcode].apply(this, opcode.args); + } + + // Flush any trailing content that might be pending. + this.pushSource(''); + + /* istanbul ignore next */ + if (this.stackSlot || this.inlineStack.length || this.compileStack.length) { + throw new Exception('Compile completed with content left on stack'); + } + + var fn = this.createFunctionContext(asObject); + if (!this.isChild) { + var ret = { + compiler: this.compilerInfo(), + main: fn + }; + var programs = this.context.programs; + for (i = 0, l = programs.length; i < l; i++) { + if (programs[i]) { + ret[i] = programs[i]; + } + } + + if (this.environment.usePartial) { + ret.usePartial = true; + } + if (this.options.data) { + ret.useData = true; + } + if (this.useDepths) { + ret.useDepths = true; + } + if (this.options.compat) { + ret.compat = true; + } + + if (!asObject) { + ret.compiler = JSON.stringify(ret.compiler); + ret = this.objectLiteral(ret); + } + + return ret; + } else { + return fn; + } + }, + + preamble: function () { + // track the last context pushed into place to allow skipping the + // getContext opcode when it would be a noop + this.lastContext = 0; + this.source = []; + }, + + createFunctionContext: function (asObject) { + var varDeclarations = ''; + + var locals = this.stackVars.concat(this.registers.list); + if (locals.length > 0) { + varDeclarations += ", " + locals.join(", "); + } + + // Generate minimizer alias mappings + for (var alias in this.aliases) { + if (this.aliases.hasOwnProperty(alias)) { + varDeclarations += ', ' + alias + '=' + this.aliases[alias]; + } + } + + var params = ["depth0", "helpers", "partials", "data"]; + + if (this.useDepths) { + params.push('depths'); + } + + // Perform a second pass over the output to merge content when possible + var source = this.mergeSource(varDeclarations); + + if (asObject) { + params.push(source); + + return Function.apply(this, params); + } else { + return 'function(' + params.join(',') + ') {\n ' + source + '}'; + } + }, + mergeSource: function (varDeclarations) { + var source = '', + buffer, + appendOnly = !this.forceBuffer, + appendFirst; + + for (var i = 0, len = this.source.length; i < len; i++) { + var line = this.source[i]; + if (line.appendToBuffer) { + if (buffer) { + buffer = buffer + '\n + ' + line.content; + } else { + buffer = line.content; + } + } else { + if (buffer) { + if (!source) { + appendFirst = true; + source = buffer + ';\n '; + } else { + source += 'buffer += ' + buffer + ';\n '; + } + buffer = undefined; + } + source += line + '\n '; + + if (!this.environment.isSimple) { + appendOnly = false; + } + } + } + + if (appendOnly) { + if (buffer || !source) { + source += 'return ' + (buffer || '""') + ';\n'; + } + } else { + varDeclarations += ", buffer = " + (appendFirst ? '' : this.initializeBuffer()); + if (buffer) { + source += 'return buffer + ' + buffer + ';\n'; + } else { + source += 'return buffer;\n'; + } + } + + if (varDeclarations) { + source = 'var ' + varDeclarations.substring(2) + (appendFirst ? '' : ';\n ') + source; + } + + return source; + }, + + // [blockValue] + // + // On stack, before: hash, inverse, program, value + // On stack, after: return value of blockHelperMissing + // + // The purpose of this opcode is to take a block of the form + // `{{#this.foo}}...{{/this.foo}}`, resolve the value of `foo`, and + // replace it on the stack with the result of properly + // invoking blockHelperMissing. + blockValue: function (name) { + this.aliases.blockHelperMissing = 'helpers.blockHelperMissing'; + + var params = [this.contextName(0)]; + this.setupParams(name, 0, params); + + var blockName = this.popStack(); + params.splice(1, 0, blockName); + + this.push('blockHelperMissing.call(' + params.join(', ') + ')'); + }, + + // [ambiguousBlockValue] + // + // On stack, before: hash, inverse, program, value + // Compiler value, before: lastHelper=value of last found helper, if any + // On stack, after, if no lastHelper: same as [blockValue] + // On stack, after, if lastHelper: value + ambiguousBlockValue: function () { + this.aliases.blockHelperMissing = 'helpers.blockHelperMissing'; + + // We're being a bit cheeky and reusing the options value from the prior exec + var params = [this.contextName(0)]; + this.setupParams('', 0, params, true); + + this.flushInline(); + + var current = this.topStack(); + params.splice(1, 0, current); + + this.pushSource("if (!" + this.lastHelper + ") { " + current + " = blockHelperMissing.call(" + params.join(", ") + "); }"); + }, + + // [appendContent] + // + // On stack, before: ... + // On stack, after: ... + // + // Appends the string value of `content` to the current buffer + appendContent: function (content) { + if (this.pendingContent) { + content = this.pendingContent + content; + } + + this.pendingContent = content; + }, + + // [append] + // + // On stack, before: value, ... + // On stack, after: ... + // + // Coerces `value` to a String and appends it to the current buffer. + // + // If `value` is truthy, or 0, it is coerced into a string and appended + // Otherwise, the empty string is appended + append: function () { + // Force anything that is inlined onto the stack so we don't have duplication + // when we examine local + this.flushInline(); + var local = this.popStack(); + this.pushSource('if (' + local + ' != null) { ' + this.appendToBuffer(local) + ' }'); + if (this.environment.isSimple) { + this.pushSource("else { " + this.appendToBuffer("''") + " }"); + } + }, + + // [appendEscaped] + // + // On stack, before: value, ... + // On stack, after: ... + // + // Escape `value` and append it to the buffer + appendEscaped: function () { + this.aliases.escapeExpression = 'this.escapeExpression'; + + this.pushSource(this.appendToBuffer("escapeExpression(" + this.popStack() + ")")); + }, + + // [getContext] + // + // On stack, before: ... + // On stack, after: ... + // Compiler value, after: lastContext=depth + // + // Set the value of the `lastContext` compiler value to the depth + getContext: function (depth) { + this.lastContext = depth; + }, + + // [pushContext] + // + // On stack, before: ... + // On stack, after: currentContext, ... + // + // Pushes the value of the current context onto the stack. + pushContext: function () { + this.pushStackLiteral(this.contextName(this.lastContext)); + }, + + // [lookupOnContext] + // + // On stack, before: ... + // On stack, after: currentContext[name], ... + // + // Looks up the value of `name` on the current context and pushes + // it onto the stack. + lookupOnContext: function (parts, falsy, scoped) { + /*jshint -W083 */ + var i = 0, + len = parts.length; + + if (!scoped && this.options.compat && !this.lastContext) { + // The depthed query is expected to handle the undefined logic for the root level that + // is implemented below, so we evaluate that directly in compat mode + this.push(this.depthedLookup(parts[i++])); + } else { + this.pushContext(); + } + + for (; i < len; i++) { + this.replaceStack(function (current) { + var lookup = this.nameLookup(current, parts[i], 'context'); + // We want to ensure that zero and false are handled properly if the context (falsy flag) + // needs to have the special handling for these values. + if (!falsy) { + return ' != null ? ' + lookup + ' : ' + current; + } else { + // Otherwise we can use generic falsy handling + return ' && ' + lookup; + } + }); + } + }, + + // [lookupData] + // + // On stack, before: ... + // On stack, after: data, ... + // + // Push the data lookup operator + lookupData: function (depth, parts) { + /*jshint -W083 */ + if (!depth) { + this.pushStackLiteral('data'); + } else { + this.pushStackLiteral('this.data(data, ' + depth + ')'); + } + + var len = parts.length; + for (var i = 0; i < len; i++) { + this.replaceStack(function (current) { + return ' && ' + this.nameLookup(current, parts[i], 'data'); + }); + } + }, + + // [resolvePossibleLambda] + // + // On stack, before: value, ... + // On stack, after: resolved value, ... + // + // If the `value` is a lambda, replace it on the stack by + // the return value of the lambda + resolvePossibleLambda: function () { + this.aliases.lambda = 'this.lambda'; + + this.push('lambda(' + this.popStack() + ', ' + this.contextName(0) + ')'); + }, + + // [pushStringParam] + // + // On stack, before: ... + // On stack, after: string, currentContext, ... + // + // This opcode is designed for use in string mode, which + // provides the string value of a parameter along with its + // depth rather than resolving it immediately. + pushStringParam: function (string, type) { + this.pushContext(); + this.pushString(type); + + // If it's a subexpression, the string result + // will be pushed after this opcode. + if (type !== 'sexpr') { + if (typeof string === 'string') { + this.pushString(string); + } else { + this.pushStackLiteral(string); + } + } + }, + + emptyHash: function () { + this.pushStackLiteral('{}'); + + if (this.trackIds) { + this.push('{}'); // hashIds + } + if (this.stringParams) { + this.push('{}'); // hashContexts + this.push('{}'); // hashTypes + } + }, + pushHash: function () { + if (this.hash) { + this.hashes.push(this.hash); + } + this.hash = { values: [], types: [], contexts: [], ids: [] }; + }, + popHash: function () { + var hash = this.hash; + this.hash = this.hashes.pop(); + + if (this.trackIds) { + this.push('{' + hash.ids.join(',') + '}'); + } + if (this.stringParams) { + this.push('{' + hash.contexts.join(',') + '}'); + this.push('{' + hash.types.join(',') + '}'); + } + + this.push('{\n ' + hash.values.join(',\n ') + '\n }'); + }, + + // [pushString] + // + // On stack, before: ... + // On stack, after: quotedString(string), ... + // + // Push a quoted version of `string` onto the stack + pushString: function (string) { + this.pushStackLiteral(this.quotedString(string)); + }, + + // [push] + // + // On stack, before: ... + // On stack, after: expr, ... + // + // Push an expression onto the stack + push: function (expr) { + this.inlineStack.push(expr); + return expr; + }, + + // [pushLiteral] + // + // On stack, before: ... + // On stack, after: value, ... + // + // Pushes a value onto the stack. This operation prevents + // the compiler from creating a temporary variable to hold + // it. + pushLiteral: function (value) { + this.pushStackLiteral(value); + }, + + // [pushProgram] + // + // On stack, before: ... + // On stack, after: program(guid), ... + // + // Push a program expression onto the stack. This takes + // a compile-time guid and converts it into a runtime-accessible + // expression. + pushProgram: function (guid) { + if (guid != null) { + this.pushStackLiteral(this.programExpression(guid)); + } else { + this.pushStackLiteral(null); + } + }, + + // [invokeHelper] + // + // On stack, before: hash, inverse, program, params..., ... + // On stack, after: result of helper invocation + // + // Pops off the helper's parameters, invokes the helper, + // and pushes the helper's return value onto the stack. + // + // If the helper is not found, `helperMissing` is called. + invokeHelper: function (paramSize, name, isSimple) { + this.aliases.helperMissing = 'helpers.helperMissing'; + + var nonHelper = this.popStack(); + var helper = this.setupHelper(paramSize, name); + + var lookup = (isSimple ? helper.name + ' || ' : '') + nonHelper + ' || helperMissing'; + this.push('((' + lookup + ').call(' + helper.callParams + '))'); + }, + + // [invokeKnownHelper] + // + // On stack, before: hash, inverse, program, params..., ... + // On stack, after: result of helper invocation + // + // This operation is used when the helper is known to exist, + // so a `helperMissing` fallback is not required. + invokeKnownHelper: function (paramSize, name) { + var helper = this.setupHelper(paramSize, name); + this.push(helper.name + ".call(" + helper.callParams + ")"); + }, + + // [invokeAmbiguous] + // + // On stack, before: hash, inverse, program, params..., ... + // On stack, after: result of disambiguation + // + // This operation is used when an expression like `{{foo}}` + // is provided, but we don't know at compile-time whether it + // is a helper or a path. + // + // This operation emits more code than the other options, + // and can be avoided by passing the `knownHelpers` and + // `knownHelpersOnly` flags at compile-time. + invokeAmbiguous: function (name, helperCall) { + this.aliases.functionType = '"function"'; + this.aliases.helperMissing = 'helpers.helperMissing'; + this.useRegister('helper'); + + var nonHelper = this.popStack(); + + this.emptyHash(); + var helper = this.setupHelper(0, name, helperCall); + + var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper'); + + this.push( + '((helper = (helper = ' + helperName + ' || ' + nonHelper + ') != null ? helper : helperMissing' + + (helper.paramsInit ? '),(' + helper.paramsInit : '') + '),' + + '(typeof helper === functionType ? helper.call(' + helper.callParams + ') : helper))'); + }, + + // [invokePartial] + // + // On stack, before: context, ... + // On stack after: result of partial invocation + // + // This operation pops off a context, invokes a partial with that context, + // and pushes the result of the invocation back. + invokePartial: function (name, indent) { + var params = [this.nameLookup('partials', name, 'partial'), "'" + indent + "'", "'" + name + "'", this.popStack(), this.popStack(), "helpers", "partials"]; + + if (this.options.data) { + params.push("data"); + } else if (this.options.compat) { + params.push('undefined'); + } + if (this.options.compat) { + params.push('depths'); + } + + this.push("this.invokePartial(" + params.join(", ") + ")"); + }, + + // [assignToHash] + // + // On stack, before: value, ..., hash, ... + // On stack, after: ..., hash, ... + // + // Pops a value off the stack and assigns it to the current hash + assignToHash: function (key) { + var value = this.popStack(), + context, + type, + id; + + if (this.trackIds) { + id = this.popStack(); + } + if (this.stringParams) { + type = this.popStack(); + context = this.popStack(); + } + + var hash = this.hash; + if (context) { + hash.contexts.push("'" + key + "': " + context); + } + if (type) { + hash.types.push("'" + key + "': " + type); + } + if (id) { + hash.ids.push("'" + key + "': " + id); + } + hash.values.push("'" + key + "': (" + value + ")"); + }, + + pushId: function (type, name) { + if (type === 'ID' || type === 'DATA') { + this.pushString(name); + } else if (type === 'sexpr') { + this.pushStackLiteral('true'); + } else { + this.pushStackLiteral('null'); + } + }, + + // HELPERS + + compiler: JavaScriptCompiler, + + compileChildren: function (environment, options) { + var children = environment.children, child, compiler; + + for (var i = 0, l = children.length; i < l; i++) { + child = children[i]; + compiler = new this.compiler(); + + var index = this.matchExistingProgram(child); + + if (index == null) { + this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children + index = this.context.programs.length; + child.index = index; + child.name = 'program' + index; + this.context.programs[index] = compiler.compile(child, options, this.context, !this.precompile); + this.context.environments[index] = child; + + this.useDepths = this.useDepths || compiler.useDepths; + } else { + child.index = index; + child.name = 'program' + index; + } + } + }, + matchExistingProgram: function (child) { + for (var i = 0, len = this.context.environments.length; i < len; i++) { + var environment = this.context.environments[i]; + if (environment && environment.equals(child)) { + return i; + } + } + }, + + programExpression: function (guid) { + var child = this.environment.children[guid], + depths = child.depths.list, + useDepths = this.useDepths, + depth; + + var programParams = [child.index, 'data']; + + if (useDepths) { + programParams.push('depths'); + } + + return 'this.program(' + programParams.join(', ') + ')'; + }, + + useRegister: function (name) { + if (!this.registers[name]) { + this.registers[name] = true; + this.registers.list.push(name); + } + }, + + pushStackLiteral: function (item) { + return this.push(new Literal(item)); + }, + + pushSource: function (source) { + if (this.pendingContent) { + this.source.push(this.appendToBuffer(this.quotedString(this.pendingContent))); + this.pendingContent = undefined; + } + + if (source) { + this.source.push(source); + } + }, + + pushStack: function (item) { + this.flushInline(); + + var stack = this.incrStack(); + this.pushSource(stack + " = " + item + ";"); + this.compileStack.push(stack); + return stack; + }, + + replaceStack: function (callback) { + var prefix = '', + inline = this.isInline(), + stack, + createdStack, + usedLiteral; + + /* istanbul ignore next */ + if (!this.isInline()) { + throw new Exception('replaceStack on non-inline'); + } + + // We want to merge the inline statement into the replacement statement via ',' + var top = this.popStack(true); + + if (top instanceof Literal) { + // Literals do not need to be inlined + prefix = stack = top.value; + usedLiteral = true; + } else { + // Get or create the current stack name for use by the inline + createdStack = !this.stackSlot; + var name = !createdStack ? this.topStackName() : this.incrStack(); + + prefix = '(' + this.push(name) + ' = ' + top + ')'; + stack = this.topStack(); + } + + var item = callback.call(this, stack); + + if (!usedLiteral) { + this.popStack(); + } + if (createdStack) { + this.stackSlot--; + } + this.push('(' + prefix + item + ')'); + }, + + incrStack: function () { + this.stackSlot++; + if (this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); } + return this.topStackName(); + }, + topStackName: function () { + return "stack" + this.stackSlot; + }, + flushInline: function () { + var inlineStack = this.inlineStack; + if (inlineStack.length) { + this.inlineStack = []; + for (var i = 0, len = inlineStack.length; i < len; i++) { + var entry = inlineStack[i]; + if (entry instanceof Literal) { + this.compileStack.push(entry); + } else { + this.pushStack(entry); + } + } + } + }, + isInline: function () { + return this.inlineStack.length; + }, + + popStack: function (wrapped) { + var inline = this.isInline(), + item = (inline ? this.inlineStack : this.compileStack).pop(); + + if (!wrapped && (item instanceof Literal)) { + return item.value; + } else { + if (!inline) { + /* istanbul ignore next */ + if (!this.stackSlot) { + throw new Exception('Invalid stack pop'); + } + this.stackSlot--; + } + return item; + } + }, + + topStack: function () { + var stack = (this.isInline() ? this.inlineStack : this.compileStack), + item = stack[stack.length - 1]; + + if (item instanceof Literal) { + return item.value; + } else { + return item; + } + }, + + contextName: function (context) { + if (this.useDepths && context) { + return 'depths[' + context + ']'; + } else { + return 'depth' + context; + } + }, + + quotedString: function (str) { + return '"' + str + .replace(/\\/g, '\\\\') + .replace(/"/g, '\\"') + .replace(/\n/g, '\\n') + .replace(/\r/g, '\\r') + .replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4 + .replace(/\u2029/g, '\\u2029') + '"'; + }, + + objectLiteral: function (obj) { + var pairs = []; + + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + pairs.push(this.quotedString(key) + ':' + obj[key]); + } + } + + return '{' + pairs.join(',') + '}'; + }, + + setupHelper: function (paramSize, name, blockHelper) { + var params = [], + paramsInit = this.setupParams(name, paramSize, params, blockHelper); + var foundHelper = this.nameLookup('helpers', name, 'helper'); + + return { + params: params, + paramsInit: paramsInit, + name: foundHelper, + callParams: [this.contextName(0)].concat(params).join(", ") + }; + }, + + setupOptions: function (helper, paramSize, params) { + var options = {}, contexts = [], types = [], ids = [], param, inverse, program; + + options.name = this.quotedString(helper); + options.hash = this.popStack(); + + if (this.trackIds) { + options.hashIds = this.popStack(); + } + if (this.stringParams) { + options.hashTypes = this.popStack(); + options.hashContexts = this.popStack(); + } + + inverse = this.popStack(); + program = this.popStack(); + + // Avoid setting fn and inverse if neither are set. This allows + // helpers to do a check for `if (options.fn)` + if (program || inverse) { + if (!program) { + program = 'this.noop'; + } + + if (!inverse) { + inverse = 'this.noop'; + } + + options.fn = program; + options.inverse = inverse; + } + + // The parameters go on to the stack in order (making sure that they are evaluated in order) + // so we need to pop them off the stack in reverse order + var i = paramSize; + while (i--) { + param = this.popStack(); + params[i] = param; + + if (this.trackIds) { + ids[i] = this.popStack(); + } + if (this.stringParams) { + types[i] = this.popStack(); + contexts[i] = this.popStack(); + } + } + + if (this.trackIds) { + options.ids = "[" + ids.join(",") + "]"; + } + if (this.stringParams) { + options.types = "[" + types.join(",") + "]"; + options.contexts = "[" + contexts.join(",") + "]"; + } + + if (this.options.data) { + options.data = "data"; + } + + return options; + }, + + // the params and contexts arguments are passed in arrays + // to fill in + setupParams: function (helperName, paramSize, params, useRegister) { + var options = this.objectLiteral(this.setupOptions(helperName, paramSize, params)); + + if (useRegister) { + this.useRegister('options'); + params.push('options'); + return 'options=' + options; + } else { + params.push(options); + return ''; + } + } + }; + + var reservedWords = ( + "break else new var" + + " case finally return void" + + " catch for switch while" + + " continue function this with" + + " default if throw" + + " delete in try" + + " do instanceof typeof" + + " abstract enum int short" + + " boolean export interface static" + + " byte extends long super" + + " char final native synchronized" + + " class float package throws" + + " const goto private transient" + + " debugger implements protected volatile" + + " double import public let yield" + ).split(" "); + + var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {}; + + for (var i = 0, l = reservedWords.length; i < l; i++) { + compilerWords[reservedWords[i]] = true; + } + + JavaScriptCompiler.isValidJavaScriptVariableName = function (name) { + return !JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name); + }; + + __exports__ = JavaScriptCompiler; + return __exports__; + })(__module2__, __module5__); + + // handlebars.js + var __module0__ = (function (__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) { + "use strict"; + var __exports__; + /*globals Handlebars: true */ + var Handlebars = __dependency1__; + + // Compiler imports + var AST = __dependency2__; + var Parser = __dependency3__.parser; + var parse = __dependency3__.parse; + var Compiler = __dependency4__.Compiler; + var compile = __dependency4__.compile; + var precompile = __dependency4__.precompile; + var JavaScriptCompiler = __dependency5__; + + var _create = Handlebars.create; + var create = function () { + var hb = _create(); + + hb.compile = function (input, options) { + return compile(input, options, hb); + }; + hb.precompile = function (input, options) { + return precompile(input, options, hb); + }; + + hb.AST = AST; + hb.Compiler = Compiler; + hb.JavaScriptCompiler = JavaScriptCompiler; + hb.Parser = Parser; + hb.parse = parse; + + return hb; + }; + + Handlebars = create(); + Handlebars.create = create; + + Handlebars['default'] = Handlebars; + + __exports__ = Handlebars; + return __exports__; + })(__module1__, __module7__, __module8__, __module11__, __module12__); + + return __module0__; +})); \ No newline at end of file diff --git a/Jint.Tests/packages.config b/Jint.Tests/packages.config index f6903fcc70..0458eb12e0 100644 --- a/Jint.Tests/packages.config +++ b/Jint.Tests/packages.config @@ -1,6 +1,10 @@  - - + + + + + + \ No newline at end of file diff --git a/Jint.Tests/xunit.runner.json b/Jint.Tests/xunit.runner.json new file mode 100644 index 0000000000..820ecc794f --- /dev/null +++ b/Jint.Tests/xunit.runner.json @@ -0,0 +1,3 @@ +{ + "methodDisplay": "method" +} diff --git a/Jint.sln b/Jint.sln index 9306e5cf1f..6cbd55116d 100644 --- a/Jint.sln +++ b/Jint.sln @@ -1,26 +1,19 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.30110.0 +# Visual Studio 15 +VisualStudioVersion = 15.0.26406.1 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jint.Tests", "Jint.Tests\Jint.Tests.csproj", "{37C7D4E0-8770-4E2A-8B6D-E53087868354}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jint", "Jint\Jint.csproj", "{4B6F353A-5D01-407D-9DC8-96D1FD4F7052}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jint.Benchmark", "Jint.Benchmark\Jint.Benchmark.csproj", "{8922A952-4F82-4A97-B41C-C0A9932BFFA8}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jint.Benchmark", "Jint.Benchmark\Jint.Benchmark.csproj", "{228D9FA5-CBC0-4489-9805-9B4456747647}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jint.Tests.Ecma", "Jint.Tests.Ecma\Jint.Tests.Ecma.csproj", "{201EB165-EE2D-45F1-AF0E-75F1CD1A20EE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jint.Repl", "Jint.Repl\Jint.Repl.csproj", "{BB3AC010-C2CE-41A5-93C6-763600EF67B3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jint", "Jint\Jint.csproj", "{678738DA-F723-4920-B9E5-CAD667104BDA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jint.Tests", "Jint.Tests\Jint.Tests.csproj", "{9FBCAB58-FE6D-4804-92B8-7CF886113708}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jint.Repl", "Jint.Repl\Jint.Repl.csproj", "{A69FD3C5-F2B0-4055-A518-F4173EBA5E4D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jint.Tests.Ecma", "Jint.Tests.Ecma\Jint.Tests.Ecma.csproj", "{2CC1F6A6-7DCC-4C7C-A619-ACE1A4296446}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{90E4A7EF-8DB1-49D4-89F9-512999531AE8}" - ProjectSection(SolutionItems) = preProject - .nuget\NuGet.Config = .nuget\NuGet.Config - .nuget\NuGet.exe = .nuget\NuGet.exe - .nuget\NuGet.targets = .nuget\NuGet.targets - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jint.Tests.CommonScripts", "Jint.Tests.CommonScripts\Jint.Tests.CommonScripts.csproj", "{9A78C21A-8887-4B1B-9AFE-246B53EE23B4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jint.Tests.CommonScripts", "Jint.Tests.CommonScripts\Jint.Tests.CommonScripts.csproj", "{B815F239-6409-4BA7-9461-18317AA2DBED}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -28,30 +21,30 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {37C7D4E0-8770-4E2A-8B6D-E53087868354}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {37C7D4E0-8770-4E2A-8B6D-E53087868354}.Debug|Any CPU.Build.0 = Debug|Any CPU - {37C7D4E0-8770-4E2A-8B6D-E53087868354}.Release|Any CPU.ActiveCfg = Release|Any CPU - {37C7D4E0-8770-4E2A-8B6D-E53087868354}.Release|Any CPU.Build.0 = Release|Any CPU - {8922A952-4F82-4A97-B41C-C0A9932BFFA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8922A952-4F82-4A97-B41C-C0A9932BFFA8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8922A952-4F82-4A97-B41C-C0A9932BFFA8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8922A952-4F82-4A97-B41C-C0A9932BFFA8}.Release|Any CPU.Build.0 = Release|Any CPU - {201EB165-EE2D-45F1-AF0E-75F1CD1A20EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {201EB165-EE2D-45F1-AF0E-75F1CD1A20EE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {201EB165-EE2D-45F1-AF0E-75F1CD1A20EE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {201EB165-EE2D-45F1-AF0E-75F1CD1A20EE}.Release|Any CPU.Build.0 = Release|Any CPU - {678738DA-F723-4920-B9E5-CAD667104BDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {678738DA-F723-4920-B9E5-CAD667104BDA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {678738DA-F723-4920-B9E5-CAD667104BDA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {678738DA-F723-4920-B9E5-CAD667104BDA}.Release|Any CPU.Build.0 = Release|Any CPU - {A69FD3C5-F2B0-4055-A518-F4173EBA5E4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A69FD3C5-F2B0-4055-A518-F4173EBA5E4D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A69FD3C5-F2B0-4055-A518-F4173EBA5E4D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A69FD3C5-F2B0-4055-A518-F4173EBA5E4D}.Release|Any CPU.Build.0 = Release|Any CPU - {9A78C21A-8887-4B1B-9AFE-246B53EE23B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9A78C21A-8887-4B1B-9AFE-246B53EE23B4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9A78C21A-8887-4B1B-9AFE-246B53EE23B4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9A78C21A-8887-4B1B-9AFE-246B53EE23B4}.Release|Any CPU.Build.0 = Release|Any CPU + {4B6F353A-5D01-407D-9DC8-96D1FD4F7052}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4B6F353A-5D01-407D-9DC8-96D1FD4F7052}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4B6F353A-5D01-407D-9DC8-96D1FD4F7052}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4B6F353A-5D01-407D-9DC8-96D1FD4F7052}.Release|Any CPU.Build.0 = Release|Any CPU + {228D9FA5-CBC0-4489-9805-9B4456747647}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {228D9FA5-CBC0-4489-9805-9B4456747647}.Debug|Any CPU.Build.0 = Debug|Any CPU + {228D9FA5-CBC0-4489-9805-9B4456747647}.Release|Any CPU.ActiveCfg = Release|Any CPU + {228D9FA5-CBC0-4489-9805-9B4456747647}.Release|Any CPU.Build.0 = Release|Any CPU + {BB3AC010-C2CE-41A5-93C6-763600EF67B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BB3AC010-C2CE-41A5-93C6-763600EF67B3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BB3AC010-C2CE-41A5-93C6-763600EF67B3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BB3AC010-C2CE-41A5-93C6-763600EF67B3}.Release|Any CPU.Build.0 = Release|Any CPU + {9FBCAB58-FE6D-4804-92B8-7CF886113708}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9FBCAB58-FE6D-4804-92B8-7CF886113708}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9FBCAB58-FE6D-4804-92B8-7CF886113708}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9FBCAB58-FE6D-4804-92B8-7CF886113708}.Release|Any CPU.Build.0 = Release|Any CPU + {2CC1F6A6-7DCC-4C7C-A619-ACE1A4296446}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2CC1F6A6-7DCC-4C7C-A619-ACE1A4296446}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2CC1F6A6-7DCC-4C7C-A619-ACE1A4296446}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2CC1F6A6-7DCC-4C7C-A619-ACE1A4296446}.Release|Any CPU.Build.0 = Release|Any CPU + {B815F239-6409-4BA7-9461-18317AA2DBED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B815F239-6409-4BA7-9461-18317AA2DBED}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B815F239-6409-4BA7-9461-18317AA2DBED}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B815F239-6409-4BA7-9461-18317AA2DBED}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Jint/.vscode/launch.json b/Jint/.vscode/launch.json new file mode 100644 index 0000000000..38a3ef757a --- /dev/null +++ b/Jint/.vscode/launch.json @@ -0,0 +1,45 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": ".NET Core Launch (console)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + "program": "${workspaceRoot}/bin/Debug//", + "args": [], + "cwd": "${workspaceRoot}", + "stopAtEntry": false + }, + { + "name": ".NET Core Launch (web)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + "program": "${workspaceRoot}/bin/Debug//", + "args": [], + "cwd": "${workspaceRoot}", + "stopAtEntry": false, + "launchBrowser": { + "enabled": true, + "args": "${auto-detect-url}", + "windows": { + "command": "cmd.exe", + "args": "/C start ${auto-detect-url}" + }, + "osx": { + "command": "open" + }, + "linux": { + "command": "xdg-open" + } + } + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach", + "processName": "" + } + ] +} \ No newline at end of file diff --git a/Jint/.vscode/tasks.json b/Jint/.vscode/tasks.json new file mode 100644 index 0000000000..67d6eb75cb --- /dev/null +++ b/Jint/.vscode/tasks.json @@ -0,0 +1,14 @@ +{ + "version": "0.1.0", + "command": "dotnet", + "isShellCommand": true, + "args": [], + "tasks": [ + { + "taskName": "build", + "args": [], + "isBuildCommand": true, + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/Jint/Directory.Build.props b/Jint/Directory.Build.props new file mode 100644 index 0000000000..16f25671d6 --- /dev/null +++ b/Jint/Directory.Build.props @@ -0,0 +1,21 @@ + + + + Jint + Jint + Javascript interpreter for .NET which provides full ECMA 5.1 compliance. + 0 + 2.11.$(BuildNumber) + + Jint + javascript, interpreter + https://github.com/sebastienros/jint + https://raw.githubusercontent.com/sebastienros/jint/master/LICENSE.txt + git + git://github.com/sebastienros/jint + + + + + + diff --git a/Jint/Engine.cs b/Jint/Engine.cs index c6a6eb423e..0ed6b525e3 100644 --- a/Jint/Engine.cs +++ b/Jint/Engine.cs @@ -18,6 +18,8 @@ using Jint.Parser; using Jint.Parser.Ast; using Jint.Runtime; +using Jint.Runtime.CallStack; +using Jint.Runtime.Debugger; using Jint.Runtime.Descriptors; using Jint.Runtime.Environments; using Jint.Runtime.Interop; @@ -32,10 +34,37 @@ public class Engine private readonly Stack _executionContexts; private JsValue _completionValue = JsValue.Undefined; private int _statementsCount; + private long _timeoutTicks; private SyntaxNode _lastSyntaxNode = null; + public ITypeConverter ClrTypeConverter; + // cache of types used when resolving CLR type names - internal Dictionary TypeCache = new Dictionary(); + internal Dictionary TypeCache = new Dictionary(); + + internal static Dictionary> TypeMappers = new Dictionary>() + { + { typeof(bool), (Engine engine, object v) => new JsValue((bool)v) }, + { typeof(byte), (Engine engine, object v) => new JsValue((byte)v) }, + { typeof(char), (Engine engine, object v) => new JsValue((char)v) }, + { typeof(DateTime), (Engine engine, object v) => engine.Date.Construct((DateTime)v) }, + { typeof(DateTimeOffset), (Engine engine, object v) => engine.Date.Construct((DateTimeOffset)v) }, + { typeof(decimal), (Engine engine, object v) => new JsValue((double)(decimal)v) }, + { typeof(double), (Engine engine, object v) => new JsValue((double)v) }, + { typeof(Int16), (Engine engine, object v) => new JsValue((Int16)v) }, + { typeof(Int32), (Engine engine, object v) => new JsValue((Int32)v) }, + { typeof(Int64), (Engine engine, object v) => new JsValue((Int64)v) }, + { typeof(SByte), (Engine engine, object v) => new JsValue((SByte)v) }, + { typeof(Single), (Engine engine, object v) => new JsValue((Single)v) }, + { typeof(string), (Engine engine, object v) => new JsValue((string)v) }, + { typeof(UInt16), (Engine engine, object v) => new JsValue((UInt16)v) }, + { typeof(UInt32), (Engine engine, object v) => new JsValue((UInt32)v) }, + { typeof(UInt64), (Engine engine, object v) => new JsValue((UInt64)v) }, + { typeof(JsValue), (Engine engine, object v) => (JsValue)v }, + { typeof(System.Text.RegularExpressions.Regex), (Engine engine, object v) => engine.RegExp.Construct(((System.Text.RegularExpressions.Regex)v).ToString().Trim('/')) } + }; + + internal JintCallStack CallStack = new JintCallStack(); public Engine() : this(null) { @@ -104,7 +133,7 @@ public Engine(Action options) // create the global environment http://www.ecma-international.org/ecma-262/5.1/#sec-10.2.3 GlobalEnvironment = LexicalEnvironment.NewObjectEnvironment(this, Global, null, false); - + // create the global execution context http://www.ecma-international.org/ecma-262/5.1/#sec-10.4.1.1 EnterExecutionContext(GlobalEnvironment, GlobalEnvironment, Global); @@ -121,7 +150,7 @@ public Engine(Action options) _statements = new StatementInterpreter(this); _expressions = new ExpressionInterpreter(this); - if (Options.IsClrAllowed()) + if (Options._IsClrAllowed) { Global.FastAddProperty("System", new NamespaceReference(this, "System"), false, false, false); Global.FastAddProperty("importNamespace", new ClrFunctionInstance(this, (thisObj, arguments) => @@ -129,6 +158,10 @@ public Engine(Action options) return new NamespaceReference(this, TypeConverter.ToString(arguments.At(0))); }), false, false, false); } + + ClrTypeConverter = new DefaultTypeConverter(this); + BreakPoints = new List(); + DebugHandler = new DebugHandler(this); } public LexicalEnvironment GlobalEnvironment; @@ -158,6 +191,33 @@ public Engine(Action options) internal Options Options { get; private set; } + #region Debugger + public delegate StepMode DebugStepDelegate(object sender, DebugInformation e); + public delegate StepMode BreakDelegate(object sender, DebugInformation e); + public event DebugStepDelegate Step; + public event BreakDelegate Break; + internal DebugHandler DebugHandler { get; private set; } + public List BreakPoints { get; private set; } + + internal StepMode? InvokeStepEvent(DebugInformation info) + { + if (Step != null) + { + return Step(this, info); + } + return null; + } + + internal StepMode? InvokeBreakEvent(DebugInformation info) + { + if (Break != null) + { + return Break(this, info); + } + return null; + } + #endregion + public ExecutionContext EnterExecutionContext(LexicalEnvironment lexicalEnvironment, LexicalEnvironment variableEnvironment, JsValue thisBinding) { var executionContext = new ExecutionContext @@ -216,6 +276,20 @@ public void ResetStatementsCount() _statementsCount = 0; } + public void ResetTimeoutTicks() + { + var timeoutIntervalTicks = Options._TimeoutInterval.Ticks; + _timeoutTicks = timeoutIntervalTicks > 0 ? DateTime.UtcNow.Ticks + timeoutIntervalTicks : 0; + } + + /// + /// Initializes list of references of called functions + /// + public void ResetCallStack() + { + CallStack.Clear(); + } + public Engine Execute(string source) { var parser = new JavaScriptParser(); @@ -231,16 +305,19 @@ public Engine Execute(string source, ParserOptions parserOptions) public Engine Execute(Program program) { ResetStatementsCount(); + ResetTimeoutTicks(); ResetLastStatement(); + ResetCallStack(); - using (new StrictModeScope(Options.IsStrict() || program.Strict)) + using (new StrictModeScope(Options._IsStrict || program.Strict)) { DeclarationBindingInstantiation(DeclarationBindingType.GlobalCode, program.FunctionDeclarations, program.VariableDeclarations, null, null); var result = _statements.ExecuteProgram(program); if (result.Type == Completion.Throw) { - throw new JavaScriptException(result.GetValueOrDefault()); + throw new JavaScriptException(result.GetValueOrDefault()) + .SetCallstack(this, result.Location); } _completionValue = result.GetValueOrDefault(); @@ -264,76 +341,86 @@ public JsValue GetCompletionValue() public Completion ExecuteStatement(Statement statement) { - var maxStatements = Options.GetMaxStatements(); + var maxStatements = Options._MaxStatements; if (maxStatements > 0 && _statementsCount++ > maxStatements) { throw new StatementsCountOverflowException(); } + if (_timeoutTicks > 0 && _timeoutTicks < DateTime.UtcNow.Ticks) + { + throw new TimeoutException(); + } + _lastSyntaxNode = statement; + if (Options._IsDebugMode) + { + DebugHandler.OnStep(statement); + } + switch (statement.Type) { case SyntaxNodes.BlockStatement: return _statements.ExecuteBlockStatement(statement.As()); - + case SyntaxNodes.BreakStatement: return _statements.ExecuteBreakStatement(statement.As()); - + case SyntaxNodes.ContinueStatement: return _statements.ExecuteContinueStatement(statement.As()); - + case SyntaxNodes.DoWhileStatement: return _statements.ExecuteDoWhileStatement(statement.As()); - + case SyntaxNodes.DebuggerStatement: return _statements.ExecuteDebuggerStatement(statement.As()); - + case SyntaxNodes.EmptyStatement: return _statements.ExecuteEmptyStatement(statement.As()); - + case SyntaxNodes.ExpressionStatement: return _statements.ExecuteExpressionStatement(statement.As()); case SyntaxNodes.ForStatement: return _statements.ExecuteForStatement(statement.As()); - + case SyntaxNodes.ForInStatement: return _statements.ExecuteForInStatement(statement.As()); case SyntaxNodes.FunctionDeclaration: return new Completion(Completion.Normal, null, null); - + case SyntaxNodes.IfStatement: return _statements.ExecuteIfStatement(statement.As()); - + case SyntaxNodes.LabeledStatement: return _statements.ExecuteLabelledStatement(statement.As()); case SyntaxNodes.ReturnStatement: return _statements.ExecuteReturnStatement(statement.As()); - + case SyntaxNodes.SwitchStatement: return _statements.ExecuteSwitchStatement(statement.As()); - + case SyntaxNodes.ThrowStatement: return _statements.ExecuteThrowStatement(statement.As()); case SyntaxNodes.TryStatement: return _statements.ExecuteTryStatement(statement.As()); - + case SyntaxNodes.VariableDeclaration: return _statements.ExecuteVariableDeclaration(statement.As()); - + case SyntaxNodes.WhileStatement: return _statements.ExecuteWhileStatement(statement.As()); - + case SyntaxNodes.WithStatement: return _statements.ExecuteWithStatement(statement.As()); case SyntaxNodes.Program: return _statements.ExecuteProgram(statement.As()); - + default: throw new ArgumentOutOfRangeException(); } @@ -424,6 +511,11 @@ public JsValue GetValue(object value) if (reference.IsUnresolvableReference()) { + if (Options._ReferenceResolver != null && + Options._ReferenceResolver.TryUnresolvableReference(this, reference, out JsValue val)) + { + return val; + } throw new JavaScriptException(ReferenceError, reference.GetReferencedName() + " is not defined"); } @@ -431,6 +523,12 @@ public JsValue GetValue(object value) if (reference.IsPropertyReference()) { + if (Options._ReferenceResolver != null && + Options._ReferenceResolver.TryPropertyReference(this, reference, ref baseValue)) + { + return baseValue; + } + if (reference.HasPrimitiveBase() == false) { var o = TypeConverter.ToObject(this, baseValue); @@ -444,13 +542,13 @@ public JsValue GetValue(object value) { return JsValue.Undefined; } - + if (desc.IsDataDescriptor()) { - return desc.Value.Value; + return desc.Value; } - var getter = desc.Get.Value; + var getter = desc.Get; if (getter == Undefined.Instance) { return Undefined.Instance; @@ -469,7 +567,7 @@ public JsValue GetValue(object value) throw new ArgumentException(); } - return record.GetBindingValue(reference.GetReferencedName(), reference.IsStrict()); + return record.GetBindingValue(reference.GetReferencedName(), reference.IsStrict()); } } @@ -551,7 +649,7 @@ public void PutPrimitiveBase(JsValue b, string name, JsValue value, bool throwOn if (desc.IsAccessorDescriptor()) { - var setter = (ICallable)desc.Set.Value.AsObject(); + var setter = (ICallable)desc.Set.AsObject(); setter.Call(b, new[] { value }); } else @@ -583,6 +681,30 @@ public JsValue Invoke(string propertyName, params object[] arguments) public JsValue Invoke(string propertyName, object thisObj, object[] arguments) { var value = GetValue(propertyName); + + return Invoke(value, thisObj, arguments); + } + + /// + /// Invoke the current value as function. + /// + /// The function to call. + /// The arguments of the function call. + /// The value returned by the function call. + public JsValue Invoke(JsValue value, params object[] arguments) + { + return Invoke(value, null, arguments); + } + + /// + /// Invoke the current value as function. + /// + /// The function to call. + /// The this value inside the function call. + /// The arguments of the function call. + /// The value returned by the function call. + public JsValue Invoke(JsValue value, object thisObj, object[] arguments) + { var callable = value.TryCast(); if (callable == null) @@ -622,7 +744,7 @@ public JsValue GetValue(JsValue scope, string propertyName) throw new ArgumentException("propertyName"); } - var reference = new Reference(scope, propertyName, Options.IsStrict()); + var reference = new Reference(scope, propertyName, Options._IsStrict); return GetValue(reference); } @@ -667,7 +789,7 @@ public void DeclarationBindingInstantiation(DeclarationBindingType declarationBi { var go = Global; var existingProp = go.GetProperty(fn); - if (existingProp.Configurable.Value.AsBoolean()) + if (existingProp.Configurable.Value) { go.DefineOwnProperty(fn, new PropertyDescriptor( @@ -679,7 +801,7 @@ public void DeclarationBindingInstantiation(DeclarationBindingType declarationBi } else { - if (existingProp.IsAccessorDescriptor() || (!existingProp.Enumerable.Value.AsBoolean())) + if (existingProp.IsAccessorDescriptor() || (!existingProp.Enumerable.Value)) { throw new JavaScriptException(TypeError); } diff --git a/Jint/Jint.csproj b/Jint/Jint.csproj index 14e856aef6..a1a8ce427b 100644 --- a/Jint/Jint.csproj +++ b/Jint/Jint.csproj @@ -1,210 +1,24 @@ - - - - - 10.0 - Debug - AnyCPU - {678738DA-F723-4920-B9E5-CAD667104BDA} - Library - Properties - Jint - Jint - v4.0 - Profile136 - 512 - {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - - - - - 4.0 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - true - + + + en-US + net40;net45;net451;netstandard1.3;netstandard2.0 Jint.snk + true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - + + + + - - - - - - - \ No newline at end of file + + + diff --git a/Jint/Jint.nuspec b/Jint/Jint.nuspec index 41b9e4d79e..9c1e0e1b0c 100644 --- a/Jint/Jint.nuspec +++ b/Jint/Jint.nuspec @@ -2,14 +2,16 @@ Jint - 2.2.0 + 2.9.1 Sebastien Ros Sebastien Ros Javascript Interpreter for .NET en-US http://github.com/sebastienros/jint - https://raw.github.com/sebastienros/jint/master/LICENSE.txt - Added more bindings: enums, static members, indexes, typed delegates - javascript interpreter + https://raw.githubusercontent.com/sebastienros/jint/master/LICENSE.txt + +Fixes bugs for: Regular expressions, Dates, JSON parse, cached literals race condition. + + javascript interpreter jint \ No newline at end of file diff --git a/Jint/Native/Argument/ArgumentsInstance.cs b/Jint/Native/Argument/ArgumentsInstance.cs new file mode 100644 index 0000000000..6c1258ba6b --- /dev/null +++ b/Jint/Native/Argument/ArgumentsInstance.cs @@ -0,0 +1,237 @@ +using System; +using System.Collections.Generic; +using Jint.Native.Function; +using Jint.Native.Object; +using Jint.Runtime; +using Jint.Runtime.Descriptors; +using Jint.Runtime.Descriptors.Specialized; +using Jint.Runtime.Environments; + +namespace Jint.Native.Argument +{ + /// + /// http://www.ecma-international.org/ecma-262/5.1/#sec-10.6 + /// + public class ArgumentsInstance : ObjectInstance + { + private ArgumentsInstance(Engine engine, Action initializer) : base(engine) + { + _initializer = initializer; + _initialized = false; + } + + public bool Strict { get; set; } + + private Action _initializer; + private bool _initialized; + + protected override void EnsureInitialized() + { + if(_initialized) + { + return; + } + + _initialized = true; + + _initializer(this); + } + + public static ArgumentsInstance CreateArgumentsObject(Engine engine, FunctionInstance func, string[] names, JsValue[] args, EnvironmentRecord env, bool strict) + { + var obj = new ArgumentsInstance(engine, self => + { + var len = args.Length; + self.FastAddProperty("length", len, true, false, true); + var map = engine.Object.Construct(Arguments.Empty); + var mappedNamed = new List(); + var indx = 0; + while (indx <= len - 1) + { + var indxStr = TypeConverter.ToString(indx); + var val = args[indx]; + self.FastAddProperty(indxStr, val, true, true, true); + if (indx < names.Length) + { + var name = names[indx]; + if (!strict && !mappedNamed.Contains(name)) + { + mappedNamed.Add(name); + Func g = n => env.GetBindingValue(name, false); + var p = new Action((n, o) => env.SetMutableBinding(name, o, true)); + + map.DefineOwnProperty(indxStr, new ClrAccessDescriptor(engine, g, p) { Configurable = true }, false); + } + } + indx++; + } + + // step 12 + if (mappedNamed.Count > 0) + { + self.ParameterMap = map; + } + + // step 13 + if (!strict) + { + self.FastAddProperty("callee", func, true, false, true); + } + // step 14 + else + { + var thrower = engine.Function.ThrowTypeError; + self.DefineOwnProperty("caller", new PropertyDescriptor(get: thrower, set: thrower, enumerable: false, configurable: false), false); + self.DefineOwnProperty("callee", new PropertyDescriptor(get: thrower, set: thrower, enumerable: false, configurable: false), false); + } + }); + + // These properties are pre-initialized as their don't trigger + // the EnsureInitialized() event and are cheap + obj.Prototype = engine.Object.PrototypeObject; + obj.Extensible = true; + obj.Strict = strict; + + + return obj; + } + + public ObjectInstance ParameterMap { get; set; } + + public override string Class + { + get + { + return "Arguments"; + } + } + + + public override PropertyDescriptor GetOwnProperty(string propertyName) + { + EnsureInitialized(); + + if (!Strict && ParameterMap != null) + { + var desc = base.GetOwnProperty(propertyName); + if (desc == PropertyDescriptor.Undefined) + { + return desc; + } + + var isMapped = ParameterMap.GetOwnProperty(propertyName); + if (isMapped != PropertyDescriptor.Undefined) + { + desc.Value = ParameterMap.Get(propertyName); + } + + return desc; + } + + return base.GetOwnProperty(propertyName); + } + + /// Implementation from ObjectInstance official specs as the one + /// in ObjectInstance is optimized for the general case and wouldn't work + /// for arrays + public override void Put(string propertyName, JsValue value, bool throwOnError) + { + EnsureInitialized(); + + if (!CanPut(propertyName)) + { + if (throwOnError) + { + throw new JavaScriptException(Engine.TypeError); + } + + return; + } + + var ownDesc = GetOwnProperty(propertyName); + + if (ownDesc.IsDataDescriptor()) + { + var valueDesc = new PropertyDescriptor(value: value, writable: null, enumerable: null, configurable: null); + DefineOwnProperty(propertyName, valueDesc, throwOnError); + return; + } + + // property is an accessor or inherited + var desc = GetProperty(propertyName); + + if (desc.IsAccessorDescriptor()) + { + var setter = desc.Set.TryCast(); + setter.Call(new JsValue(this), new[] { value }); + } + else + { + var newDesc = new PropertyDescriptor(value, true, true, true); + DefineOwnProperty(propertyName, newDesc, throwOnError); + } + } + + public override bool DefineOwnProperty(string propertyName, PropertyDescriptor desc, bool throwOnError) + { + EnsureInitialized(); + + if (!Strict && ParameterMap != null) + { + var map = ParameterMap; + var isMapped = map.GetOwnProperty(propertyName); + var allowed = base.DefineOwnProperty(propertyName, desc, false); + if (!allowed) + { + if (throwOnError) + { + throw new JavaScriptException(Engine.TypeError); + } + } + if (isMapped != PropertyDescriptor.Undefined) + { + if (desc.IsAccessorDescriptor()) + { + map.Delete(propertyName, false); + } + else + { + if (desc.Value != null && desc.Value != Undefined.Instance) + { + map.Put(propertyName, desc.Value, throwOnError); + } + + if (desc.Writable.HasValue && desc.Writable.Value == false) + { + map.Delete(propertyName, false); + } + } + } + + return true; + } + + return base.DefineOwnProperty(propertyName, desc, throwOnError); + } + + public override bool Delete(string propertyName, bool throwOnError) + { + EnsureInitialized(); + + if (!Strict && ParameterMap != null) + { + var map = ParameterMap; + var isMapped = map.GetOwnProperty(propertyName); + var result = base.Delete(propertyName, throwOnError); + if (result && isMapped != PropertyDescriptor.Undefined) + { + map.Delete(propertyName, false); + } + + return result; + } + + return base.Delete(propertyName, throwOnError); + } + } +} diff --git a/Jint/Native/Argument/ArgumentsObject.cs b/Jint/Native/Argument/ArgumentsObject.cs deleted file mode 100644 index 4a727d94e0..0000000000 --- a/Jint/Native/Argument/ArgumentsObject.cs +++ /dev/null @@ -1,169 +0,0 @@ -using System; -using System.Collections.Generic; -using Jint.Native.Function; -using Jint.Native.Object; -using Jint.Runtime; -using Jint.Runtime.Descriptors; -using Jint.Runtime.Descriptors.Specialized; -using Jint.Runtime.Environments; - -namespace Jint.Native.Argument -{ - /// - /// http://www.ecma-international.org/ecma-262/5.1/#sec-10.6 - /// - public class ArgumentsInstance : ObjectInstance - { - public ArgumentsInstance(Engine engine) : base(engine) - { - // todo: complete implementation - } - - public bool Strict { get; set; } - - public static ArgumentsInstance CreateArgumentsObject(Engine engine, FunctionInstance func, string[] names, JsValue[] args, EnvironmentRecord env, bool strict) - { - var len = args.Length; - var obj = new ArgumentsInstance(engine); - obj.Prototype = engine.Object.PrototypeObject; - obj.Extensible = true; - obj.FastAddProperty("length", len, true, false, true); - obj.Strict = strict; - var map = engine.Object.Construct(Arguments.Empty); - var mappedNamed = new List(); - var indx = 0; - while (indx <= len - 1) - { - var indxStr = TypeConverter.ToString(indx); - var val = args[indx]; - obj.FastAddProperty(indxStr, val, true, true, true); - if (indx < names.Length) - { - var name = names[indx]; - if (!strict && !mappedNamed.Contains(name)) - { - mappedNamed.Add(name); - Func g = n => env.GetBindingValue(name, false); - var p = new Action((n, o) => env.SetMutableBinding(name, o, true)); - - map.DefineOwnProperty(indxStr, new ClrAccessDescriptor(engine, g, p) { Configurable = true }, false); - } - } - indx++; - } - - // step 12 - if (mappedNamed.Count > 0) - { - obj.ParameterMap = map; - } - - // step 13 - if (!strict) - { - obj.FastAddProperty("callee",func, true, false, true); - } - // step 14 - else - { - var thrower = engine.Function.ThrowTypeError; - obj.DefineOwnProperty("caller", new PropertyDescriptor(get: thrower, set: thrower, enumerable:false, configurable:false), false); - obj.DefineOwnProperty("callee", new PropertyDescriptor(get: thrower, set: thrower, enumerable: false, configurable: false), false); - } - - return obj; - } - - public ObjectInstance ParameterMap { get; set; } - - public override string Class - { - get - { - return "Arguments"; - } - } - - - public override PropertyDescriptor GetOwnProperty(string propertyName) - { - if (!Strict && ParameterMap != null) - { - var desc = base.GetOwnProperty(propertyName); - if (desc == PropertyDescriptor.Undefined) - { - return desc; - } - - var isMapped = ParameterMap.GetOwnProperty(propertyName); - if (isMapped != PropertyDescriptor.Undefined) - { - desc.Value = ParameterMap.Get(propertyName); - } - - return desc; - } - - return base.GetOwnProperty(propertyName); - } - - public override bool DefineOwnProperty(string propertyName, PropertyDescriptor desc, bool throwOnError) - { - if (!Strict && ParameterMap != null) - { - var map = ParameterMap; - var isMapped = map.GetOwnProperty(propertyName); - var allowed = base.DefineOwnProperty(propertyName, desc, false); - if (!allowed) - { - if (throwOnError) - { - throw new JavaScriptException(Engine.TypeError); - } - } - if (isMapped != PropertyDescriptor.Undefined) - { - if (desc.IsAccessorDescriptor()) - { - map.Delete(propertyName, false); - } - else - { - if (desc.Value.HasValue && desc.Value.Value != Undefined.Instance) - { - map.Put(propertyName, desc.Value.Value, throwOnError); - } - - if (desc.Writable.HasValue && desc.Writable.Value == false) - { - map.Delete(propertyName, false); - } - } - } - - return true; - } - - return base.DefineOwnProperty(propertyName, desc, throwOnError); - } - - public override bool Delete(string propertyName, bool throwOnError) - { - if (!Strict && ParameterMap != null) - { - var map = ParameterMap; - var isMapped = map.GetOwnProperty(propertyName); - var result = base.Delete(propertyName, throwOnError); - if (result && isMapped != PropertyDescriptor.Undefined) - { - map.Delete(propertyName, false); - } - - return result; - } - - return base.Delete(propertyName, throwOnError); - } - } -} - \ No newline at end of file diff --git a/Jint/Native/Array/ArrayConstructor.cs b/Jint/Native/Array/ArrayConstructor.cs index 02a3d21586..c1678aeba5 100644 --- a/Jint/Native/Array/ArrayConstructor.cs +++ b/Jint/Native/Array/ArrayConstructor.cs @@ -64,7 +64,7 @@ public ObjectInstance Construct(JsValue[] arguments) var length = TypeConverter.ToUint32(arguments.At(0)); if (!TypeConverter.ToNumber(arguments[0]).Equals(length)) { - throw new JavaScriptException(Engine.RangeError); + throw new JavaScriptException(Engine.RangeError, "Invalid array length"); } instance.FastAddProperty("length", length, true, false, false); diff --git a/Jint/Native/Array/ArrayInstance.cs b/Jint/Native/Array/ArrayInstance.cs index 8eca73162f..57b2a0b300 100644 --- a/Jint/Native/Array/ArrayInstance.cs +++ b/Jint/Native/Array/ArrayInstance.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System.Collections.Generic; +using System.Linq; using Jint.Native.Object; using Jint.Runtime; using Jint.Runtime.Descriptors; @@ -8,7 +9,9 @@ namespace Jint.Native.Array public class ArrayInstance : ObjectInstance { private readonly Engine _engine; - + private IDictionary _array = new MruPropertyCache2(); + private PropertyDescriptor _length; + public ArrayInstance(Engine engine) : base(engine) { _engine = engine; @@ -22,20 +25,61 @@ public override string Class } } + /// Implementation from ObjectInstance official specs as the one + /// in ObjectInstance is optimized for the general case and wouldn't work + /// for arrays + public override void Put(string propertyName, JsValue value, bool throwOnError) + { + if (!CanPut(propertyName)) + { + if (throwOnError) + { + throw new JavaScriptException(Engine.TypeError); + } + + return; + } + + var ownDesc = GetOwnProperty(propertyName); + + if (ownDesc.IsDataDescriptor()) + { + var valueDesc = new PropertyDescriptor(value: value, writable: null, enumerable: null, configurable: null); + DefineOwnProperty(propertyName, valueDesc, throwOnError); + return; + } + + // property is an accessor or inherited + var desc = GetProperty(propertyName); + + if (desc.IsAccessorDescriptor()) + { + var setter = desc.Set.TryCast(); + setter.Call(new JsValue(this), new[] { value }); + } + else + { + var newDesc = new PropertyDescriptor(value, true, true, true); + DefineOwnProperty(propertyName, newDesc, throwOnError); + } + } + public override bool DefineOwnProperty(string propertyName, PropertyDescriptor desc, bool throwOnError) { var oldLenDesc = GetOwnProperty("length"); - var oldLen = TypeConverter.ToNumber(oldLenDesc.Value.Value); + var oldLen = (uint)TypeConverter.ToNumber(oldLenDesc.Value); + uint index; + if (propertyName == "length") { - if (!desc.Value.HasValue) + if (desc.Value == null) { return base.DefineOwnProperty("length", desc, throwOnError); } var newLenDesc = new PropertyDescriptor(desc); - uint newLen = TypeConverter.ToUint32(desc.Value.Value); - if (newLen != TypeConverter.ToNumber(desc.Value.Value)) + uint newLen = TypeConverter.ToUint32(desc.Value); + if (newLen != TypeConverter.ToNumber(desc.Value)) { throw new JavaScriptException(_engine.RangeError); } @@ -43,9 +87,9 @@ public override bool DefineOwnProperty(string propertyName, PropertyDescriptor d newLenDesc.Value = newLen; if (newLen >= oldLen) { - return base.DefineOwnProperty("length", newLenDesc, throwOnError); + return base.DefineOwnProperty("length", _length = newLenDesc, throwOnError); } - if (!oldLenDesc.Writable.Value.AsBoolean()) + if (!oldLenDesc.Writable.Value) { if (throwOnError) { @@ -55,7 +99,7 @@ public override bool DefineOwnProperty(string propertyName, PropertyDescriptor d return false; } bool newWritable; - if (!newLenDesc.Writable.HasValue || newLenDesc.Writable.Value.AsBoolean()) + if (!newLenDesc.Writable.HasValue || newLenDesc.Writable.Value) { newWritable = true; } @@ -64,33 +108,35 @@ public override bool DefineOwnProperty(string propertyName, PropertyDescriptor d newWritable = false; newLenDesc.Writable = true; } - - var succeeded = base.DefineOwnProperty("length", newLenDesc, throwOnError); + + var succeeded = base.DefineOwnProperty("length", _length = newLenDesc, throwOnError); if (!succeeded) { return false; } + // in the case of sparse arrays, treat each concrete element instead of // iterating over all indexes - if (Properties.Count < oldLen - newLen) + if (_array.Count < oldLen - newLen) { - var keys = Properties.Keys.ToArray(); + var keys = _array.Keys.ToArray(); foreach (var key in keys) { - uint index; + uint keyIndex; // is it the index of the array - if (uint.TryParse(key, out index) && index >= newLen && index < oldLen) + if (IsArrayIndex(key, out keyIndex) && keyIndex >= newLen && keyIndex < oldLen) { - var deleteSucceeded = Delete(key, false); + var deleteSucceeded = Delete(key.ToString(), false); if (!deleteSucceeded) { - newLenDesc.Value = new JsValue(index + 1); + newLenDesc.Value = new JsValue(keyIndex + 1); if (!newWritable) { - newLenDesc.Writable = JsValue.False; + newLenDesc.Writable = false; } - base.DefineOwnProperty("length", newLenDesc, false); + base.DefineOwnProperty("length", _length = newLenDesc, false); + if (throwOnError) { throw new JavaScriptException(_engine.TypeError); @@ -115,7 +161,8 @@ public override bool DefineOwnProperty(string propertyName, PropertyDescriptor d { newLenDesc.Writable = false; } - base.DefineOwnProperty("length", newLenDesc, false); + base.DefineOwnProperty("length", _length = newLenDesc, false); + if (throwOnError) { throw new JavaScriptException(_engine.TypeError); @@ -131,10 +178,9 @@ public override bool DefineOwnProperty(string propertyName, PropertyDescriptor d } return true; } - else if (IsArrayIndex(propertyName)) + else if (IsArrayIndex(propertyName, out index)) { - var index = TypeConverter.ToUint32(propertyName); - if (index >= oldLen && !oldLenDesc.Writable.Value.AsBoolean()) + if (index >= oldLen && !oldLenDesc.Writable.Value) { if (throwOnError) { @@ -156,7 +202,7 @@ public override bool DefineOwnProperty(string propertyName, PropertyDescriptor d if (index >= oldLen) { oldLenDesc.Value = index + 1; - base.DefineOwnProperty("length", oldLenDesc, false); + base.DefineOwnProperty("length", _length = oldLenDesc, false); } return true; } @@ -164,10 +210,132 @@ public override bool DefineOwnProperty(string propertyName, PropertyDescriptor d return base.DefineOwnProperty(propertyName, desc, throwOnError); } - public static bool IsArrayIndex(JsValue p) + public uint GetLength() + { + return TypeConverter.ToUint32(_length.Value); + } + + public override IEnumerable> GetOwnProperties() { - return TypeConverter.ToString(TypeConverter.ToUint32(p)) == TypeConverter.ToString(p) && TypeConverter.ToUint32(p) != uint.MaxValue; + foreach(var entry in _array) + { + yield return new KeyValuePair(entry.Key.ToString(), entry.Value); + } + + foreach(var entry in base.GetOwnProperties()) + { + yield return entry; + } } + public override PropertyDescriptor GetOwnProperty(string propertyName) + { + uint index; + if (IsArrayIndex(propertyName, out index)) + { + PropertyDescriptor result; + if (_array.TryGetValue(index, out result)) + { + return result; + } + else + { + return PropertyDescriptor.Undefined; + } + } + + return base.GetOwnProperty(propertyName); + } + + protected override void SetOwnProperty(string propertyName, PropertyDescriptor desc) + { + uint index; + if (IsArrayIndex(propertyName, out index)) + { + _array[index] = desc; + } + else + { + if(propertyName == "length") + { + _length = desc; + } + + base.SetOwnProperty(propertyName, desc); + } + } + + public override bool HasOwnProperty(string p) + { + uint index; + if (IsArrayIndex(p, out index)) + { + return index < GetLength() && _array.ContainsKey(index); + } + + return base.HasOwnProperty(p); + } + + public override void RemoveOwnProperty(string p) + { + uint index; + if(IsArrayIndex(p, out index)) + { + _array.Remove(index); + } + + base.RemoveOwnProperty(p); + } + + public static bool IsArrayIndex(JsValue p, out uint index) + { + index = ParseArrayIndex(TypeConverter.ToString(p)); + + return index != uint.MaxValue; + + // 15.4 - Use an optimized version of the specification + // return TypeConverter.ToString(index) == TypeConverter.ToString(p) && index != uint.MaxValue; + } + + internal static uint ParseArrayIndex(string p) + { + int d = p[0] - '0'; + + if (d < 0 || d > 9) + { + return uint.MaxValue; + } + + if(d == 0 && p.Length > 1) + { + // If p is a number that start with '0' and is not '0' then + // its ToString representation can't be the same a p. This is + // not a valid array index. '01' !== ToString(ToUInt32('01')) + // http://www.ecma-international.org/ecma-262/5.1/#sec-15.4 + + return uint.MaxValue; + } + + ulong result = (uint)d; + + for (int i = 1; i < p.Length; i++) + { + d = p[i] - '0'; + + if (d < 0 || d > 9) + { + return uint.MaxValue; + } + + result = result * 10 + (uint)d; + + if (result >= uint.MaxValue) + { + return uint.MaxValue; + } + } + + return (uint)result; + } } } diff --git a/Jint/Native/Array/ArrayPrototype.cs b/Jint/Native/Array/ArrayPrototype.cs index 09aaea2abc..63d3ff1411 100644 --- a/Jint/Native/Array/ArrayPrototype.cs +++ b/Jint/Native/Array/ArrayPrototype.cs @@ -21,7 +21,7 @@ public static ArrayPrototype CreatePrototypeObject(Engine engine, ArrayConstruct { var obj = new ArrayPrototype(engine) { - Extensible = true, + Extensible = true, Prototype = engine.Object.PrototypeObject }; @@ -387,11 +387,11 @@ private JsValue Splice(JsValue thisObj, JsValue[] arguments) var fromPresent = o.HasProperty(from); if (fromPresent) { - var fromValue = o.Get(from); + var fromValue = o.Get(from); a.DefineOwnProperty(k.ToString(), new PropertyDescriptor(fromValue, true, true, true), false); } } - + var items = arguments.Skip(2).ToArray(); if (items.Length < actualDeleteCount) { @@ -477,7 +477,7 @@ private JsValue Sort(JsValue thisObj, JsValue[] arguments) { if (!thisObj.IsObject()) { - throw new JavaScriptException(Engine.TypeError, "Array.prorotype.sort can only be applied on objects"); + throw new JavaScriptException(Engine.TypeError, "Array.prorotype.sort can only be applied on objects"); } var obj = thisObj.AsObject(); @@ -518,8 +518,16 @@ private JsValue Sort(JsValue thisObj, JsValue[] arguments) if (compareFn != null) { - var s = (int) TypeConverter.ToUint32(compareFn.Call(Undefined.Instance, new[] {x, y})); - return s; + var s = TypeConverter.ToNumber(compareFn.Call(Undefined.Instance, new[] {x, y})); + if (s < 0) + { + return -1; + } + if (s > 0) + { + return 1; + } + return 0; } var xString = TypeConverter.ToString(x); @@ -530,7 +538,7 @@ private JsValue Sort(JsValue thisObj, JsValue[] arguments) }; var array = Enumerable.Range(0, lenVal).Select(i => obj.Get(i.ToString())).ToArray(); - + // don't eat inner exceptions try { @@ -642,7 +650,7 @@ private JsValue Reverse(JsValue thisObj, JsValue[] arguments) var o = TypeConverter.ToObject(Engine, thisObj); var lenVal = o.Get("length"); var len = TypeConverter.ToUint32(lenVal); - var middle = (uint)System.Math.Floor(len/2); + var middle = (uint)System.Math.Floor(len/2.0); uint lower = 0; while (lower != middle) { @@ -686,7 +694,7 @@ private JsValue Join(JsValue thisObj, JsValue[] arguments) separator = ","; } var sep = TypeConverter.ToString(separator); - + // as per the spec, this has to be called after ToString(separator) if (len == 0) { @@ -795,7 +803,7 @@ private JsValue Concat(JsValue thisObj, JsValue[] arguments) // this is not in the specs, but is necessary in case the last element of the last // array doesn't exist, and thus the length would not be incremented a.DefineOwnProperty("length", new PropertyDescriptor(n, null, null, null), false); - + return a; } @@ -876,7 +884,7 @@ public JsValue Push(JsValue thisObject, JsValue[] arguments) { ObjectInstance o = TypeConverter.ToObject(Engine, thisObject); var lenVal = TypeConverter.ToNumber(o.Get("length")); - + // cast to double as we need to prevent an overflow double n = TypeConverter.ToUint32(lenVal); foreach (JsValue e in arguments) @@ -886,7 +894,7 @@ public JsValue Push(JsValue thisObject, JsValue[] arguments) } o.Put("length", n, true); - + return n; } diff --git a/Jint/Native/Date/DateConstructor.cs b/Jint/Native/Date/DateConstructor.cs index 9a1f5e7e25..7a68067586 100644 --- a/Jint/Native/Date/DateConstructor.cs +++ b/Jint/Native/Date/DateConstructor.cs @@ -46,53 +46,67 @@ private JsValue Parse(JsValue thisObj, JsValue[] arguments) if (!DateTime.TryParseExact(date, new[] { - "yyyy/MM/ddTH:m:s.fff", - "yyyy/MM/dd", - "yyyy/MM", - "yyyy-MM-ddTH:m:s.fff", + "yyyy-MM-ddTHH:mm:ss.FFF", + "yyyy-MM-ddTHH:mm:ss", + "yyyy-MM-ddTHH:mm", "yyyy-MM-dd", "yyyy-MM", - "yyyy", - "THH:m:s.fff", - "TH:mm:sm", - "THH:mm", - "THH" - }, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out result)) + "yyyy" + }, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal, out result)) { if (!DateTime.TryParseExact(date, new[] { - "yyyy/MM/ddTH:m:s.fffK", - "yyyy/MM/ddK", - "yyyy/MMK", - "yyyy-MM-ddTH:m:s.fffK", - "yyyy-MM-ddK", - "yyyy-MMK", + // Formats used in DatePrototype toString methods + "ddd MMM dd yyyy HH:mm:ss 'GMT'K", + "ddd MMM dd yyyy", + "HH:mm:ss 'GMT'K", + + // standard formats + "yyyy-M-dTH:m:s.FFFK", + "yyyy/M/dTH:m:s.FFFK", + "yyyy-M-dTH:m:sK", + "yyyy/M/dTH:m:sK", + "yyyy-M-dTH:mK", + "yyyy/M/dTH:mK", + "yyyy-M-d H:m:s.FFFK", + "yyyy/M/d H:m:s.FFFK", + "yyyy-M-d H:m:sK", + "yyyy/M/d H:m:sK", + "yyyy-M-d H:mK", + "yyyy/M/d H:mK", + "yyyy-M-dK", + "yyyy/M/dK", + "yyyy-MK", + "yyyy/MK", "yyyyK", - "THH:m:s.fffK", - "TH:mm:smK", + "THH:mm:ss.FFFK", + "THH:mm:ssK", "THH:mmK", "THHK" }, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out result)) { - if (!DateTime.TryParse(date, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal,out result)) + if (!DateTime.TryParse(date, Engine.Options._Culture, DateTimeStyles.AdjustToUniversal, out result)) { - throw new JavaScriptException(Engine.SyntaxError, "Invalid date"); + if (!DateTime.TryParse(date, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out result)) + { + // unrecognized dates should return NaN (15.9.4.2) + return double.NaN; + } } } } - return Construct(result); + return FromDateTime(result); } private JsValue Utc(JsValue thisObj, JsValue[] arguments) { - var local = (DateInstance) Construct(arguments); - return local.PrimitiveValue; + return TimeClip(ConstructTimeValue(arguments, useUtc: true)); } private JsValue Now(JsValue thisObj, JsValue[] arguments) { - return (DateTime.UtcNow - Epoch).TotalMilliseconds; + return System.Math.Floor((DateTime.UtcNow - Epoch).TotalMilliseconds); } public override JsValue Call(JsValue thisObject, JsValue[] arguments) @@ -109,46 +123,57 @@ public ObjectInstance Construct(JsValue[] arguments) { if (arguments.Length == 0) { - return Construct(DateTime.Now); + return Construct(DateTime.UtcNow); } else if (arguments.Length == 1) { var v = TypeConverter.ToPrimitive(arguments[0]); if (v.IsString()) { - return Parse(Undefined.Instance, Arguments.From(v)).AsObject(); + return Construct(Parse(Undefined.Instance, Arguments.From(v)).AsNumber()); } - return Construct(DatePrototype.TimeClip(TypeConverter.ToNumber(v))); + return Construct(TypeConverter.ToNumber(v)); } else { - var y = TypeConverter.ToNumber(arguments[0]); - var m = (int)TypeConverter.ToInteger(arguments[1]); - var dt = arguments.Length > 2 ? (int)TypeConverter.ToInteger(arguments[2]) : 1; - var h = arguments.Length > 3 ? (int)TypeConverter.ToInteger(arguments[3]) : 0; - var min = arguments.Length > 4 ? (int)TypeConverter.ToInteger(arguments[4]) : 0; - var s = arguments.Length > 5 ? (int)TypeConverter.ToInteger(arguments[5]) : 0; - var milli = arguments.Length > 6 ? (int)TypeConverter.ToInteger(arguments[6]) : 0; - - for (int i = 2; i < arguments.Length; i++) - { - if (double.IsNaN(TypeConverter.ToNumber(arguments[i]))) - { - return Construct(double.NaN); - } - } + return Construct(ConstructTimeValue(arguments, useUtc: false)); + } + } - if ((!double.IsNaN(y)) && (0 <= TypeConverter.ToInteger(y)) && (TypeConverter.ToInteger(y) <= 99)) + private double ConstructTimeValue(JsValue[] arguments, bool useUtc) + { + if (arguments.Length < 2) + { + throw new ArgumentOutOfRangeException("arguments", "There must be at least two arguments."); + } + + var y = TypeConverter.ToNumber(arguments[0]); + var m = (int)TypeConverter.ToInteger(arguments[1]); + var dt = arguments.Length > 2 ? (int)TypeConverter.ToInteger(arguments[2]) : 1; + var h = arguments.Length > 3 ? (int)TypeConverter.ToInteger(arguments[3]) : 0; + var min = arguments.Length > 4 ? (int)TypeConverter.ToInteger(arguments[4]) : 0; + var s = arguments.Length > 5 ? (int)TypeConverter.ToInteger(arguments[5]) : 0; + var milli = arguments.Length > 6 ? (int)TypeConverter.ToInteger(arguments[6]) : 0; + + for (int i = 2; i < arguments.Length; i++) + { + if (double.IsNaN(TypeConverter.ToNumber(arguments[i]))) { - y += 1900; + return double.NaN; } + } - var finalDate = DatePrototype.MakeDate(DatePrototype.MakeDay(y, m, dt), - DatePrototype.MakeTime(h, min, s, milli)); - - return Construct(DatePrototype.TimeClip(DatePrototype.Utc(finalDate))); + if ((!double.IsNaN(y)) && (0 <= TypeConverter.ToInteger(y)) && (TypeConverter.ToInteger(y) <= 99)) + { + y += 1900; } + + var finalDate = DatePrototype.MakeDate( + DatePrototype.MakeDay(y, m, dt), + DatePrototype.MakeTime(h, min, s, milli)); + + return TimeClip(useUtc ? finalDate : PrototypeObject.Utc(finalDate)); } public DatePrototype PrototypeObject { get; private set; } @@ -197,9 +222,22 @@ public static double TimeClip(double time) return TypeConverter.ToInteger(time); } - public static double FromDateTime(DateTime dt) + public double FromDateTime(DateTime dt) { - return System.Math.Floor((dt.ToUniversalTime() - Epoch).TotalMilliseconds); + var convertToUtcAfter = (dt.Kind == DateTimeKind.Unspecified); + + var dateAsUtc = dt.Kind == DateTimeKind.Local + ? dt.ToUniversalTime() + : DateTime.SpecifyKind(dt, DateTimeKind.Utc); + + var result = (dateAsUtc - Epoch).TotalMilliseconds; + + if (convertToUtcAfter) + { + result = PrototypeObject.Utc(result); + } + + return System.Math.Floor(result); } } } diff --git a/Jint/Native/Date/DateInstance.cs b/Jint/Native/Date/DateInstance.cs index a0ca577f47..be0d3a04f5 100644 --- a/Jint/Native/Date/DateInstance.cs +++ b/Jint/Native/Date/DateInstance.cs @@ -7,10 +7,10 @@ namespace Jint.Native.Date public class DateInstance : ObjectInstance { // Maximum allowed value to prevent DateTime overflow - internal static readonly double Max = (DateTime.MaxValue - new DateTime(170, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds; + internal static readonly double Max = (DateTime.MaxValue - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds; // Minimum allowed value to prevent DateTime overflow - internal static readonly double Min = -(new DateTime(170, 1, 1, 0, 0, 0, DateTimeKind.Utc) - DateTime.MinValue).TotalMilliseconds; + internal static readonly double Min = -(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc) - DateTime.MinValue).TotalMilliseconds; public DateInstance(Engine engine) : base(engine) diff --git a/Jint/Native/Date/DatePrototype.cs b/Jint/Native/Date/DatePrototype.cs index 04b248a897..6827518430 100644 --- a/Jint/Native/Date/DatePrototype.cs +++ b/Jint/Native/Date/DatePrototype.cs @@ -19,7 +19,7 @@ public static DatePrototype CreatePrototypeObject(Engine engine, DateConstructor { var obj = new DatePrototype(engine) { - Prototype = engine.Object.PrototypeObject, + Prototype = engine.Object.PrototypeObject, Extensible = true, PrimitiveValue = double.NaN }; @@ -78,54 +78,66 @@ public void Configure() FastAddProperty("toJSON", new ClrFunctionInstance(Engine, ToJSON, 1), true, false, true); } - private static JsValue ValueOf(JsValue thisObj, JsValue[] arguments) + private JsValue ValueOf(JsValue thisObj, JsValue[] arguments) { - return thisObj.TryCast().PrimitiveValue; + return EnsureDateInstance(thisObj).PrimitiveValue; + } + + /// + /// Converts a value to a or throws a TypeError exception. + /// c.f., http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.5 + /// + private DateInstance EnsureDateInstance(JsValue thisObj) + { + return thisObj.TryCast(value => + { + throw new JavaScriptException(Engine.TypeError, "Invalid Date"); + }); } public JsValue ToString(JsValue thisObj, JsValue[] arg2) { - return thisObj.TryCast().ToDateTime().ToLocalTime().ToString("ddd MMM dd yyyy HH:mm:ss 'GMT'K", CultureInfo.InvariantCulture); + return ToLocalTime(EnsureDateInstance(thisObj).ToDateTime()).ToString("ddd MMM dd yyyy HH:mm:ss 'GMT'K", CultureInfo.InvariantCulture); } - private static JsValue ToDateString(JsValue thisObj, JsValue[] arguments) + private JsValue ToDateString(JsValue thisObj, JsValue[] arguments) { - return thisObj.TryCast().ToDateTime().ToString("D", CultureInfo.InvariantCulture); + return ToLocalTime(EnsureDateInstance(thisObj).ToDateTime()).ToString("ddd MMM dd yyyy", CultureInfo.InvariantCulture); } - private static JsValue ToTimeString(JsValue thisObj, JsValue[] arguments) + private JsValue ToTimeString(JsValue thisObj, JsValue[] arguments) { - return thisObj.TryCast().ToDateTime().ToString("T", CultureInfo.InvariantCulture); + return ToLocalTime(EnsureDateInstance(thisObj).ToDateTime()).ToString("HH:mm:ss 'GMT'K", CultureInfo.InvariantCulture); } - private static JsValue ToLocaleString(JsValue thisObj, JsValue[] arguments) + private JsValue ToLocaleString(JsValue thisObj, JsValue[] arguments) { - return thisObj.TryCast().ToDateTime().ToString("F"); + return ToLocalTime(EnsureDateInstance(thisObj).ToDateTime()).ToString("F", Engine.Options._Culture); } - private static JsValue ToLocaleDateString(JsValue thisObj, JsValue[] arguments) + private JsValue ToLocaleDateString(JsValue thisObj, JsValue[] arguments) { - return thisObj.TryCast().ToDateTime().ToString("D"); + return ToLocalTime(EnsureDateInstance(thisObj).ToDateTime()).ToString("D", Engine.Options._Culture); } private JsValue ToLocaleTimeString(JsValue thisObj, JsValue[] arguments) { - return thisObj.TryCast().ToDateTime().ToString("T"); + return ToLocalTime(EnsureDateInstance(thisObj).ToDateTime()).ToString("T", Engine.Options._Culture); } - private static JsValue GetTime(JsValue thisObj, JsValue[] arguments) + private JsValue GetTime(JsValue thisObj, JsValue[] arguments) { - if (double.IsNaN(thisObj.TryCast().PrimitiveValue)) + if (double.IsNaN(EnsureDateInstance(thisObj).PrimitiveValue)) { return double.NaN; } - return thisObj.TryCast().PrimitiveValue; + return EnsureDateInstance(thisObj).PrimitiveValue; } - private static JsValue GetFullYear(JsValue thisObj, JsValue[] arguments) + private JsValue GetFullYear(JsValue thisObj, JsValue[] arguments) { - var t = thisObj.TryCast().PrimitiveValue; + var t = EnsureDateInstance(thisObj).PrimitiveValue; if (double.IsNaN(t)) { return double.NaN; @@ -134,9 +146,9 @@ private static JsValue GetFullYear(JsValue thisObj, JsValue[] arguments) return YearFromTime(LocalTime(t)); } - private static JsValue GetYear(JsValue thisObj, JsValue[] arguments) + private JsValue GetYear(JsValue thisObj, JsValue[] arguments) { - var t = thisObj.TryCast().PrimitiveValue; + var t = EnsureDateInstance(thisObj).PrimitiveValue; if (double.IsNaN(t)) { return double.NaN; @@ -145,9 +157,9 @@ private static JsValue GetYear(JsValue thisObj, JsValue[] arguments) return YearFromTime(LocalTime(t)) - 1900; } - private static JsValue GetUTCFullYear(JsValue thisObj, JsValue[] arguments) + private JsValue GetUTCFullYear(JsValue thisObj, JsValue[] arguments) { - var t = thisObj.TryCast().PrimitiveValue; + var t = EnsureDateInstance(thisObj).PrimitiveValue; if (double.IsNaN(t)) { return double.NaN; @@ -156,9 +168,9 @@ private static JsValue GetUTCFullYear(JsValue thisObj, JsValue[] arguments) return YearFromTime(t); } - private static JsValue GetMonth(JsValue thisObj, JsValue[] arguments) + private JsValue GetMonth(JsValue thisObj, JsValue[] arguments) { - var t = thisObj.TryCast().PrimitiveValue; + var t = EnsureDateInstance(thisObj).PrimitiveValue; if (double.IsNaN(t)) { return double.NaN; @@ -167,9 +179,9 @@ private static JsValue GetMonth(JsValue thisObj, JsValue[] arguments) return MonthFromTime(LocalTime(t)); } - private static JsValue GetUTCMonth(JsValue thisObj, JsValue[] arguments) + private JsValue GetUTCMonth(JsValue thisObj, JsValue[] arguments) { - var t = thisObj.TryCast().PrimitiveValue; + var t = EnsureDateInstance(thisObj).PrimitiveValue; if (double.IsNaN(t)) { return double.NaN; @@ -178,9 +190,9 @@ private static JsValue GetUTCMonth(JsValue thisObj, JsValue[] arguments) return MonthFromTime(t); } - private static JsValue GetDate(JsValue thisObj, JsValue[] arguments) + private JsValue GetDate(JsValue thisObj, JsValue[] arguments) { - var t = thisObj.TryCast().PrimitiveValue; + var t = EnsureDateInstance(thisObj).PrimitiveValue; if (double.IsNaN(t)) { return double.NaN; @@ -189,9 +201,9 @@ private static JsValue GetDate(JsValue thisObj, JsValue[] arguments) return DateFromTime(LocalTime(t)); } - private static JsValue GetUTCDate(JsValue thisObj, JsValue[] arguments) + private JsValue GetUTCDate(JsValue thisObj, JsValue[] arguments) { - var t = thisObj.TryCast().PrimitiveValue; + var t = EnsureDateInstance(thisObj).PrimitiveValue; if (double.IsNaN(t)) { return double.NaN; @@ -200,9 +212,9 @@ private static JsValue GetUTCDate(JsValue thisObj, JsValue[] arguments) return DateFromTime(t); } - private static JsValue GetDay(JsValue thisObj, JsValue[] arguments) + private JsValue GetDay(JsValue thisObj, JsValue[] arguments) { - var t = thisObj.TryCast().PrimitiveValue; + var t = EnsureDateInstance(thisObj).PrimitiveValue; if (double.IsNaN(t)) { return double.NaN; @@ -211,9 +223,9 @@ private static JsValue GetDay(JsValue thisObj, JsValue[] arguments) return WeekDay(LocalTime(t)); } - private static JsValue GetUTCDay(JsValue thisObj, JsValue[] arguments) + private JsValue GetUTCDay(JsValue thisObj, JsValue[] arguments) { - var t = thisObj.TryCast().PrimitiveValue; + var t = EnsureDateInstance(thisObj).PrimitiveValue; if (double.IsNaN(t)) { return double.NaN; @@ -222,9 +234,9 @@ private static JsValue GetUTCDay(JsValue thisObj, JsValue[] arguments) return WeekDay(t); } - private static JsValue GetHours(JsValue thisObj, JsValue[] arguments) + private JsValue GetHours(JsValue thisObj, JsValue[] arguments) { - var t = thisObj.TryCast().PrimitiveValue; + var t = EnsureDateInstance(thisObj).PrimitiveValue; if (double.IsNaN(t)) { return double.NaN; @@ -233,9 +245,9 @@ private static JsValue GetHours(JsValue thisObj, JsValue[] arguments) return HourFromTime(LocalTime(t)); } - private static JsValue GetUTCHours(JsValue thisObj, JsValue[] arguments) + private JsValue GetUTCHours(JsValue thisObj, JsValue[] arguments) { - var t = thisObj.TryCast().PrimitiveValue; + var t = EnsureDateInstance(thisObj).PrimitiveValue; if (double.IsNaN(t)) { return double.NaN; @@ -244,9 +256,9 @@ private static JsValue GetUTCHours(JsValue thisObj, JsValue[] arguments) return HourFromTime(t); } - private static JsValue GetMinutes(JsValue thisObj, JsValue[] arguments) + private JsValue GetMinutes(JsValue thisObj, JsValue[] arguments) { - var t = thisObj.TryCast().PrimitiveValue; + var t = EnsureDateInstance(thisObj).PrimitiveValue; if (double.IsNaN(t)) { return double.NaN; @@ -255,9 +267,9 @@ private static JsValue GetMinutes(JsValue thisObj, JsValue[] arguments) return MinFromTime(LocalTime(t)); } - private static JsValue GetUTCMinutes(JsValue thisObj, JsValue[] arguments) + private JsValue GetUTCMinutes(JsValue thisObj, JsValue[] arguments) { - var t = thisObj.TryCast().PrimitiveValue; + var t = EnsureDateInstance(thisObj).PrimitiveValue; if (double.IsNaN(t)) { return double.NaN; @@ -266,7 +278,7 @@ private static JsValue GetUTCMinutes(JsValue thisObj, JsValue[] arguments) return MinFromTime(t); } - private static JsValue GetSeconds(JsValue thisObj, JsValue[] arguments) + private JsValue GetSeconds(JsValue thisObj, JsValue[] arguments) { var t = thisObj.TryCast().PrimitiveValue; if (double.IsNaN(t)) @@ -277,9 +289,9 @@ private static JsValue GetSeconds(JsValue thisObj, JsValue[] arguments) return SecFromTime(LocalTime(t)); } - private static JsValue GetUTCSeconds(JsValue thisObj, JsValue[] arguments) + private JsValue GetUTCSeconds(JsValue thisObj, JsValue[] arguments) { - var t = thisObj.TryCast().PrimitiveValue; + var t = EnsureDateInstance(thisObj).PrimitiveValue; if (double.IsNaN(t)) { return double.NaN; @@ -288,9 +300,9 @@ private static JsValue GetUTCSeconds(JsValue thisObj, JsValue[] arguments) return SecFromTime(t); } - private static JsValue GetMilliseconds(JsValue thisObj, JsValue[] arguments) + private JsValue GetMilliseconds(JsValue thisObj, JsValue[] arguments) { - var t = thisObj.TryCast().PrimitiveValue; + var t = EnsureDateInstance(thisObj).PrimitiveValue; if (double.IsNaN(t)) { return double.NaN; @@ -299,9 +311,9 @@ private static JsValue GetMilliseconds(JsValue thisObj, JsValue[] arguments) return MsFromTime(LocalTime(t)); } - private static JsValue GetUTCMilliseconds(JsValue thisObj, JsValue[] arguments) + private JsValue GetUTCMilliseconds(JsValue thisObj, JsValue[] arguments) { - var t = thisObj.TryCast().PrimitiveValue; + var t = EnsureDateInstance(thisObj).PrimitiveValue; if (double.IsNaN(t)) { return double.NaN; @@ -310,9 +322,9 @@ private static JsValue GetUTCMilliseconds(JsValue thisObj, JsValue[] arguments) return MsFromTime(t); } - private static JsValue GetTimezoneOffset(JsValue thisObj, JsValue[] arguments) + private JsValue GetTimezoneOffset(JsValue thisObj, JsValue[] arguments) { - var t = thisObj.TryCast().PrimitiveValue; + var t = EnsureDateInstance(thisObj).PrimitiveValue; if (double.IsNaN(t)) { return double.NaN; @@ -321,43 +333,43 @@ private static JsValue GetTimezoneOffset(JsValue thisObj, JsValue[] arguments) return (t - LocalTime(t))/MsPerMinute; } - private static JsValue SetTime(JsValue thisObj, JsValue[] arguments) + private JsValue SetTime(JsValue thisObj, JsValue[] arguments) { - return thisObj.As().PrimitiveValue = TimeClip(TypeConverter.ToNumber(arguments.At(0))); + return EnsureDateInstance(thisObj).PrimitiveValue = TimeClip(TypeConverter.ToNumber(arguments.At(0))); } - private static JsValue SetMilliseconds(JsValue thisObj, JsValue[] arguments) + private JsValue SetMilliseconds(JsValue thisObj, JsValue[] arguments) { - var t = LocalTime(thisObj.As().PrimitiveValue); + var t = LocalTime(EnsureDateInstance(thisObj).PrimitiveValue); var time = MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), TypeConverter.ToNumber(arguments.At(0))); var u = TimeClip(Utc(MakeDate(Day(t), time))); thisObj.As().PrimitiveValue = u; return u; } - private static JsValue SetUTCMilliseconds(JsValue thisObj, JsValue[] arguments) + private JsValue SetUTCMilliseconds(JsValue thisObj, JsValue[] arguments) { - var t = thisObj.As().PrimitiveValue; + var t = EnsureDateInstance(thisObj).PrimitiveValue; var time = MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), TypeConverter.ToNumber(arguments.At(0))); var u = TimeClip(MakeDate(Day(t), time)); thisObj.As().PrimitiveValue = u; return u; } - private static JsValue SetSeconds(JsValue thisObj, JsValue[] arguments) + private JsValue SetSeconds(JsValue thisObj, JsValue[] arguments) { - var t = LocalTime(thisObj.As().PrimitiveValue); + var t = LocalTime(EnsureDateInstance(thisObj).PrimitiveValue); var s = TypeConverter.ToNumber(arguments.At(0)); - var milli = arguments.Length <= 1 ? MsFromTime(t) : TypeConverter.ToNumber(arguments.At(1)); + var milli = arguments.Length <= 1 ? MsFromTime(t) : TypeConverter.ToNumber(arguments.At(1)); var date = MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), s, milli)); var u = TimeClip(Utc(date)); thisObj.As().PrimitiveValue = u; return u; } - private static JsValue SetUTCSeconds(JsValue thisObj, JsValue[] arguments) + private JsValue SetUTCSeconds(JsValue thisObj, JsValue[] arguments) { - var t = thisObj.As().PrimitiveValue; + var t = EnsureDateInstance(thisObj).PrimitiveValue; var s = TypeConverter.ToNumber(arguments.At(0)); var milli = arguments.Length <= 1 ? MsFromTime(t) : TypeConverter.ToNumber(arguments.At(1)); var date = MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), s, milli)); @@ -366,9 +378,9 @@ private static JsValue SetUTCSeconds(JsValue thisObj, JsValue[] arguments) return u; } - private static JsValue SetMinutes(JsValue thisObj, JsValue[] arguments) + private JsValue SetMinutes(JsValue thisObj, JsValue[] arguments) { - var t = LocalTime(thisObj.As().PrimitiveValue); + var t = LocalTime(EnsureDateInstance(thisObj).PrimitiveValue); var m = TypeConverter.ToNumber(arguments.At(0)); var s = arguments.Length <= 1 ? SecFromTime(t) : TypeConverter.ToNumber(arguments.At(1)); var milli = arguments.Length <= 2 ? MsFromTime(t) : TypeConverter.ToNumber(arguments.At(2)); @@ -378,9 +390,9 @@ private static JsValue SetMinutes(JsValue thisObj, JsValue[] arguments) return u; } - private static JsValue SetUTCMinutes(JsValue thisObj, JsValue[] arguments) + private JsValue SetUTCMinutes(JsValue thisObj, JsValue[] arguments) { - var t = thisObj.As().PrimitiveValue; + var t = EnsureDateInstance(thisObj).PrimitiveValue; var m = TypeConverter.ToNumber(arguments.At(0)); var s = arguments.Length <= 1 ? SecFromTime(t) : TypeConverter.ToNumber(arguments.At(1)); var milli = arguments.Length <= 2 ? MsFromTime(t) : TypeConverter.ToNumber(arguments.At(2)); @@ -390,9 +402,9 @@ private static JsValue SetUTCMinutes(JsValue thisObj, JsValue[] arguments) return u; } - private static JsValue SetHours(JsValue thisObj, JsValue[] arguments) + private JsValue SetHours(JsValue thisObj, JsValue[] arguments) { - var t = LocalTime(thisObj.As().PrimitiveValue); + var t = LocalTime(EnsureDateInstance(thisObj).PrimitiveValue); var h = TypeConverter.ToNumber(arguments.At(0)); var m = arguments.Length <= 1 ? MinFromTime(t) : TypeConverter.ToNumber(arguments.At(1)); var s = arguments.Length <= 2 ? SecFromTime(t) : TypeConverter.ToNumber(arguments.At(2)); @@ -403,9 +415,9 @@ private static JsValue SetHours(JsValue thisObj, JsValue[] arguments) return u; } - private static JsValue SetUTCHours(JsValue thisObj, JsValue[] arguments) + private JsValue SetUTCHours(JsValue thisObj, JsValue[] arguments) { - var t = thisObj.As().PrimitiveValue; + var t = EnsureDateInstance(thisObj).PrimitiveValue; var h = TypeConverter.ToNumber(arguments.At(0)); var m = arguments.Length <= 1 ? MinFromTime(t) : TypeConverter.ToNumber(arguments.At(1)); var s = arguments.Length <= 2 ? SecFromTime(t) : TypeConverter.ToNumber(arguments.At(2)); @@ -416,9 +428,9 @@ private static JsValue SetUTCHours(JsValue thisObj, JsValue[] arguments) return u; } - private static JsValue SetDate(JsValue thisObj, JsValue[] arguments) + private JsValue SetDate(JsValue thisObj, JsValue[] arguments) { - var t = LocalTime(thisObj.As().PrimitiveValue); + var t = LocalTime(EnsureDateInstance(thisObj).PrimitiveValue); var dt = TypeConverter.ToNumber(arguments.At(0)); var newDate = MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t)); var u = TimeClip(Utc(newDate)); @@ -426,9 +438,9 @@ private static JsValue SetDate(JsValue thisObj, JsValue[] arguments) return u; } - private static JsValue SetUTCDate(JsValue thisObj, JsValue[] arguments) + private JsValue SetUTCDate(JsValue thisObj, JsValue[] arguments) { - var t = thisObj.As().PrimitiveValue; + var t = EnsureDateInstance(thisObj).PrimitiveValue; var dt = TypeConverter.ToNumber(arguments.At(0)); var newDate = MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t)); var u = TimeClip(newDate); @@ -436,9 +448,9 @@ private static JsValue SetUTCDate(JsValue thisObj, JsValue[] arguments) return u; } - private static JsValue SetMonth(JsValue thisObj, JsValue[] arguments) + private JsValue SetMonth(JsValue thisObj, JsValue[] arguments) { - var t = LocalTime(thisObj.As().PrimitiveValue); + var t = LocalTime(EnsureDateInstance(thisObj).PrimitiveValue); var m = TypeConverter.ToNumber(arguments.At(0)); var dt = arguments.Length <= 1 ? DateFromTime(t) : TypeConverter.ToNumber(arguments.At(1)); var newDate = MakeDate(MakeDay(YearFromTime(t), m, dt), TimeWithinDay(t)); @@ -447,9 +459,9 @@ private static JsValue SetMonth(JsValue thisObj, JsValue[] arguments) return u; } - private static JsValue SetUTCMonth(JsValue thisObj, JsValue[] arguments) + private JsValue SetUTCMonth(JsValue thisObj, JsValue[] arguments) { - var t = thisObj.As().PrimitiveValue; + var t = EnsureDateInstance(thisObj).PrimitiveValue; var m = TypeConverter.ToNumber(arguments.At(0)); var dt = arguments.Length <= 1 ? DateFromTime(t) : TypeConverter.ToNumber(arguments.At(1)); var newDate = MakeDate(MakeDay(YearFromTime(t), m, dt), TimeWithinDay(t)); @@ -458,9 +470,9 @@ private static JsValue SetUTCMonth(JsValue thisObj, JsValue[] arguments) return u; } - private static JsValue SetFullYear(JsValue thisObj, JsValue[] arguments) + private JsValue SetFullYear(JsValue thisObj, JsValue[] arguments) { - var thisTime = thisObj.As().PrimitiveValue; + var thisTime = EnsureDateInstance(thisObj).PrimitiveValue; var t = double.IsNaN(thisTime) ? +0 : LocalTime(thisTime); var y = TypeConverter.ToNumber(arguments.At(0)); var m = arguments.Length <= 1 ? MonthFromTime(t) : TypeConverter.ToNumber(arguments.At(1)); @@ -471,14 +483,14 @@ private static JsValue SetFullYear(JsValue thisObj, JsValue[] arguments) return u; } - private static JsValue SetYear(JsValue thisObj, JsValue[] arguments) + private JsValue SetYear(JsValue thisObj, JsValue[] arguments) { - var thisTime = thisObj.As().PrimitiveValue; + var thisTime = EnsureDateInstance(thisObj).PrimitiveValue; var t = double.IsNaN(thisTime) ? +0 : LocalTime(thisTime); var y = TypeConverter.ToNumber(arguments.At(0)); if (double.IsNaN(y)) { - thisObj.As().PrimitiveValue = double.NaN; + EnsureDateInstance(thisObj).PrimitiveValue = double.NaN; return double.NaN; } @@ -490,13 +502,13 @@ private static JsValue SetYear(JsValue thisObj, JsValue[] arguments) var newDate = MakeDay(fy, MonthFromTime(t), DateFromTime(t)); var u = Utc(MakeDate(newDate, TimeWithinDay(t))); - thisObj.As().PrimitiveValue = TimeClip(u); + EnsureDateInstance(thisObj).PrimitiveValue = TimeClip(u); return u; } - private static JsValue SetUTCFullYear(JsValue thisObj, JsValue[] arguments) + private JsValue SetUTCFullYear(JsValue thisObj, JsValue[] arguments) { - var thisTime = thisObj.As().PrimitiveValue; + var thisTime = EnsureDateInstance(thisObj).PrimitiveValue; var t = double.IsNaN(thisTime) ? +0 : thisTime; var y = TypeConverter.ToNumber(arguments.At(0)); var m = arguments.Length <= 1 ? MonthFromTime(t) : TypeConverter.ToNumber(arguments.At(1)); @@ -513,7 +525,7 @@ private JsValue ToUtcString(JsValue thisObj, JsValue[] arguments) { throw new JavaScriptException(Engine.TypeError); } ) - .ToDateTime().ToUniversalTime().ToString("r"); + .ToDateTime().ToUniversalTime().ToString("ddd MMM dd yyyy HH:mm:ss 'GMT'", CultureInfo.InvariantCulture); } private JsValue ToISOString(JsValue thisObj, JsValue[] arguments) @@ -527,15 +539,22 @@ private JsValue ToISOString(JsValue thisObj, JsValue[] arguments) { throw new JavaScriptException(Engine.RangeError); } - - return string.Format("{0:0000}-{1:00}-{2:00}T{3:00}:{4:00}:{5:00}.{6:000}Z", + double h = HourFromTime(t); + double m = MinFromTime(t); + double s = SecFromTime(t); + double ms = MsFromTime(t); + if (h < 0) { h += HoursPerDay; } + if (m < 0) { m += MinutesPerHour; } + if (s < 0) { s += SecondsPerMinute; } + if (ms < 0) { ms += MsPerSecond; } + return string.Format("{0:0000}-{1:00}-{2:00}T{3:00}:{4:00}:{5:00}.{6:000}Z", YearFromTime(t), MonthFromTime(t)+1, DateFromTime(t), - HourFromTime(t), - MinFromTime(t), - SecFromTime(t), - MsFromTime(t)); + h, + m, + s, + ms); } private JsValue ToJSON(JsValue thisObj, JsValue[] arguments) @@ -556,13 +575,13 @@ private JsValue ToJSON(JsValue thisObj, JsValue[] arguments) return toIso.TryCast().Call(o, Arguments.Empty); } - public static double HoursPerDay = 24; - public static double MinutesPerHour = 60; - public static double SecondsPerMinute = 60; - public static double MsPerSecond = 1000; - public static double MsPerMinute = 60000; - public static double MsPerHour = 3600000; - public static double MsPerDay = 86400000; + public const double HoursPerDay = 24; + public const double MinutesPerHour = 60; + public const double SecondsPerMinute = 60; + public const double MsPerSecond = 1000; + public const double MsPerMinute = 60000; + public const double MsPerHour = 3600000; + public const double MsPerDay = 86400000; /// /// 15.9.1.2 @@ -577,7 +596,14 @@ public static double Day(double t) /// public static double TimeWithinDay(double t) { - return t % MsPerDay; + if (t < 0) + { + return ((t % MsPerDay) + MsPerDay); + } + else + { + return (t % MsPerDay); + } } /// @@ -613,9 +639,9 @@ public static double DaysInYear(double y) /// public static double DayFromYear(double y) { - return 365*(y - 1970) - + System.Math.Floor((y - 1969)/4) - - System.Math.Floor((y - 1901)/100) + return 365*(y - 1970) + + System.Math.Floor((y - 1969)/4) + - System.Math.Floor((y - 1901)/100) + System.Math.Floor((y - 1601)/400); } @@ -637,25 +663,40 @@ public static double YearFromTime(double t) return Double.NaN; } - double upper = double.MaxValue; - double lower = double.MinValue; - while (upper > lower + 1) + var sign = (t < 0) ? -1 : 1; + var year = (sign < 0) ? 1969 : 1970; + for (var timeToTimeZero = t; ;) { - var current = System.Math.Floor((upper + lower) / 2); - - var tfy = TimeFromYear(current); + // Subtract the current year's time from the time that's left. + var timeInYear = DaysInYear(year) * MsPerDay; + timeToTimeZero -= sign * timeInYear; - if (tfy <= t) + // If there's less than the current year's worth of time left, then break. + if (sign < 0) { - lower = current; + if (sign * timeToTimeZero <= 0) + { + break; + } + else + { + year += sign; + } } - else + else { - upper = current; + if (sign * timeToTimeZero < 0) + { + break; + } + else + { + year += sign; + } } } - return lower; + return year; } /// @@ -668,12 +709,12 @@ public static double InLeapYear(double t) if (daysInYear.Equals(365)) { return 0; - } + } if (daysInYear.Equals(366)) { return 1; - } + } throw new ArgumentException(); } @@ -830,15 +871,15 @@ public static double WeekDay(double t) return (Day(t) + 4)%7; } - public static double LocalTza + public double LocalTza { get { - return TimeZoneInfo.Local.BaseUtcOffset.TotalMilliseconds; + return Engine.Options._LocalTimeZone.BaseUtcOffset.TotalMilliseconds; } } - public static double DaylightSavingTa(double t) + public double DaylightSavingTa(double t) { var timeInYear = t - TimeFromYear(YearFromTime(t)); @@ -861,37 +902,78 @@ public static double DaylightSavingTa(double t) var dateTime = new DateTime((int)year, 1, 1).AddMilliseconds(timeInYear); - return TimeZoneInfo.Local.IsDaylightSavingTime(dateTime) ? MsPerHour : 0; + return Engine.Options._LocalTimeZone.IsDaylightSavingTime(dateTime) ? MsPerHour : 0; + } + + public DateTimeOffset ToLocalTime(DateTime t) + { + switch (t.Kind) + { + case DateTimeKind.Local: + return new DateTimeOffset(TimeZoneInfo.ConvertTime(t.ToUniversalTime(), Engine.Options._LocalTimeZone), Engine.Options._LocalTimeZone.GetUtcOffset(t)); + case DateTimeKind.Utc: + return new DateTimeOffset(TimeZoneInfo.ConvertTime(t, Engine.Options._LocalTimeZone), Engine.Options._LocalTimeZone.GetUtcOffset(t)); + default: + return t; + } } - public static double LocalTime(double t) + public double LocalTime(double t) { return t + LocalTza + DaylightSavingTa(t); } - public static double Utc(double t) + public double Utc(double t) { return t - LocalTza - DaylightSavingTa(t - LocalTza); } public static double HourFromTime(double t) { - return System.Math.Floor(t / MsPerHour) % HoursPerDay; + var hours = System.Math.Floor(t / MsPerHour) % HoursPerDay; + + if (hours < 0) + { + hours += HoursPerDay; + } + + return hours; } public static double MinFromTime(double t) { - return System.Math.Floor(t / MsPerMinute) % MinutesPerHour; + var minutes = System.Math.Floor(t / MsPerMinute) % MinutesPerHour; + + if (minutes < 0) + { + minutes += MinutesPerHour; + } + + return minutes; } public static double SecFromTime(double t) { - return System.Math.Floor(t / MsPerSecond) % SecondsPerMinute; + var seconds = System.Math.Floor(t / MsPerSecond) % SecondsPerMinute; + + if (seconds < 0) + { + seconds += SecondsPerMinute; + } + + return seconds; } public static double MsFromTime(double t) { - return t % MsPerSecond; + var milli = t % MsPerSecond; + + if (milli < 0) + { + milli += MsPerSecond; + } + + return milli; } public static double DayFromMonth(double year, double month) @@ -926,7 +1008,7 @@ public static double DaysInMonth(double month, double leap) switch ((long) month) { - case 0: + case 0: case 2: case 4: case 6: @@ -942,7 +1024,7 @@ public static double DaysInMonth(double month, double leap) case 1: return 28 + leap; default: - throw new ArgumentOutOfRangeException("month"); + throw new ArgumentOutOfRangeException("month"); } } @@ -997,7 +1079,7 @@ public static double MakeDay(double year, double month, double date) { t += DaysInMonth(m, InLeapYear(t)) * MsPerDay; } - + return Day(t) + date - 1; } diff --git a/Jint/Native/Function/EvalFunctionInstance.cs b/Jint/Native/Function/EvalFunctionInstance.cs index 962d6a021b..1ec3127128 100644 --- a/Jint/Native/Function/EvalFunctionInstance.cs +++ b/Jint/Native/Function/EvalFunctionInstance.cs @@ -58,7 +58,8 @@ public JsValue Call(JsValue thisObject, JsValue[] arguments, bool directCall) if (result.Type == Completion.Throw) { - throw new JavaScriptException(result.GetValueOrDefault()); + throw new JavaScriptException(result.GetValueOrDefault()) + .SetCallstack(_engine, result.Location); } else { diff --git a/Jint/Native/Function/FunctionConstructor.cs b/Jint/Native/Function/FunctionConstructor.cs index 847e8510b0..1439124e6e 100644 --- a/Jint/Native/Function/FunctionConstructor.cs +++ b/Jint/Native/Function/FunctionConstructor.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using Jint.Native.Object; +using Jint.Native.String; using Jint.Parser; using Jint.Parser.Ast; using Jint.Runtime; @@ -52,7 +53,7 @@ private string[] ParseArgumentNames(string parameterDeclaration) var newValues = new string[values.Length]; for (var i = 0; i < values.Length; i++) { - newValues[i] = values[i].Trim(); + newValues[i] = StringPrototype.TrimEx(values[i]); } return newValues; } diff --git a/Jint/Native/Function/ScriptFunctionInstance.cs b/Jint/Native/Function/ScriptFunctionInstance.cs index 6659d35bda..4890934049 100644 --- a/Jint/Native/Function/ScriptFunctionInstance.cs +++ b/Jint/Native/Function/ScriptFunctionInstance.cs @@ -94,7 +94,9 @@ public override JsValue Call(JsValue thisArg, JsValue[] arguments) if (result.Type == Completion.Throw) { - throw new JavaScriptException(result.GetValueOrDefault()); + JavaScriptException ex = new JavaScriptException(result.GetValueOrDefault()) + .SetCallstack(Engine, result.Location); + throw ex; } if (result.Type == Completion.Return) @@ -134,4 +136,4 @@ public ObjectInstance Construct(JsValue[] arguments) public ObjectInstance PrototypeObject { get; private set; } } -} \ No newline at end of file +} diff --git a/Jint/Native/Global/GlobalObject.cs b/Jint/Native/Global/GlobalObject.cs index 46675cfd23..90e3c2c638 100644 --- a/Jint/Native/Global/GlobalObject.cs +++ b/Jint/Native/Global/GlobalObject.cs @@ -1,7 +1,9 @@ using System; +using System.Globalization; using System.Linq; using System.Text; using Jint.Native.Object; +using Jint.Native.String; using Jint.Runtime; using Jint.Runtime.Interop; @@ -15,7 +17,7 @@ private GlobalObject(Engine engine) : base(engine) public static GlobalObject CreateGlobalObject(Engine engine) { - var global = new GlobalObject(engine) {Prototype = null, Extensible = true}; + var global = new GlobalObject(engine) { Prototype = null, Extensible = true }; return global; } @@ -58,6 +60,8 @@ public void Configure() FastAddProperty("decodeURIComponent", new ClrFunctionInstance(Engine, DecodeUriComponent, 1), true, false, true); FastAddProperty("encodeURI", new ClrFunctionInstance(Engine, EncodeUri, 1), true, false, true); FastAddProperty("encodeURIComponent", new ClrFunctionInstance(Engine, EncodeUriComponent, 1), true, false, true); + FastAddProperty("escape", new ClrFunctionInstance(Engine, Escape, 1), true, false, true); + FastAddProperty("unescape", new ClrFunctionInstance(Engine, Unescape, 1), true, false, true); } /// @@ -66,7 +70,7 @@ public void Configure() public static JsValue ParseInt(JsValue thisObject, JsValue[] arguments) { string inputString = TypeConverter.ToString(arguments.At(0)); - var s = inputString.Trim(); + var s = StringPrototype.TrimEx(inputString); var sign = 1; if (!System.String.IsNullOrEmpty(s)) @@ -75,7 +79,7 @@ public static JsValue ParseInt(JsValue thisObject, JsValue[] arguments) { sign = -1; } - + if (s[0] == '-' || s[0] == '+') { s = s.Substring(1); @@ -101,7 +105,7 @@ public static JsValue ParseInt(JsValue thisObject, JsValue[] arguments) { return double.NaN; } - else if(radix != 16) + else if (radix != 16) { stripPrefix = false; } @@ -131,7 +135,7 @@ private static JsValue Parse(string number, int radix) double result = 0; double pow = 1; - for (int i = number.Length - 1; i >= 0 ; i--) + for (int i = number.Length - 1; i >= 0; i--) { double index = double.NaN; char digit = number[i]; @@ -154,7 +158,7 @@ private static JsValue Parse(string number, int radix) return Parse(number.Substring(0, i), radix); } - result += index*pow; + result += index * pow; pow = pow * radix; } @@ -167,10 +171,10 @@ private static JsValue Parse(string number, int radix) public static JsValue ParseFloat(JsValue thisObject, JsValue[] arguments) { var inputString = TypeConverter.ToString(arguments.At(0)); - var trimmedString = inputString.TrimStart(); + var trimmedString = StringPrototype.TrimStartEx(inputString); var sign = 1; - if (trimmedString.Length > 0 ) + if (trimmedString.Length > 0) { if (trimmedString[0] == '-') { @@ -185,7 +189,7 @@ public static JsValue ParseFloat(JsValue thisObject, JsValue[] arguments) if (trimmedString.StartsWith("Infinity")) { - return sign*double.PositiveInfinity; + return sign * double.PositiveInfinity; } if (trimmedString.StartsWith("NaN")) @@ -193,7 +197,7 @@ public static JsValue ParseFloat(JsValue thisObject, JsValue[] arguments) return double.NaN; } - var separator = (char) 0; + var separator = (char)0; bool isNan = true; decimal number = 0; @@ -207,8 +211,8 @@ public static JsValue ParseFloat(JsValue thisObject, JsValue[] arguments) separator = '.'; break; } - - if(c == 'e' || c == 'E') + + if (c == 'e' || c == 'E') { i++; separator = 'e'; @@ -308,8 +312,8 @@ public static JsValue ParseFloat(JsValue thisObject, JsValue[] arguments) number /= 10; } } - - return (double) (sign * number); + + return (double)(sign * number); } /// @@ -317,7 +321,7 @@ public static JsValue ParseFloat(JsValue thisObject, JsValue[] arguments) /// public static JsValue IsNaN(JsValue thisObject, JsValue[] arguments) { - var x = TypeConverter.ToNumber(arguments[0]); + var x = TypeConverter.ToNumber(arguments.At(0)); return double.IsNaN(x); } @@ -331,7 +335,7 @@ public static JsValue IsFinite(JsValue thisObject, JsValue[] arguments) return false; } - var n = TypeConverter.ToNumber(arguments[0]); + var n = TypeConverter.ToNumber(arguments.At(0)); if (double.IsNaN(n) || double.IsInfinity(n)) { return false; @@ -340,7 +344,7 @@ public static JsValue IsFinite(JsValue thisObject, JsValue[] arguments) return true; } - private static readonly char[] UriReserved = {';', '/', '?', ':', '@', '&', '=', '+', '$', ','}; + private static readonly char[] UriReserved = { ';', '/', '?', ':', '@', '&', '=', '+', '$', ',' }; private static readonly char[] UriUnescaped = { @@ -368,7 +372,7 @@ private static bool IsValidHexaChar(char c) public JsValue EncodeUri(JsValue thisObject, JsValue[] arguments) { var uriString = TypeConverter.ToString(arguments.At(0)); - var unescapedUriSet = UriReserved.Concat(UriUnescaped).Concat(new [] {'#'}).ToArray(); + var unescapedUriSet = UriReserved.Concat(UriUnescaped).Concat(new[] { '#' }).ToArray(); return Encode(uriString, unescapedUriSet); } @@ -391,7 +395,7 @@ private string Encode(string uriString, char[] unescapedUriSet) { var strLen = uriString.Length; var r = new StringBuilder(uriString.Length); - for (var k = 0; k< strLen; k++) + for (var k = 0; k < strLen; k++) { var c = uriString[k]; if (System.Array.IndexOf(unescapedUriSet, c) != -1) @@ -418,7 +422,7 @@ private string Encode(string uriString, char[] unescapedUriSet) throw new JavaScriptException(Engine.UriError); } - var kChar = (int) uriString[k]; + var kChar = (int)uriString[k]; if (kChar < 0xDC00 || kChar > 0xDFFF) { throw new JavaScriptException(Engine.UriError); @@ -439,7 +443,7 @@ private string Encode(string uriString, char[] unescapedUriSet) // 00000yyy yyzzzzzz -> 110yyyyy ; 10zzzzzz octets = new[] { - (byte)(0xC0 | (v >> 6)), + (byte)(0xC0 | (v >> 6)), (byte)(0x80 | (v & 0x3F)) }; } @@ -448,8 +452,8 @@ private string Encode(string uriString, char[] unescapedUriSet) // xxxxyyyy yyzzzzzz -> 1110xxxx; 10yyyyyy; 10zzzzzz octets = new[] { - (byte)(0xE0 | (v >> 12)), - (byte)(0x80 | ((v >> 6) & 0x3F)), + (byte)(0xE0 | (v >> 12)), + (byte)(0x80 | ((v >> 6) & 0x3F)), (byte)(0x80 | (v & 0x3F)) }; } @@ -527,7 +531,7 @@ public string Decode(string uriString, char[] reservedSet) if (!IsValidHexaChar(uriString[k + 1]) || !IsValidHexaChar(uriString[k + 2])) { - throw new JavaScriptException(Engine.UriError); + throw new JavaScriptException(Engine.UriError); } var B = Convert.ToByte(uriString[k + 1].ToString() + uriString[k + 2], 16); @@ -535,7 +539,7 @@ public string Decode(string uriString, char[] reservedSet) k += 2; if ((B & 0x80) == 0) { - C = (char) B; + C = (char)B; if (System.Array.IndexOf(reservedSet, C) == -1) { R.Append(C); @@ -554,16 +558,16 @@ public string Decode(string uriString, char[] reservedSet) { throw new JavaScriptException(Engine.UriError); } - + var Octets = new byte[n]; Octets[0] = B; - - if (k + (3*(n - 1)) >= strLen) + + if (k + (3 * (n - 1)) >= strLen) { throw new JavaScriptException(Engine.UriError); } - - for(var j=1; j + /// http://www.ecma-international.org/ecma-262/5.1/#sec-B.2.1 + /// + public JsValue Escape(JsValue thisObject, JsValue[] arguments) + { + const string whiteList = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_ + -./"; + var uriString = TypeConverter.ToString(arguments.At(0)); + + var strLen = uriString.Length; + var r = new StringBuilder(strLen); + for (var k = 0; k < strLen; k++) + { + var c = uriString[k]; + if (whiteList.IndexOf(c) != -1) + { + r.Append(c); + } + else if (c < 256) + { + r.Append(string.Format("%{0}", ((int)c).ToString("X2"))); + } + else + { + r.Append(string.Format("%u{0}", ((int)c).ToString("X4"))); + } + } + + return r.ToString(); + } + + /// + /// http://www.ecma-international.org/ecma-262/5.1/#sec-B.2.2 + /// + public JsValue Unescape(JsValue thisObject, JsValue[] arguments) + { + var uriString = TypeConverter.ToString(arguments.At(0)); + + var strLen = uriString.Length; + var r = new StringBuilder(strLen); + for (var k = 0; k < strLen; k++) + { + var c = uriString[k]; + if (c == '%') + { + if (k < strLen - 6 + && uriString[k + 1] == 'u' + && uriString.Skip(k + 2).Take(4).All(IsValidHexaChar)) + { + c = (char)int.Parse( + string.Join(string.Empty, uriString.Skip(k + 2).Take(4)), + NumberStyles.AllowHexSpecifier); + + k += 5; + } + else if (k < strLen - 3 + && uriString.Skip(k + 1).Take(2).All(IsValidHexaChar)) + { + c = (char)int.Parse( + string.Join(string.Empty, uriString.Skip(k + 1).Take(2)), + NumberStyles.AllowHexSpecifier); + + k += 2; + } + } + r.Append(c); + } + + return r.ToString(); + } } -} +} \ No newline at end of file diff --git a/Jint/Native/JsValue.cs b/Jint/Native/JsValue.cs index 96f5dbaea8..9ef1ef64d7 100644 --- a/Jint/Native/JsValue.cs +++ b/Jint/Native/JsValue.cs @@ -1,9 +1,10 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.Contracts; using System.Dynamic; +using System.Reflection; +using System.Threading; using Jint.Native.Array; using Jint.Native.Boolean; using Jint.Native.Date; @@ -18,65 +19,53 @@ namespace Jint.Native { [DebuggerTypeProxy(typeof(JsValueDebugView))] - public struct JsValue : IEquatable + public class JsValue : IEquatable { - public static JsValue Undefined = new JsValue(Types.Undefined); - public static JsValue Null = new JsValue(Types.Null); - public static JsValue False = new JsValue(false); - public static JsValue True = new JsValue(true); + public readonly static JsValue Undefined = new JsValue(Types.Undefined); + public readonly static JsValue Null = new JsValue(Types.Null); + public readonly static JsValue False = new JsValue(false); + public readonly static JsValue True = new JsValue(true); public JsValue(bool value) { - _bool = value; - _double = null; + _double = value ? 1.0 : 0.0; _object = null; - _string = null; _type = Types.Boolean; } public JsValue(double value) { - _bool = null; - _double = value; _object = null; - _string = null; _type = Types.Number; + + _double = value; } public JsValue(string value) { - _bool = null; - _double = null; - _object = null; - _string = value; + _double = double.NaN; + _object = value; _type = Types.String; } public JsValue(ObjectInstance value) { - _bool = null; - _double = null; - _object = value; - _string = null; + _double = double.NaN; _type = Types.Object; + + _object = value; } private JsValue(Types type) { - _bool = null; - _double = null; + _double = double.NaN; _object = null; - _string = null; _type = type; } - private readonly bool? _bool; - - private readonly double? _double; + private readonly double _double; - private readonly ObjectInstance _object; - - private readonly string _string; + private readonly object _object; private readonly Types _type; @@ -98,18 +87,24 @@ public bool IsArray() return IsObject() && AsObject() is ArrayInstance; } + [Pure] + public bool IsDate() + { + return IsObject() && AsObject() is DateInstance; + } + [Pure] public bool IsRegExp() { return IsObject() && AsObject() is RegExpInstance; } - + [Pure] public bool IsObject() { return _type == Types.Object; } - + [Pure] public bool IsString() { @@ -142,7 +137,7 @@ public ObjectInstance AsObject() throw new ArgumentException("The value is not an object"); } - return _object; + return _object as ObjectInstance; } [Pure] @@ -152,11 +147,34 @@ public ArrayInstance AsArray() { throw new ArgumentException("The value is not an array"); } - return AsObject() as ArrayInstance; + + return _object as ArrayInstance; + } + + [Pure] + public DateInstance AsDate() + { + if (!IsDate()) + { + throw new ArgumentException("The value is not a date"); + } + + return _object as DateInstance; } [Pure] - public T TryCast(Action fail = null) where T: class + public RegExpInstance AsRegExp() + { + if (!IsRegExp()) + { + throw new ArgumentException("The value is not a date"); + } + + return _object as RegExpInstance; + } + + [Pure] + public T TryCast(Action fail = null) where T : class { if (IsObject()) { @@ -185,7 +203,7 @@ public T As() where T : ObjectInstance { return _object as T; } - + [Pure] public bool AsBoolean() { @@ -194,12 +212,7 @@ public bool AsBoolean() throw new ArgumentException("The value is not a boolean"); } - if (!_bool.HasValue) - { - throw new ArgumentException("The value is not defined"); - } - - return _bool.Value; + return _double != 0; } [Pure] @@ -210,12 +223,12 @@ public string AsString() throw new ArgumentException("The value is not a string"); } - if (_string == null) + if (_object == null) { throw new ArgumentException("The value is not defined"); } - return _string; + return _object as string; } [Pure] @@ -226,16 +239,21 @@ public double AsNumber() throw new ArgumentException("The value is not a number"); } - if (!_double.HasValue) - { - throw new ArgumentException("The value is not defined"); - } - - return _double.Value; + return _double; } public bool Equals(JsValue other) { + if (other == null) + { + return false; + } + + if(ReferenceEquals(this, other)) + { + return true; + } + if (_type != other._type) { return false; @@ -250,11 +268,9 @@ public bool Equals(JsValue other) case Types.Null: return true; case Types.Boolean: - return _bool == other._bool; - case Types.String: - return _string == other._string; case Types.Number: return _double == other._double; + case Types.String: case Types.Object: return _object == other._object; default: @@ -280,7 +296,7 @@ public static JsValue FromObject(Engine engine, object value) return Null; } - foreach(var converter in engine.Options.GetObjectConverters()) + foreach (var converter in engine.Options._ObjectConverters) { JsValue result; if (converter.TryConvert(value, out result)) @@ -289,83 +305,58 @@ public static JsValue FromObject(Engine engine, object value) } } - var typeCode = System.Type.GetTypeCode(value.GetType()); - switch (typeCode) - { - case TypeCode.Boolean: - return new JsValue((bool)value); - case TypeCode.Byte: - return new JsValue((byte)value); - case TypeCode.Char: - return new JsValue(value.ToString()); - case TypeCode.DateTime: - return engine.Date.Construct((DateTime)value); - case TypeCode.Decimal: - return new JsValue((double)(decimal)value); - case TypeCode.Double: - return new JsValue((double)value); - case TypeCode.Int16: - return new JsValue((Int16)value); - case TypeCode.Int32: - return new JsValue((Int32)value); - case TypeCode.Int64: - return new JsValue((Int64)value); - case TypeCode.SByte: - return new JsValue((SByte)value); - case TypeCode.Single: - return new JsValue((Single)value); - case TypeCode.String: - return new JsValue((string)value); - case TypeCode.UInt16: - return new JsValue((UInt16)value); - case TypeCode.UInt32: - return new JsValue((UInt32)value); - case TypeCode.UInt64: - return new JsValue((UInt64)value); - case TypeCode.Object: - break; - case TypeCode.Empty: - break; - default: - throw new ArgumentOutOfRangeException(); - } + var valueType = value.GetType(); - if (value is DateTimeOffset) + var typeMappers = Engine.TypeMappers; + + Func typeMapper; + if (typeMappers.TryGetValue(valueType, out typeMapper)) { - return engine.Date.Construct((DateTimeOffset)value); + return typeMapper(engine, value); } // if an ObjectInstance is passed directly, use it as is var instance = value as ObjectInstance; if (instance != null) { + // Learn conversion. + // Learn conversion, racy, worst case we'll try again later + Interlocked.CompareExchange(ref Engine.TypeMappers, new Dictionary>(typeMappers) + { + [valueType] = (Engine e, object v) => new JsValue((ObjectInstance)v) + }, typeMappers); return new JsValue(instance); } - // if a JsValue is passed directly, use it as is - if (value is JsValue) + var type = value as Type; + if(type != null) { - return (JsValue) value; + var typeReference = TypeReference.CreateTypeReference(engine, type); + return new JsValue(typeReference); } - var array = value as System.Array; - if (array != null) + var a = value as System.Array; + if (a != null) { - var jsArray = engine.Array.Construct(Arguments.Empty); - foreach (var item in array) + Func convert = (Engine e, object v) => { - var jsItem = FromObject(engine, item); - engine.Array.PrototypeObject.Push(jsArray, Arguments.From(jsItem)); - } + var array = (System.Array)v; - return jsArray; - } + var jsArray = engine.Array.Construct(Arguments.Empty); + foreach (var item in array) + { + var jsItem = JsValue.FromObject(engine, item); + engine.Array.PrototypeObject.Push(jsArray, Arguments.From(jsItem)); + } - var regex = value as System.Text.RegularExpressions.Regex; - if (regex != null) - { - var jsRegex = engine.RegExp.Construct(regex.ToString().Trim('/')); - return jsRegex; + return jsArray; + }; + // racy, we don't care, worst case we'll catch up later + Interlocked.CompareExchange(ref Engine.TypeMappers, new Dictionary>(typeMappers) + { + [valueType] = convert + }, typeMappers); + return convert(engine, a); } var d = value as Delegate; @@ -374,7 +365,7 @@ public static JsValue FromObject(Engine engine, object value) return new DelegateWrapper(engine, d); } - if (value.GetType().IsEnum) + if (value.GetType().IsEnum()) { return new JsValue((Int32)value); } @@ -395,10 +386,10 @@ public object ToObject() case Types.Undefined: case Types.Null: return null; - case Types.Boolean: - return _bool; case Types.String: - return _string; + return _object; + case Types.Boolean: + return _double != 0; case Types.Number: return _double; case Types.Object: @@ -408,7 +399,7 @@ public object ToObject() return wrapper.Target; } - switch (_object.Class) + switch ((_object as ObjectInstance).Class) { case "Array": var arrayInstance = _object as ArrayInstance; @@ -433,7 +424,7 @@ public object ToObject() return result; } break; - + case "String": var stringInstance = _object as StringInstance; if (stringInstance != null) @@ -465,10 +456,10 @@ public object ToObject() var function = _object as FunctionInstance; if (function != null) { - return (Func) function.Call; + return (Func)function.Call; } - break; + break; case "Number": var numberInstance = _object as NumberInstance; @@ -488,21 +479,22 @@ public object ToObject() break; + case "Arguments": case "Object": - #if __IOS__ - IDictionary o = new Dictionary(); - #else - IDictionary o = new ExpandoObject(); - #endif - - foreach (var p in _object.Properties) +#if __IOS__ + IDictionary o = new Dictionary(); +#else + IDictionary o = new ExpandoObject(); +#endif + + foreach (var p in (_object as ObjectInstance).GetOwnProperties()) { if (!p.Value.Enumerable.HasValue || p.Value.Enumerable.Value == false) { continue; } - o.Add(p.Key, _object.Get(p.Key).ToObject()); + o.Add(p.Key, (_object as ObjectInstance).Get(p.Key).ToObject()); } return o; @@ -554,11 +546,10 @@ public override string ToString() case Types.Null: return "null"; case Types.Boolean: - return _bool.ToString(); - case Types.String: - return _string; + return _double != 0 ? bool.TrueString : bool.FalseString; case Types.Number: return _double.ToString(); + case Types.String: case Types.Object: return _object.ToString(); default: @@ -568,11 +559,31 @@ public override string ToString() public static bool operator ==(JsValue a, JsValue b) { + if ((object)a == null) + { + if ((object)b == null) + { + return true; + } + + return false; + } + return a.Equals(b); } public static bool operator !=(JsValue a, JsValue b) { + if ((object)a == null) + { + if ((object)b == null) + { + return false; + } + + return true; + } + return !a.Equals(b); } @@ -641,13 +652,12 @@ public override int GetHashCode() { unchecked { - var hashCode = _bool.GetHashCode(); + var hashCode = 0; hashCode = (hashCode * 397) ^ _double.GetHashCode(); hashCode = (hashCode * 397) ^ (_object != null ? _object.GetHashCode() : 0); - hashCode = (hashCode * 397) ^ (_string != null ? _string.GetHashCode() : 0); hashCode = (hashCode * 397) ^ (int)_type; return hashCode; } } } -} +} \ No newline at end of file diff --git a/Jint/Native/Json/JsonInstance.cs b/Jint/Native/Json/JsonInstance.cs index 7bf7d8e128..63f5f2296d 100644 --- a/Jint/Native/Json/JsonInstance.cs +++ b/Jint/Native/Json/JsonInstance.cs @@ -1,4 +1,5 @@ using Jint.Native.Object; +using Jint.Runtime; using Jint.Runtime.Interop; namespace Jint.Native.Json @@ -39,7 +40,7 @@ public JsValue Parse(JsValue thisObject, JsValue[] arguments) { var parser = new JsonParser(_engine); - return parser.Parse(arguments[0].AsString()); + return parser.Parse(TypeConverter.ToString(arguments[0])); } public JsValue Stringify(JsValue thisObject, JsValue[] arguments) diff --git a/Jint/Native/Json/JsonParser.cs b/Jint/Native/Json/JsonParser.cs index 24448d9510..902ebd9e70 100644 --- a/Jint/Native/Json/JsonParser.cs +++ b/Jint/Native/Json/JsonParser.cs @@ -161,9 +161,17 @@ private Token ScanNumericLiteral() int start = _index; string number = ""; + + // Number start with a - + if (ch == '-') + { + number += _source.CharCodeAt(_index++).ToString(); + ch = _source.CharCodeAt(_index); + } + if (ch != '.') { - number = _source.CharCodeAt(_index++).ToString(); + number += _source.CharCodeAt(_index++).ToString(); ch = _source.CharCodeAt(_index); // Hex number starts with '0x'. @@ -219,7 +227,7 @@ private Token ScanNumericLiteral() return new Token { Type = Tokens.Number, - Value = Double.Parse(number, NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, CultureInfo.InvariantCulture), + Value = Double.Parse(number, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, CultureInfo.InvariantCulture), LineNumber = _lineNumber, LineStart = _lineStart, Range = new[] {start, _index} @@ -282,7 +290,7 @@ private Token ScanNullLiteral() private Token ScanStringLiteral() { - string str = ""; + var sb = new System.Text.StringBuilder(); char quote = _source.CharCodeAt(_index); @@ -313,13 +321,13 @@ private Token ScanStringLiteral() switch (ch) { case 'n': - str += '\n'; + sb.Append('\n'); break; case 'r': - str += '\r'; + sb.Append('\r'); break; case 't': - str += '\t'; + sb.Append('\t'); break; case 'u': case 'x': @@ -327,22 +335,22 @@ private Token ScanStringLiteral() char unescaped = ScanHexEscape(ch); if (unescaped > 0) { - str += unescaped.ToString(); + sb.Append(unescaped.ToString()); } else { _index = restore; - str += ch.ToString(); + sb.Append(ch.ToString()); } break; case 'b': - str += "\b"; + sb.Append("\b"); break; case 'f': - str += "\f"; + sb.Append("\f"); break; case 'v': - str += "\x0B"; + sb.Append("\x0B"); break; default: @@ -363,11 +371,11 @@ private Token ScanStringLiteral() code = code * 8 + "01234567".IndexOf(_source.CharCodeAt(_index++)); } } - str += ((char)code).ToString(); + sb.Append(((char)code).ToString()); } else { - str += ch.ToString(); + sb.Append(ch.ToString()); } break; } @@ -387,7 +395,7 @@ private Token ScanStringLiteral() } else { - str += ch.ToString(); + sb.Append(ch.ToString()); } } @@ -399,7 +407,7 @@ private Token ScanStringLiteral() return new Token { Type = Tokens.String, - Value = str, + Value = sb.ToString(), LineNumber = _lineNumber, LineStart = _lineStart, Range = new[] {start, _index} @@ -447,6 +455,15 @@ private Token Advance() return ScanPunctuator(); } + if (ch == '-') // Negative Number + { + if (IsDecimalDigit(_source.CharCodeAt(_index + 1))) + { + return ScanNumericLiteral(); + } + return ScanPunctuator(); + } + if (IsDecimalDigit(ch)) { return ScanNumericLiteral(); @@ -596,7 +613,9 @@ public SyntaxNode PostProcess(SyntaxNode node) public ObjectInstance CreateArrayInstance(IEnumerable values) { - return _engine.Array.Construct(values.ToArray()); + var jsArray = _engine.Array.Construct(Arguments.Empty); + _engine.Array.PrototypeObject.Push(jsArray, values.ToArray()); + return jsArray; } // Throw an exception diff --git a/Jint/Native/Json/JsonSerializer.cs b/Jint/Native/Json/JsonSerializer.cs index 06f9c34f01..75a86712cc 100644 --- a/Jint/Native/Json/JsonSerializer.cs +++ b/Jint/Native/Json/JsonSerializer.cs @@ -48,7 +48,7 @@ public JsValue Serialize(JsValue value, JsValue replacer, JsValue space) _propertyList = new List(); } - foreach (var property in replacerObj.Properties.Values) + foreach (var property in replacerObj.GetOwnProperties().Select(x => x.Value)) { JsValue v = _engine.GetValue(property); string item = null; @@ -212,47 +212,47 @@ private JsValue Str(string key, ObjectInstance holder) private string Quote(string value) { - var product = "\""; + var sb = new System.Text.StringBuilder("\""); foreach (char c in value) { switch (c) { case '\"': - product += "\\\""; + sb.Append("\\\""); break; case '\\': - product += "\\\\"; + sb.Append("\\\\"); break; case '\b': - product += "\\b"; + sb.Append("\\b"); break; case '\f': - product += "\\f"; + sb.Append("\\f"); break; case '\n': - product += "\\n"; + sb.Append("\\n"); break; case '\r': - product += "\\r"; + sb.Append("\\r"); break; case '\t': - product += "\\t"; + sb.Append("\\t"); break; default: if (c < 0x20) { - product += "\\u"; - product += ((int) c).ToString("x4"); + sb.Append("\\u"); + sb.Append(((int) c).ToString("x4")); } else - product += c; + sb.Append(c); break; } } - product += "\""; - return product; + sb.Append("\""); + return sb.ToString(); } private string SerializeArray(ArrayInstance value) @@ -316,7 +316,7 @@ private string SerializeObject(ObjectInstance value) var stepback = _indent; _indent += _gap; - var k = _propertyList ?? value.Properties + var k = _propertyList ?? value.GetOwnProperties() .Where(x => x.Value.Enumerable.HasValue && x.Value.Enumerable.Value == true) .Select(x => x.Key) .ToList(); diff --git a/Jint/Native/Math/MathInstance.cs b/Jint/Native/Math/MathInstance.cs index a74ca7cfac..5b52d8dad2 100644 --- a/Jint/Native/Math/MathInstance.cs +++ b/Jint/Native/Math/MathInstance.cs @@ -8,6 +8,8 @@ namespace Jint.Native.Math { public sealed class MathInstance : ObjectInstance { + private static Random _random = new Random(); + private MathInstance(Engine engine):base(engine) { } @@ -438,7 +440,7 @@ private static JsValue Pow(JsValue thisObject, JsValue[] arguments) private static JsValue Random(JsValue thisObject, JsValue[] arguments) { - return new Random().NextDouble(); + return _random.NextDouble(); } private static JsValue Round(JsValue thisObject, JsValue[] arguments) diff --git a/Jint/Native/Null.cs b/Jint/Native/Null.cs index 376838938c..ac9cdb063a 100644 --- a/Jint/Native/Null.cs +++ b/Jint/Native/Null.cs @@ -2,7 +2,7 @@ { public static class Null { - public static JsValue Instance = JsValue.Null; - public static string Text = "null"; + public readonly static JsValue Instance = JsValue.Null; + public readonly static string Text = "null"; } } \ No newline at end of file diff --git a/Jint/Native/Number/NumberConstructor.cs b/Jint/Native/Number/NumberConstructor.cs index cd4101d4ac..00cb5fde41 100644 --- a/Jint/Native/Number/NumberConstructor.cs +++ b/Jint/Native/Number/NumberConstructor.cs @@ -1,8 +1,6 @@ -using Jint.Native.Array; -using Jint.Native.Function; +using Jint.Native.Function; using Jint.Native.Object; using Jint.Runtime; -using Jint.Runtime.Descriptors; namespace Jint.Native.Number { @@ -71,7 +69,5 @@ public NumberInstance Construct(double value) return instance; } - - } } diff --git a/Jint/Native/Number/NumberPrototype.cs b/Jint/Native/Number/NumberPrototype.cs index 0689a3bfca..4dd1dd9424 100644 --- a/Jint/Native/Number/NumberPrototype.cs +++ b/Jint/Native/Number/NumberPrototype.cs @@ -60,7 +60,7 @@ private JsValue ToLocaleString(JsValue thisObject, JsValue[] arguments) if (m < 0) { - return "-" + ToNumberString(-m); + return "-" + ToLocaleString(-m, arguments); } if (double.IsPositiveInfinity(m) || m >= double.MaxValue) @@ -73,7 +73,7 @@ private JsValue ToLocaleString(JsValue thisObject, JsValue[] arguments) return "-Infinity"; } - return m.ToString("n", Engine.Options.GetCulture()); + return m.ToString("n", Engine.Options._Culture); } private JsValue ValueOf(JsValue thisObj, JsValue[] arguments) @@ -108,16 +108,8 @@ private JsValue ToFixed(JsValue thisObj, JsValue[] arguments) { return ToNumberString(x); } - - var l = (long) x; // extract integer part - - if (f == 0) - { - return l.ToString(CultureInfo.InvariantCulture); - } - var d = x - l; - return l.ToString(CultureInfo.InvariantCulture) + d.ToString("." + new string('0', f), CultureInfo.InvariantCulture); + return x.ToString("f" + f, CultureInfo.InvariantCulture); } private JsValue ToExponential(JsValue thisObj, JsValue[] arguments) @@ -303,7 +295,7 @@ public static string ToNumberString(double m) // 123.4 s=1234, k=4, n=3 // 1234000 s = 1234, k=4, n=7 string s = null; - var rFormat = m.ToString("r"); + var rFormat = m.ToString("r", CultureInfo.InvariantCulture); if (rFormat.IndexOf("e", StringComparison.OrdinalIgnoreCase) == -1) { s = rFormat.Replace(".", "").TrimStart('0').TrimEnd('0'); diff --git a/Jint/Native/Object/ObjectConstructor.cs b/Jint/Native/Object/ObjectConstructor.cs index 3b5161192a..a7190efe0a 100644 --- a/Jint/Native/Object/ObjectConstructor.cs +++ b/Jint/Native/Object/ObjectConstructor.cs @@ -153,7 +153,7 @@ public JsValue GetOwnPropertyNames(JsValue thisObject, JsValue[] arguments) } } - foreach (var p in o.Properties) + foreach (var p in o.GetOwnProperties()) { array.DefineOwnProperty(n.ToString(), new PropertyDescriptor(p.Key, true, true, true), false); n++; @@ -215,9 +215,9 @@ public JsValue DefineProperties(JsValue thisObject, JsValue[] arguments) var properties = arguments.At(1); var props = TypeConverter.ToObject(Engine, properties); var descriptors = new List>(); - foreach (var p in props.Properties) + foreach (var p in props.GetOwnProperties()) { - if (!p.Value.Enumerable.HasValue || !p.Value.Enumerable.Value.AsBoolean()) + if (!p.Value.Enumerable.HasValue || !p.Value.Enumerable.Value) { continue; } @@ -243,11 +243,11 @@ public JsValue Seal(JsValue thisObject, JsValue[] arguments) throw new JavaScriptException(Engine.TypeError); } - foreach (var prop in o.Properties) + foreach (var prop in o.GetOwnProperties()) { - if (prop.Value.Configurable.HasValue && prop.Value.Configurable.Value.AsBoolean()) + if (prop.Value.Configurable.HasValue && prop.Value.Configurable.Value) { - prop.Value.Configurable = JsValue.False; + prop.Value.Configurable = false; } o.DefineOwnProperty(prop.Key, prop.Value, true); @@ -267,20 +267,20 @@ public JsValue Freeze(JsValue thisObject, JsValue[] arguments) throw new JavaScriptException(Engine.TypeError); } - var keys = o.Properties.Keys.ToArray(); + var keys = o.GetOwnProperties().Select(x => x.Key); foreach (var p in keys) { var desc = o.GetOwnProperty(p); if (desc.IsDataDescriptor()) { - if (desc.Writable.HasValue && desc.Writable.Value.AsBoolean()) + if (desc.Writable.HasValue && desc.Writable.Value) { - desc.Writable = JsValue.False; + desc.Writable = false; } } - if (desc.Configurable.HasValue && desc.Configurable.Value.AsBoolean()) + if (desc.Configurable.HasValue && desc.Configurable.Value) { - desc.Configurable = JsValue.False; + desc.Configurable = false; } o.DefineOwnProperty(p, desc, true); } @@ -313,7 +313,7 @@ public JsValue IsSealed(JsValue thisObject, JsValue[] arguments) throw new JavaScriptException(Engine.TypeError); } - foreach (var prop in o.Properties) + foreach (var prop in o.GetOwnProperties()) { if (prop.Value.Configurable.Value == true) { @@ -338,17 +338,17 @@ public JsValue IsFrozen(JsValue thisObject, JsValue[] arguments) throw new JavaScriptException(Engine.TypeError); } - foreach (var p in o.Properties.Keys) + foreach (var p in o.GetOwnProperties().Select(x => x.Key)) { var desc = o.GetOwnProperty(p); if (desc.IsDataDescriptor()) { - if (desc.Writable.HasValue && desc.Writable.Value.AsBoolean()) + if (desc.Writable.HasValue && desc.Writable.Value) { return false; } } - if (desc.Configurable.HasValue && desc.Configurable.Value.AsBoolean()) + if (desc.Configurable.HasValue && desc.Configurable.Value) { return false; } @@ -383,8 +383,8 @@ public JsValue Keys(JsValue thisObject, JsValue[] arguments) throw new JavaScriptException(Engine.TypeError); } - var enumerableProperties = o.Properties - .Where(x => x.Value.Enumerable.HasValue && x.Value.Enumerable.Value.AsBoolean()) + var enumerableProperties = o.GetOwnProperties() + .Where(x => x.Value.Enumerable.HasValue && x.Value.Enumerable.Value) .ToArray(); var n = enumerableProperties.Length; var array = Engine.Array.Construct(new JsValue[] {n}); diff --git a/Jint/Native/Object/ObjectInstance.cs b/Jint/Native/Object/ObjectInstance.cs index 7789cad66a..a21c8ab548 100644 --- a/Jint/Native/Object/ObjectInstance.cs +++ b/Jint/Native/Object/ObjectInstance.cs @@ -1,8 +1,7 @@ using System.Collections.Generic; -using Jint.Native.Date; -using Jint.Native.String; using Jint.Runtime; using Jint.Runtime.Descriptors; +using System; namespace Jint.Native.Object { @@ -11,26 +10,26 @@ public class ObjectInstance public ObjectInstance(Engine engine) { Engine = engine; - Properties = new Dictionary(); + Properties = new MruPropertyCache2(); } public Engine Engine { get; set; } - public IDictionary Properties { get; private set; } + protected IDictionary Properties { get; private set; } /// /// The prototype of this object. /// public ObjectInstance Prototype { get; set; } - + /// - /// If true, own properties may be added to the + /// If true, own properties may be added to the /// object. /// public bool Extensible { get; set; } /// - /// A String value indicating a specification defined + /// A String value indicating a specification defined /// classification of objects. /// public virtual string Class @@ -38,6 +37,24 @@ public virtual string Class get { return "Object"; } } + public virtual IEnumerable> GetOwnProperties() + { + EnsureInitialized(); + return Properties; + } + + public virtual bool HasOwnProperty(string p) + { + EnsureInitialized(); + return Properties.ContainsKey(p); + } + + public virtual void RemoveOwnProperty(string p) + { + EnsureInitialized(); + Properties.Remove(p); + } + /// /// Returns the value of the named property. /// http://www.ecma-international.org/ecma-262/5.1/#sec-8.12.3 @@ -55,10 +72,11 @@ public virtual JsValue Get(string propertyName) if (desc.IsDataDescriptor()) { - return desc.Value.HasValue ? desc.Value.Value : Undefined.Instance; + var val = desc.Value; + return val != null ? val : Undefined.Instance; } - var getter = desc.Get.HasValue ? desc.Get.Value : Undefined.Instance; + var getter = desc.Get != null ? desc.Get : Undefined.Instance; if (getter.IsUndefined()) { @@ -69,10 +87,10 @@ public virtual JsValue Get(string propertyName) var callable = getter.TryCast(); return callable.Call(this, Arguments.Empty); } - + /// - /// Returns the Property Descriptor of the named - /// own property of this object, or undefined if + /// Returns the Property Descriptor of the named + /// own property of this object, or undefined if /// absent. /// http://www.ecma-international.org/ecma-262/5.1/#sec-8.12.1 /// @@ -80,6 +98,8 @@ public virtual JsValue Get(string propertyName) /// public virtual PropertyDescriptor GetOwnProperty(string propertyName) { + EnsureInitialized(); + PropertyDescriptor x; if (Properties.TryGetValue(propertyName, out x)) { @@ -100,10 +120,16 @@ public virtual PropertyDescriptor GetOwnProperty(string propertyName) // optimmized implementation return x; } - + return PropertyDescriptor.Undefined; } + protected virtual void SetOwnProperty(string propertyName, PropertyDescriptor desc) + { + EnsureInitialized(); + Properties[propertyName] = desc; + } + /// /// http://www.ecma-international.org/ecma-262/5.1/#sec-8.12.2 /// @@ -117,7 +143,7 @@ public PropertyDescriptor GetProperty(string propertyName) { return prop; } - + if(Prototype == null) { return PropertyDescriptor.Undefined; @@ -127,8 +153,8 @@ public PropertyDescriptor GetProperty(string propertyName) } /// - /// Sets the specified named property to the value - /// of the second parameter. The flag controls + /// Sets the specified named property to the value + /// of the second parameter. The flag controls /// failure handling. /// /// @@ -150,9 +176,13 @@ public virtual void Put(string propertyName, JsValue value, bool throwOnError) if (ownDesc.IsDataDescriptor()) { - var valueDesc = new PropertyDescriptor(value: value, writable: null, enumerable:null, configurable:null); - DefineOwnProperty(propertyName, valueDesc, throwOnError); + ownDesc.Value = value; return; + + // as per specification + // var valueDesc = new PropertyDescriptor(value: value, writable: null, enumerable: null, configurable: null); + // DefineOwnProperty(propertyName, valueDesc, throwOnError); + // return; } // property is an accessor or inherited @@ -160,7 +190,7 @@ public virtual void Put(string propertyName, JsValue value, bool throwOnError) if (desc.IsAccessorDescriptor()) { - var setter = desc.Set.Value.TryCast(); + var setter = desc.Set.TryCast(); setter.Call(new JsValue(this), new [] {value}); } else @@ -171,8 +201,8 @@ public virtual void Put(string propertyName, JsValue value, bool throwOnError) } /// - /// Returns a Boolean value indicating whether a - /// [[Put]] operation with PropertyName can be + /// Returns a Boolean value indicating whether a + /// [[Put]] operation with PropertyName can be /// performed. /// http://www.ecma-international.org/ecma-262/5.1/#sec-8.12.4 /// @@ -186,7 +216,7 @@ public bool CanPut(string propertyName) { if (desc.IsAccessorDescriptor()) { - if (!desc.Set.HasValue || desc.Set.Value.IsUndefined()) + if (desc.Set == null || desc.Set.IsUndefined()) { return false; } @@ -194,7 +224,7 @@ public bool CanPut(string propertyName) return true; } - return desc.Writable.HasValue && desc.Writable.Value.AsBoolean(); + return desc.Writable.HasValue && desc.Writable.Value; } if (Prototype == null) @@ -211,7 +241,7 @@ public bool CanPut(string propertyName) if (inherited.IsAccessorDescriptor()) { - if (!inherited.Set.HasValue || inherited.Set.Value.IsUndefined()) + if (inherited.Set == null || inherited.Set.IsUndefined()) { return false; } @@ -225,13 +255,13 @@ public bool CanPut(string propertyName) } else { - return inherited.Writable.HasValue && inherited.Writable.Value.AsBoolean(); + return inherited.Writable.HasValue && inherited.Writable.Value; } } /// - /// Returns a Boolean value indicating whether the - /// object already has a property with the given + /// Returns a Boolean value indicating whether the + /// object already has a property with the given /// name. /// /// @@ -242,8 +272,8 @@ public bool HasProperty(string propertyName) } /// - /// Removes the specified named own property - /// from the object. The flag controls failure + /// Removes the specified named own property + /// from the object. The flag controls failure /// handling. /// /// @@ -252,15 +282,15 @@ public bool HasProperty(string propertyName) public virtual bool Delete(string propertyName, bool throwOnError) { var desc = GetOwnProperty(propertyName); - + if (desc == PropertyDescriptor.Undefined) { return true; } - if (desc.Configurable.HasValue && desc.Configurable.Value.AsBoolean()) + if (desc.Configurable.HasValue && desc.Configurable.Value) { - Properties.Remove(propertyName); + RemoveOwnProperty(propertyName); return true; } else @@ -275,13 +305,15 @@ public virtual bool Delete(string propertyName, bool throwOnError) } /// - /// Hint is a String. Returns a default value for the + /// Hint is a String. Returns a default value for the /// object. /// /// /// public JsValue DefaultValue(Types hint) { + EnsureInitialized(); + if (hint == Types.String || (hint == Types.None && Class == "Date")) { var toString = Get("toString").TryCast(); @@ -336,8 +368,8 @@ public JsValue DefaultValue(Types hint) } /// - /// Creates or alters the named own property to - /// have the state described by a Property + /// Creates or alters the named own property to + /// have the state described by a Property /// Descriptor. The flag controls failure handling. /// /// @@ -347,7 +379,11 @@ public JsValue DefaultValue(Types hint) public virtual bool DefineOwnProperty(string propertyName, PropertyDescriptor desc, bool throwOnError) { var current = GetOwnProperty(propertyName); - + + if (current == desc) { + return true; + } + if (current == PropertyDescriptor.Undefined) { if (!Extensible) @@ -363,19 +399,23 @@ public virtual bool DefineOwnProperty(string propertyName, PropertyDescriptor de { if (desc.IsGenericDescriptor() || desc.IsDataDescriptor()) { - Properties[propertyName] = new PropertyDescriptor(desc) + SetOwnProperty(propertyName, new PropertyDescriptor(desc) { - Value = desc.Value.HasValue ? desc.Value : JsValue.Undefined, - Writable = desc.Writable.HasValue ? desc.Writable : false - }; + Value = desc.Value != null ? desc.Value : JsValue.Undefined, + Writable = desc.Writable.HasValue ? desc.Writable.Value : false, + Enumerable = desc.Enumerable.HasValue ? desc.Enumerable.Value : false, + Configurable = desc.Configurable.HasValue ? desc.Configurable.Value : false + }); } else { - Properties[propertyName] = new PropertyDescriptor(desc) + SetOwnProperty(propertyName, new PropertyDescriptor(desc) { + Get = desc.Get, + Set = desc.Set, Enumerable = desc.Enumerable.HasValue ? desc.Enumerable : false, Configurable = desc.Configurable.HasValue ? desc.Configurable : false, - }; + }); } } @@ -383,83 +423,33 @@ public virtual bool DefineOwnProperty(string propertyName, PropertyDescriptor de } // Step 5 - if (!current.Configurable.HasValue && + if (!current.Configurable.HasValue && !current.Enumerable.HasValue && !current.Writable.HasValue && - !current.Get.HasValue && - !current.Set.HasValue && - !current.Value.HasValue) + current.Get == null && + current.Set == null && + current.Value == null) { + return true; } // Step 6 - var configurableIsSame = current.Configurable.HasValue - ? desc.Configurable.HasValue && (current.Configurable.Value == desc.Configurable.Value) - : !desc.Configurable.HasValue; - - var enumerableIsSame = current.Enumerable.HasValue - ? desc.Enumerable.HasValue && (current.Enumerable.Value == desc.Enumerable.Value) - : !desc.Enumerable.HasValue; - - var writableIsSame = true; - var valueIsSame = true; - - if (current.IsDataDescriptor() && desc.IsDataDescriptor()) - { - var currentDataDescriptor = current; - var descDataDescriptor = desc; - writableIsSame = currentDataDescriptor.Writable.HasValue - ? descDataDescriptor.Writable.HasValue && (currentDataDescriptor.Writable.Value == descDataDescriptor.Writable.Value) - : !descDataDescriptor.Writable.HasValue; - - var valueA = currentDataDescriptor.Value.HasValue - ? currentDataDescriptor.Value.Value - : Undefined.Instance; - - var valueB = descDataDescriptor.Value.HasValue - ? descDataDescriptor.Value.Value - : Undefined.Instance; - - valueIsSame = ExpressionInterpreter.SameValue(valueA, valueB); - } - else if (current.IsAccessorDescriptor() && desc.IsAccessorDescriptor()) - { - var currentAccessorDescriptor = current; - var descAccessorDescriptor = desc; - - var getValueA = currentAccessorDescriptor.Get.HasValue - ? currentAccessorDescriptor.Get.Value - : Undefined.Instance; - - var getValueB = descAccessorDescriptor.Get.HasValue - ? descAccessorDescriptor.Get.Value - : Undefined.Instance; - - var setValueA = currentAccessorDescriptor.Set.HasValue - ? currentAccessorDescriptor.Set.Value - : Undefined.Instance; - - var setValueB = descAccessorDescriptor.Set.HasValue - ? descAccessorDescriptor.Set.Value - : Undefined.Instance; - - valueIsSame = ExpressionInterpreter.SameValue(getValueA, getValueB) - && ExpressionInterpreter.SameValue(setValueA, setValueB); - } - else - { - valueIsSame = false; - } - - if (configurableIsSame && enumerableIsSame && writableIsSame && valueIsSame) - { + if ( + current.Configurable == desc.Configurable && + current.Writable == desc.Writable && + current.Enumerable == desc.Enumerable && + + ((current.Get == null && desc.Get == null) || (current.Get != null && desc.Get != null && ExpressionInterpreter.SameValue(current.Get, desc.Get))) && + ((current.Set == null && desc.Set == null) || (current.Set != null && desc.Set != null && ExpressionInterpreter.SameValue(current.Set, desc.Set))) && + ((current.Value == null && desc.Value == null) || (current.Value != null && desc.Value != null && ExpressionInterpreter.StrictlyEqual(current.Value, desc.Value))) + ) { return true; } - if (!current.Configurable.HasValue || !current.Configurable.Value.AsBoolean()) + if (!current.Configurable.HasValue || !current.Configurable.Value) { - if (desc.Configurable.HasValue && desc.Configurable.Value.AsBoolean()) + if (desc.Configurable.HasValue && desc.Configurable.Value) { if (throwOnError) { @@ -485,7 +475,7 @@ public virtual bool DefineOwnProperty(string propertyName, PropertyDescriptor de if (current.IsDataDescriptor() != desc.IsDataDescriptor()) { - if (!current.Configurable.HasValue || !current.Configurable.Value.AsBoolean()) + if (!current.Configurable.HasValue || !current.Configurable.Value) { if (throwOnError) { @@ -497,28 +487,28 @@ public virtual bool DefineOwnProperty(string propertyName, PropertyDescriptor de if (current.IsDataDescriptor()) { - Properties[propertyName] = current = new PropertyDescriptor( + SetOwnProperty(propertyName, current = new PropertyDescriptor( get: Undefined.Instance, set: Undefined.Instance, - enumerable: current.Enumerable.HasValue && current.Enumerable.Value.AsBoolean(), - configurable: current.Configurable.HasValue && current.Configurable.Value.AsBoolean() - ); + enumerable: current.Enumerable, + configurable: current.Configurable + )); } else { - Properties[propertyName] = current = new PropertyDescriptor( - value: Undefined.Instance, + SetOwnProperty(propertyName, current = new PropertyDescriptor( + value: Undefined.Instance, writable: null, - enumerable: current.Enumerable.HasValue && current.Enumerable.Value.AsBoolean(), - configurable: current.Configurable.HasValue && current.Configurable.Value.AsBoolean() - ); + enumerable: current.Enumerable, + configurable: current.Configurable + )); } } else if (current.IsDataDescriptor() && desc.IsDataDescriptor()) { - if (!current.Configurable.HasValue || current.Configurable.Value.AsBoolean() == false) + if (!current.Configurable.HasValue || current.Configurable.Value == false) { - if (!current.Writable.HasValue || !current.Writable.Value.AsBoolean() && desc.Writable.HasValue && desc.Writable.Value.AsBoolean()) + if (!current.Writable.HasValue || !current.Writable.Value && desc.Writable.HasValue && desc.Writable.Value) { if (throwOnError) { @@ -528,9 +518,9 @@ public virtual bool DefineOwnProperty(string propertyName, PropertyDescriptor de return false; } - if (!current.Writable.Value.AsBoolean()) + if (!current.Writable.Value) { - if (desc.Value.HasValue && !valueIsSame) + if (desc.Value != null && !ExpressionInterpreter.SameValue(desc.Value, current.Value)) { if (throwOnError) { @@ -544,11 +534,11 @@ public virtual bool DefineOwnProperty(string propertyName, PropertyDescriptor de } else if (current.IsAccessorDescriptor() && desc.IsAccessorDescriptor()) { - if (!current.Configurable.HasValue || !current.Configurable.Value.AsBoolean()) + if (!current.Configurable.HasValue || !current.Configurable.Value) { - if ((desc.Set.HasValue && !ExpressionInterpreter.SameValue(desc.Set.Value, current.Set.HasValue ? current.Set.Value : Undefined.Instance)) + if ((desc.Set != null && !ExpressionInterpreter.SameValue(desc.Set, current.Set != null ? current.Set : Undefined.Instance)) || - (desc.Get.HasValue && !ExpressionInterpreter.SameValue(desc.Get.Value, current.Get.HasValue ? current.Get.Value : Undefined.Instance))) + (desc.Get != null && !ExpressionInterpreter.SameValue(desc.Get, current.Get != null ? current.Get : Undefined.Instance))) { if (throwOnError) { @@ -561,7 +551,7 @@ public virtual bool DefineOwnProperty(string propertyName, PropertyDescriptor de } } - if (desc.Value.HasValue) + if (desc.Value != null) { current.Value = desc.Value; } @@ -581,12 +571,12 @@ public virtual bool DefineOwnProperty(string propertyName, PropertyDescriptor de current.Configurable = desc.Configurable; } - if (desc.Get.HasValue) + if (desc.Get != null) { current.Get = desc.Get; } - if (desc.Set.HasValue) + if (desc.Set != null) { current.Set = desc.Set; } @@ -604,17 +594,22 @@ public virtual bool DefineOwnProperty(string propertyName, PropertyDescriptor de /// public void FastAddProperty(string name, JsValue value, bool writable, bool enumerable, bool configurable) { - Properties.Add(name, new PropertyDescriptor(value, writable, enumerable, configurable)); + SetOwnProperty(name, new PropertyDescriptor(value, writable, enumerable, configurable)); } /// - /// Optimized version of [[Put]] when the property is known to be already declared + /// Optimized version of [[Put]] when the property is known to be already declared /// /// /// public void FastSetProperty(string name, PropertyDescriptor value) { - Properties[name] = value; + SetOwnProperty(name, value); + } + + protected virtual void EnsureInitialized() + { + } public override string ToString() diff --git a/Jint/Native/Object/ObjectPrototype.cs b/Jint/Native/Object/ObjectPrototype.cs index cf681c435c..892878eb51 100644 --- a/Jint/Native/Object/ObjectPrototype.cs +++ b/Jint/Native/Object/ObjectPrototype.cs @@ -38,7 +38,7 @@ private JsValue PropertyIsEnumerable(JsValue thisObject, JsValue[] arguments) { return false; } - return desc.Enumerable.HasValue && desc.Enumerable.Value.AsBoolean(); + return desc.Enumerable.HasValue && desc.Enumerable.Value; } private JsValue ValueOf(JsValue thisObject, JsValue[] arguments) diff --git a/Jint/Native/RegExp/RegExpConstructor.cs b/Jint/Native/RegExp/RegExpConstructor.cs index 7d28ed22f0..0fb4fbfd7e 100644 --- a/Jint/Native/RegExp/RegExpConstructor.cs +++ b/Jint/Native/RegExp/RegExpConstructor.cs @@ -138,7 +138,29 @@ public RegExpInstance Construct(string regExp) var options = ParseOptions(r, flags); try { - r.Value = new Regex(pattern, options); + if((RegexOptions.Multiline & options) == RegexOptions.Multiline) + { + // Replace all non-escaped $ occurences by \r?$ + // c.f. http://programmaticallyspeaking.com/regular-expression-multiline-mode-whats-a-newline.html + + int index = 0; + var newPattern = pattern; + while((index = newPattern.IndexOf("$", index)) != -1) + { + if(index > 0 && newPattern[index - 1] != '\\') + { + newPattern = newPattern.Substring(0, index) + @"\r?" + newPattern.Substring(index); + index += 4; + } + } + + r.Value = new Regex(newPattern, options); + } + else + { + r.Value = new Regex(pattern, options); + } + } catch (Exception e) { diff --git a/Jint/Native/RegExp/RegExpPrototype.cs b/Jint/Native/RegExp/RegExpPrototype.cs index 93210e3b48..7c19686ba2 100644 --- a/Jint/Native/RegExp/RegExpPrototype.cs +++ b/Jint/Native/RegExp/RegExpPrototype.cs @@ -86,7 +86,7 @@ internal JsValue Exec(JsValue thisObj, JsValue[] arguments) } Match r = null; - if (i < 0 || i >= length) + if (i < 0 || i > length) { R.Put("lastIndex", (double) 0, true); return Null.Instance; @@ -125,7 +125,7 @@ private static Object.ObjectInstance InitReturnValueArray(Object.ObjectInstance { array.DefineOwnProperty("index", new PropertyDescriptor(indexValue, writable: true, enumerable: true, configurable: true), true); array.DefineOwnProperty("input", new PropertyDescriptor(inputValue, writable: true, enumerable: true, configurable: true), true); - array.DefineOwnProperty("length", new PropertyDescriptor(value: lengthValue, writable: false, enumerable: false, configurable: false), true); + array.DefineOwnProperty("length", new PropertyDescriptor(value: lengthValue, writable: true, enumerable: false, configurable: false), true); return array; } } diff --git a/Jint/Native/String/StringPrototype.cs b/Jint/Native/String/StringPrototype.cs index 7095b45e39..e8bd914da9 100644 --- a/Jint/Native/String/StringPrototype.cs +++ b/Jint/Native/String/StringPrototype.cs @@ -58,6 +58,8 @@ public void Configure() FastAddProperty("toUpperCase", new ClrFunctionInstance(Engine, ToUpperCase), true, false, true); FastAddProperty("toLocaleUpperCase", new ClrFunctionInstance(Engine, ToLocaleUpperCase), true, false, true); FastAddProperty("trim", new ClrFunctionInstance(Engine, Trim), true, false, true); + FastAddProperty("padStart", new ClrFunctionInstance(Engine, PadStart), true, false, true); + FastAddProperty("padEnd", new ClrFunctionInstance(Engine, PadEnd), true, false, true); } private JsValue ToStringString(JsValue thisObj, JsValue[] arguments) @@ -74,13 +76,18 @@ private JsValue ToStringString(JsValue thisObj, JsValue[] arguments) // http://msdn.microsoft.com/en-us/library/system.char.iswhitespace(v=vs.110).aspx // http://en.wikipedia.org/wiki/Byte_order_mark const char BOM_CHAR = '\uFEFF'; + const char MONGOLIAN_VOWEL_SEPARATOR = '\u180E'; private static bool IsWhiteSpaceEx(char c) { - return char.IsWhiteSpace(c) || c == BOM_CHAR; + return + char.IsWhiteSpace(c) || + c == BOM_CHAR || + // In .NET 4.6 this was removed from WS based on Unicode 6.3 changes + c == MONGOLIAN_VOWEL_SEPARATOR; } - private static string TrimEndEx(string s) + public static string TrimEndEx(string s) { if (s.Length == 0) return string.Empty; @@ -99,7 +106,7 @@ private static string TrimEndEx(string s) return string.Empty; } - private static string TrimStartEx(string s) + public static string TrimStartEx(string s) { if (s.Length == 0) return string.Empty; @@ -118,7 +125,7 @@ private static string TrimStartEx(string s) return s.Substring(i); } - private static string TrimEx(string s) + public static string TrimEx(string s) { return TrimEndEx(TrimStartEx(s)); } @@ -506,8 +513,7 @@ private JsValue Replace(JsValue thisObj, JsValue[] arguments) for (var k = 0; k < match.Groups.Count; k++) { var group = match.Groups[k]; - if (group.Success) - args.Add(group.Value); + args.Add(group.Value); } args.Add(match.Index); @@ -614,80 +620,51 @@ private JsValue LocaleCompare(JsValue thisObj, JsValue[] arguments) return string.CompareOrdinal(s, that); } - private static List AllIndexesOf(string str, string value) + private JsValue LastIndexOf(JsValue thisObj, JsValue[] arguments) { - if (string.IsNullOrEmpty(value)) - return new List(); + TypeConverter.CheckObjectCoercible(Engine, thisObj); - var indexes = new List(); - for (int index = 0; ; index += value.Length) + var s = TypeConverter.ToString(thisObj); + var searchStr = TypeConverter.ToString(arguments.At(0)); + double numPos = double.NaN; + if (arguments.Length > 1 && arguments[1] != Undefined.Instance) { - index = str.IndexOf(value, index); - if (index == -1) // no more fond - return indexes; - indexes.Add(index); + numPos = TypeConverter.ToNumber(arguments[1]); } - } - private int LastIndexJavaScriptImplementation(string s, string searchStr, int pos = -1) - { - if (pos == -1) - pos = s.Length; + var pos = double.IsNaN(numPos) ? double.PositiveInfinity : TypeConverter.ToInteger(numPos); - var len = s.Length; - var start = System.Math.Min(System.Math.Max(pos, 0), len); - var searchLen = searchStr.Length; - var kPositions = AllIndexesOf(s, searchStr); + var len = s.Length; + var start = (int)System.Math.Min(System.Math.Max(pos, 0), len); + var searchLen = searchStr.Length; - if (kPositions.Count == 0) // Nothing found - { - return -1; - } - else if (kPositions.Count == 1) // Only one found - { - return kPositions[0] <= start ? kPositions[0] : -1; - } + var i = start; + bool found; - // Return the largest possible nonnegative integer k not larger than start - // such that k+ searchLen is not greater than len - for (var i = 0; i < kPositions.Count; i++) + do { - if (kPositions[i] <= start) + found = true; + var j = 0; + + while (found && j < searchLen) { - // ok move to the next one to find a greater pos + if ((i + searchLen > len) || (s[i + j] != searchStr[j])) + { + found = false; + } + else + { + j++; + } } - else + if (!found) { - if ((i > 0) && ((kPositions[i - 1] + searchLen) <= len)) - return kPositions[i - 1]; - else - return -1; + i--; } - } - return kPositions[kPositions.Count - 1]; - } - private JsValue LastIndexOf(JsValue thisObj, JsValue[] arguments) - { - TypeConverter.CheckObjectCoercible(Engine, thisObj); + } while (!found && i >= 0); - var s = TypeConverter.ToString(thisObj); - var searchStr = TypeConverter.ToString(arguments.At(0)); - double numPos = arguments.At(1) == Undefined.Instance ? s.Length : TypeConverter.ToNumber(arguments.At(1)); - double pos = double.IsNaN(numPos) ? double.PositiveInfinity : TypeConverter.ToInteger(numPos); - var len = s.Length; - var start = System.Math.Min(len, System.Math.Max(pos, 0)); - - // The JavaScript spec of string.lastIndexOf does match the C# spec - // Therefore we need to write our own specific implementation. - // Enjoy the fact that Ecma spec and Mozilla spec have different definition which - // I guess mean the same thing. - // Ecma spec - // http://www.ecma-international.org/ecma-262/5.1/#sec-15.5.4.8 - // Mozilla spec - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/lastIndexOf - - return LastIndexJavaScriptImplementation(s, searchStr, (int)start); + return i; } private JsValue IndexOf(JsValue thisObj, JsValue[] arguments) @@ -767,5 +744,54 @@ private JsValue ValueOf(JsValue thisObj, JsValue[] arguments) return s.PrimitiveValue; } + + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart + /// + /// The original string object + /// + /// argument[0] is the target length of the output string + /// argument[1] is the string to pad with + /// + /// + private JsValue PadStart(JsValue thisObj, JsValue[] arguments) + { + return Pad(thisObj, arguments, true); + } + + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd + /// + /// The original string object + /// + /// argument[0] is the target length of the output string + /// argument[1] is the string to pad with + /// + /// + private JsValue PadEnd(JsValue thisObj, JsValue[] arguments) + { + return Pad(thisObj, arguments, false); + } + + private JsValue Pad(JsValue thisObj, JsValue[] arguments, bool padStart) + { + TypeConverter.CheckObjectCoercible(Engine, thisObj); + var targetLength = TypeConverter.ToInt32(arguments.At(0)); + var padString = TypeConverter.ToString(arguments.At(1, new JsValue(" "))); + + var s = TypeConverter.ToString(thisObj); + if (s.Length > targetLength) + { + return s; + } + + targetLength = targetLength - s.Length; + if (targetLength > padString.Length) + { + padString = string.Join("", Enumerable.Repeat(padString, (targetLength / padString.Length) + 1)); + } + + return padStart ? $"{padString.Substring(0, targetLength)}{s}" : $"{s}{padString.Substring(0, targetLength)}"; + } } } diff --git a/Jint/Native/Undefined.cs b/Jint/Native/Undefined.cs index 8b8f64d281..03e34094c7 100644 --- a/Jint/Native/Undefined.cs +++ b/Jint/Native/Undefined.cs @@ -2,7 +2,7 @@ { public static class Undefined { - public static JsValue Instance = JsValue.Undefined; - public static string Text = "undefined"; + public readonly static JsValue Instance = JsValue.Undefined; + public readonly static string Text = "undefined"; } } \ No newline at end of file diff --git a/Jint/Options.cs b/Jint/Options.cs index c28580dae7..a68507d4b2 100644 --- a/Jint/Options.cs +++ b/Jint/Options.cs @@ -1,8 +1,8 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Reflection; -using Jint.Native; using Jint.Runtime.Interop; namespace Jint @@ -12,12 +12,17 @@ public class Options private bool _discardGlobal; private bool _strict; private bool _allowDebuggerStatement; + private bool _debugMode; private bool _allowClr; - private ITypeConverter _typeConverter = new DefaultTypeConverter(); private readonly List _objectConverters = new List(); private int _maxStatements; + private int _maxRecursionDepth = -1; + private TimeSpan _timeoutInterval; private CultureInfo _culture = CultureInfo.CurrentCulture; - private List _lookupAssemblies = new List(); + private TimeZoneInfo _localTimeZone = TimeZoneInfo.Local; + private List _lookupAssemblies = new List(); + private Predicate _clrExceptionsHandler; + private IReferenceResolver _referenceResolver; /// /// When called, doesn't initialize the global scope. @@ -52,11 +57,11 @@ public Options AllowDebuggerStatement(bool allowDebuggerStatement = true) } /// - /// Sets a instance to use when converting CLR types + /// Allow to run the script in debug mode. /// - public Options SetTypeConverter(ITypeConverter typeConverter) + public Options DebugMode(bool debugMode = true) { - _typeConverter = typeConverter; + _debugMode = debugMode; return this; } @@ -80,61 +85,100 @@ public Options AllowClr(params Assembly[] assemblies) return this; } - public Options MaxStatements(int maxStatements = 0) + /// + /// Exceptions thrown from CLR code are converted to JavaScript errors and + /// can be used in at try/catch statement. By default these exceptions are bubbled + /// to the CLR host and interrupt the script execution. + /// + public Options CatchClrExceptions() { - _maxStatements = maxStatements; + CatchClrExceptions(_ => true); return this; } - public Options Culture(CultureInfo cultureInfo) + /// + /// Exceptions that thrown from CLR code are converted to JavaScript errors and + /// can be used in at try/catch statement. By default these exceptions are bubbled + /// to the CLR host and interrupt the script execution. + /// + public Options CatchClrExceptions(Predicate handler) { - _culture = cultureInfo; + _clrExceptionsHandler = handler; return this; } - internal bool GetDiscardGlobal() + public Options MaxStatements(int maxStatements = 0) { - return _discardGlobal; + _maxStatements = maxStatements; + return this; } - - internal bool IsStrict() + + public Options TimeoutInterval(TimeSpan timeoutInterval) { - return _strict; + _timeoutInterval = timeoutInterval; + return this; } - internal bool IsDebuggerStatementAllowed() - { - return _allowDebuggerStatement; + /// + /// Sets maximum allowed depth of recursion. + /// + /// + /// The allowed depth. + /// a) In case max depth is zero no recursion is allowed. + /// b) In case max depth is equal to n it means that in one scope function can be called no more than n times. + /// + /// Options instance for fluent syntax + public Options LimitRecursion(int maxRecursionDepth = 0) + { + _maxRecursionDepth = maxRecursionDepth; + return this; } - internal bool IsClrAllowed() - { - return _allowClr; - } - - internal IList GetLookupAssemblies() + public Options Culture(CultureInfo cultureInfo) { - return _lookupAssemblies; + _culture = cultureInfo; + return this; } - internal ITypeConverter GetTypeConverter() + public Options LocalTimeZone(TimeZoneInfo timeZoneInfo) { - return _typeConverter; + _localTimeZone = timeZoneInfo; + return this; } - internal IEnumerable GetObjectConverters() + public Options SetReferencesResolver(IReferenceResolver resolver) { - return _objectConverters; + _referenceResolver = resolver; + return this; } - internal int GetMaxStatements() - { - return _maxStatements; - } + internal bool _IsGlobalDiscarded => _discardGlobal; + + internal bool _IsStrict => _strict; + + internal bool _IsDebuggerStatementAllowed => _allowDebuggerStatement; + + internal bool _IsDebugMode => _debugMode; + + internal bool _IsClrAllowed => _allowClr; + + internal Predicate _ClrExceptionsHandler => _clrExceptionsHandler; + + internal IList _LookupAssemblies => _lookupAssemblies; + + internal IEnumerable _ObjectConverters => _objectConverters; + + internal int _MaxStatements => _maxStatements; + + internal int _MaxRecursionDepth => _maxRecursionDepth; + + internal TimeSpan _TimeoutInterval => _timeoutInterval; + + internal CultureInfo _Culture => _culture; + + internal TimeZoneInfo _LocalTimeZone => _localTimeZone; + + internal IReferenceResolver _ReferenceResolver => _referenceResolver; - internal CultureInfo GetCulture() - { - return _culture; - } } } diff --git a/Jint/Parser/Ast/CallExpression.cs b/Jint/Parser/Ast/CallExpression.cs index 0fd273b94b..3a36c46875 100644 --- a/Jint/Parser/Ast/CallExpression.cs +++ b/Jint/Parser/Ast/CallExpression.cs @@ -1,3 +1,4 @@ +using Jint.Native; using System.Collections.Generic; namespace Jint.Parser.Ast @@ -5,6 +6,10 @@ namespace Jint.Parser.Ast public class CallExpression : Expression { public Expression Callee; - public IEnumerable Arguments; + public IList Arguments; + + public bool Cached; + public bool CanBeCached = true; + public JsValue[] CachedArguments; } } \ No newline at end of file diff --git a/Jint/Parser/Ast/Literal.cs b/Jint/Parser/Ast/Literal.cs index 9e6d7293cc..87346ec524 100644 --- a/Jint/Parser/Ast/Literal.cs +++ b/Jint/Parser/Ast/Literal.cs @@ -1,3 +1,5 @@ +using Jint.Native; + namespace Jint.Parser.Ast { public class Literal : Expression, IPropertyKeyExpression @@ -5,9 +7,13 @@ public class Literal : Expression, IPropertyKeyExpression public object Value; public string Raw; + public bool Cached; + public JsValue CachedValue; + public string GetKey() { return Value.ToString(); } + } } \ No newline at end of file diff --git a/Jint/Parser/Ast/WithStatement.cs b/Jint/Parser/Ast/WithStatement.cs index f99d6cc00b..4d2d397e22 100644 --- a/Jint/Parser/Ast/WithStatement.cs +++ b/Jint/Parser/Ast/WithStatement.cs @@ -1,6 +1,4 @@ -using Jint.Parser.Ast; - -namespace Jint +namespace Jint.Parser.Ast { public class WithStatement : Statement { diff --git a/Jint/Parser/JavascriptParser.cs b/Jint/Parser/JavascriptParser.cs index 0c0cefd4f7..1fb4ebdeef 100644 --- a/Jint/Parser/JavascriptParser.cs +++ b/Jint/Parser/JavascriptParser.cs @@ -1,16 +1,17 @@ -using System; +using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; using System.Text.RegularExpressions; +using Jint.Native.String; using Jint.Parser.Ast; namespace Jint.Parser { public class JavaScriptParser { - private static readonly object[] Keywords = + private static readonly HashSet Keywords = new HashSet { "if", "in", "do", "var", "for", "new", "try", "let", "this", "else", "case", "void", "with", "enum", @@ -20,7 +21,7 @@ public class JavaScriptParser "function", "continue", "debugger", "instanceof" }; - private static readonly object[] StrictModeReservedWords = + private static readonly HashSet StrictModeReservedWords = new HashSet { "implements", "interface", @@ -33,7 +34,7 @@ public class JavaScriptParser "let" }; - private static readonly object[] FutureReservedWords = + private static readonly HashSet FutureReservedWords = new HashSet { "class", "enum", @@ -145,12 +146,12 @@ private static bool IsIdentifierPart(char ch) private static bool IsFutureReservedWord(string id) { - return Array.IndexOf(FutureReservedWords, id) >= 0; + return FutureReservedWords.Contains(id); } private static bool IsStrictModeReservedWord(string id) { - return Array.IndexOf(StrictModeReservedWords, id) >= 0; + return StrictModeReservedWords.Contains(id); } private static bool IsRestrictedWord(string id) @@ -170,8 +171,8 @@ private bool IsKeyword(string id) // 'const' is specialized as Keyword in V8. // 'yield' and 'let' are for compatiblity with SpiderMonkey and ES.next. // Some others are from future reserved words. - - return Array.IndexOf(Keywords, id) >= 0; + + return Keywords.Contains(id); } // 7.4 Comments @@ -205,18 +206,18 @@ private void AddComment(string type, string value, int start, int end, Location _extra.Comments.Add(comment); } - private void SkipSingleLineComment() + private void SkipSingleLineComment(int offset) { //var start, loc, ch, comment; - int start = _index - 2; + int start = _index - offset; _location = new Location { Start = new Position { Line = _lineNumber, - Column = _index - _lineStart - 2 - } + Column = _index - _lineStart - offset + } }; while (_index < _length) @@ -247,7 +248,7 @@ private void SkipSingleLineComment() if (_extra.Comments != null) { - var comment = _source.Slice(start + 2, _index); + var comment = _source.Slice(start + offset, _index); _location.End = new Position { Line = _lineNumber, @@ -324,6 +325,8 @@ private void SkipMultiLineComment() private void SkipComment() { + bool start = _index == 0; + while (_index < _length) { char ch = _source.CharCodeAt(_index); @@ -341,20 +344,20 @@ private void SkipComment() } ++_lineNumber; _lineStart = _index; + start = true; } - else if (ch == 47) + else if (ch == '/') { - // 47 is '/' ch = _source.CharCodeAt(_index + 1); - if (ch == 47) + if (ch == '/') { ++_index; ++_index; - SkipSingleLineComment(); + SkipSingleLineComment(2); + start = true; } - else if (ch == 42) + else if (ch == '*') { - // 42 is '*' ++_index; ++_index; SkipMultiLineComment(); @@ -364,7 +367,35 @@ private void SkipComment() break; } } - else + else if (start && ch == '-') + { + if (_source.CharCodeAt(_index + 1) == '-' && _source.CharCodeAt(_index + 2) == '>') + { + // '-->' is a single line comment + _index += 3; + SkipSingleLineComment(3); + } + else + { + break; + } + } + else if (ch == '<') + { + if (_source.Slice(_index + 1, _index + 4) == "!--") + { + ++_index; // '<' + ++_index; // '!' + ++_index; // '-' + ++_index; // '-' + SkipSingleLineComment(4); + + } + else + { + break; + } + } else { break; } @@ -728,10 +759,41 @@ private Token ScanHexLiteral(int start) ThrowError(null, Messages.UnexpectedToken, "ILLEGAL"); } + double value = 0; + + if (number.Length < 16) + { + value = Convert.ToUInt64(number, 16); + } + else if(number.Length > 255) + { + value = double.PositiveInfinity; + } + else + { + double modulo = 1; + var literal = number.ToLowerInvariant(); + for (var i = literal.Length - 1; i >= 0; i--) + { + var c = literal[i]; + + if (c <= '9') + { + value += modulo * (c - '0'); + } + else + { + value += modulo * (c - 'a' + 10); + } + + modulo *= 16; + } + } + return new Token { Type = Tokens.NumericLiteral, - Value = Convert.ToInt64(number, 16), + Value = value, LineNumber = _lineNumber, LineStart = _lineStart, Range = new[] {start, _index} @@ -858,7 +920,7 @@ private Token ScanNumericLiteral() } catch (OverflowException) { - n = number.Trim().StartsWith("-") ? double.NegativeInfinity : double.PositiveInfinity; + n = StringPrototype.TrimEx(number).StartsWith("-") ? double.NegativeInfinity : double.PositiveInfinity; } catch (Exception) { @@ -881,6 +943,8 @@ private Token ScanStringLiteral() { var str = new StringBuilder(); bool octal = false; + var startLineStart = _lineStart; + var startLineNumber = _lineNumber; char quote = _source.CharCodeAt(_index); @@ -978,6 +1042,7 @@ private Token ScanStringLiteral() { ++_index; } + _lineStart = _index; } } else if (IsLineTerminator(ch)) @@ -1193,7 +1258,7 @@ private Token Advance() char ch = _source.CharCodeAt(_index); // Very common: ( and ) and ; - if (ch == 40 || ch == 41 || ch == 58) + if (ch == 40 || ch == 41 || ch == 59) { return ScanPunctuator(); } @@ -1418,7 +1483,7 @@ public BreakStatement CreateBreakStatement(Identifier label) }; } - public CallExpression CreateCallExpression(Expression callee, IEnumerable args) + public CallExpression CreateCallExpression(Expression callee, IList args) { return new CallExpression { @@ -2294,7 +2359,7 @@ private Expression ParsePrimaryExpression() // 11.2 Left-Hand-Side Expressions - private IEnumerable ParseArguments() + private IList ParseArguments() { var args = new List(); @@ -2372,7 +2437,7 @@ private Expression ParseLeftHandSideExpressionAllowCall() { if (Match("(")) { - IEnumerable args = ParseArguments(); + IList args = ParseArguments(); expr = CreateCallExpression(expr, args); } else if (Match("[")) diff --git a/Jint/Parser/ParserException.cs b/Jint/Parser/ParserException.cs index a5852a3249..4191a96e48 100644 --- a/Jint/Parser/ParserException.cs +++ b/Jint/Parser/ParserException.cs @@ -8,7 +8,10 @@ public class ParserException : Exception public string Description; public int Index; public int LineNumber; + +#if PORTABLE public string Source; +#endif public ParserException(string message) : base(message) { diff --git a/Jint/Parser/ParserExtensions.cs b/Jint/Parser/ParserExtensions.cs index adb40c5dcc..ddc4306815 100644 --- a/Jint/Parser/ParserExtensions.cs +++ b/Jint/Parser/ParserExtensions.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; namespace Jint.Parser { @@ -6,7 +7,7 @@ public static class ParserExtensions { public static string Slice(this string source, int start, int end) { - return source.Substring(start, end - start); + return source.Substring(start, Math.Min(source.Length, end) - start); } public static char CharCodeAt(this string source, int index) diff --git a/Jint/Properties/AssemblyInfo.cs b/Jint/Properties/AssemblyInfo.cs deleted file mode 100644 index 2d45edb803..0000000000 --- a/Jint/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Resources; -using System.Reflection; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Jint")] -[assembly: AssemblyDescription("Javascript Interpreter for .NET")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Sebastien Ros")] -[assembly: AssemblyProduct("Jint")] -[assembly: AssemblyCopyright("Copyright © Sébastien Ros 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] -[assembly: NeutralResourcesLanguage("en")] - -[assembly: AssemblyVersion("2.2.0")] -[assembly: AssemblyFileVersion("2.2.0")] diff --git a/Jint/ReflectionExtensions.cs b/Jint/ReflectionExtensions.cs new file mode 100644 index 0000000000..ff41e1105d --- /dev/null +++ b/Jint/ReflectionExtensions.cs @@ -0,0 +1,65 @@ +#if NETSTANDARD1_3 +using System; +using System.Linq; +using System.Reflection; + +namespace Jint +{ + internal static class ReflectionExtensions + { + internal static bool IsEnum(this Type type) + { + return type.GetTypeInfo().IsEnum; + } + + internal static bool IsGenericType(this Type type) + { + return type.GetTypeInfo().IsGenericType; + } + + internal static bool IsValueType(this Type type) + { + return type.GetTypeInfo().IsValueType; + } + + internal static bool HasAttribute(this ParameterInfo member) where T : Attribute + { + return member.GetCustomAttributes().Any(); + } + } +} +#else +using System; +using System.Reflection; + +namespace Jint +{ + internal static class ReflectionExtensions + { + internal static bool IsEnum(this Type type) + { + return type.IsEnum; + } + + internal static bool IsGenericType(this Type type) + { + return type.IsGenericType; + } + + internal static bool IsValueType(this Type type) + { + return type.IsValueType; + } + + internal static bool HasAttribute(this ParameterInfo member) where T : Attribute + { + return Attribute.IsDefined(member, typeof(T)); + } + + internal static MethodInfo GetMethodInfo(this Delegate d) + { + return d.Method; + } + } +} +#endif diff --git a/Jint/Runtime/CallStack/CallStackElement.cs b/Jint/Runtime/CallStack/CallStackElement.cs new file mode 100644 index 0000000000..023449d698 --- /dev/null +++ b/Jint/Runtime/CallStack/CallStackElement.cs @@ -0,0 +1,26 @@ +namespace Jint.Runtime +{ + using Jint.Native; + using Jint.Parser.Ast; + + public class CallStackElement + { + private string _shortDescription; + + public CallStackElement(CallExpression callExpression, JsValue function, string shortDescription) + { + _shortDescription = shortDescription; + CallExpression = callExpression; + Function = function; + } + + public CallExpression CallExpression { get; private set; } + + public JsValue Function { get; private set; } + + public override string ToString() + { + return _shortDescription; + } + } +} diff --git a/Jint/Runtime/CallStack/CallStackElementComparer.cs b/Jint/Runtime/CallStack/CallStackElementComparer.cs new file mode 100644 index 0000000000..29a86385c4 --- /dev/null +++ b/Jint/Runtime/CallStack/CallStackElementComparer.cs @@ -0,0 +1,17 @@ +namespace Jint.Runtime.CallStack +{ + using System.Collections.Generic; + + public class CallStackElementComparer: IEqualityComparer + { + public bool Equals(CallStackElement x, CallStackElement y) + { + return x.Function == y.Function; + } + + public int GetHashCode(CallStackElement obj) + { + return obj.Function.GetHashCode(); + } + } +} diff --git a/Jint/Runtime/CallStack/JintCallStack.cs b/Jint/Runtime/CallStack/JintCallStack.cs new file mode 100644 index 0000000000..ced83e5ed7 --- /dev/null +++ b/Jint/Runtime/CallStack/JintCallStack.cs @@ -0,0 +1,65 @@ +using System.Collections; + +namespace Jint.Runtime.CallStack +{ + using System.Collections.Generic; + using System.Linq; + + public class JintCallStack : IEnumerable + { + private Stack _stack = new Stack(); + + private Dictionary _statistics = + new Dictionary(new CallStackElementComparer()); + + public int Push(CallStackElement item) + { + _stack.Push(item); + if (_statistics.ContainsKey(item)) + { + return ++_statistics[item]; + } + else + { + _statistics.Add(item, 0); + return 0; + } + } + + public CallStackElement Pop() + { + var item = _stack.Pop(); + if (_statistics[item] == 0) + { + _statistics.Remove(item); + } + else + { + _statistics[item]--; + } + + return item; + } + + public void Clear() + { + _stack.Clear(); + _statistics.Clear(); + } + + public IEnumerator GetEnumerator() + { + return _stack.GetEnumerator(); + } + + public override string ToString() + { + return string.Join("->", _stack.Select(cse => cse.ToString()).Reverse()); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } +} diff --git a/Jint/Runtime/Completion.cs b/Jint/Runtime/Completion.cs index 0fe0cd6429..8916f5aeb6 100644 --- a/Jint/Runtime/Completion.cs +++ b/Jint/Runtime/Completion.cs @@ -13,7 +13,7 @@ public class Completion public static string Return = "return"; public static string Throw = "throw"; - public Completion(string type, JsValue? value, string identifier) + public Completion(string type, JsValue value, string identifier) { Type = type; Value = value; @@ -21,12 +21,14 @@ public Completion(string type, JsValue? value, string identifier) } public string Type { get; private set; } - public JsValue? Value { get; private set; } + public JsValue Value { get; private set; } public string Identifier { get; private set; } public JsValue GetValueOrDefault() { - return Value.HasValue ? Value.Value : Undefined.Instance; + return Value != null ? Value : Undefined.Instance; } + + public Jint.Parser.Location Location { get; set; } } } diff --git a/Jint/Runtime/Debugger/BreakPoint.cs b/Jint/Runtime/Debugger/BreakPoint.cs new file mode 100644 index 0000000000..dac0bd1e33 --- /dev/null +++ b/Jint/Runtime/Debugger/BreakPoint.cs @@ -0,0 +1,21 @@ +namespace Jint.Runtime.Debugger +{ + public class BreakPoint + { + public int Line { get; set; } + public int Char { get; set; } + public string Condition { get; set; } + + public BreakPoint(int line, int character) + { + Line = line; + Char = character; + } + + public BreakPoint(int line, int character, string condition) + : this(line, character) + { + Condition = condition; + } + } +} diff --git a/Jint/Runtime/Debugger/DebugHandler.cs b/Jint/Runtime/Debugger/DebugHandler.cs new file mode 100644 index 0000000000..cce320a3c0 --- /dev/null +++ b/Jint/Runtime/Debugger/DebugHandler.cs @@ -0,0 +1,202 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Jint.Native; +using Jint.Parser.Ast; +using Jint.Runtime.Environments; +using Jint.Runtime.References; + +namespace Jint.Runtime.Debugger +{ + internal class DebugHandler + { + private readonly Stack _debugCallStack; + private StepMode _stepMode; + private int _callBackStepOverDepth; + private readonly Engine _engine; + + public DebugHandler(Engine engine) + { + _engine = engine; + _debugCallStack = new Stack(); + _stepMode = StepMode.Into; + } + + internal void PopDebugCallStack() + { + if (_debugCallStack.Count > 0) + { + _debugCallStack.Pop(); + } + if (_stepMode == StepMode.Out && _debugCallStack.Count < _callBackStepOverDepth) + { + _callBackStepOverDepth = _debugCallStack.Count; + _stepMode = StepMode.Into; + } + else if (_stepMode == StepMode.Over && _debugCallStack.Count == _callBackStepOverDepth) + { + _callBackStepOverDepth = _debugCallStack.Count; + _stepMode = StepMode.Into; + } + } + + internal void AddToDebugCallStack(CallExpression callExpression) + { + var identifier = callExpression.Callee as Identifier; + if (identifier != null) + { + var stack = identifier.Name + "("; + var paramStrings = new List(); + + foreach (var argument in callExpression.Arguments) + { + if (argument != null) + { + var argIdentifier = argument as Identifier; + paramStrings.Add(argIdentifier != null ? argIdentifier.Name : "null"); + } + else + { + paramStrings.Add("null"); + } + } + + stack += string.Join(", ", paramStrings); + stack += ")"; + _debugCallStack.Push(stack); + } + } + + internal void OnStep(Statement statement) + { + var old = _stepMode; + if (statement == null) + { + return; + } + + BreakPoint breakpoint = _engine.BreakPoints.FirstOrDefault(breakPoint => BpTest(statement, breakPoint)); + bool breakpointFound = false; + + if (breakpoint != null) + { + DebugInformation info = CreateDebugInformation(statement); + var result = _engine.InvokeBreakEvent(info); + if (result.HasValue) + { + _stepMode = result.Value; + breakpointFound = true; + } + } + + if (breakpointFound == false && _stepMode == StepMode.Into) + { + DebugInformation info = CreateDebugInformation(statement); + var result = _engine.InvokeStepEvent(info); + if (result.HasValue) + { + _stepMode = result.Value; + } + } + + if (old == StepMode.Into && _stepMode == StepMode.Out) + { + _callBackStepOverDepth = _debugCallStack.Count; + } + else if (old == StepMode.Into && _stepMode == StepMode.Over) + { + var expressionStatement = statement as ExpressionStatement; + if (expressionStatement != null && expressionStatement.Expression is CallExpression) + { + _callBackStepOverDepth = _debugCallStack.Count; + } + else + { + _stepMode = StepMode.Into; + } + } + } + + private bool BpTest(Statement statement, BreakPoint breakpoint) + { + bool afterStart, beforeEnd; + + afterStart = (breakpoint.Line == statement.Location.Start.Line && + breakpoint.Char >= statement.Location.Start.Column); + + if (!afterStart) + { + return false; + } + + beforeEnd = breakpoint.Line < statement.Location.End.Line + || (breakpoint.Line == statement.Location.End.Line && + breakpoint.Char <= statement.Location.End.Column); + + if (!beforeEnd) + { + return false; + } + + if (!string.IsNullOrEmpty(breakpoint.Condition)) + { + return _engine.Execute(breakpoint.Condition).GetCompletionValue().AsBoolean(); + } + + return true; + } + + private DebugInformation CreateDebugInformation(Statement statement) + { + var info = new DebugInformation { CurrentStatement = statement, CallStack = _debugCallStack }; + + if (_engine.ExecutionContext != null && _engine.ExecutionContext.LexicalEnvironment != null) + { + var lexicalEnvironment = _engine.ExecutionContext.LexicalEnvironment; + info.Locals = GetLocalVariables(lexicalEnvironment); + info.Globals = GetGlobalVariables(lexicalEnvironment); + } + + return info; + } + + private static Dictionary GetLocalVariables(LexicalEnvironment lex) + { + Dictionary locals = new Dictionary(); + if (lex != null && lex.Record != null) + { + AddRecordsFromEnvironment(lex, locals); + } + return locals; + } + + private static Dictionary GetGlobalVariables(LexicalEnvironment lex) + { + Dictionary globals = new Dictionary(); + LexicalEnvironment tempLex = lex; + + while (tempLex != null && tempLex.Record != null) + { + AddRecordsFromEnvironment(tempLex, globals); + tempLex = tempLex.Outer; + } + return globals; + } + + private static void AddRecordsFromEnvironment(LexicalEnvironment lex, Dictionary locals) + { + var bindings = lex.Record.GetAllBindingNames(); + foreach (var binding in bindings) + { + if (locals.ContainsKey(binding) == false) + { + var jsValue = lex.Record.GetBindingValue(binding, false); + if (jsValue.TryCast() == null) + { + locals.Add(binding, jsValue); + } + } + } + } + } +} diff --git a/Jint/Runtime/Debugger/DebugInformation.cs b/Jint/Runtime/Debugger/DebugInformation.cs new file mode 100644 index 0000000000..0cff45613c --- /dev/null +++ b/Jint/Runtime/Debugger/DebugInformation.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using Jint.Native; +using Jint.Parser.Ast; +using Jint.Runtime.Environments; + +namespace Jint.Runtime.Debugger +{ + public class DebugInformation : EventArgs + { + public Stack CallStack { get; set; } + public Statement CurrentStatement { get; set; } + public Dictionary Locals { get; set; } + public Dictionary Globals { get; set; } + } +} diff --git a/Jint/Runtime/Debugger/StepMode.cs b/Jint/Runtime/Debugger/StepMode.cs new file mode 100644 index 0000000000..64984f828a --- /dev/null +++ b/Jint/Runtime/Debugger/StepMode.cs @@ -0,0 +1,10 @@ +namespace Jint.Runtime.Debugger +{ + public enum StepMode + { + None, + Over, + Into, + Out + } +} diff --git a/Jint/Runtime/Descriptors/PropertyDescriptor.cs b/Jint/Runtime/Descriptors/PropertyDescriptor.cs index da84e5552d..636bfb6a47 100644 --- a/Jint/Runtime/Descriptors/PropertyDescriptor.cs +++ b/Jint/Runtime/Descriptors/PropertyDescriptor.cs @@ -3,16 +3,6 @@ namespace Jint.Runtime.Descriptors { - public enum Fields - { - Get, - Set, - Enumerable, - Configurable, - Writable, - Value - } - public class PropertyDescriptor { public static PropertyDescriptor Undefined = new PropertyDescriptor(); @@ -21,39 +11,39 @@ public PropertyDescriptor() { } - public PropertyDescriptor(JsValue? value, bool? writable, bool? enumerable, bool? configurable) + public PropertyDescriptor(JsValue value, bool? writable, bool? enumerable, bool? configurable) { Value = value; if (writable.HasValue) { - Writable = new JsValue(writable.Value); + Writable = writable.Value; } if (enumerable.HasValue) { - Enumerable = new JsValue(enumerable.Value); + Enumerable = enumerable.Value; } if (configurable.HasValue) { - Configurable = new JsValue(configurable.Value); + Configurable = configurable.Value; } } - public PropertyDescriptor(JsValue? get, JsValue? set, bool? enumerable = null, bool? configurable = null) + public PropertyDescriptor(JsValue get, JsValue set, bool? enumerable = null, bool? configurable = null) { Get = get; Set = set; if (enumerable.HasValue) { - Enumerable = new JsValue(enumerable.Value); + Enumerable = enumerable.Value; } if (configurable.HasValue) { - Configurable = new JsValue(configurable.Value); + Configurable = configurable.Value; } } @@ -67,16 +57,16 @@ public PropertyDescriptor(PropertyDescriptor descriptor) Writable = descriptor.Writable; } - public JsValue? Get { get; set; } - public JsValue? Set { get; set; } - public JsValue? Enumerable { get; set; } - public JsValue? Writable { get; set; } - public JsValue? Configurable { get; set; } - public virtual JsValue? Value { get; set; } - + public JsValue Get { get; set; } + public JsValue Set { get; set; } + public bool? Enumerable { get; set; } + public bool? Writable { get; set; } + public bool? Configurable { get; set; } + public virtual JsValue Value { get; set; } + public bool IsAccessorDescriptor() { - if (!Get.HasValue && !Set.HasValue) + if (Get ==null && Set == null) { return false; } @@ -86,7 +76,7 @@ public bool IsAccessorDescriptor() public bool IsDataDescriptor() { - if (!Writable.HasValue && !Value.HasValue) + if (!Writable.HasValue && Value == null) { return false; } @@ -160,9 +150,9 @@ public static PropertyDescriptor ToPropertyDescriptor(Engine engine, JsValue o) desc.Set = setter; } - if (desc.Get.HasValue || desc.Get.HasValue) + if (desc.Get != null || desc.Get != null) { - if (desc.Value.HasValue || desc.Writable.HasValue) + if (desc.Value != null || desc.Writable.HasValue) { throw new JavaScriptException(engine.TypeError); } @@ -182,8 +172,8 @@ public static JsValue FromPropertyDescriptor(Engine engine, PropertyDescriptor d if (desc.IsDataDescriptor()) { - obj.DefineOwnProperty("value", new PropertyDescriptor(value: desc.Value.HasValue ? desc.Value.Value : Native.Undefined.Instance, writable: true, enumerable: true, configurable: true ), false); - obj.DefineOwnProperty("writable", new PropertyDescriptor(value: desc.Writable.HasValue && desc.Writable.Value.AsBoolean(), writable: true, enumerable: true, configurable: true), false); + obj.DefineOwnProperty("value", new PropertyDescriptor(value: desc.Value != null ? desc.Value : Native.Undefined.Instance, writable: true, enumerable: true, configurable: true ), false); + obj.DefineOwnProperty("writable", new PropertyDescriptor(value: desc.Writable.HasValue && desc.Writable.Value, writable: true, enumerable: true, configurable: true), false); } else { @@ -191,8 +181,8 @@ public static JsValue FromPropertyDescriptor(Engine engine, PropertyDescriptor d obj.DefineOwnProperty("set", new PropertyDescriptor(desc.Set ?? Native.Undefined.Instance, writable: true, enumerable: true, configurable: true), false); } - obj.DefineOwnProperty("enumerable", new PropertyDescriptor(value: desc.Enumerable.HasValue && desc.Enumerable.Value.AsBoolean(), writable: true, enumerable: true, configurable: true), false); - obj.DefineOwnProperty("configurable", new PropertyDescriptor(value: desc.Configurable.HasValue && desc.Configurable.Value.AsBoolean(), writable: true, enumerable: true, configurable: true), false); + obj.DefineOwnProperty("enumerable", new PropertyDescriptor(value: desc.Enumerable.HasValue && desc.Enumerable.Value, writable: true, enumerable: true, configurable: true), false); + obj.DefineOwnProperty("configurable", new PropertyDescriptor(value: desc.Configurable.HasValue && desc.Configurable.Value, writable: true, enumerable: true, configurable: true), false); return obj; } diff --git a/Jint/Runtime/Descriptors/Specialized/FieldInfoDescriptor.cs b/Jint/Runtime/Descriptors/Specialized/FieldInfoDescriptor.cs index d22666dde2..eb34c7d7b4 100644 --- a/Jint/Runtime/Descriptors/Specialized/FieldInfoDescriptor.cs +++ b/Jint/Runtime/Descriptors/Specialized/FieldInfoDescriptor.cs @@ -19,7 +19,7 @@ public FieldInfoDescriptor(Engine engine, FieldInfo fieldInfo, object item) Writable = !fieldInfo.Attributes.HasFlag(FieldAttributes.InitOnly); // don't write to fields marked as readonly } - public override JsValue? Value + public override JsValue Value { get { @@ -28,7 +28,7 @@ public override JsValue? Value set { - var currentValue = value.GetValueOrDefault(); + var currentValue = value; object obj; if (_fieldInfo.FieldType == typeof (JsValue)) { @@ -40,10 +40,10 @@ public override JsValue? Value obj = currentValue.ToObject(); if (obj.GetType() != _fieldInfo.FieldType) { - obj = _engine.Options.GetTypeConverter().Convert(obj, _fieldInfo.FieldType, CultureInfo.InvariantCulture); + obj = _engine.ClrTypeConverter.Convert(obj, _fieldInfo.FieldType, CultureInfo.InvariantCulture); } } - + _fieldInfo.SetValue(_item, obj); } } diff --git a/Jint/Runtime/Descriptors/Specialized/IndexDescriptor.cs b/Jint/Runtime/Descriptors/Specialized/IndexDescriptor.cs index 59ed4b64c4..2018315d70 100644 --- a/Jint/Runtime/Descriptors/Specialized/IndexDescriptor.cs +++ b/Jint/Runtime/Descriptors/Specialized/IndexDescriptor.cs @@ -1,4 +1,5 @@ -using System.Globalization; +using System; +using System.Globalization; using System.Reflection; using Jint.Native; @@ -9,35 +10,92 @@ public sealed class IndexDescriptor : PropertyDescriptor private readonly Engine _engine; private readonly object _key; private readonly object _item; - private readonly MethodInfo _getter; - private readonly MethodInfo _setter; + private readonly PropertyInfo _indexer; + private readonly MethodInfo _containsKey; - public IndexDescriptor(Engine engine, string key, object item) + public IndexDescriptor(Engine engine, Type targetType, string key, object item) { _engine = engine; _item = item; - _getter = item.GetType().GetMethod("get_Item", BindingFlags.Instance | BindingFlags.Public); - _setter = item.GetType().GetMethod("set_Item", BindingFlags.Instance | BindingFlags.Public); + // get all instance indexers with exactly 1 argument + var indexers = targetType.GetProperties(); + + // try to find first indexer having either public getter or setter with matching argument type + foreach (var indexer in indexers) + { + if (indexer.GetIndexParameters().Length != 1) continue; + if (indexer.GetGetMethod() != null || indexer.GetSetMethod() != null) + { + var paramType = indexer.GetIndexParameters()[0].ParameterType; - _key = _engine.Options.GetTypeConverter().Convert(key, _getter.GetParameters()[0].ParameterType, CultureInfo.InvariantCulture); + if (_engine.ClrTypeConverter.TryConvert(key, paramType, CultureInfo.InvariantCulture, out _key)) + { + _indexer = indexer; + // get contains key method to avoid index exception being thrown in dictionaries + _containsKey = targetType.GetMethod("ContainsKey", new Type[] { paramType }); + break; + + } + } + } + + // throw if no indexer found + if (_indexer == null) + { + throw new InvalidOperationException("No matching indexer found."); + } Writable = true; } - public override JsValue? Value + + public IndexDescriptor(Engine engine, string key, object item) + : this(engine, item.GetType(), key, item) + { + } + + public override JsValue Value { get { + var getter = _indexer.GetGetMethod(); + + if (getter == null) + { + throw new InvalidOperationException("Indexer has no public getter."); + } + object[] parameters = { _key }; - return JsValue.FromObject(_engine, _getter.Invoke(_item, parameters)); + + if (_containsKey != null) + { + if ((_containsKey.Invoke(_item, parameters) as bool?) != true) + { + return JsValue.Undefined; + } + } + + try + { + return JsValue.FromObject(_engine, getter.Invoke(_item, parameters)); + } + catch + { + return JsValue.Undefined; + } } set { - var defaultValue = _item.GetType().IsValueType ? System.Activator.CreateInstance(_item.GetType()) : null; - object[] parameters = { _key, value.HasValue ? value.Value.ToObject() : null }; - _setter.Invoke(_item, parameters); + var setter = _indexer.GetSetMethod(); + if (setter == null) + { + throw new InvalidOperationException("Indexer has no public setter."); + } + + object[] parameters = { _key, value != null ? value.ToObject() : null }; + setter.Invoke(_item, parameters); } } } diff --git a/Jint/Runtime/Descriptors/Specialized/PropertyInfoDescriptor.cs b/Jint/Runtime/Descriptors/Specialized/PropertyInfoDescriptor.cs index a6267c52ce..422dfe9951 100644 --- a/Jint/Runtime/Descriptors/Specialized/PropertyInfoDescriptor.cs +++ b/Jint/Runtime/Descriptors/Specialized/PropertyInfoDescriptor.cs @@ -19,7 +19,7 @@ public PropertyInfoDescriptor(Engine engine, PropertyInfo propertyInfo, object i Writable = propertyInfo.CanWrite; } - public override JsValue? Value + public override JsValue Value { get { @@ -28,7 +28,7 @@ public override JsValue? Value set { - var currentValue = value.GetValueOrDefault(); + var currentValue = value; object obj; if (_propertyInfo.PropertyType == typeof (JsValue)) { @@ -38,12 +38,12 @@ public override JsValue? Value { // attempt to convert the JsValue to the target type obj = currentValue.ToObject(); - if (obj.GetType() != _propertyInfo.PropertyType) + if (obj != null && obj.GetType() != _propertyInfo.PropertyType) { - obj = _engine.Options.GetTypeConverter().Convert(obj, _propertyInfo.PropertyType, CultureInfo.InvariantCulture); + obj = _engine.ClrTypeConverter.Convert(obj, _propertyInfo.PropertyType, CultureInfo.InvariantCulture); } } - + _propertyInfo.SetValue(_item, obj, null); } } diff --git a/Jint/Runtime/Environments/DeclarativeEnvironmentRecord.cs b/Jint/Runtime/Environments/DeclarativeEnvironmentRecord.cs index 1b478d1551..c96c7c2852 100644 --- a/Jint/Runtime/Environments/DeclarativeEnvironmentRecord.cs +++ b/Jint/Runtime/Environments/DeclarativeEnvironmentRecord.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using Jint.Native; namespace Jint.Runtime.Environments @@ -112,5 +113,14 @@ public void InitializeImmutableBinding(string name, JsValue value) var binding = _bindings[name]; binding.Value = value; } + + /// + /// Returns an array of all the defined binding names + /// + /// The array of all defined bindings + public override string[] GetAllBindingNames() + { + return _bindings.Keys.ToArray(); + } } } diff --git a/Jint/Runtime/Environments/EnvironmentRecord.cs b/Jint/Runtime/Environments/EnvironmentRecord.cs index a5d330f435..5faf38b398 100644 --- a/Jint/Runtime/Environments/EnvironmentRecord.cs +++ b/Jint/Runtime/Environments/EnvironmentRecord.cs @@ -56,6 +56,10 @@ protected EnvironmentRecord(Engine engine) : base(engine) /// The value to use as this. public abstract JsValue ImplicitThisValue(); - + /// + /// Returns an array of all the defined binding names + /// + /// The array of all defined bindings + public abstract string[] GetAllBindingNames(); } } diff --git a/Jint/Runtime/Environments/ObjectEnvironmentRecord.cs b/Jint/Runtime/Environments/ObjectEnvironmentRecord.cs index 5200d38c89..49f7cd6e04 100644 --- a/Jint/Runtime/Environments/ObjectEnvironmentRecord.cs +++ b/Jint/Runtime/Environments/ObjectEnvironmentRecord.cs @@ -1,4 +1,5 @@ -using Jint.Native; +using System.Linq; +using Jint.Native; using Jint.Native.Object; using Jint.Runtime.Descriptors; @@ -72,5 +73,15 @@ public override JsValue ImplicitThisValue() return Undefined.Instance; } + + public override string[] GetAllBindingNames() + { + if (_bindingObject != null) + { + return _bindingObject.GetOwnProperties().Select( x=> x.Key).ToArray(); + } + + return new string[0]; + } } } diff --git a/Jint/Runtime/ExpressionIntepreter.cs b/Jint/Runtime/ExpressionIntepreter.cs index ed23c5fb11..e31a2f1db8 100644 --- a/Jint/Runtime/ExpressionIntepreter.cs +++ b/Jint/Runtime/ExpressionIntepreter.cs @@ -3,9 +3,11 @@ using Jint.Native; using Jint.Native.Function; using Jint.Native.Number; +using Jint.Native.Object; using Jint.Parser.Ast; using Jint.Runtime.Descriptors; using Jint.Runtime.Environments; +using Jint.Runtime.Interop; using Jint.Runtime.References; namespace Jint.Runtime @@ -41,9 +43,8 @@ public JsValue EvaluateConditionalExpression(ConditionalExpression conditionalEx public JsValue EvaluateAssignmentExpression(AssignmentExpression assignmentExpression) { - JsValue rval = _engine.GetValue(EvaluateExpression(assignmentExpression.Right)); - var lref = EvaluateExpression(assignmentExpression.Left) as Reference; + JsValue rval = _engine.GetValue(EvaluateExpression(assignmentExpression.Right)); if (lref == null) { @@ -52,7 +53,7 @@ public JsValue EvaluateAssignmentExpression(AssignmentExpression assignmentExpre if (assignmentExpression.Operator == AssignmentOperator.Assign) // "=" { - + if(lref.IsStrict() && lref.GetBase().TryCast() != null && (lref.GetReferencedName() == "eval" || lref.GetReferencedName() == "arguments")) { throw new JavaScriptException(_engine.SyntaxError); @@ -132,7 +133,7 @@ public JsValue EvaluateAssignmentExpression(AssignmentExpression assignmentExpre case AssignmentOperator.UnsignedRightShiftAssign: lval = (uint)TypeConverter.ToInt32(lval) >> (int)(TypeConverter.ToUint32(rval) & 0x1F); break; - + default: throw new NotImplementedException(); @@ -195,11 +196,14 @@ private JsValue Divide(JsValue lval, JsValue rval) public JsValue EvaluateBinaryExpression(BinaryExpression expression) { - JsValue left = _engine.GetValue(EvaluateExpression(expression.Left)); - JsValue right = _engine.GetValue(EvaluateExpression(expression.Right)); + var leftExpression = EvaluateExpression(expression.Left); + JsValue left = _engine.GetValue(leftExpression); + + var rightExpression = EvaluateExpression(expression.Right); + JsValue right = _engine.GetValue(rightExpression); + JsValue value; - switch (expression.Operator) { case BinaryOperator.Plus: @@ -214,11 +218,11 @@ public JsValue EvaluateBinaryExpression(BinaryExpression expression) value = TypeConverter.ToNumber(lprim) + TypeConverter.ToNumber(rprim); } break; - + case BinaryOperator.Minus: value = TypeConverter.ToNumber(left) - TypeConverter.ToNumber(right); break; - + case BinaryOperator.Times: if (left == Undefined.Instance || right == Undefined.Instance) { @@ -229,7 +233,7 @@ public JsValue EvaluateBinaryExpression(BinaryExpression expression) value = TypeConverter.ToNumber(left) * TypeConverter.ToNumber(right); } break; - + case BinaryOperator.Divide: value = Divide(left, right); break; @@ -248,11 +252,11 @@ public JsValue EvaluateBinaryExpression(BinaryExpression expression) case BinaryOperator.Equal: value = Equal(left, right); break; - + case BinaryOperator.NotEqual: value = !Equal(left, right); break; - + case BinaryOperator.Greater: value = Compare(right, left, false); if (value == Undefined.Instance) @@ -272,7 +276,7 @@ public JsValue EvaluateBinaryExpression(BinaryExpression expression) value = true; } break; - + case BinaryOperator.Less: value = Compare(left, right); if (value == Undefined.Instance) @@ -280,7 +284,7 @@ public JsValue EvaluateBinaryExpression(BinaryExpression expression) value = false; } break; - + case BinaryOperator.LessOrEqual: value = Compare(right, left, false); if (value == Undefined.Instance || value.AsBoolean()) @@ -292,10 +296,10 @@ public JsValue EvaluateBinaryExpression(BinaryExpression expression) value = true; } break; - + case BinaryOperator.StrictlyEqual: return StrictlyEqual(left, right); - + case BinaryOperator.StricltyNotEqual: return !StrictlyEqual(left, right); @@ -327,7 +331,7 @@ public JsValue EvaluateBinaryExpression(BinaryExpression expression) value = f.HasInstance(left); break; - + case BinaryOperator.In: if (!right.IsObject()) { @@ -336,7 +340,7 @@ public JsValue EvaluateBinaryExpression(BinaryExpression expression) value = right.AsObject().HasProperty(TypeConverter.ToString(left)); break; - + default: throw new NotImplementedException(); } @@ -379,40 +383,7 @@ public static bool Equal(JsValue x, JsValue y) if (typex == typey) { - if (typex == Types.Undefined || typex == Types.Null) - { - return true; - } - - if (typex == Types.Number) - { - var nx = TypeConverter.ToNumber(x); - var ny = TypeConverter.ToNumber(y); - - if (double.IsNaN(nx) || double.IsNaN(ny)) - { - return false; - } - - if (nx.Equals(ny)) - { - return true; - } - - return false; - } - - if (typex == Types.String) - { - return TypeConverter.ToString(x) == TypeConverter.ToString(y); - } - - if (typex == Types.Boolean) - { - return x.AsBoolean() == y.AsBoolean(); - } - - return x == y; + return StrictlyEqual(x, y); } if (x == Null.Instance && y == Undefined.Instance) @@ -477,10 +448,11 @@ public static bool StrictlyEqual(JsValue x, JsValue y) { return true; } + if (typea == Types.Number) { - var nx = TypeConverter.ToNumber(x); - var ny = TypeConverter.ToNumber(y); + var nx = x.AsNumber(); + var ny = y.AsNumber(); if (double.IsNaN(nx) || double.IsNaN(ny)) { @@ -494,14 +466,28 @@ public static bool StrictlyEqual(JsValue x, JsValue y) return false; } + if (typea == Types.String) { - return TypeConverter.ToString(x) == TypeConverter.ToString(y); + return x.AsString() == y.AsString(); } + if (typea == Types.Boolean) { - return TypeConverter.ToBoolean(x) == TypeConverter.ToBoolean(y); + return x.AsBoolean() == y.AsBoolean(); } + + if (typea == Types.Object) + { + var xw = x.AsObject() as IObjectWrapper; + + if (xw != null) + { + var yw = y.AsObject() as IObjectWrapper; + return Object.Equals(xw.Target, yw.Target); + } + } + return x == y; } @@ -623,12 +609,30 @@ public Reference EvaluateIdentifier(Identifier identifier) public JsValue EvaluateLiteral(Literal literal) { + if(literal.Cached) + { + return literal.CachedValue; + } + if (literal.Type == SyntaxNodes.RegularExpressionLiteral) { - return _engine.RegExp.Construct(literal.Raw); + var regexp = _engine.RegExp.Construct(literal.Raw); + + if (regexp.Global) + { + // A Global regexp literal can't be cached or its state would evolve + return regexp; + } + + literal.CachedValue = regexp; + } + else + { + literal.CachedValue = JsValue.FromObject(_engine, literal.Value); } - return JsValue.FromObject(_engine, literal.Value); + literal.Cached = true; + return literal.CachedValue; } public JsValue EvaluateObjectExpression(ObjectExpression objectExpression) @@ -658,20 +662,20 @@ public JsValue EvaluateObjectExpression(ObjectExpression objectExpression) throw new JavaScriptException(_engine.SyntaxError); } - ScriptFunctionInstance get; + ScriptFunctionInstance get; using (new StrictModeScope(getter.Strict)) { get = new ScriptFunctionInstance( _engine, getter, - _engine.ExecutionContext.LexicalEnvironment, + _engine.ExecutionContext.LexicalEnvironment, StrictModeScope.IsStrictModeCode ); } propDesc = new PropertyDescriptor(get: get, set: null, enumerable: true, configurable:true); break; - + case PropertyKind.Set: var setter = property.Value as FunctionExpression; @@ -683,7 +687,7 @@ public JsValue EvaluateObjectExpression(ObjectExpression objectExpression) ScriptFunctionInstance set; using (new StrictModeScope(setter.Strict)) { - + set = new ScriptFunctionInstance( _engine, setter, @@ -717,12 +721,12 @@ public JsValue EvaluateObjectExpression(ObjectExpression objectExpression) if (previous.IsAccessorDescriptor() && propDesc.IsAccessorDescriptor()) { - if (propDesc.Set.HasValue && previous.Set.HasValue) + if (propDesc.Set != null && previous.Set != null) { throw new JavaScriptException(_engine.SyntaxError); } - if (propDesc.Get.HasValue && previous.Get.HasValue) + if (propDesc.Get != null && previous.Get != null) { throw new JavaScriptException(_engine.SyntaxError); } @@ -746,7 +750,7 @@ public Reference EvaluateMemberExpression(MemberExpression memberExpression) var baseValue = _engine.GetValue(baseReference); Expression expression = memberExpression.Property; - + if (!memberExpression.Computed) // index accessor ? { expression = new Literal { Type = SyntaxNodes.Literal, Value = memberExpression.Property.As().Name }; @@ -754,7 +758,7 @@ public Reference EvaluateMemberExpression(MemberExpression memberExpression) var propertyNameReference = EvaluateExpression(expression); var propertyNameValue = _engine.GetValue(propertyNameReference); - TypeConverter.CheckObjectCoercible(_engine, baseValue); + TypeConverter.CheckObjectCoercible(_engine, baseValue, memberExpression, baseReference); var propertyNameString = TypeConverter.ToString(propertyNameValue); return new Reference(baseValue, propertyNameString, StrictModeScope.IsStrictModeCode); @@ -789,23 +793,72 @@ public JsValue EvaluateCallExpression(CallExpression callExpression) { var callee = EvaluateExpression(callExpression.Callee); + if (_engine.Options._IsDebugMode) + { + _engine.DebugHandler.AddToDebugCallStack(callExpression); + } + JsValue thisObject; // todo: implement as in http://www.ecma-international.org/ecma-262/5.1/#sec-11.2.4 - var arguments = callExpression.Arguments.Select(EvaluateExpression).Select(_engine.GetValue).ToArray(); + + + JsValue[] arguments; + + if (callExpression.Cached) + { + arguments = callExpression.CachedArguments; + } + else + { + arguments = callExpression.Arguments.Select(EvaluateExpression).Select(_engine.GetValue).ToArray(); + + if (callExpression.CanBeCached) + { + // The arguments array can be cached if they are all literals + if (callExpression.Arguments.All(x => x is Literal)) + { + callExpression.CachedArguments = arguments; + callExpression.Cached = true; + } + else + { + callExpression.CanBeCached = false; + } + } + } var func = _engine.GetValue(callee); var r = callee as Reference; + if (_engine.Options._MaxRecursionDepth >= 0) + { + var stackItem = new CallStackElement(callExpression, func, r != null ? r.GetReferencedName() : "anonymous function"); + + var recursionDepth = _engine.CallStack.Push(stackItem); + + if (recursionDepth > _engine.Options._MaxRecursionDepth) + { + _engine.CallStack.Pop(); + throw new RecursionDepthOverflowException(_engine.CallStack, stackItem.ToString()); + } + } + if (func == Undefined.Instance) { - throw new JavaScriptException(_engine.TypeError, r == null ? "" : string.Format("Object has no method '{0}'", (callee as Reference).GetReferencedName())); + throw new JavaScriptException(_engine.TypeError, r == null ? "" : string.Format("Object has no method '{0}'", r.GetReferencedName())); } if (!func.IsObject()) { - throw new JavaScriptException(_engine.TypeError, r == null ? "" : string.Format("Property '{0}' of object is not a function", (callee as Reference).GetReferencedName())); + + if (_engine.Options._ReferenceResolver == null || + !_engine.Options._ReferenceResolver.TryGetCallable(_engine, callee, out func)) + { + throw new JavaScriptException(_engine.TypeError, + r == null ? "" : string.Format("Property '{0}' of object is not a function", r.GetReferencedName())); + } } var callable = func.TryCast(); @@ -813,7 +866,7 @@ public JsValue EvaluateCallExpression(CallExpression callExpression) { throw new JavaScriptException(_engine.TypeError); } - + if (r != null) { if (r.IsPropertyReference()) @@ -836,8 +889,20 @@ public JsValue EvaluateCallExpression(CallExpression callExpression) { return ((EvalFunctionInstance) callable).Call(thisObject, arguments, true); } - - return callable.Call(thisObject, arguments); + + var result = callable.Call(thisObject, arguments); + + if (_engine.Options._IsDebugMode) + { + _engine.DebugHandler.PopDebugCallStack(); + } + + if (_engine.Options._MaxRecursionDepth >= 0) + { + _engine.CallStack.Pop(); + } + + return result; } public JsValue EvaluateSequenceExpression(SequenceExpression sequenceExpression) @@ -903,10 +968,10 @@ public JsValue EvaluateThisExpression(ThisExpression thisExpression) public JsValue EvaluateNewExpression(NewExpression newExpression) { var arguments = newExpression.Arguments.Select(EvaluateExpression).Select(_engine.GetValue).ToArray(); - + // todo: optimize by defining a common abstract class or interface var callee = _engine.GetValue(EvaluateExpression(newExpression.Callee)).TryCast(); - + if (callee == null) { throw new JavaScriptException(_engine.TypeError, "The object can't be used as constructor."); @@ -932,7 +997,7 @@ public JsValue EvaluateArrayExpression(ArrayExpression arrayExpression) } n++; } - + return a; } @@ -945,17 +1010,17 @@ public JsValue EvaluateUnaryExpression(UnaryExpression unaryExpression) { case UnaryOperator.Plus: return TypeConverter.ToNumber(_engine.GetValue(value)); - + case UnaryOperator.Minus: var n = TypeConverter.ToNumber(_engine.GetValue(value)); return double.IsNaN(n) ? double.NaN : n*-1; - + case UnaryOperator.BitwiseNot: return ~TypeConverter.ToInt32(_engine.GetValue(value)); - + case UnaryOperator.LogicalNot: return !TypeConverter.ToBoolean(_engine.GetValue(value)); - + case UnaryOperator.Delete: r = value as Reference; if (r == null) @@ -982,7 +1047,7 @@ public JsValue EvaluateUnaryExpression(UnaryExpression unaryExpression) } var bindings = r.GetBase().TryCast(); return bindings.DeleteBinding(r.GetReferencedName()); - + case UnaryOperator.Void: _engine.GetValue(value); return Undefined.Instance; diff --git a/Jint/Runtime/Interop/ClrFunctionInstance.cs b/Jint/Runtime/Interop/ClrFunctionInstance.cs index a3f4ff965b..fedeb59c7d 100644 --- a/Jint/Runtime/Interop/ClrFunctionInstance.cs +++ b/Jint/Runtime/Interop/ClrFunctionInstance.cs @@ -17,6 +17,7 @@ public ClrFunctionInstance(Engine engine, Func func _func = func; Prototype = engine.Function.PrototypeObject; FastAddProperty("length", length, false, false, false); + Extensible = true; } public ClrFunctionInstance(Engine engine, Func func) diff --git a/Jint/Runtime/Interop/DefaultTypeConverter.cs b/Jint/Runtime/Interop/DefaultTypeConverter.cs index d7636a1af2..4ab2614572 100644 --- a/Jint/Runtime/Interop/DefaultTypeConverter.cs +++ b/Jint/Runtime/Interop/DefaultTypeConverter.cs @@ -1,20 +1,49 @@ using System; +using System.Collections.ObjectModel; +using System.Linq; +using System.Linq.Expressions; +using Jint.Native; +using System.Collections.Generic; +using System.Reflection; namespace Jint.Runtime.Interop { public class DefaultTypeConverter : ITypeConverter { - public object Convert(object value, Type type, IFormatProvider formatProvider) + private readonly Engine _engine; + private static readonly Dictionary _knownConversions = new Dictionary(); + private static readonly object _lockObject = new object(); + + private static MethodInfo convertChangeType = typeof(System.Convert).GetMethod("ChangeType", new Type[] { typeof(object), typeof(Type), typeof(IFormatProvider) }); + private static MethodInfo jsValueFromObject = typeof(JsValue).GetMethod("FromObject"); + private static MethodInfo jsValueToObject = typeof(JsValue).GetMethod("ToObject"); + + public DefaultTypeConverter(Engine engine) { + _engine = engine; + } + + public virtual object Convert(object value, Type type, IFormatProvider formatProvider) + { + if (value == null) + { + if (TypeConverter.TypeIsNullable(type)) + { + return null; + } + + throw new NotSupportedException(string.Format("Unable to convert null to '{0}'", type.FullName)); + } + // don't try to convert if value is derived from type if (type.IsInstanceOfType(value)) { return value; } - if (type.IsEnum) + if (type.IsEnum()) { - var integer = System.Convert.ChangeType(value, typeof (int), formatProvider); + var integer = System.Convert.ChangeType(value, typeof(int), formatProvider); if (integer == null) { throw new ArgumentOutOfRangeException(); @@ -23,7 +52,190 @@ public object Convert(object value, Type type, IFormatProvider formatProvider) return Enum.ToObject(type, integer); } + var valueType = value.GetType(); + // is the javascript value an ICallable instance ? + if (valueType == typeof(Func)) + { + var function = (Func)value; + + if (type.IsGenericType()) + { + var genericType = type.GetGenericTypeDefinition(); + + // create the requested Delegate + if (genericType.Name.StartsWith("Action")) + { + var genericArguments = type.GetGenericArguments(); + + var @params = new ParameterExpression[genericArguments.Count()]; + for (var i = 0; i < @params.Count(); i++) + { + @params[i] = Expression.Parameter(genericArguments[i], genericArguments[i].Name + i); + } + var tmpVars = new Expression[@params.Length]; + for (var i = 0; i < @params.Count(); i++) + { + var param = @params[i]; + if (param.Type.IsValueType()) + { + var boxing = Expression.Convert(param, typeof(object)); + tmpVars[i] = Expression.Call(null, jsValueFromObject, Expression.Constant(_engine, typeof(Engine)), boxing); + } + else + { + tmpVars[i] = Expression.Call(null, jsValueFromObject, Expression.Constant(_engine, typeof(Engine)), param); + } + } + var @vars = Expression.NewArrayInit(typeof(JsValue), tmpVars); + + var callExpresion = Expression.Block(Expression.Call( + Expression.Call(Expression.Constant(function.Target), + function.GetMethodInfo(), + Expression.Constant(JsValue.Undefined, typeof(JsValue)), + @vars), + jsValueToObject), Expression.Empty()); + + return Expression.Lambda(callExpresion, new ReadOnlyCollection(@params)).Compile(); + } + else if (genericType.Name.StartsWith("Func")) + { + var genericArguments = type.GetGenericArguments(); + var returnType = genericArguments.Last(); + + var @params = new ParameterExpression[genericArguments.Count() - 1]; + for (var i = 0; i < @params.Count(); i++) + { + @params[i] = Expression.Parameter(genericArguments[i], genericArguments[i].Name + i); + } + + var @vars = + Expression.NewArrayInit(typeof(JsValue), + @params.Select(p => + { + var boxingExpression = Expression.Convert(p, typeof(object)); + return Expression.Call(null, jsValueFromObject, Expression.Constant(_engine, typeof(Engine)), boxingExpression); + }) + ); + + // the final result's type needs to be changed before casting, + // for instance when a function returns a number (double) but C# expects an integer + + var callExpresion = Expression.Convert( + Expression.Call(null, + convertChangeType, + Expression.Call( + Expression.Call(Expression.Constant(function.Target), + function.GetMethodInfo(), + Expression.Constant(JsValue.Undefined, typeof(JsValue)), + @vars), + jsValueToObject), + Expression.Constant(returnType, typeof(Type)), + Expression.Constant(System.Globalization.CultureInfo.InvariantCulture, typeof(IFormatProvider)) + ), + returnType); + + return Expression.Lambda(callExpresion, new ReadOnlyCollection(@params)).Compile(); + } + } + else + { + if (type == typeof(Action)) + { + return (Action)(() => function(JsValue.Undefined, new JsValue[0])); + } + else if (typeof(MulticastDelegate).IsAssignableFrom(type)) + { + var method = type.GetMethod("Invoke"); + var arguments = method.GetParameters(); + + var @params = new ParameterExpression[arguments.Count()]; + for (var i = 0; i < @params.Count(); i++) + { + @params[i] = Expression.Parameter(typeof(object), arguments[i].Name); + } + var @vars = Expression.NewArrayInit(typeof(JsValue), @params.Select(p => Expression.Call(null, typeof(JsValue).GetMethod("FromObject"), Expression.Constant(_engine, typeof(Engine)), p))); + + var callExpression = Expression.Block( + Expression.Call( + Expression.Call(Expression.Constant(function.Target), + function.GetMethodInfo(), + Expression.Constant(JsValue.Undefined, typeof(JsValue)), + @vars), + typeof(JsValue).GetMethod("ToObject")), + Expression.Empty()); + + var dynamicExpression = Expression.Invoke(Expression.Lambda(callExpression, new ReadOnlyCollection(@params)), new ReadOnlyCollection(@params)); + + return Expression.Lambda(type, dynamicExpression, new ReadOnlyCollection(@params)).Compile(); + } + } + + } + + if (type.IsArray) + { + var source = value as object[]; + if (source == null) + throw new ArgumentException(String.Format("Value of object[] type is expected, but actual type is {0}.", value.GetType())); + + var targetElementType = type.GetElementType(); + var itemsConverted = source.Select(o => Convert(o, targetElementType, formatProvider)).ToArray(); + var result = Array.CreateInstance(targetElementType, source.Length); + itemsConverted.CopyTo(result, 0); + return result; + } + + if (type.IsGenericType() && type.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + type = Nullable.GetUnderlyingType(type); + } + return System.Convert.ChangeType(value, type, formatProvider); } + + public virtual bool TryConvert(object value, Type type, IFormatProvider formatProvider, out object converted) + { + bool canConvert; + var key = value == null ? String.Format("Null->{0}", type) : String.Format("{0}->{1}", value.GetType(), type); + + if (!_knownConversions.TryGetValue(key, out canConvert)) + { + lock (_lockObject) + { + if (!_knownConversions.TryGetValue(key, out canConvert)) + { + try + { + converted = Convert(value, type, formatProvider); + _knownConversions.Add(key, true); + return true; + } + catch + { + converted = null; + _knownConversions.Add(key, false); + return false; + } + } + } + } + + if (canConvert) + { + try + { + converted = Convert(value, type, formatProvider); + return true; + } + catch + { + converted = null; + return false; + } + } + + converted = null; + return false; + } } } diff --git a/Jint/Runtime/Interop/DelegateWrapper.cs b/Jint/Runtime/Interop/DelegateWrapper.cs index 3253016075..11a66d54b4 100644 --- a/Jint/Runtime/Interop/DelegateWrapper.cs +++ b/Jint/Runtime/Interop/DelegateWrapper.cs @@ -1,6 +1,7 @@ -using System; +using System; using System.Globalization; using System.Linq; +using System.Reflection; using Jint.Native; using Jint.Native.Function; @@ -17,35 +18,44 @@ public sealed class DelegateWrapper : FunctionInstance public DelegateWrapper(Engine engine, Delegate d) : base(engine, null, null, false) { _d = d; + Prototype = engine.Function.PrototypeObject; } - public override JsValue Call(JsValue thisObject, JsValue[] arguments) + public override JsValue Call(JsValue thisObject, JsValue[] jsArguments) { - var parameterInfos = _d.Method.GetParameters(); + var parameterInfos = _d.GetMethodInfo().GetParameters(); - // convert parameter to expected types - var parameters = new object[parameterInfos.Length]; - for (var i = 0; i < arguments.Length; i++) + bool delegateContainsParamsArgument = parameterInfos.Any(p => p.HasAttribute()); + int delegateArgumentsCount = parameterInfos.Length; + int delegateNonParamsArgumentsCount = delegateContainsParamsArgument ? delegateArgumentsCount - 1 : delegateArgumentsCount; + + int jsArgumentsCount = jsArguments.Length; + int jsArgumentsWithoutParamsCount = Math.Min(jsArgumentsCount, delegateNonParamsArgumentsCount); + + var parameters = new object[delegateArgumentsCount]; + + // convert non params parameter to expected types + for (var i = 0; i < jsArgumentsWithoutParamsCount; i++) { var parameterType = parameterInfos[i].ParameterType; if (parameterType == typeof (JsValue)) { - parameters[i] = arguments[i]; + parameters[i] = jsArguments[i]; } else { - parameters[i] = Engine.Options.GetTypeConverter().Convert( - arguments[i].ToObject(), + parameters[i] = Engine.ClrTypeConverter.Convert( + jsArguments[i].ToObject(), parameterType, CultureInfo.InvariantCulture); } } // assign null to parameters not provided - for (var i = arguments.Length; i < parameterInfos.Length; i++) + for (var i = jsArgumentsWithoutParamsCount; i < delegateNonParamsArgumentsCount; i++) { - if (parameterInfos[i].ParameterType.IsValueType) + if (parameterInfos[i].ParameterType.IsValueType()) { parameters[i] = Activator.CreateInstance(parameterInfos[i].ParameterType); } @@ -55,7 +65,49 @@ public override JsValue Call(JsValue thisObject, JsValue[] arguments) } } - return JsValue.FromObject(Engine, _d.DynamicInvoke(parameters)); + // assign params to array and converts each objet to expected type + if(delegateContainsParamsArgument) + { + int paramsArgumentIndex = delegateArgumentsCount - 1; + int paramsCount = Math.Max(0, jsArgumentsCount - delegateNonParamsArgumentsCount); + + object[] paramsParameter = new object[paramsCount]; + var paramsParameterType = parameterInfos[paramsArgumentIndex].ParameterType.GetElementType(); + + for (var i = paramsArgumentIndex; i < jsArgumentsCount; i++) + { + var paramsIndex = i - paramsArgumentIndex; + + if (paramsParameterType == typeof(JsValue)) + { + paramsParameter[paramsIndex] = jsArguments[i]; + } + else + { + paramsParameter[paramsIndex] = Engine.ClrTypeConverter.Convert( + jsArguments[i].ToObject(), + paramsParameterType, + CultureInfo.InvariantCulture); + } + } + parameters[paramsArgumentIndex] = paramsParameter; + } + try + { + return JsValue.FromObject(Engine, _d.DynamicInvoke(parameters)); + } + catch (TargetInvocationException exception) + { + var meaningfulException = exception.InnerException ?? exception; + var handler = Engine.Options._ClrExceptionsHandler; + + if (handler != null && handler(meaningfulException)) + { + throw new JavaScriptException(Engine.Error, meaningfulException.Message); + } + + throw meaningfulException; + } } } } diff --git a/Jint/Runtime/Interop/IObjectWrapper.cs b/Jint/Runtime/Interop/IObjectWrapper.cs index e8b7496ba8..cbc3d44c5b 100644 --- a/Jint/Runtime/Interop/IObjectWrapper.cs +++ b/Jint/Runtime/Interop/IObjectWrapper.cs @@ -1,11 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Jint.Runtime.Interop +namespace Jint.Runtime.Interop { - public interface IObjectWrapper + public interface IObjectWrapper { object Target { get; } } diff --git a/Jint/Runtime/Interop/IReferenceResolver.cs b/Jint/Runtime/Interop/IReferenceResolver.cs new file mode 100644 index 0000000000..5601d71fae --- /dev/null +++ b/Jint/Runtime/Interop/IReferenceResolver.cs @@ -0,0 +1,13 @@ +using Jint.Native; +using Jint.Runtime.References; + +namespace Jint.Runtime.Interop +{ + public interface IReferenceResolver + { + bool TryUnresolvableReference(Engine engine, Reference reference, out JsValue value); + bool TryPropertyReference(Engine engine, Reference reference, ref JsValue value); + bool TryGetCallable(Engine engine, object callee, out JsValue value); + bool CheckCoercible(JsValue value); + } +} \ No newline at end of file diff --git a/Jint/Runtime/Interop/ITypeConverter.cs b/Jint/Runtime/Interop/ITypeConverter.cs index beb9406161..c52f15484e 100644 --- a/Jint/Runtime/Interop/ITypeConverter.cs +++ b/Jint/Runtime/Interop/ITypeConverter.cs @@ -5,5 +5,6 @@ namespace Jint.Runtime.Interop public interface ITypeConverter { object Convert(object value, Type type, IFormatProvider formatProvider); + bool TryConvert(object value, Type type, IFormatProvider formatProvider, out object converted); } } diff --git a/Jint/Runtime/Interop/MethodInfoFunctionInstance.cs b/Jint/Runtime/Interop/MethodInfoFunctionInstance.cs index 4c29ae3dbe..38d8bfa839 100644 --- a/Jint/Runtime/Interop/MethodInfoFunctionInstance.cs +++ b/Jint/Runtime/Interop/MethodInfoFunctionInstance.cs @@ -1,7 +1,11 @@ -using System.Globalization; +using System; +using System.Collections.Generic; +using System.Globalization; using System.Linq; +using System.Linq.Expressions; using System.Reflection; using Jint.Native; +using Jint.Native.Array; using Jint.Native.Function; namespace Jint.Runtime.Interop @@ -22,46 +26,115 @@ public override JsValue Call(JsValue thisObject, JsValue[] arguments) return Invoke(_methods, thisObject, arguments); } - public JsValue Invoke(MethodInfo[] methodInfos, JsValue thisObject, JsValue[] arguments) + public JsValue Invoke(MethodInfo[] methodInfos, JsValue thisObject, JsValue[] jsArguments) { + var arguments = ProcessParamsArrays(jsArguments, methodInfos); var methods = TypeConverter.FindBestMatch(Engine, methodInfos, arguments).ToList(); + var converter = Engine.ClrTypeConverter; foreach (var method in methods) { var parameters = new object[arguments.Length]; - try + var argumentsMatch = true; + + for (var i = 0; i < arguments.Length; i++) { - for (var i = 0; i < arguments.Length; i++) + var parameterType = method.GetParameters()[i].ParameterType; + + if (parameterType == typeof(JsValue)) + { + parameters[i] = arguments[i]; + } + else if (parameterType == typeof(JsValue[]) && arguments[i].IsArray()) { - var parameterType = method.GetParameters()[i].ParameterType; + // Handle specific case of F(params JsValue[]) + + var arrayInstance = arguments[i].AsArray(); + var len = TypeConverter.ToInt32(arrayInstance.Get("length")); + var result = new JsValue[len]; + for (var k = 0; k < len; k++) + { + var pk = k.ToString(); + result[k] = arrayInstance.HasProperty(pk) + ? arrayInstance.Get(pk) + : JsValue.Undefined; + } - if (parameterType == typeof(JsValue)) + parameters[i] = result; + } + else + { + if (!converter.TryConvert(arguments[i].ToObject(), parameterType, CultureInfo.InvariantCulture, out parameters[i])) { - parameters[i] = arguments[i]; + argumentsMatch = false; + break; } - else + + var lambdaExpression = parameters[i] as LambdaExpression; + if (lambdaExpression != null) { - parameters[i] = Engine.Options.GetTypeConverter().Convert( - arguments[i].ToObject(), - parameterType, - CultureInfo.InvariantCulture); + parameters[i] = lambdaExpression.Compile(); } } + } - var result = JsValue.FromObject(Engine, method.Invoke(thisObject.ToObject(), parameters.ToArray())); - - // todo: cache method info + if (!argumentsMatch) + { + continue; + } - return result; + // todo: cache method info + try + { + return JsValue.FromObject(Engine, method.Invoke(thisObject.ToObject(), parameters.ToArray())); } - catch + catch (TargetInvocationException exception) { - // ignore method + var meaningfulException = exception.InnerException ?? exception; + var handler = Engine.Options._ClrExceptionsHandler; + + if (handler != null && handler(meaningfulException)) + { + throw new JavaScriptException(Engine.Error, meaningfulException.Message); + } + + throw meaningfulException; } } throw new JavaScriptException(Engine.TypeError, "No public methods with the specified arguments were found."); } + /// + /// Reduces a flat list of parameters to a params array + /// + private JsValue[] ProcessParamsArrays(JsValue[] jsArguments, IEnumerable methodInfos) + { + foreach (var methodInfo in methodInfos) + { + var parameters = methodInfo.GetParameters(); + if (!parameters.Any(p => p.HasAttribute())) + continue; + + var nonParamsArgumentsCount = parameters.Length - 1; + if (jsArguments.Length < nonParamsArgumentsCount) + continue; + + var newArgumentsCollection = jsArguments.Take(nonParamsArgumentsCount).ToList(); + var argsToTransform = jsArguments.Skip(nonParamsArgumentsCount).ToList(); + + if (argsToTransform.Count == 1 && argsToTransform.FirstOrDefault().IsArray()) + continue; + + var jsArray = Engine.Array.Construct(Arguments.Empty); + Engine.Array.PrototypeObject.Push(jsArray, argsToTransform.ToArray()); + + newArgumentsCollection.Add(new JsValue(jsArray)); + return newArgumentsCollection.ToArray(); + } + + return jsArguments; + } + } } diff --git a/Jint/Runtime/Interop/NamespaceReference.cs b/Jint/Runtime/Interop/NamespaceReference.cs index 79fe78aecd..f920dcbfa1 100644 --- a/Jint/Runtime/Interop/NamespaceReference.cs +++ b/Jint/Runtime/Interop/NamespaceReference.cs @@ -1,140 +1,196 @@ -using System; -using System.Globalization; -using System.Linq; -using System.Reflection; -using Jint.Native; -using Jint.Native.Object; -using Jint.Runtime.Descriptors; - -namespace Jint.Runtime.Interop -{ - /// - /// Any instance on this class represents a reference to a CLR namespace. - /// Accessing its properties will look for a class of the full name, or instantiate - /// a new as it assumes that the property is a deeper - /// level of the current namespace - /// - public class NamespaceReference : ObjectInstance, ICallable - { - private readonly string _path; - - public NamespaceReference(Engine engine, string path) : base(engine) - { - _path = path; - } - - public override bool DefineOwnProperty(string propertyName, PropertyDescriptor desc, bool throwOnError) - { - if (throwOnError) - { - throw new JavaScriptException(Engine.TypeError, "Can't define a property of a NamespaceReference"); - } - - return false; - } - - public override bool Delete(string propertyName, bool throwOnError) - { - if (throwOnError) - { - throw new JavaScriptException(Engine.TypeError, "Can't delete a property of a NamespaceReference"); - } - - return false; - } - - public JsValue Call(JsValue thisObject, JsValue[] arguments) - { - // direct calls on a NamespaceReference constructor object is creating a generic type - var genericTypes = new Type[arguments.Length]; - for (int i = 0; i < arguments.Length; i++) - { - var genericTypeReference = arguments.At(i); - if (genericTypeReference == Undefined.Instance || !genericTypeReference.IsObject() || genericTypeReference.AsObject().Class != "TypeReference") - { - throw new JavaScriptException(Engine.TypeError, "Invalid generic type parameter"); - } - - genericTypes[i] = arguments.At(0).As().Type; - } - - var typeReference = GetPath(_path + "`" + arguments.Length.ToString(CultureInfo.InvariantCulture)).As(); - - if (typeReference == null) - { - return Undefined.Instance; - } - - var genericType = typeReference.Type.MakeGenericType(genericTypes); - - return TypeReference.CreateTypeReference(Engine, genericType); - } - - public override JsValue Get(string propertyName) - { - var newPath = _path + "." + propertyName; - - return GetPath(newPath); - } - - public JsValue GetPath(string path) - { - Type type; - - if (Engine.TypeCache.TryGetValue(path, out type)) - { - if (type == null) - { - return new NamespaceReference(Engine, path); - } - - return TypeReference.CreateTypeReference(Engine, type); - } - - // search for type in mscorlib - type = Type.GetType(path); - if (type != null) - { - Engine.TypeCache.Add(path, type); - return TypeReference.CreateTypeReference(Engine, type); - } - - // search in loaded assemblies - foreach (var assembly in new[] { Assembly.GetCallingAssembly(), Assembly.GetExecutingAssembly() }.Distinct()) - { - type = assembly.GetType(path); - if (type != null) - { - Engine.TypeCache.Add(path, type); - return TypeReference.CreateTypeReference(Engine, type); - } - } - - // search in lookup asemblies - foreach (var assembly in Engine.Options.GetLookupAssemblies()) - { - type = assembly.GetType(path); - if (type != null) - { - Engine.TypeCache.Add(path, type); - return TypeReference.CreateTypeReference(Engine, type); - } - } - - // the new path doesn't represent a known class, thus return a new namespace instance - - Engine.TypeCache.Add(path, null); - return new NamespaceReference(Engine, path); - } - - public override PropertyDescriptor GetOwnProperty(string propertyName) - { - return PropertyDescriptor.Undefined; - } - - public override string ToString() - { - return "[Namespace: " + _path + "]"; - } - } -} +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Reflection; +using Jint.Native; +using Jint.Native.Object; +using Jint.Runtime.Descriptors; + +namespace Jint.Runtime.Interop +{ + /// + /// Any instance on this class represents a reference to a CLR namespace. + /// Accessing its properties will look for a class of the full name, or instantiate + /// a new as it assumes that the property is a deeper + /// level of the current namespace + /// + public class NamespaceReference : ObjectInstance, ICallable + { + private readonly string _path; + + public NamespaceReference(Engine engine, string path) : base(engine) + { + _path = path; + } + + public override bool DefineOwnProperty(string propertyName, PropertyDescriptor desc, bool throwOnError) + { + if (throwOnError) + { + throw new JavaScriptException(Engine.TypeError, "Can't define a property of a NamespaceReference"); + } + + return false; + } + + public override bool Delete(string propertyName, bool throwOnError) + { + if (throwOnError) + { + throw new JavaScriptException(Engine.TypeError, "Can't delete a property of a NamespaceReference"); + } + + return false; + } + + public JsValue Call(JsValue thisObject, JsValue[] arguments) + { + // direct calls on a NamespaceReference constructor object is creating a generic type + var genericTypes = new Type[arguments.Length]; + for (int i = 0; i < arguments.Length; i++) + { + var genericTypeReference = arguments.At(i); + if (genericTypeReference == Undefined.Instance || !genericTypeReference.IsObject() || genericTypeReference.AsObject().Class != "TypeReference") + { + throw new JavaScriptException(Engine.TypeError, "Invalid generic type parameter"); + } + + genericTypes[i] = arguments.At(i).As().Type; + } + + var typeReference = GetPath(_path + "`" + arguments.Length.ToString(CultureInfo.InvariantCulture)).As(); + + if (typeReference == null) + { + return Undefined.Instance; + } + + var genericType = typeReference.Type.MakeGenericType(genericTypes); + + return TypeReference.CreateTypeReference(Engine, genericType); + } + + public override JsValue Get(string propertyName) + { + var newPath = _path + "." + propertyName; + + return GetPath(newPath); + } + + public JsValue GetPath(string path) + { + Type type; + + if (Engine.TypeCache.TryGetValue(path, out type)) + { + if (type == null) + { + return new NamespaceReference(Engine, path); + } + + return TypeReference.CreateTypeReference(Engine, type); + } + + // search for type in mscorlib + type = Type.GetType(path); + if (type != null) + { + Engine.TypeCache.Add(path, type); + return TypeReference.CreateTypeReference(Engine, type); + } + + // search in loaded assemblies +#if NETSTANDARD1_3 + var lookupAssemblies = new[] { typeof(NamespaceReference).GetTypeInfo().Assembly }; +#else + var lookupAssemblies = new[] { Assembly.GetCallingAssembly(), Assembly.GetExecutingAssembly() }; +#endif + + foreach (var assembly in lookupAssemblies) + { + type = assembly.GetType(path); + if (type != null) + { + Engine.TypeCache.Add(path, type); + return TypeReference.CreateTypeReference(Engine, type); + } + } + + // search in lookup assemblies + foreach (var assembly in Engine.Options._LookupAssemblies) + { + type = assembly.GetType(path); + if (type != null) + { + Engine.TypeCache.Add(path, type); + return TypeReference.CreateTypeReference(Engine, type); + } + + var lastPeriodPos = path.LastIndexOf(".", StringComparison.Ordinal); + var trimPath = path.Substring(0, lastPeriodPos); + type = GetType(assembly, trimPath); + if (type != null) + foreach (Type nType in GetAllNestedTypes(type)) + { + if (nType.FullName.Replace("+", ".").Equals(path.Replace("+", "."))) + { + Engine.TypeCache.Add(path.Replace("+", "."), nType); + return TypeReference.CreateTypeReference(Engine, nType); + } + } + } + + // the new path doesn't represent a known class, thus return a new namespace instance + + Engine.TypeCache.Add(path, null); + return new NamespaceReference(Engine, path); + } + + /// Gets a type. + ///Nested type separators are converted to '.' instead of '+' + /// The assembly. + /// Name of the type. + /// + /// The type. + + private static Type GetType(Assembly assembly, string typeName) + { + Type[] types = assembly.GetTypes(); + foreach (Type t in types) + { + if (t.FullName.Replace("+", ".") == typeName.Replace("+", ".")) + { + return t; + } + } + return null; + } + + private static IEnumerable GetAllNestedTypes(Type type) + { + var types = new List(); + AddNestedTypesRecursively(types, type); + return types.ToArray(); + } + + private static void AddNestedTypesRecursively(List types, Type type) + { + Type[] nestedTypes = type.GetNestedTypes(BindingFlags.Public); + foreach (Type nestedType in nestedTypes) + { + types.Add(nestedType); + AddNestedTypesRecursively(types, nestedType); + } + } + + public override PropertyDescriptor GetOwnProperty(string propertyName) + { + return PropertyDescriptor.Undefined; + } + + public override string ToString() + { + return "[Namespace: " + _path + "]"; + } + } +} diff --git a/Jint/Runtime/Interop/ObjectWrapper .cs b/Jint/Runtime/Interop/ObjectWrapper .cs deleted file mode 100644 index b76373d6e7..0000000000 --- a/Jint/Runtime/Interop/ObjectWrapper .cs +++ /dev/null @@ -1,102 +0,0 @@ -using System; -using System.Linq; -using System.Reflection; -using Jint.Native; -using Jint.Native.Object; -using Jint.Runtime.Descriptors; -using Jint.Runtime.Descriptors.Specialized; -using System.Collections; - -namespace Jint.Runtime.Interop -{ - /// - /// Wrapps a CLR instance - /// - public sealed class ObjectWrapper : ObjectInstance, IObjectWrapper - { - public Object Target { get; set; } - - public ObjectWrapper(Engine engine, Object obj): base(engine) - { - Target = obj; - } - - public override void Put(string propertyName, JsValue value, bool throwOnError) - { - if (!CanPut(propertyName)) - { - if (throwOnError) - { - throw new JavaScriptException(Engine.TypeError); - } - - return; - } - - var ownDesc = GetOwnProperty(propertyName); - - if (ownDesc == null) - { - if (throwOnError) - { - throw new JavaScriptException(Engine.TypeError, "Unknown member: " + propertyName); - } - else - { - return; - } - } - - ownDesc.Value = value; - } - - public override PropertyDescriptor GetOwnProperty(string propertyName) - { - PropertyDescriptor x; - if (Properties.TryGetValue(propertyName, out x)) - { - return x; - } - - var type = Target.GetType(); - - // look for a property - var property = type.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public); - - if (property != null) - { - var descriptor = new PropertyInfoDescriptor(Engine, property, Target); - Properties.Add(propertyName, descriptor); - return descriptor; - } - - // look for a field - var field = type.GetField(propertyName, BindingFlags.Instance | BindingFlags.Public); - - if (field != null) - { - var descriptor = new FieldInfoDescriptor(Engine, field, Target); - Properties.Add(propertyName, descriptor); - return descriptor; - } - - // if no properties were found then look for a method - var methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public) - .Where(m => m.Name == propertyName) - .ToArray(); - - if (methods.Any()) - { - return new PropertyDescriptor(new MethodInfoFunctionInstance(Engine, methods), false, true, false); - } - - // if no methods are found check if target implemented indexing - if (type.GetProperties().Where(p => p.GetIndexParameters().Length != 0).FirstOrDefault() != null) - { - return new IndexDescriptor(Engine, propertyName, Target); - } - - return PropertyDescriptor.Undefined; - } - } -} diff --git a/Jint/Runtime/Interop/ObjectWrapper.cs b/Jint/Runtime/Interop/ObjectWrapper.cs new file mode 100644 index 0000000000..871af8e513 --- /dev/null +++ b/Jint/Runtime/Interop/ObjectWrapper.cs @@ -0,0 +1,161 @@ +using System; +using System.Linq; +using System.Reflection; +using Jint.Native; +using Jint.Native.Object; +using Jint.Runtime.Descriptors; +using Jint.Runtime.Descriptors.Specialized; + +namespace Jint.Runtime.Interop +{ + /// + /// Wraps a CLR instance + /// + public sealed class ObjectWrapper : ObjectInstance, IObjectWrapper + { + public Object Target { get; set; } + + public ObjectWrapper(Engine engine, Object obj) + : base(engine) + { + Target = obj; + } + + public override void Put(string propertyName, JsValue value, bool throwOnError) + { + if (!CanPut(propertyName)) + { + if (throwOnError) + { + throw new JavaScriptException(Engine.TypeError); + } + + return; + } + + var ownDesc = GetOwnProperty(propertyName); + + if (ownDesc == null) + { + if (throwOnError) + { + throw new JavaScriptException(Engine.TypeError, "Unknown member: " + propertyName); + } + else + { + return; + } + } + + ownDesc.Value = value; + } + + public override PropertyDescriptor GetOwnProperty(string propertyName) + { + PropertyDescriptor x; + if (Properties.TryGetValue(propertyName, out x)) + return x; + + var type = Target.GetType(); + + // look for a property + var property = type.GetProperties(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public) + .Where(p => EqualsIgnoreCasing(p.Name, propertyName)) + .FirstOrDefault(); + if (property != null) + { + var descriptor = new PropertyInfoDescriptor(Engine, property, Target); + Properties.Add(propertyName, descriptor); + return descriptor; + } + + // look for a field + var field = type.GetFields(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public) + .Where(f => EqualsIgnoreCasing(f.Name, propertyName)) + .FirstOrDefault(); + if (field != null) + { + var descriptor = new FieldInfoDescriptor(Engine, field, Target); + Properties.Add(propertyName, descriptor); + return descriptor; + } + + // if no properties were found then look for a method + var methods = type.GetMethods(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public) + .Where(m => EqualsIgnoreCasing(m.Name, propertyName)) + .ToArray(); + + if (methods.Any()) + { + var descriptor = new PropertyDescriptor(new MethodInfoFunctionInstance(Engine, methods), false, true, false); + Properties.Add(propertyName, descriptor); + return descriptor; + } + + // if no methods are found check if target implemented indexing + if (type.GetProperties().Where(p => p.GetIndexParameters().Length != 0).FirstOrDefault() != null) + { + return new IndexDescriptor(Engine, propertyName, Target); + } + + var interfaces = type.GetInterfaces(); + + // try to find a single explicit property implementation + var explicitProperties = (from iface in interfaces + from iprop in iface.GetProperties() + where EqualsIgnoreCasing(iprop.Name, propertyName) + select iprop).ToArray(); + + if (explicitProperties.Length == 1) + { + var descriptor = new PropertyInfoDescriptor(Engine, explicitProperties[0], Target); + Properties.Add(propertyName, descriptor); + return descriptor; + } + + // try to find explicit method implementations + var explicitMethods = (from iface in interfaces + from imethod in iface.GetMethods() + where EqualsIgnoreCasing(imethod.Name, propertyName) + select imethod).ToArray(); + + if (explicitMethods.Length > 0) + { + var descriptor = new PropertyDescriptor(new MethodInfoFunctionInstance(Engine, explicitMethods), false, true, false); + Properties.Add(propertyName, descriptor); + return descriptor; + } + + // try to find explicit indexer implementations + var explicitIndexers = + (from iface in interfaces + from iprop in iface.GetProperties() + where iprop.GetIndexParameters().Length != 0 + select iprop).ToArray(); + + if (explicitIndexers.Length == 1) + { + return new IndexDescriptor(Engine, explicitIndexers[0].DeclaringType, propertyName, Target); + } + + return PropertyDescriptor.Undefined; + } + + private bool EqualsIgnoreCasing(string s1, string s2) + { + bool equals = false; + if (s1.Length == s2.Length) + { + if (s1.Length > 0 && s2.Length > 0) + { + equals = (s1.ToLower()[0] == s2.ToLower()[0]); + } + if (s1.Length > 1 && s2.Length > 1) + { + equals = equals && (s1.Substring(1) == s2.Substring(1)); + } + } + return equals; + } + } +} diff --git a/Jint/Runtime/Interop/TypeReference.cs b/Jint/Runtime/Interop/TypeReference.cs index bc218b1499..8ed93be0fe 100644 --- a/Jint/Runtime/Interop/TypeReference.cs +++ b/Jint/Runtime/Interop/TypeReference.cs @@ -1,146 +1,167 @@ -using System; -using System.Globalization; -using System.Linq; -using System.Reflection; -using Jint.Native; -using Jint.Native.Function; -using Jint.Native.Object; -using Jint.Runtime.Descriptors; -using Jint.Runtime.Descriptors.Specialized; - -namespace Jint.Runtime.Interop -{ - public class TypeReference : FunctionInstance, IConstructor, IObjectWrapper - { - private TypeReference(Engine engine) - : base(engine, null, null, false) - { - } - - public Type Type { get; set; } - - public static TypeReference CreateTypeReference(Engine engine, Type type) - { - var obj = new TypeReference(engine); - obj.Extensible = false; - obj.Type = type; - - // The value of the [[Prototype]] internal property of the TypeReference constructor is the Function prototype object - obj.Prototype = engine.Function.PrototypeObject; - - obj.FastAddProperty("length", 0, false, false, false); - - // The initial value of Boolean.prototype is the Boolean prototype object - obj.FastAddProperty("prototype", engine.Object.PrototypeObject, false, false, false); - - return obj; - } - - public override JsValue Call(JsValue thisObject, JsValue[] arguments) - { - // direct calls on a TypeReference constructor object is equivalent to the new operator - return Construct(arguments); - } - - public ObjectInstance Construct(JsValue[] arguments) - { - var constructors = Type.GetConstructors(BindingFlags.Public | BindingFlags.Instance); - - var methods = TypeConverter.FindBestMatch(Engine, constructors, arguments).ToList(); - - foreach (var method in methods) - { - var parameters = new object[arguments.Length]; - try - { - for (var i = 0; i < arguments.Length; i++) - { - var parameterType = method.GetParameters()[i].ParameterType; - - if (parameterType == typeof(JsValue)) - { - parameters[i] = arguments[i]; - } - else - { - parameters[i] = Engine.Options.GetTypeConverter().Convert( - arguments[i].ToObject(), - parameterType, - CultureInfo.InvariantCulture); - } - } - - var constructor = (ConstructorInfo)method; - var result = TypeConverter.ToObject(Engine, JsValue.FromObject(Engine, constructor.Invoke(parameters.ToArray()))); - - // todo: cache method info - - return result; - } - catch - { - // ignore method - } - } - - throw new JavaScriptException(Engine.TypeError, "No public methods with the specified arguments were found."); - - } - - public override bool DefineOwnProperty(string propertyName, PropertyDescriptor desc, bool throwOnError) - { - if (throwOnError) - { - throw new JavaScriptException(Engine.TypeError, "Can't define a property of a TypeReference"); - } - - return false; - } - - public override bool Delete(string propertyName, bool throwOnError) - { - if (throwOnError) - { - throw new JavaScriptException(Engine.TypeError, "Can't delete a property of a TypeReference"); - } - - return false; - } - - public override void Put(string propertyName, JsValue value, bool throwOnError) - { - if (!CanPut(propertyName)) - { - if (throwOnError) - { - throw new JavaScriptException(Engine.TypeError); - } - - return; - } - - var ownDesc = GetOwnProperty(propertyName); - - if (ownDesc == null) - { - if (throwOnError) - { - throw new JavaScriptException(Engine.TypeError, "Unknown member: " + propertyName); - } - else - { - return; - } - } - - ownDesc.Value = value; - } - - public override PropertyDescriptor GetOwnProperty(string propertyName) - { +using System; +using System.Globalization; +using System.Linq; +using System.Reflection; +using Jint.Native; +using Jint.Native.Function; +using Jint.Native.Object; +using Jint.Runtime.Descriptors; +using Jint.Runtime.Descriptors.Specialized; + +namespace Jint.Runtime.Interop +{ + public class TypeReference : FunctionInstance, IConstructor, IObjectWrapper + { + private TypeReference(Engine engine) + : base(engine, null, null, false) + { + } + + public Type Type { get; set; } + + public static TypeReference CreateTypeReference(Engine engine, Type type) + { + var obj = new TypeReference(engine); + obj.Extensible = false; + obj.Type = type; + + // The value of the [[Prototype]] internal property of the TypeReference constructor is the Function prototype object + obj.Prototype = engine.Function.PrototypeObject; + + obj.FastAddProperty("length", 0, false, false, false); + + // The initial value of Boolean.prototype is the Boolean prototype object + obj.FastAddProperty("prototype", engine.Object.PrototypeObject, false, false, false); + + return obj; + } + + public override JsValue Call(JsValue thisObject, JsValue[] arguments) + { + // direct calls on a TypeReference constructor object is equivalent to the new operator + return Construct(arguments); + } + + public ObjectInstance Construct(JsValue[] arguments) + { + if (arguments.Length == 0 && Type.IsValueType()) + { + var instance = Activator.CreateInstance(Type); + var result = TypeConverter.ToObject(Engine, JsValue.FromObject(Engine, instance)); + + return result; + } + + var constructors = Type.GetConstructors(BindingFlags.Public | BindingFlags.Instance); + + var methods = TypeConverter.FindBestMatch(Engine, constructors, arguments).ToList(); + + foreach (var method in methods) + { + var parameters = new object[arguments.Length]; + try + { + for (var i = 0; i < arguments.Length; i++) + { + var parameterType = method.GetParameters()[i].ParameterType; + + if (parameterType == typeof(JsValue)) + { + parameters[i] = arguments[i]; + } + else + { + parameters[i] = Engine.ClrTypeConverter.Convert( + arguments[i].ToObject(), + parameterType, + CultureInfo.InvariantCulture); + } + } + + var constructor = (ConstructorInfo)method; + var instance = constructor.Invoke(parameters.ToArray()); + var result = TypeConverter.ToObject(Engine, JsValue.FromObject(Engine, instance)); + + // todo: cache method info + + return result; + } + catch + { + // ignore method + } + } + + throw new JavaScriptException(Engine.TypeError, "No public methods with the specified arguments were found."); + + } + + public override bool HasInstance(JsValue v) + { + ObjectWrapper wrapper = v.As(); + + if (wrapper == null) + { + return base.HasInstance(v); + } + + return wrapper.Target.GetType() == this.Type; + } + + public override bool DefineOwnProperty(string propertyName, PropertyDescriptor desc, bool throwOnError) + { + if (throwOnError) + { + throw new JavaScriptException(Engine.TypeError, "Can't define a property of a TypeReference"); + } + + return false; + } + + public override bool Delete(string propertyName, bool throwOnError) + { + if (throwOnError) + { + throw new JavaScriptException(Engine.TypeError, "Can't delete a property of a TypeReference"); + } + + return false; + } + + public override void Put(string propertyName, JsValue value, bool throwOnError) + { + if (!CanPut(propertyName)) + { + if (throwOnError) + { + throw new JavaScriptException(Engine.TypeError); + } + + return; + } + + var ownDesc = GetOwnProperty(propertyName); + + if (ownDesc == null) + { + if (throwOnError) + { + throw new JavaScriptException(Engine.TypeError, "Unknown member: " + propertyName); + } + else + { + return; + } + } + + ownDesc.Value = value; + } + + public override PropertyDescriptor GetOwnProperty(string propertyName) + { // todo: cache members locally - if (Type.IsEnum) + if (Type.IsEnum()) { Array enumValues = Enum.GetValues(Type); Array enumNames = Enum.GetNames(Type); @@ -153,44 +174,44 @@ public override PropertyDescriptor GetOwnProperty(string propertyName) } } return PropertyDescriptor.Undefined; - } - - var propertyInfo = Type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Static); - if (propertyInfo != null) - { - return new PropertyInfoDescriptor(Engine, propertyInfo, Type); - } - - var fieldInfo = Type.GetField(propertyName, BindingFlags.Public | BindingFlags.Static); - if (fieldInfo != null) - { - return new FieldInfoDescriptor(Engine, fieldInfo, Type); - } - - var methodInfo = Type - .GetMethods(BindingFlags.Public | BindingFlags.Static) - .Where(mi => mi.Name == propertyName) - .ToArray(); - - if (methodInfo.Length == 0) - { - return PropertyDescriptor.Undefined; - } - - return new PropertyDescriptor(new MethodInfoFunctionInstance(Engine, methodInfo), false, false, false); - } - - public object Target - { - get - { - return Type; - } - } - - public override string Class - { - get { return "TypeReference"; } - } - } -} + } + + var propertyInfo = Type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Static); + if (propertyInfo != null) + { + return new PropertyInfoDescriptor(Engine, propertyInfo, Type); + } + + var fieldInfo = Type.GetField(propertyName, BindingFlags.Public | BindingFlags.Static); + if (fieldInfo != null) + { + return new FieldInfoDescriptor(Engine, fieldInfo, Type); + } + + var methodInfo = Type + .GetMethods(BindingFlags.Public | BindingFlags.Static) + .Where(mi => mi.Name == propertyName) + .ToArray(); + + if (methodInfo.Length == 0) + { + return PropertyDescriptor.Undefined; + } + + return new PropertyDescriptor(new MethodInfoFunctionInstance(Engine, methodInfo), false, false, false); + } + + public object Target + { + get + { + return Type; + } + } + + public override string Class + { + get { return "TypeReference"; } + } + } +} diff --git a/Jint/Runtime/JavaScriptException.cs b/Jint/Runtime/JavaScriptException.cs index 4f46662095..a73a7988bf 100644 --- a/Jint/Runtime/JavaScriptException.cs +++ b/Jint/Runtime/JavaScriptException.cs @@ -1,12 +1,20 @@ using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; using Jint.Native; using Jint.Native.Error; +using Jint.Parser; +using Jint.Parser.Ast; +using Jint.Runtime.CallStack; +using Jint.Runtime.Descriptors; namespace Jint.Runtime { public class JavaScriptException : Exception { private readonly JsValue _errorObject; + private string _callStack; public JavaScriptException(ErrorConstructor errorConstructor) : base("") { @@ -25,6 +33,40 @@ public JavaScriptException(JsValue error) _errorObject = error; } + public JavaScriptException SetCallstack(Engine engine, Location location = null) + { + Location = location; + var sb = new StringBuilder(); + foreach (var cse in engine.CallStack) + { + sb.Append(" at ") + .Append(cse) + .Append("("); + + for (var index = 0; index < cse.CallExpression.Arguments.Count; index++) + { + if (index != 0) + sb.Append(", "); + var arg = cse.CallExpression.Arguments[index]; + if (arg is IPropertyKeyExpression pke) + sb.Append(pke.GetKey()); + else + sb.Append(arg); + } + + + sb.Append(") @ ") + .Append(cse.CallExpression.Location.Source) + .Append(" ") + .Append(cse.CallExpression.Location.Start.Column) + .Append(":") + .Append(cse.CallExpression.Location.Start.Line) + .AppendLine(); + } + CallStack = sb.ToString(); + return this; + } + private static string GetErrorMessage(JsValue error) { if (error.IsObject()) @@ -33,8 +75,10 @@ private static string GetErrorMessage(JsValue error) var message = oi.Get("message").AsString(); return message; } - else - return string.Empty; + if (error.IsString()) + return error.AsString(); + + return error.ToString(); } public JsValue Error { get { return _errorObject; } } @@ -43,5 +87,37 @@ public override string ToString() { return _errorObject.ToString(); } + + public string CallStack + { + get + { + if (_callStack != null) + return _callStack; + if (_errorObject == null) + return null; + if (_errorObject.IsObject() == false) + return null; + var callstack = _errorObject.AsObject().Get("callstack"); + if (callstack == JsValue.Undefined) + return null; + return callstack.AsString(); + } + set + { + _callStack = value; + if (value != null && _errorObject.IsObject()) + { + _errorObject.AsObject() + .FastAddProperty("callstack", new JsValue(value), false, false, false); + } + } + } + + public Jint.Parser.Location Location { get; set; } + + public int LineNumber { get { return null == Location ? 0 : Location.Start.Line; } } + + public int Column { get { return null == Location ? 0 : Location.Start.Column; } } } } diff --git a/Jint/Runtime/MruPropertyCache.cs b/Jint/Runtime/MruPropertyCache.cs new file mode 100644 index 0000000000..4fc233c223 --- /dev/null +++ b/Jint/Runtime/MruPropertyCache.cs @@ -0,0 +1,165 @@ +using System.Collections; +using System.Collections.Generic; + +namespace Jint.Runtime +{ + public class MruPropertyCache : IDictionary + { + private IDictionary _dictionary = new Dictionary(); + private LinkedList> _list; + private uint _length; + + public MruPropertyCache(uint length) { + _length = length; + _list = new LinkedList>(); + for(int i=0; i(default(TKey), default(TValue))); + } + } + + private bool Find(TKey key, out LinkedListNode> result) { + result = _list.First; + while(result != null) { + if(key.Equals(result.Value.Key)) { + return true; + } + + result = result.Next; + } + + return false; + } + public TValue this[TKey key] { + get { + LinkedListNode> node; + if(Find(key, out node)) { + return node.Value.Value; + } + + return _dictionary[key]; + } + + set { + LinkedListNode> node; + if (!Find(key, out node)) { + _list.AddFirst(new KeyValuePair(key, value)); + _list.RemoveLast(); + } + else + { + node.Value = new KeyValuePair(key, value); + } + + _dictionary[key] = value; + } + } + + public int Count { + get { + return _dictionary.Count; + } + } + + public bool IsReadOnly { + get { + return _dictionary.IsReadOnly; + } + } + + public ICollection Keys { + get { + return _dictionary.Keys; + } + } + + public ICollection Values { + get { + return _dictionary.Values; + } + } + + public void Add(KeyValuePair item) { + LinkedListNode> node; + if (!Find(item.Key, out node)) { + _list.AddFirst(item); + _list.RemoveLast(); + } + + _dictionary.Add(item); + } + + public void Add(TKey key, TValue value) { + LinkedListNode> node; + if (!Find(key, out node)) { + _list.AddFirst(new KeyValuePair(key, value)); + _list.RemoveLast(); + } + _dictionary.Add(key, value); + } + + public void Clear() { + _list.Clear(); + _dictionary.Clear(); + } + + public bool Contains(KeyValuePair item) { + LinkedListNode> node; + if (Find(item.Key, out node)) { + return true; + } + + return _dictionary.Contains(item); + } + + public bool ContainsKey(TKey key) { + LinkedListNode> node; + if (Find(key, out node)) { + return true; + } + + return _dictionary.ContainsKey(key); + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) { + _dictionary.CopyTo(array, arrayIndex); + } + + public IEnumerator> GetEnumerator() { + return _dictionary.GetEnumerator(); + } + + public bool Remove(KeyValuePair item) { + LinkedListNode> node; + if (Find(item.Key, out node)) + { + _list.Remove(node); + } + + return _dictionary.Remove(item); + } + + public bool Remove(TKey key) { + LinkedListNode> node; + if (Find(key, out node)) + { + _list.Remove(node); + } + + return _dictionary.Remove(key); + } + + public bool TryGetValue(TKey key, out TValue value) { + LinkedListNode> node; + if (Find(key, out node)) { + value = node.Value.Value; + return true; + } + + return _dictionary.TryGetValue(key, out value); + } + + IEnumerator IEnumerable.GetEnumerator() { + return _dictionary.GetEnumerator(); + } + } +} diff --git a/Jint/Runtime/MruPropertyCache2.cs b/Jint/Runtime/MruPropertyCache2.cs new file mode 100644 index 0000000000..da679b3684 --- /dev/null +++ b/Jint/Runtime/MruPropertyCache2.cs @@ -0,0 +1,146 @@ +using System.Collections; +using System.Collections.Generic; + +namespace Jint.Runtime +{ + public class MruPropertyCache2 : IDictionary + where TValue:class + { + private IDictionary _dictionary = new Dictionary(); + private bool _set; + private TKey _key; + private TValue _value; + + public MruPropertyCache2() { + } + + public TValue this[TKey key] { + get { + if (_set && key.Equals(_key)) + { + return _value; + } + + return _dictionary[key]; + } + + set { + _set = true; + _key = key; + _value = value; + + _dictionary[key] = value; + } + } + + public int Count { + get { + return _dictionary.Count; + } + } + + public bool IsReadOnly { + get { + return _dictionary.IsReadOnly; + } + } + + public ICollection Keys { + get { + return _dictionary.Keys; + } + } + + public ICollection Values { + get { + return _dictionary.Values; + } + } + + public void Add(KeyValuePair item) { + _set = true; + _key = item.Key; + _value = item.Value; + + _dictionary.Add(item); + } + + public void Add(TKey key, TValue value) { + _set = true; + _key = key; + _value = value; + + _dictionary.Add(key, value); + } + + public void Clear() { + _set = false; + _key = default(TKey); + _value = null; + + _dictionary.Clear(); + } + + public bool Contains(KeyValuePair item) { + if(_set && item.Key.Equals(_key)) + { + return true; + } + + return _dictionary.Contains(item); + } + + public bool ContainsKey(TKey key) { + if (_set && key.Equals(_key)) + { + return true; + } + + return _dictionary.ContainsKey(key); + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) { + _dictionary.CopyTo(array, arrayIndex); + } + + public IEnumerator> GetEnumerator() { + return _dictionary.GetEnumerator(); + } + + public bool Remove(KeyValuePair item) { + if(_set && item.Key.Equals(_key)) + { + _set = false; + _key = default(TKey); + _value = null; + } + + return _dictionary.Remove(item); + } + + public bool Remove(TKey key) { + if (_set && key.Equals(_key)) + { + _set = false; + _key = default(TKey); + _value = null; + } + + return _dictionary.Remove(key); + } + + public bool TryGetValue(TKey key, out TValue value) { + if (_set && key.Equals(_key)) + { + value = _value; + return true; + } + + return _dictionary.TryGetValue(key, out value); + } + + IEnumerator IEnumerable.GetEnumerator() { + return _dictionary.GetEnumerator(); + } + } +} diff --git a/Jint/Runtime/RecursionDepthOverflowException.cs b/Jint/Runtime/RecursionDepthOverflowException.cs new file mode 100644 index 0000000000..8289e1d7b4 --- /dev/null +++ b/Jint/Runtime/RecursionDepthOverflowException.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Jint.Native; +using Jint.Parser.Ast; + +namespace Jint.Runtime +{ + using Jint.Runtime.CallStack; + + public class RecursionDepthOverflowException : Exception + { + public string CallChain { get; private set; } + + public string CallExpressionReference { get; private set; } + + public RecursionDepthOverflowException(JintCallStack currentStack, string currentExpressionReference) + : base("The recursion is forbidden by script host.") + { + CallExpressionReference = currentExpressionReference; + + CallChain = currentStack.ToString(); + } + } + +} diff --git a/Jint/Runtime/References/Reference.cs b/Jint/Runtime/References/Reference.cs index 09b8eae014..756a4f691c 100644 --- a/Jint/Runtime/References/Reference.cs +++ b/Jint/Runtime/References/Reference.cs @@ -48,7 +48,7 @@ public bool IsUnresolvableReference() public bool IsPropertyReference() { // http://www.ecma-international.org/ecma-262/5.1/#sec-8.7 - return (_baseValue.IsObject() && _baseValue.TryCast() == null) || HasPrimitiveBase(); + return (_baseValue.IsObject() && !_baseValue.Is()) || HasPrimitiveBase(); } } } diff --git a/Jint/Runtime/StatementInterpreter.cs b/Jint/Runtime/StatementInterpreter.cs index 9baa138a70..a07c253fd7 100644 --- a/Jint/Runtime/StatementInterpreter.cs +++ b/Jint/Runtime/StatementInterpreter.cs @@ -3,6 +3,7 @@ using System.Linq; using Jint.Native; using Jint.Parser.Ast; +using Jint.Runtime.Descriptors; using Jint.Runtime.Environments; using Jint.Runtime.References; @@ -60,7 +61,7 @@ public Completion ExecuteLabelledStatement(LabelledStatement labelledStatement) var result = ExecuteStatement(labelledStatement.Body); if (result.Type == Completion.Break && result.Identifier == labelledStatement.Label.Name) { - return new Completion(Completion.Normal, result.Value, null); + return new Completion(Completion.Normal, result.Value, null); } return result; @@ -79,9 +80,9 @@ public Completion ExecuteDoWhileStatement(DoWhileStatement doWhileStatement) do { var stmt = ExecuteStatement(doWhileStatement.Body); - if (stmt.Value.HasValue) + if (stmt.Value != null) { - v = stmt.Value.Value; + v = stmt.Value; } if (stmt.Type != Completion.Continue || stmt.Identifier != doWhileStatement.LabelSet) { @@ -110,7 +111,7 @@ public Completion ExecuteDoWhileStatement(DoWhileStatement doWhileStatement) /// public Completion ExecuteWhileStatement(WhileStatement whileStatement) { - JsValue v = Undefined.Instance; + JsValue v = Undefined.Instance; while (true) { var exprRef = _engine.EvaluateExpression(whileStatement.Test); @@ -122,9 +123,9 @@ public Completion ExecuteWhileStatement(WhileStatement whileStatement) var stmt = ExecuteStatement(whileStatement.Body); - if (stmt.Value.HasValue) + if (stmt.Value != null) { - v = stmt.Value.Value; + v = stmt.Value; } if (stmt.Type != Completion.Continue || stmt.Identifier != whileStatement.LabelSet) @@ -149,7 +150,7 @@ public Completion ExecuteWhileStatement(WhileStatement whileStatement) /// public Completion ExecuteForStatement(ForStatement forStatement) { - + if (forStatement.Init != null) { if (forStatement.Init.Type == SyntaxNodes.VariableDeclaration) @@ -175,9 +176,9 @@ public Completion ExecuteForStatement(ForStatement forStatement) } var stmt = ExecuteStatement(forStatement.Body); - if (stmt.Value.HasValue) + if (stmt.Value != null) { - v = stmt.Value.Value; + v = stmt.Value; } if (stmt.Type == Completion.Break && (stmt.Identifier == null || stmt.Identifier == forStatement.LabelSet)) { @@ -205,8 +206,8 @@ public Completion ExecuteForStatement(ForStatement forStatement) /// public Completion ExecuteForInStatement(ForInStatement forInStatement) { - Identifier identifier = forInStatement.Left.Type == SyntaxNodes.VariableDeclaration - ? forInStatement.Left.As().Declarations.First().Id + Identifier identifier = forInStatement.Left.Type == SyntaxNodes.VariableDeclaration + ? forInStatement.Left.As().Declarations.First().Id : forInStatement.Left.As(); var varRef = _engine.EvaluateExpression(identifier) as Reference; @@ -220,31 +221,35 @@ public Completion ExecuteForInStatement(ForInStatement forInStatement) var obj = TypeConverter.ToObject(_engine, experValue); JsValue v = Null.Instance; - + // keys are constructed using the prototype chain var cursor = obj; var processedKeys = new HashSet(); while (cursor != null) { - var keys = cursor.Properties.Keys.ToArray(); - foreach (var p in keys) + var keys = _engine.Object.GetOwnPropertyNames(Undefined.Instance, Arguments.From(cursor)).AsArray(); + + for (var i = 0; i < keys.GetLength(); i++) { + var p = keys.GetOwnProperty(i.ToString()).Value.AsString(); + if (processedKeys.Contains(p)) { continue; } processedKeys.Add(p); - - // collection might be modified by inner statement - if (!cursor.Properties.ContainsKey(p)) + + // collection might be modified by inner statement + if (cursor.GetOwnProperty(p) == PropertyDescriptor.Undefined) { continue; } - var value = cursor.Properties[p]; - if (!value.Enumerable.HasValue || !value.Enumerable.Value.AsBoolean()) + + var value = cursor.GetOwnProperty(p); + if (!value.Enumerable.HasValue || !value.Enumerable.Value) { continue; } @@ -252,9 +257,9 @@ public Completion ExecuteForInStatement(ForInStatement forInStatement) _engine.PutValue(varRef, p); var stmt = ExecuteStatement(forInStatement.Body); - if (stmt.Value.HasValue) + if (stmt.Value != null) { - v = stmt.Value.Value; + v = stmt.Value; } if (stmt.Type == Completion.Break) { @@ -306,8 +311,8 @@ public Completion ExecuteReturnStatement(ReturnStatement statement) { return new Completion(Completion.Return, Undefined.Instance, null); } - - var exprRef = _engine.EvaluateExpression(statement.Argument); + + var exprRef = _engine.EvaluateExpression(statement.Argument); return new Completion(Completion.Return, _engine.GetValue(exprRef), null); } @@ -332,6 +337,7 @@ public Completion ExecuteWithStatement(WithStatement withStatement) catch (JavaScriptException e) { c = new Completion(Completion.Throw, e.Error, null); + c.Location = withStatement.Location; } finally { @@ -384,8 +390,8 @@ public Completion ExecuteSwitchBlock(IEnumerable switchBlock, JsValu { return r; } - - v = r.Value.HasValue ? r.Value.Value : Undefined.Instance; + + v = r.Value != null ? r.Value : Undefined.Instance; } } @@ -399,7 +405,7 @@ public Completion ExecuteSwitchBlock(IEnumerable switchBlock, JsValu return r; } - v = r.Value.HasValue ? r.Value.Value : Undefined.Instance; + v = r.Value != null ? r.Value : Undefined.Instance; } return new Completion(Completion.Normal, v, null); @@ -409,23 +415,30 @@ public Completion ExecuteStatementList(IEnumerable statementList) { var c = new Completion(Completion.Normal, null, null); Completion sl = c; + Statement s = null; try { foreach (var statement in statementList) { + s = statement; c = ExecuteStatement(statement); if (c.Type != Completion.Normal) { - return new Completion(c.Type, c.Value.HasValue ? c.Value : sl.Value, c.Identifier); + return new Completion(c.Type, c.Value != null ? c.Value : sl.Value, c.Identifier) + { + Location = c.Location + }; } sl = c; } } - catch(JavaScriptException v) + catch (JavaScriptException v) { - return new Completion(Completion.Throw, v.Error, null); + c = new Completion(Completion.Throw, v.Error, null); + c.Location = v.Location ?? s.Location; + return c; } return new Completion(c.Type, c.GetValueOrDefault(), c.Identifier); @@ -439,7 +452,9 @@ public Completion ExecuteStatementList(IEnumerable statementList) public Completion ExecuteThrowStatement(ThrowStatement throwStatement) { var exprRef = _engine.EvaluateExpression(throwStatement.Argument); - return new Completion(Completion.Throw, _engine.GetValue(exprRef), null); + Completion c = new Completion(Completion.Throw, _engine.GetValue(exprRef), null); + c.Location = throwStatement.Location; + return c; } /// @@ -476,7 +491,7 @@ public Completion ExecuteTryStatement(TryStatement tryStatement) { return b; } - + return f; } @@ -523,7 +538,7 @@ public Completion ExecuteBlockStatement(BlockStatement blockStatement) public Completion ExecuteDebuggerStatement(DebuggerStatement debuggerStatement) { - if (_engine.Options.IsDebuggerStatementAllowed()) + if (_engine.Options._IsDebuggerStatementAllowed) { if (!System.Diagnostics.Debugger.IsAttached) { diff --git a/Jint/Runtime/TypeConverter.cs b/Jint/Runtime/TypeConverter.cs index bb13913b06..2633c1da9d 100644 --- a/Jint/Runtime/TypeConverter.cs +++ b/Jint/Runtime/TypeConverter.cs @@ -6,6 +6,9 @@ using Jint.Native; using Jint.Native.Number; using Jint.Native.Object; +using Jint.Native.String; +using Jint.Parser.Ast; +using Jint.Runtime.References; namespace Jint.Runtime { @@ -134,7 +137,7 @@ public static double ToNumber(JsValue o) if (o.IsString()) { - var s = o.AsString().Trim(); + var s = StringPrototype.TrimEx(o.AsString()); if (String.IsNullOrEmpty(s)) { @@ -338,6 +341,25 @@ public static Types GetPrimitiveType(JsValue value) return value.Type; } + public static void CheckObjectCoercible(Engine engine, JsValue o, MemberExpression expression, + object baseReference) + { + if (o != Undefined.Instance && o != Null.Instance) + return; + + if (engine.Options._ReferenceResolver != null && + engine.Options._ReferenceResolver.CheckCoercible(o)) + return; + + var message = string.Empty; + var reference = baseReference as Reference; + if (reference != null) + message = $"{reference.GetReferencedName()} is {o}"; + + throw new JavaScriptException(engine.TypeError, message) + .SetCallstack(engine, expression.Location); + } + public static void CheckObjectCoercible(Engine engine, JsValue o) { if (o == Undefined.Instance || o == Null.Instance) @@ -350,8 +372,7 @@ public static IEnumerable FindBestMatch(Engine engine, MethodBase[] { methods = methods .Where(m => m.GetParameters().Count() == arguments.Length) - .ToArray() - ; + .ToArray(); if (methods.Length == 1 && !methods[0].GetParameters().Any()) { @@ -366,7 +387,18 @@ public static IEnumerable FindBestMatch(Engine engine, MethodBase[] var parameters = method.GetParameters(); for (var i = 0; i < arguments.Length; i++) { - if (objectArguments[i].GetType() != parameters[i].ParameterType) + var arg = objectArguments[i]; + var paramType = parameters[i].ParameterType; + + if (arg == null) + { + if (!TypeIsNullable(paramType)) + { + perfectMatch = false; + break; + } + } + else if (arg.GetType() != paramType) { perfectMatch = false; break; @@ -380,31 +412,15 @@ public static IEnumerable FindBestMatch(Engine engine, MethodBase[] } } - var candidates = new List(); foreach (var method in methods) { - var parameters = new object[arguments.Length]; - try - { - for (var i = 0; i < arguments.Length; i++) - { - parameters[i] = engine.Options.GetTypeConverter().Convert( - arguments[i].ToObject(), - method.GetParameters()[i].ParameterType, - CultureInfo.InvariantCulture); - } - } - catch - { - // ignore method - } - - candidates.Add(method); + yield return method; } - - foreach (var candidate in candidates) - yield return candidate; } + public static bool TypeIsNullable(Type type) + { + return !type.IsValueType() || Nullable.GetUnderlyingType(type) != null; + } } } diff --git a/README.md b/README.md index fbe9438b69..52a3fec801 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,29 @@ -[![Build status](https://ci.appveyor.com/api/projects/status/c84b8rdswh2w4744/branch/master)](https://ci.appveyor.com/project/SebastienRos/jint) +[![Build status](https://ci.appveyor.com/api/projects/status/xh2lsliy6usk60o5?svg=true)](https://ci.appveyor.com/project/SebastienRos/jint) +[![NuGet](https://img.shields.io/nuget/v/Jint.svg)](https://www.nuget.org/packages/Jint) +[![MyGet](https://img.shields.io/myget/jint/v/jint.svg)](https://www.myget.org/feed/Packages/jint) +[![Join the chat at https://gitter.im/sebastienros/jint](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/sebastienros/jint) # Jint -Jint is a Javascript interpreter for .NET. Jint doesn't compile Javascript to .NET bytecode and in this sense might be best suited for projects requiring to run relatively small scripts faster, or which need to run on different platforms. -It's available on nuget at https://www.nuget.org/packages/Jint +Jint is a __Javascript interpreter__ for .NET which provides full __ECMA 5.1__ compliance and can run on __any .NET platform__. Because it doesn't generate any .NET bytecode nor use the DLR it runs relatively small scripts faster. It's available as a PCL on Nuget at https://www.nuget.org/packages/Jint. -# Objectives +# Features - Full support for ECMAScript 5.1 - http://www.ecma-international.org/ecma-262/5.1/ - .NET Portable Class Library - http://msdn.microsoft.com/en-us/library/gg597391(v=vs.110).aspx - .NET Interoperability -# Example +> ECMAScript 6.0 currently being implemeted, see https://github.com/sebastienros/jint/issues/343 + +# Discussion + +Join the chat on [Gitter](https://gitter.im/sebastienros/jint) or post your questions with the `jint` tag on [stackoverflow](http://stackoverflow.com/questions/tagged/jint). + +# Examples This example defines a new value named `log` pointing to `Console.WriteLine`, then executes a script calling `log('Hello World!')`. -```csharp +```c# var engine = new Engine() .SetValue("log", new Action(Console.WriteLine)) ; @@ -29,7 +37,7 @@ a script calling `log('Hello World!')`. "); ``` Here, the variable `x` is set to `3` and `x * x` is executed in JavaScript. The result is returned to .NET directly, in this case as a `double` value `9`. -```csharp +```c# var square = new Engine() .SetValue("x", 3) // define a new variable .Execute("x * x") // execute a statement @@ -38,27 +46,27 @@ Here, the variable `x` is set to `3` and `x * x` is executed in JavaScript. The ; ``` You can also directly pass POCOs or anonymous objects and use them from JavaScript. In this example for instance a new `Person` instance is manipulated from JavaScript. -```csharp +```c# var p = new Person { Name = "Mickey Mouse" }; var engine = new Engine() .SetValue("p", p) - .Execute("p.Name === 'Mickey Mouse') + .Execute("p.Name === 'Mickey Mouse'") ; ``` You can invoke JavaScript function reference -```csharp +```c# var add = new Engine() - .Execute("function add(a, b) { return a + b; }"); + .Execute("function add(a, b) { return a + b; }") .GetValue("add") ; add.Invoke(1, 2); // -> 3 ``` or directly by name -```csharp +```c# var engine = new Engine() .Execute("function add(a, b) { return a + b; }") ; @@ -68,23 +76,23 @@ or directly by name ## Accessing .NET assemblies and classes You can allow an engine to access any .NET class by configuring the engine instance like this: -```csharp +```c# var engine = new Engine(cfg => cfg.AllowClr()); ``` Then you have access to the `System` namespace as a global value. Here is how it's used in the context on the command line utility: ```javascript - jint> var file = new System.IO.File('log.txt'); + jint> var file = new System.IO.StreamWriter('log.txt'); jint> file.WriteLine('Hello World !'); jint> file.Dispose(); ``` -And even create shortcuts to commong .NET methods +And even create shortcuts to common .NET methods ```javascript jint> var log = System.Console.WriteLine; jint> log('Hello World !'); => "Hello World !" ``` When allowing the CLR, you can optionally pass custom assemblies to load types from. -```csharp +```c# var engine = new Engine(cfg => cfg .AllowClr(typeof(Bar).Assembly) ); @@ -95,6 +103,14 @@ and then to assign local namespaces the same way `System` does it for you, use ` jint> var bar = new Foo.Bar(); jint> log(bar.ToString()); ``` +adding a specific CLR type reference can be done like this +```csharp +engine.SetValue("TheType", TypeReference.CreateTypeReference(engine, typeof(TheType))) +``` +and used this way +```javascript + jint> var o = new TheType(); +``` Generic types are also supported. Here is how to declare, instantiate and use a `List`: ```javascript jint> var ListOfString = System.Collections.Generic.List(System.String); @@ -104,6 +120,27 @@ Generic types are also supported. Here is how to declare, instantiate and use a jint> list.Count; // 2 ``` +## Internationalization + +You can enforce what Time Zone or Culture the engine should use when locale JavaScript methods are used if you don't want to use the computer's default values. + +This example forces the Time Zone to Pacific Standard Time. +```c# + var PST = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"); + var engine = new Engine(cfg => cfg.LocalTimeZone(PST)); + + engine.Execute("new Date().toString()"); // Wed Dec 31 1969 16:00:00 GMT-08:00 +``` + +This example is using French as the default culture. +```c# + var FR = CultureInfo.GetCultureInfo("fr-FR"); + var engine = new Engine(cfg => cfg.Culture(FR)); + + engine.Execute("new Number(1.23).toString()"); // 1.23 + engine.Execute("new Number(1.23).toLocaleString()"); // 1,23 +``` + ## Implemented features: - ECMAScript 5.1 test suite (http://test262.ecmascript.org/) @@ -124,3 +161,6 @@ Generic types are also supported. Here is how to declare, instantiate and use a - boolean -> bool - Regex -> RegExp - Function -> Delegate + +Continuous Integration kindly provided by [AppVeyor](https://www.appveyor.com) + diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000000..9f0f8cb52f --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,34 @@ +image: Visual Studio 2017 +init: + - git config --global core.autocrlf true +install: + - ps: $env:BuildNumber= $env:APPVEYOR_BUILD_NUMBER + - ps: $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = true + - ps: $env:NUGET_XMLDOC_MODE = "skip" + - ps: $env:DOTNET_CLI_TELEMETRY_OPTOUT = 1 +build_script: + - dotnet --version + - dotnet pack -c Release +test_script: + - dotnet test .\Jint.Tests\Jint.Tests.csproj -c Release -f netcoreapp1.0 + - dotnet test .\Jint.Tests.CommonScripts\Jint.Tests.CommonScripts.csproj -c Release -f netcoreapp1.0 + - dotnet test .\Jint.Tests.Ecma\Jint.Tests.Ecma.csproj -c Release -f netcoreapp1.0 +artifacts: + - path: 'Jint\**\*.nupkg' +deploy: + - provider: NuGet + on: + branch: dev + server: https://www.myget.org/F/jint/api/v2/package + api_key: + secure: 7PQvuxXn5P39X5QDlDKWbNpOKJKivpqkq7umakIirAZ12CSTAiCwjtJhSBGVboPm + skip_symbols: true + artifact: /.*\.nupkg/ + - provider: NuGet + on: + branch: master + server: https://www.nuget.org/api/v2/package + api_key: + secure: qZ6R8U4mtBXFVRhhNLJyRz3bktF/jL5BvzrCQsXcn6ATRQ4YavFP3By8Sg4hYMH5 + skip_symbols: true + artifact: /.*\.nupkg/