/* Build with `cc -lm -O2 retro-unix.c -o retro` */ #define BIT64 #define ENABLE_CLOCK #define ENABLE_FILES #define ENABLE_FLOATS #define ENABLE_MALLOC #define ENABLE_MULTICORE #define ENABLE_RNG #define ENABLE_SCRIPTING #define ENABLE_SIGNALS #define ENABLE_UNIX #define ENABLE_UNSIGNED /*--------------------------------------------------------------------- Copyright (c) 2008 - 2022, Charles Childers Portions are based on Ngaro, which was additionally copyright by the following: Copyright (c) 2009 - 2010, Luke Parrish Copyright (c) 2010, Marc Simpson Copyright (c) 2010, Jay Skeer Copyright (c) 2011, Kenneth Keating ---------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef ENABLE_SIGNALS #include #endif #ifdef ENABLE_MULTICORE #define CORES 8 #else #define CORES 1 #endif #ifdef _WIN32 #define NEEDS_STRL #endif #ifdef _WIN64 #define NEEDS_STRL #endif #if defined(__APPLE__) && defined(__MACH__) #ifdef NEEDS_STRL #undef NEEDS_STRL #endif #endif /* Configuration ----------------------------------------------------- */ #ifndef BIT64 #define CELL int32_t #define CELL_MIN INT_MIN + 1 #define CELL_MAX INT_MAX - 1 #else #define CELL int64_t #define CELL_MIN LLONG_MIN + 1 #define CELL_MAX LLONG_MAX - 1 #endif #ifndef IMAGE_SIZE #define IMAGE_SIZE 524288 /* Amount of RAM, in cells */ #endif #ifndef ADDRESSES #define ADDRESSES 256 /* Depth of address stack */ #endif #ifndef STACK_DEPTH #define STACK_DEPTH 256 /* Depth of data stack */ #endif #define TIB vm->memory[7] /* Location of TIB */ #define MAX_DEVICES 32 #define MAX_OPEN_FILES 32 #include #ifndef CELL #ifndef BIT64 #define CELL int32_t #define CELL_MIN INT_MIN + 1 #define CELL_MAX INT_MAX - 1 #else #define CELL int64_t #define CELL_MIN LLONG_MIN + 1 #define CELL_MAX LLONG_MAX - 1 #endif #endif CELL ngaImageCells = 20246; CELL ngaImage[] = { 1793,19752,20201,20245,202309,417,389,1249,1535,0,11278,0,10,1,10,2,10,3,10, 4,10,5,10,6,10,7,10,8,10,11,10,12,10,13,10,14,10,15,10, 16,10,17,10,18,10,19,10,20,10,21,10,22,10,23,10,24,10,25,68223234, 1,2575,85000450,1,656912,163,180,268505089,65,64,285281281,0,65,2063,10,101384453,0,9,10,68485378, 255,18350338,8,255,1045,18350338,16,255,1045,352393217,24,255,10,268289,-24,68229121,-16,68229121,-8,2577, 2049,58,25,459011,99,524546,99,302256641,1,10,16974595,0,50529798,10,25,524547,118,50529798,10,17108738, 1,251790353,101777669,1,17565186,109,524545,113,66,167838467,-1,134287105,3,61,659457,3,459023,130,2049,58, 25,2049,130,1793,137,2049,137,117506307,0,130,0,524545,28,135,168820993,0,149,1642241,149,134283523, 13,135,1793,130,524545,2049,130,1793,130,16846593,149,163,180,1793,66,16846593,149,135,180,1793, 66,7,10,659713,1,659713,2,659713,3,659713,4,659713,5,1793,19998,17108737,3,2,524559,130, 2049,130,2049,130,524545,0,130,524545,0,130,2049,144,1048838,2,1642241,10,7,19011,8246457295145463473,167841793, 216,11,17826049,0,216,2,15,25,524546,18112,134287105,217,29,2305,218,459023,226,2049,4875,134287361, 217,221,659201,216,10,659969,7,2049,58,25,17694978,58,244,9,84152833,48,319750404,243,117507601,246, 184618754,45,25,16974851,-1,168886532,1,134284289,1,259,134284289,0,246,660227,32,0,0,115,105,103, 105,108,58,105,0,285278479,276,6,2576,524546,104,1641217,1,167838467,273,2049,288,2049,284,524545, 276,236,17826050,275,0,2572,2563,2049,266,1793,156,459023,156,1793,314,17760513,168,3,192,8, 251727617,3,2,2049,182,16,168820993,-1,149,2049,182,2575,2049,236,17563906,0,328,9,1793,156, 285282049,3,2,134287105,149,325,524545,1793,130,16846593,3,0,130,8,659201,3,524545,28,135,17043201, 3,13,2049,135,2049,130,268505092,149,1642241,149,656131,659201,3,524545,13,135,2049,130,459009,25, 135,459009,57,135,459009,21,135,459009,23,135,1793,11,10,524546,182,134284303,184,1807,1249,1642241, 275,285282049,397,1,459012,392,117509889,216,392,134287105,397,236,16845825,0,405,389,1793,66,1793,419, 17826050,397,294,8,117506305,398,408,66,2116,11340,11700,11400,13685,13104,12432,12402,9603,9801,11514,11413, 11110,12528,11948,10302,13340,9700,13455,12753,10500,10670,12654,13320,11960,13908,10088,10605,11865,11025,0,2049, 236,987393,1,1793,130,524546,495,2049,493,2049,493,17891588,2,495,8,17045505,-24,-16,17043736,-8, 1118488,1793,130,17043202,1,169021201,2049,58,25,33883396,101450758,6404,459011,485,34668804,2,2049,482,524545,427, 485,302056196,427,659969,1,114,101,116,114,111,46,109,117,114,105,0,0,15,174,504, 193489870,100,117,112,0,515,17,174,504,6385162522,100,114,111,112,0,524,19,174,504,6385706560, 115,119,97,112,0,534,27,174,504,6385107969,99,97,108,108,0,544,29,174,504,193490778, 101,113,63,0,554,31,174,504,6383171847,45,101,113,63,0,563,33,174,504,193498500,108, 116,63,0,573,35,174,504,193493055,103,116,63,0,582,37,174,504,210712273007,102,101,116, 99,104,0,591,39,174,504,210728224082,115,116,111,114,101,0,602,41,174,504,177616,43, 0,613,43,174,504,177618,45,0,620,45,174,504,177615,42,0,627,47,174,504,6383252404, 47,109,111,100,0,634,49,174,504,193486360,97,110,100,0,644,51,174,504,5863686,111, 114,0,653,53,174,504,193511454,120,111,114,0,661,55,174,504,210727785923,115,104,105,102, 116,0,670,383,180,504,6385597157,112,117,115,104,0,681,386,180,504,193502740,112,111,112, 0,691,380,180,504,5861552,48,59,0,700,58,168,504,8246307614109670331,102,101,116,99,104,45, 110,101,120,116,0,708,61,168,504,8246931865698567806,115,116,111,114,101,45,110,101,120,116, 0,724,266,168,504,-4555094569267928757,115,58,116,111,45,110,117,109,98,101,114,0,740,118, 168,504,210726128775,115,58,101,113,63,0,757,104,168,504,7572865151309012,115,58,108,101,110,103, 116,104,0,768,66,168,504,6953390994662,99,104,111,111,115,101,0,782,76,174,504,5863476, 105,102,0,794,74,168,504,193429569,45,105,102,0,802,305,180,504,229482595734751,115,105,103, 105,108,58,40,0,811,149,156,504,7570887965854272,67,111,109,112,105,108,101,114,0,824, 3,156,504,6384141667,72,101,97,112,0,838,130,168,504,177617,44,0,848,144,168,504, 5863748,115,44,0,855,150,180,504,177632,59,0,863,339,180,504,177664,91,0,870,355, 180,504,177666,93,0,877,2,156,504,8244734546833303387,68,105,99,116,105,111,110,97,114,121, 0,884,181,168,504,6953375463185,100,58,108,105,110,107,0,900,182,168,504,6385101839,100,58, 120,116,0,912,184,168,504,229461379705849,100,58,99,108,97,115,115,0,922,190,168,504, 6953375526308,100,58,110,97,109,101,0,935,168,168,504,8246177435876103505,99,108,97,115,115,58,119, 111,114,100,0,947,180,168,504,-4577305721744236665,99,108,97,115,115,58,109,97,99,114,111, 0,963,156,168,504,8246177435875405519,99,108,97,115,115,58,100,97,116,97,0,980,192,168, 504,-3503194823018915134,100,58,97,100,100,45,104,101,97,100,101,114,0,996,306,180,504,229482595734746, 115,105,103,105,108,58,35,0,1014,312,180,504,229482595734769,115,105,103,105,108,58,58, 0,1027,331,180,504,229482595734749,115,105,103,105,108,58,38,0,1040,310,180,504,229482595734747,115, 105,103,105,108,58,36,0,1053,370,180,504,6953974492262,114,101,112,101,97,116,0,1066, 372,180,504,210706394789,97,103,97,105,110,0,1078,417,168,504,249892712402858498,105,110,116,101,114, 112,114,101,116,0,1089,236,168,504,7572225886563901,100,58,108,111,111,107,117,112,0,1104, 174,168,504,399738814153734542,99,108,97,115,115,58,112,114,105,109,105,116,105,118,101,0, 1118,4,156,504,229445000025131,86,101,114,115,105,111,110,0,1139,464,168,504,177678,105,0, 1152,130,168,504,177673,100,0,1159,458,168,504,177687,114,0,1166,243,156,504,6383922272,66, 97,115,101,0,1173,92,168,504,6385574852,112,97,99,107,0,1183,78,168,504,6954102567431,117, 110,112,97,99,107,0,1193,186,168,504,7572226160734292,100,58,115,111,117,114,99,101,0, 1205,188,168,504,6953375310887,100,58,104,97,115,104,0,1219,389,168,504,-3366153855364863819,101,114,114, 58,110,111,116,102,111,117,110,100,0,105,109,97,103,101,58,115,97,118,101, 0,103,101,0,65,68,77,69,46,114,101,116,114,111,0,0,111,0,70,76, 79,87,0,0,101,116,115,46,0,50,46,49,47,83,79,67,75,69,84,83, 46,109,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1231,1545,168, 12065,193454822,69,79,77,0,1,-3,15,10,1536,1560,168,12065,210709897370,100,101,112,116,104, 0,1,-1,15,10,1549,1576,168,12065,6953375454647,100,58,108,97,115,116,0,1,2,15, 10,1564,1595,168,12065,249883453713703409,100,58,108,97,115,116,46,120,116,0,2049,1576,2049,182, 15,10,1580,1619,168,12065,-3502687787217310053,100,58,108,97,115,116,46,99,108,97,115,115,0, 2049,1576,2049,184,15,10,1601,1642,168,12065,-4578080011420638202,100,58,108,97,115,116,46,110,97, 109,101,0,2049,1576,2049,190,10,1625,1660,168,12065,229481143079314,114,101,99,108,97,115,115, 0,2049,1576,2049,184,16,10,1647,1681,168,12065,249892660727267252,105,109,109,101,100,105,97,116, 101,0,1,180,2049,1660,10,1666,1696,168,12065,6385144159,100,97,116,97,0,1,156,2049, 1660,10,1686,1716,168,12065,249902713833354782,112,114,105,109,105,116,105,118,101,0,1,174,2049, 1660,10,1701,1731,180,12065,6385302998,104,111,111,107,0,1,1793,2049,130,1,3,15,1, 1,17,2049,130,10,1721,1758,168,12065,7572920930896175,115,101,116,45,104,111,111,107,0,1, 1,17,16,10,1744,1775,168,12065,6954102295577,117,110,104,111,111,107,0,1,1,17,2, 1,1,17,4,16,10,1763,1792,180,12065,177613,40,0,10,1785,1800,180,12065,177614,41, 0,10,1793,1818,168,12065,-4577149749211730287,99,111,109,112,105,108,101,58,108,105,116,0,1, 1,2049,130,2049,130,10,1801,1843,168,12065,-3471989134310745468,99,111,109,112,105,108,101,58,106, 117,109,112,0,1,1793,2049,130,2049,130,10,1825,1868,168,12065,-3471989134311018844,99,111,109,112, 105,108,101,58,99,97,108,108,0,1,2049,2049,130,2049,130,10,1850,1892,168,12065, -4577149749211723885,99,111,109,112,105,108,101,58,114,101,116,0,1,10,2049,130,10,1875,1913, 168,12065,8246182162316307558,99,111,109,112,105,108,105,110,103,63,0,1,149,15,10,1897,1930, 180,12065,229482595734807,115,105,103,105,108,58,96,0,2049,266,2049,130,10,1917,1948,180,12065, 229482595734803,115,105,103,105,108,58,92,0,2049,464,10,1935,1964,180,12065,229482595734805,115,105,103, 105,108,58,94,0,2049,458,10,1951,1977,168,12065,6385292201,104,101,114,101,0,1,3, 15,10,1967,1994,180,12065,229482595734775,115,105,103,105,108,58,64,0,2049,236,2049,182,15, 2049,1913,1793,2010,1,3841,2049,130,2049,130,10,1,2003,1793,2016,15,10,1,2014,2049, 66,10,1981,2034,180,12065,229482595734744,115,105,103,105,108,58,33,0,2049,236,2049,182,15, 2049,1913,1793,2050,1,4097,2049,130,2049,130,10,1,2043,1793,2056,16,10,1,2054,2049, 66,10,2021,2075,168,12065,7572225537532823,100,58,99,114,101,97,116,101,0,1793,2077,1,156, 1,0,2049,192,2049,1977,2049,1576,2049,182,16,10,2061,2102,168,12065,210731100041,118,97,114, 45,110,0,2049,2075,2049,130,10,2091,2116,168,12065,193508814,118,97,114,0,134284289,0,2102, 10,2107,2131,168,12065,210709068620,99,111,110,115,116,0,2049,2075,2049,1576,2049,182,16,10, 2120,2149,174,12065,6385740380,116,117,99,107,0,100926722,10,2139,2161,174,12065,6385561857,111,118,101, 114,0,67502597,10,2151,2172,174,12065,193500364,110,105,112,0,772,10,2163,2189,174,12065,249885844724841747, 100,114,111,112,45,112,97,105,114,0,771,10,2174,2201,174,12065,6383817805,63,100,117, 112,0,6402,10,2191,2217,168,12065,7572302161469511,100,117,112,45,112,97,105,114,0,67502597,67502597, 10,2203,2229,168,12065,193489474,100,105,112,0,525572,6,10,2220,2241,168,12065,193505809,115,105, 112,0,67502597,1,27,2049,2229,10,2232,2255,168,12065,5863248,98,105,0,1,2241,2049,2229, 8,10,2247,2270,168,12065,193487226,98,105,42,0,1,2229,2049,2229,8,10,2261,2285,168, 12065,193487248,98,105,64,0,2,2049,2270,10,2276,2298,168,12065,193507188,116,114,105,0,1793, 2307,1,2241,2049,2229,2049,2241,10,1,2300,2049,2229,8,10,2289,2323,168,12065,6385737246,116, 114,105,42,0,1793,2340,1793,2333,4,1,2229,2049,2229,10,1,2327,2049,2229,2049,2229, 10,1,2325,2049,2229,8,10,2313,2356,168,12065,6385737268,116,114,105,64,0,2,2,2049, 2323,10,2346,2372,168,12065,210732529790,119,104,105,108,101,0,1793,2381,525570,1639430,3,1,2374, 7,10,1,2374,8,3,10,2361,2397,168,12065,210730385457,117,110,116,105,108,0,1793,2408, 525570,385942534,-1,25,3,1,2399,7,10,1,2399,8,3,10,2386,2426,168,12065,229466054377278,102, 111,114,101,118,101,114,0,1793,2430,8,10,1,2428,2049,2241,1,2426,7,10,2413, 2449,168,12065,210729012103,116,105,109,101,115,0,1793,2461,4,25,33886721,1,2053,1542,1,2452, 7,10,1,2451,8,3,10,2438,2479,180,12065,229482595734835,115,105,103,105,108,58,124,0, 2049,236,1793,2487,2049,182,15,10,1,2483,1793,2495,2049,184,15,10,1,2491,2049,2255, 2049,1913,1793,2510,1,156,2049,2229,2049,1868,10,1,2503,1,27,2049,66,10,2466,2527, 168,12065,6384551781,84,82,85,69,0,1,-1,10,2517,2541,168,12065,210672985680,70,65,76,83, 69,0,1,0,10,2530,2554,168,12065,6385108193,99,97,115,101,0,1793,2559,67502597,11,10, 1,2556,2049,2229,4,1793,2571,772,8,2049,2527,10,1,2566,1793,2579,3,2049,2541,10, 1,2575,2049,66,25,6,3,3,10,2544,2600,168,12065,6953962162094,115,58,99,97,115,101, 0,1793,2606,67502597,2049,118,10,1,2602,2049,2229,4,1793,2618,772,8,2049,2527,10,1, 2613,1793,2626,3,2049,2541,10,1,2622,2049,66,25,6,3,3,10,2588,2644,168,12065, 193500566,110,111,116,0,1,-1,23,10,2635,2659,168,12065,210719911674,108,116,101,113,63,0, 2049,2217,101516555,22,10,2648,2675,168,12065,210713982069,103,116,101,113,63,0,4,2049,2659,10, 2664,2690,168,12065,210720171475,110,58,77,65,88,0,1,-5,15,10,2679,2705,168,12065,210720171729, 110,58,77,73,78,0,1,-4,15,10,2694,2722,168,12065,229474321428492,110,58,122,101,114, 111,63,0,1,0,11,10,2709,2740,168,12065,7572649618157049,110,58,45,122,101,114,111,63, 0,1,0,12,10,2726,2761,168,12065,-4562761254435316065,110,58,110,101,103,97,116,105,118,101, 63,0,1,0,13,10,2744,2782,168,12065,-4562757999622951041,110,58,112,111,115,105,116,105,118, 101,63,0,1,-1,14,10,2765,2812,168,12065,-1420858746182909718,110,58,115,116,114,105,99,116, 108,121,45,112,111,115,105,116,105,118,101,63,0,1,0,14,10,2786,2829,168, 12065,229474297120890,110,58,101,118,101,110,63,0,1,2,20,3,2049,2722,10,2816,2848,168, 12065,6953766919107,110,58,111,100,100,63,0,2049,2829,2049,2644,10,2836,2862,168,12065,193494767,105, 102,59,0,67502597,1,76,2049,2229,25,6,771,10,2853,2881,168,12065,6383175836,45,105,102, 59,0,67502597,1,74,2049,2229,2049,2644,25,6,771,10,2871,2901,174,12065,193504922,114,111, 116,0,67503109,10,2892,2910,174,12065,177620,47,0,197652,10,2903,2921,174,12065,193499461,109,111, 100,0,788,10,2912,2934,168,12065,210720211139,110,58,112,111,119,0,1,1,4,1793,2942, 67502597,19,10,1,2939,2049,2449,772,10,2923,2962,168,12065,7572652137106817,110,58,110,101,103,97, 116,101,0,1,-1,19,10,2948,2980,168,12065,7572652347517886,110,58,115,113,117,97,114,101, 0,4866,10,2966,2994,168,12065,6953767077527,110,58,115,113,114,116,0,1,1,1793,3012,2049, 2217,197652,67502597,18,1,2,197652,25,17,1,2998,7,10,1,2998,8,772,10,2982,3028, 168,12065,210720207665,110,58,109,105,110,0,2049,2217,13,1793,3035,3,10,1,3033,1793,3041, 772,10,1,3039,2049,66,10,3017,3057,168,12065,210720207411,110,58,109,97,120,0,2049,2217, 14,1793,3064,3,10,1,3062,1793,3070,772,10,1,3068,2049,66,10,3046,3086,168,12065, 210720194371,110,58,97,98,115,0,2,2049,2761,1,2962,9,10,3075,3106,168,12065,229474304963756,110, 58,108,105,109,105,116,0,4,5,2049,3028,6,2049,3057,10,3093,3125,168,12065,210720203463, 110,58,105,110,99,0,659713,1,10,3114,3139,168,12065,210720197721,110,58,100,101,99,0, 659969,1,10,3128,3158,168,12065,8246617666422322998,110,58,98,101,116,119,101,101,110,63,0,67503109, 1793,3166,67503109,67503109,2049,3106,10,1,3161,2049,2241,11,10,3142,3187,168,12065,249861296566813883,83,99, 111,112,101,76,105,115,116,0,20103,20157,10,3172,3198,168,12065,5864091,123,123,0,2049, 1576,2,1,3187,2049,61,16,10,3190,3225,168,12065,-6305314778776785742,45,45,45,114,101,118,101, 97,108,45,45,45,0,2049,1576,1,3187,2049,3125,16,10,3207,3241,168,12065,5864159,125, 125,0,1,3187,2049,58,4,15,11,1793,3255,3841,3187,4097,2,10,1,3250,1793,3281, 3841,3187,1793,3276,1,2,983567,1,3187,2049,3125,1641487,3,1,3265,7,10,1,3263,8, 16,10,1,3259,2049,66,10,3233,3296,168,0,0,66,121,116,101,0,10,3286,3312, 168,0,0,98,121,116,101,45,109,97,115,107,0,1,255,4,1,8,19,2, 1793,3326,2049,2962,24,21,10,1,3321,2049,2229,24,10,3297,3345,168,0,0,114,101, 112,108,97,99,101,0,1,0,1793,3374,1793,3369,1793,3364,1793,3359,3,3841,3296,10, 1,3355,2049,2229,10,1,3353,2049,2229,10,1,3351,2049,2229,10,1,3349,2049,2554,1, 1,1793,3400,1793,3395,1793,3390,3,3841,3296,10,1,3386,2049,2229,10,1,3384,2049,2229, 10,1,3382,2049,2554,1,2,1793,3419,1793,3414,3,3841,3296,10,1,3410,2049,2229,10, 1,3408,2049,2554,1,3,1793,3431,3,3841,3296,10,1,3427,2049,2554,3,10,3233,3460, 168,12065,-6972911891006832072,98,58,116,111,45,98,121,116,101,45,97,100,100,114,101,115,115, 0,1,4,19,10,3437,3477,168,12065,229458800096267,98,58,102,101,116,99,104,0,1,4, 20,4,1,4,20,67503109,17,15,4,2049,3312,10,3464,3504,168,12065,229458816047342,98,58,115, 116,111,114,101,0,4,4097,3296,1,4,20,4,1793,3518,2,15,2049,78,10,1, 3513,2049,2229,2049,3345,2049,92,4,16,10,3491,3542,168,12065,229466548904081,104,58,102,101,116, 99,104,0,1793,3547,2049,3477,10,1,3544,1793,3559,2049,3125,2049,3477,1,-8,24,10, 1,3551,2049,2255,22,10,3529,3578,168,12065,229466564855156,104,58,115,116,111,114,101,0,2049, 2217,1793,3586,1,255,21,10,1,3582,2049,2229,2049,3504,2049,3125,1793,3603,1,8,24, 1,255,21,10,1,3596,2049,2229,2049,3504,10,3565,3623,168,12065,229485920923616,119,58,102,101, 116,99,104,0,1,4,197652,15,10,3610,3641,168,12065,229485936874691,119,58,115,116,111,114, 101,0,1,4,197652,16,10,3628,3664,168,12065,-2542660583859062324,119,58,102,101,116,99,104,45, 110,101,120,116,0,2,1,4,17,4,2049,3623,10,3646,3690,168,12065,-3300792181564964579,104,58, 102,101,116,99,104,45,110,101,120,116,0,2,1,2,17,4,2049,3542,10,3672, 3716,168,12065,-3604044820647325481,98,58,102,101,116,99,104,45,110,101,120,116,0,2,1,1, 17,4,2049,3477,10,3698,3742,168,12065,-2542036332270164849,119,58,115,116,111,114,101,45,110,101, 120,116,0,2,1,4,17,1,3641,2049,2229,10,3724,3769,168,12065,-3300167929976067104,104,58,115, 116,111,114,101,45,110,101,120,116,0,2,1,2,17,1,3578,2049,2229,10,3751, 3796,168,12065,-3603420569058428006,98,58,115,116,111,114,101,45,110,101,120,116,0,2,1,1, 17,1,3504,2049,2229,10,3778,3819,168,12065,7572992899446007,118,58,105,110,99,45,98,121,0, 1793,3823,4367,10,1,3821,2049,2241,16,10,3805,3843,168,12065,7572992693095753,118,58,100,101,99, 45,98,121,0,1793,3847,1180687,10,1,3845,2049,2241,16,10,3829,3864,168,12065,210729690831,118, 58,105,110,99,0,1,1,4,2049,3819,10,3853,3881,168,12065,210729685089,118,58,100,101, 99,0,1,1,4,2049,3843,10,3870,3900,168,12065,229484636707508,118,58,108,105,109,105,116, 0,251790597,1542,2049,3106,4100,10,3887,3916,168,12065,6385748402,118,58,111,110,0,2049,2527,4100, 10,3906,3931,168,12065,210729697104,118,58,111,102,102,0,2049,2541,4100,10,3920,3946,168,12065, 210706586657,97,108,108,111,116,0,1,3,2049,3819,10,3935,3967,168,12065,8246989571153063777,118,58,112, 114,101,115,101,114,118,101,0,983556,1793,3975,1,27,2049,2229,10,1,3970,2049,2229, 4100,10,3951,3995,168,12065,7572993371535704,118,58,117,112,100,97,116,101,0,4,1793,4002,15, 4,8,10,1,3998,2049,2241,16,10,3981,4018,168,12065,6385123360,99,111,112,121,0,1793, 4027,285278725,1,33951492,268767489,1,6,10,1,4020,2049,2449,771,10,4008,4044,156,0,0,115, 116,97,114,116,0,0,10,4033,4055,156,0,0,101,110,100,0,0,10,4046,4072, 168,0,0,116,101,114,109,105,110,97,116,101,0,1,0,3841,4055,16,10,4008, 4096,168,12065,-3513680875729732409,98,117,102,102,101,114,58,115,116,97,114,116,0,3841,4044,10, 4078,4115,168,12065,8246143877888709904,98,117,102,102,101,114,58,101,110,100,0,3841,4055,10,4099, 4134,168,12065,8246143877888705218,98,117,102,102,101,114,58,97,100,100,0,3841,4055,16,1,4055, 2049,3864,2049,4072,10,4118,4160,168,12065,8246143877888711801,98,117,102,102,101,114,58,103,101,116, 0,1,4055,2049,3881,3841,4055,15,2049,4072,10,4144,4188,168,12065,-3513680875746570456,98,117,102,102, 101,114,58,101,109,112,116,121,0,3841,4044,4097,4055,2049,4072,10,4170,4212,168,12065, -4578413135315348908,98,117,102,102,101,114,58,115,105,122,101,0,3841,4055,3841,4044,18,10,4195, 4234,168,12065,8246143877888724869,98,117,102,102,101,114,58,115,101,116,0,4097,4044,2049,4188,10, 4218,4260,168,12065,-3186446687793719003,98,117,102,102,101,114,58,112,114,101,115,101,114,118,101, 0,3841,4044,3841,4055,1793,4273,1,27,2049,2229,4097,4044,10,1,4266,2049,2229,4097,4055, 10,4239,4297,156,12065,-4600587576916820603,84,101,109,112,83,116,114,105,110,103,115,0,32,4280, 4317,156,12065,7474516786580364824,84,101,109,112,83,116,114,105,110,103,77,97,120,0,512,4298, 4331,168,12065,229440420829967,83,84,82,73,78,71,83,0,2049,1545,3841,4297,3841,4317,19,18, 10,4318,4353,156,0,0,67,117,114,114,101,110,116,0,3,10,4340,4370,168,0, 0,115,58,112,111,105,110,116,101,114,0,3841,4353,3841,4317,19,2049,4331,17,10, 4355,4391,168,0,0,115,58,110,101,120,116,0,1,4353,2049,3864,3841,4353,3841,4297, 11,1793,4407,1,0,4097,4353,10,1,4402,9,10,4318,4423,168,12065,6953962777192,115,58,116, 101,109,112,0,2,2049,104,2049,3125,2049,4370,4,2049,4018,2049,4370,2049,4391,10,4411, 4451,168,12065,229480754149537,115,58,101,109,112,116,121,0,2049,4370,2049,4391,1,0,67502597,16, 10,4438,4472,168,12065,6953962747657,115,58,115,107,105,112,0,6,1793,4480,68223234,1,786703,0, 10,1,4475,2049,2372,2049,3139,5,10,4460,4500,168,12065,6953962453495,115,58,107,101,101,112, 0,2049,1913,1793,4509,1,4472,2049,1868,10,1,4504,9,2049,1977,1,144,2049,2229,2049, 156,10,4488,4534,180,0,229482595734750,115,105,103,105,108,58,39,0,2049,1913,1,4500,1, 4423,2049,66,10,4521,4556,168,12065,229480755051740,115,58,102,101,116,99,104,0,17,15,10, 4543,4572,168,12065,229480771002815,115,58,115,116,111,114,101,0,17,16,10,4559,4587,168,12065, 6953962169596,115,58,99,104,111,112,0,2049,4423,2,2049,104,67502597,17,2049,3139,1,0,4, 16,10,4575,4616,168,12065,249904557751418990,115,58,114,101,118,101,114,115,101,0,1793,4658,2, 2049,4423,2049,4234,1,104,1793,4634,2,2049,104,17,2049,3139,10,1,4627,2049,2255,4, 1793,4648,2,15,2049,4134,2049,3139,10,1,4641,2049,2449,3,2049,4096,2049,4423,10,1, 4618,2049,4260,10,4601,4678,168,12065,249904555657463488,115,58,112,114,101,112,101,110,100,0,2049, 4423,1793,4702,2,2049,104,17,1793,4694,2,2049,104,2049,3125,10,1,4688,2049,2229,4, 2049,4018,10,1,4682,2049,2241,10,4663,4721,168,12065,7572864733934314,115,58,97,112,112,101,110, 100,0,4,2049,4678,10,4707,4741,168,12065,8246849907066750743,115,58,102,111,114,45,101,97,99, 104,0,1793,4756,67502597,6415,3,67502597,67502597,251987205,2054,101777670,1,1,4743,7,10,1,4743,8, 771,10,4725,4779,168,12065,-2744677796467205929,115,58,105,110,100,101,120,47,99,104,97,114,0, 1793,4793,1793,4788,1,-1,1,0,10,1,4783,2049,2229,10,1,4781,2049,2229,4,1793, 4829,67502597,11,1793,4821,1793,4816,1793,4810,3,10,1,4808,2049,2229,2,10,1,4806,2049, 2229,10,1,4804,9,1,3125,2049,2229,10,1,4800,2049,4741,771,10,4761,4857,168,12065, -2157201767973730595,115,58,99,111,110,116,97,105,110,115,47,99,104,97,114,63,0,2049,4779, 1,-1,12,10,4835,4875,168,12065,6953962341782,115,58,104,97,115,104,0,1,5381,4,1793, 4883,286458116,33,10,1,4880,2049,4741,10,4863,4897,156,0,0,83,116,114,0,0,4888, 4911,168,0,0,101,120,116,114,97,99,116,0,2049,2217,3841,4897,4,2049,4018,3841, 4897,67502597,17,1,0,4,16,10,4898,4938,168,0,0,99,104,101,99,107,0,1, 4911,2049,2229,1793,4949,1,3125,2049,2229,10,1,4944,2049,2229,3841,4897,2049,4875,67502597,11, 10,4927,4974,168,0,0,108,111,99,97,116,105,111,110,0,67503109,67503109,1793,5007,1793, 5002,4,1793,4988,67502597,2049,2722,21,10,1,4983,2049,2229,4,1793,4998,772,2,10,1, 4995,9,10,1,4980,2049,2229,10,1,4978,2049,2229,10,4960,5023,168,0,0,115,101, 116,117,112,0,2049,4451,4097,4897,1,0,67503109,67503109,1,104,1,4875,2049,2255,1793,5043, 67502597,2049,104,10,1,5039,2049,2229,4,10,4863,5069,168,12065,-581580411198892688,115,58,105,110,100, 101,120,47,115,116,114,105,110,103,0,67502597,1793,5088,2049,5023,1793,5081,2049,4938,2049, 4974,10,1,5076,2049,2449,771,3,10,1,5072,2049,2229,18,1,2,18,1,-1,2049, 3057,10,5049,5110,156,0,0,83,114,99,0,0,5101,5120,156,0,0,84,97,114, 0,0,5111,5130,156,0,0,80,97,100,0,0,5121,5138,156,0,0,73,0,0, 5131,5146,156,0,0,70,0,0,5139,5155,156,0,0,65,116,0,0,5147,5171,168, 0,0,116,101,114,109,105,110,97,116,101,0,1,0,3841,5130,3841,5120,2049,104, 17,16,10,5156,5195,168,0,0,101,120,116,114,97,99,116,0,3841,5110,3841,5138, 17,3841,5130,3841,5120,2049,104,2049,4018,10,5182,5222,168,0,0,99,111,109,112,97, 114,101,0,3841,5130,3841,5120,2049,118,3841,5146,22,4097,5146,3841,5146,1793,5242,3841,5138, 4097,5155,10,1,5237,2049,74,10,5209,5257,168,0,0,110,101,120,116,0,1,5138, 2049,3864,10,5049,5286,168,12065,-6456227941126558634,115,58,99,111,110,116,97,105,110,115,47,115, 116,114,105,110,103,63,0,4097,5120,4097,5110,2049,4451,4097,5130,1,0,4097,5138,1, 0,4097,5146,3841,5110,2049,104,1793,5317,2049,5195,2049,5171,2049,5222,2049,5257,10,1,5308, 2049,2449,3841,5146,10,5262,5338,168,12065,7572864921182136,115,58,102,105,108,116,101,114,0,1793, 5366,2049,4451,2049,4234,4,1793,5358,2049,2217,4,8,1,4134,1,17,2049,66,10,1, 5347,2049,4741,3,2049,4096,10,1,5340,2049,4260,10,5324,5382,168,12065,210726137008,115,58,109, 97,112,0,1793,5404,2049,4451,2049,4234,4,1793,5396,67502597,8,2049,4134,10,1,5391,2049, 4741,3,2049,4096,10,1,5384,2049,4260,10,5371,5423,168,12065,7572865443813333,115,58,115,117,98, 115,116,114,0,1793,5429,17,2049,4451,10,1,5425,2049,2229,1793,5441,67502597,1,4018,2049, 2229,10,1,5435,2049,2241,67502597,1793,5454,17,1,0,4,16,10,1,5448,2049,2229,10, 5409,5472,168,12065,229480769412560,115,58,114,105,103,104,116,0,67502597,2049,104,67502597,18,4,2049, 5423,10,5459,5493,168,12065,6953962489469,115,58,108,101,102,116,0,1,0,4,2049,5423,10, 5481,5519,168,12065,-949014848675520942,115,58,98,101,103,105,110,115,45,119,105,116,104,63,0, 2,2049,104,1,19,2049,2229,2049,5493,2049,118,10,5499,5549,168,12065,-2744863427173801468,115,58,101, 110,100,115,45,119,105,116,104,63,0,2,2049,104,1,19,2049,2229,2049,5472,2049, 118,10,5531,5573,168,12065,6953962177261,115,58,99,111,112,121,0,67502597,2049,104,2049,3125,2049, 4018,10,5561,5595,168,12065,7572863551252214,115,58,68,73,71,73,84,83,0,2049,4472,48,49, 50,51,52,53,54,55,56,57,65,66,67,68,69,70,0,1,5597,10,5581,5640, 168,12065,-3174032931242973971,115,58,65,83,67,73,73,45,76,79,87,69,82,67,65,83,69, 0,2049,4472,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113, 114,115,116,117,118,119,120,121,122,0,1,5642,10,5617,5695,168,12065,-3174020239987242608,115,58, 65,83,67,73,73,45,85,80,80,69,82,67,65,83,69,0,2049,4472,65,66, 67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86, 87,88,89,90,0,1,5697,10,5672,5748,168,12065,4909441458232360267,115,58,65,83,67,73,73, 45,76,69,84,84,69,82,83,0,2049,4472,97,98,99,100,101,102,103,104,105, 106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,65,66,67, 68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87, 88,89,90,0,1,5750,10,5727,5825,168,12065,1619870888324870636,115,58,80,85,78,67,84,85, 65,84,73,79,78,0,2049,4472,95,33,34,35,36,37,38,39,40,41,42,43, 44,45,46,47,58,59,60,61,62,63,64,91,92,93,94,96,123,124,125,126, 0,1,5827,1,95,67502597,16,10,5806,5885,156,12065,-2745567821320788289,115,58,87,72,73,84,69, 83,80,65,67,69,0,32,9,10,13,0,5867,5897,180,12065,177612,39,0,1,4451, 2049,168,10,5890,5909,180,12065,177609,36,0,1,0,2049,156,10,5902,0,156,12065,249835240931843863, 65,83,67,73,73,58,78,85,76,0,5914,27,156,12065,249835240931833987,65,83,67,73,73, 58,69,83,67,0,5929,8,156,12065,7570764876722141,65,83,67,73,73,58,66,83,0,5944, 9,156,12065,7570764876722340,65,83,67,73,73,58,72,84,0,5958,10,156,12065,7570764876722458,65,83, 67,73,73,58,76,70,0,5972,11,156,12065,7570764876722802,65,83,67,73,73,58,86,84, 0,5986,12,156,12065,7570764876722260,65,83,67,73,73,58,70,70,0,6000,13,156,12065,7570764876722173, 65,83,67,73,73,58,67,82,0,6014,32,156,12065,-4630583730859567212,65,83,67,73,73,58, 83,80,65,67,69,0,6028,127,156,12065,249835240931832445,65,83,67,73,73,58,68,69,76, 0,6045,1,156,12065,249835240931849106,65,83,67,73,73,58,83,79,72,0,6060,2,156,12065, 249835240931849287,65,83,67,73,73,58,83,84,88,0,6075,3,156,12065,249835240931834041,65,83,67,73, 73,58,69,84,88,0,6090,4,156,12065,249835240931833872,65,83,67,73,73,58,69,79,84, 0,6105,5,156,12065,249835240931833836,65,83,67,73,73,58,69,78,81,0,6120,6,156,12065, 249835240931829111,65,83,67,73,73,58,65,67,75,0,6135,7,156,12065,249835240931830267,65,83,67,73, 73,58,66,69,76,0,6150,14,156,12065,7570764876722698,65,83,67,73,73,58,83,79,0, 6165,15,156,12065,7570764876722692,65,83,67,73,73,58,83,73,0,6179,16,156,12065,249835240931832669,65, 83,67,73,73,58,68,76,69,0,6193,17,156,12065,249835240931832352,65,83,67,73,73,58, 68,67,49,0,6208,18,156,12065,249835240931832353,65,83,67,73,73,58,68,67,50,0,6223, 19,156,12065,249835240931832354,65,83,67,73,73,58,68,67,51,0,6238,20,156,12065,249835240931832355,65, 83,67,73,73,58,68,67,52,0,6253,21,156,12065,249835240931843202,65,83,67,73,73,58, 78,65,75,0,6268,22,156,12065,249835240931849442,65,83,67,73,73,58,83,89,78,0,6283, 23,156,12065,249835240931834019,65,83,67,73,73,58,69,84,66,0,6298,24,156,12065,249835240931831226,65, 83,67,73,73,58,67,65,78,0,6313,25,156,12065,7570764876722234,65,83,67,73,73,58, 69,77,0,6328,26,156,12065,249835240931849298,65,83,67,73,73,58,83,85,66,0,6342,28, 156,12065,7570764876722273,65,83,67,73,73,58,70,83,0,6357,29,156,12065,7570764876722306,65,83,67, 73,73,58,71,83,0,6371,30,156,12065,7570764876722669,65,83,67,73,73,58,82,83,0, 6385,31,156,12065,7570764876722768,65,83,67,73,73,58,85,83,0,6399,6431,168,12065,-3553210050247798618,99, 58,108,111,119,101,114,99,97,115,101,63,0,1,97,1,122,2049,3158,10,6413, 6456,168,12065,-3552791238808663639,99,58,117,112,112,101,114,99,97,115,101,63,0,1,65,1, 90,2049,3158,10,6438,6478,168,12065,249882047462872305,99,58,108,101,116,116,101,114,63,0,1, 6431,1,6456,2049,2255,22,10,6463,6500,168,12065,7572182947632498,99,58,100,105,103,105,116,63, 0,1,48,1,57,2049,3158,10,6486,6523,168,12065,8246107997572794159,99,58,118,105,115,105,98, 108,101,63,0,1,32,1,126,2049,3158,10,6507,6544,168,12065,7572183659755470,99,58,118,111, 119,101,108,63,0,2049,4472,97,101,105,111,117,65,69,73,79,85,0,1,6546, 4,2049,4857,10,6530,6581,168,12065,-3553628119197217420,99,58,99,111,110,115,111,110,97,110,116, 63,0,2,2049,6478,1793,6591,2049,6544,2049,2644,10,1,6586,1793,6599,3,2049,2541,10, 1,6595,2049,66,10,6563,6623,168,12065,-6558963794062736370,99,58,119,104,105,116,101,115,112,97, 99,101,63,0,1,5885,4,2049,4857,10,6604,6648,168,12065,-6672106426782194349,99,58,45,108,111, 119,101,114,99,97,115,101,63,0,2049,6431,2049,2644,10,6629,6672,168,12065,-6671687615343059370,99, 58,45,117,112,112,101,114,99,97,115,101,63,0,2049,6456,2049,2644,10,6653,6692, 168,12065,249881966047746975,99,58,45,100,105,103,105,116,63,0,2049,6500,2049,2644,10,6677,6717, 168,12065,1197920222559514203,99,58,45,119,104,105,116,101,115,112,97,99,101,63,0,2049,6623, 2049,2644,10,6697,6739,168,12065,-4579699312045814628,99,58,45,118,105,115,105,98,108,101,63,0, 2049,6523,2049,2644,10,6722,6759,168,12065,249881966759869947,99,58,45,118,111,119,101,108,63,0, 2049,6544,2049,2644,10,6744,6783,168,12065,-6672524495731613151,99,58,45,99,111,110,115,111,110,97, 110,116,63,0,2049,6581,2049,2644,10,6764,6804,168,12065,8246107917359977086,99,58,116,111,45,117, 112,112,101,114,0,2,2049,6431,25,3,1,32,18,10,6788,6829,168,12065,8246107917349275483,99, 58,116,111,45,108,111,119,101,114,0,2,2049,6456,25,3,1,32,17,10,6813, 6855,168,12065,-4579599832837481303,99,58,116,111,45,115,116,114,105,110,103,0,2049,4472,46,0, 1,6857,2049,4423,1,39,2049,2241,10,6838,6887,168,12065,-6563237009071717459,99,58,116,111,103,103, 108,101,45,99,97,115,101,0,2,2049,6431,1,6804,1,6829,2049,66,10,6868,6914, 168,12065,-4579599833032159941,99,58,116,111,45,110,117,109,98,101,114,0,2,2049,6500,1793,6923, 1,48,18,10,1,6919,1793,6931,3,1,0,10,1,6927,2049,66,10,6897,6952,168, 12065,8246850501110408334,115,58,116,111,45,117,112,112,101,114,0,1,6804,2049,5382,10,6936,6973, 168,12065,8246850501099706731,115,58,116,111,45,108,111,119,101,114,0,1,6829,2049,5382,10,6957, 6995,168,12065,-4555094364049076026,115,58,116,114,105,109,45,108,101,102,116,0,2049,4423,1793,7009, 2049,58,1,6623,1,2740,2049,2255,21,10,1,6999,2049,2372,2049,3139,10,6978,7034,168, 12065,-2744161423935835847,115,58,116,114,105,109,45,114,105,103,104,116,0,2049,4423,2049,4616,2049, 6995,2049,4616,10,7016,7055,168,12065,6953962791214,115,58,116,114,105,109,0,2049,7034,2049,6995, 10,7043,7084,156,12065,-429402327855008236,82,101,119,114,105,116,101,85,110,100,101,114,115,99, 111,114,101,115,0,-1,7060,7094,168,0,0,115,117,98,0,1,95,1793,7101,1, 32,10,1,7098,2049,2554,10,7085,7119,168,0,0,114,101,119,114,105,116,101,0, 3841,7084,1793,7128,1,7094,2049,5382,10,1,7123,9,10,7106,7144,168,0,0,104,97, 110,100,108,101,0,1,4534,8,10,7060,7161,180,12065,229482595734750,115,105,103,105,108,58, 39,0,2049,7119,2049,7144,10,7148,7184,168,12065,-2744210522849075797,115,58,115,112,108,105,116,47, 99,104,97,114,0,2049,2217,2049,4779,772,2049,2217,2049,5493,1,41,2049,2229,10,7166, 7218,168,12065,-72719441055178940,115,58,115,112,108,105,116,47,115,116,114,105,110,103,0,2049, 2217,2049,5069,2049,3125,772,2049,2217,2049,5493,1,41,2049,2229,10,7198,7249,168,12065,249904557744535982, 115,58,114,101,112,108,97,99,101,0,67502597,2049,104,2049,1977,16,1793,7265,2049,7218, 4,2049,1977,15,17,10,1,7257,2049,2229,2049,4678,2049,4721,10,7234,7288,156,0,0, 83,112,108,105,116,45,79,110,0,0,7274,7301,168,0,0,109,97,116,99,104, 63,0,3841,7288,11,10,7289,7320,168,0,0,116,101,114,109,105,110,97,116,101, 0,1,0,67502597,2049,3139,16,10,7305,7337,168,0,0,115,116,101,112,0,1,3125, 2049,2229,2049,7301,1793,7351,2,2049,130,2049,7320,10,1,7345,9,10,7234,7371,168,12065, 8246850503517749147,115,58,116,111,107,101,110,105,122,101,0,4097,7288,2049,4500,2049,1977,1,0, 2049,130,1793,7393,2,2049,130,2,1,7337,2049,4741,3,10,1,7383,2049,2229,2049,1977, 67502597,18,2049,3139,67502597,16,10,7355,7418,156,0,0,78,101,101,100,108,101,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,7406,7555,156,0,0,76,101,110,0,0,7546,7568,156, 0,0,84,111,107,101,110,115,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7556,7704,156, 0,0,84,80,0,0,7696,7715,168,0,0,115,97,118,101,0,2049,4500,3841,7704, 1,7568,17,2049,3125,16,1,7704,2049,3864,10,7705,7740,168,0,0,110,101,120,116, 0,1793,7746,3841,7555,17,10,1,7742,2049,2241,10,7730,7762,168,0,0,100,111,110, 101,63,0,2049,104,2049,2722,10,7355,7793,168,12065,9213749861880762729,115,58,116,111,107,101,110, 105,122,101,45,111,110,45,115,116,114,105,110,103,0,1,0,4097,7704,1793,7807, 2,1,7418,2049,5573,2049,4721,10,1,7799,1793,7816,2049,104,4097,7555,10,1,7811,2049, 2255,1793,7833,1,7418,2049,7218,2049,7715,2049,7740,2049,7762,10,1,7822,2049,2397,1,7568, 3841,7704,2049,3139,4097,7568,772,10,7767,7859,156,0,0,83,116,114,105,110,103,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,7847,7941,168,0,0,99,104,101,99,107,45,115,105,103, 110,0,2049,2761,1793,7950,1,45,2049,4134,10,1,7945,9,10,7925,7968,168,0,0, 110,45,62,100,105,103,105,116,0,2049,5595,17,15,10,7954,7986,168,0,0,99, 111,110,118,101,114,116,0,1793,8000,3841,243,20,4,2049,7968,2049,4134,2,2049,2722, 10,1,7988,2049,2397,3,10,7767,8023,168,12065,-4562752463999572364,110,58,116,111,45,115,116,114, 105,110,103,0,1793,8037,1,7859,2049,4234,2,2049,3086,2049,7986,2049,7941,10,1,8025, 2049,4260,1,7859,2049,4616,10,8006,8056,168,0,0,99,104,97,114,0,1,32,1793, 8065,1,95,2049,4134,10,1,8060,2049,2554,1,114,1793,8078,1,13,2049,4134,10,1, 8073,2049,2554,1,110,1793,8091,1,10,2049,4134,10,1,8086,2049,2554,1,116,1793,8104, 1,9,2049,4134,10,1,8099,2049,2554,1,48,1793,8117,1,0,2049,4134,10,1,8112, 2049,2554,1,94,1793,8130,1,27,2049,4134,10,1,8125,2049,2554,2049,4134,10,8046,8147, 168,0,0,116,121,112,101,0,1,99,1793,8155,4,2049,4134,10,1,8151,2049,2554, 1,115,1793,8169,4,1,4134,2049,4741,10,1,8163,2049,2554,1,110,1793,8185,4,2049, 8023,1,4134,2049,4741,10,1,8177,2049,2554,3,10,8137,8203,168,0,0,104,97,110, 100,108,101,0,1,92,1793,8212,2049,58,2049,8056,10,1,8207,2049,2554,1,37,1793, 8225,2049,58,2049,8147,10,1,8220,2049,2554,2049,4134,10,8006,8246,168,12065,7572864928505531,115,58, 102,111,114,109,97,116,0,1793,8275,2049,4451,1793,8270,2049,4234,1793,8265,2049,58,25, 2049,8203,1,8256,7,10,1,8256,8,3,10,1,8252,2049,2241,10,1,8248,2049,4260, 10,8232,8293,168,12065,229480751847353,115,58,99,111,110,115,116,0,1,4500,2049,2229,2049,2131, 10,8280,8312,156,0,0,86,97,108,117,101,115,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,8300,8350,168,0,0,102,114,111,109,0,2049,104,2,1793,8368,1793,8361,1,8312, 4113,10,1,8357,2049,2241,2049,3139,10,1,8355,2049,2449,3,10,8340,8382,168,0,0, 116,111,0,2,2049,104,1793,8398,2049,58,1,97,18,2049,3125,1,8312,266001,10,1, 8387,2049,2449,3,10,8280,8417,168,12065,229481157528792,114,101,111,114,100,101,114,0,1,8350, 2049,2229,2049,8382,10,8404,8435,168,12065,210709288570,99,117,114,114,121,0,2049,1977,1793,8445, 4,2049,1818,2049,1843,10,1,8439,2049,2229,10,8424,8460,168,12065,6385158928,100,111,101,115, 0,2049,1595,4,2049,8435,2049,1576,2049,182,16,1,168,2049,1660,10,8450,8491,168,12065, 8246153734800721448,100,58,102,111,114,45,101,97,99,104,0,1,2,1793,8517,6415,2049,2217,1793, 8509,1793,8504,2052,10,1,8502,2049,2229,10,1,8500,2049,2229,1,8495,7,10,1,8495, 8,3,10,8475,8539,168,12065,-4578079420196310922,100,58,108,111,111,107,117,112,45,120,116,0, 1,0,4,1793,8564,2049,2217,2049,182,2831,1793,8557,4,1,2172,2049,2229,10,1,8551, 1,17,2049,66,10,1,8544,2049,8491,3,10,8522,8578,168,0,5863407,103,99,0,1, 3,4,2049,3967,10,8570,8598,168,12065,7572098019335426,97,58,108,101,110,103,116,104,0,15, 10,8584,8614,168,12065,7572098062851599,97,58,109,105,100,100,108,101,0,2049,1977,1793,8637,2, 2049,130,1793,8627,2049,3125,17,10,1,8623,2049,2229,2049,1977,4,2049,4018,10,1,8618, 2049,2229,10,8600,8654,168,12065,6953258052395,97,58,108,101,102,116,0,1,0,4,2049,8614, 10,8642,8673,168,12065,229457522989118,97,58,114,105,103,104,116,0,67502597,2049,8598,67502597,18,4, 2049,8614,10,8660,8705,168,12065,9069136730318539537,97,58,99,111,117,110,116,101,100,45,114,101, 115,117,108,116,115,0,8,2049,1977,1793,8718,2,2049,130,1,130,2049,2449,10,1, 8710,2049,2229,10,8682,8742,168,12065,8526436589641133048,97,58,102,114,111,109,45,115,116,114,105, 110,103,0,2049,1977,1793,8756,2,2049,104,2049,130,1,130,2049,4741,10,1,8746,2049, 2229,10,8723,8777,168,12065,8246014500347515589,97,58,102,111,114,45,101,97,99,104,0,4,2049, 58,1,19,2049,2229,1793,8793,5,2049,58,84018692,525572,1542,10,1,8786,2049,2449,771,10, 8761,8810,168,12065,210704781289,97,58,100,117,112,0,2049,1977,1793,8823,2,15,2049,130,1, 130,2049,8777,10,1,8814,2049,2229,10,8799,8840,168,12065,6953257740187,97,58,99,111,112,121, 0,1,3,1793,8856,4097,3,2,2049,8598,2049,130,1,130,2049,8777,10,1,8844,2049, 3967,10,8828,8878,168,12065,-4582662990808010201,97,58,116,111,45,115,116,114,105,110,103,0,1, 3,1793,8891,2049,8810,1,0,2049,130,2049,3125,10,1,8882,2049,3967,2049,4423,10,8861, 8912,168,12065,7572097601960728,97,58,97,112,112,101,110,100,0,2049,2217,1,37,2049,2285,17, 2049,1977,1793,8937,2049,130,1793,8932,1,130,2049,8777,10,1,8927,2049,2285,10,1,8923, 2049,2229,10,8898,8957,168,12065,249879240302335150,97,58,112,114,101,112,101,110,100,0,4,2049, 8912,10,8942,8973,168,12065,6953257732522,97,58,99,104,111,112,0,2049,8810,1,-1,2049,3946, 2,2049,3881,10,8961,8997,168,12065,7572097789208550,97,58,102,105,108,116,101,114,0,1793,9012, 67502597,1,27,2049,2229,4,1,130,1,17,2049,66,10,1,8999,2049,8435,2049,1977,1793, 9027,67502597,15,2049,130,2049,8777,10,1,9020,2049,2229,2049,1977,67502597,18,2049,3139,67502597,16, 10,8983,9057,168,12065,-4582686815792817282,97,58,99,111,110,116,97,105,110,115,63,0,1,0, 4,1793,9069,4,5,67502597,11,6,22,10,1,9062,2049,8777,772,10,9040,9099,168,12065, -3160266450763725308,97,58,99,111,110,116,97,105,110,115,47,115,116,114,105,110,103,63,0, 1,0,4,1793,9112,4,5,67502597,2049,118,6,22,10,1,9104,2049,8777,772,10,9075, 9129,168,12065,210704790430,97,58,109,97,112,0,4,1793,9159,2049,58,1793,9153,1793,9142,15, 67502597,8,10,1,9138,2049,2241,1,39,2049,2241,2049,3125,10,1,9136,2049,2449,771,10, 1,9132,2049,2241,10,9118,9179,168,12065,249879242396290652,97,58,114,101,118,101,114,115,101,0, 2049,1977,1793,9213,2049,58,1793,9191,17,2049,3139,10,1,9187,2049,2241,2,2049,130,1793, 9207,2,15,2049,130,2049,3139,10,1,9200,2049,2449,3,10,1,9183,2049,2229,10,9164, 9228,168,12065,6384993884,97,58,116,104,0,17,2049,3125,10,9218,9245,168,12065,229457508628298,97,58, 102,101,116,99,104,0,2049,9228,15,10,9232,9262,168,12065,229457524579373,97,58,115,116,111, 114,101,0,2049,9228,16,10,9249,9279,168,0,229457508770408,97,58,102,105,114,115,116,0, 1,0,2049,9245,10,9266,9296,168,0,6953258048468,97,58,108,97,115,116,0,2,2049,8598, 2049,3139,2049,9245,10,9284,9318,168,12065,7572098253803096,97,58,114,101,100,117,99,101,0,1, 19,2049,2229,2049,8777,10,9304,9335,168,12065,6384048135,70,82,69,69,0,2049,4331,1,1025, 18,1,513,1,12,19,18,2049,1977,18,10,9325,9365,156,0,0,78,101,120,116, 65,114,114,97,121,0,3,9350,9378,168,0,0,97,114,114,97,121,115,0,2049, 4331,1,1025,18,1,513,1,12,19,18,10,9325,9402,168,12065,6953258340118,97,58,116,101, 109,112,0,3841,9365,2,1,12,11,1793,9417,3,1,0,2,4097,9365,10,1,9410, 9,1,513,19,2049,9378,17,67502597,2049,8598,2049,3125,2049,4018,3841,9365,1,513,19,2049, 9378,17,1,9365,2049,3864,10,9390,9457,156,0,0,67,111,117,110,116,0,1,9446, 9471,168,0,0,112,114,101,112,97,114,101,0,1,0,1,9457,16,10,9458,9490, 168,0,0,114,101,115,101,114,118,101,0,4,1,0,2049,130,10,9477,9507,168, 0,0,112,97,116,99,104,0,2049,1977,67502597,18,2049,3139,67502597,16,10,9496,9529,168, 0,0,99,108,101,97,110,117,112,0,2,2049,9402,4,1,3,16,10,9516,9549, 168,0,0,114,101,99,111,114,100,0,3841,9457,2049,130,10,9537,9566,168,0,0, 109,97,116,99,104,63,0,67502597,11,10,9554,9584,168,0,0,105,116,101,114,97, 116,101,47,110,0,1793,9596,2049,9566,1,9549,9,1,9457,2049,3864,10,1,9586,2049, 8777,10,9569,9613,168,0,0,109,97,116,99,104,63,0,67502597,2049,118,10,9601,9632, 168,0,0,105,116,101,114,97,116,101,47,115,0,1793,9644,2049,9613,1,9549,9, 1,9457,2049,3864,10,1,9634,2049,8777,10,9390,9664,168,12065,249879231104077855,97,58,105,110,100, 105,99,101,115,0,2049,9471,2049,1977,1793,9676,2049,9490,2049,9584,3,10,1,9670,2049, 2229,2049,9507,2049,9529,10,9649,9707,168,0,6001861788990794213,97,58,105,110,100,105,99,101,115, 47,115,116,114,105,110,103,0,2049,9471,2049,1977,1793,9719,2049,9490,2049,9632,3,10, 1,9713,2049,2229,2049,9507,2049,9529,10,9685,9741,168,12065,229457512492152,97,58,105,110,100,101, 120,0,1793,9750,2049,9664,1,0,2049,9245,10,1,9743,2049,8578,10,9728,9775,168,12065, 4816227687043827742,97,58,105,110,100,101,120,47,115,116,114,105,110,103,0,1793,9784,2049,9707, 1,0,2049,9245,10,1,9777,2049,8578,10,9755,9801,168,12065,6953258084126,97,58,109,97,107, 101,0,2049,8705,2,2,1,3,1793,9812,2049,9179,10,1,9809,2049,3967,4,2049,8840, 10,9789,9827,180,12065,177696,123,0,1,339,2049,180,1,1560,2049,168,1,339,2049,180, 10,9820,9847,180,12065,177698,125,0,1,355,2049,180,1,2229,2049,168,1,1560,2049,168, 1,19,2049,174,1,43,2049,174,1,3139,2049,168,1,355,2049,180,1,9801,2049,168, 10,9840,9892,168,0,6953257904708,97,58,104,97,115,104,0,1,5381,4,1793,9903,4,1, 33,19,17,10,1,9897,2049,8777,10,9880,9919,168,12065,210704782197,97,58,101,113,63,0, 2049,9892,4,2049,9892,11,10,9908,9938,168,12065,6953255788674,97,58,45,101,113,63,0,2049, 9892,4,2049,9892,12,10,9926,9965,168,12065,4448793249567199488,97,58,98,101,103,105,110,115,45, 119,105,116,104,63,0,1,3,1793,9981,2,2049,8598,1,19,2049,2229,2049,8654,2049, 9919,10,1,9969,2049,3967,10,9945,10004,168,12065,-3654621344420884174,97,58,101,110,100,115,45,119, 105,116,104,63,0,1,3,1793,10020,2,2049,8598,1,19,2049,2229,2049,8673,2049,9919, 10,1,10008,2049,3967,10,9986,10041,156,0,0,83,117,98,115,116,105,116,117,116, 101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,10025,10182,168,0,0,101,120,116,114,97, 99,116,0,1,10041,2049,5573,10,10169,10200,168,0,0,99,111,109,98,105,110,101, 0,1,10041,2049,4721,2049,4721,10,10187,10221,168,0,0,102,105,110,100,45,101,110, 100,0,2,2049,104,1,10041,2049,104,18,67502597,17,10,10207,10243,168,0,0,99,108, 101,97,110,0,2049,10221,1,0,4,16,10,9986,10269,168,12065,1672736740201773236,115,58,114,101, 112,108,97,99,101,45,97,108,108,0,1,3,1793,10292,2049,10182,2049,7793,2049,4451, 4,1793,10285,2049,10200,10,1,10282,2049,8777,2049,10243,10,1,10273,2049,3967,10,10250,10315, 168,0,0,99,117,114,114,101,110,116,45,108,105,110,101,0,2049,4331,1,1025, 18,10,10297,10339,168,0,0,99,111,117,110,116,45,116,111,107,101,110,115,0, 1793,10345,1,32,11,10,1,10341,2049,5338,2049,104,10,10321,10372,168,0,0,112,114, 111,99,101,115,115,45,116,111,107,101,110,115,0,1793,10400,1,32,2049,7184,4, 1793,10393,2,2049,104,2049,2740,1,417,1,17,2049,66,10,1,10381,2049,2229,2049,3125, 10,1,10374,2049,2449,2049,417,10,10250,10423,168,12065,8246849872898570441,115,58,101,118,97,108,117, 97,116,101,0,2049,10315,2049,5573,2049,10315,2,2049,10339,2049,10372,10,10407,10443,156,0, 0,76,80,0,0,10435,10455,156,0,0,73,110,100,101,120,0,0,14,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,10444,10497,168,0,0,110,101,120,116,0,3841,10443, 1,10455,17,2049,3864,10,10487,10515,168,0,0,112,114,101,112,0,1,10443,2049,3864, 1,0,3841,10443,1,10455,17,16,10,10505,10538,168,0,0,100,111,110,101,0,1, 10443,2049,3881,10,10407,10550,168,12065,177646,73,0,3841,10443,1,10455,17,15,10,10543,10564, 168,12065,177647,74,0,3841,10443,1,10455,17,2049,3139,15,10,10557,10580,168,12065,177648,75, 0,3841,10443,1,10455,17,1,2,18,15,10,10573,10609,168,12065,6047344052022463093,105,110,100,101, 120,101,100,45,116,105,109,101,115,0,2049,10515,4,1793,10625,25,33886721,1,2053,1542, 2049,10497,1,10614,7,10,1,10614,8,3,2049,10538,10,10590,10645,168,12065,229463062432404,100,101, 99,105,109,97,108,0,1,10,4097,243,10,10632,10662,168,12065,6953352993994,98,105,110,97, 114,121,0,1,2,4097,243,10,10650,10678,168,12065,210722874360,111,99,116,97,108,0,1, 8,4097,243,10,10667,10692,168,12065,193493706,104,101,120,0,1,16,4097,243,10,10683,10708, 168,0,210731100046,118,97,114,45,115,0,1,4500,2049,2229,2049,2102,10,10697,10733,168,12065, -2634409250251928459,116,97,105,108,45,114,101,99,117,114,115,101,0,1,1793,2049,1977,1,3, 18,16,10,10715,10752,168,12065,6385224492,102,105,108,108,0,1793,10760,2049,2217,16,2049,3125, 10,1,10754,2049,2449,771,10,10742,10784,168,12065,-3171118726347914531,105,111,58,101,110,117,109,101, 114,97,116,101,0,27,10,10766,10800,168,12065,7572505472392333,105,111,58,113,117,101,114,121, 0,28,10,10786,10817,168,12065,249892680268169699,105,111,58,105,110,118,111,107,101,0,29,10, 10802,10836,168,12065,-4568031882453442320,105,111,58,115,99,97,110,45,102,111,114,0,1,-1,4, 2049,10784,1793,10867,2049,10550,2049,10800,772,67502597,11,1793,10863,1793,10858,3,2049,10550,10,1, 10854,2049,2229,10,1,10852,9,10,1,10843,2049,10609,3,10,10819,10884,168,12065,210707166203,99, 58,112,117,116,0,1793,10886,1,0,2049,10817,10,10873,10899,168,12065,5863647,110,108,0, 1,10,2049,10884,10,10891,10912,168,12065,5863816,115,112,0,1,32,2049,10884,10,10904,10926, 168,12065,193506620,116,97,98,0,1,9,2049,10884,10,10917,10942,168,12065,210726140939,115,58,112, 117,116,0,1,10884,2049,4741,10,10931,10958,168,12065,210720211334,110,58,112,117,116,0,2049, 8023,2049,10942,10,10947,10974,168,12065,210726503048,114,101,115,101,116,0,2049,1560,25,771,1, 10974,7,10,10963,10998,168,12065,8246237009912977886,100,117,109,112,45,115,116,97,99,107,0,2049, 1560,25,134284547,10998,134283782,10958,2049,10912,10,10982,11018,168,0,0,101,111,108,63,0,1793, 11024,1,13,11,10,1,11020,1793,11032,1,10,11,10,1,11028,1793,11040,1,32,11, 10,1,11036,2049,2298,22,22,10,11008,11059,168,0,0,118,97,108,105,100,63,0, 2,2049,104,2049,2740,10,11047,11074,168,0,0,98,115,63,0,2,1793,11081,1,8, 11,10,1,11077,1793,11089,1,127,11,10,1,11085,2049,2255,22,10,11065,11109,168,0, 0,99,104,101,99,107,45,98,115,0,2049,11074,1793,11132,2049,4212,1,2,2049,2675, 1793,11125,2049,4160,3,10,1,11121,9,2049,4160,3,10,1,11113,9,10,10982,11147,168, 12065,210707155874,99,58,103,101,116,0,1793,11149,1,1,2049,10836,2049,10817,10,11136,11172,168, 12065,8246849936849447419,115,58,103,101,116,45,119,111,114,100,0,1793,11200,1,7,15,2049,4234, 1793,11191,2049,11147,2,2049,4134,2049,11109,2049,11018,10,1,11181,2049,2397,2049,4096,2049,4587, 10,1,11174,2049,4260,10,11156,11214,168,12065,193487813,98,121,101,0,26,10,11205,11228,168, 12065,6953744547860,108,105,115,116,101,110,0,2049,11172,2049,11059,1,417,1,17,2049,66,1, 11228,7,10,11216,11263,156,12065,-213800119713087686,100,58,72,97,115,104,45,70,117,110,99,116, 105,111,110,0,4875,11242,11278,168,12065,7572226109254526,100,58,114,101,104,97,115,104,0,1793, 11296,1793,11288,2049,190,3841,11263,8,10,1,11282,2049,2241,2049,188,16,10,1,11280,2049, 8491,10,11264,18,156,0,210668957237,66,85,73,76,68,0,11301,11323,168,0,210709067314,99,111, 109,109,97,0,2049,130,10,11312,11336,168,0,6385123288,99,111,110,115,0,2049,1977,1793, 11346,4,2049,11323,2049,11323,10,1,11340,2049,2229,10,11326,11360,168,0,193488123,99,97,114, 0,10,11351,11370,168,0,193488222,99,100,114,0,2049,3125,10,11361,11383,168,0,6385108123,99, 97,114,64,0,2049,11360,15,10,11373,11397,168,0,6385108092,99,97,114,33,0,2049,11360, 16,10,11387,11411,168,0,6385111390,99,100,114,64,0,2049,11370,15,10,11401,11425,168,0, 6385111359,99,100,114,33,0,2049,11370,16,10,11415,11438,168,0,193454780,69,78,68,0,10, 11429,11455,168,0,8246317064958091121,102,108,108,58,99,114,101,97,116,101,0,1,11438,2049,11336, 10,11439,11467,156,0,177687,114,0,17973,11439,11484,168,0,8246317065617826724,102,108,108,58,116,111, 45,101,110,100,0,2,4097,11467,1793,11513,2049,11411,2,1,11438,12,2,1793,11502,67502597, 4097,11467,10,1,11498,1793,11508,772,10,1,11506,2049,66,10,1,11489,2049,2372,3841,11467, 10,11468,11542,168,0,4204933718218055169,102,108,108,58,97,112,112,101,110,100,47,118,97,108, 117,101,0,1,11438,2049,11336,4,2049,11484,2049,11425,10,11520,11570,168,0,-3325079438733587419,102,108, 108,58,116,111,45,105,110,100,101,120,0,1793,11575,2049,11411,10,1,11572,2049,2449, 10,11552,11593,168,0,229465928290674,102,108,108,58,100,101,108,0,2049,2217,2049,3139,2049,11570, 1793,11606,2049,3125,2049,11570,10,1,11601,2049,2229,2049,11425,10,11580,11625,156,0,6952054634723,65, 99,116,105,111,110,0,11913,11580,11644,168,0,-3325080032762929022,102,108,108,58,102,111,114,45, 101,97,99,104,0,4097,11625,1793,11667,1793,11656,2049,11383,3841,11625,8,10,1,11650,2049, 2241,2049,11411,2,1,11438,12,10,1,11648,2049,2372,3,10,11626,11689,168,0,8246317065295222655,102, 108,108,58,108,101,110,103,116,104,0,1,0,4,1793,11698,3,2049,3125,10,1, 11694,2049,11644,2049,3139,10,11673,11719,168,0,7572375633606610,102,108,108,58,100,114,111,112,0, 2,2049,11689,2049,3139,2049,11570,1,11438,4,2049,11425,10,11705,11739,156,0,177678,105,0, 0,11705,11756,168,0,8246317065188343290,102,108,108,58,105,110,106,101,99,116,0,2049,11455,4097, 11739,2049,2217,2049,3139,2049,11570,1,11570,2049,2229,3841,11739,4,2049,11425,3841,11739,2049,11425, 10,11740,11793,168,0,229465928304278,102,108,108,58,112,117,116,0,1793,11800,2049,10958,2049,10912, 10,1,11795,2049,11644,10,105,110,105,116,0,11805,12077,11780,11830,156,0,-2744922491217532500,115,58, 100,101,100,117,112,46,100,97,116,97,0,11810,11812,11839,156,0,5863786,116,49,0, 512000,11831,11848,156,0,5863787,116,50,0,0,11812,11871,168,0,-1192507208876296873,115,58,100,101,100, 117,112,46,114,101,103,105,115,116,101,114,0,2049,4500,3841,11830,4,1,11542,2049, 2241,10,11849,11903,168,0,-1192507805573830048,115,58,100,101,100,117,112,46,100,101,102,105,110, 101,100,63,0,4097,11839,1,0,4097,11848,3841,11830,1793,11923,3841,11839,2049,118,3841,11848, 22,4097,11848,10,1,11913,2049,11644,3841,11848,10,11881,11948,168,0,-2744922491217452109,115,58,100,101, 100,117,112,46,102,105,110,100,0,4097,11839,1,0,4097,11848,3841,11830,1793,11979,2, 3841,11839,2049,118,1793,11968,4097,11848,10,1,11965,1793,11974,3,10,1,11972,2049,66,10, 1,11958,2049,11644,3841,11848,10,11930,11999,168,0,229480752663076,115,58,100,101,100,117,112,0, 2,2049,11903,1793,12007,2049,11948,10,1,12004,1793,12014,2049,11871,10,1,12011,2049,66,10, 11986,12034,168,0,249904561963058472,115,58,117,110,105,113,117,101,63,0,2049,11903,10,12019,12055, 168,0,-3502357327552891667,100,58,115,101,116,45,115,111,117,114,99,101,0,1,11999,2049,2229, 2049,236,2049,186,16,10,114,101,116,114,111,46,102,111,114,116,104,0,12065,14229, 12037,12100,168,14266,-6845980351726443322,102,108,111,97,116,58,111,112,101,114,97,116,105,111,110, 0,1,2,2049,10836,2,2049,2761,1793,12150,3,2049,4472,69,114,114,111,114,58,32, 100,101,118,105,99,101,32,40,48,48,48,50,41,32,110,111,116,32,102,111, 117,110,100,0,1,12112,2049,10942,2049,10899,10,1,12109,2049,2862,2049,10817,10,12079,12173, 168,14266,8246618443670464787,110,58,116,111,45,102,108,111,97,116,0,1,0,2049,12100,10,12157, 12194,168,14266,8246850501092474552,115,58,116,111,45,102,108,111,97,116,0,1,1,2049,12100,10, 12178,12216,168,14266,-4575005096076366594,102,58,116,111,45,110,117,109,98,101,114,0,1,2,2049, 12100,10,12199,12238,168,14266,-4575005095881687956,102,58,116,111,45,115,116,114,105,110,103,0,2049, 4451,2,1,3,2049,12100,10,12221,12255,168,14258,193490032,102,58,43,0,1,4,2049,12100, 10,12246,12269,168,14258,193490034,102,58,45,0,1,5,2049,12100,10,12260,12283,168,14258,193490031, 102,58,42,0,1,6,2049,12100,10,12274,12297,168,14258,193490036,102,58,47,0,1,7, 2049,12100,10,12288,12315,168,14258,229463966214663,102,58,102,108,111,111,114,0,1,8,2049,12100, 10,12302,12335,168,14258,249886255052186944,102,58,99,101,105,108,105,110,103,0,1,9,2049,12100, 10,12320,12352,168,14258,6953453994383,102,58,115,113,114,116,0,1,10,2049,12100,10,12340,12368, 168,14258,210710711802,102,58,101,113,63,0,1,11,2049,12100,10,12357,12385,168,14258,6953451465639,102, 58,45,101,113,63,0,1,12,2049,12100,10,12373,12401,168,14258,210710719524,102,58,108,116, 63,0,1,13,2049,12100,10,12390,12417,168,14258,210710714079,102,58,103,116,63,0,1,14, 2049,12100,10,12406,12435,168,14258,229463963592506,102,58,100,101,112,116,104,0,1,15,2049,12100, 10,12422,12451,168,14258,210710710894,102,58,100,117,112,0,1,16,2049,12100,10,12440,12468,168, 14258,6953453456314,102,58,100,114,111,112,0,1,17,2049,12100,10,12456,12485,168,14258,6953454000352,102, 58,115,119,97,112,0,1,18,2049,12100,10,12473,12501,168,14258,210710719399,102,58,108,111, 103,0,1,19,2049,12100,10,12490,12519,168,14250,229463978190066,102,58,112,111,119,101,114,0, 1,20,2049,12100,10,12506,12535,168,14250,210710726831,102,58,115,105,110,0,1,21,2049,12100, 10,12524,12551,168,14250,210710727656,102,58,116,97,110,0,1,22,2049,12100,10,12540,12567,168, 14250,210710709610,102,58,99,111,115,0,1,23,2049,12100,10,12556,12584,168,14250,6953453349392,102,58, 97,115,105,110,0,1,24,2049,12100,10,12572,12601,168,14250,6953453332171,102,58,97,99,111, 115,0,1,25,2049,12100,10,12589,12618,168,14250,6953453350217,102,58,97,116,97,110,0,1, 26,2049,12100,10,12606,12635,168,14250,6953453890949,102,58,112,117,115,104,0,1,27,2049,12100, 10,12623,12651,168,14250,210710723764,102,58,112,111,112,0,1,28,2049,12100,10,12640,12670,168, 14250,7572310679561435,102,58,97,100,101,112,116,104,0,1,29,2049,12100,10,12656,12687,168,14250, 6953453855649,102,58,111,118,101,114,0,2049,12635,2049,12451,2049,12651,2049,12485,10,12675,12708,168, 14250,6953454034172,102,58,116,117,99,107,0,2049,12451,2049,12635,2049,12485,2049,12651,10,12696,12728, 168,14250,210710721388,102,58,110,105,112,0,2049,12485,2049,12468,10,12717,12750,168,14250,-4575027385529052237,102, 58,100,114,111,112,45,112,97,105,114,0,2049,12468,2049,12468,10,12733,12771,168,14250, 8246246480203571943,102,58,100,117,112,45,112,97,105,114,0,2049,12687,2049,12687,10,12755,12787,168, 14250,210710725946,102,58,114,111,116,0,2049,12635,2049,12485,2049,12651,2049,12485,10,12776,12809,180, 14240,229482595734757,115,105,103,105,108,58,46,0,2049,1913,1,4500,1,4423,2049,66,1,12194, 2049,168,10,12796,12836,168,14240,7572311399974070,102,58,115,113,117,97,114,101,0,2049,12451,2049, 12283,10,12822,12858,168,14240,-4575010631505066633,102,58,112,111,115,105,116,105,118,101,63,0,1, 0,2049,12173,2049,12417,10,12841,12882,168,14240,-4575013886317431657,102,58,110,101,103,97,116,105,118, 101,63,0,1,0,2049,12173,2049,12401,10,12865,12903,168,14240,7572311189563001,102,58,110,101,103, 97,116,101,0,1,-1,2049,12173,2049,12283,10,12889,12921,168,14240,210710707003,102,58,97,98, 115,0,2049,12451,2049,12882,1,12903,9,10,12910,12940,168,14240,210710723966,102,58,112,117,116, 0,2049,12238,2049,10942,10,12929,12955,168,14240,6385172350,102,58,80,73,0,2049,4472,51,46, 49,52,49,53,57,50,54,53,52,0,1,12957,2049,12194,10,12945,12983,168,14240,193490058, 102,58,69,0,2049,4472,50,46,55,49,56,50,56,49,56,50,56,0,1,12985, 2049,12194,10,12974,13013,168,14240,210710685186,102,58,78,65,78,0,2049,4472,48,0,1,13015, 2049,12194,2049,4472,48,0,1,13023,2049,12194,2049,12297,10,13002,13043,168,14240,210710680162,102,58, 73,78,70,0,2049,4472,49,46,48,0,1,13045,2049,12194,2049,4472,48,0,1,13055, 2049,12194,2049,12297,10,13032,13076,168,14240,6953451433999,102,58,45,73,78,70,0,2049,4472,45, 49,46,48,0,1,13078,2049,12194,2049,4472,48,0,1,13089,2049,12194,2049,12297,10,13064, 13110,168,14240,6953453797089,102,58,110,97,110,63,0,2049,12451,2049,12385,10,13098,13127,168,14240, 6953453631297,102,58,105,110,102,63,0,2049,13043,2049,12368,10,13115,13145,168,14240,229463898507918,102,58, 45,105,110,102,63,0,2049,13076,2049,12368,10,13132,13163,168,14240,229463980560013,102,58,114,111, 117,110,100,0,2049,12451,2049,12882,1793,13184,2049,4472,48,46,53,0,1,13171,2049,12194, 2049,12269,2049,12335,10,1,13169,1793,13203,2049,4472,48,46,53,0,1,13190,2049,12194,2049, 12255,2049,12315,10,1,13188,2049,66,10,13150,13219,168,14231,210710720297,102,58,109,105,110,0, 2049,12771,2049,12401,1,12468,1,12728,2049,66,10,13208,13241,168,14231,210710720043,102,58,109,97, 120,0,2049,12771,2049,12417,1,12468,1,12728,2049,66,10,13230,13265,168,14231,229463973220004,102,58, 108,105,109,105,116,0,2049,12485,2049,12635,2049,13219,2049,12651,2049,13241,10,13252,13292,168, 14231,8246246374547107374,102,58,98,101,116,119,101,101,110,63,0,2049,12787,2049,12451,2049,12635,2049, 12787,2049,12787,2049,13265,2049,12651,2049,12368,10,13276,13320,168,14231,210710716095,102,58,105,110,99, 0,2049,4472,49,0,1,13322,2049,12194,2049,12255,10,13309,13342,168,14231,210710710353,102,58,100, 101,99,0,2049,4472,49,0,1,13344,2049,12194,2049,12269,10,13331,13365,168,14231,6953453401985,102, 58,99,97,115,101,0,2049,12687,2049,12368,1793,13377,2049,12468,8,1,-1,10,1,13371, 1793,13385,3,1,0,10,1,13381,2049,66,25,6,771,10,13353,13405,168,14231,6953453985302,102, 58,115,105,103,110,0,2049,12451,2049,4472,48,0,1,13409,2049,12194,2049,12368,1793,13424, 1,0,2049,12468,10,1,13419,2049,2862,2049,4472,48,0,1,13430,2049,12194,2049,12417,1793, 13443,1,1,10,1,13440,1793,13450,1,-1,10,1,13447,2049,66,10,13393,9223372036854775805,156,14231, 210709498186,101,58,77,65,88,0,13455,-9223372036854775805,156,14231,210709498440,101,58,77,73,78,0,13466,-9223372036854775807, 156,14231,210709499265,101,58,78,65,78,0,13477,9223372036854775806,156,14231,210709494241,101,58,73,78,70,0, 13488,-9223372036854775806,156,14231,6953412298606,101,58,45,73,78,70,0,13499,13521,168,14231,6385137393,101,58,110, 63,0,1,-9223372036854775805,2049,3125,1,9223372036854775805,2049,3139,2049,3158,10,13511,13544,168,14231,6953414626089,101,58, 109,97,120,63,0,1,9223372036854775805,11,10,13532,13560,168,14231,6953414634471,101,58,109,105,110,63, 0,1,-9223372036854775805,11,10,13548,13577,168,14199,229462698216771,101,58,122,101,114,111,63,0,2049,2722, 10,13564,13592,168,14199,6953414661696,101,58,110,97,110,63,0,1,-9223372036854775807,11,10,13580,13608,168, 14199,6953414495904,101,58,105,110,102,63,0,1,9223372036854775806,11,10,13596,13625,168,14199,229462607039949,101,58, 45,105,110,102,63,0,1,-9223372036854775806,11,10,13612,13641,168,14199,6953414278252,101,58,99,108,105, 112,0,1,-9223372036854775805,1,9223372036854775805,2049,3106,10,13629,13658,168,14199,6385171963,102,58,69,49,0,1793, 13660,2049,4472,49,46,101,53,0,1,13662,2049,12194,10,13648,13691,168,14199,-1561378222854156682,102,58, 115,105,103,110,101,100,45,115,113,114,116,0,2049,12451,2049,13405,2049,12921,2049,12352, 2049,12173,2049,12283,10,13672,13725,168,14199,-3240429906897787043,102,58,115,105,103,110,101,100,45,115, 113,117,97,114,101,0,2049,12451,2049,13405,2049,12451,2049,12283,2049,12173,2049,12283,10,13704, 13752,168,0,7572308662409552,102,58,45,115,104,105,102,116,0,2049,13658,2049,12283,10,13738,13771, 168,0,7572308584138766,102,58,43,115,104,105,102,116,0,2049,13658,2049,12297,10,13757,13791,168, 0,249886182735593054,102,58,43,101,110,99,111,100,101,0,2049,13691,2049,13752,10,13776,13811,168, 0,249886185318528992,102,58,45,101,110,99,111,100,101,0,2049,12451,2049,13405,2049,13771,2049,12451, 2049,12283,2049,12173,2049,12283,10,13704,13838,168,14199,6953454025850,102,58,116,111,45,101,0,2049, 12451,2049,13110,1793,13849,2049,12468,1,-9223372036854775807,10,1,13844,2049,2862,2049,12451,2049,13127,1793,13864, 2049,12468,1,9223372036854775806,10,1,13859,2049,2862,2049,12451,2049,13145,1793,13879,2049,12468,1,-9223372036854775806,10, 1,13874,2049,2862,2049,13791,2049,13163,2049,12216,2049,13641,1,-9223372036854775805,1,12468,2049,2554,1,9223372036854775805, 1,12468,2049,2554,10,13826,13916,168,14199,6953414890458,101,58,116,111,45,102,0,1,-9223372036854775807,1, 13013,2049,2554,1,9223372036854775806,1,13043,2049,2554,1,-9223372036854775806,1,13076,2049,2554,2049,12173,2049,13811,10, 13904,13952,168,14199,229463981919218,102,58,115,116,111,114,101,0,1,13838,2049,2229,16,10,13939, 13971,168,14199,229463965968143,102,58,102,101,116,99,104,0,15,2049,13916,10,13958,13993,168,14199, -3401946998789110658,102,58,100,117,109,112,45,115,116,97,99,107,0,2049,12435,2,1,12635,2049, 2449,1793,14011,2049,12651,2049,12451,2049,12940,2049,10912,10,1,14002,2049,2449,10,13975,14035,168, 14199,-1583786518488284545,102,58,100,117,109,112,45,97,115,116,97,99,107,0,2049,12670,2,1, 12651,2049,2449,1793,14053,2049,12451,2049,12940,2049,10912,2049,12635,10,1,14044,2049,2449,10,14016, 14069,168,14199,210709538045,101,58,112,117,116,0,1,9223372036854775805,1793,14086,2049,4472,101,58,77,65, 88,0,1,14075,2049,10942,10,1,14073,2049,2554,1,-9223372036854775805,1793,14107,2049,4472,101,58,77, 73,78,0,1,14096,2049,10942,10,1,14094,2049,2554,1,0,1793,14126,2049,4472,101,58, 48,0,1,14117,2049,10942,10,1,14115,2049,2554,1,-9223372036854775807,1793,14147,2049,4472,101,58,78, 65,78,0,1,14136,2049,10942,10,1,14134,2049,2554,1,9223372036854775806,1793,14168,2049,4472,101,58, 73,78,70,0,1,14157,2049,10942,10,1,14155,2049,2554,1,-9223372036854775806,1793,14190,2049,4472,101, 58,45,73,78,70,0,1,14178,2049,10942,10,1,14176,2049,2554,2049,13916,2049,12940,10, 105,110,116,101,114,102,97,99,101,47,102,108,111,97,116,105,110,103,112,111, 105,110,116,46,114,101,116,114,111,0,14199,14238,101,58,109,105,110,63,0,14231, 14248,102,58,114,111,117,110,100,0,14240,14256,102,58,114,111,116,0,14250,14264,102, 58,108,111,103,0,14258,14278,102,58,116,111,45,115,116,114,105,110,103,0,14266, 15148,14058,14300,168,15150,8056574075740390096,102,105,108,101,58,111,112,101,114,97,116,105,111,110, 0,1,4,2049,10836,2,2049,2761,1793,14350,3,2049,4472,69,114,114,111,114,58,32, 100,101,118,105,99,101,32,40,48,48,48,52,41,32,110,111,116,32,102,111, 117,110,100,0,1,14312,2049,10942,2049,10899,10,1,14309,2049,2862,2049,10817,10,14280,0, 156,15150,6953509466161,102,105,108,101,58,82,0,14357,1,156,15150,6953509466166,102,105,108,101,58, 87,0,14369,2,156,15150,6953509466144,102,105,108,101,58,65,0,14381,3,156,15150,229465812383356,102, 105,108,101,58,82,43,0,14393,14421,168,15150,249888269686595441,102,105,108,101,58,111,112,101, 110,0,1,0,2049,14300,10,14406,14442,168,15150,8246312899643285909,102,105,108,101,58,99,108,111, 115,101,0,1,1,2049,14300,10,14426,14462,168,15121,249888269686691131,102,105,108,101,58,114,101, 97,100,0,1,2,2049,14300,10,14447,14483,168,15121,8246312899667213450,102,105,108,101,58,119,114, 105,116,101,0,1,3,2049,14300,10,14467,14503,168,15121,249888269686763376,102,105,108,101,58,116, 101,108,108,0,1,4,2049,14300,10,14488,14523,168,15121,249888269686727207,102,105,108,101,58,115, 101,101,107,0,1,5,2049,14300,10,14508,14543,168,15121,249888269686732250,102,105,108,101,58,115, 105,122,101,0,1,6,2049,14300,10,14528,14565,168,15121,-4572835417384127758,102,105,108,101,58,100, 101,108,101,116,101,0,1,7,2049,14300,10,14548,14586,168,15121,8246312899646850209,102,105,108,101, 58,102,108,117,115,104,0,1,8,2049,14300,10,14570,14612,168,0,7612651040925696305,102,105,108, 101,58,114,101,97,100,47,98,121,116,101,115,0,1,9,2049,14300,10,14591,14639, 168,0,-7028659436281878592,102,105,108,101,58,119,114,105,116,101,47,98,121,116,101,115,0, 1,10,2049,14300,10,14617,14662,168,15121,-3329616181967816770,102,105,108,101,58,101,120,105,115,116, 115,63,0,1,0,2049,14421,2,2049,2740,1793,14676,2049,14442,2049,2527,10,1,14671,1793, 14684,3,2049,2541,10,1,14680,2049,66,10,14644,14716,168,15121,-4283841618960457812,102,105,108,101,58, 111,112,101,110,45,102,111,114,45,114,101,97,100,105,110,103,0,1,0,2049, 14421,2,2049,14543,4,10,14689,14751,168,15121,2106155595587003402,102,105,108,101,58,111,112,101,110, 45,102,111,114,45,97,112,112,101,110,100,0,1,2,2049,14421,2,2049,14543,4, 10,14725,14787,168,15121,-4283841611984295498,102,105,108,101,58,111,112,101,110,45,102,111,114,45, 119,114,105,116,105,110,103,0,1,1,2049,14421,10,14760,14801,156,0,193455704,70,73, 68,0,0,14792,14812,156,0,6384542144,83,105,122,101,0,0,14802,14825,156,0,6952054634723,65, 99,116,105,111,110,0,0,14813,14838,156,0,6952114609983,66,117,102,102,101,114,0,0, 14826,14850,168,0,210644670123,45,101,111,102,63,0,3841,14801,2049,14503,3841,14812,13,10,14839, 14872,168,0,7572809360530097,112,114,101,115,101,114,118,101,0,1,14801,1793,14883,1,14812,1, 27,2049,3967,10,1,14876,2049,3967,10,14760,14908,168,15121,8056577820387649264,102,105,108,101,58,114, 101,97,100,45,108,105,110,101,0,4097,14801,1793,14965,2049,1977,2,4097,14838,2049,4234, 1793,14957,3841,14801,2049,14462,2,2049,4134,1793,14934,1,13,11,10,1,14930,1793,14942,1, 10,11,10,1,14938,1793,14950,1,0,11,10,1,14946,2049,2298,22,22,10,1,14921, 2049,2397,2049,4160,3,10,1,14912,2049,4260,3841,14838,10,14888,14996,168,15121,-8859848394595038695,102,105, 108,101,58,102,111,114,45,101,97,99,104,45,108,105,110,101,0,1793,15027,4097, 14825,2049,14716,4097,14801,4097,14812,1793,15018,3841,14801,2049,14908,3841,14825,8,2049,14850,10,1, 15008,2049,2372,3841,14801,2049,14442,10,1,14998,2049,14872,10,14972,15041,156,0,193455704,70,73, 68,0,0,14972,15058,168,15121,8246312899662267157,102,105,108,101,58,115,108,117,114,112,0,1793, 15085,4,2049,4234,2049,14716,4097,15041,1793,15076,3841,15041,2049,14462,2049,4134,10,1,15069,2049, 2449,3841,15041,2049,14442,10,1,15060,2049,4260,10,15042,15105,168,15121,249888269686739198,102,105,108,101, 58,115,112,101,119,0,2049,14787,4,1793,15114,67502597,2049,14483,10,1,15110,2049,4741,2049, 14442,10,105,110,116,101,114,102,97,99,101,47,102,105,108,101,115,121,115,116, 101,109,46,114,101,116,114,111,0,15121,15161,102,105,108,101,58,99,108,111,115, 101,0,15150,15900,15090,15184,168,15902,4299348465103751587,105,111,58,117,110,105,120,45,115,121,115, 99,97,108,108,0,1,8,2049,10836,2,2049,2761,1793,15234,3,2049,4472,69,114,114, 111,114,58,32,100,101,118,105,99,101,32,40,48,48,48,56,41,32,110,111, 116,32,102,111,117,110,100,0,1,15196,2049,10942,2049,10899,10,1,15193,2049,2862,2049, 10817,10,15163,15258,168,15902,-4549633084047572696,117,110,105,120,58,115,121,115,116,101,109,0,1, 0,2049,15184,10,15241,15278,168,15902,249909575776928405,117,110,105,120,58,102,111,114,107,0,1, 1,2049,15184,10,15263,15299,168,15902,8247016000637760504,117,110,105,120,58,101,120,101,99,48,0, 1,2,2049,15184,10,15283,15320,168,15902,8247016000637760505,117,110,105,120,58,101,120,101,99,49, 0,1,3,2049,15184,10,15304,15341,168,15902,8247016000637760506,117,110,105,120,58,101,120,101,99, 50,0,1,4,2049,15184,10,15325,15362,168,15902,8247016000637760507,117,110,105,120,58,101,120,101, 99,51,0,1,5,2049,15184,10,15346,15382,168,15902,249909575776901981,117,110,105,120,58,101,120, 105,116,0,1,6,2049,15184,10,15367,15404,168,15879,-4549633084540884128,117,110,105,120,58,103,101, 116,112,105,100,0,1,7,2049,15184,10,15387,15424,168,15879,249909575777523800,117,110,105,120,58, 119,97,105,116,0,1,8,2049,15184,10,15409,15444,168,15879,249909575777101359,117,110,105,120,58, 107,105,108,108,0,1,9,2049,15184,10,15429,15465,168,15879,8247016000650494309,117,110,105,120,58, 112,111,112,101,110,0,1,10,2049,15184,10,15449,15487,168,15879,-4549633084191325687,117,110,105,120, 58,112,99,108,111,115,101,0,1,11,2049,15184,10,15470,15508,168,15879,8247016000634812845,117,110, 105,120,58,99,104,100,105,114,0,1,13,2049,15184,10,15492,15530,168,15879,-4549633084540895924,117, 110,105,120,58,103,101,116,101,110,118,0,1,14,2049,15184,10,15513,15552,168,15879, -4549633084169702651,117,110,105,120,58,112,117,116,101,110,118,0,1,15,2049,15184,10,15535,15573, 168,15879,8247016000653932284,117,110,105,120,58,115,108,101,101,112,0,1,16,2049,15184,10,15557, 15596,168,15879,-2563939202030369066,117,110,105,120,58,101,120,101,99,117,116,101,0,1,17,2049, 15184,10,15578,15616,168,15879,249909575777281169,117,110,105,120,58,112,105,112,101,0,1,0,2049, 15465,1,14908,1,15487,2049,2255,10,15601,15645,168,15879,-2563939200175176882,117,110,105,120,58,103,101, 116,45,99,119,100,0,2049,4472,112,119,100,0,1,15647,2049,15616,2049,7055,2049,4472, 47,0,1,15659,2049,4721,10,15627,15695,168,15879,-2316844556017942917,117,110,105,120,58,99,111,117, 110,116,45,102,105,108,101,115,45,105,110,45,99,119,100,0,2049,4472,108,115, 32,45,49,32,124,32,119,99,32,45,108,0,1,15697,2049,15616,2049,7055,2049,266, 10,15666,15744,168,15879,-4594486429310984907,117,110,105,120,58,102,111,114,45,101,97,99,104,45, 102,105,108,101,0,2049,4472,108,115,32,45,49,32,45,112,0,1,15746,1,0, 2049,15465,2049,15695,1793,15779,1793,15774,2049,14908,2049,4423,67502597,8,10,1,15767,2049,2241,10, 1,15765,2049,2449,2049,15487,3,10,15720,15798,168,0,210728208851,115,116,97,114,116,0,4, 2049,4234,1,0,2049,15465,10,15787,15816,168,0,6385651009,114,101,97,100,0,2,2049,14462, 2,2049,4134,2049,2722,10,15806,15837,168,0,6953509544294,102,105,110,105,115,104,0,2049,15487, 2049,4212,10,15720,15863,168,15879,1204178398703148788,117,110,105,120,58,115,108,117,114,112,45,112, 105,112,101,0,1793,15874,2049,15798,1,15816,2049,2397,2049,15837,10,1,15865,2049,4260,10, 105,110,116,101,114,102,97,99,101,47,117,110,105,120,46,114,101,116,114,111, 0,15879,15912,117,110,105,120,58,101,120,105,116,0,15902,16005,15842,15928,168,15985,7572652289159374, 110,58,114,97,110,100,111,109,0,1,10,2049,10836,2,2049,2761,1793,15978,3,2049, 4472,69,114,114,111,114,58,32,100,101,118,105,99,101,32,40,48,48,49,48, 41,32,110,111,116,32,102,111,117,110,100,0,1,15940,2049,10942,2049,10899,10,1, 15937,2049,2862,2049,10817,10,105,110,116,101,114,102,97,99,101,47,114,110,103,46, 114,101,116,114,111,0,15985,16417,15914,16028,168,16395,4482520117059041020,99,108,111,99,107,58,111, 112,101,114,97,116,105,111,110,0,1,5,2049,10836,2,2049,2761,1793,16078,3,2049, 4472,69,114,114,111,114,58,32,100,101,118,105,99,101,32,40,48,48,48,53, 41,32,110,111,116,32,102,111,117,110,100,0,1,16040,2049,10942,2049,10899,10,1, 16037,2049,2862,2049,10817,10,16007,16106,168,16395,4482526860617352831,99,108,111,99,107,58,116,105,109, 101,115,116,97,109,112,0,1,0,2049,16028,10,16085,16126,168,16395,249884182168395049,99,108,111, 99,107,58,100,97,121,0,1,1,2049,16028,10,16111,16148,168,16395,-4577286724249897519,99,108,111, 99,107,58,109,111,110,116,104,0,1,2,2049,16028,10,16131,16169,168,16395,8246178011557794972,99, 108,111,99,107,58,121,101,97,114,0,1,3,2049,16028,10,16153,16190,168,16395,8246178011557195593, 99,108,111,99,107,58,104,111,117,114,0,1,4,2049,16028,10,16174,16213,168,16395, -3476509310577319139,99,108,111,99,107,58,109,105,110,117,116,101,0,1,5,2049,16028,10,16195, 16236,168,16395,-3476509310347652505,99,108,111,99,107,58,115,101,99,111,110,100,0,1,6,2049, 16028,10,16218,16260,168,16395,-4044342796047171665,99,108,111,99,107,58,117,116,99,58,100,97,121, 0,1,7,2049,16028,10,16241,16286,168,16395,4482528721224061399,99,108,111,99,107,58,117,116,99, 58,109,111,110,116,104,0,1,8,2049,16028,10,16265,16311,168,16395,-4336103753589045278,99,108,111, 99,107,58,117,116,99,58,121,101,97,114,0,1,9,2049,16028,10,16291,16336,168, 16395,-4336103753589644657,99,108,111,99,107,58,117,116,99,58,104,111,117,114,0,1,10,2049, 16028,10,16316,16363,168,16395,349495210710499299,99,108,111,99,107,58,117,116,99,58,109,105,110, 117,116,101,0,1,11,2049,16028,10,16341,16390,168,16395,349495210940165933,99,108,111,99,107,58, 117,116,99,58,115,101,99,111,110,100,0,1,12,2049,16028,10,105,110,116,101, 114,102,97,99,101,47,99,108,111,99,107,46,114,101,116,114,111,0,16395,16816, 16368,16441,168,0,1976442044545254821,115,99,114,105,112,116,58,111,112,101,114,97,116,105,111, 110,0,1,9,2049,10836,2,2049,2761,1793,16491,3,2049,4472,69,114,114,111,114,58, 32,100,101,118,105,99,101,32,40,48,48,48,57,41,32,110,111,116,32,102, 111,117,110,100,0,1,16453,2049,10942,2049,10899,10,1,16450,2049,2862,2049,10817,10,16368, 16520,168,16790,1976422442775525130,115,99,114,105,112,116,58,97,114,103,117,109,101,110,116,115, 0,1,0,2049,16441,10,16498,16550,168,16790,7012485947518414468,115,99,114,105,112,116,58,103,101, 116,45,97,114,103,117,109,101,110,116,0,2049,4451,4,1,1,2049,16441,10,16525, 16571,168,16790,229469872107401,105,110,99,108,117,100,101,0,1,2,2049,16441,10,16558,16593,168, 16790,-4553194680242110987,115,99,114,105,112,116,58,110,97,109,101,0,2049,4451,1,3,2049,16441, 10,16576,16625,168,16790,6834827170184619652,115,99,114,105,112,116,58,99,117,114,114,101,110,116, 45,102,105,108,101,0,2049,4451,1,4,2049,16441,10,16600,16657,180,16790,6834827170184835340,115,99, 114,105,112,116,58,99,117,114,114,101,110,116,45,108,105,110,101,0,1,5, 2049,16441,2049,156,10,16632,16690,168,16790,-4964876483161304491,115,99,114,105,112,116,58,105,103,110, 111,114,101,45,116,111,45,101,111,108,0,1,6,2049,16441,10,16664,16721,168,16790, -112287744780050755,115,99,114,105,112,116,58,97,98,111,114,116,45,105,110,99,108,117,100, 101,0,1,7,2049,16441,10,16695,16737,168,16790,210706230653,97,98,111,114,116,0,1,149, 2049,3931,1,8,2049,16441,10,16726,16776,168,0,-7741142524340576066,115,99,114,105,112,116,58,99, 117,114,114,101,110,116,45,108,105,110,101,45,116,101,120,116,0,2049,4451,1793, 16785,1,9,2049,16441,10,1,16780,2049,2241,10,105,110,116,101,114,102,97,99,101, 47,115,99,114,105,112,116,105,110,103,46,114,101,116,114,111,0,16790,17272,16746, 16840,168,17248,1183117598919957017,115,111,99,107,101,116,58,111,112,101,114,97,116,105,111,110, 0,1,7,2049,10836,2,2049,2761,1793,16997,3,2049,4472,69,114,114,111,114,58,32, 100,101,118,105,99,101,32,40,48,48,48,55,41,32,110,111,116,32,102,111, 117,110,100,0,1,16852,2049,10942,2049,10899,2049,4472,83,101,101,32,104,116,116,112, 115,58,47,47,114,101,116,114,111,102,111,114,116,104,46,111,114,103,47,115, 117,112,112,111,114,116,47,50,48,50,50,46,49,47,83,79,67,75,69,84, 83,46,109,100,0,1,16891,2049,10942,2049,10899,2049,4472,102,111,114,32,105,110,115, 116,114,117,99,116,105,111,110,115,32,111,110,32,101,110,97,98,108,105,110, 103,32,115,111,99,107,101,116,115,46,0,1,16952,2049,10942,2049,10899,10,1,16849, 2049,2862,2049,10817,10,16818,17030,168,17248,-7671511728383126910,115,111,99,107,101,116,58,103,101,116, 104,111,115,116,98,121,110,97,109,101,0,1,0,2049,16840,10,17004,17054,168,17248, 4328757989659661596,115,111,99,107,101,116,58,99,114,101,97,116,101,0,1,1,2049,16840,10, 17035,17076,168,17248,-4552658767528245371,115,111,99,107,101,116,58,98,105,110,100,0,1,2,2049, 16840,10,17059,17100,168,17248,4328757990001730167,115,111,99,107,101,116,58,108,105,115,116,101,110, 0,1,3,2049,16840,10,17081,17124,168,17248,4328757989563534360,115,111,99,107,101,116,58,97,99, 99,101,112,116,0,1,4,2049,16840,10,17105,17149,168,17248,-4724938931013862254,115,111,99,107,101, 116,58,99,111,110,110,101,99,116,0,1,5,2049,16840,10,17129,17171,168,17248,-4552658767527638798, 115,111,99,107,101,116,58,115,101,110,100,0,1,6,2049,16840,10,17154,17193,168, 17248,-4552658767527675080,115,111,99,107,101,116,58,114,101,99,118,0,1,7,2049,16840,10,17176, 17216,168,17248,-2663786738754388898,115,111,99,107,101,116,58,99,108,111,115,101,0,1,8,2049, 16840,10,17198,17243,168,17248,1183100690560715498,115,111,99,107,101,116,58,99,111,110,102,105,103, 117,114,101,0,1,9,2049,16840,10,105,110,116,101,114,102,97,99,101,47,115, 111,99,107,101,116,115,46,114,101,116,114,111,0,17248,17482,17221,17287,168,17456,229469862290528, 105,111,58,99,111,114,101,0,1,8000,2049,10836,2049,10817,10,17274,17309,168,17456,249884313919988732, 99,111,114,101,58,105,110,105,116,0,1,0,2049,17287,10,17294,17330,168,17456,8246182359371694326, 99,111,114,101,58,115,116,97,114,116,0,1,1,2049,17287,10,17314,17351,168,17456, 8246182359367475558,99,111,114,101,58,112,97,117,115,101,0,1,2,2049,17287,10,17335,17380,168, 17456,8337299194488917014,99,111,114,101,58,112,97,117,115,101,45,99,117,114,114,101,110,116, 0,1,3,2049,17287,10,17356,17402,168,17456,-4577143246433635687,99,111,114,101,58,114,101,115,117, 109,101,0,1,4,2049,17287,10,17385,17426,168,17456,-3888095465377135055,99,111,114,101,58,114,101, 97,100,47,114,101,103,0,1,5,2049,17287,10,17407,17451,168,17456,820065755623810592,99,111,114, 101,58,119,114,105,116,101,47,114,101,103,0,1,6,2049,17287,10,105,110,116, 101,114,102,97,99,101,47,109,117,108,116,105,99,111,114,101,46,114,101,116, 114,111,0,17456,17642,17431,17503,168,17622,644988671245709381,102,102,105,58,111,112,101,114,97,116, 105,111,110,0,1,8100,2049,10836,2,2049,2761,1793,17553,3,2049,4472,69,114,114,111, 114,58,32,100,101,118,105,99,101,32,40,48,48,49,48,41,32,110,111,116, 32,102,111,117,110,100,0,1,17515,2049,10942,2049,10899,10,1,17512,2049,2862,2049,10817, 10,17484,17574,168,17622,7572367767785414,102,102,105,58,111,112,101,110,0,1,0,2049,17503,10, 17560,17596,168,17622,-4572980637897979592,102,102,105,58,109,97,112,45,115,121,109,0,1,1,2049, 17503,10,17579,17617,168,17622,8246308498881747296,102,102,105,58,105,110,118,111,107,101,0,1,2, 2049,17503,10,105,110,116,101,114,102,97,99,101,47,102,102,105,46,114,101,116, 114,111,0,17622,17973,17601,17660,168,17948,8247016409221251463,117,110,115,105,103,110,101,100,58,43, 0,1,0,1,8101,2049,10836,2049,10817,17,10,17644,17686,168,17948,8247016409221251465,117,110,115,105, 103,110,101,100,58,45,0,1,0,1,8101,2049,10836,2049,10817,18,10,17670,17712,168, 17948,8247016409221251462,117,110,115,105,103,110,101,100,58,42,0,1,0,1,8101,2049,10836,2049, 10817,19,10,17696,17741,168,17948,7638409966457829387,117,110,115,105,103,110,101,100,58,47,109,111, 100,0,1,0,1,8101,2049,10836,2049,10817,20,10,17722,17769,168,17948,-2563494254608726831,117,110,115, 105,103,110,101,100,58,101,113,63,0,1,0,1,8101,2049,10836,2049,10817,11,10, 17751,17798,168,17948,7638409966457748830,117,110,115,105,103,110,101,100,58,45,101,113,63,0,1, 0,1,8101,2049,10836,2049,10817,12,10,17779,17826,168,17948,-2563494254608719109,117,110,115,105,103,110, 101,100,58,108,116,63,0,1,0,1,8101,2049,10836,2049,10817,13,10,17808,17854,168, 17948,-2563494254608724554,117,110,115,105,103,110,101,100,58,103,116,63,0,1,0,1,8101,2049, 10836,2049,10817,14,10,17836,17884,168,17948,-6186888138744896262,117,110,115,105,103,110,101,100,58,115, 104,105,102,116,0,1,0,1,8101,2049,10836,2049,10817,24,10,17864,17914,168,17948,-6186888138833512267, 117,110,115,105,103,110,101,100,58,42,47,109,111,100,0,1,1,1,0,1, 8101,2049,10836,2,2049,10817,2049,10817,10,17894,17939,168,17948,210639169918,42,47,109,111,100,0, 1,1,1,8101,2049,10836,2049,10817,10,105,110,116,101,114,102,97,99,101,47,117, 110,115,105,103,110,101,100,46,114,101,116,114,111,0,17948,18301,17928,17986,168,521216, 210720194422,110,58,97,100,100,0,17,10,17975,17999,168,521216,210720214583,110,58,115,117,98,0, 18,10,17988,18012,168,521216,210720208059,110,58,109,117,108,0,19,10,18001,18025,168,521216,210720197872, 110,58,100,105,118,0,197652,10,18014,18038,168,521216,210720207853,110,58,109,111,100,0,788, 10,18027,18054,168,521216,7572651751048528,110,58,100,105,118,109,111,100,0,20,10,18040,18067,168, 0,210709067314,99,111,109,109,97,0,2049,130,10,18056,18078,168,0,5863407,103,99,0,1, 3,4,2049,3967,10,18070,18102,168,0,-3502245454587251943,100,58,117,115,101,45,104,97,115,104, 101,115,0,1,29,1,236,1,5,18,16,1793,18116,2049,188,15,10,1,18112,1, 236,1,8,18,16,1,2049,1,236,16,1,4875,1,236,2049,3125,16,10,18084,18156, 168,0,-4893635544173424761,100,58,117,115,101,45,115,116,114,105,110,103,115,0,1,118,1, 236,1,5,18,16,1,190,1,236,1,8,18,16,1,0,1,236,16,1,0, 1,236,2049,3125,16,10,18137,18203,168,0,-3527051417241377258,98,108,111,99,107,58,105,110,118, 111,107,101,0,1,3,2049,10836,2049,10817,10,18137,18226,168,18278,8246131600073141446,98,108,111,99, 107,58,114,101,97,100,0,1,0,2049,18203,10,18210,18248,168,18278,-4578818303223200395,98,108,111, 99,107,58,119,114,105,116,101,0,1,1,2049,18203,10,18231,18273,168,18278,-4036225629868593021,98, 108,111,99,107,58,115,101,116,45,102,105,108,101,0,1,2,2049,18203,10,105, 110,116,101,114,102,97,99,101,47,98,108,111,99,107,115,46,114,101,116,114, 111,0,18278,11438,18253,18319,168,0,8246228896775126019,100,111,117,98,108,101,58,118,97,114,0, 2049,2075,4,2049,130,2049,130,10,18303,18345,168,0,-3421095308458227740,100,111,117,98,108,101,58, 102,101,116,99,104,0,2049,58,4,15,10,18327,18368,168,0,-3421095308442276665,100,111,117,98, 108,101,58,115,116,111,114,101,0,1,19,2049,2229,2049,61,16,10,18350,18394,168, 0,-3421095308461432127,100,111,117,98,108,101,58,99,111,110,115,116,0,2049,18319,1,18345,2049, 8460,10,18376,18418,168,0,-4575607512064199915,100,111,117,98,108,101,58,115,119,97,112,0,67503109, 5,67503109,6,10,18401,18439,168,0,8246228896775106679,100,111,117,98,108,101,58,100,105,112,0, 67503109,67503109,5,5,8,6,6,10,18423,18463,168,0,8246228896775123014,100,111,117,98,108,101,58, 115,105,112,0,1,2217,2049,2229,2049,18439,10,18447,18486,168,0,8246632143337714634,109,101,109,58, 105,110,118,111,107,101,0,1,15,2049,10836,2049,10817,10,18470,0,156,0,210667451248,65, 76,76,79,67,0,18493,1,156,0,6384048135,70,82,69,69,0,18504,2,156,0,210689088690, 83,84,79,82,69,0,18514,3,156,0,210673137615,70,69,84,67,72,0,18525,4,156, 0,6952683137271,82,69,83,73,90,69,0,18447,18563,168,0,249897943727936361,109,101,109,58,97,108, 108,111,99,0,1,0,2049,18486,10,18548,18583,168,0,249897943749573803,109,101,109,58,115,116, 111,114,101,0,1,2,2049,18486,10,18568,18603,168,0,249897943733622728,109,101,109,58,102,101, 116,99,104,0,1,3,2049,18486,10,18588,18622,168,0,7572664961638592,109,101,109,58,102,114, 101,101,0,1,1,2049,18486,10,18608,18643,168,0,8246632143679146032,109,101,109,58,114,101,115, 105,122,101,0,1,4,2049,18486,10,18627,18663,168,0,249897943730056489,109,101,109,58,99,101, 108,108,43,0,1,8,19,17,10,18648,18690,168,0,1050530996183190288,109,101,109,58,102,101, 116,99,104,45,100,111,117,98,108,101,0,2,1,1,2049,18663,15,5,2049,18603, 6,10,18668,18723,168,0,1730340976492540563,109,101,109,58,115,116,111,114,101,45,100,111,117, 98,108,101,0,5,5,2049,2217,1,1,2049,18663,6,2049,18583,6,2049,18583,10,18701, 18759,168,0,4283726481136624767,101,114,114,58,115,101,116,45,104,97,110,100,108,101,114,0, 1,1234,2049,10836,2,2049,2761,1793,18809,3,2049,4472,69,114,114,111,114,58,32,100, 101,118,105,99,101,32,40,49,50,51,52,41,32,110,111,116,32,102,111,117, 110,100,0,1,18771,2049,10942,2049,10899,10,1,18768,2049,2862,1,0,4,2049,10817,10, 18738,18832,168,0,229464878751060,101,114,114,58,100,115,117,0,2049,10974,2049,10899,2049,4472,69, 82,82,79,82,58,32,68,83,85,58,32,68,65,84,65,32,83,84,65,67, 75,32,85,78,68,69,82,70,76,79,87,0,1,18838,2049,10942,2049,10899,2049,11214, 10,18819,18893,168,0,229464878751054,101,114,114,58,100,115,111,0,2049,10974,2049,10899,2049,4472, 69,82,82,79,82,58,32,68,83,79,58,32,68,65,84,65,32,83,84,65, 67,75,32,79,86,69,82,70,76,79,87,0,1,18899,2049,10942,2049,10899,2049,11214, 10,18880,18962,168,0,-6210978877792005319,101,114,114,58,115,101,116,45,100,101,102,97,117,108, 116,115,0,1,18832,1,1,2049,18759,1,18893,1,2,2049,18759,10,1793,18996,1,192, 1,2,17,8,2049,1576,2049,190,3841,11263,8,2049,1576,2049,188,16,10,1,18977,18940, 19007,168,19762,193470948,84,73,66,0,1,7,15,10,18998,19027,168,19762,8246457295145463473,105,109,97, 103,101,58,115,97,118,101,0,1,1000,2049,10836,2049,10817,10,19011,19045,168,0,210711039690, 101,100,105,116,63,0,2,1793,19052,1,8,11,10,1,19048,1793,19060,1,127,11, 10,1,19056,2049,2255,22,10,19034,19078,168,0,6953539406400,103,97,116,104,101,114,0,2049, 19045,1,17,1,4134,2049,66,10,19066,19098,168,0,210709415765,99,121,99,108,101,0,2049, 11147,2049,2217,4,8,2049,2644,25,3,2049,19078,1,19098,7,10,19011,19131,168,19762,-4557881830897049127, 112,97,114,115,101,45,117,110,116,105,108,0,1793,19143,2049,4451,2049,4234,2049,19098, 771,2049,4096,10,1,19133,2049,4260,10,19114,19159,168,19762,210726130610,115,58,103,101,116,0, 1793,19181,1793,19167,1,13,11,10,1,19163,1793,19175,1,10,11,10,1,19171,2049,2255, 22,10,1,19161,2049,19131,10,19148,19197,168,19762,210708950412,99,108,101,97,114,0,2049,4472, 92,94,91,50,74,92,94,91,48,59,48,72,0,1,19199,2049,8246,2049,10942,10, 19186,19228,156,0,193454829,69,79,84,0,0,19219,19243,156,0,7571133383038306,73,103,110,111,114, 105,110,103,0,0,19229,19259,168,0,249892406716047873,105,103,110,111,114,105,110,103,63,0, 3841,19243,10,19244,19275,168,0,229486327000139,118,101,114,115,105,111,110,0,3841,4,1,100, 20,10,19262,19292,168,0,210710254026,100,111,110,101,63,0,2,4097,19228,1793,19301,1,13, 11,10,1,19297,1793,19309,1,10,11,10,1,19305,1793,19317,1,32,11,10,1,19313, 2049,2298,22,22,10,19281,19334,168,0,6385195044,101,111,108,63,0,3841,19228,1793,19342,1, 13,11,10,1,19338,1793,19350,1,10,11,10,1,19346,2049,2255,22,10,19324,19368,168, 0,6954126150804,118,97,108,105,100,63,0,2,2049,104,2049,2812,10,19356,19389,168,0,249883998779477802, 99,104,101,99,107,45,101,111,102,0,2,1793,19396,1,-1,11,10,1,19392,1793, 19404,1,4,11,10,1,19400,2049,2255,22,1,11214,9,10,19374,19421,168,0,5863258,98, 115,0,2049,4212,1,2,2049,2675,1793,19433,2049,4160,3,10,1,19429,9,2049,4160,3, 10,19413,19454,168,0,7572242387256805,99,104,101,99,107,45,98,115,0,2,1793,19461,1,8, 11,10,1,19457,1793,19469,1,127,11,10,1,19465,2049,2255,22,1,19421,9,10,19440, 19489,168,0,210708806723,99,104,101,99,107,0,2049,19389,2049,19454,10,19478,19509,168,0,249883994190734226, 99,104,97,114,97,99,116,101,114,0,2049,11147,2,2049,4134,10,19494,19527,168,0, 6953366942559,98,117,102,102,101,114,0,1793,19537,2049,19007,2049,4234,8,2049,4096,10,1,19529, 2049,4260,10,19515,19558,168,0,8246863741238799215,114,101,97,100,45,116,111,107,101,110,0,1793, 19574,1793,19569,2049,19509,2049,19489,2049,19292,10,1,19562,2049,2397,10,1,19560,2049,19527,2049, 4587,10,19542,19592,168,0,210716150453,105,110,112,117,116,0,2049,19558,2049,19368,10,19581,19610, 168,0,229479082815460,112,114,111,99,101,115,115,0,2049,19259,1793,19628,771,2049,19334,1793,19624, 1,19243,2049,3931,10,1,19619,9,10,1,19614,2049,2862,1,417,1,17,2049,66,10, 19186,19647,180,19762,5861507,47,47,0,2049,16690,1,19243,2049,3916,10,19639,19666,168,19762,6953343520347, 98,97,110,110,101,114,0,2049,19275,2049,4472,82,69,84,82,79,32,49,50,32, 40,37,110,46,37,110,41,92,110,0,1,19670,2049,8246,2049,10942,2049,9335,2049,1545, 2049,9335,18,2049,1545,2049,4472,37,110,32,77,97,120,44,32,37,110,32,85,115, 101,100,44,32,37,110,32,70,114,101,101,92,110,0,1,19706,2049,8246,2049,10942, 10,19654,19752,168,19762,6953744547860,108,105,115,116,101,110,0,2049,19666,2049,19592,2049,19610,1, 19754,7,10,105,110,116,101,114,102,97,99,101,47,114,101,116,114,111,45,117, 110,105,120,46,114,101,116,114,111,0,19740,19802,156,0,229441520490121,83,111,117,114,99, 101,115,0,1,20051,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,19789,19942,168,0,6953711201841,107,110,111,119, 110,63,0,2,1,19802,2049,9099,10,19930,19959,168,0,210716136861,105,110,100,101,120,0, 1,19802,4,2049,9775,1,19802,4,2049,9245,10,19948,19982,168,0,6953974036516,114,101,99,111, 114,100,0,2049,4500,2,1,19802,2049,3864,3841,19802,1,19802,17,16,10,1793,20049,2049, 16625,2049,19942,1793,20007,2049,19959,10,1,20004,1793,20014,2049,19982,10,1,20011,2049,66,1793, 20027,1,192,1,2,17,8,10,1,20020,2049,2229,2049,1576,2049,186,16,2049,1576,2049, 190,3841,11263,8,2049,1576,2049,188,16,10,1,19998,100,105,99,116,45,119,111,114, 100,115,45,108,105,115,116,105,110,103,46,102,111,114,116,104,0,19740,20089,168, 20051,229461403550098,100,58,119,111,114,100,115,0,1793,20098,2049,190,2049,10942,2049,10912,10,1, 20091,2049,8491,10,20076,20121,168,20051,-3502157631813457253,100,58,119,111,114,100,115,45,119,105,116, 104,0,2049,1977,2049,5573,1793,20152,2049,190,2,2049,1977,2049,5286,1793,20141,2049,10942,2049, 10912,10,1,20136,1793,20147,3,10,1,20145,2049,66,10,1,20127,2049,8491,10,20103,20178, 168,20051,2818131571306626127,100,105,115,112,108,97,121,45,105,102,45,108,101,102,116,0,2, 2049,1977,2049,5519,1793,20190,2049,10942,2049,10912,10,1,20185,1793,20196,3,10,1,20194,2049, 66,10,20103,20229,168,20051,2947807019553410009,100,58,119,111,114,100,115,45,98,101,103,105,110, 110,105,110,103,45,119,105,116,104,0,2049,1977,2049,5573,1793,20240,2049,190,2049,20178, 10,1,20235,2049,8491,10,0 }; typedef struct NgaState NgaState; typedef void (*Handler)(NgaState *); struct NgaCore { CELL sp, rp, ip; /* Stack & instruction pointers */ CELL active; /* Is core active? */ CELL u; /* Should next operation be */ /* unsigned? */ CELL data[STACK_DEPTH]; /* The data stack */ CELL address[ADDRESSES]; /* The address stack */ #ifdef ENABLE_MULTICORE CELL registers[24]; /* Internal Registers */ #endif }; struct NgaState { /* System Memory */ CELL memory[IMAGE_SIZE + 1]; /* CPU Cores */ struct NgaCore cpu[CORES]; int active; /* I/O Devices */ int devices; Handler IO_deviceHandlers[MAX_DEVICES]; Handler IO_queryHandlers[MAX_DEVICES]; CELL Dictionary, NotFound, interpret; /* Interfacing */ char string_data[8192]; #ifdef ENABLE_FLOATS double Floats[256], AFloats[256]; /* Floating Point */ CELL fsp, afsp; #endif #ifdef ENABLE_BLOCKS char BlockFile[1025]; #endif #ifdef ENABLE_ERROR CELL ErrorHandlers[64]; #endif /* Scripting */ char **sys_argv; int sys_argc; char scripting_sources[64][8192]; char line[4096]; int current_source; int perform_abort; int interactive; CELL currentLine; CELL ignoreToEOL, ignoreToEOF; /* Configuration of code & test fences for Unu */ char code_start[256], code_end[256]; char test_start[256], test_end[256]; int codeBlocks; FILE *OpenFileHandles[MAX_OPEN_FILES]; }; /* Function Prototypes ----------------------------------------------- */ void handle_error(NgaState *, CELL); CELL stack_pop(NgaState *); void stack_push(NgaState *, CELL); CELL string_inject(NgaState *, char *, CELL); char *string_extract(NgaState *, CELL); void update_rx(NgaState *); void include_file(NgaState *, char *, int); void register_device(NgaState *, void *, void *); void io_output(NgaState *); void query_output(NgaState *); void io_keyboard(NgaState *); void query_keyboard(NgaState *); void query_filesystem(NgaState *); void io_filesystem(NgaState *); void io_clock(NgaState *); void query_clock(NgaState *); void io_scripting(NgaState *); void query_scripting(NgaState *); void io_rng(NgaState *); void query_rng(NgaState *); void io_unsigned(NgaState *); void query_unsigned(NgaState *); #ifdef ENABLE_UNIX void query_unix(NgaState *); void io_unix(NgaState *); #endif #ifdef ENABLE_FLOATS void io_floatingpoint(NgaState *); void query_floatingpoint(NgaState *); #endif #ifdef ENABLE_SOCKETS void io_socket(NgaState *); void query_socket(NgaState *); #endif #ifdef ENABLE_MALLOC #ifdef BIT64 void io_malloc(NgaState *); void query_malloc(NgaState *); #endif #endif #ifdef ENABLE_BLOCKS void io_blocks(NgaState *); void query_blocks(NgaState *); #endif void io_image(NgaState *); void query_image(NgaState *); void load_embedded_image(NgaState *); CELL load_image(NgaState *, char *); void prepare_vm(NgaState *); void process_opcode_bundle(NgaState *, CELL); int validate_opcode_bundle(CELL); #ifdef NEEDS_STRL size_t strlcat(char *dst, const char *src, size_t dsize); size_t strlcpy(char *dst, const char *src, size_t dsize); #endif void inst_no(NgaState *); void inst_li(NgaState *); void inst_du(NgaState *); void inst_dr(NgaState *); void inst_sw(NgaState *); void inst_pu(NgaState *); void inst_po(NgaState *); void inst_ju(NgaState *); void inst_ca(NgaState *); void inst_cc(NgaState *); void inst_re(NgaState *); void inst_eq(NgaState *); void inst_ne(NgaState *); void inst_lt(NgaState *); void inst_gt(NgaState *); void inst_fe(NgaState *); void inst_st(NgaState *); void inst_ad(NgaState *); void inst_su(NgaState *); void inst_mu(NgaState *); void inst_di(NgaState *); void inst_an(NgaState *); void inst_or(NgaState *); void inst_xo(NgaState *); void inst_sh(NgaState *); void inst_zr(NgaState *); void inst_ha(NgaState *); void inst_ie(NgaState *); void inst_iq(NgaState *); void inst_ii(NgaState *); /* Image, Stack, and VM variables ------------------------------------ */ #define TOS vm->cpu[vm->active].data[vm->cpu[vm->active].sp] #define NOS vm->cpu[vm->active].data[vm->cpu[vm->active].sp-1] #define TORS vm->cpu[vm->active].address[vm->cpu[vm->active].rp] /* Global Variables -------------------------------------------------- */ void guard(NgaState *vm, int n, int m, int diff) { if (vm->cpu[vm->active].sp < n) { #ifdef ENABLE_ERROR if (vm->ErrorHandlers[1] != 0) { handle_error(vm, 1); } #else printf("E: Data Stack Underflow"); vm->cpu[vm->active].sp = 0; return; #endif } if (((vm->cpu[vm->active].sp + m) - n) > (STACK_DEPTH - 1)) { #ifdef ENABLE_ERROR if (vm->ErrorHandlers[2] != 0) { handle_error(vm, 2); } #else printf("E: Data Stack Overflow"); vm->cpu[vm->active].sp = 0; return; #endif } if (diff) { if (vm->cpu[vm->active].rp + diff < 0) { #ifdef ENABLE_ERROR if (vm->ErrorHandlers[3] != 0) { handle_error(vm, 3); } #else return; #endif } if (vm->cpu[vm->active].rp + diff > (ADDRESSES - 1)) { #ifdef ENABLE_ERROR if (vm->ErrorHandlers[1] != 4) { handle_error(vm, 4); } #else return; #endif } } } /* Dynamic Memory / `malloc` support --------------------------------- */ #ifdef ENABLE_MALLOC #ifdef BIT64 /*--------------------------------------------------------------------- Copyright (c) 2008 - 2022, Charles Childers Portions are based on Ngaro, which was additionally copyright by the following: Copyright (c) 2009 - 2010, Luke Parrish Copyright (c) 2010, Marc Simpson Copyright (c) 2010, Jay Skeer Copyright (c) 2011, Kenneth Keating ---------------------------------------------------------------------*/ #ifdef ENABLE_MALLOC #ifdef BIT64 typedef union { void* val; struct { CELL msw; CELL lsw; }; } double_cell; void double_add(NgaState *vm) { double_cell a; double_cell b; double_cell c; b.msw = stack_pop(vm); b.lsw = stack_pop(vm); a.msw = stack_pop(vm); a.lsw = stack_pop(vm); } void double_sub(NgaState *vm) { } void double_mul(NgaState *vm) { } void double_divmod(NgaState *vm) { } void malloc_allocate(NgaState *vm) { stack_push(vm, (CELL)malloc(stack_pop(vm))); } void malloc_free(NgaState *vm) { free((CELL*)stack_pop(vm)); } void malloc_store(NgaState *vm) { CELL value = stack_pop(vm); double_cell addr; *(CELL *) stack_pop(vm) = value; } void malloc_fetch(NgaState *vm) { double_cell addr; CELL value = *(CELL *)stack_pop(vm); stack_push(vm, value); } void malloc_realloc(NgaState *vm) { CELL bytes = stack_pop(vm); CELL* addr1; addr1 = (CELL*)stack_pop(vm); CELL* addr2; addr2 = (CELL*)realloc(addr1, bytes); stack_push(vm, (CELL)addr2); } void query_malloc(NgaState *vm) { stack_push(vm, 0); stack_push(vm, 15); } void io_malloc(NgaState *vm) { int i = stack_pop(vm); switch (i) { case 0: malloc_allocate(vm); return; case 1: malloc_free(vm); return; case 2: malloc_store(vm); return; case 3: malloc_fetch(vm); return; case 4: malloc_realloc(vm); return; } stack_push(vm, -1); } #endif #endif #endif #endif #ifdef ENABLE_ERROR /*************************************************************** Copyright (c) Charles Childers **************************************************************/ /* | 001 | Data Stack Underflow | | 002 | Data Stack Overflow | | 003 | Address Stack Underflow | | 004 | Address Stack Overflow | | 005 | Invalid Memory Access | | 006 | Division by Zero | */ #ifdef ENABLE_ERROR void execute(NgaState *vm, CELL cell); void handle_error(NgaState *vm, CELL error) { CELL saved_ip = vm->cpu[vm->active].ip; if (vm->ErrorHandlers[error] != 0) { printf("\nHandling %lld\n", error); execute(vm, vm->ErrorHandlers[error]); } vm->cpu[vm->active].ip = saved_ip; } void register_error_handler(NgaState *vm) { CELL ErrorID = stack_pop(vm); CELL ErrorHandler = stack_pop(vm); vm->ErrorHandlers[ErrorID] = ErrorHandler; printf("Assigned %lld to %lld\n", ErrorID, ErrorHandler); } void io_error(NgaState *vm) { switch (stack_pop(vm)) { case 0: register_error_handler(vm); break; default: break; } } void query_error(NgaState *vm) { stack_push(vm, 0); stack_push(vm, 1234); } #endif #endif /* Block Storage -------------------------------------------- */ #ifdef ENABLE_BLOCKS void io_blocks(NgaState *vm) { CELL op, buffer, block; int32_t m[1024]; op = stack_pop(vm); if (op == 0) { buffer = stack_pop(vm); block = stack_pop(vm); int fp = open(vm->BlockFile, O_RDONLY, 0666); lseek(fp, 4096 * block, SEEK_SET); read(fp, m, 4096); for (int i = 0; i < 1024; i++) { vm->memory[buffer + i] = (CELL)m[i]; } close(fp); } if (op == 1) { buffer = stack_pop(vm); block = stack_pop(vm); int fp = open(vm->BlockFile, O_WRONLY, 0666); lseek(fp, 4096 * block, SEEK_SET); for (int i = 0; i < 1024; i++) { m[i] = (int32_t)vm->memory[buffer + i]; } write(fp, m, 4096); close(fp); } if (op == 2) { buffer = stack_pop(vm); strlcpy(vm->BlockFile, string_extract(vm, buffer), 1024); } } void query_blocks(NgaState *vm) { stack_push(vm, 0); stack_push(vm, 3); } #endif /*--------------------------------------------------------------------- Copyright (c) 2008 - 2022, Charles Childers Portions are based on Ngaro, which was additionally copyright by the following: Copyright (c) 2009 - 2010, Luke Parrish Copyright (c) 2010, Marc Simpson Copyright (c) 2010, Jay Skeer Copyright (c) 2011, Kenneth Keating ---------------------------------------------------------------------*/ /* FileSystem Device ------------------------------------------------- */ /*--------------------------------------------------------------------- I keep an array of file handles. RETRO will use the index number as its representation of the file. ---------------------------------------------------------------------*/ /*--------------------------------------------------------------------- `files_get_handle()` returns a file handle, or 0 if there are no available handle slots in the array. ---------------------------------------------------------------------*/ CELL files_get_handle(NgaState *vm) { CELL i; for(i = 1; i < MAX_OPEN_FILES; i++) if (vm->OpenFileHandles[i] == 0) return i; return 0; } /*--------------------------------------------------------------------- `file_open()` opens a file. This pulls from the RETRO data stack: - mode (number, TOS) - filename (string, NOS) Modes are: | Mode | Corresponds To | Description | | ---- | -------------- | -------------------- | | 0 | rb | Open for reading | | 1 | w | Open for writing | | 2 | a | Open for append | | 3 | rb+ | Open for read/update | The file name should be a NULL terminated string. This will attempt to open the requested file and will return a handle (index number into the `OpenFileHandles` array). ---------------------------------------------------------------------*/ void file_open(NgaState *vm) { CELL slot, mode, name; char *request; slot = files_get_handle(vm); mode = stack_pop(vm); name = stack_pop(vm); request = string_extract(vm, name); if (slot > 0) { if (mode == 0) vm->OpenFileHandles[slot] = fopen(request, "rb"); if (mode == 1) vm->OpenFileHandles[slot] = fopen(request, "w"); if (mode == 2) vm->OpenFileHandles[slot] = fopen(request, "a"); if (mode == 3) vm->OpenFileHandles[slot] = fopen(request, "rb+"); } if (vm->OpenFileHandles[slot] == NULL) { vm->OpenFileHandles[slot] = 0; slot = 0; } stack_push(vm, slot); } /*--------------------------------------------------------------------- `file_read()` reads a byte from a file. This takes a file pointer from the stack and pushes the character that was read to the stack. ---------------------------------------------------------------------*/ void file_read(NgaState *vm) { CELL c; CELL slot = stack_pop(vm); if (slot <= 0 || slot > MAX_OPEN_FILES || vm->OpenFileHandles[slot] == 0) { printf("\nERROR (nga/file_read): Invalid file handle\n"); exit(1); } c = fgetc(vm->OpenFileHandles[slot]); stack_push(vm, feof(vm->OpenFileHandles[slot]) ? 0 : c); } /*--------------------------------------------------------------------- `file_write()` writes a byte to a file. This takes a file pointer (TOS) and a byte (NOS) from the stack. It does not return any values on the stack. ---------------------------------------------------------------------*/ void file_write(NgaState *vm) { CELL slot, c, r; slot = stack_pop(vm); if (slot <= 0 || slot > MAX_OPEN_FILES || vm->OpenFileHandles[slot] == 0) { printf("\nERROR (nga/file_write): Invalid file handle\n"); exit(1); } c = stack_pop(vm); r = fputc(c, vm->OpenFileHandles[slot]); } /*--------------------------------------------------------------------- `file_close()` closes a file. This takes a file handle from the stack and does not return anything on the stack. ---------------------------------------------------------------------*/ void file_close(NgaState *vm) { CELL slot = stack_pop(vm); if (slot <= 0 || slot > MAX_OPEN_FILES || vm->OpenFileHandles[slot] == 0) { printf("\nERROR (nga/file_close): Invalid file handle\n"); exit(1); } fclose(vm->OpenFileHandles[slot]); vm->OpenFileHandles[slot] = 0; } /*--------------------------------------------------------------------- `file_get_position()` provides the current index into a file. This takes the file handle from the stack and returns the offset. ---------------------------------------------------------------------*/ void file_get_position(NgaState *vm) { CELL slot = stack_pop(vm); if (slot <= 0 || slot > MAX_OPEN_FILES || vm->OpenFileHandles[slot] == 0) { printf("\nERROR (nga/file_get_position): Invalid file handle\n"); exit(1); } stack_push(vm, (CELL) ftell(vm->OpenFileHandles[slot])); } /*--------------------------------------------------------------------- `file_set_position()` changes the current index into a file to the specified one. This takes a file handle (TOS) and new offset (NOS) from the stack. ---------------------------------------------------------------------*/ void file_set_position(NgaState *vm) { CELL slot, pos; slot = stack_pop(vm); pos = stack_pop(vm); if (slot <= 0 || slot > MAX_OPEN_FILES || vm->OpenFileHandles[slot] == 0) { printf("\nERROR (nga/file_set_position): Invalid file handle\n"); exit(1); } fseek(vm->OpenFileHandles[slot], pos, SEEK_SET); } /*--------------------------------------------------------------------- `file_get_size()` returns the size of a file, or 0 if empty. If the file is a directory, it returns -1. It takes a file handle from the stack. ---------------------------------------------------------------------*/ void file_get_size(NgaState *vm) { CELL slot, current, r, size; struct stat buffer; slot = stack_pop(vm); if (slot <= 0 || slot > MAX_OPEN_FILES || vm->OpenFileHandles[slot] == 0) { printf("\nERROR (nga/file_get_size): Invalid file handle\n"); exit(1); } fstat(fileno(vm->OpenFileHandles[slot]), &buffer); if (!S_ISDIR(buffer.st_mode)) { current = ftell(vm->OpenFileHandles[slot]); r = fseek(vm->OpenFileHandles[slot], 0, SEEK_END); size = ftell(vm->OpenFileHandles[slot]); fseek(vm->OpenFileHandles[slot], current, SEEK_SET); } else { r = -1; size = 0; } stack_push(vm, (r == 0) ? size : 0); } /*--------------------------------------------------------------------- `file_delete()` removes a file. This takes a file name (as a string) from the stack. ---------------------------------------------------------------------*/ void file_delete(NgaState *vm) { char *request; CELL name = stack_pop(vm); request = string_extract(vm, name); unlink(request); } /*--------------------------------------------------------------------- `file_flush()` flushes any pending writes to disk. This takes a file handle from the stack. ---------------------------------------------------------------------*/ void file_flush(NgaState *vm) { CELL slot; slot = stack_pop(vm); if (slot <= 0 || slot > MAX_OPEN_FILES || vm->OpenFileHandles[slot] == 0) { printf("\nERROR (nga/file_flush): Invalid file handle\n"); exit(1); } fflush(vm->OpenFileHandles[slot]); } char file_bytes[32769]; void file_read_bytes(NgaState *vm) { CELL slot = stack_pop(vm); CELL size = stack_pop(vm); CELL dest = stack_pop(vm); CELL z = fread((char *)file_bytes, 1, size, vm->OpenFileHandles[slot]); for (CELL i = 0; i < size; i++) { CELL x = file_bytes[i]; vm->memory[dest + i] = x; } stack_push(vm, z); } void file_write_bytes(NgaState *vm) { CELL slot = stack_pop(vm); CELL size = stack_pop(vm); CELL src = stack_pop(vm); for (CELL i = 0; i < size; i++) { char x = vm->memory[src + i]; file_bytes[i] = x; } CELL z = fwrite(&file_bytes, 1, size, vm->OpenFileHandles[slot]); stack_push(vm, z); } Handler FileActions[] = { file_open, file_close, file_read, file_write, file_get_position, file_set_position, file_get_size, file_delete, file_flush, file_read_bytes, file_write_bytes, }; void query_filesystem(NgaState *vm) { stack_push(vm, 1); stack_push(vm, 4); } void io_filesystem(NgaState *vm) { FileActions[stack_pop(vm)](vm); } /* Multi Core Support ------------------------------------------------ */ #ifdef ENABLE_MULTICORE /*--------------------------------------------------------------------- Copyright (c) 2008 - 2022, Charles Childers Portions are based on Ngaro, which was additionally copyright by the following: Copyright (c) 2009 - 2010, Luke Parrish Copyright (c) 2010, Marc Simpson Copyright (c) 2010, Jay Skeer Copyright (c) 2011, Kenneth Keating ---------------------------------------------------------------------*/ /* Multi Core Support ------------------------------------------------ */ #ifdef ENABLE_MULTICORE void init_core(NgaState *vm, CELL x) { int y; vm->cpu[x].sp = 0; vm->cpu[x].rp = 0; vm->cpu[x].ip = 0; vm->cpu[x].active = 0; vm->cpu[x].u = 0; for (y = 0; y < STACK_DEPTH; y++) { vm->cpu[x].data[y] = 0; }; for (y = 0; y < ADDRESSES; y++) { vm->cpu[x].address[y] = 0; }; for (y = 0; y < 24; y++) { vm->cpu[x].registers[y] = 0; }; } void start_core(NgaState *vm, CELL x, CELL ip) { vm->cpu[x].ip = ip; vm->cpu[x].rp = 1; vm->cpu[x].active = -1; } void pause_core(NgaState *vm, CELL x) { vm->cpu[x].active = 0; } void resume_core(NgaState *vm, CELL x) { vm->cpu[x].active = -1; } void switch_core(NgaState *vm) { vm->active += 1; if (vm->active >= CORES) { vm->active = 0; } if (!vm->cpu[vm->active].active) { switch_core(vm); } } void io_multicore(NgaState *vm) { int x, y, z; x = stack_pop(vm); switch(x) { case 0: y = stack_pop(vm); init_core(vm, y); break; case 1: y = stack_pop(vm); z = stack_pop(vm); start_core(vm, y, z); break; case 2: y = stack_pop(vm); pause_core(vm, y); break; case 3: pause_core(vm, vm->active); break; case 4: y = stack_pop(vm); resume_core(vm, y); break; case 5: y = stack_pop(vm); stack_push(vm, vm->cpu[vm->active].registers[y]); break; case 6: y = stack_pop(vm); z = stack_pop(vm); vm->cpu[vm->active].registers[y] = z; break; } } void query_multicore(NgaState *vm) { stack_push(vm, 0); stack_push(vm, 8000); /* device type 8000 */ } #endif #endif #ifdef ENABLE_FFI /*--------------------------------------------------------------------- Copyright (c) 2008 - 2022, Charles Childers Portions are based on Ngaro, which was additionally copyright by the following: Copyright (c) 2009 - 2010, Luke Parrish Copyright (c) 2010, Marc Simpson Copyright (c) 2010, Jay Skeer Copyright (c) 2011, Kenneth Keating ---------------------------------------------------------------------*/ #ifdef ENABLE_FFI #include typedef void (*External)(void *); void *handles[32]; External funcs[32000]; int nlibs, nffi; void open_library(NgaState *vm) { handles[nlibs] = dlopen(string_extract(vm, stack_pop(vm)), RTLD_LAZY); stack_push(vm, nlibs); nlibs++; } void map_symbol(NgaState *vm) { int h; h = stack_pop(vm); char *s = string_extract(vm, stack_pop(vm)); funcs[nffi] = dlsym(handles[h], s); stack_push(vm, nffi); nffi++; } void invoke(NgaState *vm) { funcs[stack_pop(vm)](vm); } void io_ffi(NgaState *vm) { switch (stack_pop(vm)) { case 0: open_library(vm); break; case 1: map_symbol(vm); break; case 2: invoke(vm); break; } } void query_ffi(NgaState *vm) { stack_push(vm, 0); stack_push(vm, 8100); /* device type 8100 */ } #endif #endif #ifdef ENABLE_FLOATS /*--------------------------------------------------------------------- Copyright (c) 2008 - 2022, Charles Childers Portions are based on Ngaro, which was additionally copyright by the following: Copyright (c) 2009 - 2010, Luke Parrish Copyright (c) 2010, Marc Simpson Copyright (c) 2010, Jay Skeer Copyright (c) 2011, Kenneth Keating ---------------------------------------------------------------------*/ #ifdef ENABLE_FLOATS #include /* Floating Point ---------------------------------------------------- */ void float_guard(NgaState *vm) { if (vm->fsp < 0 || vm->fsp > 255) { printf("\nERROR (nga/float_guard): Float Stack Limits Exceeded!\n"); printf("At %lld, fsp = %lld\n", (long long)vm->cpu[vm->active].ip, (long long)vm->fsp); exit(1); } if (vm->afsp < 0 || vm->afsp > 255) { printf("\nERROR (nga/float_guard): Alternate Float Stack Limits Exceeded!\n"); printf("At %lld, afsp = %lld\n", (long long)vm->cpu[vm->active].ip, (long long)vm->afsp); exit(1); } } /*--------------------------------------------------------------------- The first two functions push a float to the stack and pop a value off the stack. ---------------------------------------------------------------------*/ void float_push(NgaState *vm, double value) { vm->fsp++; float_guard(vm); vm->Floats[vm->fsp] = value; } double float_pop(NgaState *vm) { vm->fsp--; float_guard(vm); return vm->Floats[vm->fsp + 1]; } void float_to_alt(NgaState *vm) { vm->afsp++; float_guard(vm); vm->AFloats[vm->afsp] = float_pop(vm); } void float_from_alt(NgaState *vm) { float_push(vm, vm->AFloats[vm->afsp]); vm->afsp--; float_guard(vm); } /*--------------------------------------------------------------------- RETRO operates on 32-bit signed integer values. This function just pops a number from the data stack, casts it to a float, and pushes it to the float stack. ---------------------------------------------------------------------*/ void float_from_number(NgaState *vm) { float_push(vm, (double)stack_pop(vm)); } /*--------------------------------------------------------------------- To get a float from a string in the image, I provide this function. I cheat: using `atof()` takes care of the details, so I don't have to. ---------------------------------------------------------------------*/ void float_from_string(NgaState *vm) { float_push(vm, atof(string_extract(vm, stack_pop(vm)))); } /*--------------------------------------------------------------------- Converting a floating point into a string is slightly more work. Here I pass it off to `snprintf()` to deal with. ---------------------------------------------------------------------*/ void float_to_string(NgaState *vm) { snprintf(vm->string_data, 8192, "%f", float_pop(vm)); string_inject(vm, vm->string_data, stack_pop(vm)); } /*--------------------------------------------------------------------- Converting a floating point back into a standard number requires a little care due to the signed nature. This makes adjustments for the max & min value, and then casts (rounding) the float back to a normal number. ---------------------------------------------------------------------*/ void float_to_number(NgaState *vm) { double a = float_pop(vm); if (a > 2147483647) a = 2147483647; if (a < -2147483648) a = -2147483648; stack_push(vm, (CELL)round(a)); } void float_add(NgaState *vm) { double a = float_pop(vm); double b = float_pop(vm); float_push(vm, a+b); } void float_sub(NgaState *vm) { double a = float_pop(vm); double b = float_pop(vm); float_push(vm, b-a); } void float_mul(NgaState *vm) { double a = float_pop(vm); double b = float_pop(vm); float_push(vm, a*b); } void float_div(NgaState *vm) { double a = float_pop(vm); double b = float_pop(vm); float_push(vm, b/a); } void float_floor(NgaState *vm) { float_push(vm, floor(float_pop(vm))); } void float_ceil(NgaState *vm) { float_push(vm, ceil(float_pop(vm))); } void float_eq(NgaState *vm) { double a = float_pop(vm); double b = float_pop(vm); if (a == b) stack_push(vm, -1); else stack_push(vm, 0); } void float_neq(NgaState *vm) { double a = float_pop(vm); double b = float_pop(vm); if (a != b) stack_push(vm, -1); else stack_push(vm, 0); } void float_lt(NgaState *vm) { double a = float_pop(vm); double b = float_pop(vm); if (b < a) stack_push(vm, -1); else stack_push(vm, 0); } void float_gt(NgaState *vm) { double a = float_pop(vm); double b = float_pop(vm); if (b > a) stack_push(vm, -1); else stack_push(vm, 0); } void float_depth(NgaState *vm) { stack_push(vm, vm->fsp); } void float_adepth(NgaState *vm) { stack_push(vm, vm->afsp); } void float_dup(NgaState *vm) { double a = float_pop(vm); float_push(vm, a); float_push(vm, a); } void float_drop(NgaState *vm) { float_pop(vm); } void float_swap(NgaState *vm) { double a = float_pop(vm); double b = float_pop(vm); float_push(vm, a); float_push(vm, b); } void float_log(NgaState *vm) { double a = float_pop(vm); double b = float_pop(vm); float_push(vm, log(b) / log(a)); } void float_sqrt(NgaState *vm) { float_push(vm, sqrt(float_pop(vm))); } void float_pow(NgaState *vm) { double a = float_pop(vm); double b = float_pop(vm); float_push(vm, pow(b, a)); } void float_sin(NgaState *vm) { float_push(vm, sin(float_pop(vm))); } void float_cos(NgaState *vm) { float_push(vm, cos(float_pop(vm))); } void float_tan(NgaState *vm) { float_push(vm, tan(float_pop(vm))); } void float_asin(NgaState *vm) { float_push(vm, asin(float_pop(vm))); } void float_acos(NgaState *vm) { float_push(vm, acos(float_pop(vm))); } void float_atan(NgaState *vm) { float_push(vm, atan(float_pop(vm))); } /*--------------------------------------------------------------------- With this finally done, I implement the FPU instructions. ---------------------------------------------------------------------*/ Handler FloatHandlers[] = { float_from_number, float_from_string, float_to_number, float_to_string, float_add, float_sub, float_mul, float_div, float_floor, float_ceil, float_sqrt, float_eq, float_neq, float_lt, float_gt, float_depth, float_dup, float_drop, float_swap, float_log, float_pow, float_sin, float_tan, float_cos, float_asin, float_acos, float_atan, float_to_alt, float_from_alt, float_adepth, }; void query_floatingpoint(NgaState *vm) { stack_push(vm, 1); stack_push(vm, 2); } void io_floatingpoint(NgaState *vm) { FloatHandlers[stack_pop(vm)](vm); } #endif #endif #ifdef ENABLE_CLOCK /*--------------------------------------------------------------------- Copyright (c) 2008 - 2022, Charles Childers Portions are based on Ngaro, which was additionally copyright by the following: Copyright (c) 2009 - 2010, Luke Parrish Copyright (c) 2010, Marc Simpson Copyright (c) 2010, Jay Skeer Copyright (c) 2011, Kenneth Keating ---------------------------------------------------------------------*/ /* Time and Date Functions --------------------------------------------*/ #ifdef ENABLE_CLOCK void clock_time(NgaState *vm) { stack_push(vm, (CELL)time(NULL)); } void clock_day(NgaState *vm) { time_t t = time(NULL); stack_push(vm, (CELL)localtime(&t)->tm_mday); } void clock_month(NgaState *vm) { time_t t = time(NULL); stack_push(vm, (CELL)localtime(&t)->tm_mon + 1); } void clock_year(NgaState *vm) { time_t t = time(NULL); stack_push(vm, (CELL)localtime(&t)->tm_year + 1900); } void clock_hour(NgaState *vm) { time_t t = time(NULL); stack_push(vm, (CELL)localtime(&t)->tm_hour); } void clock_minute(NgaState *vm) { time_t t = time(NULL); stack_push(vm, (CELL)localtime(&t)->tm_min); } void clock_second(NgaState *vm) { time_t t = time(NULL); stack_push(vm, (CELL)localtime(&t)->tm_sec); } void clock_day_utc(NgaState *vm) { time_t t = time(NULL); stack_push(vm, (CELL)gmtime(&t)->tm_mday); } void clock_month_utc(NgaState *vm) { time_t t = time(NULL); stack_push(vm, (CELL)gmtime(&t)->tm_mon + 1); } void clock_year_utc(NgaState *vm) { time_t t = time(NULL); stack_push(vm, (CELL)gmtime(&t)->tm_year + 1900); } void clock_hour_utc(NgaState *vm) { time_t t = time(NULL); stack_push(vm, (CELL)gmtime(&t)->tm_hour); } void clock_minute_utc(NgaState *vm) { time_t t = time(NULL); stack_push(vm, (CELL)gmtime(&t)->tm_min); } void clock_second_utc(NgaState *vm) { time_t t = time(NULL); stack_push(vm, (CELL)gmtime(&t)->tm_sec); } Handler ClockActions[] = { clock_time, clock_day, clock_month, clock_year, clock_hour, clock_minute, clock_second, clock_day_utc, clock_month_utc, clock_year_utc, clock_hour_utc, clock_minute_utc, clock_second_utc }; void query_clock(NgaState *vm) { stack_push(vm, 0); stack_push(vm, 5); } void io_clock(NgaState *vm) { ClockActions[stack_pop(vm)](vm); } #endif #endif #ifdef ENABLE_RNG /*--------------------------------------------------------------------- Copyright (c) 2008 - 2022, Charles Childers Portions are based on Ngaro, which was additionally copyright by the following: Copyright (c) 2009 - 2010, Luke Parrish Copyright (c) 2010, Marc Simpson Copyright (c) 2010, Jay Skeer Copyright (c) 2011, Kenneth Keating ---------------------------------------------------------------------*/ /* Random Number Generator --------------------------------------------*/ #ifdef ENABLE_RNG void io_rng(NgaState *vm) { int64_t r = 0; char buffer[8]; int i; ssize_t ignore; int fd = open("/dev/urandom", O_RDONLY); ignore = read(fd, buffer, 8); close(fd); for(i = 0; i < 8; ++i) { r = r << 8; r += ((int64_t)buffer[i] & 0xFF); } #ifndef BIT64 stack_push(vm, (CELL)abs((CELL)r)); #else stack_push(vm, (CELL)llabs((CELL)r)); #endif } void query_rng(NgaState *vm) { stack_push(vm, 0); stack_push(vm, 10); } #endif #endif #ifdef ENABLE_SOCKETS /*--------------------------------------------------------------------- Copyright (c) 2008 - 2022, Charles Childers Portions are based on Ngaro, which was additionally copyright by the following: Copyright (c) 2009 - 2010, Luke Parrish Copyright (c) 2010, Marc Simpson Copyright (c) 2010, Jay Skeer Copyright (c) 2011, Kenneth Keating ---------------------------------------------------------------------*/ #ifdef ENABLE_SOCKETS #include #include #include #include /*--------------------------------------------------------------------- BSD Sockets ---------------------------------------------------------------------*/ int SocketID[16]; struct sockaddr_in Sockets[16]; struct addrinfo hints, *res; void socket_getaddrinfo(NgaState *vm) { char host[1025], port[6]; strlcpy(port, string_extract(vm, stack_pop(vm)), 5); strlcpy(host, string_extract(vm, stack_pop(vm)), 1024); getaddrinfo(host, port, &hints, &res); } void socket_get_host(NgaState *vm) { struct hostent *hp; struct in_addr **addr_list; hp = gethostbyname(string_extract(vm, stack_pop(vm))); if (hp == NULL) { vm->memory[stack_pop(vm)] = 0; return; } addr_list = (struct in_addr **)hp->h_addr_list; string_inject(vm, inet_ntoa(*addr_list[0]), stack_pop(vm)); } void socket_create(NgaState *vm) { int i; int sock = socket(PF_INET, SOCK_STREAM, 0); for (i = 0; i < 16; i++) { if (SocketID[i] == 0 && sock != 0) { SocketID[i] = sock; stack_push(vm, (CELL)i); sock = 0; } } } void socket_bind(NgaState *vm) { int sock, port; memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; sock = stack_pop(vm); port = stack_pop(vm); getaddrinfo(NULL, string_extract(vm, port), &hints, &res); stack_push(vm, (CELL) bind(SocketID[sock], res->ai_addr, res->ai_addrlen)); stack_push(vm, errno); } void socket_listen(NgaState *vm) { int sock = stack_pop(vm); int backlog = stack_pop(vm); stack_push(vm, listen(SocketID[sock], backlog)); stack_push(vm, errno); } void socket_accept(NgaState *vm) { int i; int sock = stack_pop(vm); struct sockaddr_storage their_addr; socklen_t addr_size = sizeof their_addr; int new_fd = accept(SocketID[sock], (struct sockaddr *)&their_addr, &addr_size); for (i = 0; i < 16; i++) { if (SocketID[i] == 0 && new_fd != 0) { SocketID[i] = new_fd; stack_push(vm, (CELL)i); new_fd = 0; } } stack_push(vm, errno); } void socket_connect(NgaState *vm) { stack_push(vm, (CELL)connect(SocketID[stack_pop(vm)], res->ai_addr, res->ai_addrlen)); stack_push(vm, errno); } void socket_send(NgaState *vm) { int sock = stack_pop(vm); char *buf = string_extract(vm, stack_pop(vm)); stack_push(vm, send(SocketID[sock], buf, strlen(buf), 0)); stack_push(vm, errno); } void socket_recv(NgaState *vm) { char buf[8193]; int sock = stack_pop(vm); int limit = stack_pop(vm); int dest = stack_pop(vm); int len = recv(SocketID[sock], buf, limit, 0); if (len > 0) buf[len] = '\0'; if (len > 0) string_inject(vm, buf, dest); stack_push(vm, len); stack_push(vm, errno); } void socket_close(NgaState *vm) { int sock = stack_pop(vm); close(SocketID[sock]); SocketID[sock] = 0; } Handler SocketActions[] = { socket_get_host, socket_create, socket_bind, socket_listen, socket_accept, socket_connect, socket_send, socket_recv, socket_close, socket_getaddrinfo }; void io_socket(NgaState *vm) { SocketActions[stack_pop(vm)](vm); } void query_socket(NgaState *vm) { stack_push(vm, 0); stack_push(vm, 7); } #endif #endif #ifdef ENABLE_UNIX /*--------------------------------------------------------------------- Copyright (c) 2008 - 2022, Charles Childers Portions are based on Ngaro, which was additionally copyright by the following: Copyright (c) 2009 - 2010, Luke Parrish Copyright (c) 2010, Marc Simpson Copyright (c) 2010, Jay Skeer Copyright (c) 2011, Kenneth Keating ---------------------------------------------------------------------*/ #ifdef ENABLE_UNIX #include #include /*--------------------------------------------------------------------- `unix_open_pipe()` is like `file_open()`, but for pipes. This pulls from the data stack: - mode (number, TOS) - executable (string, NOS) Modes are: | Mode | Corresponds To | Description | | ---- | -------------- | -------------------- | | 0 | r | Open for reading | | 1 | w | Open for writing | | 3 | r+ | Open for read/update | The file name should be a NULL terminated string. This will attempt to open the requested file and will return a handle (index number into the `OpenFileHandles` array). Once opened, you can use the standard file words to read/write to the process. ---------------------------------------------------------------------*/ void unix_open_pipe(NgaState *vm) { CELL slot, mode, name; char *request; slot = files_get_handle(vm); mode = stack_pop(vm); name = stack_pop(vm); request = string_extract(vm, name); if (slot > 0) { if (mode == 0) vm->OpenFileHandles[slot] = popen(request, "r"); if (mode == 1) vm->OpenFileHandles[slot] = popen(request, "w"); if (mode == 3) vm->OpenFileHandles[slot] = popen(request, "r+"); } if (vm->OpenFileHandles[slot] == NULL) { vm->OpenFileHandles[slot] = 0; slot = 0; } stack_push(vm, slot); } void unix_close_pipe(NgaState *vm) { pclose(vm->OpenFileHandles[TOS]); vm->OpenFileHandles[TOS] = 0; stack_pop(vm); } void unix_system(NgaState *vm) { int ignore = 0; ignore = system(string_extract(vm, stack_pop(vm))); } void unix_fork(NgaState *vm) { stack_push(vm, fork()); } void unix_run_external(NgaState *vm) { char *line, *args[128]; int i, status; pid_t pid; char **argv = args; line = string_extract(vm, stack_pop(vm)); for(i = 0; i < 128; i++) args[i] = 0; while (*line != '\0') { while (*line == ' ' || *line == '\t' || *line == '\n') *line++ = '\0'; *argv++ = line; while (*line != '\0' && *line != ' ' && *line != '\t' && *line != '\n') line++; } if ((pid = fork()) < 0) { printf("*** ERROR: forking child process failed\n"); exit(1); } else if (pid == 0) { int e = execvp(*args, args); if (e < 0) { printf("*** ERROR: exec failed with %d\n", e); exit(1); } } else { while (wait(&status) != pid) ; } } /*--------------------------------------------------------------------- UNIX provides `execl` to execute a file, with various forms for arguments provided. RRE wraps this in several functions, one for each number of passed arguments. See the Glossary for details on what each takes from the stack. Each of these will return the error code if the execution fails. ---------------------------------------------------------------------*/ void unix_exec0(NgaState *vm) { char path[1025]; strlcpy(path, string_extract(vm, stack_pop(vm)), 1024); execl(path, path, (char *)0); stack_push(vm, errno); } void unix_exec1(NgaState *vm) { char path[1025]; char arg0[1025]; strlcpy(arg0, string_extract(vm, stack_pop(vm)), 1024); strlcpy(path, string_extract(vm, stack_pop(vm)), 1024); execl(path, path, arg0, (char *)0); stack_push(vm, errno); } void unix_exec2(NgaState *vm) { char path[1025]; char arg0[1025], arg1[1025]; strlcpy(arg1, string_extract(vm, stack_pop(vm)), 1024); strlcpy(arg0, string_extract(vm, stack_pop(vm)), 1024); strlcpy(path, string_extract(vm, stack_pop(vm)), 1024); execl(path, path, arg0, arg1, (char *)0); stack_push(vm, errno); } void unix_exec3(NgaState *vm) { char path[1025]; char arg0[1025], arg1[1025], arg2[1025]; strlcpy(arg2, string_extract(vm, stack_pop(vm)), 1024); strlcpy(arg1, string_extract(vm, stack_pop(vm)), 1024); strlcpy(arg0, string_extract(vm, stack_pop(vm)), 1024); strlcpy(path, string_extract(vm, stack_pop(vm)), 1024); execl(path, path, arg0, arg1, arg2, (char *)0); stack_push(vm, errno); } void unix_exit(NgaState *vm) { exit(stack_pop(vm)); } void unix_getpid(NgaState *vm) { stack_push(vm, getpid()); } void unix_wait(NgaState *vm) { int a; stack_push(vm, wait(&a)); } void unix_kill(NgaState *vm) { CELL a; a = stack_pop(vm); kill(stack_pop(vm), a); } void unix_write(NgaState *vm) { CELL a, b, c; ssize_t ignore; c = stack_pop(vm); b = stack_pop(vm); a = stack_pop(vm); ignore = write(fileno(vm->OpenFileHandles[c]), string_extract(vm, a), b); } void unix_chdir(NgaState *vm) { int ignore; ignore = chdir(string_extract(vm, stack_pop(vm))); } void unix_getenv(NgaState *vm) { CELL a, b; a = stack_pop(vm); b = stack_pop(vm); string_inject(vm, getenv(string_extract(vm, b)), a); } void unix_putenv(NgaState *vm) { putenv(string_extract(vm, stack_pop(vm))); } void unix_sleep(NgaState *vm) { sleep(stack_pop(vm)); } Handler UnixActions[] = { unix_system, unix_fork, unix_exec0, unix_exec1, unix_exec2, unix_exec3, unix_exit, unix_getpid, unix_wait, unix_kill, unix_open_pipe, unix_close_pipe, unix_write, unix_chdir, unix_getenv, unix_putenv, unix_sleep, unix_run_external }; void query_unix(NgaState *vm) { stack_push(vm, 3); stack_push(vm, 8); } void io_unix(NgaState *vm) { UnixActions[stack_pop(vm)](vm); } #endif #endif /*--------------------------------------------------------------------- Now on to I/O and extensions! ---------------------------------------------------------------------*/ #ifdef USE_UTF32 void display_utf8(const unsigned char* utf8_bytes, int num_bytes) { if (write(STDOUT_FILENO, utf8_bytes, num_bytes) == -1) { perror("Error writing to /dev/stdout"); } } void utf32_to_utf8(uint32_t utf32_char, unsigned char* utf8_bytes, int* num_bytes) { if (utf32_char < 0x80) { utf8_bytes[0] = (unsigned char)utf32_char; *num_bytes = 1; } else if (utf32_char < 0x800) { utf8_bytes[0] = (unsigned char)(0xC0 | (utf32_char >> 6)); utf8_bytes[1] = (unsigned char)(0x80 | (utf32_char & 0x3F)); *num_bytes = 2; } else if (utf32_char < 0x10000) { utf8_bytes[0] = (unsigned char)(0xE0 | (utf32_char >> 12)); utf8_bytes[1] = (unsigned char)(0x80 | ((utf32_char >> 6) & 0x3F)); utf8_bytes[2] = (unsigned char)(0x80 | (utf32_char & 0x3F)); *num_bytes = 3; } else if (utf32_char < 0x110000) { utf8_bytes[0] = (unsigned char)(0xF0 | (utf32_char >> 18)); utf8_bytes[1] = (unsigned char)(0x80 | ((utf32_char >> 12) & 0x3F)); utf8_bytes[2] = (unsigned char)(0x80 | ((utf32_char >> 6) & 0x3F)); utf8_bytes[3] = (unsigned char)(0x80 | (utf32_char & 0x3F)); *num_bytes = 4; } else { *num_bytes = 0; } } #endif void io_output(NgaState *vm) { #ifdef USE_UTF32 unsigned char utf8_bytes[4]; int num_bytes; utf32_to_utf8(stack_pop(vm), utf8_bytes, &num_bytes); display_utf8(utf8_bytes, num_bytes); #else putc(stack_pop(vm), stdout); #endif fflush(stdout); } void query_output(NgaState *vm) { stack_push(vm, 0); stack_push(vm, 0); } /*=====================================================================*/ #ifdef USE_UTF32 int read_character(int from) { unsigned char utf8_bytes[4] = { 0 }; int utf32_char, i, num_bytes; if (read(from, &utf8_bytes[0], 1) != 1) { return 0; } if ((utf8_bytes[0] & 0x80) == 0x00) { num_bytes = 1; } else if ((utf8_bytes[0] & 0xE0) == 0xC0) { num_bytes = 2; } else if ((utf8_bytes[0] & 0xF0) == 0xE0) { num_bytes = 3; } else if ((utf8_bytes[0] & 0xF8) == 0xF0) { num_bytes = 4; } else { return 0; } for (i = 1; i < num_bytes; i++) { if (read(from, &utf8_bytes[i], 1) != 1) { return 0; } } if (num_bytes == 1) { utf32_char = utf8_bytes[0]; } else if (num_bytes == 2) { utf32_char = ((uint32_t)(utf8_bytes[0] & 0x1F) << 6) | (utf8_bytes[1] & 0x3F); } else if (num_bytes == 3) { utf32_char = ((uint32_t)(utf8_bytes[0] & 0x0F) << 12) | ((uint32_t)(utf8_bytes[1] & 0x3F) << 6) | (utf8_bytes[2] & 0x3F); } else if (num_bytes == 4) { utf32_char = ((uint32_t)(utf8_bytes[0] & 0x07) << 18) | ((uint32_t)(utf8_bytes[1] & 0x3F) << 12) | ((uint32_t)(utf8_bytes[2] & 0x3F) << 6) | (utf8_bytes[3] & 0x3F); } else { return 0; } return utf32_char; } int fread_character(FILE *from) { unsigned char utf8_bytes[4] = { 0 }; int utf32_char, i, num_bytes; if (fread(&utf8_bytes[0], 1, 1, from) != 1) { return 0; } if ((utf8_bytes[0] & 0x80) == 0x00) { num_bytes = 1; } else if ((utf8_bytes[0] & 0xE0) == 0xC0) { num_bytes = 2; } else if ((utf8_bytes[0] & 0xF0) == 0xE0) { num_bytes = 3; } else if ((utf8_bytes[0] & 0xF8) == 0xF0) { num_bytes = 4; } else { return 0; } for (i = 1; i < num_bytes; i++) { if (fread(&utf8_bytes[i], 1, 1, from) != 1) { return 0; } } if (num_bytes == 1) { utf32_char = utf8_bytes[0]; } else if (num_bytes == 2) { utf32_char = ((uint32_t)(utf8_bytes[0] & 0x1F) << 6) | (utf8_bytes[1] & 0x3F); } else if (num_bytes == 3) { utf32_char = ((uint32_t)(utf8_bytes[0] & 0x0F) << 12) | ((uint32_t)(utf8_bytes[1] & 0x3F) << 6) | (utf8_bytes[2] & 0x3F); } else if (num_bytes == 4) { utf32_char = ((uint32_t)(utf8_bytes[0] & 0x07) << 18) | ((uint32_t)(utf8_bytes[1] & 0x3F) << 12) | ((uint32_t)(utf8_bytes[2] & 0x3F) << 6) | (utf8_bytes[3] & 0x3F); } else { return 0; } return utf32_char; } #endif void io_keyboard(NgaState *vm) { #ifdef USE_UTF32 stack_push(vm, read_character(STDIN_FILENO)); #else stack_push(vm, getc(stdin)); #endif if (TOS == 127) TOS = 8; } void query_keyboard(NgaState *vm) { stack_push(vm, 0); stack_push(vm, 1); } /*=====================================================================*/ #ifdef ENABLE_UNSIGNED void io_unsigned(NgaState *vm) { int x, y, z; long c; switch (stack_pop(vm)) { case 0: vm->cpu[vm->active].u = 1; break; case 1: c = 0; z = stack_pop(vm); y = stack_pop(vm); x = stack_pop(vm); if (vm->cpu[vm->active].u != 0) { c = (unsigned)x * (unsigned)y; stack_push(vm, (unsigned)c % (unsigned)z); stack_push(vm, (unsigned)c / (unsigned)z); } else { c = x * y; stack_push(vm, c % z); stack_push(vm, c / z); } vm->cpu[vm->active].u = 0; break; } } void query_unsigned(NgaState *vm) { stack_push(vm, 0); stack_push(vm, 8101); } #endif /*=====================================================================*/ void io_image(NgaState *vm) { FILE *fp; char *f = string_extract(vm, stack_pop(vm)); if ((fp = fopen(f, "wb")) == NULL) { printf("\nERROR (nga/io_image): Unable to save the image: %s!\n", f); exit(2); } fwrite(vm->memory, sizeof(CELL), vm->memory[3] + 1, fp); fclose(fp); } void query_image(NgaState *vm) { stack_push(vm, 0); stack_push(vm, 1000); } /*=====================================================================*/ /*--------------------------------------------------------------------- Scripting Support ---------------------------------------------------------------------*/ void scripting_arg(NgaState *vm) { CELL a, b; a = stack_pop(vm); b = stack_pop(vm); stack_push(vm, string_inject(vm, vm->sys_argv[a + 2], b)); } void scripting_arg_count(NgaState *vm) { stack_push(vm, vm->sys_argc - 2); } void scripting_include(NgaState *vm) { include_file(vm, string_extract(vm, stack_pop(vm)), 0); } void scripting_name(NgaState *vm) { stack_push(vm, string_inject(vm, vm->sys_argv[1], stack_pop(vm))); } /* addeded in scripting i/o device, revision 1 */ void scripting_source(NgaState *vm) { stack_push(vm, string_inject(vm, vm->scripting_sources[vm->current_source], stack_pop(vm))); } void scripting_line(NgaState *vm) { stack_push(vm, vm->currentLine); } void scripting_ignore_to_eol(NgaState *vm) { vm->ignoreToEOL = -1; } void scripting_ignore_to_eof(NgaState *vm) { vm->ignoreToEOF = -1; } void scripting_abort(NgaState *vm) { scripting_ignore_to_eol(vm); scripting_ignore_to_eof(vm); vm->perform_abort = -1; } void carry_out_abort(NgaState *vm) { vm->cpu[vm->active].ip = IMAGE_SIZE + 1; vm->cpu[vm->active].rp = 0; vm->cpu[vm->active].sp = 0; #ifdef ENABLE_FLOATS vm->fsp = 0; vm->afsp = 0; #endif if (vm->current_source > 0) { scripting_abort(vm); return; } vm->perform_abort = 0; vm->current_source = 0; } void scripting_line_text(NgaState *vm) { CELL target = stack_pop(vm); string_inject(vm, vm->line, target); } Handler ScriptingActions[] = { scripting_arg_count, scripting_arg, scripting_include, scripting_name, scripting_source, scripting_line, scripting_ignore_to_eol, scripting_ignore_to_eof, scripting_abort, scripting_line_text }; void query_scripting(NgaState *vm) { stack_push(vm, 2); stack_push(vm, 9); } void io_scripting(NgaState *vm) { ScriptingActions[stack_pop(vm)](vm); } /*=====================================================================*/ /*--------------------------------------------------------------------- With these out of the way, I implement `execute`, which takes an address and runs the code at it. This has a couple of interesting bits. This will also exit if the address stack depth is zero (meaning that the word being run, and it's dependencies) are finished. ---------------------------------------------------------------------*/ void invalid_opcode(NgaState *vm, CELL opcode) { CELL a, i; printf("\nERROR (nga/execute): Invalid instruction!\n"); printf("At %lld, opcode %lld\n", (long long)vm->cpu[vm->active].ip, (long long)opcode); printf("Instructions: "); a = opcode; for (i = 0; i < 4; i++) { printf("%lldd ", (long long)a & 0xFF); a = a >> 8; } printf("\n"); exit(1); } void execute(NgaState *vm, CELL cell) { CELL token; CELL opcode; if (vm->cpu[vm->active].rp == 0) vm->cpu[vm->active].rp = 1; vm->cpu[vm->active].ip = cell; token = TIB; while (vm->cpu[vm->active].ip < IMAGE_SIZE) { if (vm->perform_abort == 0) { if (vm->cpu[vm->active].ip == vm->NotFound) { printf("\nERROR: Word Not Found: "); printf("`%s`\n\n", string_extract(vm, token)); } if (vm->cpu[vm->active].ip == vm->interpret) { token = TOS; } opcode = vm->memory[vm->cpu[vm->active].ip]; if (validate_opcode_bundle(opcode) != 0) { process_opcode_bundle(vm, opcode); } else { invalid_opcode(vm, opcode); } #ifndef ENABLE_ERROR if (vm->cpu[vm->active].sp < 0 || vm->cpu[vm->active].sp > STACK_DEPTH) { printf("\nERROR (nga/execute): Stack Limits Exceeded!\n"); printf("At %lld, opcode %lld. sp = %lld, core = %lld\n", (long long)vm->cpu[vm->active].ip, (long long)opcode, (long long)vm->cpu[vm->active].sp, (long long)vm->active); exit(1); } if (vm->cpu[vm->active].rp < 0 || vm->cpu[vm->active].rp > ADDRESSES) { printf("\nERROR (nga/execute): Address Stack Limits Exceeded!\n"); printf("At %lld, opcode %lld. rp = %lld\n", (long long)vm->cpu[vm->active].ip, (long long)opcode, (long long)vm->cpu[vm->active].rp); exit(1); } #endif vm->cpu[vm->active].ip++; #ifdef ENABLE_MULTICORE switch_core(vm); #endif if (vm->cpu[vm->active].rp == 0) vm->cpu[vm->active].ip = IMAGE_SIZE; } else { carry_out_abort(vm); } } } /*--------------------------------------------------------------------- RETRO's `interpret` word expects a token on the stack. This next function copies a token to the `TIB` (text input buffer) and then calls `interpret` to process it. ---------------------------------------------------------------------*/ void evaluate(NgaState *vm, char *s) { if (strlen(s) == 0) return; string_inject(vm, s, TIB); stack_push(vm, TIB); execute(vm, vm->interpret); } /*--------------------------------------------------------------------- `read_token` reads a token from the specified file. It will stop on a whitespace or newline. It also tries to handle backspaces, though the success of this depends on how your terminal is configured. ---------------------------------------------------------------------*/ int not_eol(int c) { return (c != 9) && (c != 10) && (c != 13) && (c != 32) && (c != EOF) && (c != 0); } void read_token(FILE *file, char *token_buffer) { #ifdef USE_UTF32 int ch = fread_character(file); #else int ch = getc(file); #endif int count = 0; while (not_eol(ch)) { if ((ch == 8 || ch == 127) && count > 0) { count--; } else { token_buffer[count++] = ch; } #ifdef USE_UTF32 ch = fread_character(file); #else ch = getc(file); #endif } token_buffer[count] = '\0'; } void skip_indent(FILE *fp) { int ch = getc(fp); while (ch == ' ') { ch = getc(fp); } ungetc(ch, fp); } /*--------------------------------------------------------------------- Display the Stack Contents ---------------------------------------------------------------------*/ void dump_stack(NgaState *vm) { CELL i; if (vm->cpu[vm->active].sp == 0) return; printf("\nStack: "); for (i = 1; i <= vm->cpu[vm->active].sp; i++) { if (i == vm->cpu[vm->active].sp) printf("[ TOS: %lld ]", (long long)vm->cpu[vm->active].data[i]); else printf("%lld ", (long long)vm->cpu[vm->active].data[i]); } printf("\n"); } void dump_astack(NgaState *vm) { CELL i; if (vm->cpu[vm->active].rp == 0) return; printf("\nAddress Stack: "); for (i = 1; i <= vm->cpu[vm->active].rp; i++) { if (i == vm->cpu[vm->active].rp) printf("[ TOS: %lld ]", (long long)vm->cpu[vm->active].address[i]); else printf("%lld ", (long long)vm->cpu[vm->active].address[i]); } printf("\n"); } /*--------------------------------------------------------------------- RRE is primarily intended to be used in a batch or scripting model. The `include_file()` function will be used to read the code in the file, evaluating it as encountered. I enforce a literate model, with code in fenced blocks. E.g., # This is a test Display "Hello, World!" ~~~ 'Hello,_World! puts nl ~~~ RRE will ignore anything outside the `~~~` blocks. To identify if the current token is the start or end of a block, I provide a `fenced()` function. ---------------------------------------------------------------------*/ /* Check to see if a line is a fence boundary. This will check code blocks in all cases, and test blocks if tests_enabled is set to a non-zero value. */ int fence_boundary(NgaState *vm, char *buffer, int tests_enabled) { int flag = 1; if (strcmp(buffer, vm->code_start) == 0) { flag = -1; } if (strcmp(buffer, vm->code_end) == 0) { flag = -1; } if (strcmp(buffer, vm->test_start) == 0) { if (vm->codeBlocks == 0) { vm->codeBlocks++; } } if (tests_enabled == 0) { return flag; } if (strcmp(buffer, vm->test_start) == 0) { flag = -1; } if (strcmp(buffer, vm->test_end) == 0) { flag = -1; } return flag; } /*--------------------------------------------------------------------- And now for the actual `include_file()` function. ---------------------------------------------------------------------*/ void read_line(NgaState *vm, FILE *file, char *token_buffer) { int ch = getc(file); int count = 0; token_buffer[0] = '\0'; while ((ch != 10) && (ch != 13) && (ch != EOF) && (ch != 0)) { token_buffer[count++] = ch; #ifdef USE_UTF32 ch = fread_character(file); #else ch = getc(file); #endif } token_buffer[count] = '\0'; } int count_tokens(char *line) { int count = 1; while (*line++) { if (isspace(line[0])) count++; } return count; } void include_file(NgaState *vm, char *fname, int run_tests) { int inBlock = 0; /* Tracks status of in/out of block */ int priorBlocks = 0; char source[64 * 1024]; /* Token buffer [about 64K] */ char fence[33]; /* Used with `fence_boundary()` */ CELL ReturnStack[ADDRESSES]; CELL arp, aip; long offset = 0; CELL at = 0; int tokens = 0; FILE *fp; /* Open the file. If not found, */ fp = fopen(fname, "r"); /* exit. */ if (fp == NULL) { printf("File `%s` not found. Exiting.\n", fname); exit(1); } priorBlocks = vm->codeBlocks; vm->codeBlocks = 0; arp = vm->cpu[vm->active].rp; aip = vm->cpu[vm->active].ip; for(vm->cpu[vm->active].rp = 0; vm->cpu[vm->active].rp <= arp; vm->cpu[vm->active].rp++) ReturnStack[vm->cpu[vm->active].rp] = vm->cpu[vm->active].address[vm->cpu[vm->active].rp]; vm->cpu[vm->active].rp = 0; vm->current_source++; strlcpy(vm->scripting_sources[vm->current_source], fname, 8192); vm->ignoreToEOF = 0; while (!feof(fp) && (vm->ignoreToEOF == 0)) { /* Loop through the file */ vm->ignoreToEOL = 0; offset = ftell(fp); read_line(vm, fp, vm->line); at++; fseek(fp, offset, SEEK_SET); skip_indent(fp); tokens = count_tokens(vm->line); while (tokens > 0 && vm->ignoreToEOL == 0) { tokens--; read_token(fp, source); strlcpy(fence, source, 32); /* Copy the first three characters */ if (fence_boundary(vm, fence, run_tests) == -1) { if (inBlock == 0) { inBlock = 1; vm->codeBlocks++; } else { inBlock = 0; } } else { if (inBlock == 1) { vm->currentLine = at; evaluate(vm, source); vm->currentLine = at; } } } if (vm->ignoreToEOL == -1) { read_line(vm, fp, vm->line); } } vm->current_source--; vm->ignoreToEOF = 0; fclose(fp); if (vm->perform_abort == -1) { carry_out_abort(vm); } for(vm->cpu[vm->active].rp = 0; vm->cpu[vm->active].rp <= arp; vm->cpu[vm->active].rp++) vm->cpu[vm->active].address[vm->cpu[vm->active].rp] = ReturnStack[vm->cpu[vm->active].rp]; vm->cpu[vm->active].rp = arp; vm->cpu[vm->active].ip = aip; if (vm->codeBlocks == 0) { printf("warning: no code or test blocks found!\n"); printf(" filename: %s\n", fname); printf(" see http://unu.retroforth.org for a brief summary of\n"); printf(" the unu code format used by retro\n"); } vm->codeBlocks = priorBlocks; } /*--------------------------------------------------------------------- `initialize()` sets up Nga and loads the image (from the array in `image.c`) to memory. ---------------------------------------------------------------------*/ void initialize(NgaState *vm) { prepare_vm(vm); load_embedded_image(vm); } /*--------------------------------------------------------------------- `arg_is()` exists to aid in readability. It compares the first actual command line argument to a string and returns a boolean flag. ---------------------------------------------------------------------*/ int arg_is(char *argv, char *t) { return strcmp(argv, t) == 0; } void help(char *exename) { printf("Scripting Usage: %s filename\n\n", exename); printf("Interactive Usage: %s [-h] [-i] [-f filename] [-t filename]\n\n", exename); printf("Valid Arguments:\n\n"); printf(" -h\n"); printf(" Display this help text\n"); printf(" -i\n"); printf(" Launches in interactive mode\n"); printf(" -f filename\n"); printf(" Run the contents of the specified file\n"); printf(" -u filename\n"); printf(" Use the image in the specified file instead of the internal one\n"); printf(" -r filename\n"); printf(" Use the image in the specified file instead of the internal one and run the code in it\n"); printf(" -t filename\n"); printf(" Run the contents of the specified file, including any tests (in ``` blocks)\n\n"); } /* Signal Handler -----------------------------------------------------*/ #ifdef ENABLE_SIGNALS static void sig_handler(int _) { printf("\nCaught: %d\n", _); exit(1); } #endif /* Main Entry Point ---------------------------------------------------*/ enum flags { FLAG_HELP, FLAG_INTERACTIVE, }; int main(int argc, char **argv) { int i; int modes[16]; NgaState *vm = calloc(sizeof(NgaState), sizeof(char)); #ifdef ENABLE_SIGNALS signal(SIGHUP, sig_handler); signal(SIGINT, sig_handler); signal(SIGILL, sig_handler); signal(SIGBUS, sig_handler); signal(SIGFPE, sig_handler); #endif initialize(vm); /* Initialize Nga & image */ vm->interactive = 0; register_device(vm, io_output, query_output); register_device(vm, io_keyboard, query_keyboard); register_device(vm, io_filesystem, query_filesystem); register_device(vm, io_image, query_image); #ifdef ENABLE_FLOATS register_device(vm, io_floatingpoint, query_floatingpoint); #endif #ifdef ENABLE_UNIX register_device(vm, io_unix, query_unix); #endif #ifdef ENABLE_MALLOC #ifdef BIT64 register_device(vm, io_malloc, query_malloc); #endif #endif #ifdef ENABLE_BLOCKS register_device(vm, io_blocks, query_blocks); #endif #ifdef ENABLE_CLOCK register_device(vm, io_clock, query_clock); #endif register_device(vm, io_scripting, query_scripting); #ifdef ENABLE_RNG register_device(vm, io_rng, query_rng); #endif #ifdef ENABLE_SOCKETS register_device(vm, io_socket, query_socket); #endif #ifdef ENABLE_MULTICORE register_device(vm, io_multicore, query_multicore); #endif #ifdef ENABLE_FFI register_device(vm, io_ffi, query_ffi); nlibs = 0; nffi = 0; #endif #ifdef ENABLE_UNSIGNED register_device(vm, io_unsigned, query_unsigned); #endif #ifdef ENABLE_ERROR register_device(vm, io_error, query_error); #endif strcpy(vm->code_start, "~~~"); strcpy(vm->code_end, "~~~"); strcpy(vm->test_start, "```"); strcpy(vm->test_end, "```"); /* Setup variables related to the scripting device */ vm->currentLine = 0; /* Current Line # for script */ vm->current_source = 0; /* Current file being run */ vm->perform_abort = 0; /* Carry out abort procedure */ vm->sys_argc = argc; /* Point the global argc and */ vm->sys_argv = argv; /* argv to the actual ones */ strlcpy(vm->scripting_sources[0], "/dev/stdin", 8192); vm->ignoreToEOL = 0; vm->ignoreToEOF = 0; vm->codeBlocks = 0; if (argc >= 2 && argv[1][0] != '-') { update_rx(vm); include_file(vm, argv[1], 0); /* If no flags were passed, */ /* load the file specified, */ /* and exit */ if (vm->cpu[vm->active].sp >= 1) dump_stack(vm); exit(0); } /* Clear startup modes */ for (i = 0; i < 16; i++) modes[i] = 0; if (argc <= 1) modes[FLAG_INTERACTIVE] = 1; update_rx(vm); /* Process Arguments */ for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-h") == 0) { help(argv[0]); exit(0); } else if (strcmp(argv[i], "-i") == 0) { modes[FLAG_INTERACTIVE] = 1; vm->interactive = -1; } else if (strcmp(argv[i], "-f") == 0) { include_file(vm, argv[i + 1], 0); i++; } else if (strcmp(argv[i], "-u") == 0) { i++; load_image(vm, argv[i]); update_rx(vm); } else if (strcmp(argv[i], "-r") == 0) { i++; load_image(vm, argv[i]); modes[FLAG_INTERACTIVE] = 1; update_rx(vm); } else if (strcmp(argv[i], "-t") == 0) { include_file(vm, argv[i + 1], 1); i++; } else if (arg_is(argv[i], "--code-start") || arg_is(argv[i], "-cs")) { i++; strcpy(vm->code_start, argv[i]); } else if (arg_is(argv[i], "--code-end") || arg_is(argv[i], "-ce")) { i++; strcpy(vm->code_end, argv[i]); } else if (arg_is(argv[i], "--test-start") || arg_is(argv[i], "-ts")) { i++; strcpy(vm->test_start, argv[i]); } else if (arg_is(argv[i], "--test-end") || arg_is(argv[i], "-te")) { i++; strcpy(vm->test_end, argv[i]); } } /* Run the Listener (if interactive mode was set) */ if (modes[FLAG_INTERACTIVE] == 1) { execute(vm, 0); } /* Dump Stack */ if (vm->cpu[vm->active].sp >= 1) dump_stack(vm); free(vm); } /*=====================================================================*/ /*--------------------------------------------------------------------- Interfacing With The Image ---------------------------------------------------------------------*/ /*--------------------------------------------------------------------- Stack push/pop is easy. I could avoid these, but it aids in keeping the code readable, so it's worth the slight overhead. ---------------------------------------------------------------------*/ CELL stack_pop(NgaState *vm) { vm->cpu[vm->active].sp--; return vm->cpu[vm->active].data[vm->cpu[vm->active].sp + 1]; } void stack_push(NgaState *vm, CELL value) { vm->cpu[vm->active].sp++; vm->cpu[vm->active].data[vm->cpu[vm->active].sp] = value; } /*--------------------------------------------------------------------- Strings are next. RETRO uses C-style NULL terminated strings. So I can easily inject or extract a string. Injection iterates over the string, copying it into the image. This also takes care to ensure that the NULL terminator is added. ---------------------------------------------------------------------*/ CELL string_inject(NgaState *vm, char *str, CELL buffer) { CELL m, i; if (!str) { vm->memory[buffer] = 0; return 0; } m = strlen(str); i = 0; while (m > 0) { vm->memory[buffer + i] = (CELL)str[i]; vm->memory[buffer + i + 1] = 0; m--; i++; } return buffer; } /*--------------------------------------------------------------------- Extracting a string is similar, but I have to iterate over the VM memory instead of a C string and copy the charaters into a buffer. This uses a static buffer (`string_data`) as I prefer to avoid using `malloc()`. ---------------------------------------------------------------------*/ char *string_extract(NgaState *vm, CELL at) { CELL starting = at; CELL i = 0; while(vm->memory[starting] && i < 8192) vm->string_data[i++] = (char)vm->memory[starting++]; vm->string_data[i] = 0; return (char *)vm->string_data; } /*--------------------------------------------------------------------- This interface tracks a few words and variables in the image. These are: Dictionary - the latest dictionary header NotFound - called when a word is not found interpret - the heart of the interpreter/compiler I have to call this periodically, as the Dictionary will change as new words are defined, and the user might write a new error handler or interpreter. ---------------------------------------------------------------------*/ void update_rx(NgaState *vm) { vm->Dictionary = vm->memory[2]; vm->interpret = vm->memory[5]; vm->NotFound = vm->memory[6]; if (vm->memory[10] != 0) { execute(vm, vm->memory[10]); } } /*=====================================================================*/ void register_device(NgaState *vm, void *handler, void *query) { vm->IO_deviceHandlers[vm->devices] = handler; vm->IO_queryHandlers[vm->devices] = query; vm->devices++; } void load_embedded_image(NgaState *vm) { int i; for (i = 0; i < ngaImageCells; i++) vm->memory[i] = ngaImage[i]; } CELL load_image(NgaState *vm, char *imageFile) { FILE *fp; CELL imageSize = 0; long fileLen; if ((fp = fopen(imageFile, "rb")) != NULL) { /* Determine length (in cells) */ fseek(fp, 0, SEEK_END); fileLen = ftell(fp) / sizeof(CELL); if (fileLen > IMAGE_SIZE) { fclose(fp); printf("\nERROR (nga/ngaLoadImage): Image is larger than alloted space!\n"); exit(1); } rewind(fp); /* Read the file into memory */ imageSize = fread(vm->memory, sizeof(CELL), fileLen, fp); fclose(fp); } return imageSize; } void prepare_vm(NgaState *vm) { vm->active = 0; vm->cpu[vm->active].ip = vm->cpu[vm->active].sp = vm->cpu[vm->active].rp = vm->cpu[vm->active].u = 0; vm->cpu[vm->active].active = -1; for (vm->cpu[vm->active].ip = 0; vm->cpu[vm->active].ip < IMAGE_SIZE; vm->cpu[vm->active].ip++) vm->memory[vm->cpu[vm->active].ip] = 0; /* NO - nop instruction */ for (vm->cpu[vm->active].ip = 0; vm->cpu[vm->active].ip < STACK_DEPTH; vm->cpu[vm->active].ip++) vm->cpu[vm->active].data[vm->cpu[vm->active].ip] = 0; for (vm->cpu[vm->active].ip = 0; vm->cpu[vm->active].ip < ADDRESSES; vm->cpu[vm->active].ip++) vm->cpu[vm->active].address[vm->cpu[vm->active].ip] = 0; } void inst_no(NgaState *vm) { guard(vm, 0, 0, 0); } void inst_li(NgaState *vm) { guard(vm, 0, 1, 0); vm->cpu[vm->active].sp++; vm->cpu[vm->active].ip++; TOS = vm->memory[vm->cpu[vm->active].ip]; } void inst_du(NgaState *vm) { guard(vm, 1, 2, 0); vm->cpu[vm->active].sp++; vm->cpu[vm->active].data[vm->cpu[vm->active].sp] = NOS; } void inst_dr(NgaState *vm) { guard(vm, 1, 0, 0); vm->cpu[vm->active].data[vm->cpu[vm->active].sp] = 0; vm->cpu[vm->active].sp--; } void inst_sw(NgaState *vm) { guard(vm, 2, 2, 0); CELL a; a = TOS; TOS = NOS; NOS = a; } void inst_pu(NgaState *vm) { guard(vm, 1, 0, 1); vm->cpu[vm->active].rp++; TORS = TOS; inst_dr(vm); } void inst_po(NgaState *vm) { guard(vm, 0, 1, -1); vm->cpu[vm->active].sp++; TOS = TORS; vm->cpu[vm->active].rp--; } void inst_ju(NgaState *vm) { guard(vm, 1, 0, 0); vm->cpu[vm->active].ip = TOS - 1; inst_dr(vm); } void inst_ca(NgaState *vm) { guard(vm, 1, 0, 1); vm->cpu[vm->active].rp++; TORS = vm->cpu[vm->active].ip; vm->cpu[vm->active].ip = TOS - 1; inst_dr(vm); } void inst_cc(NgaState *vm) { guard(vm, 2, 0, 1); CELL a, b; a = TOS; inst_dr(vm); /* Target */ b = TOS; inst_dr(vm); /* Flag */ if (b != 0) { vm->cpu[vm->active].rp++; TORS = vm->cpu[vm->active].ip; vm->cpu[vm->active].ip = a - 1; } } void inst_re(NgaState *vm) { guard(vm, 0, 0, -1); vm->cpu[vm->active].ip = TORS; vm->cpu[vm->active].rp--; } void inst_eq(NgaState *vm) { guard(vm, 2, 1, 0); if (vm->cpu[vm->active].u != 0) { NOS = ((unsigned)NOS == (unsigned)TOS) ? -1 : 0; vm->cpu[vm->active].u = 0; } else { NOS = (NOS == TOS) ? -1 : 0; } inst_dr(vm); } void inst_ne(NgaState *vm) { guard(vm, 2, 1, 0); if (vm->cpu[vm->active].u != 0) { NOS = ((unsigned)NOS != (unsigned)TOS) ? -1 : 0; vm->cpu[vm->active].u = 0; } else { NOS = (NOS != TOS) ? -1 : 0; } inst_dr(vm); } void inst_lt(NgaState *vm) { guard(vm, 2, 1, 0); if (vm->cpu[vm->active].u != 0) { NOS = ((unsigned)NOS < (unsigned)TOS) ? -1 : 0; vm->cpu[vm->active].u = 0; } else { NOS = (NOS < TOS) ? -1 : 0; } inst_dr(vm); } void inst_gt(NgaState *vm) { guard(vm, 2, 1, 0); if (vm->cpu[vm->active].u != 0) { NOS = ((unsigned)NOS > (unsigned)TOS) ? -1 : 0; vm->cpu[vm->active].u = 0; } else { NOS = (NOS > TOS) ? -1 : 0; } inst_dr(vm); } void inst_fe(NgaState *vm) { guard(vm, 1, 1, 0); switch (TOS) { case -1: TOS = vm->cpu[vm->active].sp - 1; break; case -2: TOS = vm->cpu[vm->active].rp; break; case -3: TOS = IMAGE_SIZE; break; case -4: TOS = CELL_MIN; break; case -5: TOS = CELL_MAX; break; default: TOS = vm->memory[TOS]; break; } } void inst_st(NgaState *vm) { guard(vm, 2, 0, 0); vm->memory[TOS] = NOS; inst_dr(vm); inst_dr(vm); } void inst_ad(NgaState *vm) { guard(vm, 2, 1, 0); if (vm->cpu[vm->active].u != 0) { NOS = (unsigned)NOS + (unsigned)TOS; vm->cpu[vm->active].u = 0; } else { NOS += TOS; } inst_dr(vm); } void inst_su(NgaState *vm) { guard(vm, 2, 1, 0); if (vm->cpu[vm->active].u != 0) { NOS = (unsigned)NOS - (unsigned)TOS; vm->cpu[vm->active].u = 0; } else { NOS -= TOS; } inst_dr(vm); } void inst_mu(NgaState *vm) { guard(vm, 2, 1, 0); if (vm->cpu[vm->active].u != 0) { NOS = (unsigned)NOS * (unsigned)TOS; vm->cpu[vm->active].u = 0; } else { NOS *= TOS; } inst_dr(vm); } void inst_di(NgaState *vm) { guard(vm, 2, 2, 0); CELL a, b; a = TOS; b = NOS; if (b == 0) { #ifdef ENABLE_ERROR if (vm->ErrorHandlers[6] != 0) { } #endif } if (vm->cpu[vm->active].u != 0) { TOS = (unsigned)b / (unsigned)a; NOS = (unsigned)b % (unsigned)a; vm->cpu[vm->active].u = 0; } else { TOS = b / a; NOS = b % a; } } void inst_an(NgaState *vm) { guard(vm, 2, 1, 0); NOS = TOS & NOS; inst_dr(vm); } void inst_or(NgaState *vm) { guard(vm, 2, 1, 0); NOS = TOS | NOS; inst_dr(vm); } void inst_xo(NgaState *vm) { guard(vm, 2, 1, 0); NOS = TOS ^ NOS; inst_dr(vm); } void inst_sh(NgaState *vm) { guard(vm, 2, 1, 0); CELL y = TOS; CELL x = NOS; if (TOS < 0) NOS = NOS << (0 - TOS); else { if (vm->cpu[vm->active].u != 0) { NOS = (unsigned)x >> (unsigned)y; vm->cpu[vm->active].u = 0; } else { if (x < 0 && y > 0) NOS = x >> y | ~(~0U >> y); else NOS = x >> y; } } inst_dr(vm); } void inst_zr(NgaState *vm) { guard(vm, 1, 0, 0); if (TOS == 0) { inst_dr(vm); vm->cpu[vm->active].ip = TORS; vm->cpu[vm->active].rp--; } } void inst_ha(NgaState *vm) { guard(vm, 0, 0, 0); vm->cpu[vm->active].ip = IMAGE_SIZE; vm->cpu[vm->active].rp = 0; } void inst_ie(NgaState *vm) { guard(vm, 1, 1, 0); stack_push(vm, vm->devices); } void inst_iq(NgaState *vm) { guard(vm, 1, 1, 0); vm->IO_queryHandlers[stack_pop(vm)](vm); } void inst_ii(NgaState *vm) { guard(vm, 1, 0, 0); vm->IO_deviceHandlers[stack_pop(vm)](vm); } Handler instructions[] = { inst_no, inst_li, inst_du, inst_dr, inst_sw, inst_pu, inst_po, inst_ju, inst_ca, inst_cc, inst_re, inst_eq, inst_ne, inst_lt, inst_gt, inst_fe, inst_st, inst_ad, inst_su, inst_mu, inst_di, inst_an, inst_or, inst_xo, inst_sh, inst_zr, inst_ha, inst_ie, inst_iq, inst_ii }; void process_opcode(NgaState *vm, CELL opcode) { #ifdef FAST switch (opcode) { case 0: break; case 1: inst_li(vm); break; case 2: inst_du(vm); break; case 3: inst_dr(vm); break; case 4: inst_sw(vm); break; case 5: inst_pu(vm); break; case 6: inst_po(vm); break; case 7: inst_ju(vm); break; case 8: inst_ca(vm); break; case 9: inst_cc(vm); break; case 10: inst_re(vm); break; case 11: inst_eq(vm); break; case 12: inst_ne(vm); break; case 13: inst_lt(vm); break; case 14: inst_gt(vm); break; case 15: inst_fe(vm); break; case 16: inst_st(vm); break; case 17: inst_ad(vm); break; case 18: inst_su(vm); break; case 19: inst_mu(vm); break; case 20: inst_di(vm); break; case 21: inst_an(vm); break; case 22: inst_or(vm); break; case 23: inst_xo(vm); break; case 24: inst_sh(vm); break; case 25: inst_zr(vm); break; case 26: inst_ha(vm); break; case 27: inst_ie(vm); break; case 28: inst_iq(vm); break; case 29: inst_ii(vm); break; default: break; } #else if (opcode != 0) instructions[opcode](vm); #endif } int validate_opcode_bundle(CELL opcode) { CELL raw = opcode; CELL current; int valid = -1; int i; for (i = 0; i < 4; i++) { current = raw & 0xFF; if (!(current >= 0 && current <= 29)) valid = 0; raw = raw >> 8; } return valid; } void process_opcode_bundle(NgaState *vm, CELL opcode) { CELL raw = opcode; int i; for (i = 0; i < 4; i++) { process_opcode(vm, raw & 0xFF); raw = raw >> 8; } } #ifdef NEEDS_STRL /*--------------------------------------------------------------------- Copyright (c) 1998, 2015 Todd C. Miller Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. --------------------------------------------------------------------*/ size_t strlcat(char *dst, const char *src, size_t dsize) { const char *odst = dst; const char *osrc = src; size_t n = dsize; size_t dlen; /* Find the end of dst and adjust bytes left but don't go past end. */ while (n-- != 0 && *dst != '\0') dst++; dlen = dst - odst; n = dsize - dlen; if (n-- == 0) return(dlen + strlen(src)); while (*src != '\0') { if (n != 0) { *dst++ = *src; n--; } src++; } *dst = '\0'; return(dlen + (src - osrc)); /* count does not include NUL */ } size_t strlcpy(char *dst, const char *src, size_t dsize) { const char *osrc = src; size_t nleft = dsize; /* Copy as many bytes as will fit. */ if (nleft != 0) { while (--nleft != 0) { if ((*dst++ = *src++) == '\0') break; } } /* Not enough room in dst, add NUL and traverse rest of src. */ if (nleft == 0) { if (dsize != 0) *dst = '\0'; /* NUL-terminate dst */ while (*src++) ; } return(src - osrc - 1); /* count does not include NUL */ } #endif