/* Build with `cc -lm -O2 retro-unix.c -o retro` */ #define ENABLE_FLOATS #define ENABLE_FILES #define ENABLE_UNIX #define ENABLE_RNG #define ENABLE_CLOCK #define ENABLE_SCRIPTING #define BIT64 /************************************************************** _ __ _ _ _ __ ___| |_ _ __ ___ / _| ___ _ __| |_| |__ | '__/ _ \ __| '__/ _ \| |_ / _ \| '__| __| '_ \ | | | __/ |_| | | (_) | _| (_) | | | |_| | | | |_| \___|\__|_| \___/|_| \___/|_| \__|_| |_| for nga (c) Charles Childers, Luke Parrish, Marc Simpsonn, Jay Skeer, Kenneth Keating **************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include /************************************************************** _ __ _ _ _ __ ___| |_ _ __ ___ / _| ___ _ __| |_| |__ | '__/ _ \ __| '__/ _ \| |_ / _ \| '__| __| '_ \ | | | __/ |_| | | (_) | _| (_) | | | |_| | | | |_| \___|\__|_| \___/|_| \___/|_| \__|_| |_| for nga (c) Charles Childers, Luke Parrish, Marc Simpsonn, Jay Skeer, Kenneth Keating **************************************************************/ #ifndef MAKEFILE_CONFIG #define ENABLE_FLOATS #define ENABLE_FILES #define ENABLE_UNIX #define ENABLE_RNG #define ENABLE_CLOCK #define ENABLE_SCRIPTING /* #define ENABLE_SOCKETS */ #define ENABLE_SIGNALS #define ENABLE_MULTICORE /* #define ENABLE_FFI */ #define ENABLE_ERROR #define ENABLE_UNSIGNED #define ENABLE_MALLOC #define ENABLE_BLOCKS #define ENABLE_IOCTL #endif #ifdef ENABLE_MULTICORE #define CORES 8 #else #define CORES 1 #endif #if defined(_WIN32) || defined(_WIN64) #define NEEDS_STRL #endif #if defined(__APPLE__) && defined(__MACH__) && defined(NEEDS_STRL) #undef NEEDS_STRL #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 #ifdef BRANCH_PREDICTION /* The Compiler Magic Trick */ #define unlikely(x) __builtin_expect((x),0) #endif #define DEVICE_OUTPUT 0 #define DEVICE_KEYBOARD 1 #define DEVICE_FLOATS 2 #define DEVICE_FILES 4 #define DEVICE_BLOCKS 3 #define DEVICE_CLOCK 5 #define DEVICE_RESERVED6 6 #define DEVICE_SOCKET 7 #define DEVICE_UNIX 8 #define DEVICE_SCRIPTING 9 #define DEVICE_RNG 10 #define DEVICE_RESERVED11 11 #define DEVICE_RESERVED12 12 #define DEVICE_RESERVED13 13 #define DEVICE_IOCTL 14 #define DEVICE_MALLOC 15 #define DEVICE_IMAGE 1000 #define DEVICE_ERROR 1234 #define DEVICE_MULTICORE 8000 #define DEVICE_FFI 8100 #define DEVICE_UNSIGNED 8101 #define ACTIVE vm->cpu[vm->active] #define TIB vm->memory[7] #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 = 21062; CELL ngaImage[] = { 1793,11587,21024,21061,202409,417,389,1249,1535,0,11633,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,20331,17108737,3,2,524559,130, 2049,130,2049,130,524545,0,130,524545,0,130,2049,144,1048838,2,1642241,10,7,19872,8246457295145463473,167841793, 216,11,17826049,0,216,2,15,25,524546,18781,134287105,217,29,2305,218,459023,226,2049,4819,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,10968,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,98,108,101,0,46,114,101,116,114,111,0,0,111,0,95,102, 111,117,110,100,0,101,116,114,111,0,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, 12482,193454822,69,79,77,0,1,-3,15,10,1536,1560,168,12482,210709897370,100,101,112,116,104, 0,1,-1,15,10,1549,1576,168,12482,6953375454647,100,58,108,97,115,116,0,1,2,15, 10,1564,1595,168,12482,249883453713703409,100,58,108,97,115,116,46,120,116,0,2049,1576,2049,182, 15,10,1580,1619,168,12482,-3502687787217310053,100,58,108,97,115,116,46,99,108,97,115,115,0, 2049,1576,2049,184,15,10,1601,1642,168,12482,-4578080011420638202,100,58,108,97,115,116,46,110,97, 109,101,0,2049,1576,2049,190,10,1625,1660,168,12482,229481143079314,114,101,99,108,97,115,115, 0,2049,1576,2049,184,16,10,1647,1681,168,12482,249892660727267252,105,109,109,101,100,105,97,116, 101,0,1,180,2049,1660,10,1666,1696,168,12482,6385144159,100,97,116,97,0,1,156,2049, 1660,10,1686,1716,168,12482,249902713833354782,112,114,105,109,105,116,105,118,101,0,1,174,2049, 1660,10,1701,1731,180,12482,6385302998,104,111,111,107,0,1,1793,2049,130,1,3,15,1, 1,17,2049,130,10,1721,1758,168,12482,7572920930896175,115,101,116,45,104,111,111,107,0,1, 1,17,16,10,1744,1775,168,12482,6954102295577,117,110,104,111,111,107,0,1,1,17,2, 1,1,17,4,16,10,1763,1792,180,12482,177613,40,0,10,1785,1800,180,12482,177614,41, 0,10,1793,1818,168,12482,-4577149749211730287,99,111,109,112,105,108,101,58,108,105,116,0,1, 1,2049,130,2049,130,10,1801,1843,168,12482,-3471989134310745468,99,111,109,112,105,108,101,58,106, 117,109,112,0,1,1793,2049,130,2049,130,10,1825,1868,168,12482,-3471989134311018844,99,111,109,112, 105,108,101,58,99,97,108,108,0,1,2049,2049,130,2049,130,10,1850,1892,168,12482, -4577149749211723885,99,111,109,112,105,108,101,58,114,101,116,0,1,10,2049,130,10,1875,1913, 168,12482,8246182162316307558,99,111,109,112,105,108,105,110,103,63,0,1,149,15,10,1897,1930, 180,12482,229482595734807,115,105,103,105,108,58,96,0,2049,266,2049,130,10,1917,1948,180,12482, 229482595734803,115,105,103,105,108,58,92,0,2049,464,10,1935,1964,180,12482,229482595734805,115,105,103, 105,108,58,94,0,2049,458,10,1951,1977,168,12482,6385292201,104,101,114,101,0,1,3, 15,10,1967,1994,180,12482,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,12482,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,12482,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,12482,210731100041,118,97,114, 45,110,0,2049,2075,2049,130,10,2091,2116,168,12482,193508814,118,97,114,0,134284289,0,2102, 10,2107,2131,168,12482,210709068620,99,111,110,115,116,0,2049,2075,2049,1576,2049,182,16,10, 2120,2149,174,12482,6385740380,116,117,99,107,0,100926722,10,2139,2161,174,12482,6385561857,111,118,101, 114,0,67502597,10,2151,2172,174,12482,193500364,110,105,112,0,772,10,2163,2189,174,12482,249885844724841747, 100,114,111,112,45,112,97,105,114,0,771,10,2174,2201,174,12482,6383817805,63,100,117, 112,0,6402,10,2191,2217,168,12482,7572302161469511,100,117,112,45,112,97,105,114,0,67502597,67502597, 10,2203,2229,168,12482,193489474,100,105,112,0,525572,6,10,2220,2241,168,12482,193505809,115,105, 112,0,67502597,1,27,2049,2229,10,2232,2255,168,12482,5863248,98,105,0,1,2241,2049,2229, 8,10,2247,2270,168,12482,193487226,98,105,42,0,1,2229,2049,2229,8,10,2261,2285,168, 12482,193487248,98,105,64,0,2,2049,2270,10,2276,2298,168,12482,193507188,116,114,105,0,1793, 2307,1,2241,2049,2229,2049,2241,10,1,2300,2049,2229,8,10,2289,2323,168,12482,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,12482,6385737268,116,114,105,64,0,2,2,2049, 2323,10,2346,2372,168,12482,210732529790,119,104,105,108,101,0,1793,2381,525570,1639430,3,1,2374, 7,10,1,2374,8,3,10,2361,2397,168,12482,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,12482,229466054377278,102, 111,114,101,118,101,114,0,1793,2430,8,10,1,2428,2049,2241,1,2426,7,10,2413, 2449,168,12482,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,12482,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,12482,6384551781,84,82,85,69,0,1,-1,10,2517,2541,168,12482,210672985680,70,65,76,83, 69,0,1,0,10,2530,2554,168,12482,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,12482,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,12482, 193500566,110,111,116,0,1,-1,23,10,2635,2659,168,12482,210719911674,108,116,101,113,63,0, 2049,2217,101516555,22,10,2648,2675,168,12482,210713982069,103,116,101,113,63,0,4,2049,2659,10, 2664,2690,168,12482,210720171475,110,58,77,65,88,0,1,-5,15,10,2679,2705,168,12482,210720171729, 110,58,77,73,78,0,1,-4,15,10,2694,2722,168,12482,229474321428492,110,58,122,101,114, 111,63,0,1,0,11,10,2709,2740,168,12482,7572649618157049,110,58,45,122,101,114,111,63, 0,1,0,12,10,2726,2761,168,12482,-4562761254435316065,110,58,110,101,103,97,116,105,118,101, 63,0,1,0,13,10,2744,2782,168,12482,-4562757999622951041,110,58,112,111,115,105,116,105,118, 101,63,0,1,-1,14,10,2765,2812,168,12482,-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, 12482,229474297120890,110,58,101,118,101,110,63,0,1,2,20,3,2049,2722,10,2816,2848,168, 12482,6953766919107,110,58,111,100,100,63,0,2049,2829,2049,2644,10,2836,2862,168,12482,193494767,105, 102,59,0,67502597,1,76,2049,2229,25,6,771,10,2853,2881,168,12482,6383175836,45,105,102, 59,0,67502597,1,74,2049,2229,2049,2644,25,6,771,10,2871,2901,174,12482,193504922,114,111, 116,0,67503109,10,2892,2910,174,12482,177620,47,0,197652,10,2903,2921,174,12482,193499461,109,111, 100,0,788,10,2912,2934,168,12482,210720211139,110,58,112,111,119,0,1,1,4,1793,2942, 67502597,19,10,1,2939,2049,2449,772,10,2923,2962,168,12482,7572652137106817,110,58,110,101,103,97, 116,101,0,1,-1,19,10,2948,2980,168,12482,7572652347517886,110,58,115,113,117,97,114,101, 0,4866,10,2966,2994,168,12482,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,12482,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,12482,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,12482, 210720194371,110,58,97,98,115,0,2,2049,2761,1,2962,9,10,3075,3106,168,12482,229474304963756,110, 58,108,105,109,105,116,0,4,5,2049,3028,6,2049,3057,10,3093,3125,168,12482,210720203463, 110,58,105,110,99,0,659713,1,10,3114,3139,168,12482,210720197721,110,58,100,101,99,0, 659969,1,10,3128,3158,168,12482,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,12482,249861296566813883,83,99, 111,112,101,76,105,115,116,0,20746,20859,10,3172,3198,168,12482,5864091,123,123,0,2049, 1576,2,1,3187,2049,61,16,10,3190,3225,168,12482,-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,12482,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,12482,-6972911891006832072,98,58,116,111,45,98,121,116,101,45,97,100,100,114,101,115,115, 0,4865,4,10,3437,3476,168,12482,229458800096267,98,58,102,101,116,99,104,0,267265,4,134288385, 4,2901,266001,2049,3312,10,3463,3498,168,12482,229458816047342,98,58,115,116,111,114,101,0,1048836, 3296,267265,4,1793,3507,134287106,78,10,1,3504,2049,2229,2049,3345,2049,92,4,16,10,3485, 3531,168,12482,229466548904081,104,58,102,101,116,99,104,0,1,3476,1793,3543,2049,3125,2049,3476, 1,-8,24,10,1,3535,2049,2255,22,10,3518,3562,168,12482,229466564855156,104,58,115,116,111, 114,101,0,2049,2217,102039813,255,2049,3498,2049,3125,18350341,8,255,117507605,3498,10,3549,3589,168, 12482,229485920923616,119,58,102,101,116,99,104,0,1,4,197652,15,10,3576,3607,168,12482,229485936874691, 119,58,115,116,111,114,101,0,1,4,197652,16,10,3594,3630,168,12482,-2542660583859062324,119,58, 102,101,116,99,104,45,110,101,120,116,0,2,1,4,17,4,2049,3589,10,3612, 3656,168,12482,-3300792181564964579,104,58,102,101,116,99,104,45,110,101,120,116,0,2,1,2, 17,4,2049,3531,10,3638,3682,168,12482,-3604044820647325481,98,58,102,101,116,99,104,45,110,101, 120,116,0,2,1,1,17,4,2049,3476,10,3664,3708,168,12482,-2542036332270164849,119,58,115,116, 111,114,101,45,110,101,120,116,0,2,1,4,17,1,3607,2049,2229,10,3690,3735, 168,12482,-3300167929976067104,104,58,115,116,111,114,101,45,110,101,120,116,0,2,1,2,17, 1,3562,2049,2229,10,3717,3762,168,12482,-3603420569058428006,98,58,115,116,111,114,101,45,110,101, 120,116,0,2,1,1,17,1,3498,2049,2229,10,3744,3785,168,12482,7572992899446007,118,58,105, 110,99,45,98,121,0,286196994,659462,10,3771,3802,168,12482,7572992693095753,118,58,100,101,99,45, 98,121,0,68093186,168822290,10,3788,3816,168,12482,210729690831,118,58,105,110,99,0,1,1,4, 2049,3785,10,3805,3833,168,12482,210729685089,118,58,100,101,99,0,1,1,4,2049,3802,10, 3822,3852,168,12482,229484636707508,118,58,108,105,109,105,116,0,251790597,1542,2049,3106,4100,10,3839, 3868,168,12482,6385748402,118,58,111,110,0,2049,2527,4100,10,3858,3883,168,12482,210729697104,118,58, 111,102,102,0,2049,2541,4100,10,3872,3898,168,12482,210706586657,97,108,108,111,116,0,1, 3,2049,3785,10,3887,3919,168,12482,8246989571153063777,118,58,112,114,101,115,101,114,118,101,0, 84869636,1,27,2049,2229,1049606,10,3903,3940,168,12482,7572993371535704,118,58,117,112,100,97,116,101, 0,4,1793,3947,15,4,8,10,1,3943,2049,2241,16,10,3926,3963,168,12482,6385123360,99, 111,112,121,0,1793,3972,285278725,1,33951492,268767489,1,6,10,1,3965,2049,2449,771,10,3953, 3989,156,0,0,115,116,97,114,116,0,0,10,3978,4000,156,0,0,101,110,100, 0,0,10,3991,4017,168,0,0,116,101,114,109,105,110,97,116,101,0,1,0, 3841,4000,16,10,3953,4041,168,12482,-3513680875729732409,98,117,102,102,101,114,58,115,116,97,114, 116,0,3841,3989,10,4023,4060,168,12482,8246143877888709904,98,117,102,102,101,114,58,101,110,100, 0,3841,4000,10,4044,4079,168,12482,8246143877888705218,98,117,102,102,101,114,58,97,100,100,0, 3841,4000,16,1,4000,2049,3816,2049,4017,10,4063,4105,168,12482,8246143877888711801,98,117,102,102,101, 114,58,103,101,116,0,1,4000,2049,3833,3841,4000,15,2049,4017,10,4089,4133,168,12482, -3513680875746570456,98,117,102,102,101,114,58,101,109,112,116,121,0,3841,3989,4097,4000,2049,4017, 10,4115,4157,168,12482,-4578413135315348908,98,117,102,102,101,114,58,115,105,122,101,0,3841,4000, 3841,3989,18,10,4140,4179,168,12482,8246143877888724869,98,117,102,102,101,114,58,115,101,116,0, 4097,3989,2049,4133,10,4163,4205,168,12482,-3186446687793719003,98,117,102,102,101,114,58,112,114,101, 115,101,114,118,101,0,3841,3989,3841,4000,1793,4218,1,27,2049,2229,4097,3989,10,1, 4211,2049,2229,4097,4000,10,4184,4242,156,12482,-4600587576916820603,84,101,109,112,83,116,114,105,110, 103,115,0,32,4225,4262,156,12482,7474516786580364824,84,101,109,112,83,116,114,105,110,103,77, 97,120,0,512,4243,4276,168,12482,229440420829967,83,84,82,73,78,71,83,0,2049,1545,3841, 4242,3841,4262,19,18,10,4263,4298,156,0,0,67,117,114,114,101,110,116,0,1, 10,4285,4315,168,0,0,115,58,112,111,105,110,116,101,114,0,3841,4298,3841,4262, 19,2049,4276,17,10,4300,4336,168,0,0,115,58,110,101,120,116,0,1,4298,2049, 3816,3841,4298,3841,4242,11,1793,4352,1,0,4097,4298,10,1,4347,9,10,4263,4368,168, 12482,6953962777192,115,58,116,101,109,112,0,2,2049,104,2049,3125,2049,4315,4,2049,3963,2049, 4315,2049,4336,10,4356,4396,168,12482,229480754149537,115,58,101,109,112,116,121,0,2049,4315,2049, 4336,1,0,67502597,16,10,4383,4417,168,12482,6953962747657,115,58,115,107,105,112,0,6,1793, 4425,68223234,1,786703,0,10,1,4420,2049,2372,2049,3139,5,10,4405,4445,168,12482,6953962453495,115, 58,107,101,101,112,0,2049,1913,1793,4454,1,4417,2049,1868,10,1,4449,9,2049,1977, 1,144,2049,2229,2049,156,10,4433,4479,180,0,229482595734750,115,105,103,105,108,58,39,0, 2049,1913,1,4445,1,4368,2049,66,10,4466,4501,168,12482,229480755051740,115,58,102,101,116,99, 104,0,17,15,10,4488,4517,168,12482,229480771002815,115,58,115,116,111,114,101,0,17,16, 10,4504,4532,168,12482,6953962169596,115,58,99,104,111,112,0,2049,4368,2,2049,104,67502597,17, 2049,3139,1,0,4,16,10,4520,4561,168,12482,249904557751418990,115,58,114,101,118,101,114,115, 101,0,1793,4603,2,2049,4368,2049,4179,1,104,1793,4579,2,2049,104,17,2049,3139,10, 1,4572,2049,2255,4,1793,4593,2,15,2049,4079,2049,3139,10,1,4586,2049,2449,3,2049, 4041,2049,4368,10,1,4563,2049,4205,10,4546,4623,168,12482,249904555657463488,115,58,112,114,101,112, 101,110,100,0,2049,4368,1793,4647,2,2049,104,17,1793,4639,2,2049,104,2049,3125,10, 1,4633,2049,2229,4,2049,3963,10,1,4627,2049,2241,10,4608,4666,168,12482,7572864733934314,115,58, 97,112,112,101,110,100,0,4,2049,4623,10,4652,4686,168,12482,8246849907066750743,115,58,102,111, 114,45,101,97,99,104,0,1793,4701,67502597,6415,3,67502597,67502597,251987205,2054,101777670,1,1,4688, 7,10,1,4688,8,771,10,4670,4724,168,12482,-2744677796467205929,115,58,105,110,100,101,120,47, 99,104,97,114,0,4,1793,4747,2049,58,25,4,1793,4736,67502597,12,10,1,4733,2049, 2229,4,25,3,1,4727,7,10,1,4727,1793,4756,18,2049,3139,772,10,1,4751,1793, 4765,2049,104,67502597,11,10,1,4760,2049,2298,1793,4775,3,1,-1,10,1,4771,9,10, 4706,4801,168,12482,-2157201767973730595,115,58,99,111,110,116,97,105,110,115,47,99,104,97,114, 63,0,2049,4724,1,-1,12,10,4779,4819,168,12482,6953962341782,115,58,104,97,115,104,0, 1,5381,4,1793,4827,286458116,33,10,1,4824,2049,4686,10,4807,4841,156,0,0,83,116, 114,0,0,4832,4855,168,0,0,101,120,116,114,97,99,116,0,2049,2217,3841,4841, 4,2049,3963,3841,4841,67502597,17,1,0,4,16,10,4842,4882,168,0,0,99,104,101, 99,107,0,1,4855,2049,2229,1793,4893,1,3125,2049,2229,10,1,4888,2049,2229,3841,4841, 2049,4819,67502597,11,10,4871,4918,168,0,0,108,111,99,97,116,105,111,110,0,67503109, 67503109,1793,4951,1793,4946,4,1793,4932,67502597,2049,2722,21,10,1,4927,2049,2229,4,1793,4942, 772,2,10,1,4939,9,10,1,4924,2049,2229,10,1,4922,2049,2229,10,4904,4967,168, 0,0,115,101,116,117,112,0,2049,4396,4097,4841,1,0,67503109,67503109,1,104,1,4819, 2049,2255,1793,4987,67502597,2049,104,10,1,4983,2049,2229,4,10,4807,5013,168,12482,-581580411198892688,115, 58,105,110,100,101,120,47,115,116,114,105,110,103,0,67502597,1793,5032,2049,4967,1793, 5025,2049,4882,2049,4918,10,1,5020,2049,2449,771,3,10,1,5016,2049,2229,18,1,2, 18,1,-1,2049,3057,10,4993,5054,156,0,0,83,114,99,0,0,5045,5064,156,0, 0,84,97,114,0,0,5055,5074,156,0,0,80,97,100,0,0,5065,5082,156,0, 0,73,0,0,5075,5090,156,0,0,70,0,0,5083,5099,156,0,0,65,116,0, 0,5091,5115,168,0,0,116,101,114,109,105,110,97,116,101,0,1,0,3841,5074, 3841,5064,2049,104,17,16,10,5100,5139,168,0,0,101,120,116,114,97,99,116,0, 3841,5054,3841,5082,17,3841,5074,3841,5064,2049,104,2049,3963,10,5126,5166,168,0,0,99, 111,109,112,97,114,101,0,3841,5074,3841,5064,2049,118,3841,5090,22,4097,5090,3841,5090, 1793,5186,3841,5082,4097,5099,10,1,5181,2049,74,10,5153,5201,168,0,0,110,101,120, 116,0,1,5082,2049,3816,10,4993,5230,168,12482,-6456227941126558634,115,58,99,111,110,116,97,105, 110,115,47,115,116,114,105,110,103,63,0,4097,5064,4097,5054,2049,4396,4097,5074,1, 0,4097,5082,1,0,4097,5090,3841,5054,2049,104,1793,5261,2049,5139,2049,5115,2049,5166,2049, 5201,10,1,5252,2049,2449,3841,5090,10,5206,5282,168,12482,7572864921182136,115,58,102,105,108,116, 101,114,0,1793,5310,2049,4396,2049,4179,4,1793,5302,2049,2217,4,8,1,4079,1,17, 2049,66,10,1,5291,2049,4686,3,2049,4041,10,1,5284,2049,4205,10,5268,5326,168,12482, 210726137008,115,58,109,97,112,0,1793,5348,2049,4396,2049,4179,4,1793,5340,67502597,8,2049,4079, 10,1,5335,2049,4686,3,2049,4041,10,1,5328,2049,4205,10,5315,5367,168,12482,7572865443813333,115, 58,115,117,98,115,116,114,0,1793,5373,17,2049,4396,10,1,5369,2049,2229,1793,5385, 67502597,1,3963,2049,2229,10,1,5379,2049,2241,67502597,1793,5398,17,1,0,4,16,10,1, 5392,2049,2229,10,5353,5416,168,12482,229480769412560,115,58,114,105,103,104,116,0,67502597,2049,104, 67502597,18,4,2049,5367,10,5403,5437,168,12482,6953962489469,115,58,108,101,102,116,0,1,0, 4,2049,5367,10,5425,5463,168,12482,-949014848675520942,115,58,98,101,103,105,110,115,45,119,105, 116,104,63,0,2,2049,104,1,19,2049,2229,2049,5437,2049,118,10,5443,5493,168,12482, -2744863427173801468,115,58,101,110,100,115,45,119,105,116,104,63,0,2,2049,104,1,19,2049, 2229,2049,5416,2049,118,10,5475,5517,168,12482,6953962177261,115,58,99,111,112,121,0,67502597,2049, 104,2049,3125,2049,3963,10,5505,5539,168,12482,7572863551252214,115,58,68,73,71,73,84,83,0, 2049,4417,48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70,0,1, 5541,10,5525,5584,168,12482,-3174032931242973971,115,58,65,83,67,73,73,45,76,79,87,69,82, 67,65,83,69,0,2049,4417,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,5586,10,5561,5639,168, 12482,-3174020239987242608,115,58,65,83,67,73,73,45,85,80,80,69,82,67,65,83,69,0, 2049,4417,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,5641,10,5616,5692,168,12482,4909441458232360267,115,58,65, 83,67,73,73,45,76,69,84,84,69,82,83,0,2049,4417,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,5694,10,5671,5769,168,12482,1619870888324870636,115,58,80,85, 78,67,84,85,65,84,73,79,78,0,2049,4417,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,5771,1,95,67502597,16,10,5750,5829,156,12482,-2745567821320788289,115,58,87, 72,73,84,69,83,80,65,67,69,0,32,9,10,13,0,5811,5841,180,12482,177612, 39,0,1,4396,2049,168,10,5834,5853,180,12482,177609,36,0,1,0,2049,156,10,5846, 0,156,12482,249835240931843863,65,83,67,73,73,58,78,85,76,0,5858,27,156,12482,249835240931833987,65, 83,67,73,73,58,69,83,67,0,5873,8,156,12482,7570764876722141,65,83,67,73,73,58, 66,83,0,5888,9,156,12482,7570764876722340,65,83,67,73,73,58,72,84,0,5902,10,156, 12482,7570764876722458,65,83,67,73,73,58,76,70,0,5916,11,156,12482,7570764876722802,65,83,67,73, 73,58,86,84,0,5930,12,156,12482,7570764876722260,65,83,67,73,73,58,70,70,0,5944, 13,156,12482,7570764876722173,65,83,67,73,73,58,67,82,0,5958,32,156,12482,-4630583730859567212,65,83, 67,73,73,58,83,80,65,67,69,0,5972,127,156,12482,249835240931832445,65,83,67,73,73, 58,68,69,76,0,5989,1,156,12482,249835240931849106,65,83,67,73,73,58,83,79,72,0, 6004,2,156,12482,249835240931849287,65,83,67,73,73,58,83,84,88,0,6019,3,156,12482,249835240931834041, 65,83,67,73,73,58,69,84,88,0,6034,4,156,12482,249835240931833872,65,83,67,73,73, 58,69,79,84,0,6049,5,156,12482,249835240931833836,65,83,67,73,73,58,69,78,81,0, 6064,6,156,12482,249835240931829111,65,83,67,73,73,58,65,67,75,0,6079,7,156,12482,249835240931830267, 65,83,67,73,73,58,66,69,76,0,6094,14,156,12482,7570764876722698,65,83,67,73,73, 58,83,79,0,6109,15,156,12482,7570764876722692,65,83,67,73,73,58,83,73,0,6123,16, 156,12482,249835240931832669,65,83,67,73,73,58,68,76,69,0,6137,17,156,12482,249835240931832352,65,83, 67,73,73,58,68,67,49,0,6152,18,156,12482,249835240931832353,65,83,67,73,73,58,68, 67,50,0,6167,19,156,12482,249835240931832354,65,83,67,73,73,58,68,67,51,0,6182,20, 156,12482,249835240931832355,65,83,67,73,73,58,68,67,52,0,6197,21,156,12482,249835240931843202,65,83, 67,73,73,58,78,65,75,0,6212,22,156,12482,249835240931849442,65,83,67,73,73,58,83, 89,78,0,6227,23,156,12482,249835240931834019,65,83,67,73,73,58,69,84,66,0,6242,24, 156,12482,249835240931831226,65,83,67,73,73,58,67,65,78,0,6257,25,156,12482,7570764876722234,65,83, 67,73,73,58,69,77,0,6272,26,156,12482,249835240931849298,65,83,67,73,73,58,83,85, 66,0,6286,28,156,12482,7570764876722273,65,83,67,73,73,58,70,83,0,6301,29,156,12482, 7570764876722306,65,83,67,73,73,58,71,83,0,6315,30,156,12482,7570764876722669,65,83,67,73,73, 58,82,83,0,6329,31,156,12482,7570764876722768,65,83,67,73,73,58,85,83,0,6343,6375, 168,12482,-3553210050247798618,99,58,108,111,119,101,114,99,97,115,101,63,0,1,97,1,122, 2049,3158,10,6357,6400,168,12482,-3552791238808663639,99,58,117,112,112,101,114,99,97,115,101,63, 0,1,65,1,90,2049,3158,10,6382,6422,168,12482,249882047462872305,99,58,108,101,116,116,101, 114,63,0,1,6375,1,6400,2049,2255,22,10,6407,6444,168,12482,7572182947632498,99,58,100,105, 103,105,116,63,0,1,48,1,57,2049,3158,10,6430,6467,168,12482,8246107997572794159,99,58,118, 105,115,105,98,108,101,63,0,1,32,1,126,2049,3158,10,6451,6488,168,12482,7572183659755470, 99,58,118,111,119,101,108,63,0,2049,4417,97,101,105,111,117,65,69,73,79, 85,0,1,6490,4,2049,4801,10,6474,6525,168,12482,-3553628119197217420,99,58,99,111,110,115,111, 110,97,110,116,63,0,2,2049,6422,1793,6535,2049,6488,2049,2644,10,1,6530,1793,6543, 3,2049,2541,10,1,6539,2049,66,10,6507,6567,168,12482,-6558963794062736370,99,58,119,104,105,116, 101,115,112,97,99,101,63,0,1,5829,4,2049,4801,10,6548,6592,168,12482,-6672106426782194349,99, 58,45,108,111,119,101,114,99,97,115,101,63,0,2049,6375,2049,2644,10,6573,6616, 168,12482,-6671687615343059370,99,58,45,117,112,112,101,114,99,97,115,101,63,0,2049,6400,2049, 2644,10,6597,6636,168,12482,249881966047746975,99,58,45,100,105,103,105,116,63,0,2049,6444,2049, 2644,10,6621,6661,168,12482,1197920222559514203,99,58,45,119,104,105,116,101,115,112,97,99,101, 63,0,2049,6567,2049,2644,10,6641,6683,168,12482,-4579699312045814628,99,58,45,118,105,115,105,98, 108,101,63,0,2049,6467,2049,2644,10,6666,6703,168,12482,249881966759869947,99,58,45,118,111,119, 101,108,63,0,2049,6488,2049,2644,10,6688,6727,168,12482,-6672524495731613151,99,58,45,99,111,110, 115,111,110,97,110,116,63,0,2049,6525,2049,2644,10,6708,6748,168,12482,8246107917359977086,99,58, 116,111,45,117,112,112,101,114,0,2,2049,6375,25,3,1,32,18,10,6732,6773, 168,12482,8246107917349275483,99,58,116,111,45,108,111,119,101,114,0,2,2049,6400,25,3,1, 32,17,10,6757,6799,168,12482,-4579599832837481303,99,58,116,111,45,115,116,114,105,110,103,0, 2049,4417,46,0,1,6801,2049,4368,1,39,2049,2241,10,6782,6831,168,12482,-6563237009071717459,99,58, 116,111,103,103,108,101,45,99,97,115,101,0,2,2049,6375,1,6748,1,6773,2049, 66,10,6812,6858,168,12482,-4579599833032159941,99,58,116,111,45,110,117,109,98,101,114,0,2, 2049,6444,1793,6867,1,48,18,10,1,6863,1793,6875,3,1,0,10,1,6871,2049,66, 10,6841,6896,168,12482,8246850501110408334,115,58,116,111,45,117,112,112,101,114,0,1,6748,2049, 5326,10,6880,6917,168,12482,8246850501099706731,115,58,116,111,45,108,111,119,101,114,0,1,6773, 2049,5326,10,6901,6939,168,12482,-4555094364049076026,115,58,116,114,105,109,45,108,101,102,116,0, 2049,4368,1793,6953,2049,58,1,6567,1,2740,2049,2255,21,10,1,6943,2049,2372,2049,3139, 10,6922,6978,168,12482,-2744161423935835847,115,58,116,114,105,109,45,114,105,103,104,116,0,2049, 4368,2049,4561,2049,6939,2049,4561,10,6960,6999,168,12482,6953962791214,115,58,116,114,105,109,0, 2049,6978,2049,6939,10,6987,7028,156,12482,-429402327855008236,82,101,119,114,105,116,101,85,110,100, 101,114,115,99,111,114,101,115,0,-1,7004,7038,168,0,0,115,117,98,0,1, 95,1793,7045,1,32,10,1,7042,2049,2554,10,7029,7063,168,0,0,114,101,119,114, 105,116,101,0,3841,7028,1793,7072,1,7038,2049,5326,10,1,7067,9,10,7050,7088,168, 0,0,104,97,110,100,108,101,0,1,4479,8,10,7004,7105,180,12482,229482595734750,115,105, 103,105,108,58,39,0,2049,7063,2049,7088,10,7092,7128,168,12482,-2744210522849075797,115,58,115,112, 108,105,116,47,99,104,97,114,0,2049,2217,2049,4724,772,2049,2217,2049,5437,1,41, 2049,2229,10,7110,7162,168,12482,-72719441055178940,115,58,115,112,108,105,116,47,115,116,114,105, 110,103,0,2049,2217,2049,5013,2049,3125,772,2049,2217,2049,5437,1,41,2049,2229,10,7142, 7193,168,12482,249904557744535982,115,58,114,101,112,108,97,99,101,0,67502597,2049,104,2049,1977,16, 1793,7209,2049,7162,4,2049,1977,15,17,10,1,7201,2049,2229,2049,4623,2049,4666,10,7178, 7232,156,0,0,83,112,108,105,116,45,79,110,0,0,7218,7245,168,0,0,109, 97,116,99,104,63,0,3841,7232,11,10,7233,7264,168,0,0,116,101,114,109,105, 110,97,116,101,0,1,0,67502597,2049,3139,16,10,7249,7281,168,0,0,115,116,101, 112,0,1,3125,2049,2229,2049,7245,1793,7295,2,2049,130,2049,7264,10,1,7289,9,10, 7178,7315,168,12482,8246850503517749147,115,58,116,111,107,101,110,105,122,101,0,4097,7232,2049,4445, 2049,1977,1,0,2049,130,1793,7337,2,2049,130,2,1,7281,2049,4686,3,10,1,7327, 2049,2229,2049,1977,67502597,18,2049,3139,67502597,16,10,7299,7362,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,7350,7499,156,0,0,76,101,110,0, 0,7490,7512,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,7500,7648,156,0,0,84,80,0,0,7640,7659,168,0,0,115,97,118,101,0, 2049,4445,3841,7648,1,7512,17,2049,3125,16,1,7648,2049,3816,10,7649,7684,168,0,0, 110,101,120,116,0,1793,7690,3841,7499,17,10,1,7686,2049,2241,10,7674,7706,168,0, 0,100,111,110,101,63,0,2049,104,2049,2722,10,7299,7737,168,12482,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,7648,1793,7751,2,1,7362,2049,5517,2049,4666,10,1,7743,1793,7760,2049,104,4097,7499, 10,1,7755,2049,2255,1793,7777,1,7362,2049,7162,2049,7659,2049,7684,2049,7706,10,1,7766, 2049,2397,1,7512,3841,7648,2049,3139,4097,7512,772,10,7711,7803,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,7791,7885,168,0,0,99,104,101,99,107, 45,115,105,103,110,0,2049,2761,1793,7894,1,45,2049,4079,10,1,7889,9,10,7869, 7912,168,0,0,110,45,62,100,105,103,105,116,0,2049,5539,17,15,10,7898,7930, 168,0,0,99,111,110,118,101,114,116,0,1793,7944,3841,243,20,4,2049,7912,2049, 4079,2,2049,2722,10,1,7932,2049,2397,3,10,7711,7976,168,0,-3499893649969689757,110,58,116,111, 45,115,116,114,105,110,103,47,114,101,118,101,114,115,101,100,0,1793,7990,1, 7803,2049,4179,2,2049,3086,2049,7930,2049,7885,10,1,7978,2049,4205,1,7803,10,7950,8014, 168,12482,-4562752463999572364,110,58,116,111,45,115,116,114,105,110,103,0,2049,7976,2049,4561,10, 7997,8029,168,0,0,99,104,97,114,0,1,32,1793,8038,1,95,2049,4079,10,1, 8033,2049,2554,1,114,1793,8051,1,13,2049,4079,10,1,8046,2049,2554,1,110,1793,8064, 1,10,2049,4079,10,1,8059,2049,2554,1,116,1793,8077,1,9,2049,4079,10,1,8072, 2049,2554,1,48,1793,8090,1,0,2049,4079,10,1,8085,2049,2554,1,94,1793,8103,1, 27,2049,4079,10,1,8098,2049,2554,2049,4079,10,8019,8120,168,0,0,116,121,112,101, 0,1,99,1793,8128,4,2049,4079,10,1,8124,2049,2554,1,115,1793,8142,4,1,4079, 2049,4686,10,1,8136,2049,2554,1,110,1793,8158,4,2049,8014,1,4079,2049,4686,10,1, 8150,2049,2554,3,10,8110,8176,168,0,0,104,97,110,100,108,101,0,1,92,1793, 8185,2049,58,2049,8029,10,1,8180,2049,2554,1,37,1793,8198,2049,58,2049,8120,10,1, 8193,2049,2554,2049,4079,10,7997,8219,168,12482,7572864928505531,115,58,102,111,114,109,97,116,0, 1793,8248,2049,4396,1793,8243,2049,4179,1793,8238,2049,58,25,2049,8176,1,8229,7,10,1, 8229,8,3,10,1,8225,2049,2241,10,1,8221,2049,4205,10,8205,8266,168,12482,229480751847353,115, 58,99,111,110,115,116,0,1,4445,2049,2229,2049,2131,10,8253,8285,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,8273,8323,168,0,0,102, 114,111,109,0,2049,104,2,1793,8341,1793,8334,1,8285,4113,10,1,8330,2049,2241,2049, 3139,10,1,8328,2049,2449,3,10,8313,8355,168,0,0,116,111,0,2,2049,104,1793, 8371,2049,58,1,97,18,2049,3125,1,8285,266001,10,1,8360,2049,2449,3,10,8253,8390, 168,12482,229481157528792,114,101,111,114,100,101,114,0,1,8323,2049,2229,2049,8355,10,8377,8408, 168,12482,210709288570,99,117,114,114,121,0,2049,1977,1793,8418,4,2049,1818,2049,1843,10,1, 8412,2049,2229,10,8397,8433,168,12482,6385158928,100,111,101,115,0,2049,1595,4,2049,8408,2049, 1576,2049,182,16,1,168,2049,1660,10,8423,8464,168,12482,8246153734800721448,100,58,102,111,114,45, 101,97,99,104,0,1,2,1793,8477,6415,2049,2217,134481157,1542,1,8468,7,10,1,8468, 8,3,10,8448,8499,168,12482,-4578079420196310922,100,58,108,111,111,107,117,112,45,120,116,0, 1,0,4,1793,8524,2049,2217,2049,182,2831,1793,8517,4,1,2172,2049,2229,10,1,8511, 1,17,2049,66,10,1,8504,2049,8464,3,10,8482,8538,168,12482,5863407,103,99,0,1, 3,4,2049,3919,10,8530,8558,168,12482,7572098019335426,97,58,108,101,110,103,116,104,0,15, 10,8544,8574,168,12482,7572098062851599,97,58,109,105,100,100,108,101,0,2049,1977,1793,8597,2, 2049,130,1793,8587,2049,3125,17,10,1,8583,2049,2229,2049,1977,4,2049,3963,10,1,8578, 2049,2229,10,8560,8614,168,12482,6953258052395,97,58,108,101,102,116,0,1,0,4,2049,8574, 10,8602,8633,168,12482,229457522989118,97,58,114,105,103,104,116,0,67502597,2049,8558,67502597,18,4, 2049,8574,10,8620,8665,168,12482,9069136730318539537,97,58,99,111,117,110,116,101,100,45,114,101, 115,117,108,116,115,0,8,2049,1977,1793,8678,2,2049,130,1,130,2049,2449,10,1, 8670,2049,2229,10,8642,8702,168,12482,8526436589641133048,97,58,102,114,111,109,45,115,116,114,105, 110,103,0,2049,1977,1793,8716,2,2049,104,2049,130,1,130,2049,4686,10,1,8706,2049, 2229,10,8683,8737,168,12482,8246014500347515589,97,58,102,111,114,45,101,97,99,104,0,4,2049, 58,1,19,2049,2229,1793,8753,5,2049,58,84018692,525572,1542,10,1,8746,2049,2449,771,10, 8721,8770,168,12482,210704781289,97,58,100,117,112,0,2049,1977,1793,8783,2,15,2049,130,1, 130,2049,8737,10,1,8774,2049,2229,10,8759,8800,168,12482,6953257740187,97,58,99,111,112,121, 0,1,3,1793,8816,4097,3,2,2049,8558,2049,130,1,130,2049,8737,10,1,8804,2049, 3919,10,8788,8838,168,12482,-4582662990808010201,97,58,116,111,45,115,116,114,105,110,103,0,1, 3,1793,8851,2049,8770,1,0,2049,130,2049,3125,10,1,8842,2049,3919,2049,4368,10,8821, 8872,168,12482,7572097601960728,97,58,97,112,112,101,110,100,0,2049,2217,1,37,2049,2285,17, 2049,1977,1793,8897,2049,130,1793,8892,1,130,2049,8737,10,1,8887,2049,2285,10,1,8883, 2049,2229,10,8858,8917,168,12482,249879240302335150,97,58,112,114,101,112,101,110,100,0,4,2049, 8872,10,8902,8933,168,12482,6953257732522,97,58,99,104,111,112,0,2049,8770,1,-1,2049,3898, 2,2049,3833,10,8921,8957,168,12482,7572097789208550,97,58,102,105,108,116,101,114,0,1793,8972, 67502597,1,27,2049,2229,4,1,130,1,17,2049,66,10,1,8959,2049,8408,2049,1977,1793, 8987,67502597,15,2049,130,2049,8737,10,1,8980,2049,2229,2049,1977,67502597,18,2049,3139,67502597,16, 10,8943,9017,168,12482,-4582686815792817282,97,58,99,111,110,116,97,105,110,115,63,0,1,0, 4,1793,9029,4,5,67502597,11,6,22,10,1,9022,2049,8737,772,10,9000,9059,168,12482, -3160266450763725308,97,58,99,111,110,116,97,105,110,115,47,115,116,114,105,110,103,63,0, 1,0,4,1793,9072,4,5,67502597,2049,118,6,22,10,1,9064,2049,8737,772,10,9035, 9089,168,12482,210704790430,97,58,109,97,112,0,4,1793,9119,2049,58,1793,9113,1793,9102,15, 67502597,8,10,1,9098,2049,2241,1,39,2049,2241,2049,3125,10,1,9096,2049,2449,771,10, 1,9092,2049,2241,10,9078,9139,168,12482,249879242396290652,97,58,114,101,118,101,114,115,101,0, 2049,1977,1793,9173,2049,58,1793,9151,17,2049,3139,10,1,9147,2049,2241,2,2049,130,1793, 9167,2,15,2049,130,2049,3139,10,1,9160,2049,2449,3,10,1,9143,2049,2229,10,9124, 9188,168,12482,6384993884,97,58,116,104,0,17,2049,3125,10,9178,9205,168,12482,229457508628298,97,58, 102,101,116,99,104,0,2049,9188,15,10,9192,9222,168,12482,229457524579373,97,58,115,116,111, 114,101,0,2049,9188,16,10,9209,9239,168,12482,229457508770408,97,58,102,105,114,115,116,0, 1,0,2049,9205,10,9226,9256,168,12482,6953258048468,97,58,108,97,115,116,0,2,2049,8558, 2049,3139,2049,9205,10,9244,9278,168,12482,7572098253803096,97,58,114,101,100,117,99,101,0,1, 19,2049,2229,2049,8737,10,9264,9295,168,12482,6384048135,70,82,69,69,0,2049,4276,1,1025, 18,1,513,1,12,19,18,2049,1977,18,10,9285,9325,156,0,0,78,101,120,116, 65,114,114,97,121,0,10,9310,9338,168,0,0,97,114,114,97,121,115,0,2049, 9295,2049,1977,17,10,9285,9356,168,12482,6953258340118,97,58,116,101,109,112,0,3841,9325,2, 1,12,11,1793,9371,3,1,0,2,4097,9325,10,1,9364,9,1,513,19,2049,9338, 17,67502597,2049,8558,2049,3125,2049,3963,3841,9325,1,513,19,2049,9338,17,1,9325,2049,3816, 10,9344,9411,156,0,0,67,111,117,110,116,0,3,9400,9425,168,0,0,112,114, 101,112,97,114,101,0,1,0,1,9411,16,10,9412,9444,168,0,0,114,101,115, 101,114,118,101,0,4,1,0,2049,130,10,9431,9461,168,0,0,112,97,116,99, 104,0,2049,1977,67502597,18,2049,3139,67502597,16,10,9450,9483,168,0,0,99,108,101,97, 110,117,112,0,2,2049,9356,4,1,3,16,10,9470,9503,168,0,0,114,101,99, 111,114,100,0,3841,9411,2049,130,10,9491,9523,168,0,0,105,116,101,114,97,116, 101,47,110,0,1793,9535,67502597,11,1,9503,9,1,9411,2049,3816,10,1,9525,2049,8737, 10,9508,9555,168,0,0,105,116,101,114,97,116,101,47,115,0,1793,9568,67502597,2049, 118,1,9503,9,1,9411,2049,3816,10,1,9557,2049,8737,10,9344,9588,168,12482,249879231104077855,97, 58,105,110,100,105,99,101,115,0,2049,9425,2049,1977,1793,9600,2049,9444,2049,9523,3, 10,1,9594,2049,2229,2049,9461,2049,9483,10,9573,9631,168,12482,6001861788990794213,97,58,105,110,100, 105,99,101,115,47,115,116,114,105,110,103,0,2049,9425,2049,1977,1793,9643,2049,9444, 2049,9555,3,10,1,9637,2049,2229,2049,9461,2049,9483,10,9609,9665,168,12482,229457512492152,97,58, 105,110,100,101,120,0,1793,9674,2049,9588,1,0,2049,9205,10,1,9667,2049,8538,10, 9652,9699,168,12482,4816227687043827742,97,58,105,110,100,101,120,47,115,116,114,105,110,103,0, 1793,9708,2049,9631,1,0,2049,9205,10,1,9701,2049,8538,10,9679,9725,168,12482,6953258084126,97, 58,109,97,107,101,0,2049,8665,2,2,1,3,1793,9736,2049,9139,10,1,9733,2049, 3919,4,2049,8800,10,9713,9751,180,12482,177696,123,0,1,339,2049,180,1,1560,2049,168, 1,339,2049,180,10,9744,9771,180,12482,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,9725,2049,168,10,9764,9816,168,12482,6953257904708,97,58,104,97,115,104,0,1,5381,4, 1793,9827,4,1,33,19,17,10,1,9821,2049,8737,10,9804,9843,168,12482,210704782197,97,58, 101,113,63,0,2049,9816,4,2049,9816,11,10,9832,9862,168,12482,6953255788674,97,58,45,101, 113,63,0,2049,9816,4,2049,9816,12,10,9850,9889,168,12482,4448793249567199488,97,58,98,101,103, 105,110,115,45,119,105,116,104,63,0,1,3,1793,9905,2,2049,8558,1,19,2049, 2229,2049,8614,2049,9843,10,1,9893,2049,3919,10,9869,9928,168,12482,-3654621344420884174,97,58,101,110, 100,115,45,119,105,116,104,63,0,1,3,1793,9944,2,2049,8558,1,19,2049,2229, 2049,8633,2049,9843,10,1,9932,2049,3919,10,9910,9965,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,9949,10106,168,0,0,101, 120,116,114,97,99,116,0,1,9965,2049,5517,10,10093,10124,168,0,0,99,111,109, 98,105,110,101,0,1,9965,2049,4666,2049,4666,10,10111,10145,168,0,0,102,105,110, 100,45,101,110,100,0,2,2049,104,1,9965,2049,104,18,67502597,17,10,10131,10167,168, 0,0,99,108,101,97,110,0,2049,10145,1,0,4,16,10,9910,10193,168,12482,1672736740201773236, 115,58,114,101,112,108,97,99,101,45,97,108,108,0,1,3,1793,10216,2049,10106, 2049,7737,2049,4396,4,1793,10209,2049,10124,10,1,10206,2049,8737,2049,10167,10,1,10197,2049, 3919,10,10174,10239,168,0,0,99,117,114,114,101,110,116,45,108,105,110,101,0, 2049,4276,1,1025,18,10,10221,10263,168,0,0,99,111,117,110,116,45,116,111,107, 101,110,115,0,1793,10269,1,32,11,10,1,10265,2049,5282,2049,104,10,10245,10296,168, 0,0,112,114,111,99,101,115,115,45,116,111,107,101,110,115,0,1793,10324,1, 32,2049,7128,4,1793,10317,2,2049,104,2049,2740,1,417,1,17,2049,66,10,1,10305, 2049,2229,2049,3125,10,1,10298,2049,2449,2049,417,10,10174,10347,168,12482,8246849872898570441,115,58,101, 118,97,108,117,97,116,101,0,2049,10239,2049,5517,2049,10239,2,2049,10263,2049,10296,10, 10331,10367,156,0,0,76,80,0,0,10359,10379,156,0,0,73,110,100,101,120,0, 0,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,10368,10421,168,0,0,110,101,120, 116,0,3841,10367,1,10379,17,2049,3816,10,10411,10439,168,0,0,112,114,101,112,0, 1,10367,2049,3816,1,0,3841,10367,1,10379,17,16,10,10429,10462,168,0,0,100,111, 110,101,0,1,10367,2049,3833,10,10331,10474,168,12482,177646,73,0,3841,10367,1,10379,17, 15,10,10467,10488,168,12482,177647,74,0,3841,10367,1,10379,17,2049,3139,15,10,10481,10504, 168,12482,177648,75,0,3841,10367,1,10379,17,1,2,18,15,10,10497,10533,168,12482,6047344052022463093, 105,110,100,101,120,101,100,45,116,105,109,101,115,0,2049,10439,4,1793,10549,25, 33886721,1,2053,1542,2049,10421,1,10538,7,10,1,10538,8,3,2049,10462,10,10514,10569,168, 12482,229463062432404,100,101,99,105,109,97,108,0,1,10,4097,243,10,10556,10586,168,12482,6953352993994, 98,105,110,97,114,121,0,1,2,4097,243,10,10574,10602,168,12482,210722874360,111,99,116, 97,108,0,1,8,4097,243,10,10591,10616,168,12482,193493706,104,101,120,0,1,16,4097, 243,10,10607,10632,168,12482,210731100046,118,97,114,45,115,0,1,4445,2049,2229,2049,2102,10, 10621,10657,168,12482,-2634409250251928459,116,97,105,108,45,114,101,99,117,114,115,101,0,1,1793, 2049,1977,1,3,18,16,10,10639,10676,168,12482,6385224492,102,105,108,108,0,1793,10684,2049, 2217,16,2049,3125,10,1,10678,2049,2449,771,10,10666,10708,168,12482,-3171118726347914531,105,111,58,101, 110,117,109,101,114,97,116,101,0,27,10,10690,10724,168,12482,7572505472392333,105,111,58,113, 117,101,114,121,0,28,10,10710,10741,168,12482,249892680268169699,105,111,58,105,110,118,111,107, 101,0,29,10,10726,10760,168,12482,-4568031882453442320,105,111,58,115,99,97,110,45,102,111,114, 0,1,-1,4,2049,10708,1793,10791,2049,10474,2049,10724,772,67502597,11,1793,10787,1793,10782,3, 2049,10474,10,1,10778,2049,2229,10,1,10776,9,10,1,10767,2049,10533,3,10,10743,10808, 168,12482,210707166203,99,58,112,117,116,0,1793,10810,1,0,2049,10741,10,10797,10823,168,12482, 5863647,110,108,0,1,10,2049,10808,10,10815,10836,168,12482,5863816,115,112,0,1,32,2049, 10808,10,10828,10850,168,12482,193506620,116,97,98,0,1,9,2049,10808,10,10841,10866,168,12482, 210726140939,115,58,112,117,116,0,1,10808,2049,4686,10,10855,10882,168,12482,210720211334,110,58,112, 117,116,0,2049,7976,2,2049,104,1,41,2049,2241,2049,3125,1793,10902,2,15,2049,10808, 2049,3139,10,1,10895,2049,2449,3,10,10871,10919,168,12482,210726503048,114,101,115,101,116,0, 2049,1560,25,771,1,10919,7,10,10908,10943,168,12482,8246237009912977886,100,117,109,112,45,115,116, 97,99,107,0,2049,1560,25,134284547,10943,134283782,10882,2049,10836,10,10927,10962,168,12482,193470948,84, 73,66,0,1,7,15,10,1793,11005,2049,4417,69,82,82,79,82,58,32,87,111, 114,100,32,78,111,116,32,70,111,117,110,100,58,32,0,1,10970,2049,10866,2049, 10962,2049,10866,2049,10823,10,1,10968,10953,11018,168,12482,210707155874,99,58,103,101,116,0,1793, 11020,1,1,2049,10760,2049,10741,10,11007,11036,168,12482,193487813,98,121,101,0,26,10,11027, 11052,156,12482,7571133383038306,73,103,110,111,114,105,110,103,0,0,11038,11062,156,0,0,69, 79,84,0,0,11053,11076,168,0,0,118,101,114,115,105,111,110,0,3841,4,1, 100,20,10,11063,11093,168,0,0,100,111,110,101,63,0,2,4097,11062,1793,11102,1, 13,11,10,1,11098,1793,11110,1,10,11,10,1,11106,1793,11118,1,32,11,10,1, 11114,2049,2298,22,22,10,11082,11135,168,0,0,101,111,108,63,0,3841,11062,1793,11143, 1,13,11,10,1,11139,1793,11151,1,10,11,10,1,11147,2049,2255,22,10,11125,11169, 168,0,0,118,97,108,105,100,63,0,2,2049,104,2049,2812,10,11157,11190,168,0, 0,99,104,101,99,107,45,101,111,102,0,2,1793,11197,1,-1,11,10,1,11193, 1793,11205,1,4,11,10,1,11201,2049,2255,22,1,11036,9,10,11175,11222,168,0,0, 98,115,0,2049,4157,1,2,2049,2675,1793,11234,2049,4105,3,10,1,11230,9,2049,4105, 3,10,11214,11255,168,0,0,99,104,101,99,107,45,98,115,0,2,1793,11262,1, 8,11,10,1,11258,1793,11270,1,127,11,10,1,11266,2049,2255,22,1,11222,9,10, 11241,11290,168,0,0,99,104,101,99,107,0,2049,11190,2049,11255,10,11279,11310,168,0, 0,99,104,97,114,97,99,116,101,114,0,2049,11018,2,2049,4079,10,11295,11328,168, 0,0,98,117,102,102,101,114,0,1793,11338,2049,10962,2049,4179,8,2049,4041,10,1, 11330,2049,4205,10,11316,11359,168,0,0,114,101,97,100,45,116,111,107,101,110,0, 1793,11375,1793,11370,2049,11310,2049,11290,2049,11093,10,1,11363,2049,2397,10,1,11361,2049,11328, 2049,4532,10,11343,11393,168,0,0,105,110,112,117,116,0,2049,11359,2049,11169,10,11382, 11411,168,0,0,112,114,111,99,101,115,115,0,3841,11052,1793,11429,771,2049,11135,1793, 11425,1,11052,2049,3883,10,1,11420,9,10,1,11415,2049,2862,1,417,1,17,2049,66, 10,11038,11456,168,12482,8246849936849447419,115,58,103,101,116,45,119,111,114,100,0,1793,11484,1, 7,15,2049,4179,1793,11475,2049,11018,2,2049,4079,2049,11255,2049,11093,10,1,11465,2049,2397, 2049,4041,2049,4532,10,1,11458,2049,4205,10,11440,11501,168,12482,6953343520347,98,97,110,110,101, 114,0,2049,11076,2049,4417,82,69,84,82,79,32,49,50,32,40,37,110,46,37, 110,41,92,110,0,1,11505,2049,8219,2049,10866,2049,9295,2049,1545,2049,9295,18,2049,1545, 2049,4417,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,11541,2049,8219,2049,10866,10,11489,11587,168,12482, 6953744547860,108,105,115,116,101,110,0,2049,11501,2049,11393,2049,11411,1,11589,7,10,11575,11618, 156,12482,-213800119713087686,100,58,72,97,115,104,45,70,117,110,99,116,105,111,110,0,4819, 11597,11633,168,12482,7572226109254526,100,58,114,101,104,97,115,104,0,1793,11651,1793,11643,2049,190, 3841,11618,8,10,1,11637,2049,2241,2049,188,16,10,1,11635,2049,8464,10,11619,1,156, 12468,210668957237,66,85,73,76,68,0,11656,11678,168,12151,210709067314,99,111,109,109,97,0,2049, 130,10,11667,11691,168,12151,6385123288,99,111,110,115,0,2049,1977,1793,11701,4,2049,11678,2049, 11678,10,1,11695,2049,2229,10,11681,11715,168,12151,193488123,99,97,114,0,10,11706,11725,168, 12151,193488222,99,100,114,0,2049,3125,10,11716,11738,168,12151,6385108123,99,97,114,64,0,2049, 11715,15,10,11728,11752,168,12151,6385108092,99,97,114,33,0,2049,11715,16,10,11742,11766,168, 12151,6385111390,99,100,114,64,0,2049,11725,15,10,11756,11780,168,12151,6385111359,99,100,114,33, 0,2049,11725,16,10,11770,11793,168,12151,193454780,69,78,68,0,10,11784,11810,168,12151,8246317064958091121, 102,108,108,58,99,114,101,97,116,101,0,1,11793,2049,11691,10,11794,11822,156,0, 177687,114,0,18995,11794,11839,168,12151,8246317065617826724,102,108,108,58,116,111,45,101,110,100,0, 2,4097,11822,1793,11864,2049,11766,2,1,11793,12,2,1793,11857,67502597,4097,11822,10,1,11853, 1,2172,2049,66,10,1,11844,2049,2372,3841,11822,10,11823,11893,168,12151,4204933718218055169,102,108,108, 58,97,112,112,101,110,100,47,118,97,108,117,101,0,1,11793,2049,11691,4,2049, 11839,2049,11780,10,11871,11921,168,12151,-3325079438733587419,102,108,108,58,116,111,45,105,110,100,101, 120,0,1,11766,2049,2449,10,11903,11939,168,12151,229465928290674,102,108,108,58,100,101,108,0, 2049,2217,2049,3139,2049,11921,1793,11952,2049,3125,2049,11921,10,1,11947,2049,2229,2049,11780,10, 11926,11971,156,0,6952054634723,65,99,116,105,111,110,0,12323,11926,11990,168,12151,-3325080032762929022,102,108, 108,58,102,111,114,45,101,97,99,104,0,4097,11971,1793,12013,1793,12002,2049,11738,3841, 11971,8,10,1,11996,2049,2241,2049,11766,2,1,11793,12,10,1,11994,2049,2372,3,10, 11972,12035,168,12151,8246317065295222655,102,108,108,58,108,101,110,103,116,104,0,1,0,4,1793, 12044,3,2049,3125,10,1,12040,2049,11990,2049,3139,10,12019,12065,168,12151,7572375633606610,102,108,108, 58,100,114,111,112,0,2,2049,12035,2049,3139,2049,11921,1,11793,4,2049,11780,10,12051, 12085,156,0,177678,105,0,0,12051,12102,168,12151,8246317065188343290,102,108,108,58,105,110,106,101, 99,116,0,2049,11810,4097,12085,2049,2217,2049,3139,2049,11921,1,11921,2049,2229,3841,12085,4, 2049,11780,3841,12085,2049,11780,10,12086,12139,168,12151,229465928304278,102,108,108,58,112,117,116,0, 1793,12146,2049,10882,2049,10836,10,1,12141,2049,11990,10,105,110,116,101,114,102,97,99, 101,47,108,108,46,114,101,116,114,111,0,105,110,105,116,0,12170,12412,12126,12195, 156,12390,-2744922491217532500,115,58,100,101,100,117,112,46,100,97,116,97,0,12175,12177,12204,156, 0,5863786,116,49,0,508928,12196,12213,156,0,5863787,116,50,0,19846,12177,12236,168,12390,-1192507208876296873, 115,58,100,101,100,117,112,46,114,101,103,105,115,116,101,114,0,2049,4445,3841, 12195,4,1,11893,2049,2241,10,12214,12268,168,12390,-1192507805573830048,115,58,100,101,100,117,112,46, 100,101,102,105,110,101,100,63,0,4097,12204,1,0,4097,12213,3841,12195,1793,12288,3841, 12204,2049,118,3841,12213,22,4097,12213,10,1,12278,2049,11990,3841,12213,10,12246,12313,168,12390, -2744922491217452109,115,58,100,101,100,117,112,46,102,105,110,100,0,4097,12204,1,0,4097,12213, 3841,12195,1793,12340,2,3841,12204,2049,118,1793,12333,4097,12213,10,1,12330,1,17,2049,66, 10,1,12323,2049,11990,3841,12213,10,12295,12360,168,12390,229480752663076,115,58,100,101,100,117,112, 0,2049,4368,2,2049,12268,1,12313,1,12236,2049,66,10,12347,12387,168,12390,249904561963058472,115,58, 117,110,105,113,117,101,63,0,2049,12268,10,105,110,116,101,114,102,97,99,101, 47,100,101,100,117,112,46,114,101,116,114,111,0,12390,12466,12372,12432,168,12442,-3502357327552891667, 100,58,115,101,116,45,115,111,117,114,99,101,0,1,12360,2049,2229,2049,236,2049, 186,16,10,105,110,116,101,114,102,97,99,101,47,115,111,117,114,99,101,115, 46,114,101,116,114,111,0,12442,12480,98,117,105,108,100,46,114,101,116,114,111, 0,12468,12494,114,101,116,114,111,46,102,111,114,116,104,0,12482,12931,12414,0,156, 12907,-2419379730924625824,68,69,86,73,67,69,58,79,85,84,80,85,84,0,12496,1,156,12907, 3179875372589939872,68,69,86,73,67,69,58,75,69,89,66,79,65,82,68,0,12515,2,156, 12907,-2419379731287713704,68,69,86,73,67,69,58,70,76,79,65,84,83,0,12536,4,156,12907, -5104244739232646654,68,69,86,73,67,69,58,70,73,76,69,83,0,12555,3,156,12907,-2419379731444253395,68, 69,86,73,67,69,58,66,76,79,67,75,83,0,12573,5,156,12907,-5104244739236093413,68,69, 86,73,67,69,58,67,76,79,67,75,0,12592,6,156,12907,-5744567309556069531,68,69,86,73, 67,69,58,82,69,83,69,82,86,69,68,54,0,12610,7,156,12907,-2419379730775816680,68,69, 86,73,67,69,58,83,79,67,75,69,84,0,12632,8,156,12907,-4626612040269427085,68,69,86, 73,67,69,58,85,78,73,88,0,12651,9,156,12907,-5744565989521702654,68,69,86,73,67,69, 58,83,67,82,73,80,84,73,78,71,0,12668,10,156,12907,8244683305011325430,68,69,86,73, 67,69,58,82,78,71,0,12690,11,156,12907,-5103280478254778479,68,69,86,73,67,69,58,82, 69,83,69,82,86,69,68,49,49,0,12706,12,156,12907,-5103280478254778478,68,69,86,73,67, 69,58,82,69,83,69,82,86,69,68,49,50,0,12729,13,156,12907,-5103280478254778477,68,69, 86,73,67,69,58,82,69,83,69,82,86,69,68,49,51,0,12752,14,156,12907, -5104244739228882582,68,69,86,73,67,69,58,73,79,67,84,76,0,12775,15,156,12907,-2419379731026907097,68, 69,86,73,67,69,58,77,65,76,76,79,67,0,12793,1000,156,12907,-5104244739228957070,68,69, 86,73,67,69,58,73,77,65,71,69,0,12812,1234,156,12907,-5104244739233502279,68,69,86,73, 67,69,58,69,82,82,79,82,0,12830,8000,156,12907,-5744573668168662717,68,69,86,73,67,69, 58,77,85,76,84,73,67,79,82,69,0,12848,8100,156,12907,8244683305011312100,68,69,86,73, 67,69,58,70,70,73,0,12870,8101,156,12907,3179875810170796684,68,69,86,73,67,69,58,85, 78,83,73,71,78,69,68,0,105,110,116,101,114,102,97,99,101,47,100,101, 118,105,99,101,115,46,114,101,116,114,111,0,12907,15091,12886,12954,168,15061,-6845980351726443322,102, 108,111,97,116,58,111,112,101,114,97,116,105,111,110,0,1,2,2049,10760,2, 2049,2761,1793,13012,3,2049,4417,69,114,114,111,114,58,32,102,108,111,97,116,105, 110,103,32,112,111,105,110,116,32,100,101,118,105,99,101,32,110,111,116,32, 102,111,117,110,100,0,1,12966,2049,10866,2049,10823,10,1,12963,2049,2862,2049,10741,10, 12933,13035,168,15061,8246618443670464787,110,58,116,111,45,102,108,111,97,116,0,1,0,2049,12954, 10,13019,13056,168,15061,8246850501092474552,115,58,116,111,45,102,108,111,97,116,0,1,1,2049, 12954,10,13040,13078,168,15061,-4575005096076366594,102,58,116,111,45,110,117,109,98,101,114,0,1, 2,2049,12954,10,13061,13100,168,15061,-4575005095881687956,102,58,116,111,45,115,116,114,105,110,103, 0,2049,4396,2,1,3,2049,12954,10,13083,13117,168,15061,193490032,102,58,43,0,1,4, 2049,12954,10,13108,13131,168,15061,193490034,102,58,45,0,1,5,2049,12954,10,13122,13145,168, 15061,193490031,102,58,42,0,1,6,2049,12954,10,13136,13159,168,15061,193490036,102,58,47,0, 1,7,2049,12954,10,13150,13177,168,15061,229463966214663,102,58,102,108,111,111,114,0,1,8, 2049,12954,10,13164,13197,168,15061,249886255052186944,102,58,99,101,105,108,105,110,103,0,1,9, 2049,12954,10,13182,13214,168,15061,6953453994383,102,58,115,113,114,116,0,1,10,2049,12954,10, 13202,13230,168,15061,210710711802,102,58,101,113,63,0,1,11,2049,12954,10,13219,13247,168,15061, 6953451465639,102,58,45,101,113,63,0,1,12,2049,12954,10,13235,13263,168,15061,210710719524,102,58, 108,116,63,0,1,13,2049,12954,10,13252,13279,168,15061,210710714079,102,58,103,116,63,0, 1,14,2049,12954,10,13268,13297,168,15061,229463963592506,102,58,100,101,112,116,104,0,1,15, 2049,12954,10,13284,13313,168,15061,210710710894,102,58,100,117,112,0,1,16,2049,12954,10,13302, 13330,168,15061,6953453456314,102,58,100,114,111,112,0,1,17,2049,12954,10,13318,13347,168,15061, 6953454000352,102,58,115,119,97,112,0,1,18,2049,12954,10,13335,13363,168,15061,210710719399,102,58, 108,111,103,0,1,19,2049,12954,10,13352,13381,168,15061,229463978190066,102,58,112,111,119,101, 114,0,1,20,2049,12954,10,13368,13397,168,15061,210710726831,102,58,115,105,110,0,1,21, 2049,12954,10,13386,13413,168,15061,210710727656,102,58,116,97,110,0,1,22,2049,12954,10,13402, 13429,168,15061,210710709610,102,58,99,111,115,0,1,23,2049,12954,10,13418,13446,168,15061,6953453349392, 102,58,97,115,105,110,0,1,24,2049,12954,10,13434,13463,168,15061,6953453332171,102,58,97, 99,111,115,0,1,25,2049,12954,10,13451,13480,168,15061,6953453350217,102,58,97,116,97,110, 0,1,26,2049,12954,10,13468,13497,168,15061,6953453890949,102,58,112,117,115,104,0,1,27, 2049,12954,10,13485,13513,168,15061,210710723764,102,58,112,111,112,0,1,28,2049,12954,10,13502, 13532,168,15061,7572310679561435,102,58,97,100,101,112,116,104,0,1,29,2049,12954,10,13518,13549, 168,15061,6953453855649,102,58,111,118,101,114,0,2049,13497,2049,13313,2049,13513,2049,13347,10,13537, 13570,168,15061,6953454034172,102,58,116,117,99,107,0,2049,13313,2049,13497,2049,13347,2049,13513,10, 13558,13590,168,15061,210710721388,102,58,110,105,112,0,2049,13347,2049,13330,10,13579,13612,168,15061, -4575027385529052237,102,58,100,114,111,112,45,112,97,105,114,0,2049,13330,2049,13330,10,13595,13633, 168,15061,8246246480203571943,102,58,100,117,112,45,112,97,105,114,0,2049,13549,2049,13549,10,13617, 13649,168,15061,210710725946,102,58,114,111,116,0,2049,13497,2049,13347,2049,13513,2049,13347,10,13638, 13671,180,15061,229482595734757,115,105,103,105,108,58,46,0,2049,1913,1,4445,1,4368,2049,66, 1,13056,2049,168,10,13658,13698,168,15061,7572311399974070,102,58,115,113,117,97,114,101,0,2049, 13313,2049,13145,10,13684,13720,168,15061,-4575010631505066633,102,58,112,111,115,105,116,105,118,101,63, 0,1,0,2049,13035,2049,13279,10,13703,13744,168,15061,-4575013886317431657,102,58,110,101,103,97,116, 105,118,101,63,0,1,0,2049,13035,2049,13263,10,13727,13765,168,15061,7572311189563001,102,58,110, 101,103,97,116,101,0,1,-1,2049,13035,2049,13145,10,13751,13783,168,15061,210710707003,102,58, 97,98,115,0,2049,13313,2049,13744,1,13765,9,10,13772,13802,168,15061,210710723966,102,58,112, 117,116,0,2049,13100,2049,10866,10,13791,13817,168,15061,6385172350,102,58,80,73,0,2049,4417, 51,46,49,52,49,53,57,50,54,53,52,0,1,13819,2049,13056,10,13807,13845,168, 15061,193490058,102,58,69,0,2049,4417,50,46,55,49,56,50,56,49,56,50,56,0, 1,13847,2049,13056,10,13836,13875,168,15061,210710685186,102,58,78,65,78,0,2049,4417,48,0, 1,13877,2049,13056,2049,4417,48,0,1,13885,2049,13056,2049,13159,10,13864,13905,168,15061,210710680162, 102,58,73,78,70,0,2049,4417,49,46,48,0,1,13907,2049,13056,2049,4417,48,0, 1,13917,2049,13056,2049,13159,10,13894,13938,168,15061,6953451433999,102,58,45,73,78,70,0,2049, 4417,45,49,46,48,0,1,13940,2049,13056,2049,4417,48,0,1,13951,2049,13056,2049,13159, 10,13926,13972,168,15061,6953453797089,102,58,110,97,110,63,0,2049,13313,2049,13247,10,13960,13989, 168,15061,6953453631297,102,58,105,110,102,63,0,2049,13905,2049,13230,10,13977,14007,168,15061,229463898507918, 102,58,45,105,110,102,63,0,2049,13938,2049,13230,10,13994,14025,168,15061,229463980560013,102,58, 114,111,117,110,100,0,2049,13313,2049,13744,1793,14046,2049,4417,48,46,53,0,1,14033, 2049,13056,2049,13131,2049,13197,10,1,14031,1793,14065,2049,4417,48,46,53,0,1,14052,2049, 13056,2049,13117,2049,13177,10,1,14050,2049,66,10,14012,14081,168,15061,210710720297,102,58,109,105, 110,0,2049,13633,2049,13263,1,13330,1,13590,2049,66,10,14070,14103,168,15061,210710720043,102,58, 109,97,120,0,2049,13633,2049,13279,1,13330,1,13590,2049,66,10,14092,14127,168,15061,229463973220004, 102,58,108,105,109,105,116,0,2049,13347,2049,13497,2049,14081,2049,13513,2049,14103,10,14114, 14154,168,15061,8246246374547107374,102,58,98,101,116,119,101,101,110,63,0,2049,13649,2049,13313,2049, 13497,2049,13649,2049,13649,2049,14127,2049,13513,2049,13230,10,14138,14182,168,15061,210710716095,102,58,105, 110,99,0,2049,4417,49,0,1,14184,2049,13056,2049,13117,10,14171,14204,168,15061,210710710353,102, 58,100,101,99,0,2049,4417,49,0,1,14206,2049,13056,2049,13131,10,14193,14227,168,15061, 6953453401985,102,58,99,97,115,101,0,2049,13549,2049,13230,1793,14239,2049,13330,8,1,-1,10, 1,14233,1793,14247,3,1,0,10,1,14243,2049,66,25,6,771,10,14215,14267,168,15061, 6953453985302,102,58,115,105,103,110,0,2049,13313,2049,4417,48,0,1,14271,2049,13056,2049,13230, 1793,14286,1,0,2049,13330,10,1,14281,2049,2862,2049,4417,48,0,1,14292,2049,13056,2049, 13279,1793,14305,1,1,10,1,14302,1793,14312,1,-1,10,1,14309,2049,66,10,14255,9223372036854775805, 156,15061,210709498186,101,58,77,65,88,0,14317,-9223372036854775805,156,15061,210709498440,101,58,77,73,78,0, 14328,-9223372036854775807,156,15061,210709499265,101,58,78,65,78,0,14339,9223372036854775806,156,15061,210709494241,101,58,73,78, 70,0,14350,-9223372036854775806,156,15061,6953412298606,101,58,45,73,78,70,0,14361,14383,168,15061,6385137393,101, 58,110,63,0,1,-9223372036854775805,2049,3125,1,9223372036854775805,2049,3139,2049,3158,10,14373,14406,168,15061,6953414626089, 101,58,109,97,120,63,0,1,9223372036854775805,11,10,14394,14422,168,15061,6953414634471,101,58,109,105, 110,63,0,1,-9223372036854775805,11,10,14410,14439,168,15061,229462698216771,101,58,122,101,114,111,63,0, 2049,2722,10,14426,14454,168,15061,6953414661696,101,58,110,97,110,63,0,1,-9223372036854775807,11,10,14442, 14470,168,15061,6953414495904,101,58,105,110,102,63,0,1,9223372036854775806,11,10,14458,14487,168,15061,229462607039949, 101,58,45,105,110,102,63,0,1,-9223372036854775806,11,10,14474,14503,168,15061,6953414278252,101,58,99, 108,105,112,0,1,-9223372036854775805,1,9223372036854775805,2049,3106,10,14491,14520,168,15061,6385171963,102,58,69,49, 0,1793,14522,2049,4417,49,46,101,53,0,1,14524,2049,13056,10,14510,14553,168,15061,-1561378222854156682, 102,58,115,105,103,110,101,100,45,115,113,114,116,0,2049,13313,2049,14267,2049,13783, 2049,13214,2049,13035,2049,13145,10,14534,14587,168,15061,-3240429906897787043,102,58,115,105,103,110,101,100, 45,115,113,117,97,114,101,0,2049,13313,2049,14267,2049,13313,2049,13145,2049,13035,2049,13145, 10,14566,14614,168,0,7572308662409552,102,58,45,115,104,105,102,116,0,2049,14520,2049,13145,10, 14600,14633,168,0,7572308584138766,102,58,43,115,104,105,102,116,0,2049,14520,2049,13159,10,14619, 14653,168,0,249886182735593054,102,58,43,101,110,99,111,100,101,0,2049,14553,2049,14614,10,14638, 14673,168,0,249886185318528992,102,58,45,101,110,99,111,100,101,0,2049,13313,2049,14267,2049,14633, 2049,13313,2049,13145,2049,13035,2049,13145,10,14566,14700,168,15061,6953454025850,102,58,116,111,45,101, 0,2049,13313,2049,13972,1793,14711,2049,13330,1,-9223372036854775807,10,1,14706,2049,2862,2049,13313,2049,13989, 1793,14726,2049,13330,1,9223372036854775806,10,1,14721,2049,2862,2049,13313,2049,14007,1793,14741,2049,13330,1, -9223372036854775806,10,1,14736,2049,2862,2049,14653,2049,14025,2049,13078,2049,14503,1,-9223372036854775805,1,13330,2049,2554, 1,9223372036854775805,1,13330,2049,2554,10,14688,14778,168,15061,6953414890458,101,58,116,111,45,102,0,1, -9223372036854775807,1,13875,2049,2554,1,9223372036854775806,1,13905,2049,2554,1,-9223372036854775806,1,13938,2049,2554,2049,13035,2049, 14673,10,14766,14814,168,15061,229463981919218,102,58,115,116,111,114,101,0,1,14700,2049,2229,16, 10,14801,14833,168,15061,229463965968143,102,58,102,101,116,99,104,0,15,2049,14778,10,14820,14855, 168,15061,-3401946998789110658,102,58,100,117,109,112,45,115,116,97,99,107,0,2049,13297,2,1, 13497,2049,2449,1793,14873,2049,13513,2049,13313,2049,13802,2049,10836,10,1,14864,2049,2449,10,14837, 14897,168,15061,-1583786518488284545,102,58,100,117,109,112,45,97,115,116,97,99,107,0,2049,13532, 2,1,13513,2049,2449,1793,14915,2049,13313,2049,13802,2049,10836,2049,13497,10,1,14906,2049,2449, 10,14878,14931,168,15061,210709538045,101,58,112,117,116,0,1,9223372036854775805,1793,14948,2049,4417,101,58, 77,65,88,0,1,14937,2049,10866,10,1,14935,2049,2554,1,-9223372036854775805,1793,14969,2049,4417,101, 58,77,73,78,0,1,14958,2049,10866,10,1,14956,2049,2554,1,0,1793,14988,2049,4417, 101,58,48,0,1,14979,2049,10866,10,1,14977,2049,2554,1,-9223372036854775807,1793,15009,2049,4417,101, 58,78,65,78,0,1,14998,2049,10866,10,1,14996,2049,2554,1,9223372036854775806,1793,15030,2049,4417, 101,58,73,78,70,0,1,15019,2049,10866,10,1,15017,2049,2554,1,-9223372036854775806,1793,15052,2049, 4417,101,58,45,73,78,70,0,1,15040,2049,10866,10,1,15038,2049,2554,2049,14778,2049, 13802,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,15061,15938,14920,15113,168,15911,8056574075740390096,102, 105,108,101,58,111,112,101,114,97,116,105,111,110,0,1,4,2049,10760,2,2049, 2761,1793,15162,3,2049,4417,69,114,114,111,114,58,32,102,105,108,101,115,32,100, 101,118,105,99,101,32,110,111,116,32,102,111,117,110,100,0,1,15125,2049,10866, 2049,10823,10,1,15122,2049,2862,2049,10741,10,15093,0,156,15911,6953509466161,102,105,108,101,58, 82,0,15169,1,156,15911,6953509466166,102,105,108,101,58,87,0,15181,2,156,15911,6953509466144,102, 105,108,101,58,65,0,15193,3,156,15911,229465812383356,102,105,108,101,58,82,43,0,15205, 15233,168,15911,249888269686595441,102,105,108,101,58,111,112,101,110,0,1,0,2049,15113,10,15218, 15254,168,15911,8246312899643285909,102,105,108,101,58,99,108,111,115,101,0,1,1,2049,15113,10, 15238,15274,168,15911,249888269686691131,102,105,108,101,58,114,101,97,100,0,1,2,2049,15113,10, 15259,15295,168,15911,8246312899667213450,102,105,108,101,58,119,114,105,116,101,0,1,3,2049,15113, 10,15279,15315,168,15911,249888269686763376,102,105,108,101,58,116,101,108,108,0,1,4,2049,15113, 10,15300,15335,168,15911,249888269686727207,102,105,108,101,58,115,101,101,107,0,1,5,2049,15113, 10,15320,15355,168,15911,249888269686732250,102,105,108,101,58,115,105,122,101,0,1,6,2049,15113, 10,15340,15377,168,15911,-4572835417384127758,102,105,108,101,58,100,101,108,101,116,101,0,1,7, 2049,15113,10,15360,15398,168,15911,8246312899646850209,102,105,108,101,58,102,108,117,115,104,0,1, 8,2049,15113,10,15382,15424,168,15911,7612651040925696305,102,105,108,101,58,114,101,97,100,47,98, 121,116,101,115,0,1,9,2049,15113,10,15403,15451,168,15911,-7028659436281878592,102,105,108,101,58, 119,114,105,116,101,47,98,121,116,101,115,0,1,10,2049,15113,10,15429,15473,168, 15911,-4572835416836630931,102,105,108,101,58,114,101,97,100,47,99,0,1,11,2049,15113,10,15456, 15496,168,15911,-3329616158956188292,102,105,108,101,58,119,114,105,116,101,47,99,0,1,12,2049, 15113,10,15478,15519,168,15911,-3329616181967816770,102,105,108,101,58,101,120,105,115,116,115,63,0, 1,0,2049,15233,2,2049,2740,1793,15533,2049,15254,2049,2527,10,1,15528,1793,15541,3,2049, 2541,10,1,15537,2049,66,10,15501,15573,168,15911,-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,15233,2,2049, 15355,4,10,15546,15608,168,15911,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,15233,2,2049,15355,4,10,15582,15644, 168,15911,-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,15233,10,15617,15658,156,0,193455704,70,73,68,0,0, 15649,15669,156,0,6384542144,83,105,122,101,0,0,15659,15682,156,0,6952054634723,65,99,116,105, 111,110,0,0,15670,15694,168,0,210644670123,45,101,111,102,63,0,3841,15658,2049,15315,3841, 15669,13,10,15683,15716,168,0,7572809360530097,112,114,101,115,101,114,118,101,0,1,15658,1793, 15727,1,15669,1,27,2049,3919,10,1,15720,2049,3919,10,15617,15752,168,15911,8056577820387649264,102,105, 108,101,58,114,101,97,100,45,108,105,110,101,0,2049,1977,4,1,13,2049,15113, 2049,1977,10,15732,15786,168,15911,-8859848394595038695,102,105,108,101,58,102,111,114,45,101,97,99, 104,45,108,105,110,101,0,1793,15817,4097,15682,2049,15573,4097,15658,4097,15669,1793,15808,3841, 15658,2049,15752,3841,15682,8,2049,15694,10,1,15798,2049,2372,3841,15658,2049,15254,10,1,15788, 2049,15716,10,15762,15831,156,0,193455704,70,73,68,0,0,15762,15848,168,15911,8246312899662267157,102,105, 108,101,58,115,108,117,114,112,0,1793,15875,4,2049,4179,2049,15573,4097,15831,1793,15866, 3841,15831,2049,15274,2049,4079,10,1,15859,2049,2449,3841,15831,2049,15254,10,1,15850,2049,4205, 10,15832,15895,168,15911,249888269686739198,102,105,108,101,58,115,112,101,119,0,2049,15644,4,1793, 15904,67502597,2049,15295,10,1,15900,2049,4686,2049,15254,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,15911, 16675,15880,15961,168,16654,4299348465103751587,105,111,58,117,110,105,120,45,115,121,115,99,97,108, 108,0,1,8,2049,10760,2,2049,2761,1793,16009,3,2049,4417,69,114,114,111,114,58, 32,85,78,73,88,32,100,101,118,105,99,101,32,110,111,116,32,102,111,117, 110,100,0,1,15973,2049,10866,2049,10823,10,1,15970,2049,2862,2049,10741,10,15940,16033,168, 16654,-4549633084047572696,117,110,105,120,58,115,121,115,116,101,109,0,1,0,2049,15961,10,16016, 16053,168,16654,249909575776928405,117,110,105,120,58,102,111,114,107,0,1,1,2049,15961,10,16038, 16074,168,16654,8247016000637760504,117,110,105,120,58,101,120,101,99,48,0,1,2,2049,15961,10, 16058,16095,168,16654,8247016000637760505,117,110,105,120,58,101,120,101,99,49,0,1,3,2049,15961, 10,16079,16116,168,16654,8247016000637760506,117,110,105,120,58,101,120,101,99,50,0,1,4,2049, 15961,10,16100,16137,168,16654,8247016000637760507,117,110,105,120,58,101,120,101,99,51,0,1,5, 2049,15961,10,16121,16157,168,16654,249909575776901981,117,110,105,120,58,101,120,105,116,0,1,6, 2049,15961,10,16142,16179,168,16654,-4549633084540884128,117,110,105,120,58,103,101,116,112,105,100,0, 1,7,2049,15961,10,16162,16199,168,16654,249909575777523800,117,110,105,120,58,119,97,105,116,0, 1,8,2049,15961,10,16184,16219,168,16654,249909575777101359,117,110,105,120,58,107,105,108,108,0, 1,9,2049,15961,10,16204,16240,168,16654,8247016000650494309,117,110,105,120,58,112,111,112,101,110, 0,1,10,2049,15961,10,16224,16262,168,16654,-4549633084191325687,117,110,105,120,58,112,99,108,111, 115,101,0,1,11,2049,15961,10,16245,16283,168,16654,8247016000634812845,117,110,105,120,58,99,104, 100,105,114,0,1,13,2049,15961,10,16267,16305,168,16654,-4549633084540895924,117,110,105,120,58,103, 101,116,101,110,118,0,1,14,2049,15961,10,16288,16327,168,16654,-4549633084169702651,117,110,105,120, 58,112,117,116,101,110,118,0,1,15,2049,15961,10,16310,16348,168,16654,8247016000653932284,117,110, 105,120,58,115,108,101,101,112,0,1,16,2049,15961,10,16332,16371,168,16654,-2563939202030369066,117, 110,105,120,58,101,120,101,99,117,116,101,0,1,17,2049,15961,10,16353,16391,168, 16654,249909575777281169,117,110,105,120,58,112,105,112,101,0,1,0,2049,16240,1,15752,1,16262, 2049,2255,10,16376,16420,168,16654,-2563939200175176882,117,110,105,120,58,103,101,116,45,99,119,100, 0,2049,4417,112,119,100,0,1,16422,2049,16391,2049,6999,2049,4417,47,0,1,16434,2049, 4666,10,16402,16470,168,16654,-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,4417,108,115,32,45,49,32,124, 32,119,99,32,45,108,0,1,16472,2049,16391,2049,6999,2049,266,10,16441,16519,168,16654, -4594486429310984907,117,110,105,120,58,102,111,114,45,101,97,99,104,45,102,105,108,101,0, 2049,4417,108,115,32,45,49,32,45,112,0,1,16521,1,0,2049,16240,2049,16470,1793, 16554,1793,16549,2049,15752,2049,4368,67502597,8,10,1,16542,2049,2241,10,1,16540,2049,2449,2049, 16262,3,10,16495,16573,168,0,210728208851,115,116,97,114,116,0,4,2049,4179,1,0,2049, 16240,10,16562,16591,168,0,6385651009,114,101,97,100,0,2,2049,15274,2,2049,4079,2049,2722, 10,16581,16612,168,0,6953509544294,102,105,110,105,115,104,0,2049,16262,2049,4157,10,16495,16638, 168,16654,1204178398703148788,117,110,105,120,58,115,108,117,114,112,45,112,105,112,101,0,1793, 16649,2049,16573,1,16591,2049,2397,2049,16612,10,1,16640,2049,4205,10,105,110,116,101,114, 102,97,99,101,47,117,110,105,120,46,114,101,116,114,111,0,16654,16765,16617,16691, 168,16745,7572652289159374,110,58,114,97,110,100,111,109,0,1,10,2049,10760,2,2049,2761,1793, 16738,3,2049,4417,69,114,114,111,114,58,32,82,78,71,32,100,101,118,105,99, 101,32,110,111,116,32,102,111,117,110,100,0,1,16703,2049,10866,2049,10823,10,1, 16700,2049,2862,2049,10741,10,105,110,116,101,114,102,97,99,101,47,114,110,103,46, 114,101,116,114,111,0,16745,17176,16677,16788,168,17154,4482520117059041020,99,108,111,99,107,58,111, 112,101,114,97,116,105,111,110,0,1,5,2049,10760,2,2049,2761,1793,16837,3,2049, 4417,69,114,114,111,114,58,32,99,108,111,99,107,32,100,101,118,105,99,101, 32,110,111,116,32,102,111,117,110,100,0,1,16800,2049,10866,2049,10823,10,1,16797, 2049,2862,2049,10741,10,16767,16865,168,17154,4482526860617352831,99,108,111,99,107,58,116,105,109,101, 115,116,97,109,112,0,1,0,2049,16788,10,16844,16885,168,17154,249884182168395049,99,108,111,99, 107,58,100,97,121,0,1,1,2049,16788,10,16870,16907,168,17154,-4577286724249897519,99,108,111,99, 107,58,109,111,110,116,104,0,1,2,2049,16788,10,16890,16928,168,17154,8246178011557794972,99,108, 111,99,107,58,121,101,97,114,0,1,3,2049,16788,10,16912,16949,168,17154,8246178011557195593,99, 108,111,99,107,58,104,111,117,114,0,1,4,2049,16788,10,16933,16972,168,17154,-3476509310577319139, 99,108,111,99,107,58,109,105,110,117,116,101,0,1,5,2049,16788,10,16954,16995, 168,17154,-3476509310347652505,99,108,111,99,107,58,115,101,99,111,110,100,0,1,6,2049,16788, 10,16977,17019,168,17154,-4044342796047171665,99,108,111,99,107,58,117,116,99,58,100,97,121,0, 1,7,2049,16788,10,17000,17045,168,17154,4482528721224061399,99,108,111,99,107,58,117,116,99,58, 109,111,110,116,104,0,1,8,2049,16788,10,17024,17070,168,17154,-4336103753589045278,99,108,111,99, 107,58,117,116,99,58,121,101,97,114,0,1,9,2049,16788,10,17050,17095,168,17154, -4336103753589644657,99,108,111,99,107,58,117,116,99,58,104,111,117,114,0,1,10,2049,16788, 10,17075,17122,168,17154,349495210710499299,99,108,111,99,107,58,117,116,99,58,109,105,110,117, 116,101,0,1,11,2049,16788,10,17100,17149,168,17154,349495210940165933,99,108,111,99,107,58,117, 116,99,58,115,101,99,111,110,100,0,1,12,2049,16788,10,105,110,116,101,114, 102,97,99,101,47,99,108,111,99,107,46,114,101,116,114,111,0,17154,17578,17127, 17200,168,0,1976442044545254821,115,99,114,105,112,116,58,111,112,101,114,97,116,105,111,110, 0,1,9,2049,10760,2,2049,2761,1793,17253,3,2049,4417,69,114,114,111,114,58,32, 115,99,114,105,112,116,105,110,103,32,100,101,118,105,99,101,32,110,111,116, 32,102,111,117,110,100,0,1,17212,2049,10866,2049,10823,10,1,17209,2049,2862,2049,10741, 10,17127,17282,168,17552,1976422442775525130,115,99,114,105,112,116,58,97,114,103,117,109,101,110, 116,115,0,1,0,2049,17200,10,17260,17312,168,17552,7012485947518414468,115,99,114,105,112,116,58, 103,101,116,45,97,114,103,117,109,101,110,116,0,2049,4396,4,1,1,2049,17200, 10,17287,17333,168,17552,229469872107401,105,110,99,108,117,100,101,0,1,2,2049,17200,10,17320, 17355,168,17552,-4553194680242110987,115,99,114,105,112,116,58,110,97,109,101,0,2049,4396,1,3, 2049,17200,10,17338,17387,168,17552,6834827170184619652,115,99,114,105,112,116,58,99,117,114,114,101, 110,116,45,102,105,108,101,0,2049,4396,1,4,2049,17200,10,17362,17419,180,17552,6834827170184835340, 115,99,114,105,112,116,58,99,117,114,114,101,110,116,45,108,105,110,101,0, 1,5,2049,17200,2049,156,10,17394,17452,168,17552,-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,17200,10,17426,17483, 168,17552,-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,17200,10,17457,17499,168,17552,210706230653,97,98,111,114,116,0, 1,149,2049,3883,1,8,2049,17200,10,17488,17538,168,17552,-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, 4396,1793,17547,1,9,2049,17200,10,1,17542,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,17552, 18034,17508,17602,168,18036,1183117598919957017,115,111,99,107,101,116,58,111,112,101,114,97,116,105, 111,110,0,1,7,2049,10760,2,2049,2761,1793,17759,3,2049,4417,69,114,114,111,114, 58,32,115,111,99,107,101,116,32,100,101,118,105,99,101,32,110,111,116,32, 102,111,117,110,100,0,1,17614,2049,10866,2049,10823,2049,4417,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,17653,2049,10866,2049,10823,2049,4417,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,17714,2049,10866,2049,10823,10, 1,17611,2049,2862,2049,10741,10,17580,17792,168,18010,-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,17602,10,17766,17816, 168,18010,4328757989659661596,115,111,99,107,101,116,58,99,114,101,97,116,101,0,1,1,2049, 17602,10,17797,17838,168,18010,-4552658767528245371,115,111,99,107,101,116,58,98,105,110,100,0,1, 2,2049,17602,10,17821,17862,168,18010,4328757990001730167,115,111,99,107,101,116,58,108,105,115,116, 101,110,0,1,3,2049,17602,10,17843,17886,168,18010,4328757989563534360,115,111,99,107,101,116,58, 97,99,99,101,112,116,0,1,4,2049,17602,10,17867,17911,168,18010,-4724938931013862254,115,111,99, 107,101,116,58,99,111,110,110,101,99,116,0,1,5,2049,17602,10,17891,17933,168, 18010,-4552658767527638798,115,111,99,107,101,116,58,115,101,110,100,0,1,6,2049,17602,10,17916, 17955,168,18010,-4552658767527675080,115,111,99,107,101,116,58,114,101,99,118,0,1,7,2049,17602, 10,17938,17978,168,18010,-2663786738754388898,115,111,99,107,101,116,58,99,108,111,115,101,0,1, 8,2049,17602,10,17960,18005,168,18010,1183100690560715498,115,111,99,107,101,116,58,99,111,110,102, 105,103,117,114,101,0,1,9,2049,17602,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,18010,18053,115,111,99, 107,101,116,58,111,112,101,114,97,116,105,111,110,0,18036,18263,17983,18068,168,18237, 229469862290528,105,111,58,99,111,114,101,0,1,8000,2049,10760,2049,10741,10,18055,18090,168,18237, 249884313919988732,99,111,114,101,58,105,110,105,116,0,1,0,2049,18068,10,18075,18111,168,18237, 8246182359371694326,99,111,114,101,58,115,116,97,114,116,0,1,1,2049,18068,10,18095,18132,168, 18237,8246182359367475558,99,111,114,101,58,112,97,117,115,101,0,1,2,2049,18068,10,18116,18161, 168,18237,8337299194488917014,99,111,114,101,58,112,97,117,115,101,45,99,117,114,114,101,110, 116,0,1,3,2049,18068,10,18137,18183,168,18237,-4577143246433635687,99,111,114,101,58,114,101,115, 117,109,101,0,1,4,2049,18068,10,18166,18207,168,18237,-3888095465377135055,99,111,114,101,58,114, 101,97,100,47,114,101,103,0,1,5,2049,18068,10,18188,18232,168,18237,820065755623810592,99,111, 114,101,58,119,114,105,116,101,47,114,101,103,0,1,6,2049,18068,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,18237,18420,18212,18284,168,18400,644988671245709381,102,102,105,58,111,112,101,114,97, 116,105,111,110,0,1,8100,2049,10760,2,2049,2761,1793,18331,3,2049,4417,69,114,114, 111,114,58,32,70,70,73,32,100,101,118,105,99,101,32,110,111,116,32,102, 111,117,110,100,0,1,18296,2049,10866,2049,10823,10,1,18293,2049,2862,2049,10741,10,18265, 18352,168,18400,7572367767785414,102,102,105,58,111,112,101,110,0,1,0,2049,18284,10,18338,18374, 168,18400,-4572980637897979592,102,102,105,58,109,97,112,45,115,121,109,0,1,1,2049,18284,10, 18357,18395,168,18400,8246308498881747296,102,102,105,58,105,110,118,111,107,101,0,1,2,2049,18284, 10,105,110,116,101,114,102,97,99,101,47,102,102,105,46,114,101,116,114,111, 0,18400,18751,18379,18438,168,18726,8247016409221251463,117,110,115,105,103,110,101,100,58,43,0,1, 0,1,8101,2049,10760,2049,10741,17,10,18422,18464,168,18726,8247016409221251465,117,110,115,105,103,110, 101,100,58,45,0,1,0,1,8101,2049,10760,2049,10741,18,10,18448,18490,168,18726,8247016409221251462, 117,110,115,105,103,110,101,100,58,42,0,1,0,1,8101,2049,10760,2049,10741,19, 10,18474,18519,168,18726,7638409966457829387,117,110,115,105,103,110,101,100,58,47,109,111,100,0, 1,0,1,8101,2049,10760,2049,10741,20,10,18500,18547,168,18726,-2563494254608726831,117,110,115,105,103, 110,101,100,58,101,113,63,0,1,0,1,8101,2049,10760,2049,10741,11,10,18529,18576, 168,18726,7638409966457748830,117,110,115,105,103,110,101,100,58,45,101,113,63,0,1,0,1, 8101,2049,10760,2049,10741,12,10,18557,18604,168,18726,-2563494254608719109,117,110,115,105,103,110,101,100, 58,108,116,63,0,1,0,1,8101,2049,10760,2049,10741,13,10,18586,18632,168,18726,-2563494254608724554, 117,110,115,105,103,110,101,100,58,103,116,63,0,1,0,1,8101,2049,10760,2049, 10741,14,10,18614,18662,168,18726,-6186888138744896262,117,110,115,105,103,110,101,100,58,115,104,105, 102,116,0,1,0,1,8101,2049,10760,2049,10741,24,10,18642,18692,168,18726,-6186888138833512267,117,110, 115,105,103,110,101,100,58,42,47,109,111,100,0,1,1,1,0,1,8101,2049, 10760,2,2049,10741,2049,10741,10,18672,18717,168,18726,210639169918,42,47,109,111,100,0,1,1, 1,8101,2049,10760,2049,10741,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,18726,18877,18706,18771,168,18854,-3502245454587251943,100, 58,117,115,101,45,104,97,115,104,101,115,0,1,29,1,236,1,5,18,16, 1793,18785,2049,188,15,10,1,18781,1,236,1,8,18,16,1,2049,1,236,16,1, 4819,1,236,2049,3125,16,10,18753,18825,168,18854,-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,105,110,116,101,114, 102,97,99,101,47,102,117,116,117,114,101,46,114,101,116,114,111,0,18854,18995, 18806,18897,168,0,-3527051417241377258,98,108,111,99,107,58,105,110,118,111,107,101,0,1,3, 2049,10760,2049,10741,10,18806,18920,168,18972,8246131600073141446,98,108,111,99,107,58,114,101,97,100, 0,1,0,2049,18897,10,18904,18942,168,18972,-4578818303223200395,98,108,111,99,107,58,119,114,105, 116,101,0,1,1,2049,18897,10,18925,18967,168,18972,-4036225629868593021,98,108,111,99,107,58,115, 101,116,45,102,105,108,101,0,1,2,2049,18897,10,105,110,116,101,114,102,97, 99,101,47,98,108,111,99,107,115,46,114,101,116,114,111,0,18972,19870,18947,19018, 168,19242,4283726481136624767,101,114,114,58,115,101,116,45,104,97,110,100,108,101,114,0,1, 1234,2049,10760,2,2049,2761,1793,19076,3,2049,4417,69,114,114,111,114,58,32,101,114, 114,111,114,32,104,97,110,100,108,105,110,103,32,100,101,118,105,99,101,32, 110,111,116,32,102,111,117,110,100,0,1,19030,2049,10866,2049,10823,10,1,19027,2049, 2862,1,0,4,2049,10741,10,18997,19099,168,19242,229464878751060,101,114,114,58,100,115,117,0, 2049,10919,2049,10823,2049,4417,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, 19105,2049,10866,2049,10823,2049,11036,10,19086,19160,168,19242,229464878751054,101,114,114,58,100,115,111, 0,2049,10919,2049,10823,2049,4417,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, 19166,2049,10866,2049,10823,2049,11036,10,19147,19229,168,19242,-6210978877792005319,101,114,114,58,115,101,116, 45,100,101,102,97,117,108,116,115,0,1,19099,1,1,2049,19018,1,19160,1,2, 2049,19018,10,105,110,116,101,114,102,97,99,101,47,101,114,114,111,114,46,114, 101,116,114,111,0,19207,19285,168,0,-1159954141530329845,105,111,99,116,108,58,111,112,101,114, 97,116,105,111,110,0,1,14,2049,10760,2,2049,2761,1793,19334,3,2049,4417,69,114, 114,111,114,58,32,105,111,99,116,108,32,100,101,118,105,99,101,32,110,111, 116,32,102,111,117,110,100,0,1,19297,2049,10866,2049,10823,10,1,19294,2049,2862,2049, 10741,10,19264,19362,168,0,-1159947561758408230,105,111,99,116,108,58,116,101,114,109,45,115,105, 122,101,0,1,0,2049,19285,10,19341,19389,168,0,-1384827797416383269,105,111,99,116,108,58,115, 101,116,45,99,98,114,101,97,107,0,1,1,2049,19285,10,19367,19416,168,0,-1384827797064164732, 105,111,99,116,108,58,115,101,116,45,108,98,114,101,97,107,0,1,2,2049, 19285,10,19394,19443,168,0,-1384833267584846441,105,111,99,116,108,58,115,97,118,101,45,115,116, 97,116,101,0,1,3,2049,19285,10,19421,19473,168,0,1092846777098631660,105,111,99,116,108,58, 114,101,115,116,111,114,101,45,115,116,97,116,101,0,1,4,2049,19285,10,1793, 19499,1,192,1,2,17,8,2049,1576,2049,190,3841,11618,8,2049,1576,2049,188,16,10, 1,19480,19448,19511,168,19846,6384117006,72,79,77,69,0,2049,1977,1,4096,17,10,37,115, 47,46,99,111,110,102,105,103,47,114,101,116,114,111,102,111,114,116,104,47, 108,105,98,114,97,114,121,47,37,115,46,114,101,116,114,111,0,19501,19517,156, 19846,6061648467740287960,108,105,98,114,97,114,121,58,46,67,79,78,70,73,71,0,46,47, 108,105,98,114,97,114,121,47,37,115,46,114,101,116,114,111,0,19556,19577,156, 19846,-4563659402581934926,108,105,98,114,97,114,121,58,67,87,68,0,19596,19630,168,19846,-4563659402581898990,108, 105,98,114,97,114,121,58,99,119,100,0,1,19577,2049,8219,10,19613,19656,168,19846, 6061648469031755928,108,105,98,114,97,114,121,58,46,99,111,110,102,105,103,0,2049,4417,72, 79,77,69,0,1,19658,2049,19511,2049,16305,2049,19511,1,19517,2049,8219,10,19635,19698,168, 19846,-2879782938503308011,108,105,98,114,97,114,121,58,102,105,108,101,110,97,109,101,0,2, 2049,19630,2,2049,15519,1793,19708,772,10,1,19706,2049,2862,3,2049,19656,2,2049,15519,1793, 19721,10,1,19720,2049,2862,3,2049,4396,10,19676,19752,168,19846,-2799120562421764174,108,105,98,114,97, 114,121,58,99,111,110,116,97,105,110,115,63,0,1,19630,1,19656,2049,2255,1, 15519,2049,2285,22,10,19729,19782,168,19846,-3026807695525939020,108,105,98,114,97,114,121,58,108,111, 97,100,0,2,2049,19752,1793,19792,2049,19698,2049,17333,10,1,19787,1793,19841,2049,4417,69, 82,82,79,82,58,32,76,105,98,114,97,114,121,32,96,37,115,96,32,119, 97,115,32,110,111,116,32,102,111,117,110,100,0,1,19798,2049,8219,2049,10866,2049, 10823,10,1,19796,2049,66,10,105,110,116,101,114,102,97,99,101,47,108,105,98, 114,97,114,121,46,114,101,116,114,111,0,19846,11793,19764,19888,168,20095,8246457295145463473,105,109, 97,103,101,58,115,97,118,101,0,1,1000,2049,10760,2049,10741,10,19872,19906,168,0, 210711039690,101,100,105,116,63,0,2,1793,19913,1,8,11,10,1,19909,1793,19921,1,127, 11,10,1,19917,2049,2255,22,10,19895,19939,168,0,6953539406400,103,97,116,104,101,114,0, 2049,19906,1,17,1,4079,2049,66,10,19927,19959,168,0,210709415765,99,121,99,108,101,0, 2049,11018,2049,2217,4,8,2049,2644,25,3,2049,19939,1,19959,7,10,19872,19992,168,20095, -4557881830897049127,112,97,114,115,101,45,117,110,116,105,108,0,1793,20004,2049,4396,2049,4179,2049, 19959,771,2049,4041,10,1,19994,2049,4205,10,19975,20020,168,20095,210726130610,115,58,103,101,116, 0,1793,20042,1793,20028,1,13,11,10,1,20024,1793,20036,1,10,11,10,1,20032,2049, 2255,22,10,1,20022,2049,19992,10,20009,20058,168,20095,210708950412,99,108,101,97,114,0,2049, 4417,92,94,91,50,74,92,94,91,48,59,48,72,0,1,20060,2049,8219,2049,10866, 10,20047,20088,180,20095,5861507,47,47,0,2049,17452,1,11052,2049,3868,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,20080,20135,156,0,229441520490121,83,111,117,114,99,101,115,0,3,20384,20578,20769, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,20122,20275,168,0,6953711201841,107,110,111,119,110,63,0,2,1,20135,2049, 9059,10,20263,20292,168,0,210716136861,105,110,100,101,120,0,1,20135,4,2049,9699,1,20135, 4,2049,9205,10,20281,20315,168,0,6953974036516,114,101,99,111,114,100,0,2049,4445,2,1, 20135,2049,3816,3841,20135,1,20135,17,16,10,1793,20382,2049,17387,2049,20275,1793,20340,2049,20292, 10,1,20337,1793,20347,2049,20315,10,1,20344,2049,66,1793,20360,1,192,1,2,17,8, 10,1,20353,2049,2229,2049,1576,2049,186,16,2049,1576,2049,190,3841,11618,8,2049,1576,2049, 188,16,10,1,20331,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,20080,20422,168,20384,229461403550098,100,58,119,111,114, 100,115,0,1793,20431,2049,190,2049,10866,2049,10836,10,1,20424,2049,8464,10,20409,20454,168, 20384,-3502157631813457253,100,58,119,111,114,100,115,45,119,105,116,104,0,2049,1977,2049,5517,1793, 20485,2049,190,2,2049,1977,2049,5230,1793,20474,2049,10866,2049,10836,10,1,20469,1793,20480,3, 10,1,20478,2049,66,10,1,20460,2049,8464,10,20436,20511,168,20384,2818131571306626127,100,105,115,112, 108,97,121,45,105,102,45,108,101,102,116,0,2,2049,1977,2049,5463,1793,20523,2049, 10866,2049,10836,10,1,20518,1793,20529,3,10,1,20527,2049,66,10,20436,20562,168,20384,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,5517,1793,20573,2049,190,2049,20511,10,1,20568,2049,8464,10,101, 120,116,101,110,115,105,111,110,115,47,100,111,117,98,108,101,46,114,101,116, 114,111,0,20534,20618,168,20578,8246228896775126019,100,111,117,98,108,101,58,118,97,114,0,2049, 2075,4,2049,130,2049,130,10,20602,20644,168,20578,-3421095308458227740,100,111,117,98,108,101,58,102, 101,116,99,104,0,2049,58,4,15,10,20626,20667,168,20578,-3421095308442276665,100,111,117,98,108, 101,58,115,116,111,114,101,0,1,19,2049,2229,2049,61,16,10,20649,20693,168,20578, -3421095308461432127,100,111,117,98,108,101,58,99,111,110,115,116,0,2049,20618,1,20644,2049,8433, 10,20675,20717,168,20578,-4575607512064199915,100,111,117,98,108,101,58,115,119,97,112,0,67503109,5, 67503109,6,10,20700,20738,168,20578,8246228896775106679,100,111,117,98,108,101,58,100,105,112,0,67503109, 67503109,5,5,8,6,6,10,20722,20762,168,20578,8246228896775123014,100,111,117,98,108,101,58,115, 105,112,0,1,2217,2049,2229,2049,20738,10,101,120,116,101,110,115,105,111,110,115, 47,109,97,108,108,111,99,46,114,101,116,114,111,0,20746,20809,168,20769,8246632143337714634,109, 101,109,58,105,110,118,111,107,101,0,1,15,2049,10760,2049,10741,10,20793,0,156, 20769,210667451248,65,76,76,79,67,0,20816,1,156,20769,6384048135,70,82,69,69,0,20827,2, 156,20769,210689088690,83,84,79,82,69,0,20837,3,156,20769,210673137615,70,69,84,67,72,0, 20848,4,156,20769,6952683137271,82,69,83,73,90,69,0,20746,20886,168,20769,249897943727936361,109,101,109, 58,97,108,108,111,99,0,1,0,2049,20809,10,20871,20906,168,20769,249897943749573803,109,101,109, 58,115,116,111,114,101,0,1,2,2049,20809,10,20891,20926,168,20769,249897943733622728,109,101,109, 58,102,101,116,99,104,0,1,3,2049,20809,10,20911,20945,168,20769,7572664961638592,109,101,109, 58,102,114,101,101,0,1,1,2049,20809,10,20931,20966,168,20769,8246632143679146032,109,101,109,58, 114,101,115,105,122,101,0,1,4,2049,20809,10,20950,20986,168,20769,249897943730056489,109,101,109, 58,99,101,108,108,43,0,1,8,19,17,10,20971,21013,168,20769,1050530996183190288,109,101,109, 58,102,101,116,99,104,45,100,111,117,98,108,101,0,2,1,1,2049,20986,15, 5,2049,20926,6,10,20991,21046,168,20769,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,20986,6,2049,20906,6,2049, 20906,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, 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]; }; #define V void #define IO(name) void io_name(NgaState *); void query_name(NgaState *); /* Function Prototypes ----------------------------------------------- */ V handle_error(NgaState *, CELL); CELL stack_pop(NgaState *); V stack_push(NgaState *, CELL); CELL string_inject(NgaState *, char *, CELL); char *string_extract(NgaState *, CELL); V update_rx(NgaState *); V include_file(NgaState *, char *, int); V include_plain_file(NgaState *, char *, int); V register_device(NgaState *, V *, V *); IO(output) IO(keyboard) IO(filesystem) IO(scripting) IO(rng) IO(unsigned) #ifdef ENABLE_UNIX IO(unix) #endif #ifdef ENABLE_FLOATS IO(floatingpoint) #endif #ifdef ENABLE_SOCKETS IO(socket) #endif #ifdef ENABLE_MALLOC #ifdef BIT64 IO(malloc) #endif #endif #ifdef ENABLE_BLOCKS IO(blocks) #endif #ifdef ENABLE_IOCTL IO(ioctl) #endif IO(image) V load_embedded_image(NgaState *); CELL load_image(NgaState *, char *); V prepare_vm(NgaState *); V process_opcode_bundle(NgaState *, CELL); #ifndef BRANCH_PREDICTION V validate_opcode_bundle(NgaState *, CELL); #endif #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 V i_no(NgaState *); V i_li(NgaState *); V i_du(NgaState *); V i_dr(NgaState *); V i_sw(NgaState *); V i_pu(NgaState *); V i_po(NgaState *); V i_ju(NgaState *); V i_ca(NgaState *); V i_cc(NgaState *); V i_re(NgaState *); V i_eq(NgaState *); V i_ne(NgaState *); V i_lt(NgaState *); V i_gt(NgaState *); V i_fe(NgaState *); V i_st(NgaState *); V i_ad(NgaState *); V i_su(NgaState *); V i_mu(NgaState *); V i_di(NgaState *); V i_an(NgaState *); V i_or(NgaState *); V i_xo(NgaState *); V i_sh(NgaState *); V i_zr(NgaState *); V i_ha(NgaState *); V i_ie(NgaState *); V i_iq(NgaState *); V i_ii(NgaState *); /* Image, Stack, and VM variables ------------------------------------ */ #define TOS ACTIVE.data[ACTIVE.sp] #define NOS ACTIVE.data[ACTIVE.sp-1] #define TORS ACTIVE.address[ACTIVE.rp] /* Global Variables -------------------------------------------------- */ int verbose; #ifndef BRANCH_PREDICTION V guard(NgaState *vm, int n, int m, int diff) { if (ACTIVE.sp < n) { #ifdef ENABLE_ERROR if (vm->ErrorHandlers[1] != 0) { handle_error(vm, 1); } #else printf("E: Data Stack Underflow"); ACTIVE.sp = 0; return; #endif } if (((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"); ACTIVE.sp = 0; return; #endif } if (diff) { if (ACTIVE.rp + diff < 0) { #ifdef ENABLE_ERROR if (vm->ErrorHandlers[3] != 0) { handle_error(vm, 3); } #else return; #endif } if (ACTIVE.rp + diff > (ADDRESSES - 1)) { #ifdef ENABLE_ERROR if (vm->ErrorHandlers[1] != 4) { handle_error(vm, 4); } #else return; #endif } } } #else V guard(NgaState *vm, int n, int m, int diff) { if (unlikely(ACTIVE.sp < n)) { #ifdef ENABLE_ERROR if (vm->ErrorHandlers[1] != 0) { handle_error(vm, 1); } #else printf("E: Data Stack Underflow"); ACTIVE.sp = 0; return; #endif } if (unlikely(((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"); ACTIVE.sp = 0; return; #endif } if (unlikely(ACTIVE.rp + diff < 0)) { #ifdef ENABLE_ERROR if (vm->ErrorHandlers[3] != 0) { handle_error(vm, 3); } #else return; #endif } if (unlikely(ACTIVE.rp + diff > (ADDRESSES - 1))) { #ifdef ENABLE_ERROR if (vm->ErrorHandlers[1] != 4) { handle_error(vm, 4); } #else return; #endif } } #endif #ifdef ENABLE_IOCTL /************************************************************** _ __ _ _ _ __ ___| |_ _ __ ___ / _| ___ _ __| |_| |__ | '__/ _ \ __| '__/ _ \| |_ / _ \| '__| __| '_ \ | | | __/ |_| | | (_) | _| (_) | | | |_| | | | |_| \___|\__|_| \___/|_| \___/|_| \__|_| |_| for nga (c) Charles Childers, Luke Parrish, Marc Simpsonn, Jay Skeer, Kenneth Keating **************************************************************/ #ifdef ENABLE_IOCTL #include #include void ioctl_get_terminal_size(NgaState *vm) { struct winsize size; ioctl(STDOUT_FILENO, TIOCGWINSZ, &size); stack_push(vm, size.ws_row); stack_push(vm, size.ws_col); } void ioctl_set_character_breaking_mode(NgaState *vm) { struct termios term; tcgetattr(STDIN_FILENO, &term); term.c_lflag &=(~ICANON & ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &term); } void ioctl_set_line_buffered_mode(NgaState *vm) { struct termios term; tcgetattr(STDIN_FILENO, &term); term.c_lflag |= ICANON; term.c_lflag |= ECHO; tcsetattr(STDIN_FILENO, TCSANOW, &term); } struct termios savedTermState; void ioctl_save_current_state(NgaState *vm) { tcgetattr(STDIN_FILENO, &savedTermState); } void ioctl_restore_saved_state(NgaState *vm) { tcsetattr(STDIN_FILENO, TCSANOW, &savedTermState); } Handler IOCTLActions[] = { ioctl_get_terminal_size, ioctl_set_character_breaking_mode, ioctl_set_line_buffered_mode, ioctl_save_current_state, ioctl_restore_saved_state }; V query_ioctl(NgaState *vm) { stack_push(vm, 0); stack_push(vm, DEVICE_IOCTL); } V io_ioctl(NgaState *vm) { IOCTLActions[stack_pop(vm)](vm); } #endif #endif #ifdef ENABLE_MALLOC #ifdef BIT64 /************************************************************** _ __ _ _ _ __ ___| |_ _ __ ___ / _| ___ _ __| |_| |__ | '__/ _ \ __| '__/ _ \| |_ / _ \| '__| __| '_ \ | | | __/ |_| | | (_) | _| (_) | | | |_| | | | |_| \___|\__|_| \___/|_| \___/|_| \__|_| |_| for nga (c) Charles Childers, Luke Parrish, Marc Simpsonn, Jay Skeer, Kenneth Keating **************************************************************/ #ifdef ENABLE_MALLOC #ifdef BIT64 typedef union { V* val; struct { CELL msw; CELL lsw; }; } double_cell; V 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); } V double_sub(NgaState *vm) { } V double_mul(NgaState *vm) { } V double_divmod(NgaState *vm) { } V malloc_allocate(NgaState *vm) { stack_push(vm, (CELL)malloc(stack_pop(vm))); } V malloc_free(NgaState *vm) { free((CELL*)stack_pop(vm)); } V malloc_store(NgaState *vm) { CELL value = stack_pop(vm); double_cell addr; *(CELL *) stack_pop(vm) = value; } V malloc_fetch(NgaState *vm) { double_cell addr; CELL value = *(CELL *)stack_pop(vm); stack_push(vm, value); } V 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); } V query_malloc(NgaState *vm) { stack_push(vm, 0); stack_push(vm, DEVICE_MALLOC); } V 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 /************************************************************** _ __ _ _ _ __ ___| |_ _ __ ___ / _| ___ _ __| |_| |__ | '__/ _ \ __| '__/ _ \| |_ / _ \| '__| __| '_ \ | | | __/ |_| | | (_) | _| (_) | | | |_| | | | |_| \___|\__|_| \___/|_| \___/|_| \__|_| |_| for nga (c) Charles Childers, Luke Parrish, Marc Simpsonn, Jay Skeer, Kenneth Keating **************************************************************/ /* | 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 V execute(NgaState *vm, CELL cell); V handle_error(NgaState *vm, CELL error) { CELL saved_ip = vm->cpu[vm->active].ip; if (vm->ErrorHandlers[error] != 0) { printf("\nHandling %lld\n", (long long)error); execute(vm, vm->ErrorHandlers[error]); } vm->cpu[vm->active].ip = saved_ip; } V 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", (long long)ErrorID, (long long)ErrorHandler); } V io_error(NgaState *vm) { switch (stack_pop(vm)) { case 0: register_error_handler(vm); break; default: break; } } V query_error(NgaState *vm) { stack_push(vm, 0); stack_push(vm, DEVICE_ERROR); } #endif #endif #ifdef ENABLE_BLOCKS /************************************************************** _ __ _ _ _ __ ___| |_ _ __ ___ / _| ___ _ __| |_| |__ | '__/ _ \ __| '__/ _ \| |_ / _ \| '__| __| '_ \ | | | __/ |_| | | (_) | _| (_) | | | |_| | | | |_| \___|\__|_| \___/|_| \___/|_| \__|_| |_| for nga (c) Charles Childers, Luke Parrish, Marc Simpsonn, Jay Skeer, Kenneth Keating **************************************************************/ V read_block(NgaState *vm) { CELL buffer = stack_pop(vm); CELL block = stack_pop(vm); int32_t m[1024]; 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); } V write_block(NgaState *vm) { CELL buffer = stack_pop(vm); CELL block = stack_pop(vm); int32_t m[1024]; 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); } V set_block_file(NgaState *vm) { CELL buffer = stack_pop(vm); strlcpy(vm->BlockFile, string_extract(vm, buffer), 1024); } V io_blocks(NgaState *vm) { switch (stack_pop(vm)) { case 0: read_block(vm); break; case 1: write_block(vm); break; case 2: set_block_file(vm); break; } } V query_blocks(NgaState *vm) { stack_push(vm, 0); stack_push(vm, DEVICE_BLOCKS); } #endif #ifdef ENABLE_FILES /************************************************************** _ __ _ _ _ __ ___| |_ _ __ ___ / _| ___ _ __| |_| |__ | '__/ _ \ __| '__/ _ \| |_ / _ \| '__| __| '_ \ | | | __/ |_| | | (_) | _| (_) | | | |_| | | | |_| \___|\__|_| \___/|_| \___/|_| \__|_| |_| for nga (c) Charles Childers, Luke Parrish, Marc Simpsonn, Jay Skeer, Kenneth Keating **************************************************************/ V utf32_to_utf8(uint32_t, unsigned char*, int*); int fread_character(FILE *); /*--------------------------------------------------------------------- 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) { for(CELL 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). ---------------------------------------------------------------------*/ V file_open(NgaState *vm) { CELL slot = files_get_handle(vm); CELL mode = stack_pop(vm); CELL name = stack_pop(vm); char *modes[] = {"rb", "w", "a", "rb+"}; char *request = string_extract(vm, name); if (slot > 0) { vm->OpenFileHandles[slot] = fopen(request, modes[mode]); } if (vm->OpenFileHandles[slot] == NULL) { vm->OpenFileHandles[slot] = 0; slot = 0; } stack_push(vm, slot); // FILE *file = (slot > 0) ? fopen(request, modes[mode]) : NULL; // vm->OpenFileHandles[slot] = (file != NULL) ? file : 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. ---------------------------------------------------------------------*/ V file_read(NgaState *vm) { CELL slot = stack_pop(vm); FILE *file = vm->OpenFileHandles[slot]; if (slot <= 0 || slot > MAX_OPEN_FILES || file == 0) { printf("\nERROR (nga/file_read): Invalid file handle\n"); exit(1); } stack_push(vm, feof(file) ? 0 : fgetc(file)); } /*-------------------------------------------------------------- `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. ------------------------------------------------------------*/ V file_write(NgaState *vm) { CELL slot = stack_pop(vm); FILE *file = vm->OpenFileHandles[slot]; if (slot <= 0 || slot > MAX_OPEN_FILES || file == 0) { printf("\nERROR (nga/file_write): Invalid file handle\n"); exit(1); } fputc(stack_pop(vm), file); } /*-------------------------------------------------------------- `file_close()` closes a file. This takes a file handle from the stack and does not return anything on the stack. ------------------------------------------------------------*/ V file_close(NgaState *vm) { CELL slot = stack_pop(vm); FILE *file = vm->OpenFileHandles[slot]; if (slot <= 0 || slot > MAX_OPEN_FILES || file == 0) { printf("\nERROR (nga/file_close): Invalid file handle\n"); exit(1); } fclose(file); 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. ------------------------------------------------------------*/ V 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. ------------------------------------------------------------*/ V 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. ------------------------------------------------------------*/ V 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. ------------------------------------------------------------*/ V 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. ------------------------------------------------------------*/ V 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]; V 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); } V 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); } V file_read_character(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 = fread_character(vm->OpenFileHandles[slot]); stack_push(vm, feof(vm->OpenFileHandles[slot]) ? 0 : c); } V file_write_character(NgaState *vm) { unsigned char utf8_bytes[4]; int num_bytes; CELL slot, c, r; utf32_to_utf8(stack_pop(vm), utf8_bytes, &num_bytes); 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); } r = fwrite(&utf8_bytes, num_bytes, 1, vm->OpenFileHandles[slot]); } V file_read_line(NgaState *vm) { CELL slot = stack_pop(vm); CELL targ = stack_pop(vm); CELL c; if (slot <= 0 || slot > MAX_OPEN_FILES || vm->OpenFileHandles[slot] == 0) { printf("\nERROR (nga/file_read): Invalid file handle\n"); exit(1); } c = fread_character(vm->OpenFileHandles[slot]); vm->memory[targ] = c; targ++; while (c != 10 && c != 13 && c != 0) { c = fread_character(vm->OpenFileHandles[slot]); vm->memory[targ] = c; targ++; } vm->memory[targ - 1] = 0; } V file_write_line(NgaState *vm) { } 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, file_read_character,file_write_character, file_read_line, file_write_line, }; V query_filesystem(NgaState *vm) { stack_push(vm, 3); stack_push(vm, DEVICE_FILES); } V io_filesystem(NgaState *vm) { FileActions[stack_pop(vm)](vm); } #endif #ifdef ENABLE_MULTICORE /************************************************************** _ __ _ _ _ __ ___| |_ _ __ ___ / _| ___ _ __| |_| |__ | '__/ _ \ __| '__/ _ \| |_ / _ \| '__| __| '_ \ | | | __/ |_| | | (_) | _| (_) | | | |_| | | | |_| \___|\__|_| \___/|_| \___/|_| \__|_| |_| for nga (c) Charles Childers, Luke Parrish, Marc Simpsonn, Jay Skeer, 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, DEVICE_MULTICORE); } #endif #endif #ifdef ENABLE_FFI /************************************************************** _ __ _ _ _ __ ___| |_ _ __ ___ / _| ___ _ __| |_| |__ | '__/ _ \ __| '__/ _ \| |_ / _ \| '__| __| '_ \ | | | __/ |_| | | (_) | _| (_) | | | |_| | | | |_| \___|\__|_| \___/|_| \___/|_| \__|_| |_| for nga (c) Charles Childers, Luke Parrish, Marc Simpsonn, Jay Skeer, Kenneth Keating **************************************************************/ #ifdef ENABLE_FFI #include typedef void (*External)(void *); V *handles[32]; External funcs[32000]; int nlibs, nffi; V open_library(NgaState *vm) { handles[nlibs] = dlopen(string_extract(vm, stack_pop(vm)), RTLD_LAZY); stack_push(vm, nlibs); nlibs++; } V 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++; } V invoke(NgaState *vm) { funcs[stack_pop(vm)](vm); } V 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; } } V query_ffi(NgaState *vm) { stack_push(vm, 0); stack_push(vm, DEVICE_FFI); } #endif #endif #ifdef ENABLE_FLOATS /************************************************************** _ __ _ _ _ __ ___| |_ _ __ ___ / _| ___ _ __| |_| |__ | '__/ _ \ __| '__/ _ \| |_ / _ \| '__| __| '_ \ | | | __/ |_| | | (_) | _| (_) | | | |_| | | | |_| \___|\__|_| \___/|_| \___/|_| \__|_| |_| for nga (c) Charles Childers, Luke Parrish, Marc Simpsonn, Jay Skeer, 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, DEVICE_FLOATS); } void io_floatingpoint(NgaState *vm) { FloatHandlers[stack_pop(vm)](vm); } #endif #endif #ifdef ENABLE_CLOCK /************************************************************** _ __ _ _ _ __ ___| |_ _ __ ___ / _| ___ _ __| |_| |__ | '__/ _ \ __| '__/ _ \| |_ / _ \| '__| __| '_ \ | | | __/ |_| | | (_) | _| (_) | | | |_| | | | |_| \___|\__|_| \___/|_| \___/|_| \__|_| |_| for nga (c) Charles Childers, Luke Parrish, Marc Simpsonn, Jay Skeer, Kenneth Keating **************************************************************/ #ifdef ENABLE_CLOCK time_t current_time; V clock_time(NgaState *vm) { stack_push(vm, (CELL)time(NULL)); } V clock_day(NgaState *vm) { stack_push(vm, (CELL)localtime(¤t_time)->tm_mday); } V clock_month(NgaState *vm) { stack_push(vm, (CELL)localtime(¤t_time)->tm_mon + 1); } V clock_year(NgaState *vm) { stack_push(vm, (CELL)localtime(¤t_time)->tm_year + 1900); } V clock_hour(NgaState *vm) { stack_push(vm, (CELL)localtime(¤t_time)->tm_hour); } V clock_minute(NgaState *vm) { stack_push(vm, (CELL)localtime(¤t_time)->tm_min); } V clock_second(NgaState *vm) { stack_push(vm, (CELL)localtime(¤t_time)->tm_sec); } V clock_day_utc(NgaState *vm) { stack_push(vm, (CELL)gmtime(¤t_time)->tm_mday); } V clock_month_utc(NgaState *vm) { stack_push(vm, (CELL)gmtime(¤t_time)->tm_mon + 1); } V clock_year_utc(NgaState *vm) { stack_push(vm, (CELL)gmtime(¤t_time)->tm_year + 1900); } V clock_hour_utc(NgaState *vm) { stack_push(vm, (CELL)gmtime(¤t_time)->tm_hour); } V clock_minute_utc(NgaState *vm) { stack_push(vm, (CELL)gmtime(¤t_time)->tm_min); } V clock_second_utc(NgaState *vm) { stack_push(vm, (CELL)gmtime(¤t_time)->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 }; V query_clock(NgaState *vm) { stack_push(vm, 0); stack_push(vm, DEVICE_CLOCK); } V io_clock(NgaState *vm) { current_time = time(NULL); ClockActions[stack_pop(vm)](vm); } #endif #endif #ifdef ENABLE_RNG /************************************************************** _ __ _ _ _ __ ___| |_ _ __ ___ / _| ___ _ __| |_| |__ | '__/ _ \ __| '__/ _ \| |_ / _ \| '__| __| '_ \ | | | __/ |_| | | (_) | _| (_) | | | |_| | | | |_| \___|\__|_| \___/|_| \___/|_| \__|_| |_| for nga (c) Charles Childers, Luke Parrish, Marc Simpsonn, Jay Skeer, Kenneth Keating **************************************************************/ #ifdef ENABLE_RNG V 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 } V query_rng(NgaState *vm) { stack_push(vm, 0); stack_push(vm, DEVICE_RNG); } #endif #endif #ifdef ENABLE_SOCKETS /************************************************************** _ __ _ _ _ __ ___| |_ _ __ ___ / _| ___ _ __| |_| |__ | '__/ _ \ __| '__/ _ \| |_ / _ \| '__| __| '_ \ | | | __/ |_| | | (_) | _| (_) | | | |_| | | | |_| \___|\__|_| \___/|_| \___/|_| \__|_| |_| for nga (c) Charles Childers, Luke Parrish, Marc Simpsonn, Jay Skeer, Kenneth Keating **************************************************************/ #ifdef ENABLE_SOCKETS #include #include #include #include /*--------------------------------------------------------------------- BSD Sockets ---------------------------------------------------------------------*/ int SocketID[16]; struct sockaddr_in Sockets[16]; struct addrinfo hints, *res; V 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); } V 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)); } V 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; } } } V 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); } V 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); } V 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); } V socket_connect(NgaState *vm) { stack_push(vm, (CELL)connect(SocketID[stack_pop(vm)], res->ai_addr, res->ai_addrlen)); stack_push(vm, errno); } V 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); } V 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); } V 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 }; V io_socket(NgaState *vm) { SocketActions[stack_pop(vm)](vm); } V query_socket(NgaState *vm) { stack_push(vm, 0); stack_push(vm, DEVICE_SOCKETS); } #endif #endif #ifdef ENABLE_UNIX /************************************************************** _ __ _ _ _ __ ___| |_ _ __ ___ / _| ___ _ __| |_| |__ | '__/ _ \ __| '__/ _ \| |_ / _ \| '__| __| '_ \ | | | __/ |_| | | (_) | _| (_) | | | |_| | | | |_| \___|\__|_| \___/|_| \___/|_| \__|_| |_| for nga (c) Charles Childers, Luke Parrish, Marc Simpsonn, Jay Skeer, 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. ------------------------------------------------------------*/ V unix_open_pipe(NgaState *vm) { CELL slot, mode, name; char *request; const char *modes[] = {"r", "w", "", "r+"}; slot = files_get_handle(vm); mode = stack_pop(vm); name = stack_pop(vm); request = string_extract(vm, name); if (slot > 0) { vm->OpenFileHandles[slot] = popen(request, modes[mode]); } if (vm->OpenFileHandles[slot] == NULL) { vm->OpenFileHandles[slot] = 0; slot = 0; } stack_push(vm, slot); } V unix_close_pipe(NgaState *vm) { pclose(vm->OpenFileHandles[TOS]); vm->OpenFileHandles[TOS] = 0; stack_pop(vm); } V unix_system(NgaState *vm) { int ignore = 0; ignore = system(string_extract(vm, stack_pop(vm))); } V unix_fork(NgaState *vm) { stack_push(vm, fork()); } V 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. Retro 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. ------------------------------------------------------------*/ V 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); } V 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); } V 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); } V 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); } V unix_exit(NgaState *vm) { exit(stack_pop(vm)); } V unix_getpid(NgaState *vm) { stack_push(vm, getpid()); } V unix_wait(NgaState *vm) { int a; stack_push(vm, wait(&a)); } V unix_kill(NgaState *vm) { CELL a = stack_pop(vm); kill(stack_pop(vm), a); } V unix_write(NgaState *vm) { ssize_t ignore; CELL c = stack_pop(vm); CELL b = stack_pop(vm); CELL a = stack_pop(vm); ignore = write(fileno(vm->OpenFileHandles[c]), string_extract(vm, a), b); } V unix_chdir(NgaState *vm) { int ignore = chdir(string_extract(vm, stack_pop(vm))); } V unix_getenv(NgaState *vm) { CELL a = stack_pop(vm); CELL b = stack_pop(vm); string_inject(vm, getenv(string_extract(vm, b)), a); } V unix_putenv(NgaState *vm) { putenv(string_extract(vm, stack_pop(vm))); } V 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 }; V query_unix(NgaState *vm) { stack_push(vm, 3); stack_push(vm, DEVICE_UNIX); } V io_unix(NgaState *vm) { UnixActions[stack_pop(vm)](vm); } #endif #endif /*--------------------------------------------------------------------- Now on to I/O and extensions! ---------------------------------------------------------------------*/ V 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"); } } V 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; } } V io_output(NgaState *vm) { unsigned char utf8_bytes[4]; int num_bytes; utf32_to_utf8(stack_pop(vm), utf8_bytes, &num_bytes); display_utf8(utf8_bytes, num_bytes); fflush(stdout); } V query_output(NgaState *vm) { stack_push(vm, 0); stack_push(vm, DEVICE_OUTPUT); } /*=====================================================================*/ 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; } V io_keyboard(NgaState *vm) { stack_push(vm, read_character(STDIN_FILENO)); if (TOS == 127) TOS = 8; } V query_keyboard(NgaState *vm) { stack_push(vm, 0); stack_push(vm, DEVICE_KEYBOARD); } /*=====================================================================*/ #ifdef ENABLE_UNSIGNED V io_unsigned(NgaState *vm) { int x, y, z; long c; switch (stack_pop(vm)) { case 0: ACTIVE.u = 1; break; case 1: c = 0; z = stack_pop(vm); y = stack_pop(vm); x = stack_pop(vm); if (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); } ACTIVE.u = 0; break; } } V query_unsigned(NgaState *vm) { stack_push(vm, 0); stack_push(vm, DEVICE_UNSIGNED); } #endif /*=====================================================================*/ V 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); } V query_image(NgaState *vm) { stack_push(vm, 0); stack_push(vm, DEVICE_IMAGE); } /*=====================================================================*/ /*--------------------------------------------------------------------- Scripting Support ---------------------------------------------------------------------*/ V 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)); } V scripting_arg_count(NgaState *vm) { stack_push(vm, vm->sys_argc - 2); } V scripting_include(NgaState *vm) { include_file(vm, string_extract(vm, stack_pop(vm)), 0); } V scripting_include_plain(NgaState *vm) { include_plain_file(vm, string_extract(vm, stack_pop(vm)), 0); } V 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 */ V scripting_source(NgaState *vm) { stack_push(vm, string_inject(vm, vm->scripting_sources[vm->current_source], stack_pop(vm))); } V scripting_line(NgaState *vm) { stack_push(vm, vm->currentLine); } V scripting_ignore_to_eol(NgaState *vm) { vm->ignoreToEOL = -1; } V scripting_ignore_to_eof(NgaState *vm) { vm->ignoreToEOF = -1; } V scripting_abort(NgaState *vm) { scripting_ignore_to_eol(vm); scripting_ignore_to_eof(vm); vm->perform_abort = -1; } V carry_out_abort(NgaState *vm) { ACTIVE.ip = IMAGE_SIZE + 1; ACTIVE.rp = 0; 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; } V 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, scripting_include_plain }; V query_scripting(NgaState *vm) { stack_push(vm, 3); stack_push(vm, DEVICE_SCRIPTING); } V 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. ---------------------------------------------------------------------*/ V invalid_opcode(NgaState *vm, CELL opcode) { CELL a, i; printf("\nERROR (nga/execute): Invalid instruction!\n"); printf("At %lld, opcode %lld\n", (long long)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); } V execute(NgaState *vm, CELL cell) { CELL opcode; if (ACTIVE.rp == 0) ACTIVE.rp = 1; ACTIVE.ip = cell; while (ACTIVE.ip < IMAGE_SIZE) { if (vm->perform_abort == 0) { opcode = vm->memory[ACTIVE.ip]; #ifndef BRANCH_PREDICTION validate_opcode_bundle(vm, opcode); #endif process_opcode_bundle(vm, opcode); #ifndef ENABLE_ERROR if (ACTIVE.sp < 0 || ACTIVE.sp > STACK_DEPTH) { printf("\nERROR (nga/execute): Stack Limits Exceeded!\n"); printf("At %lld, opcode %lld. sp = %lld, core = %lld\n", (long long)ACTIVE.ip, (long long)opcode, (long long)ACTIVE.sp, (long long)vm->active); exit(1); } if (ACTIVE.rp < 0 || ACTIVE.rp > ADDRESSES) { printf("\nERROR (nga/execute): Address Stack Limits Exceeded!\n"); printf("At %lld, opcode %lld. rp = %lld\n", (long long)ACTIVE.ip, (long long)opcode, (long long)ACTIVE.rp); exit(1); } #endif ACTIVE.ip++; #ifdef ENABLE_MULTICORE switch_core(vm); #endif if (ACTIVE.rp == 0) 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. ---------------------------------------------------------------------*/ V 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); } V read_token(FILE *file, char *token_buffer) { int ch = fread_character(file); int count = 0; while (not_eol(ch)) { if ((ch == 8 || ch == 127) && count > 0) { count--; } else { token_buffer[count++] = ch; } ch = fread_character(file); } token_buffer[count] = '\0'; } V skip_indent(FILE *fp) { int ch = getc(fp); while (ch == ' ') { ch = getc(fp); } ungetc(ch, fp); } /*--------------------------------------------------------------------- Display the Stack Contents ---------------------------------------------------------------------*/ V dump_stack(NgaState *vm) { if (ACTIVE.sp == 0) return; printf("\nStack: "); for (CELL i = 1; i <= ACTIVE.sp; i++) { if (i == ACTIVE.sp) printf("[ TOS: %lld ]", (long long)ACTIVE.data[i]); else printf("%lld ", (long long)ACTIVE.data[i]); } printf("\n"); } V dump_astack(NgaState *vm) { if (ACTIVE.rp == 0) return; printf("\nAddress Stack: "); for (CELL i = 1; i <= ACTIVE.rp; i++) { if (i == ACTIVE.rp) printf("[ TOS: %lld ]", (long long)ACTIVE.address[i]); else printf("%lld ", (long long)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. ---------------------------------------------------------------------*/ V 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; ch = fread_character(file); } token_buffer[count] = '\0'; } int count_tokens(char *line) { int count = 1; while (*line++) { if (isspace(line[0])) count++; } return count; } V 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 = ACTIVE.rp; aip = ACTIVE.ip; for(ACTIVE.rp = 0; ACTIVE.rp <= arp; ACTIVE.rp++) ReturnStack[ACTIVE.rp] = ACTIVE.address[ACTIVE.rp]; 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(ACTIVE.rp = 0; ACTIVE.rp <= arp; ACTIVE.rp++) ACTIVE.address[ACTIVE.rp] = ReturnStack[ACTIVE.rp]; ACTIVE.rp = arp; 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; } V include_plain_file(NgaState *vm, char *fname, int run_tests) { char source[64 * 1024]; /* Token buffer [about 64K] */ 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); } arp = ACTIVE.rp; aip = ACTIVE.ip; for(ACTIVE.rp = 0; ACTIVE.rp <= arp; ACTIVE.rp++) ReturnStack[ACTIVE.rp] = ACTIVE.address[ACTIVE.rp]; 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); 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(ACTIVE.rp = 0; ACTIVE.rp <= arp; ACTIVE.rp++) ACTIVE.address[ACTIVE.rp] = ReturnStack[ACTIVE.rp]; ACTIVE.rp = arp; ACTIVE.ip = aip; } /*--------------------------------------------------------------------- `initialize()` sets up Nga and loads the image (from the array in `image.c`) to memory. ---------------------------------------------------------------------*/ V initialize(NgaState *vm) { prepare_vm(vm); load_embedded_image(vm); vm->interactive = 0; strlcpy(vm->code_start, "~~~", 256); strlcpy(vm->code_end, "~~~", 256); strlcpy(vm->test_start, "```", 256); strlcpy(vm->test_end, "```", 256); /* 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 */ strlcpy(vm->scripting_sources[0], "/dev/stdin", 8192); vm->ignoreToEOL = 0; vm->ignoreToEOF = 0; vm->codeBlocks = 0; } V 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 code blocks in the specified file\n"); printf(" -p 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 code blocks in the specified file, including any tests (in ``` blocks)\n\n"); printf(" -v\n"); printf(" Run in verbose mode\n"); } /* Signal Handler -----------------------------------------------------*/ #ifdef ENABLE_SIGNALS static V sig_handler(int _) { printf("\nCaught: %d\n", _); exit(1); } #endif /* Main Entry Point ---------------------------------------------------*/ enum flags { FLAG_HELP, FLAG_INTERACTIVE, }; V register_devices(NgaState *vm) { register_device(vm, io_output, query_output); register_device(vm, io_keyboard, query_keyboard); #ifdef ENABLE_FILES register_device(vm, io_filesystem, query_filesystem); #endif 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 #ifdef ENABLE_IOCTL register_device(vm, io_ioctl, query_ioctl); #endif } V register_signal_handlers() { #ifdef ENABLE_SIGNALS signal(SIGHUP, sig_handler); signal(SIGINT, sig_handler); signal(SIGILL, sig_handler); signal(SIGBUS, sig_handler); signal(SIGFPE, sig_handler); #endif } #define ARG(n) (strcmp(argv[i], n) == 0) int main(int argc, char **argv) { int i; int modes[16]; NgaState *vm = calloc(sizeof(NgaState), sizeof(char)); verbose = 0; register_signal_handlers(); initialize(vm); /* Initialize Nga & image */ register_devices(vm); vm->sys_argc = argc; /* Point the global argc and */ vm->sys_argv = argv; /* argv to the actual ones */ /* Check arguments. If no flags were passed, load & run the file specified and exit. */ if (argc >= 2 && argv[1][0] != '-') { update_rx(vm); include_file(vm, argv[1], 0); if (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 ARG("-h") { help(argv[0]); exit(0); } else if ARG("-v") { verbose = 1; } else if ARG("-i") { modes[FLAG_INTERACTIVE] = 1; vm->interactive = -1; } else if ARG("-f") { include_file(vm, argv[i + 1], 0); i++; } else if ARG("-p") { include_plain_file(vm, argv[i + 1], 0); i++; } else if ARG("-u") { i++; load_image(vm, argv[i]); update_rx(vm); } else if ARG("-r") { i++; load_image(vm, argv[i]); modes[FLAG_INTERACTIVE] = 1; update_rx(vm); } else if ARG("-t") { include_file(vm, argv[i + 1], 1); i++; } else if (ARG("--code-start") || ARG("-cs")) { i++; strlcpy(vm->code_start, argv[i], 256); } else if (ARG("--code-end") || ARG("-ce")) { i++; strlcpy(vm->code_end, argv[i], 256); } else if (ARG("--test-start") || ARG("-ts")) { i++; strlcpy(vm->test_start, argv[i], 256); } else if (ARG("--test-end") || ARG("-te")) { i++; strlcpy(vm->test_end, argv[i], 256); } } /* Run the Listener (if interactive mode was set) */ if (modes[FLAG_INTERACTIVE] == 1) { execute(vm, 0); } /* Dump Stack */ if (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) { ACTIVE.sp--; return ACTIVE.data[ACTIVE.sp + 1]; } V stack_push(NgaState *vm, CELL value) { ACTIVE.sp++; ACTIVE.data[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) { if (!str) { vm->memory[buffer] = 0; return 0; } for (CELL i = 0; str[i] != '\0'; i++) { vm->memory[buffer + i] = (CELL)str[i]; vm->memory[buffer + i + 1] = 0; } 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, 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 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. ---------------------------------------------------------------------*/ V update_rx(NgaState *vm) { vm->Dictionary = vm->memory[2]; vm->interpret = vm->memory[5]; if (vm->memory[10] != 0) { execute(vm, vm->memory[10]); } } /*=====================================================================*/ V register_device(NgaState *vm, V *handler, V *query) { vm->IO_deviceHandlers[vm->devices] = handler; vm->IO_queryHandlers[vm->devices] = query; vm->devices++; } V 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); /* Erase old image in memory: 0 = nop instruction */ for (int i = 0; i < IMAGE_SIZE; i++) { vm->memory[i] = 0; } /* Read the file into memory */ imageSize = fread(vm->memory, sizeof(CELL), fileLen, fp); fclose(fp); } return imageSize; } V prepare_vm(NgaState *vm) { vm->active = 0; ACTIVE.ip = ACTIVE.sp = ACTIVE.rp = ACTIVE.u = 0; ACTIVE.active = -1; for (ACTIVE.ip = 0; ACTIVE.ip < IMAGE_SIZE; ACTIVE.ip++) vm->memory[ACTIVE.ip] = 0; /* NO - nop instruction */ for (ACTIVE.ip = 0; ACTIVE.ip < STACK_DEPTH; ACTIVE.ip++) ACTIVE.data[ACTIVE.ip] = 0; for (ACTIVE.ip = 0; ACTIVE.ip < ADDRESSES; ACTIVE.ip++) ACTIVE.address[ACTIVE.ip] = 0; } V i_no(NgaState *vm) { #ifndef BRANCH_PREDICTION guard(vm, 0, 0, 0); #endif } V i_li(NgaState *vm) { guard(vm, 0, 1, 0); ACTIVE.sp++; ACTIVE.ip++; TOS = vm->memory[ACTIVE.ip]; } V i_du(NgaState *vm) { guard(vm, 1, 2, 0); ACTIVE.sp++; ACTIVE.data[ACTIVE.sp] = NOS; } V i_dr(NgaState *vm) { guard(vm, 1, 0, 0); ACTIVE.data[ACTIVE.sp] = 0; ACTIVE.sp--; } V i_sw(NgaState *vm) { guard(vm, 2, 2, 0); CELL a; a = TOS; TOS = NOS; NOS = a; } V i_pu(NgaState *vm) { guard(vm, 1, 0, 1); ACTIVE.rp++; TORS = TOS; i_dr(vm); } V i_po(NgaState *vm) { guard(vm, 0, 1, -1); ACTIVE.sp++; TOS = TORS; ACTIVE.rp--; } V i_ju(NgaState *vm) { guard(vm, 1, 0, 0); ACTIVE.ip = TOS - 1; i_dr(vm); } V i_ca(NgaState *vm) { guard(vm, 1, 0, 1); ACTIVE.rp++; TORS = ACTIVE.ip; ACTIVE.ip = TOS - 1; i_dr(vm); } V i_cc(NgaState *vm) { guard(vm, 2, 0, 1); CELL a, b; a = TOS; i_dr(vm); /* Target */ b = TOS; i_dr(vm); /* Flag */ if (b != 0) { ACTIVE.rp++; TORS = ACTIVE.ip; ACTIVE.ip = a - 1; } } V i_re(NgaState *vm) { guard(vm, 0, 0, -1); ACTIVE.ip = TORS; ACTIVE.rp--; } V i_eq(NgaState *vm) { guard(vm, 2, 1, 0); if (ACTIVE.u != 0) { NOS = ((unsigned)NOS == (unsigned)TOS) ? -1 : 0; ACTIVE.u = 0; } else { NOS = (NOS == TOS) ? -1 : 0; } i_dr(vm); } V i_ne(NgaState *vm) { guard(vm, 2, 1, 0); if (ACTIVE.u != 0) { NOS = ((unsigned)NOS != (unsigned)TOS) ? -1 : 0; ACTIVE.u = 0; } else { NOS = (NOS != TOS) ? -1 : 0; } i_dr(vm); } V i_lt(NgaState *vm) { guard(vm, 2, 1, 0); if (ACTIVE.u != 0) { NOS = ((unsigned)NOS < (unsigned)TOS) ? -1 : 0; ACTIVE.u = 0; } else { NOS = (NOS < TOS) ? -1 : 0; } i_dr(vm); } V i_gt(NgaState *vm) { guard(vm, 2, 1, 0); if (ACTIVE.u != 0) { NOS = ((unsigned)NOS > (unsigned)TOS) ? -1 : 0; ACTIVE.u = 0; } else { NOS = (NOS > TOS) ? -1 : 0; } i_dr(vm); } V i_fe(NgaState *vm) { guard(vm, 1, 1, 0); switch (TOS) { case -1: TOS = ACTIVE.sp - 1; break; case -2: TOS = 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; } } V i_st(NgaState *vm) { guard(vm, 2, 0, 0); vm->memory[TOS] = NOS; i_dr(vm); i_dr(vm); } V i_ad(NgaState *vm) { guard(vm, 2, 1, 0); if (ACTIVE.u != 0) { NOS = (unsigned)NOS + (unsigned)TOS; ACTIVE.u = 0; } else { NOS += TOS; } i_dr(vm); } V i_su(NgaState *vm) { guard(vm, 2, 1, 0); if (ACTIVE.u != 0) { NOS = (unsigned)NOS - (unsigned)TOS; ACTIVE.u = 0; } else { NOS -= TOS; } i_dr(vm); } V i_mu(NgaState *vm) { guard(vm, 2, 1, 0); if (ACTIVE.u != 0) { NOS = (unsigned)NOS * (unsigned)TOS; ACTIVE.u = 0; } else { NOS *= TOS; } i_dr(vm); } V i_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 (ACTIVE.u != 0) { TOS = (unsigned)b / (unsigned)a; NOS = (unsigned)b % (unsigned)a; ACTIVE.u = 0; } else { TOS = b / a; NOS = b % a; } } V i_an(NgaState *vm) { guard(vm, 2, 1, 0); NOS = TOS & NOS; i_dr(vm); } V i_or(NgaState *vm) { guard(vm, 2, 1, 0); NOS = TOS | NOS; i_dr(vm); } V i_xo(NgaState *vm) { guard(vm, 2, 1, 0); NOS = TOS ^ NOS; i_dr(vm); } V i_sh(NgaState *vm) { guard(vm, 2, 1, 0); CELL y = TOS; CELL x = NOS; if (TOS < 0) NOS = NOS << (0 - TOS); else { if (ACTIVE.u != 0) { NOS = (unsigned)x >> (unsigned)y; ACTIVE.u = 0; } else { if (x < 0 && y > 0) NOS = x >> y | ~(~0U >> y); else NOS = x >> y; } } i_dr(vm); } V i_zr(NgaState *vm) { guard(vm, 1, 0, 0); if (TOS == 0) { i_dr(vm); ACTIVE.ip = TORS; ACTIVE.rp--; } } V i_ha(NgaState *vm) { guard(vm, 0, 0, 0); ACTIVE.ip = IMAGE_SIZE; ACTIVE.rp = 0; exit(0); } V i_ie(NgaState *vm) { guard(vm, 1, 1, 0); stack_push(vm, vm->devices); } V i_iq(NgaState *vm) { guard(vm, 1, 1, 0); vm->IO_queryHandlers[stack_pop(vm)](vm); } V i_ii(NgaState *vm) { guard(vm, 1, 0, 0); vm->IO_deviceHandlers[stack_pop(vm)](vm); } Handler instructions[] = { i_no, i_li, i_du, i_dr, i_sw, i_pu, i_po, i_ju, i_ca, i_cc, i_re, i_eq, i_ne, i_lt, i_gt, i_fe, i_st, i_ad, i_su, i_mu, i_di, i_an, i_or, i_xo, i_sh, i_zr, i_ha, i_ie, i_iq, i_ii }; V process_opcode(NgaState *vm, CELL opcode) { #ifdef FAST switch (opcode) { case 0: break; case 1: i_li(vm); break; case 2: i_du(vm); break; case 3: i_dr(vm); break; case 4: i_sw(vm); break; case 5: i_pu(vm); break; case 6: i_po(vm); break; case 7: i_ju(vm); break; case 8: i_ca(vm); break; case 9: i_cc(vm); break; case 10: i_re(vm); break; case 11: i_eq(vm); break; case 12: i_ne(vm); break; case 13: i_lt(vm); break; case 14: i_gt(vm); break; case 15: i_fe(vm); break; case 16: i_st(vm); break; case 17: i_ad(vm); break; case 18: i_su(vm); break; case 19: i_mu(vm); break; case 20: i_di(vm); break; case 21: i_an(vm); break; case 22: i_or(vm); break; case 23: i_xo(vm); break; case 24: i_sh(vm); break; case 25: i_zr(vm); break; case 26: i_ha(vm); break; case 27: i_ie(vm); break; case 28: i_iq(vm); break; case 29: i_ii(vm); break; default: break; } #else if (opcode != 0) instructions[opcode](vm); #endif } #ifndef BRANCH_PREDICTION V validate_opcode_bundle(NgaState *vm, CELL opcode) { CELL remainingOpcode = opcode; for (int i = 0; i < 4; i++) { CELL current = remainingOpcode & 0xFF; if (current < 0 || current > 29) { invalid_opcode(vm, opcode); } remainingOpcode >>= 8; } } #endif V verbose_details(NgaState *vm, CELL opcode) { fprintf(stderr, "ip: %lld ", (long long)ACTIVE.ip); fprintf(stderr, "sp: %lld ", (long long)ACTIVE.sp); fprintf(stderr, "rp: %lld ", (long long)ACTIVE.rp); fprintf(stderr, "core: %lld ", (long long)vm->active); fprintf(stderr, "opcode: %lld\n", (long long)opcode); } #define INST(n) ((opcode >> n) & 0xFF) != 0 V process_opcode_bundle(NgaState *vm, CELL opcode) { #ifndef BRANCH_PREDICTION if (INST(0)) instructions[opcode & 0xFF](vm); if (INST(8)) instructions[(opcode >> 8) & 0xFF](vm); if (INST(16)) instructions[(opcode >> 16) & 0xFF](vm); if (INST(24)) instructions[(opcode >> 24) & 0xFF](vm); #else for (size_t i = 0; i < 4; ++i) { uint8_t current = ((uint8_t*)&opcode)[i]; if (unlikely(current > 29)) { invalid_opcode(vm, opcode); } instructions[current](vm); } #endif } #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