[{"data":1,"prerenderedAt":1790},["ShallowReactive",2],{"docs-navigation:en":3,"content-page:docs:qXACug39aGJIGMSN1cP19O2w47H_uZNMeiAJyzR1ats":195,"content-page-surround:docs:qXACug39aGJIGMSN1cP19O2w47H_uZNMeiAJyzR1ats":1779,"i-lucide:file":1784,"i-lucide:clipboard":1788},[4,54,74],{"title":5,"page":6,"canonicalKey":7,"locale":8,"id":9,"draft":6,"icon":10,"sidebar":11,"children":12},"Guides",false,"1","en","content:en:1.docs:1.guides:.navigation.yml","lucide:route","section",[13,19,26,33,40,47],{"title":14,"id":15,"canonicalKey":16,"locale":8,"draft":6,"icon":17,"path":18},"Install Guild Wars on Mac","content:en:1.docs:1.guides:1.install.md","1\u002F1","lucide:download","\u002Fdocs\u002Fguides\u002Finstall",{"title":20,"id":21,"canonicalKey":22,"locale":8,"draft":6,"navigation":23,"icon":24,"path":25},"Accounts & mobile linking","content:en:1.docs:1.guides:2.accounts.md","1\u002F2",{"title":20},"lucide:key-round","\u002Fdocs\u002Fguides\u002Faccounts",{"title":27,"id":28,"canonicalKey":29,"locale":8,"draft":6,"navigation":30,"icon":31,"path":32},"Play on Mac: options","content:en:1.docs:1.guides:3.play-guild-wars-on-mac.md","1\u002F3",{"title":27},"lucide:scale","\u002Fdocs\u002Fguides\u002Fplay-guild-wars-on-mac",{"title":34,"id":35,"canonicalKey":36,"locale":8,"draft":6,"navigation":37,"icon":38,"path":39},"Performance","content:en:1.docs:1.guides:4.performance.md","1\u002F4",{"title":34},"lucide:gauge","\u002Fdocs\u002Fguides\u002Fperformance",{"title":41,"id":42,"canonicalKey":43,"locale":8,"draft":6,"navigation":44,"icon":45,"path":46},"Templates","content:en:1.docs:1.guides:5.templates.md","1\u002F5",{"title":41},"lucide:bookmark","\u002Fdocs\u002Fguides\u002Ftemplates",{"title":48,"id":49,"canonicalKey":50,"locale":8,"draft":6,"navigation":51,"icon":52,"path":53},"Troubleshooting","content:en:1.docs:1.guides:6.troubleshooting.md","1\u002F6",{"title":48},"lucide:wrench","\u002Fdocs\u002Fguides\u002Ftroubleshooting",{"title":55,"page":6,"canonicalKey":56,"locale":8,"id":57,"draft":6,"icon":58,"sidebar":59,"children":60},"Project","2","content:en:1.docs:2.project:.navigation.yml","lucide:shield-check","group",[61,67],{"title":62,"id":63,"canonicalKey":64,"locale":8,"draft":6,"navigation":65,"icon":58,"path":66},"Safety & account risk","content:en:1.docs:2.project:1.safety.md","2\u002F1",{"title":62},"\u002Fdocs\u002Fproject\u002Fsafety",{"title":68,"id":69,"canonicalKey":70,"locale":8,"draft":6,"navigation":71,"icon":72,"path":73},"About & credits","content:en:1.docs:2.project:2.about.md","2\u002F2",{"title":68},"lucide:users","\u002Fdocs\u002Fproject\u002Fabout",{"title":75,"page":6,"canonicalKey":76,"locale":8,"id":77,"draft":6,"icon":78,"sidebar":11,"children":79},"For ArenaNet","3","content:en:1.docs:3.upstream:.navigation.yml","lucide:send",[80,87,94,120,146,158,177],{"title":81,"id":82,"canonicalKey":83,"locale":8,"draft":6,"navigation":84,"icon":85,"path":86},"Introduction","content:en:1.docs:3.upstream:1.introduction.md","3\u002F1",{"title":81},"lucide:book-open-check","\u002Fdocs\u002Fupstream\u002Fintroduction",{"title":88,"id":89,"canonicalKey":90,"locale":8,"draft":6,"navigation":91,"icon":92,"path":93},"Request summary","content:en:1.docs:3.upstream:2.request-summary.md","3\u002F2",{"title":88},"lucide:list-checks","\u002Fdocs\u002Fupstream\u002Frequest-summary",{"title":95,"page":6,"canonicalKey":96,"locale":8,"id":97,"draft":6,"icon":98,"sidebar":59,"children":99},"File system","3\u002F3","content:en:1.docs:3.upstream:3.filesystem:.navigation.yml","lucide:folder-x",[100,106,113],{"title":101,"id":102,"canonicalKey":103,"locale":8,"draft":6,"navigation":104,"icon":98,"path":105},"File routines (UR-01…04)","content:en:1.docs:3.upstream:3.filesystem:1.unimplemented-routines.md","3\u002F3\u002F1",{"title":101},"\u002Fdocs\u002Fupstream\u002Ffilesystem\u002Funimplemented-routines",{"title":107,"id":108,"canonicalKey":109,"locale":8,"draft":6,"navigation":110,"icon":111,"path":112},"RemoveExtension (UR-05)","content:en:1.docs:3.upstream:3.filesystem:2.path-remove-extension.md","3\u002F3\u002F2",{"title":107},"lucide:scissors","\u002Fdocs\u002Fupstream\u002Ffilesystem\u002Fpath-remove-extension",{"title":114,"id":115,"canonicalKey":116,"locale":8,"draft":6,"navigation":117,"icon":118,"path":119},"File::Open mode (UR-06)","content:en:1.docs:3.upstream:3.filesystem:3.file-open-mode.md","3\u002F3\u002F3",{"title":114},"lucide:file-plus-2","\u002Fdocs\u002Fupstream\u002Ffilesystem\u002Ffile-open-mode",{"title":121,"page":6,"canonicalKey":122,"locale":8,"id":123,"draft":6,"icon":124,"sidebar":59,"children":125},"Input","3\u002F4","content:en:1.docs:3.upstream:4.input:.navigation.yml","lucide:mouse-pointer-click",[126,132,139],{"title":127,"id":128,"canonicalKey":129,"locale":8,"draft":6,"navigation":130,"icon":124,"path":131},"Double-click (UR-07)","content:en:1.docs:3.upstream:4.input:1.double-click-flag.md","3\u002F4\u002F1",{"title":127},"\u002Fdocs\u002Fupstream\u002Finput\u002Fdouble-click-flag",{"title":133,"id":134,"canonicalKey":135,"locale":8,"draft":6,"navigation":136,"icon":137,"path":138},"Key labels (UR-08)","content:en:1.docs:3.upstream:4.input:2.key-labels.md","3\u002F4\u002F2",{"title":133},"lucide:keyboard","\u002Fdocs\u002Fupstream\u002Finput\u002Fkey-labels",{"title":140,"id":141,"canonicalKey":142,"locale":8,"draft":6,"navigation":143,"icon":144,"path":145},"Cursor re-test (UR-09)","content:en:1.docs:3.upstream:4.input:3.cursor-re-evaluation.md","3\u002F4\u002F3",{"title":140},"lucide:pointer","\u002Fdocs\u002Fupstream\u002Finput\u002Fcursor-re-evaluation",{"title":147,"page":6,"canonicalKey":148,"locale":8,"id":149,"draft":6,"icon":150,"sidebar":59,"children":151},"Runtime","3\u002F5","content:en:1.docs:3.upstream:5.runtime:.navigation.yml","lucide:cpu",[152],{"title":153,"id":154,"canonicalKey":155,"locale":8,"draft":6,"navigation":156,"icon":150,"path":157},"Heap maximum (UR-10)","content:en:1.docs:3.upstream:5.runtime:1.heap-maximum.md","3\u002F5\u002F1",{"title":153},"\u002Fdocs\u002Fupstream\u002Fruntime\u002Fheap-maximum",{"title":159,"page":6,"canonicalKey":160,"locale":8,"id":161,"draft":6,"icon":162,"sidebar":59,"children":163},"Interface proposals","3\u002F6","content:en:1.docs:3.upstream:6.proposals:.navigation.yml","lucide:plug",[164,171],{"title":165,"id":166,"canonicalKey":167,"locale":8,"draft":6,"navigation":168,"icon":169,"path":170},"Build identity (UR-11)","content:en:1.docs:3.upstream:6.proposals:1.build-identification.md","3\u002F6\u002F1",{"title":165},"lucide:fingerprint","\u002Fdocs\u002Fupstream\u002Fproposals\u002Fbuild-identification",{"title":172,"id":173,"canonicalKey":174,"locale":8,"draft":6,"navigation":175,"icon":162,"path":176},"Host interface (UR-12)","content:en:1.docs:3.upstream:6.proposals:2.platform-host-interface.md","3\u002F6\u002F2",{"title":172},"\u002Fdocs\u002Fupstream\u002Fproposals\u002Fplatform-host-interface",{"title":178,"page":6,"canonicalKey":179,"locale":8,"id":180,"draft":6,"icon":181,"sidebar":59,"children":182},"Reference","3\u002F7","content:en:1.docs:3.upstream:7.reference:.navigation.yml","lucide:microscope",[183,189],{"title":184,"id":185,"canonicalKey":186,"locale":8,"draft":6,"navigation":187,"icon":52,"path":188},"Our workarounds","content:en:1.docs:3.upstream:7.reference:1.our-workarounds.md","3\u002F7\u002F1",{"title":184},"\u002Fdocs\u002Fupstream\u002Freference\u002Four-workarounds",{"title":190,"id":191,"canonicalKey":192,"locale":8,"draft":6,"navigation":193,"icon":181,"path":194},"Verification method","content:en:1.docs:3.upstream:7.reference:2.verification-method.md","3\u002F7\u002F2",{"title":190},"\u002Fdocs\u002Fupstream\u002Freference\u002Fverification-method",{"title":196,"ref":197,"description":198,"icon":98,"updated":199,"navigation":200,"body":201,"type":1763,"id":102,"canonicalKey":103,"draft":6,"partial":6,"locale":8,"collection":1764,"navigationFile":6,"file":1765,"resolvedRefs":1771,"route":1772,"resolution":1776},"UR-01 to UR-04: unimplemented Emscripten file routines","docs\u002Fupstream\u002Ffilesystem\u002Funimplemented-routines","Four routines in Base\u002FOs\u002FEmscripten ship as stubs. They disable template save and list, screenshots, and chat logs. One of them aborts the client.","2026-08-04",{"title":101},{"type":202,"children":203,"toc":1730},"root",[204,234,393,405,412,524,528,534,558,568,575,580,593,611,630,635,749,768,774,792,810,816,888,891,897,914,923,928,946,951,961,973,1096,1101,1106,1129,1151,1164,1169,1249,1252,1258,1274,1283,1288,1292,1300,1316,1341,1352,1357,1382,1410,1415,1459,1462,1468,1490,1499,1504,1509,1517,1529,1534,1539,1544,1559,1564,1593,1622,1625,1631,1636,1705,1711,1716],{"type":205,"tag":206,"props":207,"children":208},"element","p",{},[209,212,218,220,225,227,232],{"type":210,"value":211},"text","Four routines in ",{"type":205,"tag":213,"props":214,"children":215},"code",{},[216],{"type":210,"value":217},"Base\u002FOs\u002FEmscripten",{"type":210,"value":219}," ship without an implementation. Three\nreturn a constant; one calls ",{"type":205,"tag":213,"props":221,"children":222},{},[223],{"type":210,"value":224},"assert",{"type":210,"value":226}," and then ",{"type":205,"tag":213,"props":228,"children":229},{},[230],{"type":210,"value":231},"unreachable",{"type":210,"value":233},". Between them they\ndisable skill and equipment templates, the template list, screenshots, and chat\nlogs — and the fourth one aborts the client.",{"type":205,"tag":235,"props":236,"children":237},"table",{},[238,267],{"type":205,"tag":239,"props":240,"children":241},"thead",{},[242],{"type":205,"tag":243,"props":244,"children":245},"tr",{},[246,252,257,262],{"type":205,"tag":247,"props":248,"children":249},"th",{},[250],{"type":210,"value":251},"ID",{"type":205,"tag":247,"props":253,"children":254},{},[255],{"type":210,"value":256},"Routine",{"type":205,"tag":247,"props":258,"children":259},{},[260],{"type":210,"value":261},"Today",{"type":205,"tag":247,"props":263,"children":264},{},[265],{"type":210,"value":266},"Fix",{"type":205,"tag":268,"props":269,"children":270},"tbody",{},[271,301,330,356],{"type":205,"tag":243,"props":272,"children":273},{},[274,283,288,293],{"type":205,"tag":275,"props":276,"children":277},"td",{},[278],{"type":205,"tag":213,"props":279,"children":280},{},[281],{"type":210,"value":282},"UR-01",{"type":205,"tag":275,"props":284,"children":285},{},[286],{"type":210,"value":287},"Directory creation",{"type":205,"tag":275,"props":289,"children":290},{},[291],{"type":210,"value":292},"Returns error 2 unconditionally",{"type":205,"tag":275,"props":294,"children":295},{},[296],{"type":205,"tag":213,"props":297,"children":298},{},[299],{"type":210,"value":300},"FS.mkdirTree",{"type":205,"tag":243,"props":302,"children":303},{},[304,312,317,322],{"type":205,"tag":275,"props":305,"children":306},{},[307],{"type":205,"tag":213,"props":308,"children":309},{},[310],{"type":210,"value":311},"UR-02",{"type":205,"tag":275,"props":313,"children":314},{},[315],{"type":210,"value":316},"Directory enumeration",{"type":205,"tag":275,"props":318,"children":319},{},[320],{"type":210,"value":321},"Empty body, every directory reads as empty",{"type":205,"tag":275,"props":323,"children":324},{},[325],{"type":205,"tag":213,"props":326,"children":327},{},[328],{"type":210,"value":329},"FS.readdir",{"type":205,"tag":243,"props":331,"children":332},{},[333,341,346,351],{"type":205,"tag":275,"props":334,"children":335},{},[336],{"type":205,"tag":213,"props":337,"children":338},{},[339],{"type":210,"value":340},"UR-03",{"type":205,"tag":275,"props":342,"children":343},{},[344],{"type":210,"value":345},"Entry-name derivation",{"type":205,"tag":275,"props":347,"children":348},{},[349],{"type":210,"value":350},"Returns 0, writes nothing",{"type":205,"tag":275,"props":352,"children":353},{},[354],{"type":210,"value":355},"Path arithmetic",{"type":205,"tag":243,"props":357,"children":358},{},[359,367,372,385],{"type":205,"tag":275,"props":360,"children":361},{},[362],{"type":205,"tag":213,"props":363,"children":364},{},[365],{"type":210,"value":366},"UR-04",{"type":205,"tag":275,"props":368,"children":369},{},[370],{"type":210,"value":371},"File deletion",{"type":205,"tag":275,"props":373,"children":374},{},[375,379,381],{"type":205,"tag":213,"props":376,"children":377},{},[378],{"type":210,"value":224},{"type":210,"value":380}," and ",{"type":205,"tag":213,"props":382,"children":383},{},[384],{"type":210,"value":231},{"type":205,"tag":275,"props":386,"children":387},{},[388],{"type":205,"tag":213,"props":389,"children":390},{},[391],{"type":210,"value":392},"FS.unlink",{"type":205,"tag":206,"props":394,"children":395},{},[396,398,403],{"type":210,"value":397},"Build used for the measurements below:\n",{"type":205,"tag":213,"props":399,"children":400},{},[401],{"type":210,"value":402},"b0319704f3072d6948a66026a35af5eb0af12b48d70986783c293e7c77e98483",{"type":210,"value":404},".",{"type":205,"tag":406,"props":407,"children":409},"h2",{"id":408},"what-the-player-sees",[410],{"type":210,"value":411},"What the player sees",{"type":205,"tag":235,"props":413,"children":414},{},[415,431],{"type":205,"tag":239,"props":416,"children":417},{},[418],{"type":205,"tag":243,"props":419,"children":420},{},[421,426],{"type":205,"tag":247,"props":422,"children":423},{},[424],{"type":210,"value":425},"Action",{"type":205,"tag":247,"props":427,"children":428},{},[429],{"type":210,"value":430},"Result today",{"type":205,"tag":268,"props":432,"children":433},{},[434,451,464,480,493,511],{"type":205,"tag":243,"props":435,"children":436},{},[437,442],{"type":205,"tag":275,"props":438,"children":439},{},[440],{"type":210,"value":441},"Save a skill template",{"type":205,"tag":275,"props":443,"children":444},{},[445],{"type":205,"tag":446,"props":447,"children":448},"em",{},[449],{"type":210,"value":450},"\"The attempt to save the Skills Template named … failed because the file could not be created\u002Fwritten to\"",{"type":205,"tag":243,"props":452,"children":453},{},[454,459],{"type":205,"tag":275,"props":455,"children":456},{},[457],{"type":210,"value":458},"Open \"Load from Skills Template\"",{"type":205,"tag":275,"props":460,"children":461},{},[462],{"type":210,"value":463},"The list is always empty, also after a successful save",{"type":205,"tag":243,"props":465,"children":466},{},[467,472],{"type":205,"tag":275,"props":468,"children":469},{},[470],{"type":210,"value":471},"Rename a template",{"type":205,"tag":275,"props":473,"children":474},{},[475],{"type":205,"tag":446,"props":476,"children":477},{},[478],{"type":210,"value":479},"\"The attempt to rename the Skills Template named … failed\"",{"type":205,"tag":243,"props":481,"children":482},{},[483,488],{"type":205,"tag":275,"props":484,"children":485},{},[486],{"type":210,"value":487},"Delete a template",{"type":205,"tag":275,"props":489,"children":490},{},[491],{"type":210,"value":492},"The client stops",{"type":205,"tag":243,"props":494,"children":495},{},[496,501],{"type":205,"tag":275,"props":497,"children":498},{},[499],{"type":210,"value":500},"Take a screenshot",{"type":205,"tag":275,"props":502,"children":503},{},[504,506],{"type":210,"value":505},"No file appears in ",{"type":205,"tag":213,"props":507,"children":508},{},[509],{"type":210,"value":510},"Screens\u002F",{"type":205,"tag":243,"props":512,"children":513},{},[514,519],{"type":205,"tag":275,"props":515,"children":516},{},[517],{"type":210,"value":518},"Write a chat log",{"type":205,"tag":275,"props":520,"children":521},{},[522],{"type":210,"value":523},"No file appears",{"type":205,"tag":525,"props":526,"children":527},"hr",{},[],{"type":205,"tag":406,"props":529,"children":531},{"id":530},"ur-01-directory-creation-always-fails",[532],{"type":210,"value":533},"UR-01 — directory creation always fails",{"type":205,"tag":206,"props":535,"children":536},{},[537,543,545,550,552,557],{"type":205,"tag":538,"props":539,"children":540},"strong",{},[541],{"type":210,"value":542},"Function 404",{"type":210,"value":544},", signature ",{"type":205,"tag":213,"props":546,"children":547},{},[548],{"type":210,"value":549},"(wchar_t* path, int recursive) -> int",{"type":210,"value":551},", in\n",{"type":205,"tag":213,"props":553,"children":554},{},[555],{"type":210,"value":556},"Base\u002FOs\u002FEmscripten\u002FEmscriptenPath.cpp",{"type":210,"value":404},{"type":205,"tag":206,"props":559,"children":560},{},[561,566],{"type":205,"tag":538,"props":562,"children":563},{},[564],{"type":210,"value":565},"Fix:",{"type":210,"value":567}," low effort, small blast radius — one clear task with a working\nWindows equivalent, and four call sites that all expect this behaviour\nalready.",{"type":205,"tag":569,"props":570,"children":572},"h3",{"id":571},"ur-01-directory-creation-always-fails-what-the-client-does-now",[573],{"type":210,"value":574},"What the client does now",{"type":205,"tag":206,"props":576,"children":577},{},[578],{"type":210,"value":579},"The complete function body is two instructions:",{"type":205,"tag":581,"props":582,"children":586},"pre",{"language":583,"class":584,"tabindex":585},"wasm","shiki dark:dark-plus","0",[587],{"type":205,"tag":213,"props":588,"children":590},{"class":589},"language-wasm",[591],{"type":210,"value":592},"i32.const 2\nend",{"type":205,"tag":206,"props":594,"children":595},{},[596,598,602,604,609],{"type":210,"value":597},"It returns ",{"type":205,"tag":213,"props":599,"children":600},{},[601],{"type":210,"value":56},{"type":210,"value":603}," (",{"type":205,"tag":213,"props":605,"children":606},{},[607],{"type":210,"value":608},"ERROR_FILE_NOT_FOUND",{"type":210,"value":610},") every time, without touching the\nEmscripten file system. We called the shipped function directly:",{"type":205,"tag":581,"props":612,"children":614},{"language":210,"class":613,"tabindex":585},"shiki shiki-themes light-plus dark-plus dark:dark-plus",[615],{"type":205,"tag":213,"props":616,"children":618},{"class":617},"language-text",[619],{"type":205,"tag":620,"props":621,"children":624},"span",{"class":622,"style":623},"line","display: inline",[625],{"type":205,"tag":620,"props":626,"children":627},{},[628],{"type":210,"value":629},"func_404(L\"Templates\u002FSkills\u002F\", 1) = 2",{"type":205,"tag":206,"props":631,"children":632},{},[633],{"type":210,"value":634},"All callers treat a non-zero result as a failure of the whole operation:",{"type":205,"tag":235,"props":636,"children":637},{},[638,654],{"type":205,"tag":239,"props":639,"children":640},{},[641],{"type":205,"tag":243,"props":642,"children":643},{},[644,649],{"type":205,"tag":247,"props":645,"children":646},{},[647],{"type":210,"value":648},"Caller",{"type":205,"tag":247,"props":650,"children":651},{},[652],{"type":210,"value":653},"Purpose",{"type":205,"tag":268,"props":655,"children":656},{},[657,689,713,731],{"type":205,"tag":243,"props":658,"children":659},{},[660,670],{"type":205,"tag":275,"props":661,"children":662},{},[663,665],{"type":210,"value":664},"9757, ",{"type":205,"tag":213,"props":666,"children":667},{},[668],{"type":210,"value":669},"Gw\u002FAccount\u002FCli\u002FAcctCliTemplate.cpp",{"type":205,"tag":275,"props":671,"children":672},{},[673,675,680,682,687],{"type":210,"value":674},"Create ",{"type":205,"tag":213,"props":676,"children":677},{},[678],{"type":210,"value":679},"Templates\u002FSkills",{"type":210,"value":681}," or ",{"type":205,"tag":213,"props":683,"children":684},{},[685],{"type":210,"value":686},"Templates\u002FEquipment",{"type":210,"value":688}," before a write",{"type":205,"tag":243,"props":690,"children":691},{},[692,702],{"type":205,"tag":275,"props":693,"children":694},{},[695,697],{"type":210,"value":696},"12433, ",{"type":205,"tag":213,"props":698,"children":699},{},[700],{"type":210,"value":701},"Gw\u002FUi\u002FUiScreen.cpp",{"type":205,"tag":275,"props":703,"children":704},{},[705,706,711],{"type":210,"value":674},{"type":205,"tag":213,"props":707,"children":708},{},[709],{"type":210,"value":710},"Screens",{"type":210,"value":712}," before a screenshot",{"type":205,"tag":243,"props":714,"children":715},{},[716,726],{"type":205,"tag":275,"props":717,"children":718},{},[719,721],{"type":210,"value":720},"11744, ",{"type":205,"tag":213,"props":722,"children":723},{},[724],{"type":210,"value":725},"CtChatLog.cpp",{"type":205,"tag":275,"props":727,"children":728},{},[729],{"type":210,"value":730},"Create the chat-log directory",{"type":205,"tag":243,"props":732,"children":733},{},[734,744],{"type":205,"tag":275,"props":735,"children":736},{},[737,739],{"type":210,"value":738},"11460, ",{"type":205,"tag":213,"props":740,"children":741},{},[742],{"type":210,"value":743},"ActDlgLogin.cpp",{"type":205,"tag":275,"props":745,"children":746},{},[747],{"type":210,"value":748},"The result is discarded",{"type":205,"tag":206,"props":750,"children":751},{},[752,754,759,761,766],{"type":210,"value":753},"The template save path checks this result before opening the file, so\n",{"type":205,"tag":213,"props":755,"children":756},{},[757],{"type":210,"value":758},"AcctCliTemplate.cpp:1020",{"type":210,"value":760}," stores error 2 and the client reports that it can't\ncreate the file — without ever reaching the file system. We confirmed this:\nthe save failure occurs with zero ",{"type":205,"tag":213,"props":762,"children":763},{},[764],{"type":210,"value":765},"openat",{"type":210,"value":767}," activity.",{"type":205,"tag":569,"props":769,"children":771},{"id":770},"ur-01-directory-creation-always-fails-expected-behaviour",[772],{"type":210,"value":773},"Expected behaviour",{"type":205,"tag":206,"props":775,"children":776},{},[777,779,784,786,790],{"type":210,"value":778},"Create the directory, including parent directories when ",{"type":205,"tag":213,"props":780,"children":781},{},[782],{"type":210,"value":783},"recursive",{"type":210,"value":785}," is set.\nReturn ",{"type":205,"tag":213,"props":787,"children":788},{},[789],{"type":210,"value":585},{"type":210,"value":791}," on success and the matching error code on failure.",{"type":205,"tag":206,"props":793,"children":794},{},[795,797,802,804,808],{"type":210,"value":796},"The module imports no ",{"type":205,"tag":213,"props":798,"children":799},{},[800],{"type":210,"value":801},"mkdir",{"type":210,"value":803},". ",{"type":205,"tag":213,"props":805,"children":806},{},[807],{"type":210,"value":300},{"type":210,"value":809}," in the Emscripten file-system\nAPI is the direct equivalent.",{"type":205,"tag":569,"props":811,"children":813},{"id":812},"ur-01-directory-creation-always-fails-acceptance-criteria",[814],{"type":210,"value":815},"Acceptance criteria",{"type":205,"tag":817,"props":818,"children":819},"ul",{},[820,844,855,866,878],{"type":205,"tag":821,"props":822,"children":823},"li",{},[824,829,831,835,837,842],{"type":205,"tag":213,"props":825,"children":826},{},[827],{"type":210,"value":828},"func_404(L\"Templates\u002FSkills\u002F\", 1)",{"type":210,"value":830}," returns ",{"type":205,"tag":213,"props":832,"children":833},{},[834],{"type":210,"value":585},{"type":210,"value":836}," on a mount where\n",{"type":205,"tag":213,"props":838,"children":839},{},[840],{"type":210,"value":841},"Templates\u002F",{"type":210,"value":843}," does not exist yet.",{"type":205,"tag":821,"props":845,"children":846},{},[847,849,853],{"type":210,"value":848},"After the call, ",{"type":205,"tag":213,"props":850,"children":851},{},[852],{"type":210,"value":679},{"type":210,"value":854}," exists and is a directory.",{"type":205,"tag":821,"props":856,"children":857},{},[858,860,864],{"type":210,"value":859},"A second call on the same path returns ",{"type":205,"tag":213,"props":861,"children":862},{},[863],{"type":210,"value":585},{"type":210,"value":865}," and changes nothing.",{"type":205,"tag":821,"props":867,"children":868},{},[869,871,876],{"type":210,"value":870},"A call with ",{"type":205,"tag":213,"props":872,"children":873},{},[874],{"type":210,"value":875},"recursive = 0",{"type":210,"value":877}," on a path whose parent is absent returns a\nnon-zero error code.",{"type":205,"tag":821,"props":879,"children":880},{},[881,883,887],{"type":210,"value":882},"A screenshot creates a file in ",{"type":205,"tag":213,"props":884,"children":885},{},[886],{"type":210,"value":510},{"type":210,"value":404},{"type":205,"tag":525,"props":889,"children":890},{},[],{"type":205,"tag":406,"props":892,"children":894},{"id":893},"ur-02-directory-enumeration-does-nothing",[895],{"type":210,"value":896},"UR-02 — directory enumeration does nothing",{"type":205,"tag":206,"props":898,"children":899},{},[900,905,907,912],{"type":205,"tag":538,"props":901,"children":902},{},[903],{"type":210,"value":904},"Function 405",{"type":210,"value":906},", signature\n",{"type":205,"tag":213,"props":908,"children":909},{},[910],{"type":210,"value":911},"(FileList* out, const wchar_t* pattern, int flags) -> void",{"type":210,"value":913},", same translation\nunit.",{"type":205,"tag":206,"props":915,"children":916},{},[917,921],{"type":205,"tag":538,"props":918,"children":919},{},[920],{"type":210,"value":565},{"type":210,"value":922}," medium effort — the pattern match and the allocation contract need\ncare. Small blast radius: the callers already handle a list of any length.",{"type":205,"tag":569,"props":924,"children":926},{"id":925},"ur-02-directory-enumeration-does-nothing-what-the-client-does-now",[927],{"type":210,"value":574},{"type":205,"tag":206,"props":929,"children":930},{},[931,933,938,940,944],{"type":210,"value":932},"The function body is empty — it returns without writing to ",{"type":205,"tag":213,"props":934,"children":935},{},[936],{"type":210,"value":937},"out",{"type":210,"value":939},". The caller\nzeroes ",{"type":205,"tag":213,"props":941,"children":942},{},[943],{"type":210,"value":937},{"type":210,"value":945}," before the call, so every directory reads as empty.",{"type":205,"tag":206,"props":947,"children":948},{},[949],{"type":210,"value":950},"The output structure, taken from the call sites:",{"type":205,"tag":581,"props":952,"children":954},{"language":953,"class":584,"tabindex":585},"c",[955],{"type":205,"tag":213,"props":956,"children":958},{"class":957},"language-c",[959],{"type":210,"value":960},"struct FileList {          \u002F\u002F 16 bytes, the caller zeroes this\n    Entry*   entries;      \u002F\u002F +0   the caller frees this with free()\n    uint32_t _pad;         \u002F\u002F +4\n    uint32_t count;        \u002F\u002F +8\n    uint32_t _pad2;        \u002F\u002F +12\n};\n\nstruct Entry {             \u002F\u002F 544 bytes, stride confirmed at every call site\n    uint8_t  header[24];   \u002F\u002F +0   no caller reads this\n    wchar_t  name[260];    \u002F\u002F +24  file name, with extension\n};",{"type":205,"tag":206,"props":962,"children":963},{},[964,966,971],{"type":210,"value":965},"The ",{"type":205,"tag":213,"props":967,"children":968},{},[969],{"type":210,"value":970},"flags",{"type":210,"value":972}," parameter selects the entry kind. We observed these values:",{"type":205,"tag":235,"props":974,"children":975},{},[976,995],{"type":205,"tag":239,"props":977,"children":978},{},[979],{"type":205,"tag":243,"props":980,"children":981},{},[982,986,991],{"type":205,"tag":247,"props":983,"children":984},{},[985],{"type":210,"value":648},{"type":205,"tag":247,"props":987,"children":988},{},[989],{"type":210,"value":990},"Pattern",{"type":205,"tag":247,"props":992,"children":993},{},[994],{"type":210,"value":970},{"type":205,"tag":268,"props":996,"children":997},{},[998,1024,1049,1072],{"type":205,"tag":243,"props":999,"children":1000},{},[1001,1011,1019],{"type":205,"tag":275,"props":1002,"children":1003},{},[1004,1006],{"type":210,"value":1005},"9747, ",{"type":205,"tag":213,"props":1007,"children":1008},{},[1009],{"type":210,"value":1010},"AcctCliTemplate.cpp",{"type":205,"tag":275,"props":1012,"children":1013},{},[1014],{"type":205,"tag":213,"props":1015,"children":1016},{},[1017],{"type":210,"value":1018},"Templates\u002FSkills\u002F*.txt",{"type":205,"tag":275,"props":1020,"children":1021},{},[1022],{"type":210,"value":1023},"17 — files",{"type":205,"tag":243,"props":1025,"children":1026},{},[1027,1036,1044],{"type":205,"tag":275,"props":1028,"children":1029},{},[1030,1032],{"type":210,"value":1031},"9746, ",{"type":205,"tag":213,"props":1033,"children":1034},{},[1035],{"type":210,"value":1010},{"type":205,"tag":275,"props":1037,"children":1038},{},[1039],{"type":205,"tag":213,"props":1040,"children":1041},{},[1042],{"type":210,"value":1043},"Templates\u002FSkills\u002F*",{"type":205,"tag":275,"props":1045,"children":1046},{},[1047],{"type":210,"value":1048},"18 — directories",{"type":205,"tag":243,"props":1050,"children":1051},{},[1052,1060,1068],{"type":205,"tag":275,"props":1053,"children":1054},{},[1055,1056],{"type":210,"value":720},{"type":205,"tag":213,"props":1057,"children":1058},{},[1059],{"type":210,"value":725},{"type":205,"tag":275,"props":1061,"children":1062},{},[1063],{"type":205,"tag":213,"props":1064,"children":1065},{},[1066],{"type":210,"value":1067},"\u003Cdir>\u002Fgw???.txt",{"type":205,"tag":275,"props":1069,"children":1070},{},[1071],{"type":210,"value":7},{"type":205,"tag":243,"props":1073,"children":1074},{},[1075,1084,1092],{"type":205,"tag":275,"props":1076,"children":1077},{},[1078,1079],{"type":210,"value":696},{"type":205,"tag":213,"props":1080,"children":1081},{},[1082],{"type":210,"value":1083},"UiScreen.cpp",{"type":205,"tag":275,"props":1085,"children":1086},{},[1087],{"type":205,"tag":213,"props":1088,"children":1089},{},[1090],{"type":210,"value":1091},"Screens\u002Fgw???.???",{"type":205,"tag":275,"props":1093,"children":1094},{},[1095],{"type":210,"value":7},{"type":205,"tag":206,"props":1097,"children":1098},{},[1099],{"type":210,"value":1100},"Bit 0 selects files, bit 1 selects directories. Bit 4 shows up only in the\ntemplate scans; we didn't determine its meaning.",{"type":205,"tag":569,"props":1102,"children":1104},{"id":1103},"ur-02-directory-enumeration-does-nothing-expected-behaviour",[1105],{"type":210,"value":773},{"type":205,"tag":206,"props":1107,"children":1108},{},[1109,1111,1115,1117,1122,1123,1128],{"type":210,"value":1110},"Write the matching entries into ",{"type":205,"tag":213,"props":1112,"children":1113},{},[1114],{"type":210,"value":937},{"type":210,"value":1116},", setting ",{"type":205,"tag":213,"props":1118,"children":1119},{},[1120],{"type":210,"value":1121},"entries",{"type":210,"value":380},{"type":205,"tag":213,"props":1124,"children":1125},{},[1126],{"type":210,"value":1127},"count",{"type":210,"value":404},{"type":205,"tag":206,"props":1130,"children":1131},{},[1132,1133,1138,1140,1144,1145,1150],{"type":210,"value":796},{"type":205,"tag":213,"props":1134,"children":1135},{},[1136],{"type":210,"value":1137},"getdents",{"type":210,"value":1139},". Use ",{"type":205,"tag":213,"props":1141,"children":1142},{},[1143],{"type":210,"value":329},{"type":210,"value":380},{"type":205,"tag":213,"props":1146,"children":1147},{},[1148],{"type":210,"value":1149},"FS.stat",{"type":210,"value":404},{"type":205,"tag":1152,"props":1153,"children":1155},"warning",{"title":1154},"Allocation contract",[1156,1158,1162],{"type":210,"value":1157},"The caller frees ",{"type":205,"tag":213,"props":1159,"children":1160},{},[1161],{"type":210,"value":1121},{"type":210,"value":1163},", so the block has to come from the client's own\nallocator. Don't allocate it in the host or in a different heap.",{"type":205,"tag":569,"props":1165,"children":1167},{"id":1166},"ur-02-directory-enumeration-does-nothing-acceptance-criteria",[1168],{"type":210,"value":815},{"type":205,"tag":817,"props":1170,"children":1171},{},[1172,1183,1194,1199,1216,1232,1244],{"type":205,"tag":821,"props":1173,"children":1174},{},[1175,1177,1182],{"type":210,"value":1176},"A directory with three matching files gives ",{"type":205,"tag":213,"props":1178,"children":1179},{},[1180],{"type":210,"value":1181},"count = 3",{"type":210,"value":404},{"type":205,"tag":821,"props":1184,"children":1185},{},[1186,1188,1193],{"type":210,"value":1187},"Each entry holds the file name with its extension at offset ",{"type":205,"tag":213,"props":1189,"children":1190},{},[1191],{"type":210,"value":1192},"+24",{"type":210,"value":404},{"type":205,"tag":821,"props":1195,"children":1196},{},[1197],{"type":210,"value":1198},"The entry stride is 544 bytes.",{"type":205,"tag":821,"props":1200,"children":1201},{},[1202,1207,1209,1214],{"type":205,"tag":213,"props":1203,"children":1204},{},[1205],{"type":210,"value":1206},"flags = 1",{"type":210,"value":1208}," returns files only. ",{"type":205,"tag":213,"props":1210,"children":1211},{},[1212],{"type":210,"value":1213},"flags = 2",{"type":210,"value":1215}," returns directories only.",{"type":205,"tag":821,"props":1217,"children":1218},{},[1219,1224,1225,1230],{"type":205,"tag":213,"props":1220,"children":1221},{},[1222],{"type":210,"value":1223},"*",{"type":210,"value":380},{"type":205,"tag":213,"props":1226,"children":1227},{},[1228],{"type":210,"value":1229},"?",{"type":210,"value":1231}," match inside one path component.",{"type":205,"tag":821,"props":1233,"children":1234},{},[1235,1237,1242],{"type":210,"value":1236},"The caller can call ",{"type":205,"tag":213,"props":1238,"children":1239},{},[1240],{"type":210,"value":1241},"free(out->entries)",{"type":210,"value":1243}," without a fault.",{"type":205,"tag":821,"props":1245,"children":1246},{},[1247],{"type":210,"value":1248},"\"Load from Skills Template\" lists a template that the player saved before.",{"type":205,"tag":525,"props":1250,"children":1251},{},[],{"type":205,"tag":406,"props":1253,"children":1255},{"id":1254},"ur-03-entry-name-derivation-writes-nothing",[1256],{"type":210,"value":1257},"UR-03 — entry-name derivation writes nothing",{"type":205,"tag":206,"props":1259,"children":1260},{},[1261,1266,1267,1272],{"type":205,"tag":538,"props":1262,"children":1263},{},[1264],{"type":210,"value":1265},"Function 416",{"type":210,"value":906},{"type":205,"tag":213,"props":1268,"children":1269},{},[1270],{"type":210,"value":1271},"(wchar_t* dst, int, const wchar_t* baseDir, int, const wchar_t* path, int dstChars) -> int",{"type":210,"value":1273},",\nsame translation unit.",{"type":205,"tag":206,"props":1275,"children":1276},{},[1277,1281],{"type":205,"tag":538,"props":1278,"children":1279},{},[1280],{"type":210,"value":565},{"type":210,"value":1282}," low effort. Medium blast radius — the two model paths flip from\ntheir fallback branch to the main branch after the fix; test them together\nwith this change.",{"type":205,"tag":569,"props":1284,"children":1286},{"id":1285},"ur-03-entry-name-derivation-writes-nothing-what-the-client-does-now",[1287],{"type":210,"value":574},{"type":205,"tag":206,"props":1289,"children":1290},{},[1291],{"type":210,"value":579},{"type":205,"tag":581,"props":1293,"children":1294},{"language":583,"class":584,"tabindex":585},[1295],{"type":205,"tag":213,"props":1296,"children":1297},{"class":589},[1298],{"type":210,"value":1299},"i32.const 0\nend",{"type":205,"tag":206,"props":1301,"children":1302},{},[1303,1304,1308,1310,1315],{"type":210,"value":597},{"type":205,"tag":213,"props":1305,"children":1306},{},[1307],{"type":210,"value":585},{"type":210,"value":1309}," and writes nothing to ",{"type":205,"tag":213,"props":1311,"children":1312},{},[1313],{"type":210,"value":1314},"dst",{"type":210,"value":404},{"type":205,"tag":206,"props":1317,"children":1318},{},[1319,1321,1325,1327,1332,1334,1339],{"type":210,"value":1320},"Callers: 9746 and 9747 (",{"type":205,"tag":213,"props":1322,"children":1323},{},[1324],{"type":210,"value":1010},{"type":210,"value":1326},", both template scans), 4463\n(",{"type":205,"tag":213,"props":1328,"children":1329},{},[1330],{"type":210,"value":1331},"MdlDecomp.cpp",{"type":210,"value":1333},"), and 4532 (",{"type":205,"tag":213,"props":1335,"children":1336},{},[1337],{"type":210,"value":1338},"MdlTex.cpp",{"type":210,"value":1340},").",{"type":205,"tag":206,"props":1342,"children":1343},{},[1344,1346,1350],{"type":210,"value":1345},"In the template scans the client drops the result and then reads ",{"type":205,"tag":213,"props":1347,"children":1348},{},[1349],{"type":210,"value":1314},{"type":210,"value":1351}," anyway,\nso it ends up cleaning and registering uninitialised stack memory as the\ntemplate name. The two model paths test the result and take their fallback\nbranch.",{"type":205,"tag":569,"props":1353,"children":1355},{"id":1354},"ur-03-entry-name-derivation-writes-nothing-expected-behaviour",[1356],{"type":210,"value":773},{"type":205,"tag":206,"props":1358,"children":1359},{},[1360,1362,1367,1369,1374,1376,1380],{"type":210,"value":1361},"Write ",{"type":205,"tag":213,"props":1363,"children":1364},{},[1365],{"type":210,"value":1366},"path",{"type":210,"value":1368}," relative to ",{"type":205,"tag":213,"props":1370,"children":1371},{},[1372],{"type":210,"value":1373},"baseDir",{"type":210,"value":1375}," into ",{"type":205,"tag":213,"props":1377,"children":1378},{},[1379],{"type":210,"value":1314},{"type":210,"value":1381}," and return the number of\ncharacters written.",{"type":205,"tag":206,"props":1383,"children":1384},{},[1385,1387,1391,1393,1398,1399,1403,1405,1409],{"type":210,"value":1386},"In the template scans, ",{"type":205,"tag":213,"props":1388,"children":1389},{},[1390],{"type":210,"value":1373},{"type":210,"value":1392}," is ",{"type":205,"tag":213,"props":1394,"children":1395},{},[1396],{"type":210,"value":1397},"Templates\u002FSkills\u002F",{"type":210,"value":380},{"type":205,"tag":213,"props":1400,"children":1401},{},[1402],{"type":210,"value":1366},{"type":210,"value":1404}," is an entry\nname from ",{"type":205,"tag":213,"props":1406,"children":1407},{},[1408],{"type":210,"value":311},{"type":210,"value":404},{"type":205,"tag":569,"props":1411,"children":1413},{"id":1412},"ur-03-entry-name-derivation-writes-nothing-acceptance-criteria",[1414],{"type":210,"value":815},{"type":205,"tag":817,"props":1416,"children":1417},{},[1418,1442,1454],{"type":205,"tag":821,"props":1419,"children":1420},{},[1421,1423,1428,1429,1434,1436,1440],{"type":210,"value":1422},"With ",{"type":205,"tag":213,"props":1424,"children":1425},{},[1426],{"type":210,"value":1427},"baseDir = L\"Templates\u002FSkills\u002F\"",{"type":210,"value":380},{"type":205,"tag":213,"props":1430,"children":1431},{},[1432],{"type":210,"value":1433},"path = L\"Templates\u002FSkills\u002FMy.txt\"",{"type":210,"value":1435},",\n",{"type":205,"tag":213,"props":1437,"children":1438},{},[1439],{"type":210,"value":1314},{"type":210,"value":1441}," holds the relative name and the return value is non-zero.",{"type":205,"tag":821,"props":1443,"children":1444},{},[1445,1447,1452],{"type":210,"value":1446},"The function writes at most ",{"type":205,"tag":213,"props":1448,"children":1449},{},[1450],{"type":210,"value":1451},"dstChars",{"type":210,"value":1453}," characters.",{"type":205,"tag":821,"props":1455,"children":1456},{},[1457],{"type":210,"value":1458},"The two model paths keep their current behaviour when the derivation fails.",{"type":205,"tag":525,"props":1460,"children":1461},{},[],{"type":205,"tag":406,"props":1463,"children":1465},{"id":1464},"ur-04-file-deletion-stops-the-client",[1466],{"type":210,"value":1467},"UR-04 — file deletion stops the client",{"type":205,"tag":206,"props":1469,"children":1470},{},[1471,1476,1477,1482,1483,1488],{"type":205,"tag":538,"props":1472,"children":1473},{},[1474],{"type":210,"value":1475},"Function 552",{"type":210,"value":544},{"type":205,"tag":213,"props":1478,"children":1479},{},[1480],{"type":210,"value":1481},"(const wchar_t* path) -> int",{"type":210,"value":551},{"type":205,"tag":213,"props":1484,"children":1485},{},[1486],{"type":210,"value":1487},"Base\u002FOs\u002FEmscripten\u002FExe\u002FEmscriptenExeFile.cpp",{"type":210,"value":1489},", line 840.",{"type":205,"tag":206,"props":1491,"children":1492},{},[1493,1497],{"type":205,"tag":538,"props":1494,"children":1495},{},[1496],{"type":210,"value":565},{"type":210,"value":1498}," low effort, small blast radius — one live call path.",{"type":205,"tag":569,"props":1500,"children":1502},{"id":1501},"ur-04-file-deletion-stops-the-client-what-the-client-does-now",[1503],{"type":210,"value":574},{"type":205,"tag":206,"props":1505,"children":1506},{},[1507],{"type":210,"value":1508},"The complete function body is an assertion and a trap:",{"type":205,"tag":581,"props":1510,"children":1511},{"language":583,"class":584,"tabindex":585},[1512],{"type":205,"tag":213,"props":1513,"children":1514},{"class":589},[1515],{"type":210,"value":1516},"i32.const \"not implemented\"\ni32.const \"..\u002F..\u002F..\u002F..\u002FBase\u002FOs\u002FEmscripten\u002FExe\u002FEmscriptenExeFile.cpp\"\ni32.const 840\ncall \u003Cassert>\nunreachable",{"type":205,"tag":206,"props":1518,"children":1519},{},[1520,1522,1527],{"type":210,"value":1521},"The call path is ",{"type":205,"tag":213,"props":1523,"children":1524},{},[1525],{"type":210,"value":1526},"File::Delete",{"type":210,"value":1528}," → 730 → 678 → 552. The caller reads a non-zero\nresult as success and reports error 4 otherwise.",{"type":205,"tag":206,"props":1530,"children":1531},{},[1532],{"type":210,"value":1533},"A delete therefore stops the client. A rename stops it too, because a rename is\ntwo steps — write the new name, then delete the old one. When the write step\nfails first, the client reports a rename failure instead.",{"type":205,"tag":569,"props":1535,"children":1537},{"id":1536},"ur-04-file-deletion-stops-the-client-expected-behaviour",[1538],{"type":210,"value":773},{"type":205,"tag":206,"props":1540,"children":1541},{},[1542],{"type":210,"value":1543},"Delete the file. Return non-zero on success, zero on failure.",{"type":205,"tag":206,"props":1545,"children":1546},{},[1547,1548,1553,1554,1558],{"type":210,"value":796},{"type":205,"tag":213,"props":1549,"children":1550},{},[1551],{"type":210,"value":1552},"unlink",{"type":210,"value":1139},{"type":205,"tag":213,"props":1555,"children":1556},{},[1557],{"type":210,"value":392},{"type":210,"value":404},{"type":205,"tag":569,"props":1560,"children":1562},{"id":1561},"ur-04-file-deletion-stops-the-client-acceptance-criteria",[1563],{"type":210,"value":815},{"type":205,"tag":817,"props":1565,"children":1566},{},[1567,1572,1577,1582],{"type":205,"tag":821,"props":1568,"children":1569},{},[1570],{"type":210,"value":1571},"A delete of an existing template removes the file and returns non-zero.",{"type":205,"tag":821,"props":1573,"children":1574},{},[1575],{"type":210,"value":1576},"A delete of an absent file returns zero and does not stop the client.",{"type":205,"tag":821,"props":1578,"children":1579},{},[1580],{"type":210,"value":1581},"A rename of a template completes, and the old file is gone.",{"type":205,"tag":821,"props":1583,"children":1584},{},[1585,1587,1591],{"type":210,"value":1586},"No ",{"type":205,"tag":213,"props":1588,"children":1589},{},[1590],{"type":210,"value":224},{"type":210,"value":1592}," call remains on this path.",{"type":205,"tag":1594,"props":1595,"children":1597},"info",{"title":1596},"Ten more unimplemented bodies nearby",[1598,1617],{"type":205,"tag":206,"props":1599,"children":1600},{},[1601,1603,1608,1610,1615],{"type":210,"value":1602},"The same translation unit holds eight more ",{"type":205,"tag":213,"props":1604,"children":1605},{},[1606],{"type":210,"value":1607},"assert(\"not implemented\")",{"type":210,"value":1609}," bodies:\nfunctions 526, 527, 532, 533, 534, 535, 538, and 539, at lines 490, 601, 608,\nand 634. ",{"type":205,"tag":213,"props":1611,"children":1612},{},[1613],{"type":210,"value":1614},"Net\u002FDiagLib\u002FEmscripten\u002FEmscriptenDiagLib.cpp",{"type":210,"value":1616}," holds two more, at\nlines 23 and 28.",{"type":205,"tag":206,"props":1618,"children":1619},{},[1620],{"type":210,"value":1621},"None of them is reachable today — the eight are vtable slots with no live\ncaller, and the DiagLib pair sits behind a disabled flag. We list them in case\nthey're useful for planning.",{"type":205,"tag":525,"props":1623,"children":1624},{},[],{"type":205,"tag":406,"props":1626,"children":1628},{"id":1627},"how-to-reproduce",[1629],{"type":210,"value":1630},"How to reproduce",{"type":205,"tag":206,"props":1632,"children":1633},{},[1634],{"type":210,"value":1635},"These steps need a stock client. No host change is needed.",{"type":205,"tag":1637,"props":1638,"children":1640},"steps",{"mode":1639},"numbered",[1641,1647,1657,1663,1679,1684],{"type":205,"tag":569,"props":1642,"children":1644},{"id":1643},"how-to-reproduce-save-a-template",[1645],{"type":210,"value":1646},"Save a template",{"type":205,"tag":206,"props":1648,"children":1649},{},[1650,1652,1656],{"type":210,"value":1651},"Log in and open the skills panel. Save a build under any name. The save fails.\nThis is ",{"type":205,"tag":213,"props":1653,"children":1654},{},[1655],{"type":210,"value":282},{"type":210,"value":404},{"type":205,"tag":569,"props":1658,"children":1660},{"id":1659},"how-to-reproduce-open-the-template-list",[1661],{"type":210,"value":1662},"Open the template list",{"type":205,"tag":206,"props":1664,"children":1665},{},[1666,1668,1672,1674,1678],{"type":210,"value":1667},"Open \"Load from Skills Template\". The list is empty. This is ",{"type":205,"tag":213,"props":1669,"children":1670},{},[1671],{"type":210,"value":311},{"type":210,"value":1673}," and\n",{"type":205,"tag":213,"props":1675,"children":1676},{},[1677],{"type":210,"value":340},{"type":210,"value":404},{"type":205,"tag":569,"props":1680,"children":1682},{"id":1681},"how-to-reproduce-delete-a-template",[1683],{"type":210,"value":487},{"type":205,"tag":206,"props":1685,"children":1686},{},[1687,1689,1693,1694,1698,1700,1704],{"type":210,"value":1688},"This step needs a build in which ",{"type":205,"tag":213,"props":1690,"children":1691},{},[1692],{"type":210,"value":282},{"type":210,"value":380},{"type":205,"tag":213,"props":1695,"children":1696},{},[1697],{"type":210,"value":311},{"type":210,"value":1699}," work. Delete a listed\ntemplate. The client stops. This is ",{"type":205,"tag":213,"props":1701,"children":1702},{},[1703],{"type":210,"value":366},{"type":210,"value":404},{"type":205,"tag":406,"props":1706,"children":1708},{"id":1707},"our-workaround-today",[1709],{"type":210,"value":1710},"Our workaround today",{"type":205,"tag":206,"props":1712,"children":1713},{},[1714],{"type":210,"value":1715},"The host rewrites the module before starting the client: it appends five\nforwarder functions and repoints the stub call sites at them. Each forwarder\ncalls out to the host through a marker value on an existing syscall import,\nand the host does the actual file work in the Emscripten file system.",{"type":205,"tag":206,"props":1717,"children":1718},{},[1719,1721,1728],{"type":210,"value":1720},"That rewrite has to be re-certified for every new client build. Implementing\nthese four routines makes it unnecessary —\n",{"type":205,"tag":1722,"props":1723,"children":1725},"a",{"href":1724},"$docs\u002Fupstream\u002Freference\u002Four-workarounds",[1726],{"type":210,"value":1727},"our workarounds",{"type":210,"value":1729}," has the detail.",{"title":1731,"searchDepth":1732,"depth":1732,"links":1733},"",4,[1734,1736,1742,1747,1752,1757,1762],{"id":408,"depth":1735,"text":411},2,{"id":530,"depth":1735,"text":533,"children":1737},[1738,1740,1741],{"id":571,"depth":1739,"text":574},3,{"id":770,"depth":1739,"text":773},{"id":812,"depth":1739,"text":815},{"id":893,"depth":1735,"text":896,"children":1743},[1744,1745,1746],{"id":925,"depth":1739,"text":574},{"id":1103,"depth":1739,"text":773},{"id":1166,"depth":1739,"text":815},{"id":1254,"depth":1735,"text":1257,"children":1748},[1749,1750,1751],{"id":1285,"depth":1739,"text":574},{"id":1354,"depth":1739,"text":773},{"id":1412,"depth":1739,"text":815},{"id":1464,"depth":1735,"text":1467,"children":1753},[1754,1755,1756],{"id":1501,"depth":1739,"text":574},{"id":1536,"depth":1739,"text":773},{"id":1561,"depth":1739,"text":815},{"id":1627,"depth":1735,"text":1630,"children":1758},[1759,1760,1761],{"id":1643,"depth":1739,"text":1646},{"id":1659,"depth":1739,"text":1662},{"id":1681,"depth":1739,"text":487},{"id":1707,"depth":1735,"text":1710},"markdown","docs",{"source":1766,"path":1767,"stem":1768,"dir":1769,"extension":1770},"content","en\u002F1.docs\u002F3.upstream\u002F3.filesystem\u002F1.unimplemented-routines.md","en\u002F1.docs\u002F3.upstream\u002F3.filesystem\u002F1.unimplemented-routines","filesystem","md",{"$docs\u002Fupstream\u002Freference\u002Four-workarounds":188},{"requestedPath":105,"resolvedPath":105,"alternates":1773},[1774],{"locale":8,"path":105,"source":1775},"variant",{"requested":1777,"resolved":1778,"usedFallback":6},{"locale":8},{"locale":8},{"previous":1780,"next":1782},{"title":88,"id":89,"canonicalKey":90,"locale":8,"draft":6,"navigation":1781,"path":93},{"title":88},{"title":107,"id":108,"canonicalKey":109,"locale":8,"draft":6,"navigation":1783,"path":112},{"title":107},{"left":1785,"top":1785,"width":1786,"height":1786,"rotate":1785,"vFlip":6,"hFlip":6,"body":1787},0,24,"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\"\u002F>\u003Cpath d=\"M14 2v5a1 1 0 0 0 1 1h5\"\u002F>\u003C\u002Fg>",{"left":1785,"top":1785,"width":1786,"height":1786,"rotate":1785,"vFlip":6,"hFlip":6,"body":1789},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"8\" height=\"4\" x=\"8\" y=\"2\" rx=\"1\" ry=\"1\"\u002F>\u003Cpath d=\"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\"\u002F>\u003C\u002Fg>",1786362927327]