Spaces:
Paused
Paused
Download ling_bundle.js from taellinglin/HatchLing: direct link, hf CLI and curl.
- Browser
- Download file 135 kB
-
https://huggingface.co/spaces/taellinglin/HatchLing/resolve/main/ling_bundle.js
- Command line
-
hf download hf://spaces/taellinglin/HatchLing/ling_bundle.js
-
curl -L -o ling_bundle.js https://huggingface.co/spaces/taellinglin/HatchLing/resolve/main/ling_bundle.js
135 kB
| /* @ds-bundle: {"format":4,"namespace":"Ling","components":[{"name":"Hatch"},{"name":"Tile"},{"name":"Dial"},{"name":"Drum"},{"name":"Node"},{"name":"Connector"},{"name":"Mesh"},{"name":"Frame"},{"name":"Legend"},{"name":"TitlePlate"},{"name":"Panel"}]} */ | |
| /* Ling design system: line work only. Every function returns SVG markup made of | |
| outlines and generated hatch segments. No fills, no gradients, no clip masks. */ | |
| (function (root) { | |
| 'use strict'; | |
| // Glyph outlines, flattened and normalised to each glyph's own bounding box: | |
| // GLYPHS[face][char] = [width, height, [[x,y,x,y,...], ...]] (y down). | |
| var GLYPHS = {"daemon":{"!":[212,699,[[0,611,6,577,26,548,54,529,88,523,122,529,150,548,170,577,176,611,170,645,150,674,122,693,88,699,54,693,26,674,6,645],[212,0,204,42,195,85,186,128,177,170,168,210,160,247,151,288,142,328,133,368,65,368,68,329,71,288,74,246,77,204,79,164,81,126,84,84,86,42,88,0]]],"\"":[384,164,[[208,0,193,43,172,78,149,107,126,129,98,149,68,164,0,164,23,137,41,113,55,91,70,63,79,40,84,18,84,0],[384,0,369,43,348,78,325,107,302,129,274,149,244,164,176,164,199,137,217,113,231,91,246,63,255,40,260,18,260,0]]],"#":[729,751,[[393,1,393,2,294,2,235,205,293,1],[172,420,206,304,207,304,173,420],[76,751,144,518,145,518,77,751],[634,0,634,1,535,1,500,120,534,0],[317,750,385,518,318,750],[487,508,387,508,410,430,510,430],[247,508,147,508,169,430,269,430],[147,508,0,508,0,430,169,430],[387,508,247,508,269,430,410,430],[672,430,672,508,487,508,510,430],[550,293,450,293,472,215,572,215],[309,293,209,293,232,215,332,215],[209,293,48,293,48,215,232,215],[450,293,309,293,332,215,472,215],[720,215,720,293,550,293,572,215],[535,1,634,1,575,205,729,205,729,303,547,303,513,420,681,420,681,518,485,518,418,750,318,750,385,518,387,508,487,508,417,750,318,750,418,750,485,518,681,518,681,420,513,420,547,303,729,303,729,205,575,205,634,1,572,215,472,215,500,120],[447,304,450,293,550,293,510,430,410,430,413,420],[294,2,393,2,332,215,232,215,234,205],[172,420,173,420,207,304,206,304,209,293,309,293,269,430,169,430],[77,751,145,518,144,518,147,508,247,508,176,751]]],"$":[500,749,[[400,283,399,248,397,217,394,192,384,160,370,136,351,119,325,108,292,103,251,101,210,103,177,108,151,119,131,136,116,160,107,192,103,217,101,248,100,283,102,333,107,372,116,401,131,422,151,437,177,446,210,450,251,451,292,450,325,446,351,437,370,422,384,401,394,372,398,333],[0,286,0,284,0,283,0,282,0,281,2,232,7,188,16,149,28,115,44,86,63,62,85,42,111,26,140,14,173,6,210,2,250,0,289,2,324,6,356,14,385,25,411,40,433,59,453,83,470,113,482,146,490,175,495,208,499,243,500,282,500,286,500,287,498,337,493,380,484,417,473,449,457,476,438,498,416,516,390,530,361,540,328,546,291,550,251,551,250,551,210,550,173,546,140,540,110,530,84,516,62,498,43,476,28,449,16,417,7,380,2,337,0,287],[175,279,176,305,178,325,183,340,190,351,200,358,214,363,230,365,251,366,272,365,288,363,301,358,311,351,318,340,322,325,324,305,325,279,324,253,322,232,318,217,311,206,301,198,288,193,272,191,251,190,230,191,214,193,200,198,190,206,183,217,178,232,176,253],[125,283,128,235,139,198,156,172,180,154,212,144,250,140,288,144,320,154,344,172,361,198,372,235,375,283,373,319,368,348,358,371,344,389,326,402,304,410,279,414,250,416,220,414,195,410,174,402,156,389,142,371,132,348,127,319],[175,285,176,311,178,330,183,345,190,355,200,361,214,364,230,366,251,366,272,366,288,364,301,361,311,355,318,345,322,330,324,311,325,285,324,259,322,238,318,222,311,210,301,201,288,195,272,192,251,191,230,192,214,195,200,201,190,210,183,222,178,238,176,259],[125,283,129,236,139,199,156,172,181,155,212,144,251,141,289,144,321,155,344,172,361,199,372,236,375,283,373,319,368,348,358,371,344,389,327,402,306,410,280,414,251,416,221,414,196,410,174,402,156,389,143,371,133,348,127,319],[1,30,79,30,79,749,1,749]]],"%":[569,751,[[50,139,51,113,53,92,57,77,64,66,74,58,88,54,104,52,125,51,146,52,162,54,176,58,186,66,193,77,197,92,199,113,200,139,199,165,197,186,193,201,186,212,176,219,162,224,146,225,125,226,104,225,88,224,74,219,64,212,57,201,53,186,51,165],[0,144,3,96,14,59,31,32,55,15,87,4,125,1,163,4,195,15,219,32,236,59,247,96,250,144,248,180,242,210,233,232,219,250,201,263,180,270,154,275,125,276,95,275,70,270,49,263,31,250,17,232,8,210,2,180],[50,146,51,172,53,191,57,205,64,215,74,221,88,224,104,226,125,226,146,226,162,224,176,221,186,215,193,205,197,191,199,172,200,146,199,120,197,98,193,82,186,70,176,61,162,55,146,52,125,51,104,52,88,55,74,61,64,70,57,82,53,98,51,120],[0,144,3,96,14,59,31,32,55,15,87,4,125,1,163,4,195,15,219,32,236,59,247,96,250,144,248,180,242,210,233,232,219,250,201,263,180,270,154,275,125,276,95,275,70,270,49,263,31,250,17,232,8,210,2,180],[369,614,370,588,372,568,376,552,384,541,394,534,406,529,423,527,444,526,465,527,482,529,494,534,504,541,512,552,516,568,518,588,519,614,518,640,516,660,512,676,504,687,494,694,482,698,465,700,444,701,423,700,406,698,394,694,384,687,376,676,372,660,370,640],[319,619,322,571,333,534,350,508,374,490,406,480,444,476,482,479,514,490,538,508,555,534,566,571,569,619,567,655,562,684,552,707,538,725,520,738,498,746,473,750,444,751,414,750,389,746,368,738,350,725,336,707,326,684,321,655],[369,621,370,647,372,666,376,680,384,690,394,696,406,700,423,701,444,701,465,701,482,700,494,696,504,690,512,680,516,666,518,647,519,621,518,595,516,574,512,557,504,544,494,536,482,530,465,527,444,526,423,527,406,530,394,536,384,544,376,557,372,574,370,595],[319,619,322,571,333,534,350,508,374,490,406,480,444,476,482,479,514,490,538,508,555,534,566,571,569,619,567,655,562,684,552,707,538,725,520,738,498,746,473,750,444,751,414,750,389,746,368,738,350,725,336,707,326,684,321,655],[343,0,443,0,226,750,126,750]]],"&":[428,583,[[341,582,259,583,18,0,94,0,341,583],[302,283,78,283,80,458,428,280,428,370,386,391,349,410,318,425,292,438,253,458,227,470,213,477,209,478,211,478,215,476,219,474,221,472,217,474,203,482,177,494,137,514,111,528,79,543,42,562,0,583,0,208,30,208,54,208,72,207,87,207,99,207,110,207,120,207,132,207,147,207,165,208,188,208,219,208,221,205,220,82,190,83,170,84,159,84,152,84,149,85,150,85,147,86,140,86,129,86,110,87,80,88,40,0,303,0]]],"'":[208,164,[[208,0,193,43,172,78,149,107,126,129,98,149,68,164,0,164,23,137,41,113,55,91,70,63,79,40,84,18,84,0]]],"(":[445,806,[[405,0,445,2,445,89,416,88,387,89,370,91,352,93,335,96,317,100,301,104,285,110,269,116,252,124,233,134,214,148,194,164,174,182,157,200,142,220,129,240,120,259,108,290,100,320,93,349,88,379,88,403,90,433,94,464,102,496,112,527,126,558,144,587,165,615,190,640,218,663,249,683,285,698,325,708,328,708,336,710,346,712,356,714,368,716,380,718,389,719,396,719,445,719,445,806,374,806,355,805,332,802,308,796,284,790,260,783,236,775,217,768,202,761,180,749,157,735,134,718,112,698,91,675,73,652,58,628,46,605,39,590,32,574,27,558,22,543,20,537,18,525,14,509,10,492,6,474,3,458,1,445,0,437,0,373,0,368,1,360,2,352,4,343,5,334,6,326,8,321,8,318,14,292,20,266,28,239,38,212,51,186,66,160,86,134,110,109,143,82,176,60,209,42,242,28,275,18,308,11,341,6,374,1]]],")":[445,806,[[71,1,104,6,137,11,170,18,203,28,236,42,269,60,302,82,335,109,359,134,378,160,394,186,407,212,417,239,425,266,432,292,437,318,437,321,438,326,440,334,442,343,443,352,444,360,445,368,445,373,445,437,444,445,442,458,439,474,435,492,431,509,428,525,425,537,423,543,418,558,412,574,406,590,399,605,387,628,372,652,354,675,333,698,311,718,288,735,265,749,243,761,228,768,208,775,186,783,162,790,137,796,112,802,90,805,71,806,0,806,0,719,49,719,56,719,66,718,77,716,88,714,99,712,109,710,116,708,120,708,160,698,196,683,228,663,255,640,280,615,301,587,319,558,333,527,344,496,351,464,356,433,357,403,357,379,352,349,346,320,337,290,325,259,316,240,304,220,288,200,270,182,252,164,232,148,212,134,193,124,176,116,160,110,144,104,128,100,110,96,92,93,75,91,58,89,29,88,0,89,0,2,40,0]]],"*":[334,334,[[334,138,334,196,0,196,0,138],[138,0,196,0,196,334,138,334],[264,28,306,70,70,306,28,264],[28,70,70,28,306,264,264,306]]],"+":[445,445,[[445,183,445,261,0,261,0,183],[184,0,262,0,262,445,184,445]]],",":[176,266,[[88,0,123,6,151,26,170,54,176,88,176,103,174,120,171,136,165,154,156,171,145,190,130,209,110,228,107,230,102,235,95,241,88,248,80,255,74,260,70,265,68,266,0,266,19,243,38,220,53,197,66,174,37,161,16,140,4,114,0,88,6,54,26,26,54,6]]],"-":[445,78,[[445,0,445,78,0,78,0,0]]],".":[176,176,[[0,88,6,54,26,26,54,6,88,0,122,6,150,26,170,54,176,88,170,122,150,150,122,170,88,176,54,170,26,150,6,122]]],"/":[317,750,[[0,750,217,0,317,0,100,750]]],"0":[500,745,[[400,370,399,333,397,298,394,265,384,219,370,180,351,147,325,122,292,106,251,101,210,106,177,122,151,147,131,180,116,219,107,265,103,298,101,333,100,370,101,407,103,442,107,476,113,508,121,537,130,564,150,597,176,623,209,640,250,645,291,640,324,623,350,597,370,564,379,537,387,508,393,476,397,442,399,407],[0,373,0,371,0,370,0,369,0,368,1,330,4,293,9,257,16,222,28,180,44,141,63,106,85,75,111,49,140,28,173,12,210,3,250,0,289,2,323,9,353,20,380,35,405,52,427,72,446,96,462,127,475,162,484,201,492,242,496,285,499,328,500,369,500,373,500,374,499,413,496,450,491,486,484,521,472,564,457,603,438,638,416,669,390,695,360,716,327,732,290,742,250,745,249,745,209,742,172,732,139,716,110,695,84,669,62,638,43,603,28,564,16,521,9,486,4,450,1,413,0,374]]],"1":[456,749,[[23,381,23,423,22,465,20,507,18,545,16,585,13,626,9,669,5,710,0,749,68,749,75,715,81,680,88,646,95,612,101,583,108,553,114,522,121,492,128,462,134,432,141,405,147,381],[356,169,356,136,355,112,353,96,350,86,345,81,338,82,328,85,316,90,300,95,281,100,258,105,230,106,202,105,179,100,160,95,144,90,130,85,120,82,113,81,108,86,104,96,102,112,100,136,100,169,100,201,102,224,104,238,108,246,113,248,120,245,130,239,144,232,160,224,179,216,202,211,230,209,258,211,281,216,300,224,316,232,328,239,338,245,345,248,350,246,353,238,355,224,356,201],[0,172,0,170,0,169,0,168,0,167,1,120,6,82,12,54,29,24,52,8,83,1,122,1,154,3,189,5,229,5,259,4,288,2,317,1,344,0,368,2,390,6,410,15,426,29,437,42,445,52,450,62,454,73,455,87,456,106,456,133,456,168,456,172,456,173,455,220,451,256,444,283,435,302,422,314,406,320,386,322,363,320,336,318,305,314,270,310,230,309,229,309,189,310,154,314,122,318,95,320,72,322,52,320,35,314,22,302,12,283,6,256,1,220,0,173]]],"2":[456,749,[[23,381,23,423,22,465,20,507,18,545,16,585,13,626,9,669,5,710,0,749,68,749,75,715,81,680,88,646,95,612,101,583,108,553,114,522,121,492,128,462,134,432,141,405,147,381],[356,169,356,136,355,112,353,96,350,86,345,81,338,82,328,85,316,90,300,95,281,100,258,105,230,106,202,105,179,100,160,95,144,90,130,85,120,82,113,81,108,86,104,96,102,112,100,136,100,169,100,201,102,224,104,238,108,246,113,248,120,245,130,239,144,232,160,224,179,216,202,211,230,209,258,211,281,216,300,224,316,232,328,239,338,245,345,248,350,246,353,238,355,224,356,201],[0,172,0,170,0,169,0,168,0,167,1,120,6,82,12,54,29,24,52,8,83,1,122,1,154,3,189,5,229,5,259,4,288,2,317,1,344,0,368,2,390,6,410,15,426,29,437,42,445,52,450,62,454,73,455,87,456,106,456,133,456,168,456,172,456,173,455,220,451,256,444,283,435,302,422,314,406,320,386,322,363,320,336,318,305,314,270,310,230,309,229,309,189,310,154,314,122,318,95,320,72,322,52,320,35,314,22,302,12,283,6,256,1,220,0,173],[177,381,177,423,176,465,174,507,172,545,170,585,167,626,163,669,159,710,154,749,222,749,229,715,235,680,242,646,249,612,255,583,262,553,268,522,275,492,282,462,288,432,295,405,301,381]]],"3":[456,749,[[23,381,23,423,22,465,20,507,18,545,16,585,13,626,9,669,5,710,0,749,68,749,75,715,81,680,88,646,95,612,101,583,108,553,114,522,121,492,128,462,134,432,141,405,147,381],[331,381,331,423,330,465,328,507,326,545,324,585,321,626,317,669,313,710,308,749,376,749,383,715,389,680,396,646,403,612,409,583,416,553,422,522,429,492,436,462,442,432,449,405,455,381],[356,169,356,136,355,112,353,96,350,86,345,81,338,82,328,85,316,90,300,95,281,100,258,105,230,106,202,105,179,100,160,95,144,90,130,85,120,82,113,81,108,86,104,96,102,112,100,136,100,169,100,201,102,224,104,238,108,246,113,248,120,245,130,239,144,232,160,224,179,216,202,211,230,209,258,211,281,216,300,224,316,232,328,239,338,245,345,248,350,246,353,238,355,224,356,201],[0,172,0,170,0,169,0,168,0,167,1,120,6,82,12,54,29,24,52,8,83,1,122,1,154,3,189,5,229,5,259,4,288,2,317,1,344,0,368,2,390,6,410,15,426,29,437,42,445,52,450,62,454,73,455,87,456,106,456,133,456,168,456,172,456,173,455,220,451,256,444,283,435,302,422,314,406,320,386,322,363,320,336,318,305,314,270,310,230,309,229,309,189,310,154,314,122,318,95,320,72,322,52,320,35,314,22,302,12,283,6,256,1,220,0,173],[177,381,177,423,176,465,174,507,172,545,170,585,167,626,163,669,159,710,154,749,222,749,229,715,235,680,242,646,249,612,255,583,262,553,268,522,275,492,282,462,288,432,295,405,301,381]]],"4":[455,742,[[23,374,23,416,22,458,20,500,18,538,16,578,13,620,9,662,5,703,0,742,68,742,75,708,81,673,88,639,95,605,101,576,108,546,114,515,121,484,128,454,134,426,141,398,147,374],[0,192,455,192,455,292,0,292],[230,0,259,2,286,10,310,22,331,38,348,58,360,82,368,108,371,138,369,191,267,193,269,144,266,127,259,114,246,105,229,102,212,105,200,114,193,128,191,143,191,194,90,191,90,131,91,117,95,101,101,84,110,67,121,51,133,36,147,23,163,15,180,9,197,4,213,1]]],"5":[455,742,[[23,374,23,416,22,458,20,500,18,538,16,578,13,620,9,662,5,703,0,742,68,742,75,708,81,673,88,639,95,605,101,576,108,546,114,515,121,484,128,454,134,426,141,398,147,374],[0,192,455,192,455,292,0,292],[230,0,259,2,286,10,310,22,331,38,348,58,360,82,368,108,371,138,369,191,267,193,269,144,266,127,259,114,246,105,229,102,212,105,200,114,193,128,191,143,191,194,90,191,90,131,91,117,95,101,101,84,110,67,121,51,133,36,147,23,163,15,180,9,197,4,213,1],[177,374,177,416,176,458,174,500,172,538,170,578,167,620,163,662,159,703,154,742,222,742,229,708,235,673,242,639,249,605,255,576,262,546,268,515,275,484,282,454,288,426,295,398,301,374]]],"6":[455,742,[[23,374,23,416,22,458,20,500,18,538,16,578,13,620,9,662,5,703,0,742,68,742,75,708,81,673,88,639,95,605,101,576,108,546,114,515,121,484,128,454,134,426,141,398,147,374],[0,192,455,192,455,292,0,292],[230,0,259,2,286,10,310,22,331,38,348,58,360,82,368,108,371,138,369,191,267,193,269,144,266,127,259,114,246,105,229,102,212,105,200,114,193,128,191,143,191,194,90,191,90,131,91,117,95,101,101,84,110,67,121,51,133,36,147,23,163,15,180,9,197,4,213,1],[331,374,331,416,330,458,328,500,326,538,324,578,321,620,317,662,313,703,308,742,376,742,383,708,389,673,396,639,403,605,409,576,416,546,422,515,429,484,436,454,442,426,449,398,455,374],[177,374,177,416,176,458,174,500,172,538,170,578,167,620,163,662,159,703,154,742,222,742,229,708,235,673,242,639,249,605,255,576,262,546,268,515,275,484,282,454,288,426,295,398,301,374]]],"7":[455,750,[[23,382,23,424,22,466,20,508,18,546,16,586,13,628,9,670,5,711,0,750,68,750,75,716,81,681,88,647,95,613,101,584,108,554,114,523,121,492,128,462,134,434,141,406,147,382],[0,200,455,200,455,300,0,300],[0,0,455,0,455,100,0,100]]],"8":[455,750,[[23,382,23,424,22,466,20,508,18,546,16,586,13,628,9,670,5,711,0,750,68,750,75,716,81,681,88,647,95,613,101,584,108,554,114,523,121,492,128,462,134,434,141,406,147,382],[0,200,455,200,455,300,0,300],[0,0,455,0,455,100,0,100],[177,382,177,424,176,466,174,508,172,546,170,586,167,628,163,670,159,711,154,750,222,750,229,716,235,681,242,647,249,613,255,584,262,554,268,523,275,492,282,462,288,434,295,406,301,382]]],"9":[455,751,[[23,383,23,425,22,467,20,509,18,547,16,587,13,628,9,671,5,712,0,751,68,751,75,717,81,682,88,648,95,614,101,585,108,555,114,524,121,494,128,464,134,434,141,407,147,383],[0,201,455,201,455,301,0,301],[0,1,455,1,455,101,0,101,0,0],[331,383,331,425,330,467,328,509,326,547,324,587,321,628,317,671,313,712,308,751,376,751,383,717,389,682,396,648,403,614,409,585,416,555,422,524,429,494,436,464,442,434,449,407,455,383],[177,383,177,425,176,467,174,509,172,547,170,587,167,628,163,671,159,712,154,751,222,751,229,717,235,682,242,648,249,614,255,585,262,555,268,524,275,494,282,464,288,434,295,407,301,383]]],":":[176,399,[[0,311,6,277,26,248,54,229,88,223,122,229,150,248,170,277,176,311,170,345,150,374,122,393,88,399,54,393,26,374,6,345],[0,88,6,54,26,26,54,6,88,0,122,6,150,26,170,54,176,88,170,122,150,150,122,170,88,176,54,170,26,150,6,122]]],";":[176,491,[[0,88,6,54,26,26,54,6,88,0,122,6,150,26,170,54,176,88,170,122,150,150,122,170,88,176,54,170,26,150,6,122],[88,225,123,232,151,251,170,280,176,313,176,328,174,344,171,361,165,378,156,396,145,415,130,434,110,453,107,455,102,460,95,466,88,473,80,480,74,486,70,490,68,491,0,491,19,468,38,445,53,422,66,399,37,386,16,364,4,339,0,313,6,279,26,250,54,231]]],"<":[448,804,[[361,2,448,2,448,74,448,82,446,92,444,105,442,118,440,129,438,140,436,148,435,152,424,191,410,232,397,258,382,285,364,311,348,330,328,348,309,364,290,378,279,386,268,392,257,398,246,403,254,408,262,412,271,417,280,422,303,437,327,457,350,480,369,504,394,542,412,582,426,622,436,660,437,666,438,674,440,685,442,697,444,708,446,719,447,727,447,731,447,804,360,804,360,753,360,746,358,736,357,726,356,715,354,704,352,695,350,687,349,682,347,672,344,661,340,650,337,639,329,617,316,594,299,569,279,546,257,524,234,504,210,489,188,478,182,476,176,473,169,470,163,468,140,460,114,454,88,450,64,448,0,448,0,359,74,359,82,358,94,356,109,353,124,349,138,345,151,342,160,339,164,338,196,325,226,309,252,289,275,266,296,242,314,216,328,188,340,160,350,132,358,90,361,51,361,0]]],"=":[455,301,[[0,201,455,201,455,301,0,301],[0,1,455,1,455,101,0,101,0,0]]],">":[448,801,[[87,49,90,88,98,130,108,158,119,186,134,213,151,239,172,263,195,286,221,306,251,322,283,335,287,336,296,338,310,342,324,346,339,350,353,353,365,355,373,356,448,356,448,445,383,445,359,447,333,452,307,458,284,466,278,468,272,471,266,474,260,476,237,486,214,502,191,521,169,544,149,567,132,592,119,615,111,637,108,648,104,658,100,669,98,680,97,685,96,693,94,702,92,713,91,724,90,734,88,744,88,751,88,801,1,801,1,729,1,725,2,717,4,706,6,695,7,683,8,672,10,664,11,658,22,619,36,580,47,553,62,527,79,501,98,478,120,455,145,435,168,420,176,415,185,410,194,406,202,401,191,395,180,390,169,383,158,376,139,362,120,346,100,328,84,308,66,282,51,256,38,230,23,189,12,150,12,145,10,137,8,126,6,114,3,102,2,90,0,80,0,72,0,0,87,0]]],"?":[226,701,[[0,613,6,579,26,551,54,532,88,525,122,532,150,551,170,579,176,613,170,647,150,676,122,695,88,701,54,695,26,676,6,647],[0,132,0,1,49,0,90,3,125,9,166,25,196,47,215,74,224,106,226,140,222,175,213,210,200,247,182,286,160,327,133,370,65,370,80,337,93,307,102,280,113,245,118,215,120,191,118,171,112,156,105,144,80,128,43,126]]],"@":[500,551,[[102,327,103,334,104,342,105,350,106,358,108,375,112,391,118,407,130,423,136,429,143,434,150,438,158,440,169,443,181,446,194,449,205,450,294,450,297,450,304,448,313,446,321,444,329,442,336,440,343,439,351,438,386,429,422,414,459,395,494,380,494,382,494,384,492,390,491,396,489,404,487,411,484,418,482,425,481,430,473,449,463,469,449,488,430,507,417,516,400,525,383,532,364,539,345,544,326,548,308,550,293,551,202,551,198,550,186,548,172,546,160,544,143,541,126,536,107,529,89,519,72,507,56,492,41,476,30,457,17,425,8,392,4,359,1,327],[178,327,184,341,192,354,204,363,222,366,282,366,297,363,310,354,318,341,323,327,466,327,458,335,449,343,440,350,432,357,405,375,378,390,351,403,347,404,340,406,332,408,322,410,312,413,303,414,295,416,288,416,221,416,184,409,156,389,137,360,127,327],[1,327,1,320,0,314,1,237,3,222,5,207,7,192,10,177,17,147,28,116,45,86,69,56,83,43,98,33,112,25,127,19,132,18,142,15,156,12,170,8,185,5,200,2,213,1,222,0,277,0,292,1,308,3,324,6,340,10,350,12,360,16,369,19,379,23,400,32,420,46,438,64,454,84,467,105,478,126,485,147,490,166,490,170,492,178,493,188,495,200,497,211,498,222,500,231,500,236,500,283,498,286,494,293,488,301,483,307,475,318,466,327,323,327,324,322,325,318,325,315,325,311,325,257,324,250,323,242,320,232,317,223,313,214,308,206,302,200,295,197,283,194,276,193,270,192,260,192,239,193,222,194,208,199,196,206,188,215,182,226,178,238,176,250,175,263,175,308,176,317,178,327,127,327,126,322,126,316,126,311,126,305,126,282,127,252,132,225,139,201,151,180,168,164,190,152,217,144,251,142,267,143,284,145,303,149,320,156,336,166,350,180,361,196,368,217,370,225,372,238,374,251,375,261,375,305,398,279,398,230,397,217,395,200,391,183,385,166,377,150,367,135,355,123,340,116,335,115,331,114,327,112,322,110,321,110,316,109,311,108,304,106,297,105,290,104,285,103,281,103,219,103,211,104,200,106,188,108,176,112,164,115,152,120,144,125,138,129,124,147,116,164,111,182,107,199,105,211,103,225,102,236,101,241,101,322,101,323,102,324,102,325,102,327]]],"A":[500,750,[[166,750,0,0,100,0,250,650,401,0,500,0,333,750]]],"B":[500,750,[[100,407,400,407,400,97,0,97,0,0,500,0,500,503,200,503,200,750,100,750]]],"C":[500,750,[[200,653,200,0,300,0,300,653,500,653,500,749,0,750,0,654]]],"D":[500,750,[[100,318,100,0,200,0,200,221,500,221,500,750,0,750,0,653,399,653,400,653,400,318]]],"E":[500,745,[[0,447,0,303,500,0,500,134,100,377,498,613,498,745]]],"F":[500,750,[[0,0,500,0,500,100,100,100,100,650,500,650,500,750,0,750,1,727,1,726,0,726,0,727,0,726]]],"G":[500,750,[[0,0,100,0,100,648,400,648,400,0,500,0,500,750,400,750,398,750,0,750]]],"H":[500,750,[[0,0,500,0,500,750,0,750,0,650,400,650,400,100,0,100]]],"I":[500,750,[[166,0,333,0,500,750,400,750,250,100,100,750,0,750]]],"J":[500,750,[[0,0,500,0,500,100,100,99,100,750,0,750]]],"K":[500,750,[[100,100,99,750,0,750,0,0,500,0,500,750,400,750,400,100]]],"L":[500,750,[[400,650,100,650,100,750,0,750,0,0,500,0,500,750,400,750],[400,550,400,100,101,100,100,550]]],"M":[500,751,[[368,750,0,750,0,650,360,650,365,650,400,441,400,425,0,425,0,325,400,325,400,100,0,100,0,0,500,0,500,422,500,441,450,751]]],"N":[500,750,[[350,750,394,441,394,425,0,425,0,325,400,325,400,100,0,100,0,0,500,0,500,351,500,441,450,750]]],"O":[500,750,[[500,425,454,421,416,429,385,447,360,472,340,503,324,540,314,578,306,618,301,656,300,692,299,725,300,750,200,750,200,704,198,661,195,620,189,583,180,550,168,520,152,493,132,471,107,452,77,439,42,429,0,425,0,325,41,318,77,307,107,294,133,277,161,252,182,224,197,194,207,163,212,130,212,96,210,62,206,30,200,0,300,0,308,42,313,84,314,125,310,165,303,203,292,238,276,271,255,301,230,326,200,348,165,364,125,375,145,382,166,391,186,403,205,418,222,436,235,457,245,480,250,505,259,467,271,434,284,406,310,372,340,346,374,330,412,322,455,320,500,325,500,375]]],"P":[500,749,[[415,350,100,350,100,650,500,650,500,749,1,749,0,250,315,250,315,0,415,0,415,340]]],"Q":[500,750,[[100,325,500,325,500,425,100,425,100,750,0,750,0,0,100,0]]],"R":[500,750,[[300,650,450,650,450,750,50,750,50,650,200,650,200,100,0,100,0,0,500,0,500,100,300,100]]],"S":[500,750,[[0,0,500,0,500,100,100,100,100,325,500,325,500,750,400,750,371,750,0,750,0,650,400,650,400,425,0,425]]],"T":[500,750,[[300,100,300,750,200,750,200,100,0,100,0,0,500,0,500,100]]],"U":[500,750,[[500,325,500,425,0,750,0,650,400,373,0,100,0,0]]],"V":[500,750,[[100,100,500,100,500,200,350,200,350,400,250,400,250,200,100,200,100,750,0,750,0,0,100,0]]],"W":[500,750,[[100,425,100,675,0,675,0,75,100,75,100,326,400,326,400,0,500,0,500,750,400,750,400,425]]],"X":[500,750,[[0,0,100,0,100,650,200,650,200,0,500,0,500,750,400,750,400,100,300,100,300,750,0,750,0,461,0,18]]],"Y":[500,750,[[100,100,100,650,500,650,500,750,0,750,0,720,0,688,0,652,0,614,0,572,0,527,0,479,0,428,0,374,0,321,0,270,0,222,0,177,0,136,0,97,0,62,0,29,0,0,500,0,500,100,350,100,350,400,250,400,250,100]]],"Z":[500,750,[[500,0,500,750,400,750,400,100,0,100,0,0]]],"[":[200,783,[[0,0,200,0,200,98,98,98,98,686,200,686,200,783,0,783]]],"\\":[317,750,[[317,750,217,750,0,0,100,0]]],"]":[200,783,[[200,0,200,783,0,783,0,686,102,686,102,98,0,98,0,0]]],"^":[804,448,[[802,361,802,448,730,448,722,448,712,446,699,445,686,442,675,440,664,438,656,436,652,435,613,424,572,410,546,397,519,382,493,364,474,348,456,328,440,309,426,290,418,279,412,268,406,257,401,246,396,254,392,262,387,271,382,280,367,303,347,327,324,350,300,369,262,394,222,412,182,426,144,436,138,437,130,438,119,440,107,442,96,444,85,446,77,447,73,447,0,447,0,360,51,360,58,360,68,358,78,357,89,356,100,354,109,352,117,350,122,349,132,347,143,344,154,340,165,337,187,329,210,316,235,299,258,279,280,257,300,234,315,211,326,188,328,182,331,176,334,169,336,163,344,140,350,114,354,88,356,64,356,0,445,0,445,74,446,82,448,94,451,109,455,124,459,138,462,151,465,160,466,164,479,196,495,226,515,252,538,275,562,296,588,314,616,328,644,340,672,350,714,358,753,361,804,361]]],"_":[672,96,[[672,22,672,96,0,95,0,0,672,0]]],"`":[211,164,[[124,0,126,38,136,72,150,100,166,123,187,146,211,164,143,164,105,141,74,115,50,88,31,61,14,31,0,0]]],"a":[503,499,[[298,499,210,499,0,0,104,0,254,375,404,0,503,0]]],"b":[500,500,[[194,266,400,266,400,95,0,95,0,0,500,0,500,353,500,363,499,363,200,363,200,500,100,500,100,266]]],"c":[500,496,[[300,399,500,399,500,496,0,496,0,399,200,398,200,0,300,0]]],"d":[500,500,[[208,230,111,230,111,224,111,0,211,0,211,130,500,130,500,139,500,500,0,500,0,400,400,400,400,230]]],"e":[499,503,[[0,298,0,210,499,0,499,104,124,254,499,404,499,503]]],"f":[500,500,[[0,0,500,0,500,100,97,100,97,400,495,400,495,500,1,500,0,500]]],"g":[500,500,[[0,500,0,0,99,0,99,402,403,402,403,0,500,0,500,500,499,500]]],"h":[500,500,[[500,500,0,500,0,400,400,400,400,100,0,100,0,0,497,1,500,0]]],"i":[503,499,[[205,0,293,0,503,499,399,499,249,124,99,499,0,499]]],"j":[500,500,[[0,0,500,0,500,100,99,101,100,100,100,500,0,500]]],"k":[500,500,[[500,0,500,500,400,500,402,96,400,100,100,100,100,500,0,500,0,0]]],"l":[500,499,[[400,399,100,400,100,499,0,499,0,0,500,0,500,499,400,499],[400,299,400,99,100,99,100,299]]],"m":[503,500,[[400,200,400,100,386,100,0,100,0,0,503,0,500,0,500,286,500,306,500,500,0,500,0,400,400,400,400,300,0,300,0,200]]],"n":[500,500,[[400,500,400,414,400,300,0,300,0,200,400,200,400,100,0,100,0,0,500,0,500,287,500,290,500,500]]],"o":[500,500,[[0,291,0,191,43,191,84,184,120,170,150,151,172,127,190,100,198,76,203,43,205,0,305,0,304,39,303,71,300,96,292,127,279,158,261,187,240,210,213,228,174,241,194,248,208,255,216,261,224,268,231,274,238,282,246,296,255,320,264,297,276,274,294,252,319,230,348,212,381,200,409,194,449,192,500,191,500,291,462,291,429,295,402,301,370,315,346,334,329,357,316,384,308,416,305,455,305,465,305,478,305,490,305,500,205,500,205,490,205,478,205,465,205,455,201,418,194,389,182,366,160,340,132,319,102,304,73,296,40,292]]],"p":[500,500,[[317,230,100,230,100,399,500,400,500,500,0,500,0,129,0,130,315,130,315,0,415,0,415,230]]],"q":[500,500,[[100,300,100,500,0,500,0,0,100,0,100,200,500,200,500,300]]],"r":[503,500,[[301,100,301,400,302,400,503,400,503,500,1,500,1,400,201,400,201,100,0,100,0,0,501,0,501,100]]],"s":[500,500,[[0,1,500,0,500,100,105,100,105,198,107,200,142,200,178,200,216,200,255,200,296,200,337,200,379,200,419,200,460,200,500,200,500,500,460,500,421,500,380,500,339,500,298,500,256,500,215,500,172,500,130,500,87,500,44,500,0,500,0,405,400,405,400,300,0,300]]],"t":[500,500,[[200,100,0,100,0,0,500,0,500,100,300,100,300,500,200,500]]],"u":[499,503,[[499,205,499,293,0,503,0,399,375,249,0,99,0,0]]],"v":[499,500,[[99,100,499,100,499,200,349,200,349,350,249,350,249,200,99,200,99,500,0,500,0,0,99,0]]],"w":[500,500,[[400,300,100,300,100,500,0,500,0,0,100,0,100,200,400,200,400,0,500,0,500,500,400,500]]],"x":[500,500,[[0,500,0,0,100,0,100,400,200,400,200,382,200,342,200,299,200,252,200,202,200,162,200,121,200,80,200,40,200,0,500,0,500,40,500,80,500,121,500,162,500,204,500,246,500,289,500,332,500,374,500,416,500,458,500,500,400,500,400,100,300,100,300,500]]],"y":[500,500,[[250,100,100,100,100,400,500,400,500,500,0,500,0,0,500,0,500,100,350,100,350,129,350,300,250,300]]],"z":[500,500,[[500,0,500,500,400,500,400,100,0,100,0,0]]],"{":[340,806,[[158,0,245,0,245,74,243,106,236,143,225,181,212,218,197,253,180,284,164,310,148,326,156,330,170,336,186,341,203,346,221,352,238,356,254,358,266,359,340,359,340,390,340,446,334,447,330,447,329,447,327,447,326,447,323,447,320,447,317,448,274,447,260,448,244,450,226,454,208,458,190,463,174,469,159,475,148,480,162,498,174,516,186,534,196,551,203,566,212,586,220,610,228,636,234,662,240,688,244,712,245,731,245,805,157,806,157,753,156,730,152,704,151,697,150,690,148,683,146,675,138,648,127,620,113,593,95,566,74,541,50,517,25,493,1,469,24,447,48,430,72,416,95,403,72,391,48,376,23,358,0,337,17,320,34,302,52,286,69,270,89,249,104,228,117,206,128,185,133,174,138,158,143,140,148,122,152,102,155,83,157,66,158,51]]],"|":[100,750,[[100,750,0,750,0,0,100,0]]],"}":[340,808,[[182,53,183,68,185,85,188,104,192,124,197,142,202,160,207,175,212,186,223,207,236,229,251,251,271,272,288,288,306,304,323,322,340,339,317,360,292,378,268,393,245,405,268,418,292,432,316,449,339,471,315,494,290,518,266,543,245,568,227,595,213,622,202,650,195,677,193,685,191,692,189,698,188,706,186,718,184,731,183,744,183,755,183,808,95,808,95,733,96,714,100,690,106,664,112,638,120,612,128,588,137,567,144,552,154,535,166,517,178,499,192,482,181,477,166,471,150,465,132,460,114,456,96,452,80,450,66,449,23,449,20,449,17,448,14,448,13,448,11,448,10,448,6,449,0,448,0,391,0,360,74,360,86,359,102,356,119,353,137,348,154,343,170,338,184,332,192,328,176,312,160,286,143,255,128,220,115,183,104,145,97,108,95,76,95,0,182,1]]],"~":[409,161,[[126,0,135,0,142,1,151,3,160,6,160,2,161,0,230,0,230,38,234,59,246,76,264,86,283,89,291,88,300,86,309,83,318,78,325,72,332,65,336,56,337,46,337,0,409,0,409,48,408,54,406,64,404,73,403,77,400,90,392,104,382,118,369,130,355,141,340,150,326,156,314,158,309,158,304,160,299,161,297,161,271,161,251,157,251,161,179,161,179,123,175,102,162,86,143,75,124,72,107,76,90,86,76,102,72,120,72,161,0,161,0,117,1,103,5,87,11,70,20,54,31,39,44,26,59,15,76,8,90,4,102,2,113,0]]]},"chesilin":{"!":[97,844,[[47,0,97,0,97,6,96,12,94,24,92,40,90,53,86,74,83,96,80,118,77,139,76,144,74,158,72,177,68,198,62,218,55,236,46,250,37,254,0,250,4,209,10,167,16,126,23,84,34,42],[47,595,97,595,97,601,96,611,94,630,90,657,86,686,81,717,76,747,71,773,67,792,66,798,64,806,61,814,58,822,55,830,50,838,46,842,42,844,0,844,4,803,10,761,16,720,23,679,34,637]]],",":[432,844,[[424,0,428,1,430,4,431,8,432,12,432,92,430,118,426,153,422,195,414,241,407,273,399,306,388,338,376,370,362,400,345,428,326,454,304,476,279,495,251,509,220,518,185,521,142,520,119,517,96,514,72,506,50,494,36,482,24,469,16,455,10,440,5,424,2,408,0,393,0,379,0,332,3,298,3,87,4,82,5,71,8,57,11,42,16,27,21,14,28,4,36,1,39,2,41,5,43,9,44,14,44,18,44,22,44,26,44,27,43,219,42,254,42,275,41,286,40,293,40,297,40,300,40,306,41,321,43,337,47,354,55,370,70,385,97,403,126,412,154,416,183,419,195,420,202,420,206,419,209,419,245,416,276,408,302,394,333,364,356,328,367,300,376,271,382,239,385,207,388,175,390,144,392,78,393,70,395,58,398,45,401,32,405,20,410,10,417,2],[54,590,336,590,321,739,321,751,320,755,318,766,314,782,310,798,305,815,299,830,293,840,286,844,24,844,24,796,24,791,25,780,26,767,27,756,30,714,35,673,42,632]]],".":[317,844,[[30,0,317,0,317,6,317,11,316,23,313,37,311,48,308,73,304,98,300,123,297,148,296,155,294,169,291,186,286,205,282,223,276,239,269,250,262,254,0,254,0,198,1,187,2,168,5,143,8,118,11,92,14,69,16,51,17,42,19,32,22,21,26,10],[30,591,317,591,317,597,317,602,316,613,313,627,311,638,308,664,304,688,300,713,297,738,296,745,294,759,291,776,286,795,282,813,276,829,269,840,262,844,0,844,0,788,1,777,2,758,5,733,8,708,11,682,14,659,16,641,17,632,19,622,22,612,26,601]]],"0":[362,664,[[362,0,362,59,361,68,356,77,349,85,341,93,225,93,225,567,362,567,362,630,361,640,356,648,349,656,341,664,0,664,0,620,2,609,7,597,14,584,22,571,133,571,133,93,0,93,0,49,2,38,7,26,14,13,22,0]]],"1":[264,659,[[264,0,264,638,252,646,238,653,225,658,214,659,174,659,174,94,0,94,0,50,2,39,7,27,14,14,22,0]]],"2":[263,662,[[263,0,263,623,262,633,256,644,248,653,242,662,0,662,0,613,2,602,8,590,16,578,27,566,173,566,173,21,195,12,225,5]]],"3":[262,658,[[262,0,262,636,254,642,242,650,231,656,220,658,177,658,177,372,0,372,0,323,2,312,8,300,16,286,27,274,62,274,90,274,111,274,128,274,140,274,150,274,160,275,170,275,170,21,188,14,208,8,233,4]]],"4":[362,663,[[195,0,235,0,235,565,362,565,362,629,361,638,356,647,348,655,340,663,0,663,0,618,1,607,6,595,14,582,22,570,144,570,144,21,157,13,171,6,184,1]]],"5":[362,659,[[362,0,362,60,361,70,356,78,348,86,340,94,223,94,223,637,210,645,196,652,184,657,173,659,132,659,132,93,0,93,0,49,1,38,6,26,14,14,22,0]]],"6":[368,664,[[27,0,368,0,368,642,350,650,331,657,314,662,301,664,292,663,286,662,282,659,277,658,277,96,6,96,5,92,2,86,1,79,0,70,2,57,8,38,16,18]]],"7":[366,663,[[116,0,366,0,366,69,365,78,361,84,355,91,350,98,95,98,95,642,83,648,70,656,58,662,47,663,0,663,0,27,11,20,26,14,43,10,61,6,78,3,94,2,108,0]]],"8":[364,663,[[51,0,91,0,91,568,364,568,364,629,362,638,357,647,350,655,342,663,0,663,0,22,14,14,28,6,40,2]]],"9":[367,663,[[367,0,367,624,366,634,360,644,352,654,346,663,0,663,0,614,2,603,8,591,16,578,27,567,277,567,277,22,294,14,314,8,338,4]]],"?":[432,844,[[425,0,429,1,432,6,432,10,432,13,432,93,430,120,426,156,422,198,414,244,407,275,399,308,388,340,376,372,362,403,345,430,326,456,304,478,279,496,251,511,219,519,184,522,155,522,134,520,113,516,92,512,71,505,49,494,32,479,20,461,11,442,5,422,2,402,0,383,0,365,0,349,0,316,0,280,1,243,1,206,1,171,2,136,2,104,4,76,5,69,6,58,9,46,13,34,18,22,23,12,30,4,37,2,40,3,42,8,44,12,45,15,45,231,41,315,43,330,46,346,52,361,63,378,72,388,86,396,102,403,119,409,137,414,154,417,170,419,182,420,224,420,244,418,264,412,285,403,304,391,323,376,340,358,353,337,363,315,374,277,382,238,386,199,390,161,392,72,393,65,396,55,398,43,402,31,406,20,412,10,418,2],[166,595,216,595,216,601,216,606,214,617,212,631,210,642,206,666,202,690,199,714,196,738,195,745,193,759,190,776,186,795,180,813,174,829,168,840,161,844,120,844,124,803,129,761,135,720,142,679,153,637]]],"A":[78,321,[[45,0,78,0,78,276,76,286,72,297,66,308,61,321,42,321,42,102,34,100,25,101,16,102,7,103,3,99,1,96,0,91,0,83,0,77,2,66,4,52,8,38,14,24,22,12,32,3]]],"B":[290,1006,[[189,531,178,532,164,534,151,538,142,542,130,555,119,571,110,590,102,610,97,630,93,650,91,668,90,683,90,727,91,743,94,762,100,784,106,806,114,826,122,846,132,864,143,877,162,894,180,906,198,913,216,919,214,531],[271,0,275,0,280,1,284,3,287,7,290,578,290,985,288,990,281,994,272,997,262,1000,251,1003,242,1004,234,1006,231,1006,224,1005,218,1004,215,999,215,989,209,992,202,994,194,996,187,997,152,994,121,986,95,972,63,944,38,910,20,871,8,830,2,789,0,752,0,725,2,711,3,698,4,684,7,670,10,657,14,644,19,630,23,616,34,588,53,560,76,534,102,510,131,490,160,474,188,462,214,458,212,24,214,19,220,14,228,10,237,7,247,4,257,2,266,0],[189,531,178,532,164,534,151,538,142,542,130,555,119,571,110,590,102,610,97,630,93,650,91,668,90,683,90,727,91,743,94,762,100,784,106,806,114,826,122,846,132,864,143,877,162,894,180,906,198,913,216,919,214,531],[271,0,275,0,280,1,284,3,287,7,290,578,290,985,288,990,281,994,272,997,262,1000,251,1003,242,1004,234,1006,231,1006,224,1005,218,1004,215,999,215,989,209,992,202,994,194,996,187,997,152,994,121,986,95,972,63,944,38,910,20,871,8,830,2,789,0,752,0,725,2,711,3,698,4,684,7,670,10,657,14,644,19,630,23,616,34,588,53,560,76,534,102,510,131,490,160,474,188,462,214,458,212,24,214,19,220,14,228,10,237,7,247,4,257,2,266,0]]],"C":[290,1005,[[77,314,76,709,85,706,94,704,104,703,113,702,122,701,131,699,140,696,148,690,164,674,176,656,184,639,190,621,193,603,196,586,198,568,200,551,200,522,199,502,197,479,193,455,187,430,179,406,168,384,154,363,137,345,106,324],[63,0,67,0,70,0,74,1,78,4,78,237,83,236,90,236,95,235,98,235,138,239,175,252,209,273,231,295,251,322,267,355,280,393,281,399,283,406,285,415,286,424,288,432,289,440,290,445,290,448,290,517,286,556,275,598,264,625,249,652,232,677,212,701,189,722,164,741,136,757,106,768,74,775,74,981,72,986,67,990,59,995,50,998,40,1001,30,1003,21,1004,15,1005,11,1005,6,1004,3,1003,0,998,4,23,5,19,10,14,19,10,28,7,39,4,49,2,58,0],[77,314,76,709,85,706,94,704,104,703,113,702,122,701,131,699,140,696,148,690,164,674,176,656,184,639,190,621,193,603,196,586,198,568,200,551,200,522,199,502,197,479,193,455,187,430,179,406,168,384,154,363,137,345,106,324],[63,0,67,0,70,0,74,1,78,4,78,237,83,236,90,236,95,235,98,235,138,239,175,252,209,273,231,295,251,322,267,355,280,393,281,399,283,406,285,415,286,424,288,432,289,440,290,445,290,448,290,517,286,556,275,598,264,625,249,652,232,677,212,701,189,722,164,741,136,757,106,768,74,775,74,981,72,986,67,990,59,995,50,998,40,1001,30,1003,21,1004,15,1005,11,1005,6,1004,3,1003,0,998,4,23,5,19,10,14,19,10,28,7,39,4,49,2,58,0]]],"D":[289,1006,[[215,75,199,82,184,84,168,85,154,89,138,98,125,112,115,129,108,144,106,151,103,160,100,172,97,186,94,199,92,212,90,224,89,233,89,278,90,298,94,322,100,347,109,372,120,397,134,420,151,440,171,454,172,455,176,457,182,460,189,463,196,466,202,469,208,471,211,472,213,472],[274,0,277,0,282,2,287,3,289,5,286,982,283,987,276,992,268,996,259,999,249,1002,240,1004,231,1006,225,1006,221,1006,216,1004,212,1002,211,999,213,549,213,548,212,548,208,548,200,549,192,550,188,550,168,549,148,546,127,540,106,530,87,518,68,503,51,484,36,461,28,444,20,427,14,409,10,392,9,387,8,380,6,370,4,360,3,349,2,340,0,333,0,329,0,278,2,244,8,210,18,178,32,147,49,119,69,94,92,71,117,51,144,34,173,21,204,13,235,9,244,7,252,5,259,3,265,2,270,0],[215,75,199,82,184,84,168,85,154,89,138,98,125,112,115,129,108,144,106,151,103,160,100,172,97,186,94,199,92,212,90,224,89,233,89,278,90,298,94,322,100,347,109,372,120,397,134,420,151,440,171,454,172,455,176,457,182,460,189,463,196,466,202,469,208,471,211,472,213,472],[274,0,277,0,282,2,287,3,289,5,286,982,283,987,276,992,268,996,259,999,249,1002,240,1004,231,1006,225,1006,221,1006,216,1004,212,1002,211,999,213,549,213,548,212,548,208,548,200,549,192,550,188,550,168,549,148,546,127,540,106,530,87,518,68,503,51,484,36,461,28,444,20,427,14,409,10,392,9,387,8,380,6,370,4,360,3,349,2,340,0,333,0,329,0,278,2,244,8,210,18,178,32,147,49,119,69,94,92,71,117,51,144,34,173,21,204,13,235,9,244,7,252,5,259,3,265,2,270,0]]],"E":[109,270,[[54,0,72,10,85,20,95,30,102,40,106,50,108,60,109,71,109,83,108,102,103,126,96,152,88,180,79,207,70,233,62,255,55,270,46,263,36,254,27,245,18,235,11,225,5,215,1,206,0,197,1,188,5,170,11,145,18,118,26,87,36,56,45,26]]],"F":[393,1006,[[78,534,76,931,82,929,88,926,95,924,100,923,134,918,169,909,204,896,235,877,262,853,284,824,298,790,303,750,298,709,284,670,261,635,238,611,209,588,176,569,138,551,134,550,128,547,119,544,109,541,100,538,91,536,84,534,81,534],[64,0,68,0,74,2,80,4,80,8,77,457,103,457,138,459,174,467,211,479,248,496,283,518,317,544,319,24,320,19,326,14,334,10,344,7,354,4,364,2,372,0,378,0,382,0,386,0,389,2,393,5,391,674,392,682,393,690,393,698,393,706,389,748,376,787,356,824,332,857,302,887,268,914,232,938,196,958,158,974,122,986,89,994,58,997,47,998,36,1002,25,1005,14,1006,11,1006,6,1005,3,1003,0,999,5,25,5,21,10,16,19,12,29,8,40,4,50,2,59,0],[78,534,76,931,82,929,88,926,95,924,100,923,134,918,169,909,204,896,235,877,262,853,284,824,298,790,303,750,298,709,284,670,261,635,238,611,209,588,176,569,138,551,134,550,128,547,119,544,109,541,100,538,91,536,84,534,81,534],[64,0,68,0,74,2,80,4,80,8,77,457,103,457,138,459,174,467,211,479,248,496,283,518,317,544,319,24,320,19,326,14,334,10,344,7,354,4,364,2,372,0,378,0,382,0,386,0,389,2,393,5,391,674,392,682,393,690,393,698,393,706,389,748,376,787,356,824,332,857,302,887,268,914,232,938,196,958,158,974,122,986,89,994,58,997,47,998,36,1002,25,1005,14,1006,11,1006,6,1005,3,1003,0,999,5,25,5,21,10,16,19,12,29,8,40,4,50,2,59,0]]],"G":[392,1005,[[75,84,77,474,82,474,87,475,96,475,112,474,152,468,194,454,221,440,247,420,271,395,285,376,294,356,299,336,302,316,303,308,303,304,303,302,303,300,300,271,292,242,278,212,257,182,230,156,197,132,167,115,136,101,105,91],[59,0,66,0,72,2,75,7,75,17,85,12,92,10,99,8,108,8,131,10,157,14,184,22,211,32,238,44,264,58,288,73,309,89,333,112,353,136,368,160,379,184,380,186,382,192,384,198,386,206,388,214,390,222,392,229,392,233,392,984,390,988,384,992,378,994,375,996,373,996,368,998,362,999,354,1000,347,1002,340,1004,335,1005,332,1005,329,1005,323,1004,318,1001,318,998,315,427,285,454,256,476,226,495,196,510,157,526,117,539,77,548,79,980,77,986,71,990,63,995,54,998,44,1001,34,1003,25,1004,19,1005,16,1005,12,1004,9,1003,5,1000,0,22,3,18,10,14,17,10,26,7,35,4,44,2,53,0],[75,84,77,474,82,474,87,475,96,475,112,474,152,468,194,454,221,440,247,420,271,395,285,376,294,356,299,336,302,316,303,308,303,304,303,302,303,300,300,271,292,242,278,212,257,182,230,156,197,132,167,115,136,101,105,91],[59,0,66,0,72,2,75,7,75,17,85,12,92,10,99,8,108,8,131,10,157,14,184,22,211,32,238,44,264,58,288,73,309,89,333,112,353,136,368,160,379,184,380,186,382,192,384,198,386,206,388,214,390,222,392,229,392,233,392,984,390,988,384,992,378,994,375,996,373,996,368,998,362,999,354,1000,347,1002,340,1004,335,1005,332,1005,329,1005,323,1004,318,1001,318,998,315,427,285,454,256,476,226,495,196,510,157,526,117,539,77,548,79,980,77,986,71,990,63,995,54,998,44,1001,34,1003,25,1004,19,1005,16,1005,12,1004,9,1003,5,1000,0,22,3,18,10,14,17,10,26,7,35,4,44,2,53,0]]],"H":[288,997,[[272,0,275,0,280,2,286,4,286,8,288,505,274,516,258,522,241,525,225,527,220,528,214,530,209,532,204,532,201,532,196,532,192,531,189,531,179,532,166,534,153,537,145,541,132,552,121,567,112,586,104,606,98,627,94,648,91,666,90,681,90,728,91,738,93,750,96,765,100,781,103,796,106,810,109,820,111,825,116,838,125,853,136,868,148,881,160,893,174,904,189,912,203,917,209,919,216,920,222,921,230,922,234,923,240,923,245,923,250,924,254,926,257,929,259,933,260,938,258,950,251,962,241,971,230,980,218,987,206,992,194,996,186,997,151,994,121,986,95,972,63,944,38,910,19,871,8,830,2,790,0,753,0,719,3,693,8,668,14,643,22,617,34,589,52,561,76,534,102,510,130,490,160,474,188,462,214,458,211,24,214,20,220,16,228,12,238,8,248,5,258,2,266,1]]],"I":[180,82,[[0,0,143,0,148,6,154,14,160,21,166,28,172,36,176,43,179,50,180,55,180,82,54,82,48,80,40,74,31,66,22,58,14,48,6,38,2,29,0,23]]],"J":[291,1006,[[78,535,75,931,81,929,87,928,93,926,98,924,105,922,111,922,122,922,134,918,145,912,156,904,165,893,174,882,180,870,184,860,186,853,188,843,191,832,194,819,197,806,199,794,200,782,201,773,201,729,200,710,196,687,190,662,182,636,171,612,157,589,141,570,122,555,119,554,114,551,108,548,101,544,94,541,88,538,83,536,80,535],[64,0,68,0,74,2,80,4,80,8,77,457,103,457,134,459,163,467,188,479,221,504,246,534,266,568,280,606,288,643,291,678,291,734,289,768,282,800,272,832,257,861,240,889,220,914,197,936,172,956,144,972,116,985,87,993,57,997,46,999,34,1002,24,1005,14,1006,11,1006,6,1006,3,1004,0,1000,5,25,5,21,10,16,19,12,29,8,40,5,50,2,59,1],[78,535,75,931,81,929,87,928,93,926,98,924,105,922,111,922,122,922,134,918,145,912,156,904,165,893,174,882,180,870,184,860,186,853,188,843,191,832,194,819,197,806,199,794,200,782,201,773,201,729,200,710,196,687,190,662,182,636,171,612,157,589,141,570,122,555,119,554,114,551,108,548,101,544,94,541,88,538,83,536,80,535],[64,0,68,0,74,2,80,4,80,8,77,457,103,457,134,459,163,467,188,479,221,504,246,534,266,568,280,606,288,643,291,678,291,734,289,768,282,800,272,832,257,861,240,889,220,914,197,936,172,956,144,972,116,985,87,993,57,997,46,999,34,1002,24,1005,14,1006,11,1006,6,1006,3,1004,0,1000,5,25,5,21,10,16,19,12,29,8,40,5,50,2,59,1]]],"K":[290,1005,[[77,314,76,709,85,706,94,704,104,703,113,702,122,701,131,699,140,696,148,690,164,674,176,656,184,639,190,621,193,603,196,586,198,568,200,551,200,522,199,502,197,479,193,455,187,430,179,406,168,384,154,363,137,345,106,324],[63,0,67,0,70,0,74,1,78,4,78,237,83,236,90,236,95,235,98,235,138,239,175,252,209,273,231,295,251,322,267,355,280,393,281,399,283,406,285,415,286,424,288,432,289,440,290,445,290,448,290,517,286,556,275,598,264,625,249,652,232,677,212,701,189,722,164,741,136,757,106,768,74,775,74,981,72,986,67,990,59,995,50,998,40,1001,30,1003,21,1004,15,1005,11,1005,6,1004,3,1003,0,998,4,23,5,19,10,14,19,10,28,7,39,4,49,2,58,0],[77,314,76,709,85,706,94,704,104,703,113,702,122,701,131,699,140,696,148,690,164,674,176,656,184,639,190,621,193,603,196,586,198,568,200,551,200,522,199,502,197,479,193,455,187,430,179,406,168,384,154,363,137,345,106,324],[63,0,67,0,70,0,74,1,78,4,78,237,83,236,90,236,95,235,98,235,138,239,175,252,209,273,231,295,251,322,267,355,280,393,281,399,283,406,285,415,286,424,288,432,289,440,290,445,290,448,290,517,286,556,275,598,264,625,249,652,232,677,212,701,189,722,164,741,136,757,106,768,74,775,74,981,72,986,67,990,59,995,50,998,40,1001,30,1003,21,1004,15,1005,11,1005,6,1004,3,1003,0,998,4,23,5,19,10,14,19,10,28,7,39,4,49,2,58,0]]],"L":[487,1009,[[187,77,160,81,139,94,123,112,110,133,102,157,96,182,92,207,90,228,90,251,90,266,92,283,94,300,96,315,100,334,107,356,116,380,129,402,144,423,162,441,183,455,207,463,209,77,205,78,198,78,192,77],[282,548,280,934,309,934,333,929,352,916,367,896,379,872,388,848,393,823,396,801,397,784,397,738,396,723,393,706,388,686,383,666,377,647,370,629,362,613,355,601,337,582,318,566,300,555],[268,0,273,0,276,0,280,2,284,5,282,471,282,472,283,472,286,471,291,470,297,468,300,467,345,472,383,488,415,513,442,543,462,578,476,615,484,653,487,689,487,748,486,753,485,762,483,774,480,787,478,800,476,811,474,820,473,825,468,842,461,860,452,877,442,894,421,923,398,947,373,967,347,982,321,994,294,1002,268,1007,242,1009,232,1008,222,1007,212,1004,205,999,207,540,202,541,196,542,190,543,187,543,155,541,127,533,102,521,70,496,44,466,24,431,10,393,3,355,0,320,0,270,0,265,2,257,3,248,4,238,6,228,8,220,9,214,9,210,17,181,28,151,43,121,64,92,90,65,118,43,148,26,178,12,207,5,236,2,253,2,256,2,261,1,266,0],[187,77,160,81,139,94,123,112,110,133,102,157,96,182,92,207,90,228,90,251,90,266,92,283,94,300,96,315,100,334,107,356,116,380,129,402,144,423,162,441,183,455,207,463,209,77,205,78,198,78,192,77],[282,548,280,934,309,934,333,929,352,916,367,896,379,872,388,848,393,823,396,801,397,784,397,738,396,723,393,706,388,686,383,666,377,647,370,629,362,613,355,601,337,582,318,566,300,555],[268,0,273,0,276,0,280,2,284,5,282,471,282,472,283,472,286,471,291,470,297,468,300,467,345,472,383,488,415,513,442,543,462,578,476,615,484,653,487,689,487,748,486,753,485,762,483,774,480,787,478,800,476,811,474,820,473,825,468,842,461,860,452,877,442,894,421,923,398,947,373,967,347,982,321,994,294,1002,268,1007,242,1009,232,1008,222,1007,212,1004,205,999,207,540,202,541,196,542,190,543,187,543,155,541,127,533,102,521,70,496,44,466,24,431,10,393,3,355,0,320,0,270,0,265,2,257,3,248,4,238,6,228,8,220,9,214,9,210,17,181,28,151,43,121,64,92,90,65,118,43,148,26,178,12,207,5,236,2,253,2,256,2,261,1,266,0]]],"M":[333,1005,[[238,530,202,534,172,546,146,564,126,588,110,614,100,644,93,673,91,702,93,735,100,768,111,799,128,828,151,856,180,880,217,901,260,918,258,530,253,531,246,530,241,530],[60,0,64,0,68,0,71,1,75,3,77,559,112,527,148,501,185,481,222,467,259,458,295,455,304,456,314,457,325,460,332,466,333,982,330,987,324,992,316,996,306,999,297,1002,288,1004,280,1005,274,1005,262,1002,259,992,254,993,248,995,243,996,238,997,217,996,196,992,174,986,155,979,116,957,84,932,57,904,36,874,20,844,8,812,2,779,0,748,0,743,1,734,2,722,3,713,1,23,4,18,11,14,19,9,28,6,37,3,46,2,54,0],[238,530,202,534,172,546,146,564,126,588,110,614,100,644,93,673,91,702,93,735,100,768,111,799,128,828,151,856,180,880,217,901,260,918,258,530,253,531,246,530,241,530],[60,0,64,0,68,0,71,1,75,3,77,559,112,527,148,501,185,481,222,467,259,458,295,455,304,456,314,457,325,460,332,466,333,982,330,987,324,992,316,996,306,999,297,1002,288,1004,280,1005,274,1005,262,1002,259,992,254,993,248,995,243,996,238,997,217,996,196,992,174,986,155,979,116,957,84,932,57,904,36,874,20,844,8,812,2,779,0,748,0,743,1,734,2,722,3,713,1,23,4,18,11,14,19,9,28,6,37,3,46,2,54,0]]],"N":[288,997,[[103,0,148,6,186,22,217,47,243,77,263,112,277,149,285,187,288,222,288,272,285,312,274,354,264,383,251,410,234,436,215,460,193,482,168,502,140,518,108,530,74,538,76,974,73,979,66,984,58,988,49,991,39,994,30,996,21,997,15,997,12,997,6,996,2,994,2,990,0,495,8,486,18,480,27,477,38,474,48,472,58,470,69,469,79,466,109,466,118,465,126,464,135,462,143,456,159,440,171,424,180,406,186,388,190,369,194,350,196,332,198,315,198,285,196,253,190,218,180,183,164,150,143,120,116,96,81,79,39,73,34,72,31,68,30,62,29,58,31,46,38,34,49,24,60,16,72,9,84,4,95,1]]],"O":[181,228,[[29,0,46,16,68,34,94,54,119,76,142,97,162,120,176,143,181,165,180,177,177,193,172,211,164,228,134,206,107,185,82,164,67,151,52,138,38,124,26,112,15,100,7,88,2,79,0,70,0,63,1,54,2,45,5,34,9,24,14,14,20,6]]],"P":[392,1006,[[318,74,309,78,299,81,263,86,226,96,191,109,159,128,132,152,110,180,95,215,90,257,93,289,104,322,120,354,144,386,176,413,214,436,239,448,264,458,290,467,316,472],[377,0,380,0,385,0,389,1,392,5,388,981,386,986,380,990,372,995,364,998,354,1001,344,1003,336,1004,329,1005,325,1005,322,1005,318,1004,314,1000,316,547,315,547,311,547,304,548,298,549,295,549,268,548,240,544,212,537,183,527,154,515,126,500,100,482,76,461,75,983,72,988,65,992,57,996,48,999,38,1002,28,1004,20,1006,14,1006,11,1006,6,1004,1,1002,0,998,2,332,1,323,0,312,0,303,0,299,4,257,17,218,37,182,62,148,92,118,126,90,162,67,198,47,236,31,272,20,305,12,334,9,346,7,356,4,366,1],[318,74,309,78,299,81,263,86,226,96,191,109,159,128,132,152,110,180,95,215,90,257,93,289,104,322,120,354,144,386,176,413,214,436,239,448,264,458,290,467,316,472],[377,0,380,0,385,0,389,1,392,5,388,981,386,986,380,990,372,995,364,998,354,1001,344,1003,336,1004,329,1005,325,1005,322,1005,318,1004,314,1000,316,547,315,547,311,547,304,548,298,549,295,549,268,548,240,544,212,537,183,527,154,515,126,500,100,482,76,461,75,983,72,988,65,992,57,996,48,999,38,1002,28,1004,20,1006,14,1006,11,1006,6,1004,1,1002,0,998,2,332,1,323,0,312,0,303,0,299,4,257,17,218,37,182,62,148,92,118,126,90,162,67,198,47,236,31,272,20,305,12,334,9,346,7,356,4,366,1]]],"Q":[290,1005,[[77,314,76,709,85,706,94,704,104,703,113,702,122,701,131,699,140,696,148,690,164,674,176,656,184,639,190,621,193,603,196,586,198,568,200,551,200,522,199,502,197,479,193,455,187,430,179,406,168,384,154,363,137,345,106,324],[63,0,67,0,70,0,74,1,78,4,78,237,83,236,90,236,95,235,98,235,138,239,175,252,209,273,231,295,251,322,267,355,280,393,281,399,283,406,285,415,286,424,288,432,289,440,290,445,290,448,290,517,286,556,275,598,264,625,249,652,232,677,212,701,189,722,164,741,136,757,106,768,74,775,74,981,72,986,67,990,59,995,50,998,40,1001,30,1003,21,1004,15,1005,11,1005,6,1004,3,1003,0,998,4,23,5,19,10,14,19,10,28,7,39,4,49,2,58,0],[77,314,76,709,85,706,94,704,104,703,113,702,122,701,131,699,140,696,148,690,164,674,176,656,184,639,190,621,193,603,196,586,198,568,200,551,200,522,199,502,197,479,193,455,187,430,179,406,168,384,154,363,137,345,106,324],[63,0,67,0,70,0,74,1,78,4,78,237,83,236,90,236,95,235,98,235,138,239,175,252,209,273,231,295,251,322,267,355,280,393,281,399,283,406,285,415,286,424,288,432,289,440,290,445,290,448,290,517,286,556,275,598,264,625,249,652,232,677,212,701,189,722,164,741,136,757,106,768,74,775,74,981,72,986,67,990,59,995,50,998,40,1001,30,1003,21,1004,15,1005,11,1005,6,1004,3,1003,0,998,4,23,5,19,10,14,19,10,28,7,39,4,49,2,58,0]]],"R":[289,997,[[63,0,66,0,70,1,74,2,77,4,75,458,76,458,80,458,86,457,93,456,97,456,137,460,173,472,206,492,229,514,248,541,265,574,278,613,279,618,281,626,283,635,284,646,286,656,288,666,289,673,289,677,289,728,287,763,280,798,269,830,254,862,237,890,216,916,193,939,168,959,140,975,111,987,81,995,51,997,43,996,36,994,31,990,29,981,32,968,40,956,53,945,67,936,82,928,96,923,108,920,115,921,119,921,124,920,146,910,163,894,175,876,184,856,190,835,194,812,196,791,199,771,199,743,197,713,192,678,182,642,168,608,147,578,120,552,87,536,45,530,42,530,38,531,33,532,30,532,28,532,24,531,20,530,15,528,10,527,6,524,2,522,0,520,3,24,6,20,12,16,20,11,29,8,39,4,48,2,57,0]]],"S":[332,1006,[[74,88,76,474,92,474,120,471,147,464,172,451,194,433,212,411,226,384,237,354,242,320,243,310,243,304,243,301,243,299,241,275,236,248,228,221,216,195,200,170,180,146,155,124,126,107,124,106,118,104,111,101,103,98,95,94,87,91,80,89,76,88],[59,0,64,0,70,2,74,6,74,13,80,11,84,10,87,9,88,8,90,8,92,8,94,8,98,8,129,10,160,17,188,29,216,44,240,62,263,82,292,117,314,155,327,194,332,233,332,984,330,989,324,992,318,995,315,996,313,996,308,998,302,1000,294,1002,287,1003,280,1004,275,1006,272,1006,269,1006,263,1004,258,1002,258,998,255,446,222,477,187,503,149,523,111,537,74,546,39,549,29,549,22,548,14,547,2,542,0,22,3,18,8,14,16,10,26,7,35,4,44,2,52,0],[74,88,76,474,92,474,120,471,147,464,172,451,194,433,212,411,226,384,237,354,242,320,243,310,243,304,243,301,243,299,241,275,236,248,228,221,216,195,200,170,180,146,155,124,126,107,124,106,118,104,111,101,103,98,95,94,87,91,80,89,76,88],[59,0,64,0,70,2,74,6,74,13,80,11,84,10,87,9,88,8,90,8,92,8,94,8,98,8,129,10,160,17,188,29,216,44,240,62,263,82,292,117,314,155,327,194,332,233,332,984,330,989,324,992,318,995,315,996,313,996,308,998,302,1000,294,1002,287,1003,280,1004,275,1006,272,1006,269,1006,263,1004,258,1002,258,998,255,446,222,477,187,503,149,523,111,537,74,546,39,549,29,549,22,548,14,547,2,542,0,22,3,18,8,14,16,10,26,7,35,4,44,2,52,0]]],"T":[291,1005,[[76,86,76,475,112,475,136,470,155,456,170,436,182,413,191,388,197,363,200,341,201,325,201,278,200,261,196,240,191,218,184,195,175,173,164,152,153,134,140,120,108,98],[59,0,72,4,76,17,84,13,91,10,98,9,106,8,151,14,188,30,220,55,246,85,266,120,280,157,288,195,291,230,291,288,287,326,276,368,265,395,252,422,235,448,216,472,193,494,168,514,140,529,110,541,77,547,80,981,77,987,70,992,62,996,53,999,43,1002,34,1004,25,1005,18,1005,15,1005,11,1004,8,1003,5,999,0,24,1,22,3,18,6,15,9,13,11,12,16,10,24,8,32,6,40,4,48,2,55,0],[76,86,76,475,112,475,136,470,155,456,170,436,182,413,191,388,197,363,200,341,201,325,201,278,200,261,196,240,191,218,184,195,175,173,164,152,153,134,140,120,108,98],[59,0,72,4,76,17,84,13,91,10,98,9,106,8,151,14,188,30,220,55,246,85,266,120,280,157,288,195,291,230,291,288,287,326,276,368,265,395,252,422,235,448,216,472,193,494,168,514,140,529,110,541,77,547,80,981,77,987,70,992,62,996,53,999,43,1002,34,1004,25,1005,18,1005,15,1005,11,1004,8,1003,5,999,0,24,1,22,3,18,6,15,9,13,11,12,16,10,24,8,32,6,40,4,48,2,55,0]]],"U":[202,364,[[143,0,154,1,169,4,185,7,202,12,202,30,189,38,175,44,160,50,145,56,145,336,124,350,107,358,92,363,75,364,70,362,60,356,47,347,34,336,22,325,10,312,3,300,0,288,2,278,10,266,19,258,29,255,38,256,43,260,47,266,50,270,50,28,71,17,95,8,120,2]]],"V":[392,1006,[[77,510,77,579,99,558,121,540,143,525,166,510,392,510,392,578,392,985,390,990,383,994,374,998,363,1000,352,1003,342,1004,335,1006,333,1006,321,1002,318,989,311,992,303,995,295,997,288,998,258,996,227,990,194,980,161,966,130,949,100,929,73,906,49,879,28,850,13,818,3,784,0,748,0,744,0,736,1,726,3,718,2,510],[317,531,280,531,269,532,256,535,242,538,233,541,188,559,152,581,124,607,105,637,94,671,90,707,95,748,110,786,134,822,159,846,187,868,220,887,257,904,272,910,288,914,304,918,319,921],[2,510,1,24,4,19,10,14,18,10,28,7,37,4,46,2,54,0,60,0,63,0,67,0,71,2,75,4,77,510],[392,510,166,510,204,490,242,476,279,466,317,458,315,25,318,19,324,14,332,10,342,6,351,4,360,2,369,0,375,0,379,0,384,2,388,4,389,8],[317,531,280,531,269,532,256,535,242,538,233,541,188,559,152,581,124,607,105,637,94,671,90,707,95,748,110,786,134,822,159,846,187,868,220,887,257,904,272,910,288,914,304,918,319,921],[60,0,63,0,67,0,71,2,75,4,77,579,107,552,136,529,166,510,196,494,237,479,277,466,317,458,315,25,318,19,324,14,332,10,342,6,351,4,360,2,369,0,375,0,379,0,384,2,388,4,389,8,392,578,392,985,390,990,383,994,374,998,363,1000,352,1003,342,1004,335,1006,333,1006,321,1002,318,989,311,992,303,995,295,997,288,998,258,996,227,990,194,980,161,966,130,949,100,929,73,906,49,879,28,850,13,818,3,784,0,748,0,744,0,736,1,726,3,718,1,24,4,19,10,14,18,10,28,7,37,4,46,2,54,0]]],"W":[333,1006,[[259,78,246,83,232,86,219,86,205,88,186,93,166,103,148,118,132,135,117,154,106,174,98,194,95,212,95,217,94,222,93,228,91,233,91,255,92,280,96,306,103,332,114,358,128,382,147,406,171,428,200,447,204,449,210,452,218,456,228,460,237,464,245,467,252,469,255,470,257,470],[320,0,323,0,328,2,333,4,333,6,332,522,330,528,321,533,308,538,293,542,277,546,262,548,248,550,240,550,200,546,156,534,127,520,101,503,77,482,75,984,72,989,66,993,58,997,50,1000,40,1003,30,1004,22,1006,16,1006,11,1006,8,1006,4,1004,1,999,3,337,1,327,0,316,0,306,0,301,3,262,11,225,24,190,42,158,63,128,87,102,114,77,144,57,176,40,209,26,242,16,275,10,279,10,284,8,290,6,296,4,303,3,310,2,315,0],[259,78,246,83,232,86,219,86,205,88,186,93,166,103,148,118,132,135,117,154,106,174,98,194,95,212,95,217,94,222,93,228,91,233,91,255,92,280,96,306,103,332,114,358,128,382,147,406,171,428,200,447,204,449,210,452,218,456,228,460,237,464,245,467,252,469,255,470,257,470],[320,0,323,0,328,2,333,4,333,6,332,522,330,528,321,533,308,538,293,542,277,546,262,548,248,550,240,550,200,546,156,534,127,520,101,503,77,482,75,984,72,989,66,993,58,997,50,1000,40,1003,30,1004,22,1006,16,1006,11,1006,8,1006,4,1004,1,999,3,337,1,327,0,316,0,306,0,301,3,262,11,225,24,190,42,158,63,128,87,102,114,77,144,57,176,40,209,26,242,16,275,10,279,10,284,8,290,6,296,4,303,3,310,2,315,0]]],"X":[487,1009,[[277,81,280,473,285,471,289,470,293,469,298,468,303,468,308,468,313,467,318,466,335,462,348,453,360,441,370,427,377,412,382,396,387,381,390,368,392,355,393,342,394,330,396,317,396,289,395,268,393,243,389,217,382,191,371,166,358,142,341,120,321,102,318,100,313,98,307,94,300,90,293,87,287,84,282,82,280,81],[205,539,197,541,189,542,181,542,172,543,164,544,156,546,149,549,142,554,126,570,114,588,106,605,100,622,96,640,94,658,92,676,90,693,90,722,91,742,92,765,96,789,102,813,110,837,122,860,135,880,152,898,166,910,180,918,194,924,207,929],[262,0,266,0,270,2,274,4,277,4,280,4,286,3,292,2,294,2,334,6,371,18,404,38,427,60,446,87,463,120,476,159,477,164,478,172,480,181,482,192,484,202,486,212,487,219,487,223,487,274,484,313,474,354,459,396,436,435,417,459,396,481,371,502,343,518,313,531,279,539,282,983,279,990,272,994,266,996,260,998,255,1000,247,1002,238,1003,227,1005,216,1007,205,1008,195,1009,188,1009,156,1007,128,999,102,987,70,962,44,932,25,898,11,860,3,823,0,788,0,736,3,698,12,656,28,615,50,576,69,552,90,530,114,510,142,493,172,480,205,471,203,24,205,19,211,14,219,10,228,7,238,4,248,2,256,0],[277,81,280,473,285,471,289,470,293,469,298,468,303,468,308,468,313,467,318,466,335,462,348,453,360,441,370,427,377,412,382,396,387,381,390,368,392,355,393,342,394,330,396,317,396,289,395,268,393,243,389,217,382,191,371,166,358,142,341,120,321,102,318,100,313,98,307,94,300,90,293,87,287,84,282,82,280,81],[205,539,197,541,189,542,181,542,172,543,164,544,156,546,149,549,142,554,126,570,114,588,106,605,100,622,96,640,94,658,92,676,90,693,90,722,91,742,92,765,96,789,102,813,110,837,122,860,135,880,152,898,166,910,180,918,194,924,207,929],[262,0,266,0,270,2,274,4,277,4,280,4,286,3,292,2,294,2,334,6,371,18,404,38,427,60,446,87,463,120,476,159,477,164,478,172,480,181,482,192,484,202,486,212,487,219,487,223,487,274,484,313,474,354,459,396,436,435,417,459,396,481,371,502,343,518,313,531,279,539,282,983,279,990,272,994,266,996,260,998,255,1000,247,1002,238,1003,227,1005,216,1007,205,1008,195,1009,188,1009,156,1007,128,999,102,987,70,962,44,932,25,898,11,860,3,823,0,788,0,736,3,698,12,656,28,615,50,576,69,552,90,530,114,510,142,493,172,480,205,471,203,24,205,19,211,14,219,10,228,7,238,4,248,2,256,0]]],"Y":[487,1008,[[278,81,280,464,294,460,307,458,316,458,325,456,339,452,350,445,360,435,368,424,375,411,380,398,385,385,388,374,388,371,390,364,391,356,392,347,394,337,396,328,397,320,397,314,397,274,396,257,394,238,389,217,383,196,375,175,366,155,356,138,344,123,327,107,311,96,295,87],[263,0,266,0,271,2,275,3,278,3,281,3,286,2,292,2,294,2,340,7,380,22,413,46,440,75,461,109,476,146,484,185,487,223,487,278,484,317,473,357,456,397,432,434,413,457,390,478,366,496,338,512,307,524,274,532,263,535,248,540,233,544,221,546,219,546,216,546,212,545,210,545,207,546,200,548,194,550,188,551,177,552,164,552,153,554,143,559,126,574,114,590,106,607,100,625,96,643,94,661,92,678,90,695,90,720,91,743,93,768,98,795,106,822,117,848,132,872,151,895,175,914,178,916,184,918,192,921,200,924,209,928,218,930,225,932,230,933,255,933,263,934,270,935,275,939,277,948,274,962,266,974,255,985,242,994,228,1000,214,1004,201,1007,192,1008,151,1003,109,990,82,973,58,950,37,919,19,881,8,840,7,836,6,830,5,823,4,814,2,806,1,798,0,791,0,785,0,736,3,698,12,658,28,617,50,580,69,556,90,535,114,516,142,500,172,488,205,480,203,23,206,18,212,14,220,10,229,7,239,4,248,2,257,0],[278,81,280,464,294,460,307,458,316,458,325,456,339,452,350,445,360,435,368,424,375,411,380,398,385,385,388,374,388,371,390,364,391,356,392,347,394,337,396,328,397,320,397,314,397,274,396,257,394,238,389,217,383,196,375,175,366,155,356,138,344,123,327,107,311,96,295,87],[263,0,266,0,271,2,275,3,278,3,281,3,286,2,292,2,294,2,340,7,380,22,413,46,440,75,461,109,476,146,484,185,487,223,487,278,484,317,473,357,456,397,432,434,413,457,390,478,366,496,338,512,307,524,274,532,263,535,248,540,233,544,221,546,219,546,216,546,212,545,210,545,207,546,200,548,194,550,188,551,177,552,164,552,153,554,143,559,126,574,114,590,106,607,100,625,96,643,94,661,92,678,90,695,90,720,91,743,93,768,98,795,106,822,117,848,132,872,151,895,175,914,178,916,184,918,192,921,200,924,209,928,218,930,225,932,230,933,255,933,263,934,270,935,275,939,277,948,274,962,266,974,255,985,242,994,228,1000,214,1004,201,1007,192,1008,151,1003,109,990,82,973,58,950,37,919,19,881,8,840,7,836,6,830,5,823,4,814,2,806,1,798,0,791,0,785,0,736,3,698,12,658,28,617,50,580,69,556,90,535,114,516,142,500,172,488,205,480,203,23,206,18,212,14,220,10,229,7,239,4,248,2,257,0]]],"Z":[480,1009,[[199,544,188,548,178,549,167,550,157,551,135,560,118,574,106,592,97,612,91,632,88,654,85,675,83,693,83,748,89,782,96,816,110,850,133,884,150,901,168,912,185,921,202,927],[287,0,333,5,372,20,406,44,433,73,454,107,468,144,477,183,480,221,480,280,476,317,466,356,449,396,426,433,407,456,385,477,361,495,334,510,305,522,274,529,276,986,273,991,266,996,258,1000,249,1003,239,1006,230,1008,221,1009,215,1009,211,1008,207,1007,204,1006,201,1005,199,1005,194,1006,188,1007,185,1007,161,1006,136,1001,112,993,88,981,67,965,47,944,30,918,15,886,14,884,12,878,10,872,7,864,4,856,2,848,0,842,0,838,0,678,1,673,3,664,6,655,10,646,13,636,16,628,19,622,20,619,33,592,52,566,74,542,100,522,126,504,154,490,182,480,206,476,208,476,214,474,221,472,230,469,238,466,246,464,254,462,258,462,260,462,264,463,268,464,270,464,273,463,279,461,286,459,292,458,304,457,316,456,328,453,339,447,355,432,366,416,374,400,380,382,383,365,386,348,387,331,390,314,390,293,388,263,384,228,375,191,361,156,341,124,314,98,280,80,236,74,233,74,228,75,224,76,222,76,208,72,203,60,206,46,214,34,225,23,238,14,252,8,266,4,278,1],[199,544,188,548,178,549,167,550,157,551,135,560,118,574,106,592,97,612,91,632,88,654,85,675,83,693,83,748,89,782,96,816,110,850,133,884,150,901,168,912,185,921,202,927],[287,0,333,5,372,20,406,44,433,73,454,107,468,144,477,183,480,221,480,280,476,317,466,356,449,396,426,433,407,456,385,477,361,495,334,510,305,522,274,529,276,986,273,991,266,996,258,1000,249,1003,239,1006,230,1008,221,1009,215,1009,211,1008,207,1007,204,1006,201,1005,199,1005,194,1006,188,1007,185,1007,161,1006,136,1001,112,993,88,981,67,965,47,944,30,918,15,886,14,884,12,878,10,872,7,864,4,856,2,848,0,842,0,838,0,678,1,673,3,664,6,655,10,646,13,636,16,628,19,622,20,619,33,592,52,566,74,542,100,522,126,504,154,490,182,480,206,476,208,476,214,474,221,472,230,469,238,466,246,464,254,462,258,462,260,462,264,463,268,464,270,464,273,463,279,461,286,459,292,458,304,457,316,456,328,453,339,447,355,432,366,416,374,400,380,382,383,365,386,348,387,331,390,314,390,293,388,263,384,228,375,191,361,156,341,124,314,98,280,80,236,74,233,74,228,75,224,76,222,76,208,72,203,60,206,46,214,34,225,23,238,14,252,8,266,4,278,1]]],"a":[78,321,[[45,0,78,0,78,276,76,286,72,297,66,308,61,321,42,321,42,102,34,100,25,101,16,102,7,103,3,99,1,96,0,91,0,83,0,77,2,66,4,52,8,38,14,24,22,12,32,3]]],"b":[290,1006,[[189,531,178,532,164,534,151,538,142,542,130,555,119,571,110,590,102,610,97,630,93,650,91,668,90,683,90,727,91,743,94,762,100,784,106,806,114,826,122,846,132,864,143,877,162,894,180,906,198,913,216,919,214,531],[271,0,275,0,280,1,284,3,287,7,290,578,290,985,288,990,281,994,272,997,262,1000,251,1003,242,1004,234,1006,231,1006,224,1005,218,1004,215,999,215,989,209,992,202,994,194,996,187,997,152,994,121,986,95,972,63,944,38,910,20,871,8,830,2,789,0,752,0,725,2,711,3,698,4,684,7,670,10,657,14,644,19,630,23,616,34,588,53,560,76,534,102,510,131,490,160,474,188,462,214,458,212,24,214,19,220,14,228,10,237,7,247,4,257,2,266,0],[189,531,178,532,164,534,151,538,142,542,130,555,119,571,110,590,102,610,97,630,93,650,91,668,90,683,90,727,91,743,94,762,100,784,106,806,114,826,122,846,132,864,143,877,162,894,180,906,198,913,216,919,214,531],[271,0,275,0,280,1,284,3,287,7,290,578,290,985,288,990,281,994,272,997,262,1000,251,1003,242,1004,234,1006,231,1006,224,1005,218,1004,215,999,215,989,209,992,202,994,194,996,187,997,152,994,121,986,95,972,63,944,38,910,20,871,8,830,2,789,0,752,0,725,2,711,3,698,4,684,7,670,10,657,14,644,19,630,23,616,34,588,53,560,76,534,102,510,131,490,160,474,188,462,214,458,212,24,214,19,220,14,228,10,237,7,247,4,257,2,266,0]]],"c":[290,1005,[[77,314,76,709,85,706,94,704,104,703,113,702,122,701,131,699,140,696,148,690,164,674,176,656,184,639,190,621,193,603,196,586,198,568,200,551,200,522,199,502,197,479,193,455,187,430,179,406,168,384,154,363,137,345,106,324],[63,0,67,0,70,0,74,1,78,4,78,237,83,236,90,236,95,235,98,235,138,239,175,252,209,273,231,295,251,322,267,355,280,393,281,399,283,406,285,415,286,424,288,432,289,440,290,445,290,448,290,517,286,556,275,598,264,625,249,652,232,677,212,701,189,722,164,741,136,757,106,768,74,775,74,981,72,986,67,990,59,995,50,998,40,1001,30,1003,21,1004,15,1005,11,1005,6,1004,3,1003,0,998,4,23,5,19,10,14,19,10,28,7,39,4,49,2,58,0],[77,314,76,709,85,706,94,704,104,703,113,702,122,701,131,699,140,696,148,690,164,674,176,656,184,639,190,621,193,603,196,586,198,568,200,551,200,522,199,502,197,479,193,455,187,430,179,406,168,384,154,363,137,345,106,324],[63,0,67,0,70,0,74,1,78,4,78,237,83,236,90,236,95,235,98,235,138,239,175,252,209,273,231,295,251,322,267,355,280,393,281,399,283,406,285,415,286,424,288,432,289,440,290,445,290,448,290,517,286,556,275,598,264,625,249,652,232,677,212,701,189,722,164,741,136,757,106,768,74,775,74,981,72,986,67,990,59,995,50,998,40,1001,30,1003,21,1004,15,1005,11,1005,6,1004,3,1003,0,998,4,23,5,19,10,14,19,10,28,7,39,4,49,2,58,0]]],"d":[289,1006,[[215,75,199,82,184,84,168,85,154,89,138,98,125,112,115,129,108,144,106,151,103,160,100,172,97,186,94,199,92,212,90,224,89,233,89,278,90,298,94,322,100,347,109,372,120,397,134,420,151,440,171,454,172,455,176,457,182,460,189,463,196,466,202,469,208,471,211,472,213,472],[274,0,277,0,282,2,287,3,289,5,286,982,283,987,276,992,268,996,259,999,249,1002,240,1004,231,1006,225,1006,221,1006,216,1004,212,1002,211,999,213,549,213,548,212,548,208,548,200,549,192,550,188,550,168,549,148,546,127,540,106,530,87,518,68,503,51,484,36,461,28,444,20,427,14,409,10,392,9,387,8,380,6,370,4,360,3,349,2,340,0,333,0,329,0,278,2,244,8,210,18,178,32,147,49,119,69,94,92,71,117,51,144,34,173,21,204,13,235,9,244,7,252,5,259,3,265,2,270,0],[215,75,199,82,184,84,168,85,154,89,138,98,125,112,115,129,108,144,106,151,103,160,100,172,97,186,94,199,92,212,90,224,89,233,89,278,90,298,94,322,100,347,109,372,120,397,134,420,151,440,171,454,172,455,176,457,182,460,189,463,196,466,202,469,208,471,211,472,213,472],[274,0,277,0,282,2,287,3,289,5,286,982,283,987,276,992,268,996,259,999,249,1002,240,1004,231,1006,225,1006,221,1006,216,1004,212,1002,211,999,213,549,213,548,212,548,208,548,200,549,192,550,188,550,168,549,148,546,127,540,106,530,87,518,68,503,51,484,36,461,28,444,20,427,14,409,10,392,9,387,8,380,6,370,4,360,3,349,2,340,0,333,0,329,0,278,2,244,8,210,18,178,32,147,49,119,69,94,92,71,117,51,144,34,173,21,204,13,235,9,244,7,252,5,259,3,265,2,270,0]]],"e":[109,270,[[54,0,72,10,85,20,95,30,102,40,106,50,108,60,109,71,109,83,108,102,103,126,96,152,88,180,79,207,70,233,62,255,55,270,46,263,36,254,27,245,18,235,11,225,5,215,1,206,0,197,1,188,5,170,11,145,18,118,26,87,36,56,45,26]]],"f":[395,1006,[[78,534,76,931,82,929,88,926,95,924,100,923,134,918,169,909,204,896,235,877,262,853,284,824,298,790,303,750,298,709,284,670,261,635,238,611,209,588,176,569,138,551,134,550,128,547,119,544,109,541,100,538,91,536,84,534,81,534],[64,0,68,0,74,2,80,4,80,8,77,457,103,457,138,459,174,467,211,479,248,496,283,518,317,544,319,24,320,19,326,14,335,10,344,7,355,4,366,2,374,0,380,0,384,0,388,0,391,2,395,5,393,674,394,682,394,690,393,698,393,706,389,748,376,787,356,824,332,857,302,887,268,914,232,938,196,958,158,974,122,986,89,994,58,997,47,998,36,1002,25,1005,14,1006,11,1006,6,1005,3,1003,0,999,5,25,5,21,10,16,19,12,29,8,40,4,50,2,59,0],[78,534,76,931,82,929,88,926,95,924,100,923,134,918,169,909,204,896,235,877,262,853,284,824,298,790,303,750,298,709,284,670,261,635,238,611,209,588,176,569,138,551,134,550,128,547,119,544,109,541,100,538,91,536,84,534,81,534],[64,0,68,0,74,2,80,4,80,8,77,457,103,457,138,459,174,467,211,479,248,496,283,518,317,544,319,24,320,19,326,14,335,10,344,7,355,4,366,2,374,0,380,0,384,0,388,0,391,2,395,5,393,674,394,682,394,690,393,698,393,706,389,748,376,787,356,824,332,857,302,887,268,914,232,938,196,958,158,974,122,986,89,994,58,997,47,998,36,1002,25,1005,14,1006,11,1006,6,1005,3,1003,0,999,5,25,5,21,10,16,19,12,29,8,40,4,50,2,59,0]]],"g":[392,1005,[[75,84,77,474,82,474,87,475,96,475,112,474,152,468,194,454,221,440,247,420,271,395,285,376,294,356,299,336,302,316,303,308,303,304,303,302,303,300,300,271,292,242,278,212,257,182,230,156,197,132,167,115,136,101,105,91],[59,0,66,0,72,2,75,7,75,17,85,12,92,10,99,8,108,8,131,10,157,14,184,22,211,32,238,44,264,58,288,73,309,89,333,112,353,136,368,160,379,184,380,186,382,192,384,198,386,206,388,214,390,222,392,229,392,233,392,984,390,988,384,992,378,994,375,996,373,996,368,998,362,999,354,1000,347,1002,340,1004,335,1005,332,1005,329,1005,323,1004,318,1001,318,998,315,427,285,454,256,476,226,495,196,510,157,526,117,539,77,548,79,980,77,986,71,990,63,995,54,998,44,1001,34,1003,25,1004,19,1005,16,1005,12,1004,9,1003,5,1000,0,22,3,18,10,14,17,10,26,7,35,4,44,2,53,0],[75,84,77,474,82,474,87,475,96,475,112,474,152,468,194,454,221,440,247,420,271,395,285,376,294,356,299,336,302,316,303,308,303,304,303,302,303,300,300,271,292,242,278,212,257,182,230,156,197,132,167,115,136,101,105,91],[59,0,66,0,72,2,75,7,75,17,85,12,92,10,99,8,108,8,131,10,157,14,184,22,211,32,238,44,264,58,288,73,309,89,333,112,353,136,368,160,379,184,380,186,382,192,384,198,386,206,388,214,390,222,392,229,392,233,392,984,390,988,384,992,378,994,375,996,373,996,368,998,362,999,354,1000,347,1002,340,1004,335,1005,332,1005,329,1005,323,1004,318,1001,318,998,315,427,285,454,256,476,226,495,196,510,157,526,117,539,77,548,79,980,77,986,71,990,63,995,54,998,44,1001,34,1003,25,1004,19,1005,16,1005,12,1004,9,1003,5,1000,0,22,3,18,10,14,17,10,26,7,35,4,44,2,53,0]]],"h":[288,997,[[272,0,275,0,280,2,286,4,286,8,288,505,274,516,258,522,241,525,225,527,220,528,214,530,209,532,204,532,201,532,196,532,192,531,189,531,179,532,166,534,153,537,145,541,132,552,121,567,112,586,104,606,98,627,94,648,91,666,90,681,90,728,91,738,93,750,96,765,100,781,103,796,106,810,109,820,111,825,116,838,125,853,136,868,148,881,160,893,174,904,189,912,203,917,209,919,216,920,222,921,230,922,234,923,240,923,245,923,250,924,254,926,257,929,259,933,260,938,258,950,251,962,241,971,230,980,218,987,206,992,194,996,186,997,151,994,121,986,95,972,63,944,38,910,19,871,8,830,2,790,0,753,0,719,3,693,8,668,14,643,22,617,34,589,52,561,76,534,102,510,130,490,160,474,188,462,214,458,211,24,214,20,220,16,228,12,238,8,248,5,258,2,266,1]]],"i":[180,82,[[0,0,143,0,148,6,154,14,160,21,166,28,172,36,176,43,179,50,180,55,180,82,54,82,48,80,40,74,31,66,22,58,14,48,6,38,2,29,0,23]]],"j":[291,1006,[[78,535,75,931,81,929,87,928,93,926,98,924,105,922,111,922,122,922,134,918,145,912,156,904,165,893,174,882,180,870,184,860,186,853,188,843,191,832,194,819,197,806,199,794,200,782,201,773,201,729,200,710,196,687,190,662,182,636,171,612,157,589,141,570,122,555,119,554,114,551,108,548,101,544,94,541,88,538,83,536,80,535],[64,0,68,0,74,2,80,4,80,8,77,457,103,457,134,459,163,467,188,479,221,504,246,534,266,568,280,606,288,643,291,678,291,734,289,768,282,800,272,832,257,861,240,889,220,914,197,936,172,956,144,972,116,985,87,993,57,997,46,999,34,1002,24,1005,14,1006,11,1006,6,1006,3,1004,0,1000,5,25,5,21,10,16,19,12,29,8,40,5,50,2,59,1],[78,535,75,931,81,929,87,928,93,926,98,924,105,922,111,922,122,922,134,918,145,912,156,904,165,893,174,882,180,870,184,860,186,853,188,843,191,832,194,819,197,806,199,794,200,782,201,773,201,729,200,710,196,687,190,662,182,636,171,612,157,589,141,570,122,555,119,554,114,551,108,548,101,544,94,541,88,538,83,536,80,535],[64,0,68,0,74,2,80,4,80,8,77,457,103,457,134,459,163,467,188,479,221,504,246,534,266,568,280,606,288,643,291,678,291,734,289,768,282,800,272,832,257,861,240,889,220,914,197,936,172,956,144,972,116,985,87,993,57,997,46,999,34,1002,24,1005,14,1006,11,1006,6,1006,3,1004,0,1000,5,25,5,21,10,16,19,12,29,8,40,5,50,2,59,1]]],"k":[290,1005,[[77,314,76,709,85,706,94,704,104,703,113,702,122,701,131,699,140,696,148,690,164,674,176,656,184,639,190,621,193,603,196,586,198,568,200,551,200,522,199,502,197,479,193,455,187,430,179,406,168,384,154,363,137,345,106,324],[63,0,67,0,70,0,74,1,78,4,78,237,83,236,90,236,95,235,98,235,138,239,175,252,209,273,231,295,251,322,267,355,280,393,281,399,283,406,285,415,286,424,288,432,289,440,290,445,290,448,290,517,286,556,275,598,264,625,249,652,232,677,212,701,189,722,164,741,136,757,106,768,74,775,74,981,72,986,67,990,59,995,50,998,40,1001,30,1003,21,1004,15,1005,11,1005,6,1004,3,1003,0,998,4,23,5,19,10,14,19,10,28,7,39,4,49,2,58,0],[77,314,76,709,85,706,94,704,104,703,113,702,122,701,131,699,140,696,148,690,164,674,176,656,184,639,190,621,193,603,196,586,198,568,200,551,200,522,199,502,197,479,193,455,187,430,179,406,168,384,154,363,137,345,106,324],[63,0,67,0,70,0,74,1,78,4,78,237,83,236,90,236,95,235,98,235,138,239,175,252,209,273,231,295,251,322,267,355,280,393,281,399,283,406,285,415,286,424,288,432,289,440,290,445,290,448,290,517,286,556,275,598,264,625,249,652,232,677,212,701,189,722,164,741,136,757,106,768,74,775,74,981,72,986,67,990,59,995,50,998,40,1001,30,1003,21,1004,15,1005,11,1005,6,1004,3,1003,0,998,4,23,5,19,10,14,19,10,28,7,39,4,49,2,58,0]]],"l":[487,1009,[[187,77,160,81,139,94,123,112,110,133,102,157,96,182,92,207,90,228,90,251,90,266,92,283,94,300,96,315,100,334,107,356,116,380,129,402,144,423,162,441,183,455,207,463,209,77,205,78,198,78,192,77],[282,548,280,934,309,934,333,929,352,916,367,896,379,872,388,848,393,823,396,801,397,784,397,738,396,723,393,706,388,686,383,666,377,647,370,629,362,613,355,601,337,582,318,566,300,555],[268,0,273,0,276,0,280,2,284,5,282,471,282,472,283,472,286,471,291,470,297,468,300,467,345,472,383,488,415,513,442,543,462,578,476,615,484,653,487,689,487,748,486,753,485,762,483,774,480,787,478,800,476,811,474,820,473,825,468,842,461,860,452,877,442,894,421,923,398,947,373,967,347,982,321,994,294,1002,268,1007,242,1009,232,1008,222,1007,212,1004,205,999,207,540,202,541,196,542,190,543,187,543,155,541,127,533,102,521,70,496,44,466,24,431,10,393,3,355,0,320,0,270,0,265,2,257,3,248,4,238,6,228,8,220,9,214,9,210,17,181,28,151,43,121,64,92,90,65,118,43,148,26,178,12,207,5,236,2,253,2,256,2,261,1,266,0],[187,77,160,81,139,94,123,112,110,133,102,157,96,182,92,207,90,228,90,251,90,266,92,283,94,300,96,315,100,334,107,356,116,380,129,402,144,423,162,441,183,455,207,463,209,77,205,78,198,78,192,77],[282,548,280,934,309,934,333,929,352,916,367,896,379,872,388,848,393,823,396,801,397,784,397,738,396,723,393,706,388,686,383,666,377,647,370,629,362,613,355,601,337,582,318,566,300,555],[268,0,273,0,276,0,280,2,284,5,282,471,282,472,283,472,286,471,291,470,297,468,300,467,345,472,383,488,415,513,442,543,462,578,476,615,484,653,487,689,487,748,486,753,485,762,483,774,480,787,478,800,476,811,474,820,473,825,468,842,461,860,452,877,442,894,421,923,398,947,373,967,347,982,321,994,294,1002,268,1007,242,1009,232,1008,222,1007,212,1004,205,999,207,540,202,541,196,542,190,543,187,543,155,541,127,533,102,521,70,496,44,466,24,431,10,393,3,355,0,320,0,270,0,265,2,257,3,248,4,238,6,228,8,220,9,214,9,210,17,181,28,151,43,121,64,92,90,65,118,43,148,26,178,12,207,5,236,2,253,2,256,2,261,1,266,0]]],"m":[333,1005,[[238,530,202,534,172,546,146,564,126,588,110,614,100,644,93,673,91,702,93,735,100,768,111,799,128,828,151,856,180,880,217,901,260,918,258,530,253,531,246,530,241,530],[60,0,64,0,68,0,71,1,75,3,77,559,112,527,148,501,185,481,222,467,259,458,295,455,304,456,314,457,325,460,332,466,333,982,330,987,324,992,316,996,306,999,297,1002,288,1004,280,1005,274,1005,262,1002,259,992,254,993,248,995,243,996,238,997,217,996,196,992,174,986,155,979,116,957,84,932,57,904,36,874,20,844,8,812,2,779,0,748,0,743,1,734,2,722,3,713,1,23,4,18,11,14,19,9,28,6,37,3,46,2,54,0],[238,530,202,534,172,546,146,564,126,588,110,614,100,644,93,673,91,702,93,735,100,768,111,799,128,828,151,856,180,880,217,901,260,918,258,530,253,531,246,530,241,530],[60,0,64,0,68,0,71,1,75,3,77,559,112,527,148,501,185,481,222,467,259,458,295,455,304,456,314,457,325,460,332,466,333,982,330,987,324,992,316,996,306,999,297,1002,288,1004,280,1005,274,1005,262,1002,259,992,254,993,248,995,243,996,238,997,217,996,196,992,174,986,155,979,116,957,84,932,57,904,36,874,20,844,8,812,2,779,0,748,0,743,1,734,2,722,3,713,1,23,4,18,11,14,19,9,28,6,37,3,46,2,54,0]]],"n":[288,997,[[103,0,148,6,186,22,217,47,243,77,263,112,277,149,285,187,288,222,288,272,285,312,274,354,264,383,251,410,234,436,215,460,193,482,168,502,140,518,108,530,74,538,76,974,73,979,66,984,58,988,49,991,39,994,30,996,21,997,15,997,12,997,6,996,2,994,2,990,0,495,8,486,18,480,27,477,38,474,48,472,58,470,69,469,79,466,109,466,118,465,126,464,135,462,143,456,159,440,171,424,180,406,186,388,190,369,194,350,196,332,198,315,198,285,196,253,190,218,180,183,164,150,143,120,116,96,81,79,39,73,34,72,31,68,30,62,29,58,31,46,38,34,49,24,60,16,72,9,84,4,95,1]]],"o":[181,228,[[29,0,46,16,68,34,94,54,119,76,142,97,162,120,176,143,181,165,180,177,177,193,172,211,164,228,134,206,107,185,82,164,67,151,52,138,38,124,26,112,15,100,7,88,2,79,0,70,0,63,1,54,2,45,5,34,9,24,14,14,20,6]]],"p":[392,1006,[[318,74,309,78,299,81,263,86,226,96,191,109,159,128,132,152,110,180,95,215,90,257,93,289,104,322,120,354,144,386,176,413,214,436,239,448,264,458,290,467,316,472],[377,0,380,0,385,0,389,1,392,5,388,981,386,986,380,990,372,995,364,998,354,1001,344,1003,336,1004,329,1005,325,1005,322,1005,318,1004,314,1000,316,547,315,547,311,547,304,548,298,549,295,549,268,548,240,544,212,537,183,527,154,515,126,500,100,482,76,461,75,983,72,988,65,992,57,996,48,999,38,1002,28,1004,20,1006,14,1006,11,1006,6,1004,1,1002,0,998,2,332,1,323,0,312,0,303,0,299,4,257,17,218,37,182,62,148,92,118,126,90,162,67,198,47,236,31,272,20,305,12,334,9,346,7,356,4,366,1],[318,74,309,78,299,81,263,86,226,96,191,109,159,128,132,152,110,180,95,215,90,257,93,289,104,322,120,354,144,386,176,413,214,436,239,448,264,458,290,467,316,472],[377,0,380,0,385,0,389,1,392,5,388,981,386,986,380,990,372,995,364,998,354,1001,344,1003,336,1004,329,1005,325,1005,322,1005,318,1004,314,1000,316,547,315,547,311,547,304,548,298,549,295,549,268,548,240,544,212,537,183,527,154,515,126,500,100,482,76,461,75,983,72,988,65,992,57,996,48,999,38,1002,28,1004,20,1006,14,1006,11,1006,6,1004,1,1002,0,998,2,332,1,323,0,312,0,303,0,299,4,257,17,218,37,182,62,148,92,118,126,90,162,67,198,47,236,31,272,20,305,12,334,9,346,7,356,4,366,1]]],"q":[290,1005,[[77,314,76,709,85,706,94,704,104,703,113,702,122,701,131,699,140,696,148,690,164,674,176,656,184,639,190,621,193,603,196,586,198,568,200,551,200,522,199,502,197,479,193,455,187,430,179,406,168,384,154,363,137,345,106,324],[63,0,67,0,70,0,74,1,78,4,78,237,83,236,90,236,95,235,98,235,138,239,175,252,209,273,231,295,251,322,267,355,280,393,281,399,283,406,285,415,286,424,288,432,289,440,290,445,290,448,290,517,286,556,275,598,264,625,249,652,232,677,212,701,189,722,164,741,136,757,106,768,74,775,74,981,72,986,67,990,59,995,50,998,40,1001,30,1003,21,1004,15,1005,11,1005,6,1004,3,1003,0,998,4,23,5,19,10,14,19,10,28,7,39,4,49,2,58,0],[77,314,76,709,85,706,94,704,104,703,113,702,122,701,131,699,140,696,148,690,164,674,176,656,184,639,190,621,193,603,196,586,198,568,200,551,200,522,199,502,197,479,193,455,187,430,179,406,168,384,154,363,137,345,106,324],[63,0,67,0,70,0,74,1,78,4,78,237,83,236,90,236,95,235,98,235,138,239,175,252,209,273,231,295,251,322,267,355,280,393,281,399,283,406,285,415,286,424,288,432,289,440,290,445,290,448,290,517,286,556,275,598,264,625,249,652,232,677,212,701,189,722,164,741,136,757,106,768,74,775,74,981,72,986,67,990,59,995,50,998,40,1001,30,1003,21,1004,15,1005,11,1005,6,1004,3,1003,0,998,4,23,5,19,10,14,19,10,28,7,39,4,49,2,58,0]]],"r":[289,997,[[63,0,66,0,70,1,74,2,77,4,75,458,76,458,80,458,86,457,93,456,97,456,137,460,173,472,206,492,229,514,248,541,265,574,278,613,279,618,281,626,283,635,284,646,286,656,288,666,289,673,289,677,289,728,287,763,280,798,269,830,254,862,237,890,216,916,193,939,168,959,140,975,111,987,81,995,51,997,43,996,36,994,31,990,29,981,32,968,40,956,53,945,67,936,82,928,96,923,108,920,115,921,119,921,124,920,146,910,163,894,175,876,184,856,190,835,194,812,196,791,199,771,199,743,197,713,192,678,182,642,168,608,147,578,120,552,87,536,45,530,42,530,38,531,33,532,30,532,28,532,24,531,20,530,15,528,10,527,6,524,2,522,0,520,3,24,6,20,12,16,20,11,29,8,39,4,48,2,57,0]]],"s":[332,1006,[[74,88,76,474,92,474,120,471,147,464,172,451,194,433,212,411,226,384,237,354,242,320,243,310,243,304,243,301,243,299,241,275,236,248,228,221,216,195,200,170,180,146,155,124,126,107,124,106,118,104,111,101,103,98,95,94,87,91,80,89,76,88],[59,0,64,0,70,2,74,6,74,13,80,11,84,10,87,9,88,8,90,8,92,8,94,8,98,8,129,10,160,17,188,29,216,44,240,62,263,82,292,117,314,155,327,194,332,233,332,984,330,989,324,992,318,995,315,996,313,996,308,998,302,1000,294,1002,287,1003,280,1004,275,1006,272,1006,269,1006,263,1004,258,1002,258,998,255,446,222,477,187,503,149,523,111,537,74,546,39,549,29,549,22,548,14,547,2,542,0,22,3,18,8,14,16,10,26,7,35,4,44,2,52,0],[74,88,76,474,92,474,120,471,147,464,172,451,194,433,212,411,226,384,237,354,242,320,243,310,243,304,243,301,243,299,241,275,236,248,228,221,216,195,200,170,180,146,155,124,126,107,124,106,118,104,111,101,103,98,95,94,87,91,80,89,76,88],[59,0,64,0,70,2,74,6,74,13,80,11,84,10,87,9,88,8,90,8,92,8,94,8,98,8,129,10,160,17,188,29,216,44,240,62,263,82,292,117,314,155,327,194,332,233,332,984,330,989,324,992,318,995,315,996,313,996,308,998,302,1000,294,1002,287,1003,280,1004,275,1006,272,1006,269,1006,263,1004,258,1002,258,998,255,446,222,477,187,503,149,523,111,537,74,546,39,549,29,549,22,548,14,547,2,542,0,22,3,18,8,14,16,10,26,7,35,4,44,2,52,0]]],"t":[291,1005,[[76,86,76,475,112,475,136,470,155,456,170,436,182,413,191,388,197,363,200,341,201,325,201,278,200,261,196,240,191,218,184,195,175,173,164,152,153,134,140,120,108,98],[59,0,72,4,76,17,84,13,91,10,98,9,106,8,151,14,188,30,220,55,246,85,266,120,280,157,288,195,291,230,291,288,287,326,276,368,265,395,252,422,235,448,216,472,193,494,168,514,140,529,110,541,77,547,80,981,77,987,70,992,62,996,53,999,43,1002,34,1004,25,1005,18,1005,15,1005,11,1004,8,1003,5,999,0,24,1,22,3,18,6,15,9,13,11,12,16,10,24,8,32,6,40,4,48,2,55,0],[76,86,76,475,112,475,136,470,155,456,170,436,182,413,191,388,197,363,200,341,201,325,201,278,200,261,196,240,191,218,184,195,175,173,164,152,153,134,140,120,108,98],[59,0,72,4,76,17,84,13,91,10,98,9,106,8,151,14,188,30,220,55,246,85,266,120,280,157,288,195,291,230,291,288,287,326,276,368,265,395,252,422,235,448,216,472,193,494,168,514,140,529,110,541,77,547,80,981,77,987,70,992,62,996,53,999,43,1002,34,1004,25,1005,18,1005,15,1005,11,1004,8,1003,5,999,0,24,1,22,3,18,6,15,9,13,11,12,16,10,24,8,32,6,40,4,48,2,55,0]]],"u":[202,364,[[143,0,154,1,169,4,185,7,202,12,202,30,189,38,175,44,160,50,145,56,145,336,124,350,107,358,92,363,75,364,70,362,60,356,47,347,34,336,22,325,10,312,3,300,0,288,2,278,10,266,19,258,29,255,38,256,43,260,47,266,50,270,50,28,71,17,95,8,120,2]]],"v":[392,1006,[[77,510,77,579,99,558,121,540,143,525,166,510,392,510,392,578,392,985,390,990,383,994,374,998,363,1000,352,1003,342,1004,335,1006,333,1006,321,1002,318,989,311,992,303,995,295,997,288,998,258,996,227,990,194,980,161,966,130,949,100,929,73,906,49,879,28,850,13,818,3,784,0,748,0,744,0,736,1,726,3,718,2,510],[317,531,280,531,269,532,256,535,242,538,233,541,188,559,152,581,124,607,105,637,94,671,90,707,95,748,110,786,134,822,159,846,187,868,220,887,257,904,272,910,288,914,304,918,319,921],[2,510,1,24,4,19,10,14,18,10,28,7,37,4,46,2,54,0,60,0,63,0,67,0,71,2,75,4,77,510],[166,510,204,490,242,476,279,466,317,458,315,25,318,19,324,14,332,10,342,6,351,4,360,2,369,0,375,0,379,0,384,2,388,4,389,8,392,510],[317,531,280,531,269,532,256,535,242,538,233,541,188,559,152,581,124,607,105,637,94,671,90,707,95,748,110,786,134,822,159,846,187,868,220,887,257,904,272,910,288,914,304,918,319,921],[60,0,63,0,67,0,71,2,75,4,77,579,107,552,136,529,166,510,196,494,237,479,277,466,317,458,315,25,318,19,324,14,332,10,342,6,351,4,360,2,369,0,375,0,379,0,384,2,388,4,389,8,392,578,392,985,390,990,383,994,374,998,363,1000,352,1003,342,1004,335,1006,333,1006,321,1002,318,989,311,992,303,995,295,997,288,998,258,996,227,990,194,980,161,966,130,949,100,929,73,906,49,879,28,850,13,818,3,784,0,748,0,744,0,736,1,726,3,718,1,24,4,19,10,14,18,10,28,7,37,4,46,2,54,0]]],"w":[333,1006,[[259,78,246,83,232,86,219,86,205,88,186,93,166,103,148,118,132,135,117,154,106,174,98,194,95,212,95,217,94,222,93,228,91,233,91,255,92,280,96,306,103,332,114,358,128,382,147,406,171,428,200,447,204,449,210,452,218,456,228,460,237,464,245,467,252,469,255,470,257,470],[320,0,323,0,328,2,333,4,333,6,332,522,330,528,321,533,308,538,293,542,277,546,262,548,248,550,240,550,200,546,156,534,127,520,101,503,77,482,75,984,72,989,66,993,58,997,50,1000,40,1003,30,1004,22,1006,16,1006,11,1006,8,1006,4,1004,1,999,3,337,1,327,0,316,0,306,0,301,3,262,11,225,24,190,42,158,63,128,87,102,114,77,144,57,176,40,209,26,242,16,275,10,279,10,284,8,290,6,296,4,303,3,310,2,315,0],[259,78,246,83,232,86,219,86,205,88,186,93,166,103,148,118,132,135,117,154,106,174,98,194,95,212,95,217,94,222,93,228,91,233,91,255,92,280,96,306,103,332,114,358,128,382,147,406,171,428,200,447,204,449,210,452,218,456,228,460,237,464,245,467,252,469,255,470,257,470],[320,0,323,0,328,2,333,4,333,6,332,522,330,528,321,533,308,538,293,542,277,546,262,548,248,550,240,550,200,546,156,534,127,520,101,503,77,482,75,984,72,989,66,993,58,997,50,1000,40,1003,30,1004,22,1006,16,1006,11,1006,8,1006,4,1004,1,999,3,337,1,327,0,316,0,306,0,301,3,262,11,225,24,190,42,158,63,128,87,102,114,77,144,57,176,40,209,26,242,16,275,10,279,10,284,8,290,6,296,4,303,3,310,2,315,0]]],"x":[487,1009,[[277,81,280,473,285,471,289,470,293,469,298,468,303,468,308,468,313,467,318,466,335,462,348,453,360,441,370,427,377,412,382,396,387,381,390,368,392,355,393,342,394,330,396,317,396,289,395,268,393,243,389,217,382,191,371,166,358,142,341,120,321,102,318,100,313,98,307,94,300,90,293,87,287,84,282,82,280,81],[205,539,197,541,189,542,181,542,172,543,164,544,156,546,149,549,142,554,126,570,114,588,106,605,100,622,96,640,94,658,92,676,90,693,90,722,91,742,92,765,96,789,102,813,110,837,122,860,135,880,152,898,166,910,180,918,194,924,207,929],[262,0,266,0,270,2,274,4,277,4,280,4,286,3,292,2,294,2,334,6,371,18,404,38,427,60,446,87,463,120,476,159,477,164,478,172,480,181,482,192,484,202,486,212,487,219,487,223,487,274,484,313,474,354,459,396,436,435,417,459,396,481,371,502,343,518,313,531,279,539,282,983,279,990,272,994,266,996,260,998,255,1000,247,1002,238,1003,227,1005,216,1007,205,1008,195,1009,188,1009,156,1007,128,999,102,987,70,962,44,932,25,898,11,860,3,823,0,788,0,736,3,698,12,656,28,615,50,576,69,552,90,530,114,510,142,493,172,480,205,471,203,24,205,19,211,14,219,10,228,7,238,4,248,2,256,0],[277,81,280,473,285,471,289,470,293,469,298,468,303,468,308,468,313,467,318,466,335,462,348,453,360,441,370,427,377,412,382,396,387,381,390,368,392,355,393,342,394,330,396,317,396,289,395,268,393,243,389,217,382,191,371,166,358,142,341,120,321,102,318,100,313,98,307,94,300,90,293,87,287,84,282,82,280,81],[205,539,197,541,189,542,181,542,172,543,164,544,156,546,149,549,142,554,126,570,114,588,106,605,100,622,96,640,94,658,92,676,90,693,90,722,91,742,92,765,96,789,102,813,110,837,122,860,135,880,152,898,166,910,180,918,194,924,207,929],[262,0,266,0,270,2,274,4,277,4,280,4,286,3,292,2,294,2,334,6,371,18,404,38,427,60,446,87,463,120,476,159,477,164,478,172,480,181,482,192,484,202,486,212,487,219,487,223,487,274,484,313,474,354,459,396,436,435,417,459,396,481,371,502,343,518,313,531,279,539,282,983,279,990,272,994,266,996,260,998,255,1000,247,1002,238,1003,227,1005,216,1007,205,1008,195,1009,188,1009,156,1007,128,999,102,987,70,962,44,932,25,898,11,860,3,823,0,788,0,736,3,698,12,656,28,615,50,576,69,552,90,530,114,510,142,493,172,480,205,471,203,24,205,19,211,14,219,10,228,7,238,4,248,2,256,0]]],"y":[487,1008,[[278,81,280,464,294,460,307,458,316,458,325,456,339,452,350,445,360,435,368,424,375,411,380,398,385,385,388,374,388,371,390,364,391,356,392,347,394,337,396,328,397,320,397,314,397,274,396,257,394,238,389,217,383,196,375,175,366,155,356,138,344,123,327,107,311,96,295,87],[263,0,266,0,271,2,275,3,278,3,281,3,286,2,292,2,294,2,340,7,380,22,413,46,440,75,461,109,476,146,484,185,487,223,487,278,484,317,473,357,456,397,432,434,413,457,390,478,366,496,338,512,307,524,274,532,263,535,248,540,233,544,221,546,219,546,216,546,212,545,210,545,207,546,200,548,194,550,188,551,177,552,164,552,153,554,143,559,126,574,114,590,106,607,100,625,96,643,94,661,92,678,90,695,90,720,91,743,93,768,98,795,106,822,117,848,132,872,151,895,175,914,178,916,184,918,192,921,200,924,209,928,218,930,225,932,230,933,255,933,263,934,270,935,275,939,277,948,274,962,266,974,255,985,242,994,228,1000,214,1004,201,1007,192,1008,151,1003,109,990,82,973,58,950,37,919,19,881,8,840,7,836,6,830,5,823,4,814,2,806,1,798,0,791,0,785,0,736,3,698,12,658,28,617,50,580,69,556,90,535,114,516,142,500,172,488,205,480,203,23,206,18,212,14,220,10,229,7,239,4,248,2,257,0],[278,81,280,464,294,460,307,458,316,458,325,456,339,452,350,445,360,435,368,424,375,411,380,398,385,385,388,374,388,371,390,364,391,356,392,347,394,337,396,328,397,320,397,314,397,274,396,257,394,238,389,217,383,196,375,175,366,155,356,138,344,123,327,107,311,96,295,87],[263,0,266,0,271,2,275,3,278,3,281,3,286,2,292,2,294,2,340,7,380,22,413,46,440,75,461,109,476,146,484,185,487,223,487,278,484,317,473,357,456,397,432,434,413,457,390,478,366,496,338,512,307,524,274,532,263,535,248,540,233,544,221,546,219,546,216,546,212,545,210,545,207,546,200,548,194,550,188,551,177,552,164,552,153,554,143,559,126,574,114,590,106,607,100,625,96,643,94,661,92,678,90,695,90,720,91,743,93,768,98,795,106,822,117,848,132,872,151,895,175,914,178,916,184,918,192,921,200,924,209,928,218,930,225,932,230,933,255,933,263,934,270,935,275,939,277,948,274,962,266,974,255,985,242,994,228,1000,214,1004,201,1007,192,1008,151,1003,109,990,82,973,58,950,37,919,19,881,8,840,7,836,6,830,5,823,4,814,2,806,1,798,0,791,0,785,0,736,3,698,12,658,28,617,50,580,69,556,90,535,114,516,142,500,172,488,205,480,203,23,206,18,212,14,220,10,229,7,239,4,248,2,257,0]]],"z":[480,1009,[[199,544,188,548,178,549,167,550,157,551,135,560,118,574,106,592,97,612,91,632,88,654,85,675,83,693,83,748,89,782,96,816,110,850,133,884,150,901,168,912,185,921,202,927],[287,0,333,5,372,20,406,44,433,73,454,107,468,144,477,183,480,221,480,280,476,317,466,356,449,396,426,433,407,456,385,477,361,495,334,510,305,522,274,529,276,986,273,991,266,996,258,1000,249,1003,239,1006,230,1008,221,1009,215,1009,211,1008,207,1007,204,1006,201,1005,199,1005,194,1006,188,1007,185,1007,161,1006,136,1001,112,993,88,981,67,965,47,944,30,918,15,886,14,884,12,878,10,872,7,864,4,856,2,848,0,842,0,838,0,678,1,673,3,664,6,655,10,646,13,636,16,628,19,622,20,619,33,592,52,566,74,542,100,522,126,504,154,490,182,480,206,476,208,476,214,474,221,472,230,469,238,466,246,464,254,462,258,462,260,462,264,463,268,464,270,464,273,463,279,461,286,459,292,458,304,457,316,456,328,453,339,447,355,432,366,416,374,400,380,382,383,365,386,348,387,331,390,314,390,293,388,263,384,228,375,191,361,156,341,124,314,98,280,80,236,74,233,74,228,75,224,76,222,76,208,72,203,60,206,46,214,34,225,23,238,14,252,8,266,4,278,1],[199,544,188,548,178,549,167,550,157,551,135,560,118,574,106,592,97,612,91,632,88,654,85,675,83,693,83,748,89,782,96,816,110,850,133,884,150,901,168,912,185,921,202,927],[287,0,333,5,372,20,406,44,433,73,454,107,468,144,477,183,480,221,480,280,476,317,466,356,449,396,426,433,407,456,385,477,361,495,334,510,305,522,274,529,276,986,273,991,266,996,258,1000,249,1003,239,1006,230,1008,221,1009,215,1009,211,1008,207,1007,204,1006,201,1005,199,1005,194,1006,188,1007,185,1007,161,1006,136,1001,112,993,88,981,67,965,47,944,30,918,15,886,14,884,12,878,10,872,7,864,4,856,2,848,0,842,0,838,0,678,1,673,3,664,6,655,10,646,13,636,16,628,19,622,20,619,33,592,52,566,74,542,100,522,126,504,154,490,182,480,206,476,208,476,214,474,221,472,230,469,238,466,246,464,254,462,258,462,260,462,264,463,268,464,270,464,273,463,279,461,286,459,292,458,304,457,316,456,328,453,339,447,355,432,366,416,374,400,380,382,383,365,386,348,387,331,390,314,390,293,388,263,384,228,375,191,361,156,341,124,314,98,280,80,236,74,233,74,228,75,224,76,222,76,208,72,203,60,206,46,214,34,225,23,238,14,252,8,266,4,278,1]]]}}; | |
| var KEYS = ['asm', 'lit', 'bind', 'ctl', 'call', 'fn', 'mod']; | |
| var SHAPES = { asm: 'octagon', lit: 'cross', bind: 'circle', ctl: 'triangle', call: 'diamond', fn: 'hexagon', mod: 'square', loop: 'ring' }; | |
| var MEANS = { | |
| asm: 'architecture, hardware, boot, extern, unsafe', lit: 'literals, media, constants, assets', | |
| bind: 'bindings, data, memory, storage', ctl: 'control flow, branches, loops, scheduling', | |
| call: 'calls, network, I/O, messages', fn: 'functions, codegen, emit, transform', | |
| mod: 'modules, namespaces, the root, identity' | |
| }; | |
| var ANGLES = { frame: [45], cross: [45, -45], alt: [30, -60], grid: [0, 90] }; | |
| var RAD = Math.PI / 180; | |
| // ---------- small helpers ---------- | |
| function n2(v) { return String(Math.round(v * 100) / 100); } | |
| function clamp(v, a, b) { return v < a ? a : v > b ? b : v; } | |
| function P(cx, cy, r, a) { return [cx + r * Math.sin(a * RAD), cy - r * Math.cos(a * RAD)]; } | |
| function dPoly(pts, open) { | |
| var s = ''; | |
| for (var i = 0; i < pts.length; i++) s += (i ? 'L' : 'M') + n2(pts[i][0]) + ' ' + n2(pts[i][1]); | |
| return s + (open ? '' : 'Z'); | |
| } | |
| function dSegs(S) { | |
| var s = ''; | |
| for (var i = 0; i < S.length; i++) s += 'M' + n2(S[i][0]) + ' ' + n2(S[i][1]) + 'L' + n2(S[i][2]) + ' ' + n2(S[i][3]); | |
| return s; | |
| } | |
| function path(d, w, extra) { return d ? '<path d="' + d + '" stroke-width="' + n2(w) + '"' + (extra || '') + '/>' : ''; } | |
| function group(color, inner, attrs) { return '<g class="lg lg-' + (color || 'ink') + '"' + (attrs || '') + '>' + inner + '</g>'; } | |
| function esc(s) { return String(s).replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<'); } | |
| function weightFor(size) { return clamp(size / 32, 0.5, 2); } | |
| function rng(seed) { | |
| var a = (seed >>> 0) || 1; | |
| return function () { | |
| a |= 0; a = a + 0x6D2B79F5 | 0; | |
| var t = Math.imul(a ^ a >>> 15, 1 | a); | |
| t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t; | |
| return ((t ^ t >>> 14) >>> 0) / 4294967296; | |
| }; | |
| } | |
| // ---------- shapes: { d, pts, inset(i) } ---------- | |
| function rectPts(x, y, w, h) { return [[x, y], [x + w, y], [x + w, y + h], [x, y + h]]; } | |
| function Rect(x, y, w, h) { | |
| return { d: dPoly(rectPts(x, y, w, h)), pts: rectPts(x, y, w, h), | |
| inset: function (i) { return w - 2 * i > 0 && h - 2 * i > 0 ? rectPts(x + i, y + i, w - 2 * i, h - 2 * i) : []; } }; | |
| } | |
| function circlePts(cx, cy, r) { | |
| var n = clamp(Math.ceil(r * 1.2), 24, 120), pts = []; | |
| for (var i = 0; i < n; i++) pts.push(P(cx, cy, r, i * 360 / n)); | |
| return pts; | |
| } | |
| function Circle(cx, cy, r) { | |
| return { d: 'M' + n2(cx - r) + ' ' + n2(cy) + 'A' + n2(r) + ' ' + n2(r) + ' 0 1 0 ' + n2(cx + r) + ' ' + n2(cy) + 'A' + n2(r) + ' ' + n2(r) + ' 0 1 0 ' + n2(cx - r) + ' ' + n2(cy) + 'Z', | |
| pts: circlePts(cx, cy, r), inset: function (i) { return r - i > 0 ? circlePts(cx, cy, r - i) : []; } }; | |
| } | |
| function ngonPts(cx, cy, r, n, rot) { | |
| var pts = []; | |
| for (var i = 0; i < n; i++) pts.push(P(cx, cy, r, (rot || 0) + i * 360 / n)); | |
| return pts; | |
| } | |
| function Ngon(cx, cy, r, n, rot) { | |
| return { d: dPoly(ngonPts(cx, cy, r, n, rot)), pts: ngonPts(cx, cy, r, n, rot), | |
| inset: function (i) { var rr = r - i / Math.cos(Math.PI / n); return rr > 0 ? ngonPts(cx, cy, rr, n, rot) : []; } }; | |
| } | |
| function crossPts(cx, cy, r, t) { | |
| return [[cx - t, cy - r], [cx + t, cy - r], [cx + t, cy - t], [cx + r, cy - t], [cx + r, cy + t], [cx + t, cy + t], | |
| [cx + t, cy + r], [cx - t, cy + r], [cx - t, cy + t], [cx - r, cy + t], [cx - r, cy - t], [cx - t, cy - t]]; | |
| } | |
| function Cross(cx, cy, r) { | |
| var t = r * 0.34; | |
| return { d: dPoly(crossPts(cx, cy, r, t)), pts: crossPts(cx, cy, r, t), | |
| inset: function (i) { return t - i > 0 ? crossPts(cx, cy, r - i, t - i) : []; } }; | |
| } | |
| function sectorPts(cx, cy, r0, r1, a0, a1) { | |
| var n = Math.max(2, Math.ceil(Math.abs(a1 - a0) / 3)), pts = [], i; | |
| for (i = 0; i <= n; i++) pts.push(P(cx, cy, r1, a0 + (a1 - a0) * i / n)); | |
| for (i = n; i >= 0; i--) pts.push(P(cx, cy, r0, a0 + (a1 - a0) * i / n)); | |
| return pts; | |
| } | |
| function Sector(cx, cy, r0, r1, a0, a1) { | |
| var big = Math.abs(a1 - a0) > 180 ? 1 : 0, A = P(cx, cy, r1, a0), B = P(cx, cy, r1, a1), C = P(cx, cy, r0, a1), D = P(cx, cy, r0, a0); | |
| return { d: 'M' + n2(A[0]) + ' ' + n2(A[1]) + 'A' + n2(r1) + ' ' + n2(r1) + ' 0 ' + big + ' 1 ' + n2(B[0]) + ' ' + n2(B[1]) + | |
| 'L' + n2(C[0]) + ' ' + n2(C[1]) + 'A' + n2(r0) + ' ' + n2(r0) + ' 0 ' + big + ' 0 ' + n2(D[0]) + ' ' + n2(D[1]) + 'Z', | |
| pts: sectorPts(cx, cy, r0, r1, a0, a1), | |
| inset: function (i) { | |
| var da = i / ((r0 + r1) / 2) / RAD; | |
| return (r1 - r0 - 2 * i > 0 && a1 - a0 - 2 * da > 0) ? sectorPts(cx, cy, r0 + i, r1 - i, a0 + da, a1 - da) : []; | |
| } }; | |
| } | |
| function Poly(pts) { return { d: dPoly(pts), pts: pts, inset: function () { return pts; } }; } | |
| // ---------- the hatch engine ---------- | |
| // Real geometric intersection: scanlines against polygon edges (non-zero winding), | |
| // minus the hole polygons. Returns [[x1,y1,x2,y2], ...]. Nothing overshoots. | |
| function spans(polys, v) { | |
| var xs = [], i, j; | |
| for (i = 0; i < polys.length; i++) { | |
| var p = polys[i], n = p.length; | |
| for (j = 0; j < n; j++) { | |
| var a = p[j], b = p[(j + 1) % n]; | |
| if ((a[1] <= v) !== (b[1] <= v)) xs.push([a[0] + (v - a[1]) / (b[1] - a[1]) * (b[0] - a[0]), b[1] > a[1] ? 1 : -1]); | |
| } | |
| } | |
| xs.sort(function (m, k) { return m[0] - k[0]; }); | |
| var out = [], w = 0, start = 0; | |
| for (i = 0; i < xs.length; i++) { | |
| var prev = w; w += xs[i][1]; | |
| if (prev === 0 && w !== 0) start = xs[i][0]; | |
| else if (prev !== 0 && w === 0) out.push([start, xs[i][0]]); | |
| } | |
| return out; | |
| } | |
| function subtract(A, B) { | |
| if (!B.length) return A; | |
| var out = []; | |
| for (var i = 0; i < A.length; i++) { | |
| var cur = [A[i]]; | |
| for (var j = 0; j < B.length; j++) { | |
| var next = []; | |
| for (var k = 0; k < cur.length; k++) { | |
| var s = cur[k][0], e = cur[k][1], bs = B[j][0], be = B[j][1]; | |
| if (be <= s || bs >= e) next.push(cur[k]); | |
| else { if (bs > s) next.push([s, bs]); if (be < e) next.push([be, e]); } | |
| } | |
| cur = next; | |
| } | |
| out = out.concat(cur); | |
| } | |
| return out; | |
| } | |
| function hatch(polys, angle, spacing, opt) { | |
| opt = opt || {}; | |
| polys = polys.filter(function (p) { return p && p.length > 2; }); | |
| if (!polys.length || !(spacing > 0)) return []; | |
| var t = angle * RAD, c = Math.cos(t), s = Math.sin(t); | |
| function rot(p) { return p.map(function (q) { return [q[0] * c - q[1] * s, q[0] * s + q[1] * c]; }); } | |
| var R = polys.map(rot), H = (opt.holes || []).filter(function (p) { return p && p.length > 2; }).map(rot); | |
| var mn = Infinity, mx = -Infinity, i, k; | |
| for (i = 0; i < R.length; i++) for (k = 0; k < R[i].length; k++) { mn = Math.min(mn, R[i][k][1]); mx = Math.max(mx, R[i][k][1]); } | |
| var trim = opt.trim || 0, out = []; | |
| for (k = Math.floor(mn / spacing); k <= Math.ceil(mx / spacing); k++) { | |
| var v = (k + 0.5) * spacing; | |
| if (v <= mn || v >= mx) continue; | |
| var A = subtract(spans(R, v), H.length ? spans(H, v) : []); | |
| for (i = 0; i < A.length; i++) { | |
| var a = A[i][0] + trim, b = A[i][1] - trim; | |
| if (b - a > 0.2) out.push([a * c + v * s, -a * s + v * c, b * c + v * s, -b * s + v * c]); | |
| } | |
| } | |
| return out; | |
| } | |
| // Outline plus hatch for one shape. The hatch is inset from the outline by half the | |
| // spacing; children (holes) are subtracted, buffered by the caller. | |
| function fill(shape, set, spacing, w, opt) { | |
| opt = opt || {}; | |
| var angles = typeof set === 'string' ? ANGLES[set] : set, inner = shape.inset(opt.inset == null ? spacing / 2 : opt.inset), segs = []; | |
| for (var i = 0; i < angles.length; i++) segs = segs.concat(hatch([inner], angles[i], spacing, { holes: opt.holes })); | |
| var hw = opt.solid ? Math.min(w, spacing) : Math.min(w, spacing / 2); | |
| return (opt.outline === false ? '' : path(shape.d, w)) + path(dSegs(segs), hw); | |
| } | |
| // ---------- glyphs: fitted to their own bounding box, never by baseline ---------- | |
| function glyphFit(face, ch, bw, bh) { | |
| var g = GLYPHS[face] && GLYPHS[face][ch]; | |
| if (!g) return null; | |
| var sc = Math.min(bw / g[0], bh / g[1]), gw = g[0] * sc, gh = g[1] * sc; | |
| var polys = g[2].map(function (flat) { | |
| var pts = []; | |
| for (var i = 0; i < flat.length; i += 2) pts.push([flat[i] * sc - gw / 2, flat[i + 1] * sc - gh / 2]); | |
| return pts; | |
| }); | |
| return { polys: polys, w: gw, h: gh }; | |
| } | |
| function subdivide(a, b, maxLen) { | |
| var n = Math.max(1, Math.ceil(Math.hypot(b[0] - a[0], b[1] - a[1]) / maxLen)), out = []; | |
| for (var i = 0; i <= n; i++) out.push([a[0] + (b[0] - a[0]) * i / n, a[1] + (b[1] - a[1]) * i / n]); | |
| return out; | |
| } | |
| // Glyph centred on (0,0) in a flat cell, then placed through `place` (a point map). | |
| // place may return null for hidden points (the back of a drum). | |
| function glyph(face, ch, bw, bh, w, place, opt) { | |
| opt = opt || {}; | |
| var g = glyphFit(face, ch, bw, bh); | |
| if (!g) return ''; | |
| var step = opt.step || 1e9, d = '', i, j, k; | |
| function run(pts, closed) { | |
| var s = '', pen = false, n = pts.length, m = closed ? n : n - 1; | |
| for (i = 0; i < m; i++) { | |
| var sub = subdivide(pts[i], pts[(i + 1) % n], step); | |
| for (j = pen ? 1 : 0; j < sub.length; j++) { | |
| var q = place(sub[j]); | |
| if (!q) { pen = false; continue; } | |
| s += (pen ? 'L' : 'M') + n2(q[0]) + ' ' + n2(q[1]); pen = true; | |
| } | |
| } | |
| return s; | |
| } | |
| for (k = 0; k < g.polys.length; k++) d += run(g.polys[k], true); | |
| var sp = Math.max(g.h * 0.09, opt.minSpacing || 0.7), segs = hatch(g.polys, 45, sp, {}), hd = ''; | |
| for (k = 0; k < segs.length; k++) hd += run([[segs[k][0], segs[k][1]], [segs[k][2], segs[k][3]]], false); | |
| return path(d, w) + path(hd, Math.min(w, sp / 2)); | |
| } | |
| // ---------- TILE ---------- | |
| function brackets(x, y, s, ins, arm) { | |
| var a = x + ins, b = y + ins, c = x + s - ins, e = y + s - ins; | |
| return 'M' + n2(a) + ' ' + n2(b + arm) + 'V' + n2(b) + 'H' + n2(a + arm) + 'M' + n2(c - arm) + ' ' + n2(b) + 'H' + n2(c) + 'V' + n2(b + arm) + | |
| 'M' + n2(c) + ' ' + n2(e - arm) + 'V' + n2(e) + 'H' + n2(c - arm) + 'M' + n2(a + arm) + ' ' + n2(e) + 'H' + n2(a) + 'V' + n2(e - arm); | |
| } | |
| function Tile(o) { | |
| o = o || {}; | |
| var s = o.size || 32, x = o.x || 0, y = o.y || 0, w = o.weight || weightFor(s), out = ''; | |
| out += path(dPoly(rectPts(x, y, s, s)), w); | |
| out += path(brackets(x, y, s, s * 0.055, s * 0.21), w * 1.4); | |
| var cx = x + s / 2, cy = y + s / 2, ch = o.ch == null ? '' : String(o.ch), g = ch && ch !== ' ' ? glyphFit('daemon', ch, s * 0.6, s * 0.6) : null; | |
| if (o.fill) { | |
| var sp = Math.max(s * 0.045, 1.4) * (o.density || 1), holes = []; | |
| if (g) holes.push(rectPts(cx - g.w / 2 - sp, cy - g.h / 2 - sp, g.w + 2 * sp, g.h + 2 * sp)); | |
| out += fill(Rect(x + s * 0.055, y + s * 0.055, s * 0.89, s * 0.89), o.fill, sp, w, { holes: holes, outline: false }); | |
| } | |
| if (g) out += glyph('daemon', ch, s * 0.6, s * 0.6, w, function (p) { return [cx + p[0], cy + p[1]]; }); | |
| else if (ch === ' ') out = fill(Circle(cx, cy, s * 0.07), 'frame', Math.max(w * 0.8, 0.6), w, { solid: true }); | |
| return group(o.color, out); | |
| } | |
| function wordWidth(text, size) { var n = String(text).length; return n ? n * size + (n - 1) * size * 0.14 : 0; } | |
| // A run of tiles. One letter per tile; a space is a tile-sized gap holding a small dot. | |
| function Word(o) { | |
| o = o || {}; | |
| var text = String(o.text == null ? '' : o.text), s = o.size || 32, x = o.x || 0, y = o.y || 0, out = ''; | |
| if (o.align === 'center') x -= wordWidth(text, s) / 2; | |
| else if (o.align === 'right') x -= wordWidth(text, s); | |
| for (var i = 0; i < text.length; i++) { | |
| var col = typeof o.color === 'function' ? o.color(i, text[i]) : o.color; | |
| out += Tile({ ch: text[i], x: x + i * s * 1.14, y: y, size: s, color: col, weight: o.weight, fill: o.fill }); | |
| } | |
| return out; | |
| } | |
| // ---------- RING TEXT (Chesilin) ---------- | |
| function Ring(o) { | |
| o = o || {}; | |
| var cx = o.cx || 0, cy = o.cy || 0, r1 = o.r1, r0 = o.r0, band = r1 - r0, rm = (r0 + r1) / 2; | |
| var text = String(o.text == null ? '' : o.text), n = o.cells || text.length || 1, start = o.start || 0, sweep = o.sweep || 360; | |
| var w = o.weight || weightFor(band * 1.3), da = sweep / n, out = '', i; | |
| if (sweep >= 360) out += path(Circle(cx, cy, r1).d + Circle(cx, cy, r0).d, w); | |
| else out += path(Sector(cx, cy, r0, r1, start, start + sweep).d, w); | |
| var div = ''; | |
| for (i = (sweep >= 360 ? 0 : 1); i < n; i++) { var A = P(cx, cy, r0, start + i * da), B = P(cx, cy, r1, start + i * da); div += 'M' + n2(A[0]) + ' ' + n2(A[1]) + 'L' + n2(B[0]) + ' ' + n2(B[1]); } | |
| if (o.dividers !== false) out += path(div, w * 0.75); | |
| var arc = rm * da * RAD; | |
| for (i = 0; i < n; i++) { | |
| var ch = text[i % (text.length || 1)]; | |
| if (!ch || ch === ' ') continue; | |
| var ac = start + (i + 0.5) * da; | |
| out += glyph(o.face || 'chesilin', ch, arc * 0.7, band * 0.62, w, (function (ac) { | |
| return function (p) { return P(cx, cy, rm - p[1], ac + p[0] / rm / RAD); }; | |
| })(ac), { step: Math.max(1.5, rm * 0.05) }); | |
| } | |
| return group(o.color, out); | |
| } | |
| // ---------- DIAL ---------- | |
| function Dial(o) { | |
| o = o || {}; | |
| var cx = o.cx || 0, cy = o.cy || 0, r = o.r || 120, u = Math.max(0.5, r / 150), w = o.weight || clamp(r / 130, 0.6, 1.5); | |
| var color = o.color || 'ink', out = '', rc = r, i, inner = ''; | |
| if (o.bezel !== false) { | |
| var gap = 9 * u, bez = { d: Circle(cx, cy, r).d + Circle(cx, cy, r - gap).d, pts: [], inset: function () { return []; } }; | |
| var segs = hatch([circlePts(cx, cy, r - gap * 0.18)], 45, Math.max(gap * 0.3, 1.5), { holes: [circlePts(cx, cy, r - gap * 0.82)] }); | |
| inner += path(bez.d, w) + path(dSegs(segs), Math.min(w, 0.75)); | |
| rc = r - gap; | |
| var ticks = o.ticks == null ? 60 : o.ticks, td = '', tl = ''; | |
| for (i = 0; i < ticks; i++) { | |
| var long = ticks % 12 === 0 && i % (ticks / 12) === 0, A = P(cx, cy, rc, i * 360 / ticks), B = P(cx, cy, rc - (long ? 7 : 3.5) * u, i * 360 / ticks); | |
| var seg = 'M' + n2(A[0]) + ' ' + n2(A[1]) + 'L' + n2(B[0]) + ' ' + n2(B[1]); | |
| if (long) tl += seg; else td += seg; | |
| } | |
| if (ticks) { inner += path(td, w * 0.75) + path(tl, w * 1.4); rc -= 10 * u; } | |
| if (o.diamonds !== false) for (i = 0; i < 4; i++) { var c = P(cx, cy, r * 1.26, 45 + i * 90); inner += fill(Ngon(c[0], c[1], 7 * u, 4, 0), 'cross', Math.max(1.4, u * 1.4), w); } | |
| } | |
| out += group(color, inner); | |
| var rings = o.rings || []; | |
| for (i = 0; i < rings.length; i++) { | |
| var band = rings[i].band || 22 * u; | |
| var ringOut = Ring({ cx: cx, cy: cy, r1: rc, r0: rc - band, text: rings[i].text, cells: rings[i].cells, color: rings[i].color || color, start: rings[i].start, weight: w }); | |
| // spin: seconds per turn; positive turns clockwise, negative counter-clockwise | |
| out += rings[i].spin ? '<g class="' + (rings[i].spin > 0 ? 'lg-cw' : 'lg-ccw') + '" style="transform-origin:' + n2(cx) + 'px ' + n2(cy) + 'px;--lg-turn:' + n2(Math.abs(rings[i].spin)) + 's">' + ringOut + '</g>' : ringOut; | |
| rc -= band; | |
| } | |
| if (o.sectors && o.sectors.items && o.sectors.items.length) { | |
| var items = o.sectors.items, sb = o.sectors.band || 30 * u, total = 0, a = 0, steps = [3.4, 2.4, 1.6, 1]; | |
| if (rings.length) rc -= 3 * u; | |
| for (i = 0; i < items.length; i++) total += items[i].value == null ? 1 : items[i].value; | |
| for (i = 0; i < items.length; i++) { | |
| var da = (items[i].value == null ? 1 : items[i].value) / total * 360; | |
| var sp = Math.max(sb * 0.05, 1.5) * (items[i].density ? steps[clamp(items[i].density, 1, 4) - 1] : 1.6); | |
| var set = o.sectors.density ? 'cross' : (i % 2 ? 'alt' : 'cross'); | |
| out += group(items[i].color || color, fill(Sector(cx, cy, rc - sb, rc, a, a + da), set, sp, w)); | |
| a += da; | |
| } | |
| rc -= sb; | |
| } | |
| var hub = o.hub || {}, rh = hub.r || Math.max(rc - 8 * u, r * 0.2), hubOut = path(Circle(cx, cy, rh).d, w); | |
| out += group(hub.color || color, hubOut); | |
| if (hub.word != null) { | |
| var txt = String(hub.word), cell = Math.min(rh * 0.8, rh * 1.5 / (txt.length * 1.14 - 0.14)); | |
| out += Word({ text: txt, x: cx, y: cy - cell / 2, size: cell, color: hub.color || color, align: 'center' }); | |
| } else if (hub.glyph) { | |
| out += group(hub.color || color, '<text class="lg-script" x="' + n2(cx) + '" y="' + n2(cy) + '" font-size="' + n2(rh * 1.15) + '" stroke-width="' + n2(w) + '" text-anchor="middle" dominant-baseline="central">' + esc(hub.glyph) + '</text>'); | |
| } | |
| var hands = o.hands || []; | |
| for (i = 0; i < hands.length; i++) { | |
| var h = hands[i], L = (h.length || 0.8) * (o.handReach || r * 0.7), hwid = (h.width || 5) * u, ang = h.angle || 0; | |
| var tip = P(cx, cy, L, ang), l = P(cx, cy, hwid, ang - 90), rr = P(cx, cy, hwid, ang + 90), tail = P(cx, cy, hwid * 2.2, ang + 180); | |
| var tl2 = P(tip[0], tip[1], hwid * 0.25, ang - 90), tr2 = P(tip[0], tip[1], hwid * 0.25, ang + 90); | |
| out += group(h.color || color, fill(Poly([tail, l, tl2, tr2, rr]), h.set || 'cross', Math.max(1.4, hwid * 0.3), w, { inset: 0 }), ' data-hand="' + i + '"'); | |
| } | |
| if (hands.length) out += group(color, path(Circle(cx, cy, 3 * u).d, w)); | |
| return out; | |
| } | |
| // ---------- DRUM ---------- | |
| function Drum(o) { | |
| o = o || {}; | |
| var cx = o.cx || 0, y0 = o.y || 0, R = o.r || 60, rows = o.rows || [], rowH = o.rowH || 30, cap = o.cap == null ? 10 : o.cap; | |
| var phi = (o.tilt == null ? 16 : o.tilt) * RAD, sf = Math.sin(phi), cf = Math.cos(phi), turn = o.turn || 0, w = o.weight || 1, color = o.color || 'ink'; | |
| var H = cap * 2 + rows.length * rowH; | |
| function proj(th, v) { return [cx + R * Math.sin(th), y0 + R * sf * (1 + Math.cos(th)) + v * cf]; } | |
| function front(th) { return Math.cos(th) > 0.02; } | |
| function arcAt(v, a0, a1) { | |
| var pts = [], n = 48; | |
| for (var i = 0; i <= n; i++) pts.push(proj(a0 + (a1 - a0) * i / n, v)); | |
| return dPoly(pts, true); | |
| } | |
| var out = '', s = '', i, k; | |
| // silhouette, end cap ellipse, front edges | |
| var a = proj(-Math.PI / 2, 0), b = proj(-Math.PI / 2, H), c = proj(Math.PI / 2, 0), e = proj(Math.PI / 2, H); | |
| s += arcAt(0, -Math.PI, Math.PI) + 'Z' + 'M' + n2(a[0]) + ' ' + n2(a[1]) + 'L' + n2(b[0]) + ' ' + n2(b[1]) + 'M' + n2(c[0]) + ' ' + n2(c[1]) + 'L' + n2(e[0]) + ' ' + n2(e[1]) + arcAt(H, -Math.PI / 2, Math.PI / 2); | |
| out += path(s, w * 1.4); | |
| // end cap: circle plus hatch chords | |
| var chords = hatch([circlePts(0, 0, R - 2)], 45, Math.max(R * 0.12, 3), {}), cd = ''; | |
| for (i = 0; i < chords.length; i++) cd += 'M' + n2(cx + chords[i][0]) + ' ' + n2(y0 + R * sf + chords[i][1] * sf) + 'L' + n2(cx + chords[i][2]) + ' ' + n2(y0 + R * sf + chords[i][3] * sf); | |
| out += path(cd, w * 0.6); | |
| // row rules | |
| var rules = ''; | |
| for (i = 0; i <= rows.length; i++) rules += arcAt(cap + i * rowH, -Math.PI / 2, Math.PI / 2); | |
| out += path(rules, w); | |
| // helical hatch bands at both ends (hatch generated on the unrolled surface) | |
| var circ = 2 * Math.PI * R, hel = ''; | |
| [[0, cap], [H - cap, H]].forEach(function (band) { | |
| var segs = hatch([rectPts(-circ / 2, band[0] + 1, circ, band[1] - band[0] - 2)], 45, Math.max(cap * 0.45, 3), {}); | |
| for (var q = 0; q < segs.length; q++) { | |
| var sub = subdivide([segs[q][0], segs[q][1]], [segs[q][2], segs[q][3]], 2), pen = false; | |
| for (var m = 0; m < sub.length; m++) { | |
| var th = sub[m][0] / R + turn * RAD; th = Math.atan2(Math.sin(th), Math.cos(th)); | |
| if (!front(th)) { pen = false; continue; } | |
| var pt = proj(th, sub[m][1]); hel += (pen ? 'L' : 'M') + n2(pt[0]) + ' ' + n2(pt[1]); pen = true; | |
| } | |
| } | |
| }); | |
| out += path(hel, w * 0.6); | |
| out = group(color, out); | |
| // rows of ring text, glyphs bending with the surface | |
| for (k = 0; k < rows.length; k++) { | |
| var row = rows[k], text = String(row.text || ''), n = row.cells || Math.max(text.length, 12), da = 2 * Math.PI / n, vc = cap + (k + 0.5) * rowH, inner = '', div = ''; | |
| var rowTurn = (turn + (row.turn || 0)) * RAD * (k % 2 && o.counter ? -1 : 1); | |
| for (i = 0; i < n; i++) { | |
| var edge = i * da + rowTurn; edge = Math.atan2(Math.sin(edge), Math.cos(edge)); | |
| if (front(edge)) { var p0 = proj(edge, vc - rowH / 2), p1 = proj(edge, vc + rowH / 2); div += 'M' + n2(p0[0]) + ' ' + n2(p0[1]) + 'L' + n2(p1[0]) + ' ' + n2(p1[1]); } | |
| var ch = text[i % (text.length || 1)]; | |
| if (!ch || ch === ' ') continue; | |
| var tc = (i + 0.5) * da + rowTurn; tc = Math.atan2(Math.sin(tc), Math.cos(tc)); | |
| if (Math.cos(tc) < -0.2) continue; | |
| inner += glyph(row.face || 'chesilin', ch, R * da * 0.7, rowH * 0.62, w, (function (tc, vc) { | |
| return function (p) { var th = tc + p[0] / R; return front(th) && Math.abs(th) < Math.PI ? proj(th, vc + p[1]) : null; }; | |
| })(tc, vc), { step: 1.5 }); | |
| } | |
| out += group(row.color || color, path(div, w * 0.75) + inner); | |
| } | |
| return out; | |
| } | |
| Drum.size = function (o) { | |
| var R = o.r || 60, phi = (o.tilt == null ? 16 : o.tilt) * RAD, H = (o.cap == null ? 10 : o.cap) * 2 + (o.rows || []).length * (o.rowH || 30); | |
| return { w: 2 * R, h: 2 * R * Math.sin(phi) + H * Math.cos(phi) }; | |
| }; | |
| // ---------- NODE ---------- | |
| function nodeShape(kind, x, y, r) { | |
| switch (SHAPES[kind] || kind) { | |
| case 'square': return Rect(x - r * 0.84, y - r * 0.84, r * 1.68, r * 1.68); | |
| case 'hexagon': return Ngon(x, y, r, 6, 30); | |
| case 'diamond': return Ngon(x, y, r * 1.08, 4, 0); | |
| case 'triangle': return Ngon(x, y + r * 0.16, r * 1.16, 3, 0); | |
| case 'cross': return Cross(x, y, r); | |
| case 'octagon': return Ngon(x, y, r, 8, 22.5); | |
| default: return Circle(x, y, r * 0.96); | |
| } | |
| } | |
| function Node(o) { | |
| o = o || {}; | |
| var kind = o.kind || 'mod', x = o.x || 0, y = o.y || 0, r = o.r || 14, w = o.weight || weightFor(r * 2.4); | |
| var color = o.color || (kind === 'loop' ? 'ctl' : (MEANS[kind] ? kind : 'ink')), sp = Math.max(r * 2 * 0.06, 1.5), out; | |
| if ((SHAPES[kind] || kind) === 'ring') { | |
| out = path(Circle(x, y, r * 0.96).d, w) + fill(Circle(x, y, r * 0.42), 'frame', Math.max(w * 0.8, 0.6), w, { solid: true }); | |
| } else out = fill(nodeShape(kind, x, y, r), o.set || 'cross', sp, w); | |
| out = group(color, out); | |
| if (o.label) { | |
| var ls = o.labelSize || 16; | |
| out += Word({ text: o.label, x: x, y: y + r + ls * 0.5, size: ls, color: color, align: 'center' }); | |
| } | |
| return out; | |
| } | |
| // ---------- CONNECTOR ---------- | |
| function Connector(o) { | |
| o = o || {}; | |
| var A = o.from, B = o.to, w = o.weight || 1, primary = o.kind !== 'secondary', color = o.color || 'ink'; | |
| var dot = 3.2 * w, dia = 5 * w, pts = [], len = 0, d = '', i; | |
| if (o.lane) { | |
| var L = o.lane, a0 = Math.atan2(A[0] - L.cx, -(A[1] - L.cy)) / RAD, a1 = Math.atan2(B[0] - L.cx, -(B[1] - L.cy)) / RAD, da = a1 - a0; | |
| while (da > 180) da -= 360; while (da < -180) da += 360; | |
| var S = P(L.cx, L.cy, L.r, a0), n = Math.max(2, Math.ceil(Math.abs(da) / 3)); | |
| pts.push(A); | |
| for (i = 0; i <= n; i++) pts.push(P(L.cx, L.cy, L.r, a0 + da * i / n)); | |
| pts.push(B); | |
| var E = P(L.cx, L.cy, L.r, a0 + da); | |
| d = 'M' + n2(A[0]) + ' ' + n2(A[1]) + 'L' + n2(S[0]) + ' ' + n2(S[1]) + 'A' + n2(L.r) + ' ' + n2(L.r) + ' 0 0 ' + (da > 0 ? 1 : 0) + ' ' + n2(E[0]) + ' ' + n2(E[1]) + 'L' + n2(B[0]) + ' ' + n2(B[1]); | |
| } else { | |
| var ux = B[0] - A[0], uy = B[1] - A[1], m = Math.hypot(ux, uy) || 1; ux /= m; uy /= m; | |
| var s0 = [A[0] + ux * dot, A[1] + uy * dot], s1 = [B[0] - ux * dia, B[1] - uy * dia]; | |
| pts = [s0, s1]; d = dPoly(pts, true); | |
| } | |
| for (i = 1; i < pts.length; i++) len += Math.hypot(pts[i][0] - pts[i - 1][0], pts[i][1] - pts[i - 1][1]); | |
| var out = path(d, primary ? w * 2 : w, primary ? '' : ' stroke-dasharray="' + n2(6 * w) + ' ' + n2(4 * w) + '"'); | |
| out += fill(Circle(A[0], A[1], dot), 'frame', Math.max(w * 0.8, 0.6), w, { solid: true }); | |
| var last = pts[pts.length - 2], rot = Math.atan2(B[0] - last[0], -(B[1] - last[1])) / RAD; | |
| out += path(Ngon(B[0], B[1], dia, 4, rot).d, w); | |
| if (o.packet) { | |
| var speed = typeof o.packet === 'number' ? o.packet : 48, ps = 3.2 * w; | |
| out += '<g class="lg-packet">' + fill(Rect(-ps, -ps, ps * 2, ps * 2), 'cross', Math.max(1.3, ps * 0.4), w, { inset: 0 }) + | |
| '<animateMotion dur="' + n2(len / speed) + 's" begin="' + n2(-(o.phase || 0) * len / speed) + 's" repeatCount="indefinite" rotate="auto" path="' + dPoly(pts, true) + '"/></g>'; | |
| } | |
| return group(color, out); | |
| } | |
| // ---------- MESH ---------- | |
| function Grid(o) { | |
| o = o || {}; | |
| var x = o.x || 0, y = o.y || 0, cols = o.cols || 8, rows = o.rows || 4, s = o.cell || 32, pitch = s * 1.14, vals = o.values || '', out = ''; | |
| var ax = 0, base = o.addressBase || 16; | |
| if (o.address !== false) { | |
| var aw = Math.max(2, ((rows - 1) * cols).toString(base).length), as = s * 0.5; | |
| for (var r0 = 0; r0 < rows; r0++) { | |
| var adr = (r0 * cols).toString(base).toUpperCase(); while (adr.length < aw) adr = '0' + adr; | |
| out += Word({ text: adr, x: x, y: y + r0 * pitch + (s - as) / 2, size: as, color: 'ink' }); | |
| } | |
| ax = wordWidth(new Array(aw + 1).join('0'), as) + s * 0.4; | |
| } | |
| for (var r = 0; r < rows; r++) for (var c = 0; c < cols; c++) { | |
| var i = r * cols + c, v = typeof vals === 'function' ? vals(i, r, c) : vals[i], col = typeof o.color === 'function' ? o.color(i, r, c) : o.color; | |
| var live = v != null && v !== ' ' && v !== ''; | |
| out += Tile({ ch: live ? v : '', x: x + ax + c * pitch, y: y + r * pitch, size: s, color: live ? (col || 'bind') : 'ink', fill: live ? ((r + c) % 2 ? 'cross' : 'grid') : null, density: 1.6 }); | |
| } | |
| return out; | |
| } | |
| Grid.size = function (o) { | |
| var cols = o.cols || 8, rows = o.rows || 4, s = o.cell || 32, base = o.addressBase || 16; | |
| var aw = Math.max(2, ((rows - 1) * cols).toString(base).length), ax = o.address === false ? 0 : wordWidth(new Array(aw + 1).join('0'), s * 0.5) + s * 0.4; | |
| return { w: ax + wordWidth(new Array(cols + 1).join('0'), s), h: rows * s + (rows - 1) * s * 0.14 }; | |
| }; | |
| // Circle packing inside a parent circle: largest first, centre exclusion, then a | |
| // second pass of small items in the gaps. Deterministic for a given seed. | |
| function pack(o) { | |
| o = o || {}; | |
| var R = o.r || 100, hub = o.hub || 0, pad = o.pad == null ? 3 : o.pad, rand = rng(o.seed || 1), items = [], i, t; | |
| var count = o.count || 18, mx = o.max || R * 0.26, mn = o.min || R * 0.07, radii = []; | |
| for (i = 0; i < count; i++) radii.push(mn + (mx - mn) * Math.pow(rand(), 2.2)); | |
| radii.sort(function (a, b) { return b - a; }); | |
| function place(r, tries) { | |
| for (t = 0; t < tries; t++) { | |
| var a = rand() * 2 * Math.PI, d = Math.sqrt(rand()) * (R - pad - r), px = d * Math.cos(a), py = d * Math.sin(a), ok = d - r >= hub + pad; | |
| for (var k = 0; ok && k < items.length; k++) ok = Math.hypot(px - items[k].x, py - items[k].y) >= r + items[k].r + pad; | |
| if (ok) { items.push({ x: px, y: py, r: r, index: items.length }); return true; } | |
| } | |
| return false; | |
| } | |
| for (i = 0; i < radii.length; i++) place(radii[i], 500); | |
| var first = items.length, fillers = o.fillers == null ? 40 : o.fillers; | |
| for (i = 0; i < fillers; i++) place(mn * (0.45 + 0.4 * rand()), 120); | |
| for (i = 0; i < items.length; i++) { items[i].small = i >= first; items[i].x += o.cx || 0; items[i].y += o.cy || 0; } | |
| return items; | |
| } | |
| function Bubble(o) { | |
| o = o || {}; | |
| var cx = o.cx || 0, cy = o.cy || 0, R = o.r || 100, w = o.weight || 1, colors = o.colors || KEYS, items = o.items || pack(o), labels = o.labels || '', out = ''; | |
| out += group(o.color || 'ink', path(Circle(cx, cy, R).d, w * 1.4) + (o.hub ? path(Circle(cx, cy, o.hub).d, w) : '')); | |
| for (var i = 0; i < items.length; i++) { | |
| var it = items[i], col = it.color || colors[i % colors.length], sp = Math.max(it.r * 0.12, 1.5), holes = [], extra = ''; | |
| var ch = !it.small && it.r >= 12 ? labels[i] : null; | |
| if (ch && ch !== ' ') { | |
| var cell = it.r * 0.95; | |
| holes.push(rectPts(it.x - cell / 2 - sp, it.y - cell / 2 - sp, cell + 2 * sp, cell + 2 * sp)); | |
| extra = Tile({ ch: ch, x: it.x - cell / 2, y: it.y - cell / 2, size: cell, color: col }); | |
| } | |
| out += group(col, it.small ? path(Circle(it.x, it.y, it.r).d, w * 0.75) : fill(Circle(it.x, it.y, it.r), i % 2 ? 'alt' : 'cross', sp, w, { holes: holes })) + extra; | |
| } | |
| return out; | |
| } | |
| function Mesh(o) { return (o && o.type === 'bubble') ? Bubble(o) : Grid(o); } | |
| Mesh.size = Grid.size; Mesh.pack = pack; | |
| // ---------- FRAME ---------- | |
| function Frame(o) { | |
| o = o || {}; | |
| var x = o.x || 0, y = o.y || 0, W = o.w || 320, H = o.h || 200, w = o.weight || 1, gap = o.gap || 8, arm = o.bracket || 24, out = '', holes = [], i; | |
| var cut = o.diamonds ? gap * 1.35 : 0; | |
| function rule(ins) { | |
| var a = x + ins, b = y + ins, c = x + W - ins, e = y + H - ins, k = cut ? cut - ins : 0; | |
| if (!cut) return dPoly(rectPts(a, b, W - 2 * ins, H - 2 * ins)); | |
| return 'M' + n2(a + k) + ' ' + n2(b) + 'H' + n2(c - k) + 'M' + n2(c) + ' ' + n2(b + k) + 'V' + n2(e - k) + 'M' + n2(c - k) + ' ' + n2(e) + 'H' + n2(a + k) + 'M' + n2(a) + ' ' + n2(e - k) + 'V' + n2(b + k); | |
| } | |
| var tab = '', tabHole = null; | |
| if (o.title) { | |
| var ts = o.titleSize || 16, tw = wordWidth(o.title, ts), tx = x + gap + arm + gap, pad = ts * 0.4, th = ts + pad * 2; | |
| tabHole = [tx - 1, tx + tw + pad * 2 + 1]; | |
| tab = path('M' + n2(tx) + ' ' + n2(y) + 'V' + n2(y - th) + 'H' + n2(tx + tw + pad * 2) + 'V' + n2(y), w * 2) + '</g>' + Word({ text: o.title, x: tx + pad, y: y - th + pad, size: ts, color: o.titleColor || o.color }) + '<g class="lg lg-' + (o.color || 'ink') + '">'; | |
| } | |
| out += path(rule(0), w * 2) + path(rule(gap), w); | |
| if (o.diamonds) { | |
| var corners = [[x + gap / 2, y + gap / 2], [x + W - gap / 2, y + gap / 2], [x + W - gap / 2, y + H - gap / 2], [x + gap / 2, y + H - gap / 2]]; | |
| for (i = 0; i < 4; i++) { var dm = Ngon(corners[i][0], corners[i][1], gap * 1.2, 4, 0); out += fill(dm, 'cross', Math.max(1.4, gap * 0.2), w); holes.push(ngonPts(corners[i][0], corners[i][1], gap * 1.2 + 2, 4, 0)); } | |
| } | |
| if (o.dots) { | |
| var mids = [[x + W / 2, y + gap / 2], [x + W - gap / 2, y + H / 2], [x + W / 2, y + H - gap / 2], [x + gap / 2, y + H / 2]]; | |
| for (i = 0; i < 4; i++) { out += fill(Circle(mids[i][0], mids[i][1], gap * 0.28), 'frame', Math.max(w * 0.8, 0.6), w, { solid: true }); holes.push(circlePts(mids[i][0], mids[i][1], gap * 0.28 + 2.5)); } | |
| } | |
| var hs = Math.max(gap * 0.5, 3), ins = Math.min(hs / 2, gap * 0.22); | |
| holes.push(rectPts(x + gap - ins, y + gap - ins, W - 2 * gap + 2 * ins, H - 2 * gap + 2 * ins)); | |
| out += path(dSegs(hatch([rectPts(x + ins, y + ins, W - 2 * ins, H - 2 * ins)], 45, hs, { holes: holes })), Math.min(w, 0.75)); | |
| var bi = gap * 2; | |
| out += path('M' + n2(x + bi) + ' ' + n2(y + bi + arm) + 'V' + n2(y + bi) + 'H' + n2(x + bi + arm) + 'M' + n2(x + W - bi - arm) + ' ' + n2(y + bi) + 'H' + n2(x + W - bi) + 'V' + n2(y + bi + arm) + | |
| 'M' + n2(x + W - bi) + ' ' + n2(y + H - bi - arm) + 'V' + n2(y + H - bi) + 'H' + n2(x + W - bi - arm) + 'M' + n2(x + bi + arm) + ' ' + n2(y + H - bi) + 'H' + n2(x + bi) + 'V' + n2(y + H - bi - arm), w * 2); | |
| if (o.ticks) { | |
| var td = '', step = 8, k = 0, v; | |
| for (v = x + bi + arm + step; v < x + W - bi - arm; v += step, k++) { var tl = k % 5 === 0 ? 6 : 3; td += 'M' + n2(v) + ' ' + n2(y + gap) + 'v' + tl + 'M' + n2(v) + ' ' + n2(y + H - gap) + 'v' + (-tl); } | |
| for (k = 0, v = y + bi + arm + step; v < y + H - bi - arm; v += step, k++) { var tk = k % 5 === 0 ? 6 : 3; td += 'M' + n2(x + gap) + ' ' + n2(v) + 'h' + tk + 'M' + n2(x + W - gap) + ' ' + n2(v) + 'h' + (-tk); } | |
| out += path(td, w * 0.75); | |
| } | |
| return group(o.color, out + tab); | |
| } | |
| // The clear content box inside a frame. | |
| Frame.inner = function (o) { var gap = o.gap || 8, m = gap * 2 + 6; return { x: (o.x || 0) + m, y: (o.y || 0) + m, w: (o.w || 320) - 2 * m, h: (o.h || 200) - 2 * m }; }; | |
| // ---------- LEGEND ---------- | |
| function Legend(o) { | |
| o = o || {}; | |
| var x = o.x || 0, y = o.y || 0, s = o.size || 16, keys = o.keys || KEYS, cols = o.cols || 1, per = Math.ceil(keys.length / cols), rowH = s * 1.7, colW = s * 2.2 + wordWidth('0000', s) + s * 1.4, out = ''; | |
| for (var i = 0; i < keys.length; i++) { | |
| var k = keys[i], col = k === 'loop' ? 'ctl' : k, px = x + Math.floor(i / per) * colW, py = y + (i % per) * rowH; | |
| out += Node({ kind: k, x: px + s * 0.8, y: py + s / 2, r: s * 0.62, color: col, set: i % 2 ? 'alt' : 'cross' }); | |
| out += Word({ text: (o.labels && o.labels[k]) || k, x: px + s * 2.2, y: py, size: s, color: col }); | |
| } | |
| return out; | |
| } | |
| Legend.size = function (o) { | |
| o = o || {}; | |
| var s = o.size || 16, keys = o.keys || KEYS, cols = o.cols || 1, per = Math.ceil(keys.length / cols); | |
| return { w: cols * (s * 2.2 + wordWidth('0000', s) + s * 1.4) - s * 1.4, h: per * s * 1.7 - s * 0.7 }; | |
| }; | |
| // ---------- TITLE PLATE ---------- | |
| function plateSize(o) { | |
| var s = o.size || 24, small = o.small || 16, gap = o.gap || 6, pad = gap * 2 + 8; | |
| var w = Math.max(wordWidth(o.title || '', s), wordWidth(o.subtitle || '', small), wordWidth(o.rev || '', small)); | |
| var h = s + (o.subtitle ? small + 8 : 0) + (o.rev ? small + 14 : 0); | |
| return { w: w + pad * 2, h: h + pad * 2, pad: pad, s: s, small: small, gap: gap }; | |
| } | |
| function TitlePlate(o) { | |
| o = o || {}; | |
| var m = plateSize(o), x = o.x || 0, y = o.y || 0, color = o.color || 'mod', out = '', cy = y + m.pad; | |
| out += Frame({ x: x, y: y, w: m.w, h: m.h, gap: m.gap, bracket: 0.001, color: 'ink', dots: o.dots }); | |
| out += Word({ text: o.title || '', x: x + m.pad, y: cy, size: m.s, color: color }); cy += m.s; | |
| if (o.subtitle) { cy += 8; out += Word({ text: o.subtitle, x: x + m.pad, y: cy, size: m.small, color: 'ink' }); cy += m.small; } | |
| if (o.rev) { | |
| cy += 7; out += group('ink', path('M' + n2(x + m.pad) + ' ' + n2(cy) + 'H' + n2(x + m.w - m.pad), 1)); cy += 7; | |
| out += Word({ text: o.rev, x: x + m.pad, y: cy, size: m.small, color: 'ink' }); | |
| } | |
| return out; | |
| } | |
| TitlePlate.size = function (o) { var m = plateSize(o || {}); return { w: m.w, h: m.h }; }; | |
| // ---------- svg wrapper, mount ---------- | |
| function Art(inner, o) { | |
| o = o || {}; | |
| var w = o.w || 320, h = o.h || 200; | |
| return '<svg class="lg-art" xmlns="http://www.w3.org/2000/svg" viewBox="' + (o.viewBox || ('0 0 ' + n2(w) + ' ' + n2(h))) + '" width="' + n2(w) + '" height="' + n2(h) + '"' + | |
| (o.label ? ' role="img" aria-label="' + esc(o.label) + '"' : ' aria-hidden="true"') + '>' + inner + '</svg>'; | |
| } | |
| function reduced() { return !!(root.matchMedia && root.matchMedia('(prefers-reduced-motion: reduce)').matches); } | |
| function mount(el, inner, o) { | |
| if (typeof el === 'string') el = document.querySelector(el); | |
| el.innerHTML = Art(inner, o); | |
| var svg = el.firstChild, texts = svg.querySelectorAll('text.lg-script'); | |
| // other scripts are centred on their own bounding box, never on the baseline | |
| function centre() { | |
| for (var i = 0; i < texts.length; i++) { | |
| var t = texts[i], x = parseFloat(t.getAttribute('x')), y = parseFloat(t.getAttribute('y')); | |
| if (!t.hasAttribute('data-cx')) { t.setAttribute('data-cx', x); t.setAttribute('data-cy', y); } | |
| var cx = parseFloat(t.getAttribute('data-cx')), cy = parseFloat(t.getAttribute('data-cy')), b; | |
| try { b = t.getBBox(); } catch (e) { continue; } | |
| t.setAttribute('x', n2(x + cx - (b.x + b.width / 2))); t.setAttribute('y', n2(y + cy - (b.y + b.height / 2))); | |
| } | |
| } | |
| if (texts.length) { centre(); if (document.fonts && document.fonts.ready) document.fonts.ready.then(centre); } | |
| if (reduced() && svg.pauseAnimations) { svg.pauseAnimations(); svg.classList.add('lg-paused'); } | |
| return svg; | |
| } | |
| // ---------- PANEL (DOM) ---------- | |
| // One translucent control panel, set in Daemon tiles. Real buttons underneath: | |
| // every control carries its plain-text name for assistive tech. | |
| function Panel(el, o) { | |
| if (typeof el === 'string') el = document.querySelector(el); | |
| o = o || {}; | |
| var s = o.size || 16, state = { open: o.open == null ? !(root.matchMedia && root.matchMedia('(max-width: 760px)').matches) : o.open, toggles: {}, speed: 0 }; | |
| var toggles = o.toggles || [], speed = o.speed, steps = speed ? (speed.steps || 5) : 0; | |
| toggles.forEach(function (t) { state.toggles[t.id] = t.on !== false; }); | |
| if (speed) state.speed = speed.value == null ? (reduced() ? 0 : Math.min(2, steps - 1)) : speed.value; | |
| function word(text, color) { return Art(Word({ text: text, size: s, color: color, x: 1, y: 1 }), { w: wordWidth(text, s) + 2, h: s + 2 }); } | |
| function sw(on, color) { return Art(Tile({ ch: '', size: s, x: 1, y: 1, color: on ? color : 'ink', fill: on ? 'cross' : null, density: 1.5 }), { w: s + 2, h: s + 2 }); } | |
| function emit(kind, id) { if (o.onChange) o.onChange({ toggles: state.toggles, speed: state.speed, open: state.open }, kind, id); } | |
| function render() { | |
| var h = '<div class="lg-panel-box' + (state.open ? '' : ' lg-collapsed') + '">'; | |
| h += '<button type="button" class="lg-panel-head" data-k="open" aria-expanded="' + state.open + '" aria-label="' + esc((o.title || 'controls') + (state.open ? ', collapse' : ', expand')) + '">' + word(o.title || 'controls', o.color || 'mod') + sw(state.open, o.color || 'mod') + '</button>'; | |
| if (state.open) { | |
| h += '<div class="lg-panel-rows">'; | |
| toggles.forEach(function (t) { | |
| var on = state.toggles[t.id]; | |
| h += '<button type="button" class="lg-panel-row" data-k="toggle" data-id="' + esc(t.id) + '" aria-pressed="' + on + '" aria-label="' + esc(t.label || t.id) + '">' + sw(on, t.color || 'ctl') + word(t.label || t.id, on ? (t.color || 'ctl') : 'ink') + '</button>'; | |
| }); | |
| if (speed) { | |
| h += '<div class="lg-panel-row lg-panel-speed" role="group" aria-label="' + esc(speed.label || 'speed') + '">'; | |
| for (var i = 0; i < steps; i++) { | |
| var cur = i === state.speed; | |
| h += '<button type="button" data-k="speed" data-id="' + i + '" aria-pressed="' + cur + '" aria-label="' + esc((speed.label || 'speed') + ' ' + i + (i === 0 ? ', stopped' : '')) + '">' + | |
| Art(Tile({ ch: String(i), size: s, x: 1, y: 1, color: cur ? (speed.color || 'ctl') : 'ink', fill: cur ? 'cross' : null, density: 1.5 }), { w: s + 2, h: s + 2 }) + '</button>'; | |
| } | |
| h += word(speed.label || 'speed', 'ink') + '</div>'; | |
| } | |
| h += '</div>'; | |
| } | |
| el.innerHTML = h + '</div>'; | |
| } | |
| el.classList.add('lg-panel'); | |
| el.addEventListener('click', function (ev) { | |
| var b = ev.target.closest ? ev.target.closest('button[data-k]') : null; | |
| if (!b) return; | |
| var k = b.getAttribute('data-k'), id = b.getAttribute('data-id'); | |
| if (k === 'open') state.open = !state.open; | |
| else if (k === 'toggle') state.toggles[id] = !state.toggles[id]; | |
| else if (k === 'speed') state.speed = +id; | |
| render(); emit(k, id); | |
| var again = el.querySelector('button[data-k="' + k + '"]' + (id != null ? '[data-id="' + id + '"]' : '')); | |
| if (again) again.focus(); | |
| }); | |
| render(); | |
| return { state: state, render: render }; | |
| } | |
| // ---------- HATCH (the foundation, as a swatch) ---------- | |
| function Hatch(o) { | |
| o = o || {}; | |
| var x = o.x || 0, y = o.y || 0, w = o.w || 64, h = o.h || 64, shape; | |
| if (o.shape === 'circle') shape = Circle(x + w / 2, y + h / 2, Math.min(w, h) / 2); | |
| else if (o.shape === 'sector') shape = Sector(o.cx, o.cy, o.r0, o.r1, o.a0, o.a1); | |
| else if (o.shape === 'ngon') shape = Ngon(x + w / 2, y + h / 2, Math.min(w, h) / 2, o.sides || 6, o.rot || 0); | |
| else if (o.points) shape = Poly(o.points); | |
| else shape = Rect(x, y, w, h); | |
| var steps = [3.4, 2.4, 1.6, 1], base = o.spacing || Math.max(Math.min(w, h) * 0.05, 1.5); | |
| var sp = base * (o.density ? steps[clamp(o.density, 1, 4) - 1] : 1.6); | |
| return group(o.color, fill(shape, o.set || 'cross', sp, o.weight || 1, { holes: o.holes, solid: o.solid })); | |
| } | |
| var Ling = { | |
| Hatch: Hatch, Tile: Tile, Word: Word, Ring: Ring, Dial: Dial, Drum: Drum, Node: Node, Connector: Connector, | |
| Mesh: Mesh, Grid: Grid, Bubble: Bubble, Frame: Frame, Legend: Legend, TitlePlate: TitlePlate, Panel: Panel, | |
| Art: Art, mount: mount, pack: pack, wordWidth: wordWidth, reducedMotion: reduced, | |
| keys: KEYS, shapes: SHAPES, means: MEANS, angles: ANGLES, | |
| geometry: { hatch: hatch, fill: fill, Rect: Rect, Circle: Circle, Ngon: Ngon, Cross: Cross, Sector: Sector, Poly: Poly, point: P, glyph: glyph, glyphFit: glyphFit, segments: dSegs, has: function (face, ch) { return !!(GLYPHS[face] && GLYPHS[face][ch]); } } | |
| }; | |
| root.Ling = Ling; | |
| if (typeof module !== 'undefined' && module.exports) module.exports = Ling; | |
| })(typeof window !== 'undefined' ? window : globalThis); | |