[{"data":1,"prerenderedAt":4238},["ShallowReactive",2],{"page-\u002Flua\u002F12-standard-library":3},{"id":4,"title":5,"body":6,"description":4229,"extension":4230,"meta":4231,"navigation":148,"path":4232,"seo":4233,"stem":4236,"__hash__":4237},"content\u002Flua\u002F12-standard-library.md","Lua 12 — Standard Library Deep-Dive",{"type":7,"value":8,"toc":4220},"minimark",[9,14,62,69,3932,3941,3950,3959,3963,3976,3993,4008,4081,4096,4100,4216],[10,11,13],"h1",{"id":12},"_12-standard-library-deep-dive","12 — Standard Library Deep-Dive",[15,16,17,18,22,23,22,26,22,29,22,32,22,35,22,38,22,41,22,44,47,48,22,51,22,54,57,58,61],"p",{},"Lua's standard library is deliberately small: ",[19,20,21],"code",{},"math",", ",[19,24,25],{},"string",[19,27,28],{},"table",[19,30,31],{},"io",[19,33,34],{},"os",[19,36,37],{},"debug",[19,39,40],{},"coroutine",[19,42,43],{},"utf8",[19,45,46],{},"package",". Each is a single table of functions. No ",[19,49,50],{},"array",[19,52,53],{},"json",[19,55,56],{},"re",", or ",[19,59,60],{},"datetime"," modules — those are external (luarocks). This chapter covers the non-obvious behaviors and production patterns for each library.",[63,64,66,68],"h2",{"id":65},"math-numbers-randomness",[19,67,21],{}," — Numbers & Randomness",[70,71,73,530,538],"code-wrapper",{"language":72},"lua",[74,75,79],"pre",{"className":76,"code":77,"language":72,"meta":78,"style":78},"language-lua shiki shiki-themes github-light github-dark","-- Integer\u002Ffloat inspection (5.3+)\nmath.type(42)        -- \"integer\"\nmath.type(42.0)      -- \"float\"\nmath.type(\"42\")     -- nil (not a number)\n\n-- Integer limits (5.3+)\nmath.maxinteger     -- 9223372036854775807 (2^63 - 1)\nmath.mininteger     -- -9223372036854775808 (-2^63)\nmath.maxinteger + 1 -- math.mininteger (WRAPS — no overflow error)\nmath.tointeger(3.0)  -- 3 (converts float to int if representable)\nmath.tointeger(3.5)  -- nil (not an integer value)\nmath.tointeger(1e30) -- nil (too large for int64)\n\n-- Rounding\nmath.floor(3.7)      -- 3 (toward -inf)\nmath.ceil(3.2)       -- 4 (toward +inf)\nmath.floor(-3.7)     -- -4 (toward -inf, NOT -3 like C truncation)\nmath.ceil(-3.2)      -- -3 (toward +inf)\n\n-- Precision: math.maxinteger is exact; floats lose precision beyond 2^53\nmath.maxinteger == math.maxinteger + 0.0  -- false (float can't represent maxint)\n\n-- Constants\nmath.pi              -- 3.1415926535898\nmath.huge            -- inf (IEEE 754 positive infinity)\nmath.abs(-5)         -- 5\nmath.sqrt(16)        -- 4.0\nmath.exp(1)          -- 2.7182818284590 (e^1)\nmath.log(10)         -- 2.3025850929940 (natural log)\nmath.log(100, 10)    -- 2.0 (log base 10)\nmath.fmod(10, 3)     -- 1.0 (float modulo, truncates toward zero)\n10 % 3              -- 1 (integer modulo, follows sign of dividend)\nmath.fmod(-10, 3)   -- -1.0 (truncation: -10\u002F3 = -3.33, trunc = -3, rem = -1)\n-10 % 3             -- 2 (Lua modulo: follows sign of divisor, -10 = -4*3 + 2)\n","",[19,80,81,90,110,126,143,150,156,165,174,189,206,221,237,242,248,264,281,298,314,319,325,344,349,355,364,373,392,408,425,441,461,481,495,516],{"__ignoreMap":78},[82,83,86],"span",{"class":84,"line":85},"line",1,[82,87,89],{"class":88},"sdCPZ","-- Integer\u002Ffloat inspection (5.3+)\n",[82,91,93,97,101,104,107],{"class":84,"line":92},2,[82,94,96],{"class":95},"snvgF","math.type",[82,98,100],{"class":99},"ssxIu","(",[82,102,103],{"class":95},"42",[82,105,106],{"class":99},")        ",[82,108,109],{"class":88},"-- \"integer\"\n",[82,111,113,115,117,120,123],{"class":84,"line":112},3,[82,114,96],{"class":95},[82,116,100],{"class":99},[82,118,119],{"class":95},"42.0",[82,121,122],{"class":99},")      ",[82,124,125],{"class":88},"-- \"float\"\n",[82,127,129,131,133,137,140],{"class":84,"line":128},4,[82,130,96],{"class":95},[82,132,100],{"class":99},[82,134,136],{"class":135},"sJ6F3","\"42\"",[82,138,139],{"class":99},")     ",[82,141,142],{"class":88},"-- nil (not a number)\n",[82,144,146],{"class":84,"line":145},5,[82,147,149],{"emptyLinePlaceholder":148},true,"\n",[82,151,153],{"class":84,"line":152},6,[82,154,155],{"class":88},"-- Integer limits (5.3+)\n",[82,157,159,162],{"class":84,"line":158},7,[82,160,161],{"class":95},"math.maxinteger",[82,163,164],{"class":88},"     -- 9223372036854775807 (2^63 - 1)\n",[82,166,168,171],{"class":84,"line":167},8,[82,169,170],{"class":95},"math.mininteger",[82,172,173],{"class":88},"     -- -9223372036854775808 (-2^63)\n",[82,175,177,179,183,186],{"class":84,"line":176},9,[82,178,161],{"class":95},[82,180,182],{"class":181},"svdQ7"," +",[82,184,185],{"class":95}," 1",[82,187,188],{"class":88}," -- math.mininteger (WRAPS — no overflow error)\n",[82,190,192,195,197,200,203],{"class":84,"line":191},10,[82,193,194],{"class":95},"math.tointeger",[82,196,100],{"class":99},[82,198,199],{"class":95},"3.0",[82,201,202],{"class":99},")  ",[82,204,205],{"class":88},"-- 3 (converts float to int if representable)\n",[82,207,209,211,213,216,218],{"class":84,"line":208},11,[82,210,194],{"class":95},[82,212,100],{"class":99},[82,214,215],{"class":95},"3.5",[82,217,202],{"class":99},[82,219,220],{"class":88},"-- nil (not an integer value)\n",[82,222,224,226,228,231,234],{"class":84,"line":223},12,[82,225,194],{"class":95},[82,227,100],{"class":99},[82,229,230],{"class":95},"1e30",[82,232,233],{"class":99},") ",[82,235,236],{"class":88},"-- nil (too large for int64)\n",[82,238,240],{"class":84,"line":239},13,[82,241,149],{"emptyLinePlaceholder":148},[82,243,245],{"class":84,"line":244},14,[82,246,247],{"class":88},"-- Rounding\n",[82,249,251,254,256,259,261],{"class":84,"line":250},15,[82,252,253],{"class":95},"math.floor",[82,255,100],{"class":99},[82,257,258],{"class":95},"3.7",[82,260,122],{"class":99},[82,262,263],{"class":88},"-- 3 (toward -inf)\n",[82,265,267,270,272,275,278],{"class":84,"line":266},16,[82,268,269],{"class":95},"math.ceil",[82,271,100],{"class":99},[82,273,274],{"class":95},"3.2",[82,276,277],{"class":99},")       ",[82,279,280],{"class":88},"-- 4 (toward +inf)\n",[82,282,284,286,288,291,293,295],{"class":84,"line":283},17,[82,285,253],{"class":95},[82,287,100],{"class":99},[82,289,290],{"class":181},"-",[82,292,258],{"class":95},[82,294,139],{"class":99},[82,296,297],{"class":88},"-- -4 (toward -inf, NOT -3 like C truncation)\n",[82,299,301,303,305,307,309,311],{"class":84,"line":300},18,[82,302,269],{"class":95},[82,304,100],{"class":99},[82,306,290],{"class":181},[82,308,274],{"class":95},[82,310,122],{"class":99},[82,312,313],{"class":88},"-- -3 (toward +inf)\n",[82,315,317],{"class":84,"line":316},19,[82,318,149],{"emptyLinePlaceholder":148},[82,320,322],{"class":84,"line":321},20,[82,323,324],{"class":88},"-- Precision: math.maxinteger is exact; floats lose precision beyond 2^53\n",[82,326,328,330,333,336,338,341],{"class":84,"line":327},21,[82,329,161],{"class":95},[82,331,332],{"class":181}," ==",[82,334,335],{"class":95}," math.maxinteger",[82,337,182],{"class":181},[82,339,340],{"class":95}," 0.0",[82,342,343],{"class":88},"  -- false (float can't represent maxint)\n",[82,345,347],{"class":84,"line":346},22,[82,348,149],{"emptyLinePlaceholder":148},[82,350,352],{"class":84,"line":351},23,[82,353,354],{"class":88},"-- Constants\n",[82,356,358,361],{"class":84,"line":357},24,[82,359,360],{"class":95},"math.pi",[82,362,363],{"class":88},"              -- 3.1415926535898\n",[82,365,367,370],{"class":84,"line":366},25,[82,368,369],{"class":95},"math.huge",[82,371,372],{"class":88},"            -- inf (IEEE 754 positive infinity)\n",[82,374,376,379,381,383,386,389],{"class":84,"line":375},26,[82,377,378],{"class":95},"math.abs",[82,380,100],{"class":99},[82,382,290],{"class":181},[82,384,385],{"class":95},"5",[82,387,388],{"class":99},")         ",[82,390,391],{"class":88},"-- 5\n",[82,393,395,398,400,403,405],{"class":84,"line":394},27,[82,396,397],{"class":95},"math.sqrt",[82,399,100],{"class":99},[82,401,402],{"class":95},"16",[82,404,106],{"class":99},[82,406,407],{"class":88},"-- 4.0\n",[82,409,411,414,416,419,422],{"class":84,"line":410},28,[82,412,413],{"class":95},"math.exp",[82,415,100],{"class":99},[82,417,418],{"class":95},"1",[82,420,421],{"class":99},")          ",[82,423,424],{"class":88},"-- 2.7182818284590 (e^1)\n",[82,426,428,431,433,436,438],{"class":84,"line":427},29,[82,429,430],{"class":95},"math.log",[82,432,100],{"class":99},[82,434,435],{"class":95},"10",[82,437,388],{"class":99},[82,439,440],{"class":88},"-- 2.3025850929940 (natural log)\n",[82,442,444,446,448,451,453,455,458],{"class":84,"line":443},30,[82,445,430],{"class":95},[82,447,100],{"class":99},[82,449,450],{"class":95},"100",[82,452,22],{"class":99},[82,454,435],{"class":95},[82,456,457],{"class":99},")    ",[82,459,460],{"class":88},"-- 2.0 (log base 10)\n",[82,462,464,467,469,471,473,476,478],{"class":84,"line":463},31,[82,465,466],{"class":95},"math.fmod",[82,468,100],{"class":99},[82,470,435],{"class":95},[82,472,22],{"class":99},[82,474,475],{"class":95},"3",[82,477,139],{"class":99},[82,479,480],{"class":88},"-- 1.0 (float modulo, truncates toward zero)\n",[82,482,484,486,489,492],{"class":84,"line":483},32,[82,485,435],{"class":95},[82,487,488],{"class":181}," %",[82,490,491],{"class":95}," 3",[82,493,494],{"class":88},"              -- 1 (integer modulo, follows sign of dividend)\n",[82,496,498,500,502,504,506,508,510,513],{"class":84,"line":497},33,[82,499,466],{"class":95},[82,501,100],{"class":99},[82,503,290],{"class":181},[82,505,435],{"class":95},[82,507,22],{"class":99},[82,509,475],{"class":95},[82,511,512],{"class":99},")   ",[82,514,515],{"class":88},"-- -1.0 (truncation: -10\u002F3 = -3.33, trunc = -3, rem = -1)\n",[82,517,519,521,523,525,527],{"class":84,"line":518},34,[82,520,290],{"class":181},[82,522,435],{"class":95},[82,524,488],{"class":181},[82,526,491],{"class":95},[82,528,529],{"class":88},"             -- 2 (Lua modulo: follows sign of divisor, -10 = -4*3 + 2)\n",[531,532,534,537],"h3",{"id":533},"mathrandom-seeding",[19,535,536],{},"math.random"," & Seeding",[70,539,540,911,917],{"language":72},[74,541,543],{"className":76,"code":542,"language":72,"meta":78,"style":78},"-- math.random(): float [0, 1)\n-- math.random(n): integer [1, n]\n-- math.random(m, n): integer [m, n]\n\nmath.random()       -- 0.5 (pseudo-random float)\nmath.random(10)     -- 7 (integer 1-10)\nmath.random(5, 15)  -- 11 (integer 5-15)\n\n-- SEEDING: math.randomseed(seed)\n-- CRITICAL: without a seed, every program run produces the SAME sequence\n-- BAD: math.randomseed(1) — deterministic, same every run\n-- BAD: math.randomseed(0) — math.random(1, 10) may return the same value repeatedly\n-- GOOD: seed with high-resolution time + os.time for entropy\nmath.randomseed(os.time())\n-- BETTER (5.4+): math.randomseed(x, y) — two seeds for better distribution\nmath.randomseed(os.time(), os.clock() * 1e6)\n-- BEST: use a crypto library for security-sensitive randomness (luarocks install openssl)\n\n-- Production: secure random without external deps (if \u002Fdev\u002Furandom is available)\nlocal function secure_random(bytes)\n  local f = io.open(\"\u002Fdev\u002Furandom\", \"rb\")\n  if not f then return nil end\n  local data = f:read(bytes)\n  f:close()\n  return data\nend\nlocal seed_data = secure_random(8)  -- 8 bytes from \u002Fdev\u002Furandom\nif seed_data then\n  local seed = 0\n  for i = 1, #seed_data do\n    seed = seed * 256 + seed_data:byte(i)\n  end\n  math.randomseed(seed)\nend\n",[19,544,545,550,555,560,564,574,587,605,609,614,619,624,629,634,647,652,678,683,687,692,707,733,755,775,788,796,801,822,832,844,867,894,899,907],{"__ignoreMap":78},[82,546,547],{"class":84,"line":85},[82,548,549],{"class":88},"-- math.random(): float [0, 1)\n",[82,551,552],{"class":84,"line":92},[82,553,554],{"class":88},"-- math.random(n): integer [1, n]\n",[82,556,557],{"class":84,"line":112},[82,558,559],{"class":88},"-- math.random(m, n): integer [m, n]\n",[82,561,562],{"class":84,"line":128},[82,563,149],{"emptyLinePlaceholder":148},[82,565,566,568,571],{"class":84,"line":145},[82,567,536],{"class":95},[82,569,570],{"class":99},"()       ",[82,572,573],{"class":88},"-- 0.5 (pseudo-random float)\n",[82,575,576,578,580,582,584],{"class":84,"line":152},[82,577,536],{"class":95},[82,579,100],{"class":99},[82,581,435],{"class":95},[82,583,139],{"class":99},[82,585,586],{"class":88},"-- 7 (integer 1-10)\n",[82,588,589,591,593,595,597,600,602],{"class":84,"line":158},[82,590,536],{"class":95},[82,592,100],{"class":99},[82,594,385],{"class":95},[82,596,22],{"class":99},[82,598,599],{"class":95},"15",[82,601,202],{"class":99},[82,603,604],{"class":88},"-- 11 (integer 5-15)\n",[82,606,607],{"class":84,"line":167},[82,608,149],{"emptyLinePlaceholder":148},[82,610,611],{"class":84,"line":176},[82,612,613],{"class":88},"-- SEEDING: math.randomseed(seed)\n",[82,615,616],{"class":84,"line":191},[82,617,618],{"class":88},"-- CRITICAL: without a seed, every program run produces the SAME sequence\n",[82,620,621],{"class":84,"line":208},[82,622,623],{"class":88},"-- BAD: math.randomseed(1) — deterministic, same every run\n",[82,625,626],{"class":84,"line":223},[82,627,628],{"class":88},"-- BAD: math.randomseed(0) — math.random(1, 10) may return the same value repeatedly\n",[82,630,631],{"class":84,"line":239},[82,632,633],{"class":88},"-- GOOD: seed with high-resolution time + os.time for entropy\n",[82,635,636,639,641,644],{"class":84,"line":244},[82,637,638],{"class":95},"math.randomseed",[82,640,100],{"class":99},[82,642,643],{"class":95},"os.time",[82,645,646],{"class":99},"())\n",[82,648,649],{"class":84,"line":250},[82,650,651],{"class":88},"-- BETTER (5.4+): math.randomseed(x, y) — two seeds for better distribution\n",[82,653,654,656,658,660,663,666,669,672,675],{"class":84,"line":266},[82,655,638],{"class":95},[82,657,100],{"class":99},[82,659,643],{"class":95},[82,661,662],{"class":99},"(), ",[82,664,665],{"class":95},"os.clock",[82,667,668],{"class":99},"() ",[82,670,671],{"class":181},"*",[82,673,674],{"class":95}," 1e6",[82,676,677],{"class":99},")\n",[82,679,680],{"class":84,"line":283},[82,681,682],{"class":88},"-- BEST: use a crypto library for security-sensitive randomness (luarocks install openssl)\n",[82,684,685],{"class":84,"line":300},[82,686,149],{"emptyLinePlaceholder":148},[82,688,689],{"class":84,"line":316},[82,690,691],{"class":88},"-- Production: secure random without external deps (if \u002Fdev\u002Furandom is available)\n",[82,693,694,697,700,704],{"class":84,"line":321},[82,695,696],{"class":181},"local",[82,698,699],{"class":181}," function",[82,701,703],{"class":702},"sIsaT"," secure_random",[82,705,706],{"class":99},"(bytes)\n",[82,708,709,712,715,718,721,723,726,728,731],{"class":84,"line":327},[82,710,711],{"class":181},"  local",[82,713,714],{"class":99}," f ",[82,716,717],{"class":181},"=",[82,719,720],{"class":95}," io.open",[82,722,100],{"class":99},[82,724,725],{"class":135},"\"\u002Fdev\u002Furandom\"",[82,727,22],{"class":99},[82,729,730],{"class":135},"\"rb\"",[82,732,677],{"class":99},[82,734,735,738,741,743,746,749,752],{"class":84,"line":346},[82,736,737],{"class":181},"  if",[82,739,740],{"class":181}," not",[82,742,714],{"class":99},[82,744,745],{"class":181},"then",[82,747,748],{"class":181}," return",[82,750,751],{"class":95}," nil",[82,753,754],{"class":181}," end\n",[82,756,757,759,762,764,767,770,773],{"class":84,"line":351},[82,758,711],{"class":181},[82,760,761],{"class":99}," data ",[82,763,717],{"class":181},[82,765,766],{"class":702}," f",[82,768,769],{"class":99},":",[82,771,772],{"class":95},"read",[82,774,706],{"class":99},[82,776,777,780,782,785],{"class":84,"line":357},[82,778,779],{"class":702},"  f",[82,781,769],{"class":99},[82,783,784],{"class":95},"close",[82,786,787],{"class":99},"()\n",[82,789,790,793],{"class":84,"line":366},[82,791,792],{"class":181},"  return",[82,794,795],{"class":99}," data\n",[82,797,798],{"class":84,"line":375},[82,799,800],{"class":181},"end\n",[82,802,803,805,808,810,812,814,817,819],{"class":84,"line":394},[82,804,696],{"class":181},[82,806,807],{"class":99}," seed_data ",[82,809,717],{"class":181},[82,811,703],{"class":95},[82,813,100],{"class":99},[82,815,816],{"class":95},"8",[82,818,202],{"class":99},[82,820,821],{"class":88},"-- 8 bytes from \u002Fdev\u002Furandom\n",[82,823,824,827,829],{"class":84,"line":410},[82,825,826],{"class":181},"if",[82,828,807],{"class":99},[82,830,831],{"class":181},"then\n",[82,833,834,836,839,841],{"class":84,"line":427},[82,835,711],{"class":181},[82,837,838],{"class":99}," seed ",[82,840,717],{"class":181},[82,842,843],{"class":95}," 0\n",[82,845,846,849,852,854,856,858,861,864],{"class":84,"line":443},[82,847,848],{"class":181},"  for",[82,850,851],{"class":99}," i ",[82,853,717],{"class":181},[82,855,185],{"class":95},[82,857,22],{"class":99},[82,859,860],{"class":181},"#",[82,862,863],{"class":99},"seed_data ",[82,865,866],{"class":181},"do\n",[82,868,869,872,874,876,878,881,883,886,888,891],{"class":84,"line":463},[82,870,871],{"class":99},"    seed ",[82,873,717],{"class":181},[82,875,838],{"class":99},[82,877,671],{"class":181},[82,879,880],{"class":95}," 256",[82,882,182],{"class":181},[82,884,885],{"class":702}," seed_data",[82,887,769],{"class":99},[82,889,890],{"class":95},"byte",[82,892,893],{"class":99},"(i)\n",[82,895,896],{"class":84,"line":483},[82,897,898],{"class":181},"  end\n",[82,900,901,904],{"class":84,"line":497},[82,902,903],{"class":95},"  math.randomseed",[82,905,906],{"class":99},"(seed)\n",[82,908,909],{"class":84,"line":518},[82,910,800],{"class":181},[531,912,914,916],{"id":913},"math-utility-functions",[19,915,21],{}," utility functions",[70,918,919,1191,1197],{"language":72},[74,920,922],{"className":76,"code":921,"language":72,"meta":78,"style":78},"math.max(3, 7, 1)   -- 7 (variadic)\nmath.min(3, 7, 1)   -- 1\nmath.huge           -- inf\n-math.huge          -- -inf\nmath.abs(math.huge) -- inf\n\n-- modf: separate integer and fractional parts\nlocal int, frac = math.modf(3.14)  -- 3, 0.14\nlocal int2, frac2 = math.modf(-3.14) -- -3, -0.14\n\n-- IEEE 754 edge cases:\n1 \u002F 0     -- inf (NOT an error — IEEE 754)\n-1 \u002F 0    -- -inf\n0 \u002F 0     -- -nan (or nan)\nmath.huge - math.huge  -- -nan (indeterminate)\n1e308 * 10  -- inf (overflow to infinity)\n1e-308 * 0.001 -- 0 (underflow to zero)\n-- NaN comparison: NaN ~= NaN is true (the only value where x ~= x)\nlocal nan = 0\u002F0\nprint(nan == nan)  -- false (NaN is never equal to anything, including itself)\nprint(nan ~= nan)  -- true (this is the NaN check pattern)\n",[19,923,924,947,969,976,985,998,1002,1007,1029,1051,1055,1060,1073,1086,1098,1111,1125,1138,1143,1160,1177],{"__ignoreMap":78},[82,925,926,929,931,933,935,938,940,942,944],{"class":84,"line":85},[82,927,928],{"class":95},"math.max",[82,930,100],{"class":99},[82,932,475],{"class":95},[82,934,22],{"class":99},[82,936,937],{"class":95},"7",[82,939,22],{"class":99},[82,941,418],{"class":95},[82,943,512],{"class":99},[82,945,946],{"class":88},"-- 7 (variadic)\n",[82,948,949,952,954,956,958,960,962,964,966],{"class":84,"line":92},[82,950,951],{"class":95},"math.min",[82,953,100],{"class":99},[82,955,475],{"class":95},[82,957,22],{"class":99},[82,959,937],{"class":95},[82,961,22],{"class":99},[82,963,418],{"class":95},[82,965,512],{"class":99},[82,967,968],{"class":88},"-- 1\n",[82,970,971,973],{"class":84,"line":112},[82,972,369],{"class":95},[82,974,975],{"class":88},"           -- inf\n",[82,977,978,980,982],{"class":84,"line":128},[82,979,290],{"class":181},[82,981,369],{"class":95},[82,983,984],{"class":88},"          -- -inf\n",[82,986,987,989,991,993,995],{"class":84,"line":145},[82,988,378],{"class":95},[82,990,100],{"class":99},[82,992,369],{"class":95},[82,994,233],{"class":99},[82,996,997],{"class":88},"-- inf\n",[82,999,1000],{"class":84,"line":152},[82,1001,149],{"emptyLinePlaceholder":148},[82,1003,1004],{"class":84,"line":158},[82,1005,1006],{"class":88},"-- modf: separate integer and fractional parts\n",[82,1008,1009,1011,1014,1016,1019,1021,1024,1026],{"class":84,"line":167},[82,1010,696],{"class":181},[82,1012,1013],{"class":99}," int, frac ",[82,1015,717],{"class":181},[82,1017,1018],{"class":95}," math.modf",[82,1020,100],{"class":99},[82,1022,1023],{"class":95},"3.14",[82,1025,202],{"class":99},[82,1027,1028],{"class":88},"-- 3, 0.14\n",[82,1030,1031,1033,1036,1038,1040,1042,1044,1046,1048],{"class":84,"line":176},[82,1032,696],{"class":181},[82,1034,1035],{"class":99}," int2, frac2 ",[82,1037,717],{"class":181},[82,1039,1018],{"class":95},[82,1041,100],{"class":99},[82,1043,290],{"class":181},[82,1045,1023],{"class":95},[82,1047,233],{"class":99},[82,1049,1050],{"class":88},"-- -3, -0.14\n",[82,1052,1053],{"class":84,"line":191},[82,1054,149],{"emptyLinePlaceholder":148},[82,1056,1057],{"class":84,"line":208},[82,1058,1059],{"class":88},"-- IEEE 754 edge cases:\n",[82,1061,1062,1064,1067,1070],{"class":84,"line":223},[82,1063,418],{"class":95},[82,1065,1066],{"class":181}," \u002F",[82,1068,1069],{"class":95}," 0",[82,1071,1072],{"class":88},"     -- inf (NOT an error — IEEE 754)\n",[82,1074,1075,1077,1079,1081,1083],{"class":84,"line":239},[82,1076,290],{"class":181},[82,1078,418],{"class":95},[82,1080,1066],{"class":181},[82,1082,1069],{"class":95},[82,1084,1085],{"class":88},"    -- -inf\n",[82,1087,1088,1091,1093,1095],{"class":84,"line":244},[82,1089,1090],{"class":95},"0",[82,1092,1066],{"class":181},[82,1094,1069],{"class":95},[82,1096,1097],{"class":88},"     -- -nan (or nan)\n",[82,1099,1100,1102,1105,1108],{"class":84,"line":250},[82,1101,369],{"class":95},[82,1103,1104],{"class":181}," -",[82,1106,1107],{"class":95}," math.huge",[82,1109,1110],{"class":88},"  -- -nan (indeterminate)\n",[82,1112,1113,1116,1119,1122],{"class":84,"line":266},[82,1114,1115],{"class":95},"1e308",[82,1117,1118],{"class":181}," *",[82,1120,1121],{"class":95}," 10",[82,1123,1124],{"class":88},"  -- inf (overflow to infinity)\n",[82,1126,1127,1130,1132,1135],{"class":84,"line":283},[82,1128,1129],{"class":95},"1e-308",[82,1131,1118],{"class":181},[82,1133,1134],{"class":95}," 0.001",[82,1136,1137],{"class":88}," -- 0 (underflow to zero)\n",[82,1139,1140],{"class":84,"line":300},[82,1141,1142],{"class":88},"-- NaN comparison: NaN ~= NaN is true (the only value where x ~= x)\n",[82,1144,1145,1147,1150,1152,1154,1157],{"class":84,"line":316},[82,1146,696],{"class":181},[82,1148,1149],{"class":99}," nan ",[82,1151,717],{"class":181},[82,1153,1069],{"class":95},[82,1155,1156],{"class":181},"\u002F",[82,1158,1159],{"class":95},"0\n",[82,1161,1162,1165,1168,1171,1174],{"class":84,"line":321},[82,1163,1164],{"class":95},"print",[82,1166,1167],{"class":99},"(nan ",[82,1169,1170],{"class":181},"==",[82,1172,1173],{"class":99}," nan)  ",[82,1175,1176],{"class":88},"-- false (NaN is never equal to anything, including itself)\n",[82,1178,1179,1181,1183,1186,1188],{"class":84,"line":327},[82,1180,1164],{"class":95},[82,1182,1167],{"class":99},[82,1184,1185],{"class":181},"~=",[82,1187,1173],{"class":99},[82,1189,1190],{"class":88},"-- true (this is the NaN check pattern)\n",[63,1192,1194,1196],{"id":1193},"os-time-date-environment",[19,1195,34],{}," — Time, Date, Environment",[70,1198,1199,1552,1556],{"language":72},[74,1200,1202],{"className":76,"code":1201,"language":72,"meta":78,"style":78},"-- os.time(table?): epoch seconds (UTC). Table optional (defaults to now).\nos.time()  -- 1710460800 (seconds since 1970-01-01 00:00:00 UTC)\nos.time({year=2024, month=1, day=15, hour=0})  -- epoch for that date\nos.time({year=2024, month=1, day=15})  -- epoch for midnight 2024-01-15\n\n-- os.date(format, time?): formatted date string\nos.date(\"%Y-%m-%d %H:%M:%S\")  -- \"2024-01-15 13:55:36\" (local time)\nos.date(\"!%Y-%m-%d\")          -- \"2024-01-15\" (UTC — ! prefix)\nos.date(\"%A\", os.time())      -- \"Monday\" (full weekday name, localized)\nos.date(\"*t\", os.time())      -- table: {year=2024, month=1, day=15, hour=13, ...}\nos.date(\"!*t\")                -- UTC table\n\n-- os.clock(): CPU time (seconds) used by the program — for benchmarking\nlocal start = os.clock()\n-- ... work ...\nlocal elapsed = os.clock() - start  -- CPU time, NOT wall clock\n\n-- os.difftime(t2, t1): difference in seconds (handles platform differences)\nlocal diff = os.difftime(os.time(), start_time)\n\n-- os.getenv(name): environment variable (or nil)\nprint(os.getenv(\"HOME\"))  -- \"\u002Fhome\u002Fuser\" (or nil if not set)\n\n-- os.execute(command): run shell command, return status\n-- Lua 5.4+: returns true\u002Fnil, \"exit\"\u002F\"signal\", exit_code\nlocal ok, reason, code = os.execute(\"ls -la\")\nprint(ok, reason, code)  -- true \"exit\" 0 (success)\n\n-- os.exit(code, close): exit the program\nos.exit(1)  -- exit with code 1\n-- In 5.4: os.exit(1, true) — close all \u003Cclose> variables before exiting\n",[19,1203,1204,1209,1219,1258,1285,1289,1294,1309,1323,1342,1360,1375,1379,1384,1398,1403,1424,1428,1433,1452,1456,1461,1481,1485,1490,1495,1514,1524,1528,1533,1547],{"__ignoreMap":78},[82,1205,1206],{"class":84,"line":85},[82,1207,1208],{"class":88},"-- os.time(table?): epoch seconds (UTC). Table optional (defaults to now).\n",[82,1210,1211,1213,1216],{"class":84,"line":92},[82,1212,643],{"class":95},[82,1214,1215],{"class":99},"()  ",[82,1217,1218],{"class":88},"-- 1710460800 (seconds since 1970-01-01 00:00:00 UTC)\n",[82,1220,1221,1223,1226,1228,1231,1234,1236,1238,1241,1243,1245,1248,1250,1252,1255],{"class":84,"line":112},[82,1222,643],{"class":95},[82,1224,1225],{"class":99},"({year",[82,1227,717],{"class":181},[82,1229,1230],{"class":95},"2024",[82,1232,1233],{"class":99},", month",[82,1235,717],{"class":181},[82,1237,418],{"class":95},[82,1239,1240],{"class":99},", day",[82,1242,717],{"class":181},[82,1244,599],{"class":95},[82,1246,1247],{"class":99},", hour",[82,1249,717],{"class":181},[82,1251,1090],{"class":95},[82,1253,1254],{"class":99},"})  ",[82,1256,1257],{"class":88},"-- epoch for that date\n",[82,1259,1260,1262,1264,1266,1268,1270,1272,1274,1276,1278,1280,1282],{"class":84,"line":128},[82,1261,643],{"class":95},[82,1263,1225],{"class":99},[82,1265,717],{"class":181},[82,1267,1230],{"class":95},[82,1269,1233],{"class":99},[82,1271,717],{"class":181},[82,1273,418],{"class":95},[82,1275,1240],{"class":99},[82,1277,717],{"class":181},[82,1279,599],{"class":95},[82,1281,1254],{"class":99},[82,1283,1284],{"class":88},"-- epoch for midnight 2024-01-15\n",[82,1286,1287],{"class":84,"line":145},[82,1288,149],{"emptyLinePlaceholder":148},[82,1290,1291],{"class":84,"line":152},[82,1292,1293],{"class":88},"-- os.date(format, time?): formatted date string\n",[82,1295,1296,1299,1301,1304,1306],{"class":84,"line":158},[82,1297,1298],{"class":95},"os.date",[82,1300,100],{"class":99},[82,1302,1303],{"class":135},"\"%Y-%m-%d %H:%M:%S\"",[82,1305,202],{"class":99},[82,1307,1308],{"class":88},"-- \"2024-01-15 13:55:36\" (local time)\n",[82,1310,1311,1313,1315,1318,1320],{"class":84,"line":167},[82,1312,1298],{"class":95},[82,1314,100],{"class":99},[82,1316,1317],{"class":135},"\"!%Y-%m-%d\"",[82,1319,421],{"class":99},[82,1321,1322],{"class":88},"-- \"2024-01-15\" (UTC — ! prefix)\n",[82,1324,1325,1327,1329,1332,1334,1336,1339],{"class":84,"line":176},[82,1326,1298],{"class":95},[82,1328,100],{"class":99},[82,1330,1331],{"class":135},"\"%A\"",[82,1333,22],{"class":99},[82,1335,643],{"class":95},[82,1337,1338],{"class":99},"())      ",[82,1340,1341],{"class":88},"-- \"Monday\" (full weekday name, localized)\n",[82,1343,1344,1346,1348,1351,1353,1355,1357],{"class":84,"line":191},[82,1345,1298],{"class":95},[82,1347,100],{"class":99},[82,1349,1350],{"class":135},"\"*t\"",[82,1352,22],{"class":99},[82,1354,643],{"class":95},[82,1356,1338],{"class":99},[82,1358,1359],{"class":88},"-- table: {year=2024, month=1, day=15, hour=13, ...}\n",[82,1361,1362,1364,1366,1369,1372],{"class":84,"line":208},[82,1363,1298],{"class":95},[82,1365,100],{"class":99},[82,1367,1368],{"class":135},"\"!*t\"",[82,1370,1371],{"class":99},")                ",[82,1373,1374],{"class":88},"-- UTC table\n",[82,1376,1377],{"class":84,"line":223},[82,1378,149],{"emptyLinePlaceholder":148},[82,1380,1381],{"class":84,"line":239},[82,1382,1383],{"class":88},"-- os.clock(): CPU time (seconds) used by the program — for benchmarking\n",[82,1385,1386,1388,1391,1393,1396],{"class":84,"line":244},[82,1387,696],{"class":181},[82,1389,1390],{"class":99}," start ",[82,1392,717],{"class":181},[82,1394,1395],{"class":95}," os.clock",[82,1397,787],{"class":99},[82,1399,1400],{"class":84,"line":250},[82,1401,1402],{"class":88},"-- ... work ...\n",[82,1404,1405,1407,1410,1412,1414,1416,1418,1421],{"class":84,"line":266},[82,1406,696],{"class":181},[82,1408,1409],{"class":99}," elapsed ",[82,1411,717],{"class":181},[82,1413,1395],{"class":95},[82,1415,668],{"class":99},[82,1417,290],{"class":181},[82,1419,1420],{"class":99}," start  ",[82,1422,1423],{"class":88},"-- CPU time, NOT wall clock\n",[82,1425,1426],{"class":84,"line":283},[82,1427,149],{"emptyLinePlaceholder":148},[82,1429,1430],{"class":84,"line":300},[82,1431,1432],{"class":88},"-- os.difftime(t2, t1): difference in seconds (handles platform differences)\n",[82,1434,1435,1437,1440,1442,1445,1447,1449],{"class":84,"line":316},[82,1436,696],{"class":181},[82,1438,1439],{"class":99}," diff ",[82,1441,717],{"class":181},[82,1443,1444],{"class":95}," os.difftime",[82,1446,100],{"class":99},[82,1448,643],{"class":95},[82,1450,1451],{"class":99},"(), start_time)\n",[82,1453,1454],{"class":84,"line":321},[82,1455,149],{"emptyLinePlaceholder":148},[82,1457,1458],{"class":84,"line":327},[82,1459,1460],{"class":88},"-- os.getenv(name): environment variable (or nil)\n",[82,1462,1463,1465,1467,1470,1472,1475,1478],{"class":84,"line":346},[82,1464,1164],{"class":95},[82,1466,100],{"class":99},[82,1468,1469],{"class":95},"os.getenv",[82,1471,100],{"class":99},[82,1473,1474],{"class":135},"\"HOME\"",[82,1476,1477],{"class":99},"))  ",[82,1479,1480],{"class":88},"-- \"\u002Fhome\u002Fuser\" (or nil if not set)\n",[82,1482,1483],{"class":84,"line":351},[82,1484,149],{"emptyLinePlaceholder":148},[82,1486,1487],{"class":84,"line":357},[82,1488,1489],{"class":88},"-- os.execute(command): run shell command, return status\n",[82,1491,1492],{"class":84,"line":366},[82,1493,1494],{"class":88},"-- Lua 5.4+: returns true\u002Fnil, \"exit\"\u002F\"signal\", exit_code\n",[82,1496,1497,1499,1502,1504,1507,1509,1512],{"class":84,"line":375},[82,1498,696],{"class":181},[82,1500,1501],{"class":99}," ok, reason, code ",[82,1503,717],{"class":181},[82,1505,1506],{"class":95}," os.execute",[82,1508,100],{"class":99},[82,1510,1511],{"class":135},"\"ls -la\"",[82,1513,677],{"class":99},[82,1515,1516,1518,1521],{"class":84,"line":394},[82,1517,1164],{"class":95},[82,1519,1520],{"class":99},"(ok, reason, code)  ",[82,1522,1523],{"class":88},"-- true \"exit\" 0 (success)\n",[82,1525,1526],{"class":84,"line":410},[82,1527,149],{"emptyLinePlaceholder":148},[82,1529,1530],{"class":84,"line":427},[82,1531,1532],{"class":88},"-- os.exit(code, close): exit the program\n",[82,1534,1535,1538,1540,1542,1544],{"class":84,"line":443},[82,1536,1537],{"class":95},"os.exit",[82,1539,100],{"class":99},[82,1541,418],{"class":95},[82,1543,202],{"class":99},[82,1545,1546],{"class":88},"-- exit with code 1\n",[82,1548,1549],{"class":84,"line":463},[82,1550,1551],{"class":88},"-- In 5.4: os.exit(1, true) — close all \u003Cclose> variables before exiting\n",[531,1553,1555],{"id":1554},"date-math","Date math",[70,1557,1558,1950,1956],{"language":72},[74,1559,1561],{"className":76,"code":1560,"language":72,"meta":78,"style":78},"-- Add days to a date: os.time + seconds, then os.date\nlocal function add_days(date_table, days)\n  local epoch = os.time(date_table)\n  local new_epoch = epoch + days * 24 * 60 * 60  -- seconds per day\n  return os.date(\"*t\", new_epoch)  -- back to table\nend\n\nlocal today = os.date(\"*t\")\nlocal next_week = add_days(today, 7)\nprint(next_week.year, next_week.month, next_week.day)\n\n-- Days between two dates:\nlocal function days_between(t1, t2)\n  return math.floor(os.difftime(os.time(t2), os.time(t1)) \u002F (24 * 60 * 60))\nend\nprint(days_between({year=2024, month=1, day=1}, {year=2024, month=12, day=31}))  -- 365\n\n-- Edge case: daylight saving time transitions\n-- Adding 24*60*60 seconds doesn't always move forward 1 calendar day across DST\n-- For date math, normalize to noon (avoids midnight DST issues):\nlocal function safe_add_days(year, month, day, days)\n  local t = {year=year, month=month, day=day, hour=12}  -- noon avoids DST edge\n  local epoch = os.time(t)\n  return os.date(\"*t\", epoch + days * 24 * 60 * 60)\nend\n",[19,1562,1563,1568,1580,1595,1629,1646,1650,1654,1671,1689,1712,1716,1721,1733,1776,1780,1834,1838,1843,1848,1853,1865,1902,1915,1946],{"__ignoreMap":78},[82,1564,1565],{"class":84,"line":85},[82,1566,1567],{"class":88},"-- Add days to a date: os.time + seconds, then os.date\n",[82,1569,1570,1572,1574,1577],{"class":84,"line":92},[82,1571,696],{"class":181},[82,1573,699],{"class":181},[82,1575,1576],{"class":702}," add_days",[82,1578,1579],{"class":99},"(date_table, days)\n",[82,1581,1582,1584,1587,1589,1592],{"class":84,"line":112},[82,1583,711],{"class":181},[82,1585,1586],{"class":99}," epoch ",[82,1588,717],{"class":181},[82,1590,1591],{"class":95}," os.time",[82,1593,1594],{"class":99},"(date_table)\n",[82,1596,1597,1599,1602,1604,1606,1609,1612,1614,1617,1619,1622,1624,1626],{"class":84,"line":128},[82,1598,711],{"class":181},[82,1600,1601],{"class":99}," new_epoch ",[82,1603,717],{"class":181},[82,1605,1586],{"class":99},[82,1607,1608],{"class":181},"+",[82,1610,1611],{"class":99}," days ",[82,1613,671],{"class":181},[82,1615,1616],{"class":95}," 24",[82,1618,1118],{"class":181},[82,1620,1621],{"class":95}," 60",[82,1623,1118],{"class":181},[82,1625,1621],{"class":95},[82,1627,1628],{"class":88},"  -- seconds per day\n",[82,1630,1631,1633,1636,1638,1640,1643],{"class":84,"line":145},[82,1632,792],{"class":181},[82,1634,1635],{"class":95}," os.date",[82,1637,100],{"class":99},[82,1639,1350],{"class":135},[82,1641,1642],{"class":99},", new_epoch)  ",[82,1644,1645],{"class":88},"-- back to table\n",[82,1647,1648],{"class":84,"line":152},[82,1649,800],{"class":181},[82,1651,1652],{"class":84,"line":158},[82,1653,149],{"emptyLinePlaceholder":148},[82,1655,1656,1658,1661,1663,1665,1667,1669],{"class":84,"line":167},[82,1657,696],{"class":181},[82,1659,1660],{"class":99}," today ",[82,1662,717],{"class":181},[82,1664,1635],{"class":95},[82,1666,100],{"class":99},[82,1668,1350],{"class":135},[82,1670,677],{"class":99},[82,1672,1673,1675,1678,1680,1682,1685,1687],{"class":84,"line":176},[82,1674,696],{"class":181},[82,1676,1677],{"class":99}," next_week ",[82,1679,717],{"class":181},[82,1681,1576],{"class":95},[82,1683,1684],{"class":99},"(today, ",[82,1686,937],{"class":95},[82,1688,677],{"class":99},[82,1690,1691,1693,1696,1699,1702,1705,1707,1710],{"class":84,"line":191},[82,1692,1164],{"class":95},[82,1694,1695],{"class":99},"(next_week.",[82,1697,1698],{"class":702},"year",[82,1700,1701],{"class":99},", next_week.",[82,1703,1704],{"class":702},"month",[82,1706,1701],{"class":99},[82,1708,1709],{"class":702},"day",[82,1711,677],{"class":99},[82,1713,1714],{"class":84,"line":208},[82,1715,149],{"emptyLinePlaceholder":148},[82,1717,1718],{"class":84,"line":223},[82,1719,1720],{"class":88},"-- Days between two dates:\n",[82,1722,1723,1725,1727,1730],{"class":84,"line":239},[82,1724,696],{"class":181},[82,1726,699],{"class":181},[82,1728,1729],{"class":702}," days_between",[82,1731,1732],{"class":99},"(t1, t2)\n",[82,1734,1735,1737,1740,1742,1745,1747,1749,1752,1754,1757,1759,1762,1765,1767,1769,1771,1773],{"class":84,"line":244},[82,1736,792],{"class":181},[82,1738,1739],{"class":95}," math.floor",[82,1741,100],{"class":99},[82,1743,1744],{"class":95},"os.difftime",[82,1746,100],{"class":99},[82,1748,643],{"class":95},[82,1750,1751],{"class":99},"(t2), ",[82,1753,643],{"class":95},[82,1755,1756],{"class":99},"(t1)) ",[82,1758,1156],{"class":181},[82,1760,1761],{"class":99}," (",[82,1763,1764],{"class":95},"24",[82,1766,1118],{"class":181},[82,1768,1621],{"class":95},[82,1770,1118],{"class":181},[82,1772,1621],{"class":95},[82,1774,1775],{"class":99},"))\n",[82,1777,1778],{"class":84,"line":250},[82,1779,800],{"class":181},[82,1781,1782,1784,1786,1789,1791,1793,1795,1797,1799,1801,1803,1805,1807,1810,1812,1814,1816,1818,1821,1823,1825,1828,1831],{"class":84,"line":266},[82,1783,1164],{"class":95},[82,1785,100],{"class":99},[82,1787,1788],{"class":95},"days_between",[82,1790,1225],{"class":99},[82,1792,717],{"class":181},[82,1794,1230],{"class":95},[82,1796,1233],{"class":99},[82,1798,717],{"class":181},[82,1800,418],{"class":95},[82,1802,1240],{"class":99},[82,1804,717],{"class":181},[82,1806,418],{"class":95},[82,1808,1809],{"class":99},"}, {year",[82,1811,717],{"class":181},[82,1813,1230],{"class":95},[82,1815,1233],{"class":99},[82,1817,717],{"class":181},[82,1819,1820],{"class":95},"12",[82,1822,1240],{"class":99},[82,1824,717],{"class":181},[82,1826,1827],{"class":95},"31",[82,1829,1830],{"class":99},"}))  ",[82,1832,1833],{"class":88},"-- 365\n",[82,1835,1836],{"class":84,"line":283},[82,1837,149],{"emptyLinePlaceholder":148},[82,1839,1840],{"class":84,"line":300},[82,1841,1842],{"class":88},"-- Edge case: daylight saving time transitions\n",[82,1844,1845],{"class":84,"line":316},[82,1846,1847],{"class":88},"-- Adding 24*60*60 seconds doesn't always move forward 1 calendar day across DST\n",[82,1849,1850],{"class":84,"line":321},[82,1851,1852],{"class":88},"-- For date math, normalize to noon (avoids midnight DST issues):\n",[82,1854,1855,1857,1859,1862],{"class":84,"line":327},[82,1856,696],{"class":181},[82,1858,699],{"class":181},[82,1860,1861],{"class":702}," safe_add_days",[82,1863,1864],{"class":99},"(year, month, day, days)\n",[82,1866,1867,1869,1872,1874,1877,1879,1882,1884,1887,1889,1892,1894,1896,1899],{"class":84,"line":346},[82,1868,711],{"class":181},[82,1870,1871],{"class":99}," t ",[82,1873,717],{"class":181},[82,1875,1876],{"class":99}," {year",[82,1878,717],{"class":181},[82,1880,1881],{"class":99},"year, month",[82,1883,717],{"class":181},[82,1885,1886],{"class":99},"month, day",[82,1888,717],{"class":181},[82,1890,1891],{"class":99},"day, hour",[82,1893,717],{"class":181},[82,1895,1820],{"class":95},[82,1897,1898],{"class":99},"}  ",[82,1900,1901],{"class":88},"-- noon avoids DST edge\n",[82,1903,1904,1906,1908,1910,1912],{"class":84,"line":351},[82,1905,711],{"class":181},[82,1907,1586],{"class":99},[82,1909,717],{"class":181},[82,1911,1591],{"class":95},[82,1913,1914],{"class":99},"(t)\n",[82,1916,1917,1919,1921,1923,1925,1928,1930,1932,1934,1936,1938,1940,1942,1944],{"class":84,"line":357},[82,1918,792],{"class":181},[82,1920,1635],{"class":95},[82,1922,100],{"class":99},[82,1924,1350],{"class":135},[82,1926,1927],{"class":99},", epoch ",[82,1929,1608],{"class":181},[82,1931,1611],{"class":99},[82,1933,671],{"class":181},[82,1935,1616],{"class":95},[82,1937,1118],{"class":181},[82,1939,1621],{"class":95},[82,1941,1118],{"class":181},[82,1943,1621],{"class":95},[82,1945,677],{"class":99},[82,1947,1948],{"class":84,"line":366},[82,1949,800],{"class":181},[63,1951,1953,1955],{"id":1952},"table-operations-internals",[19,1954,28],{}," — Operations & Internals",[70,1957,1958,2381,2388],{"language":72},[74,1959,1961],{"className":76,"code":1960,"language":72,"meta":78,"style":78},"-- table.insert(t, [pos,] value): insert at pos (default: end), shifts elements right\nlocal t = {1, 2, 4, 5}\ntable.insert(t, 3, 3)  -- insert 3 at index 3: {1, 2, 3, 4, 5}\n-- O(n) — shifts all elements after pos\n\n-- table.remove(t, [pos]): remove and return element at pos (default: end)\nlocal v = table.remove(t, 3)  -- returns 3; t = {1, 2, 4, 5}\n-- O(n) — shifts elements left\n\n-- table.move(src, f, e, t, [dest]): move src[f..e] to dest starting at t\n-- In-place if dest omitted (operates on src)\nlocal a = {1, 2, 3, 4, 5}\ntable.move(a, 2, 4, 1)  -- a = {2, 3, 4, 4, 5} (moved src[2..4] to position 1)\n-- For overlapping ranges, Lua handles the direction correctly\n\n-- table.concat(t, sep, i, j): join array part with separator\ntable.concat({1, 2, 3}, \", \")      -- \"1, 2, 3\"\ntable.concat({1, 2, 3}, \"-\", 2, 3) -- \"2-3\" (from index 2 to 3)\n-- Elements MUST be strings or numbers (errors on tables\u002Ffunctions\u002Fnils)\ntable.concat({1, nil, 3}, \",\")    -- ERROR: invalid value (nil) at index 2\n\n-- table.pack\u002Funpack (5.2+)\nlocal packed = table.pack(1, nil, 3)  -- {1, nil, 3, n = 3} (preserves nils via .n)\nlocal a, b, c = table.unpack(packed, 1, packed.n)  -- 1, nil, 3 (use .n for range)\n\n-- table.unpack: convert table to multiple values\nlocal function sum(a, b, c) return a + b + c end\nlocal args = {1, 2, 3}\nprint(sum(table.unpack(args)))  -- 6\n",[19,1962,1963,1968,1998,2017,2022,2026,2031,2052,2057,2061,2066,2071,2102,2125,2130,2134,2139,2168,2202,2207,2234,2238,2243,2272,2300,2304,2309,2338,2361],{"__ignoreMap":78},[82,1964,1965],{"class":84,"line":85},[82,1966,1967],{"class":88},"-- table.insert(t, [pos,] value): insert at pos (default: end), shifts elements right\n",[82,1969,1970,1972,1974,1976,1979,1981,1983,1986,1988,1991,1993,1995],{"class":84,"line":92},[82,1971,696],{"class":181},[82,1973,1871],{"class":99},[82,1975,717],{"class":181},[82,1977,1978],{"class":99}," {",[82,1980,418],{"class":95},[82,1982,22],{"class":99},[82,1984,1985],{"class":95},"2",[82,1987,22],{"class":99},[82,1989,1990],{"class":95},"4",[82,1992,22],{"class":99},[82,1994,385],{"class":95},[82,1996,1997],{"class":99},"}\n",[82,1999,2000,2003,2006,2008,2010,2012,2014],{"class":84,"line":112},[82,2001,2002],{"class":95},"table.insert",[82,2004,2005],{"class":99},"(t, ",[82,2007,475],{"class":95},[82,2009,22],{"class":99},[82,2011,475],{"class":95},[82,2013,202],{"class":99},[82,2015,2016],{"class":88},"-- insert 3 at index 3: {1, 2, 3, 4, 5}\n",[82,2018,2019],{"class":84,"line":128},[82,2020,2021],{"class":88},"-- O(n) — shifts all elements after pos\n",[82,2023,2024],{"class":84,"line":145},[82,2025,149],{"emptyLinePlaceholder":148},[82,2027,2028],{"class":84,"line":152},[82,2029,2030],{"class":88},"-- table.remove(t, [pos]): remove and return element at pos (default: end)\n",[82,2032,2033,2035,2038,2040,2043,2045,2047,2049],{"class":84,"line":158},[82,2034,696],{"class":181},[82,2036,2037],{"class":99}," v ",[82,2039,717],{"class":181},[82,2041,2042],{"class":95}," table.remove",[82,2044,2005],{"class":99},[82,2046,475],{"class":95},[82,2048,202],{"class":99},[82,2050,2051],{"class":88},"-- returns 3; t = {1, 2, 4, 5}\n",[82,2053,2054],{"class":84,"line":167},[82,2055,2056],{"class":88},"-- O(n) — shifts elements left\n",[82,2058,2059],{"class":84,"line":176},[82,2060,149],{"emptyLinePlaceholder":148},[82,2062,2063],{"class":84,"line":191},[82,2064,2065],{"class":88},"-- table.move(src, f, e, t, [dest]): move src[f..e] to dest starting at t\n",[82,2067,2068],{"class":84,"line":208},[82,2069,2070],{"class":88},"-- In-place if dest omitted (operates on src)\n",[82,2072,2073,2075,2078,2080,2082,2084,2086,2088,2090,2092,2094,2096,2098,2100],{"class":84,"line":223},[82,2074,696],{"class":181},[82,2076,2077],{"class":99}," a ",[82,2079,717],{"class":181},[82,2081,1978],{"class":99},[82,2083,418],{"class":95},[82,2085,22],{"class":99},[82,2087,1985],{"class":95},[82,2089,22],{"class":99},[82,2091,475],{"class":95},[82,2093,22],{"class":99},[82,2095,1990],{"class":95},[82,2097,22],{"class":99},[82,2099,385],{"class":95},[82,2101,1997],{"class":99},[82,2103,2104,2107,2110,2112,2114,2116,2118,2120,2122],{"class":84,"line":239},[82,2105,2106],{"class":95},"table.move",[82,2108,2109],{"class":99},"(a, ",[82,2111,1985],{"class":95},[82,2113,22],{"class":99},[82,2115,1990],{"class":95},[82,2117,22],{"class":99},[82,2119,418],{"class":95},[82,2121,202],{"class":99},[82,2123,2124],{"class":88},"-- a = {2, 3, 4, 4, 5} (moved src[2..4] to position 1)\n",[82,2126,2127],{"class":84,"line":244},[82,2128,2129],{"class":88},"-- For overlapping ranges, Lua handles the direction correctly\n",[82,2131,2132],{"class":84,"line":250},[82,2133,149],{"emptyLinePlaceholder":148},[82,2135,2136],{"class":84,"line":266},[82,2137,2138],{"class":88},"-- table.concat(t, sep, i, j): join array part with separator\n",[82,2140,2141,2144,2147,2149,2151,2153,2155,2157,2160,2163,2165],{"class":84,"line":283},[82,2142,2143],{"class":95},"table.concat",[82,2145,2146],{"class":99},"({",[82,2148,418],{"class":95},[82,2150,22],{"class":99},[82,2152,1985],{"class":95},[82,2154,22],{"class":99},[82,2156,475],{"class":95},[82,2158,2159],{"class":99},"}, ",[82,2161,2162],{"class":135},"\", \"",[82,2164,122],{"class":99},[82,2166,2167],{"class":88},"-- \"1, 2, 3\"\n",[82,2169,2170,2172,2174,2176,2178,2180,2182,2184,2186,2189,2191,2193,2195,2197,2199],{"class":84,"line":300},[82,2171,2143],{"class":95},[82,2173,2146],{"class":99},[82,2175,418],{"class":95},[82,2177,22],{"class":99},[82,2179,1985],{"class":95},[82,2181,22],{"class":99},[82,2183,475],{"class":95},[82,2185,2159],{"class":99},[82,2187,2188],{"class":135},"\"-\"",[82,2190,22],{"class":99},[82,2192,1985],{"class":95},[82,2194,22],{"class":99},[82,2196,475],{"class":95},[82,2198,233],{"class":99},[82,2200,2201],{"class":88},"-- \"2-3\" (from index 2 to 3)\n",[82,2203,2204],{"class":84,"line":316},[82,2205,2206],{"class":88},"-- Elements MUST be strings or numbers (errors on tables\u002Ffunctions\u002Fnils)\n",[82,2208,2209,2211,2213,2215,2217,2220,2222,2224,2226,2229,2231],{"class":84,"line":321},[82,2210,2143],{"class":95},[82,2212,2146],{"class":99},[82,2214,418],{"class":95},[82,2216,22],{"class":99},[82,2218,2219],{"class":95},"nil",[82,2221,22],{"class":99},[82,2223,475],{"class":95},[82,2225,2159],{"class":99},[82,2227,2228],{"class":135},"\",\"",[82,2230,457],{"class":99},[82,2232,2233],{"class":88},"-- ERROR: invalid value (nil) at index 2\n",[82,2235,2236],{"class":84,"line":327},[82,2237,149],{"emptyLinePlaceholder":148},[82,2239,2240],{"class":84,"line":346},[82,2241,2242],{"class":88},"-- table.pack\u002Funpack (5.2+)\n",[82,2244,2245,2247,2250,2252,2255,2257,2259,2261,2263,2265,2267,2269],{"class":84,"line":351},[82,2246,696],{"class":181},[82,2248,2249],{"class":99}," packed ",[82,2251,717],{"class":181},[82,2253,2254],{"class":95}," table.pack",[82,2256,100],{"class":99},[82,2258,418],{"class":95},[82,2260,22],{"class":99},[82,2262,2219],{"class":95},[82,2264,22],{"class":99},[82,2266,475],{"class":95},[82,2268,202],{"class":99},[82,2270,2271],{"class":88},"-- {1, nil, 3, n = 3} (preserves nils via .n)\n",[82,2273,2274,2276,2279,2281,2284,2287,2289,2292,2295,2297],{"class":84,"line":357},[82,2275,696],{"class":181},[82,2277,2278],{"class":99}," a, b, c ",[82,2280,717],{"class":181},[82,2282,2283],{"class":95}," table.unpack",[82,2285,2286],{"class":99},"(packed, ",[82,2288,418],{"class":95},[82,2290,2291],{"class":99},", packed.",[82,2293,2294],{"class":702},"n",[82,2296,202],{"class":99},[82,2298,2299],{"class":88},"-- 1, nil, 3 (use .n for range)\n",[82,2301,2302],{"class":84,"line":366},[82,2303,149],{"emptyLinePlaceholder":148},[82,2305,2306],{"class":84,"line":375},[82,2307,2308],{"class":88},"-- table.unpack: convert table to multiple values\n",[82,2310,2311,2313,2315,2318,2321,2324,2326,2328,2331,2333,2336],{"class":84,"line":394},[82,2312,696],{"class":181},[82,2314,699],{"class":181},[82,2316,2317],{"class":702}," sum",[82,2319,2320],{"class":99},"(a, b, c) ",[82,2322,2323],{"class":181},"return",[82,2325,2077],{"class":99},[82,2327,1608],{"class":181},[82,2329,2330],{"class":99}," b ",[82,2332,1608],{"class":181},[82,2334,2335],{"class":99}," c ",[82,2337,800],{"class":181},[82,2339,2340,2342,2345,2347,2349,2351,2353,2355,2357,2359],{"class":84,"line":410},[82,2341,696],{"class":181},[82,2343,2344],{"class":99}," args ",[82,2346,717],{"class":181},[82,2348,1978],{"class":99},[82,2350,418],{"class":95},[82,2352,22],{"class":99},[82,2354,1985],{"class":95},[82,2356,22],{"class":99},[82,2358,475],{"class":95},[82,2360,1997],{"class":99},[82,2362,2363,2365,2367,2370,2372,2375,2378],{"class":84,"line":427},[82,2364,1164],{"class":95},[82,2366,100],{"class":99},[82,2368,2369],{"class":95},"sum",[82,2371,100],{"class":99},[82,2373,2374],{"class":95},"table.unpack",[82,2376,2377],{"class":99},"(args)))  ",[82,2379,2380],{"class":88},"-- 6\n",[531,2382,2384,2387],{"id":2383},"tablesort-custom-comparators",[19,2385,2386],{},"table.sort"," — Custom Comparators",[70,2389,2390,2614,2620],{"language":72},[74,2391,2393],{"className":76,"code":2392,"language":72,"meta":78,"style":78},"-- table.sort(t, comp?): in-place sort of array part (1..n)\n-- comp(a, b): must return true if a should come BEFORE b (strict less-than)\n-- CRITICAL: comp must be a STRICT weak ordering (not \u003C=, which causes undefined behavior)\n-- Sort is unstable (pre-5.4); 5.4+ is stable.\n\nlocal data = {{name=\"C\", age=30}, {name=\"A\", age=25}, {name=\"B\", age=25}}\n\n-- Single key sort:\ntable.sort(data, function(a, b) return a.age \u003C b.age end)\n-- {A(25), B(25), C(30)} or {B(25), A(25), C(30)} (unstable if pre-5.4)\n\n-- Multi-key: sort by age, then name (stable sort in reverse priority order)\ntable.sort(data, function(a, b) return a.name \u003C b.name end)  -- secondary: name\ntable.sort(data, function(a, b) return a.age \u003C b.age end)    -- primary: age (stable)\n-- Result: A(25), B(25), C(30) (age primary, name secondary — preserved by stability)\n\n-- ANTI-PATTERN: using \u003C= in comparator (undefined behavior)\n-- table.sort(t, function(a, b) return a \u003C= b end)  -- WRONG: must be strict \u003C\n-- This can cause: infinite loop, wrong order, or crash in some implementations\n",[19,2394,2395,2400,2405,2410,2415,2419,2474,2478,2483,2517,2522,2526,2531,2561,2590,2595,2599,2604,2609],{"__ignoreMap":78},[82,2396,2397],{"class":84,"line":85},[82,2398,2399],{"class":88},"-- table.sort(t, comp?): in-place sort of array part (1..n)\n",[82,2401,2402],{"class":84,"line":92},[82,2403,2404],{"class":88},"-- comp(a, b): must return true if a should come BEFORE b (strict less-than)\n",[82,2406,2407],{"class":84,"line":112},[82,2408,2409],{"class":88},"-- CRITICAL: comp must be a STRICT weak ordering (not \u003C=, which causes undefined behavior)\n",[82,2411,2412],{"class":84,"line":128},[82,2413,2414],{"class":88},"-- Sort is unstable (pre-5.4); 5.4+ is stable.\n",[82,2416,2417],{"class":84,"line":145},[82,2418,149],{"emptyLinePlaceholder":148},[82,2420,2421,2423,2425,2427,2430,2432,2435,2438,2440,2443,2446,2448,2451,2453,2455,2458,2460,2462,2465,2467,2469,2471],{"class":84,"line":152},[82,2422,696],{"class":181},[82,2424,761],{"class":99},[82,2426,717],{"class":181},[82,2428,2429],{"class":99}," {{name",[82,2431,717],{"class":181},[82,2433,2434],{"class":135},"\"C\"",[82,2436,2437],{"class":99},", age",[82,2439,717],{"class":181},[82,2441,2442],{"class":95},"30",[82,2444,2445],{"class":99},"}, {name",[82,2447,717],{"class":181},[82,2449,2450],{"class":135},"\"A\"",[82,2452,2437],{"class":99},[82,2454,717],{"class":181},[82,2456,2457],{"class":95},"25",[82,2459,2445],{"class":99},[82,2461,717],{"class":181},[82,2463,2464],{"class":135},"\"B\"",[82,2466,2437],{"class":99},[82,2468,717],{"class":181},[82,2470,2457],{"class":95},[82,2472,2473],{"class":99},"}}\n",[82,2475,2476],{"class":84,"line":158},[82,2477,149],{"emptyLinePlaceholder":148},[82,2479,2480],{"class":84,"line":167},[82,2481,2482],{"class":88},"-- Single key sort:\n",[82,2484,2485,2487,2490,2493,2496,2498,2501,2504,2507,2510,2512,2515],{"class":84,"line":176},[82,2486,2386],{"class":95},[82,2488,2489],{"class":99},"(data, ",[82,2491,2492],{"class":181},"function",[82,2494,2495],{"class":99},"(a, b) ",[82,2497,2323],{"class":181},[82,2499,2500],{"class":99}," a.",[82,2502,2503],{"class":702},"age",[82,2505,2506],{"class":181}," \u003C",[82,2508,2509],{"class":99}," b.",[82,2511,2503],{"class":702},[82,2513,2514],{"class":181}," end",[82,2516,677],{"class":99},[82,2518,2519],{"class":84,"line":191},[82,2520,2521],{"class":88},"-- {A(25), B(25), C(30)} or {B(25), A(25), C(30)} (unstable if pre-5.4)\n",[82,2523,2524],{"class":84,"line":208},[82,2525,149],{"emptyLinePlaceholder":148},[82,2527,2528],{"class":84,"line":223},[82,2529,2530],{"class":88},"-- Multi-key: sort by age, then name (stable sort in reverse priority order)\n",[82,2532,2533,2535,2537,2539,2541,2543,2545,2548,2550,2552,2554,2556,2558],{"class":84,"line":239},[82,2534,2386],{"class":95},[82,2536,2489],{"class":99},[82,2538,2492],{"class":181},[82,2540,2495],{"class":99},[82,2542,2323],{"class":181},[82,2544,2500],{"class":99},[82,2546,2547],{"class":702},"name",[82,2549,2506],{"class":181},[82,2551,2509],{"class":99},[82,2553,2547],{"class":702},[82,2555,2514],{"class":181},[82,2557,202],{"class":99},[82,2559,2560],{"class":88},"-- secondary: name\n",[82,2562,2563,2565,2567,2569,2571,2573,2575,2577,2579,2581,2583,2585,2587],{"class":84,"line":244},[82,2564,2386],{"class":95},[82,2566,2489],{"class":99},[82,2568,2492],{"class":181},[82,2570,2495],{"class":99},[82,2572,2323],{"class":181},[82,2574,2500],{"class":99},[82,2576,2503],{"class":702},[82,2578,2506],{"class":181},[82,2580,2509],{"class":99},[82,2582,2503],{"class":702},[82,2584,2514],{"class":181},[82,2586,457],{"class":99},[82,2588,2589],{"class":88},"-- primary: age (stable)\n",[82,2591,2592],{"class":84,"line":250},[82,2593,2594],{"class":88},"-- Result: A(25), B(25), C(30) (age primary, name secondary — preserved by stability)\n",[82,2596,2597],{"class":84,"line":266},[82,2598,149],{"emptyLinePlaceholder":148},[82,2600,2601],{"class":84,"line":283},[82,2602,2603],{"class":88},"-- ANTI-PATTERN: using \u003C= in comparator (undefined behavior)\n",[82,2605,2606],{"class":84,"line":300},[82,2607,2608],{"class":88},"-- table.sort(t, function(a, b) return a \u003C= b end)  -- WRONG: must be strict \u003C\n",[82,2610,2611],{"class":84,"line":316},[82,2612,2613],{"class":88},"-- This can cause: infinite loop, wrong order, or crash in some implementations\n",[63,2615,2617,2619],{"id":2616},"string-format-patterns",[19,2618,25],{}," — Format & Patterns",[70,2621,2622,2989,2995],{"language":72},[74,2623,2625],{"className":76,"code":2624,"language":72,"meta":78,"style":78},"-- string.format (C printf compatible):\n-- %s string, %d integer, %f float, %e scientific, %g compact, %x\u002F%X hex\n-- %o octal, %c char, %q Lua-quoted string\n-- %5d width 5 (right-pad), %-5d left-pad, %05d zero-pad\n-- %.2f 2 decimals, %10.2f width 10, 2 decimals\n\nstring.format(\"%d\", 42)          -- \"42\"\nstring.format(\"%05d\", 42)        -- \"00042\"\nstring.format(\"%.2f\", 3.14159)   -- \"3.14\"\nstring.format(\"%e\", 123456)      -- \"1.234560e+05\"\nstring.format(\"%g\", 0.0001)      -- \"0.0001\"\nstring.format(\"%g\", 100000)      -- \"100000\"\nstring.format(\"%x\", 255)         -- \"ff\"\nstring.format(\"%X\", 255)         -- \"FF\"\nstring.format(\"%o\", 8)           -- \"10\"\nstring.format(\"%c\", 65)          -- \"A\" (char from code)\nstring.format(\"%q\", 'he\"llo')    -- '\"he\\\\\"llo\"' (Lua-safe quoted)\n\n-- %q: the only format that handles ALL Lua string edge cases\n-- Escapes control chars, quotes, backslashes — output is valid Lua source\nlocal s = \"tab\\there\\nnewline\"\nlocal encoded = string.format(\"%q\", s)  -- '\"tab\\\\there\\\\nnewline\"'\n-- load(\"return \" .. encoded)() == s  -- true (round-trips perfectly)\n\n-- string.pack\u002Funpack (5.3+): binary packing\u002Funpacking (struct.pack equivalent)\nlocal packed = string.pack(\">I2\", 300)  -- big-endian 2-byte int: \"\\x01\\x2C\"\nlocal val = string.unpack(\">I2\", packed)  -- 300\n-- Format: > big-endian, \u003C little-endian, I2 2-byte int, s string, b byte, f float\n",[19,2626,2627,2632,2637,2642,2647,2652,2656,2675,2693,2712,2731,2750,2768,2787,2805,2824,2843,2862,2866,2871,2876,2900,2922,2927,2931,2936,2962,2984],{"__ignoreMap":78},[82,2628,2629],{"class":84,"line":85},[82,2630,2631],{"class":88},"-- string.format (C printf compatible):\n",[82,2633,2634],{"class":84,"line":92},[82,2635,2636],{"class":88},"-- %s string, %d integer, %f float, %e scientific, %g compact, %x\u002F%X hex\n",[82,2638,2639],{"class":84,"line":112},[82,2640,2641],{"class":88},"-- %o octal, %c char, %q Lua-quoted string\n",[82,2643,2644],{"class":84,"line":128},[82,2645,2646],{"class":88},"-- %5d width 5 (right-pad), %-5d left-pad, %05d zero-pad\n",[82,2648,2649],{"class":84,"line":145},[82,2650,2651],{"class":88},"-- %.2f 2 decimals, %10.2f width 10, 2 decimals\n",[82,2653,2654],{"class":84,"line":152},[82,2655,149],{"emptyLinePlaceholder":148},[82,2657,2658,2661,2663,2666,2668,2670,2672],{"class":84,"line":158},[82,2659,2660],{"class":95},"string.format",[82,2662,100],{"class":99},[82,2664,2665],{"class":135},"\"%d\"",[82,2667,22],{"class":99},[82,2669,103],{"class":95},[82,2671,421],{"class":99},[82,2673,2674],{"class":88},"-- \"42\"\n",[82,2676,2677,2679,2681,2684,2686,2688,2690],{"class":84,"line":167},[82,2678,2660],{"class":95},[82,2680,100],{"class":99},[82,2682,2683],{"class":135},"\"%05d\"",[82,2685,22],{"class":99},[82,2687,103],{"class":95},[82,2689,106],{"class":99},[82,2691,2692],{"class":88},"-- \"00042\"\n",[82,2694,2695,2697,2699,2702,2704,2707,2709],{"class":84,"line":176},[82,2696,2660],{"class":95},[82,2698,100],{"class":99},[82,2700,2701],{"class":135},"\"%.2f\"",[82,2703,22],{"class":99},[82,2705,2706],{"class":95},"3.14159",[82,2708,512],{"class":99},[82,2710,2711],{"class":88},"-- \"3.14\"\n",[82,2713,2714,2716,2718,2721,2723,2726,2728],{"class":84,"line":191},[82,2715,2660],{"class":95},[82,2717,100],{"class":99},[82,2719,2720],{"class":135},"\"%e\"",[82,2722,22],{"class":99},[82,2724,2725],{"class":95},"123456",[82,2727,122],{"class":99},[82,2729,2730],{"class":88},"-- \"1.234560e+05\"\n",[82,2732,2733,2735,2737,2740,2742,2745,2747],{"class":84,"line":208},[82,2734,2660],{"class":95},[82,2736,100],{"class":99},[82,2738,2739],{"class":135},"\"%g\"",[82,2741,22],{"class":99},[82,2743,2744],{"class":95},"0.0001",[82,2746,122],{"class":99},[82,2748,2749],{"class":88},"-- \"0.0001\"\n",[82,2751,2752,2754,2756,2758,2760,2763,2765],{"class":84,"line":223},[82,2753,2660],{"class":95},[82,2755,100],{"class":99},[82,2757,2739],{"class":135},[82,2759,22],{"class":99},[82,2761,2762],{"class":95},"100000",[82,2764,122],{"class":99},[82,2766,2767],{"class":88},"-- \"100000\"\n",[82,2769,2770,2772,2774,2777,2779,2782,2784],{"class":84,"line":239},[82,2771,2660],{"class":95},[82,2773,100],{"class":99},[82,2775,2776],{"class":135},"\"%x\"",[82,2778,22],{"class":99},[82,2780,2781],{"class":95},"255",[82,2783,388],{"class":99},[82,2785,2786],{"class":88},"-- \"ff\"\n",[82,2788,2789,2791,2793,2796,2798,2800,2802],{"class":84,"line":244},[82,2790,2660],{"class":95},[82,2792,100],{"class":99},[82,2794,2795],{"class":135},"\"%X\"",[82,2797,22],{"class":99},[82,2799,2781],{"class":95},[82,2801,388],{"class":99},[82,2803,2804],{"class":88},"-- \"FF\"\n",[82,2806,2807,2809,2811,2814,2816,2818,2821],{"class":84,"line":250},[82,2808,2660],{"class":95},[82,2810,100],{"class":99},[82,2812,2813],{"class":135},"\"%o\"",[82,2815,22],{"class":99},[82,2817,816],{"class":95},[82,2819,2820],{"class":99},")           ",[82,2822,2823],{"class":88},"-- \"10\"\n",[82,2825,2826,2828,2830,2833,2835,2838,2840],{"class":84,"line":266},[82,2827,2660],{"class":95},[82,2829,100],{"class":99},[82,2831,2832],{"class":135},"\"%c\"",[82,2834,22],{"class":99},[82,2836,2837],{"class":95},"65",[82,2839,421],{"class":99},[82,2841,2842],{"class":88},"-- \"A\" (char from code)\n",[82,2844,2845,2847,2849,2852,2854,2857,2859],{"class":84,"line":283},[82,2846,2660],{"class":95},[82,2848,100],{"class":99},[82,2850,2851],{"class":135},"\"%q\"",[82,2853,22],{"class":99},[82,2855,2856],{"class":135},"'he\"llo'",[82,2858,457],{"class":99},[82,2860,2861],{"class":88},"-- '\"he\\\\\"llo\"' (Lua-safe quoted)\n",[82,2863,2864],{"class":84,"line":300},[82,2865,149],{"emptyLinePlaceholder":148},[82,2867,2868],{"class":84,"line":316},[82,2869,2870],{"class":88},"-- %q: the only format that handles ALL Lua string edge cases\n",[82,2872,2873],{"class":84,"line":321},[82,2874,2875],{"class":88},"-- Escapes control chars, quotes, backslashes — output is valid Lua source\n",[82,2877,2878,2880,2883,2885,2888,2891,2894,2897],{"class":84,"line":327},[82,2879,696],{"class":181},[82,2881,2882],{"class":99}," s ",[82,2884,717],{"class":181},[82,2886,2887],{"class":135}," \"tab",[82,2889,2890],{"class":95},"\\t",[82,2892,2893],{"class":135},"here",[82,2895,2896],{"class":95},"\\n",[82,2898,2899],{"class":135},"newline\"\n",[82,2901,2902,2904,2907,2909,2912,2914,2916,2919],{"class":84,"line":346},[82,2903,696],{"class":181},[82,2905,2906],{"class":99}," encoded ",[82,2908,717],{"class":181},[82,2910,2911],{"class":95}," string.format",[82,2913,100],{"class":99},[82,2915,2851],{"class":135},[82,2917,2918],{"class":99},", s)  ",[82,2920,2921],{"class":88},"-- '\"tab\\\\there\\\\nnewline\"'\n",[82,2923,2924],{"class":84,"line":351},[82,2925,2926],{"class":88},"-- load(\"return \" .. encoded)() == s  -- true (round-trips perfectly)\n",[82,2928,2929],{"class":84,"line":357},[82,2930,149],{"emptyLinePlaceholder":148},[82,2932,2933],{"class":84,"line":366},[82,2934,2935],{"class":88},"-- string.pack\u002Funpack (5.3+): binary packing\u002Funpacking (struct.pack equivalent)\n",[82,2937,2938,2940,2942,2944,2947,2949,2952,2954,2957,2959],{"class":84,"line":375},[82,2939,696],{"class":181},[82,2941,2249],{"class":99},[82,2943,717],{"class":181},[82,2945,2946],{"class":95}," string.pack",[82,2948,100],{"class":99},[82,2950,2951],{"class":135},"\">I2\"",[82,2953,22],{"class":99},[82,2955,2956],{"class":95},"300",[82,2958,202],{"class":99},[82,2960,2961],{"class":88},"-- big-endian 2-byte int: \"\\x01\\x2C\"\n",[82,2963,2964,2966,2969,2971,2974,2976,2978,2981],{"class":84,"line":394},[82,2965,696],{"class":181},[82,2967,2968],{"class":99}," val ",[82,2970,717],{"class":181},[82,2972,2973],{"class":95}," string.unpack",[82,2975,100],{"class":99},[82,2977,2951],{"class":135},[82,2979,2980],{"class":99},", packed)  ",[82,2982,2983],{"class":88},"-- 300\n",[82,2985,2986],{"class":84,"line":410},[82,2987,2988],{"class":88},"-- Format: > big-endian, \u003C little-endian, I2 2-byte int, s string, b byte, f float\n",[63,2990,2992,2994],{"id":2991},"debug-introspection-profiling",[19,2993,37],{}," — Introspection & Profiling",[70,2996,2997,3537,3543],{"language":72},[74,2998,3000],{"className":76,"code":2999,"language":72,"meta":78,"style":78},"-- debug.getinfo(level, what): get info about a stack frame\nlocal info = debug.getinfo(1, \"Slnu\")\n-- info.source    — \"@script.lua\" (or \"stdin\", or \"=[C]\" for C functions)\n-- info.short_src — \"script.lua\" (abbreviated)\n-- info.currentline — current line in that frame\n-- info.linedefined — first line of the function\n-- info.lastlinedefined — last line\n-- info.what      — \"Lua\", \"C\", \"main\"\n-- info.name      — function name (may be nil for anonymous)\n-- info.namewhat  — \"global\", \"local\", \"method\", \"field\", \"upvalue\", \"\"\n-- info.nups      — number of upvalues\n-- info.isvararg  — true if function is vararg (with \"u\" flag)\n\n-- debug.getlocal(level, index): get local variable by index in a frame\nlocal function dump_frame(level)\n  level = level or 1\n  local i = 1\n  while true do\n    local name, value = debug.getlocal(level, i)\n    if not name then break end\n    print(string.format(\"  [%d] %s = %s\", i, name, tostring(value)))\n    i = i + 1\n  end\nend\n\n-- debug.setlocal(level, index, value): SET a local variable (powerful debugging)\n-- debug.getupvalue(fn, index) \u002F debug.setupvalue(fn, index, value): upvalue access\n\n-- debug.traceback(msg, level): stack trace string\nprint(debug.traceback(\"here\", 2))  -- skip this function and the caller\n\n-- debug.sethook(callback, events, count?): execution hooks\n-- Events: \"c\" call, \"r\" return, \"l\" line, \"c\" + count = every N instructions\nlocal function profile(fn)\n  local counts = {}\n  debug.sethook(function(event, line)\n    local info = debug.getinfo(2, \"Sl\")\n    local key = info.source .. \":\" .. line\n    counts[key] = (counts[key] or 0) + 1\n  end, \"l\")\n  fn()\n  debug.sethook()  -- remove hook\n  return counts\nend\n\n-- Production: simple line profiler\nlocal function simple_profiler(fn)\n  local start = os.clock()\n  local ok, result = pcall(fn)\n  local elapsed = os.clock() - start\n  if not ok then error(result, 2) end\n  return result, elapsed  -- return result + CPU time\nend\n",[19,3001,3002,3007,3030,3035,3040,3045,3050,3055,3060,3065,3070,3075,3080,3084,3089,3101,3117,3127,3138,3154,3171,3194,3207,3211,3215,3219,3224,3229,3233,3238,3261,3265,3270,3275,3287,3300,3313,3335,3363,3384,3397,3405,3415,3423,3428,3433,3439,3451,3464,3479,3497,3521,3532],{"__ignoreMap":78},[82,3003,3004],{"class":84,"line":85},[82,3005,3006],{"class":88},"-- debug.getinfo(level, what): get info about a stack frame\n",[82,3008,3009,3011,3014,3016,3019,3021,3023,3025,3028],{"class":84,"line":92},[82,3010,696],{"class":181},[82,3012,3013],{"class":99}," info ",[82,3015,717],{"class":181},[82,3017,3018],{"class":95}," debug.getinfo",[82,3020,100],{"class":99},[82,3022,418],{"class":95},[82,3024,22],{"class":99},[82,3026,3027],{"class":135},"\"Slnu\"",[82,3029,677],{"class":99},[82,3031,3032],{"class":84,"line":112},[82,3033,3034],{"class":88},"-- info.source    — \"@script.lua\" (or \"stdin\", or \"=[C]\" for C functions)\n",[82,3036,3037],{"class":84,"line":128},[82,3038,3039],{"class":88},"-- info.short_src — \"script.lua\" (abbreviated)\n",[82,3041,3042],{"class":84,"line":145},[82,3043,3044],{"class":88},"-- info.currentline — current line in that frame\n",[82,3046,3047],{"class":84,"line":152},[82,3048,3049],{"class":88},"-- info.linedefined — first line of the function\n",[82,3051,3052],{"class":84,"line":158},[82,3053,3054],{"class":88},"-- info.lastlinedefined — last line\n",[82,3056,3057],{"class":84,"line":167},[82,3058,3059],{"class":88},"-- info.what      — \"Lua\", \"C\", \"main\"\n",[82,3061,3062],{"class":84,"line":176},[82,3063,3064],{"class":88},"-- info.name      — function name (may be nil for anonymous)\n",[82,3066,3067],{"class":84,"line":191},[82,3068,3069],{"class":88},"-- info.namewhat  — \"global\", \"local\", \"method\", \"field\", \"upvalue\", \"\"\n",[82,3071,3072],{"class":84,"line":208},[82,3073,3074],{"class":88},"-- info.nups      — number of upvalues\n",[82,3076,3077],{"class":84,"line":223},[82,3078,3079],{"class":88},"-- info.isvararg  — true if function is vararg (with \"u\" flag)\n",[82,3081,3082],{"class":84,"line":239},[82,3083,149],{"emptyLinePlaceholder":148},[82,3085,3086],{"class":84,"line":244},[82,3087,3088],{"class":88},"-- debug.getlocal(level, index): get local variable by index in a frame\n",[82,3090,3091,3093,3095,3098],{"class":84,"line":250},[82,3092,696],{"class":181},[82,3094,699],{"class":181},[82,3096,3097],{"class":702}," dump_frame",[82,3099,3100],{"class":99},"(level)\n",[82,3102,3103,3106,3108,3111,3114],{"class":84,"line":266},[82,3104,3105],{"class":99},"  level ",[82,3107,717],{"class":181},[82,3109,3110],{"class":99}," level ",[82,3112,3113],{"class":181},"or",[82,3115,3116],{"class":95}," 1\n",[82,3118,3119,3121,3123,3125],{"class":84,"line":283},[82,3120,711],{"class":181},[82,3122,851],{"class":99},[82,3124,717],{"class":181},[82,3126,3116],{"class":95},[82,3128,3129,3132,3135],{"class":84,"line":300},[82,3130,3131],{"class":181},"  while",[82,3133,3134],{"class":95}," true",[82,3136,3137],{"class":181}," do\n",[82,3139,3140,3143,3146,3148,3151],{"class":84,"line":316},[82,3141,3142],{"class":181},"    local",[82,3144,3145],{"class":99}," name, value ",[82,3147,717],{"class":181},[82,3149,3150],{"class":95}," debug.getlocal",[82,3152,3153],{"class":99},"(level, i)\n",[82,3155,3156,3159,3161,3164,3166,3169],{"class":84,"line":321},[82,3157,3158],{"class":181},"    if",[82,3160,740],{"class":181},[82,3162,3163],{"class":99}," name ",[82,3165,745],{"class":181},[82,3167,3168],{"class":181}," break",[82,3170,754],{"class":181},[82,3172,3173,3176,3178,3180,3182,3185,3188,3191],{"class":84,"line":327},[82,3174,3175],{"class":95},"    print",[82,3177,100],{"class":99},[82,3179,2660],{"class":95},[82,3181,100],{"class":99},[82,3183,3184],{"class":135},"\"  [%d] %s = %s\"",[82,3186,3187],{"class":99},", i, name, ",[82,3189,3190],{"class":95},"tostring",[82,3192,3193],{"class":99},"(value)))\n",[82,3195,3196,3199,3201,3203,3205],{"class":84,"line":346},[82,3197,3198],{"class":99},"    i ",[82,3200,717],{"class":181},[82,3202,851],{"class":99},[82,3204,1608],{"class":181},[82,3206,3116],{"class":95},[82,3208,3209],{"class":84,"line":351},[82,3210,898],{"class":181},[82,3212,3213],{"class":84,"line":357},[82,3214,800],{"class":181},[82,3216,3217],{"class":84,"line":366},[82,3218,149],{"emptyLinePlaceholder":148},[82,3220,3221],{"class":84,"line":375},[82,3222,3223],{"class":88},"-- debug.setlocal(level, index, value): SET a local variable (powerful debugging)\n",[82,3225,3226],{"class":84,"line":394},[82,3227,3228],{"class":88},"-- debug.getupvalue(fn, index) \u002F debug.setupvalue(fn, index, value): upvalue access\n",[82,3230,3231],{"class":84,"line":410},[82,3232,149],{"emptyLinePlaceholder":148},[82,3234,3235],{"class":84,"line":427},[82,3236,3237],{"class":88},"-- debug.traceback(msg, level): stack trace string\n",[82,3239,3240,3242,3244,3247,3249,3252,3254,3256,3258],{"class":84,"line":443},[82,3241,1164],{"class":95},[82,3243,100],{"class":99},[82,3245,3246],{"class":95},"debug.traceback",[82,3248,100],{"class":99},[82,3250,3251],{"class":135},"\"here\"",[82,3253,22],{"class":99},[82,3255,1985],{"class":95},[82,3257,1477],{"class":99},[82,3259,3260],{"class":88},"-- skip this function and the caller\n",[82,3262,3263],{"class":84,"line":463},[82,3264,149],{"emptyLinePlaceholder":148},[82,3266,3267],{"class":84,"line":483},[82,3268,3269],{"class":88},"-- debug.sethook(callback, events, count?): execution hooks\n",[82,3271,3272],{"class":84,"line":497},[82,3273,3274],{"class":88},"-- Events: \"c\" call, \"r\" return, \"l\" line, \"c\" + count = every N instructions\n",[82,3276,3277,3279,3281,3284],{"class":84,"line":518},[82,3278,696],{"class":181},[82,3280,699],{"class":181},[82,3282,3283],{"class":702}," profile",[82,3285,3286],{"class":99},"(fn)\n",[82,3288,3290,3292,3295,3297],{"class":84,"line":3289},35,[82,3291,711],{"class":181},[82,3293,3294],{"class":99}," counts ",[82,3296,717],{"class":181},[82,3298,3299],{"class":99}," {}\n",[82,3301,3303,3306,3308,3310],{"class":84,"line":3302},36,[82,3304,3305],{"class":95},"  debug.sethook",[82,3307,100],{"class":99},[82,3309,2492],{"class":181},[82,3311,3312],{"class":99},"(event, line)\n",[82,3314,3316,3318,3320,3322,3324,3326,3328,3330,3333],{"class":84,"line":3315},37,[82,3317,3142],{"class":181},[82,3319,3013],{"class":99},[82,3321,717],{"class":181},[82,3323,3018],{"class":95},[82,3325,100],{"class":99},[82,3327,1985],{"class":95},[82,3329,22],{"class":99},[82,3331,3332],{"class":135},"\"Sl\"",[82,3334,677],{"class":99},[82,3336,3338,3340,3343,3345,3348,3351,3354,3357,3360],{"class":84,"line":3337},38,[82,3339,3142],{"class":181},[82,3341,3342],{"class":99}," key ",[82,3344,717],{"class":181},[82,3346,3347],{"class":99}," info.",[82,3349,3350],{"class":702},"source",[82,3352,3353],{"class":181}," ..",[82,3355,3356],{"class":135}," \":\" ",[82,3358,3359],{"class":181},"..",[82,3361,3362],{"class":99}," line\n",[82,3364,3366,3369,3371,3374,3376,3378,3380,3382],{"class":84,"line":3365},39,[82,3367,3368],{"class":99},"    counts[key] ",[82,3370,717],{"class":181},[82,3372,3373],{"class":99}," (counts[key] ",[82,3375,3113],{"class":181},[82,3377,1069],{"class":95},[82,3379,233],{"class":99},[82,3381,1608],{"class":181},[82,3383,3116],{"class":95},[82,3385,3387,3390,3392,3395],{"class":84,"line":3386},40,[82,3388,3389],{"class":181},"  end",[82,3391,22],{"class":99},[82,3393,3394],{"class":135},"\"l\"",[82,3396,677],{"class":99},[82,3398,3400,3403],{"class":84,"line":3399},41,[82,3401,3402],{"class":95},"  fn",[82,3404,787],{"class":99},[82,3406,3408,3410,3412],{"class":84,"line":3407},42,[82,3409,3305],{"class":95},[82,3411,1215],{"class":99},[82,3413,3414],{"class":88},"-- remove hook\n",[82,3416,3418,3420],{"class":84,"line":3417},43,[82,3419,792],{"class":181},[82,3421,3422],{"class":99}," counts\n",[82,3424,3426],{"class":84,"line":3425},44,[82,3427,800],{"class":181},[82,3429,3431],{"class":84,"line":3430},45,[82,3432,149],{"emptyLinePlaceholder":148},[82,3434,3436],{"class":84,"line":3435},46,[82,3437,3438],{"class":88},"-- Production: simple line profiler\n",[82,3440,3442,3444,3446,3449],{"class":84,"line":3441},47,[82,3443,696],{"class":181},[82,3445,699],{"class":181},[82,3447,3448],{"class":702}," simple_profiler",[82,3450,3286],{"class":99},[82,3452,3454,3456,3458,3460,3462],{"class":84,"line":3453},48,[82,3455,711],{"class":181},[82,3457,1390],{"class":99},[82,3459,717],{"class":181},[82,3461,1395],{"class":95},[82,3463,787],{"class":99},[82,3465,3467,3469,3472,3474,3477],{"class":84,"line":3466},49,[82,3468,711],{"class":181},[82,3470,3471],{"class":99}," ok, result ",[82,3473,717],{"class":181},[82,3475,3476],{"class":95}," pcall",[82,3478,3286],{"class":99},[82,3480,3482,3484,3486,3488,3490,3492,3494],{"class":84,"line":3481},50,[82,3483,711],{"class":181},[82,3485,1409],{"class":99},[82,3487,717],{"class":181},[82,3489,1395],{"class":95},[82,3491,668],{"class":99},[82,3493,290],{"class":181},[82,3495,3496],{"class":99}," start\n",[82,3498,3500,3502,3504,3507,3509,3512,3515,3517,3519],{"class":84,"line":3499},51,[82,3501,737],{"class":181},[82,3503,740],{"class":181},[82,3505,3506],{"class":99}," ok ",[82,3508,745],{"class":181},[82,3510,3511],{"class":95}," error",[82,3513,3514],{"class":99},"(result, ",[82,3516,1985],{"class":95},[82,3518,233],{"class":99},[82,3520,800],{"class":181},[82,3522,3524,3526,3529],{"class":84,"line":3523},52,[82,3525,792],{"class":181},[82,3527,3528],{"class":99}," result, elapsed  ",[82,3530,3531],{"class":88},"-- return result + CPU time\n",[82,3533,3535],{"class":84,"line":3534},53,[82,3536,800],{"class":181},[63,3538,3540,3542],{"id":3539},"package-module-system-internals",[19,3541,46],{}," — Module System Internals",[70,3544,3545,3841,3845,3865],{"language":72},[74,3546,3548],{"className":76,"code":3547,"language":72,"meta":78,"style":78},"-- package.loaded: cache of loaded modules (table name → module value)\nprint(package.loaded.string)  -- the string library table\npackage.loaded[\"my_module\"] = nil  -- evict (force reload on next require)\n\n-- package.preload: programmatic module registration (checked before filesystem)\npackage.preload[\"injected\"] = function()\n  return {hello = function() return \"injected\" end}\nend\nrequire(\"injected\").hello()  -- \"injected\" (no file needed)\n\n-- package.searchers (5.2+): ordered list of loader functions\n-- Each: function(name) → loader_fn | error_string | nil\n-- Default: [preload, path searcher, cpath searcher, all-in-one]\n\n-- Add a custom searcher (insert at position 1 to check first):\ntable.insert(package.searchers, 1, function(name)\n  local source = my_embedded_modules[name]  -- your custom source map\n  if not source then return nil end  -- not found, try next searcher\n  local fn, err = load(source, name, \"t\")\n  if not fn then return err end\n  return fn\nend)\n\n-- package.searchpath(name, path, sep, rep): find a file on a path\nlocal found = package.searchpath(\"mymod.utils\", package.path)\n-- Returns \"\u002Fpath\u002Fto\u002Fmymod\u002Futils.lua\" or nil + \"tried paths\" error\n",[19,3549,3550,3555,3574,3594,3598,3603,3621,3647,3651,3670,3674,3679,3684,3689,3693,3698,3718,3733,3752,3772,3790,3797,3803,3807,3812,3836],{"__ignoreMap":78},[82,3551,3552],{"class":84,"line":85},[82,3553,3554],{"class":88},"-- package.loaded: cache of loaded modules (table name → module value)\n",[82,3556,3557,3559,3561,3564,3567,3569,3571],{"class":84,"line":92},[82,3558,1164],{"class":95},[82,3560,100],{"class":99},[82,3562,3563],{"class":95},"package.loaded",[82,3565,3566],{"class":99},".",[82,3568,25],{"class":702},[82,3570,202],{"class":99},[82,3572,3573],{"class":88},"-- the string library table\n",[82,3575,3576,3578,3581,3584,3587,3589,3591],{"class":84,"line":112},[82,3577,3563],{"class":95},[82,3579,3580],{"class":99},"[",[82,3582,3583],{"class":135},"\"my_module\"",[82,3585,3586],{"class":99},"] ",[82,3588,717],{"class":181},[82,3590,751],{"class":95},[82,3592,3593],{"class":88},"  -- evict (force reload on next require)\n",[82,3595,3596],{"class":84,"line":128},[82,3597,149],{"emptyLinePlaceholder":148},[82,3599,3600],{"class":84,"line":145},[82,3601,3602],{"class":88},"-- package.preload: programmatic module registration (checked before filesystem)\n",[82,3604,3605,3608,3610,3613,3615,3617,3619],{"class":84,"line":152},[82,3606,3607],{"class":95},"package.preload",[82,3609,3580],{"class":99},[82,3611,3612],{"class":135},"\"injected\"",[82,3614,3586],{"class":99},[82,3616,717],{"class":181},[82,3618,699],{"class":181},[82,3620,787],{"class":99},[82,3622,3623,3625,3627,3630,3633,3635,3637,3639,3642,3645],{"class":84,"line":158},[82,3624,792],{"class":181},[82,3626,1978],{"class":99},[82,3628,3629],{"class":702},"hello",[82,3631,3632],{"class":181}," =",[82,3634,699],{"class":181},[82,3636,668],{"class":99},[82,3638,2323],{"class":181},[82,3640,3641],{"class":135}," \"injected\" ",[82,3643,3644],{"class":181},"end",[82,3646,1997],{"class":99},[82,3648,3649],{"class":84,"line":167},[82,3650,800],{"class":181},[82,3652,3653,3656,3658,3660,3663,3665,3667],{"class":84,"line":176},[82,3654,3655],{"class":95},"require",[82,3657,100],{"class":99},[82,3659,3612],{"class":135},[82,3661,3662],{"class":99},").",[82,3664,3629],{"class":95},[82,3666,1215],{"class":99},[82,3668,3669],{"class":88},"-- \"injected\" (no file needed)\n",[82,3671,3672],{"class":84,"line":191},[82,3673,149],{"emptyLinePlaceholder":148},[82,3675,3676],{"class":84,"line":208},[82,3677,3678],{"class":88},"-- package.searchers (5.2+): ordered list of loader functions\n",[82,3680,3681],{"class":84,"line":223},[82,3682,3683],{"class":88},"-- Each: function(name) → loader_fn | error_string | nil\n",[82,3685,3686],{"class":84,"line":239},[82,3687,3688],{"class":88},"-- Default: [preload, path searcher, cpath searcher, all-in-one]\n",[82,3690,3691],{"class":84,"line":244},[82,3692,149],{"emptyLinePlaceholder":148},[82,3694,3695],{"class":84,"line":250},[82,3696,3697],{"class":88},"-- Add a custom searcher (insert at position 1 to check first):\n",[82,3699,3700,3702,3704,3707,3709,3711,3713,3715],{"class":84,"line":266},[82,3701,2002],{"class":95},[82,3703,100],{"class":99},[82,3705,3706],{"class":95},"package.searchers",[82,3708,22],{"class":99},[82,3710,418],{"class":95},[82,3712,22],{"class":99},[82,3714,2492],{"class":181},[82,3716,3717],{"class":99},"(name)\n",[82,3719,3720,3722,3725,3727,3730],{"class":84,"line":283},[82,3721,711],{"class":181},[82,3723,3724],{"class":99}," source ",[82,3726,717],{"class":181},[82,3728,3729],{"class":99}," my_embedded_modules[name]  ",[82,3731,3732],{"class":88},"-- your custom source map\n",[82,3734,3735,3737,3739,3741,3743,3745,3747,3749],{"class":84,"line":300},[82,3736,737],{"class":181},[82,3738,740],{"class":181},[82,3740,3724],{"class":99},[82,3742,745],{"class":181},[82,3744,748],{"class":181},[82,3746,751],{"class":95},[82,3748,2514],{"class":181},[82,3750,3751],{"class":88},"  -- not found, try next searcher\n",[82,3753,3754,3756,3759,3761,3764,3767,3770],{"class":84,"line":316},[82,3755,711],{"class":181},[82,3757,3758],{"class":99}," fn, err ",[82,3760,717],{"class":181},[82,3762,3763],{"class":95}," load",[82,3765,3766],{"class":99},"(source, name, ",[82,3768,3769],{"class":135},"\"t\"",[82,3771,677],{"class":99},[82,3773,3774,3776,3778,3781,3783,3785,3788],{"class":84,"line":321},[82,3775,737],{"class":181},[82,3777,740],{"class":181},[82,3779,3780],{"class":99}," fn ",[82,3782,745],{"class":181},[82,3784,748],{"class":181},[82,3786,3787],{"class":99}," err ",[82,3789,800],{"class":181},[82,3791,3792,3794],{"class":84,"line":327},[82,3793,792],{"class":181},[82,3795,3796],{"class":99}," fn\n",[82,3798,3799,3801],{"class":84,"line":346},[82,3800,3644],{"class":181},[82,3802,677],{"class":99},[82,3804,3805],{"class":84,"line":351},[82,3806,149],{"emptyLinePlaceholder":148},[82,3808,3809],{"class":84,"line":357},[82,3810,3811],{"class":88},"-- package.searchpath(name, path, sep, rep): find a file on a path\n",[82,3813,3814,3816,3819,3821,3824,3826,3829,3831,3834],{"class":84,"line":366},[82,3815,696],{"class":181},[82,3817,3818],{"class":99}," found ",[82,3820,717],{"class":181},[82,3822,3823],{"class":95}," package.searchpath",[82,3825,100],{"class":99},[82,3827,3828],{"class":135},"\"mymod.utils\"",[82,3830,22],{"class":99},[82,3832,3833],{"class":95},"package.path",[82,3835,677],{"class":99},[82,3837,3838],{"class":84,"line":375},[82,3839,3840],{"class":88},"-- Returns \"\u002Fpath\u002Fto\u002Fmymod\u002Futils.lua\" or nil + \"tried paths\" error\n",[63,3842,3844],{"id":3843},"tips-tricks","💡 Tips & Tricks",[15,3846,3847,3858,3859,3861,3862,3864],{},[3848,3849,3850,3853,3854,3857],"strong",{},[19,3851,3852],{},"os.clock()"," for CPU benchmarking, ",[19,3855,3856],{},"os.time()"," for wall clock",": ",[19,3860,3852],{}," measures process CPU time (more precise for benchmarks); ",[19,3863,3856],{}," measures wall clock (affected by other processes).",[70,3866,3867],{"language":72},[74,3868,3870],{"className":76,"code":3869,"language":72,"meta":78,"style":78},"local start = os.clock()\nfor i = 1, 1000000 do end  -- CPU-bound\nprint(string.format(\"%.4fs CPU\", os.clock() - start))\n",[19,3871,3872,3884,3908],{"__ignoreMap":78},[82,3873,3874,3876,3878,3880,3882],{"class":84,"line":85},[82,3875,696],{"class":181},[82,3877,1390],{"class":99},[82,3879,717],{"class":181},[82,3881,1395],{"class":95},[82,3883,787],{"class":99},[82,3885,3886,3889,3891,3893,3895,3897,3900,3903,3905],{"class":84,"line":92},[82,3887,3888],{"class":181},"for",[82,3890,851],{"class":99},[82,3892,717],{"class":181},[82,3894,185],{"class":95},[82,3896,22],{"class":99},[82,3898,3899],{"class":95},"1000000",[82,3901,3902],{"class":181}," do",[82,3904,2514],{"class":181},[82,3906,3907],{"class":88},"  -- CPU-bound\n",[82,3909,3910,3912,3914,3916,3918,3921,3923,3925,3927,3929],{"class":84,"line":112},[82,3911,1164],{"class":95},[82,3913,100],{"class":99},[82,3915,2660],{"class":95},[82,3917,100],{"class":99},[82,3919,3920],{"class":135},"\"%.4fs CPU\"",[82,3922,22],{"class":99},[82,3924,665],{"class":95},[82,3926,668],{"class":99},[82,3928,290],{"class":181},[82,3930,3931],{"class":99}," start))\n",[15,3933,3934,3940],{},[3848,3935,3936,3939],{},[19,3937,3938],{},"math.randomseed(os.time())"," once at startup",": Forgetting to seed gives the same sequence every run — a common bug.",[15,3942,3943,3949],{},[3848,3944,3945,3948],{},[19,3946,3947],{},"string.format(\"%q\", x)"," for safe serialization",": The only format that handles all Lua string edge cases (embedded nulls, control chars, quotes).",[15,3951,3952,3958],{},[3848,3953,3954,3957],{},[19,3955,3956],{},"debug.sethook"," for coverage testing",": Hook on \"l\" (line) events to record which lines were executed.",[63,3960,3962],{"id":3961},"️-edge-cases-gotchas","⚠️ Edge Cases & Gotchas",[15,3964,3965,3858,3972,3975],{},[3848,3966,3967,1156,3969,3971],{},[19,3968,253],{},[19,3970,269],{}," on very large floats lose precision",[19,3973,3974],{},"math.floor(1e20)"," may not give the expected integer due to float representation.",[15,3977,3978,3983,3984,3986,3987,1761,3990,3662],{},[3848,3979,3980,3982],{},[19,3981,3856],{}," returns seconds, not milliseconds",": For sub-second timing, use ",[19,3985,3852],{}," (CPU time) or a high-resolution timer from ",[19,3988,3989],{},"luasocket",[19,3991,3992],{},"socket.gettime()",[15,3994,3995,4003,4004,4007],{},[3848,3996,3997,3999,4000],{},[19,3998,2386],{}," comparator must be strict ",[19,4001,4002],{},"\u003C",": Using ",[19,4005,4006],{},"\u003C="," causes undefined behavior (potential infinite loop or crash).",[70,4009,4010],{"language":72},[74,4011,4013],{"className":76,"code":4012,"language":72,"meta":78,"style":78},"-- BAD: \u003C= in comparator\ntable.sort(t, function(a, b) return a \u003C= b end)  -- UNDEFINED BEHAVIOR\n-- If a == b, comp returns true for BOTH (a,b) and (b,a) — violates strict ordering\n\n-- GOOD: strict \u003C\ntable.sort(t, function(a, b) return a \u003C b end)\n",[19,4014,4015,4020,4045,4050,4054,4059],{"__ignoreMap":78},[82,4016,4017],{"class":84,"line":85},[82,4018,4019],{"class":88},"-- BAD: \u003C= in comparator\n",[82,4021,4022,4024,4026,4028,4030,4032,4034,4036,4038,4040,4042],{"class":84,"line":92},[82,4023,2386],{"class":95},[82,4025,2005],{"class":99},[82,4027,2492],{"class":181},[82,4029,2495],{"class":99},[82,4031,2323],{"class":181},[82,4033,2077],{"class":99},[82,4035,4006],{"class":181},[82,4037,2330],{"class":99},[82,4039,3644],{"class":181},[82,4041,202],{"class":99},[82,4043,4044],{"class":88},"-- UNDEFINED BEHAVIOR\n",[82,4046,4047],{"class":84,"line":112},[82,4048,4049],{"class":88},"-- If a == b, comp returns true for BOTH (a,b) and (b,a) — violates strict ordering\n",[82,4051,4052],{"class":84,"line":128},[82,4053,149],{"emptyLinePlaceholder":148},[82,4055,4056],{"class":84,"line":145},[82,4057,4058],{"class":88},"-- GOOD: strict \u003C\n",[82,4060,4061,4063,4065,4067,4069,4071,4073,4075,4077,4079],{"class":84,"line":152},[82,4062,2386],{"class":95},[82,4064,2005],{"class":99},[82,4066,2492],{"class":181},[82,4068,2495],{"class":99},[82,4070,2323],{"class":181},[82,4072,2077],{"class":99},[82,4074,4002],{"class":181},[82,4076,2330],{"class":99},[82,4078,3644],{"class":181},[82,4080,677],{"class":99},[15,4082,4083,4092,4093,4095],{},[3848,4084,4085,4087,4088,4091],{},[19,4086,2660],{}," ",[19,4089,4090],{},"%s"," with nil errors",": Unlike ",[19,4094,1164],{},", format doesn't auto-tostring nil.",[63,4097,4099],{"id":4098},"spot-the-bug","🧠 Spot the Bug",[70,4101,4102,4187],{"language":72},[74,4103,4105],{"className":76,"code":4104,"language":72,"meta":78,"style":78},"math.randomseed(42)\nlocal a = math.random(1, 100)\nmath.randomseed(42)\nlocal b = math.random(1, 100)\nprint(a, b)\nprint(a == b)\n",[19,4106,4107,4117,4138,4148,4168,4175],{"__ignoreMap":78},[82,4108,4109,4111,4113,4115],{"class":84,"line":85},[82,4110,638],{"class":95},[82,4112,100],{"class":99},[82,4114,103],{"class":95},[82,4116,677],{"class":99},[82,4118,4119,4121,4123,4125,4128,4130,4132,4134,4136],{"class":84,"line":92},[82,4120,696],{"class":181},[82,4122,2077],{"class":99},[82,4124,717],{"class":181},[82,4126,4127],{"class":95}," math.random",[82,4129,100],{"class":99},[82,4131,418],{"class":95},[82,4133,22],{"class":99},[82,4135,450],{"class":95},[82,4137,677],{"class":99},[82,4139,4140,4142,4144,4146],{"class":84,"line":112},[82,4141,638],{"class":95},[82,4143,100],{"class":99},[82,4145,103],{"class":95},[82,4147,677],{"class":99},[82,4149,4150,4152,4154,4156,4158,4160,4162,4164,4166],{"class":84,"line":128},[82,4151,696],{"class":181},[82,4153,2330],{"class":99},[82,4155,717],{"class":181},[82,4157,4127],{"class":95},[82,4159,100],{"class":99},[82,4161,418],{"class":95},[82,4163,22],{"class":99},[82,4165,450],{"class":95},[82,4167,677],{"class":99},[82,4169,4170,4172],{"class":84,"line":145},[82,4171,1164],{"class":95},[82,4173,4174],{"class":99},"(a, b)\n",[82,4176,4177,4179,4182,4184],{"class":84,"line":152},[82,4178,1164],{"class":95},[82,4180,4181],{"class":99},"(a ",[82,4183,1170],{"class":181},[82,4185,4186],{"class":99}," b)\n",[4188,4189,4190,4194,4204,4213],"details",{},[4191,4192,4193],"summary",{},"Answer",[15,4195,4196,4197,4200,4201,3566],{},"Prints the same number twice, and ",[19,4198,4199],{},"true"," for ",[19,4202,4203],{},"a == b",[15,4205,4206,4209,4210,4212],{},[19,4207,4208],{},"math.randomseed(42)"," resets the PRNG to the same state. Two calls with the same seed produce the same sequence. This is why you seed ONCE at startup (with ",[19,4211,3856],{}," or entropy), not before every random call.",[15,4214,4215],{},"The bug in production: seeding before each call makes your \"random\" numbers fully predictable and repeating. Fix: seed once at program start, never again.",[4217,4218,4219],"style",{},"html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}",{"title":78,"searchDepth":92,"depth":92,"links":4221},[4222,4227,4228],{"id":65,"depth":92,"text":4223,"children":4224},"math — Numbers & Randomness",[4225],{"id":533,"depth":112,"text":4226},"math.random & Seeding",{"id":3961,"depth":92,"text":3962},{"id":4098,"depth":92,"text":4099},"[object Object]","md",{},"\u002Flua\u002F12-standard-library",{"title":5,"description":4234},{"Deep-dive into Lua's standard library":4235},"math (random\u002Fprecision\u002Finteger ops), os (time\u002Fdate\u002Fenvironment), table (sort\u002Fmove\u002Funpack internals), string (format\u002Fpatterns), debug (introspection\u002Fhooks), and package (searchers\u002Fpreload). Production patterns for random seeding, date math, and profiler construction.","lua\u002F12-standard-library","6pgWlhEbGgd9xiD8F4MI0MTRynYUouXG7kxOV46ghxE",1789924650596]