@shipstatic/drop 2.2.4 → 2.3.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../node_modules/.pnpm/@shipstatic+types@2.12.0/node_modules/@shipstatic/types/dist/index.js","../src/files.ts","../node_modules/.pnpm/fflate@0.8.3/node_modules/fflate/esm/browser.js","../src/zip.ts","../src/process.ts","../src/entries.ts","../src/useDrop.ts"],"names":["filePath","err","l","td","dat","_a","i","e","processFiles"],"mappings":";;;;AAsSO,IAAM,SAAA,GAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUrB,UAAA,EAAY,mBAAA;AAAA;AAAA,EAEZ,QAAA,EAAU,WAAA;AAAA;AAAA,EAEV,SAAA,EAAW,WAAA;AAAA;AAAA,EAEX,SAAA,EAAW,qBAAA;AAAA;AAAA,EAEX,cAAA,EAAgB,uBAAA;AAAA;AAAA,EAEhB,QAAA,EAAU,sBAAA;AAAA;AAAA,EAEV,GAAA,EAAK,uBAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWL,WAAA,EAAa,aAAA;AAAA;AAAA,EAEb,OAAA,EAAS,eAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBT,OAAA,EAAS,eAAA;AAAA;AAAA,EAET,SAAA,EAAW,qBAAA;AAAA;AAAA,EAEX,IAAA,EAAM,YAAA;AAAA;AAAA,EAEN,MAAA,EAAQ;AACZ,CAAA;AAOA,IAAM,uBAAA,uBAA8B,GAAA,CAAI;AAAA,EACpC,SAAA,CAAU,OAAA;AAAA,EACV,SAAA,CAAU,OAAA;AAAA,EACV,SAAA,CAAU,SAAA;AAAA,EACV,SAAA,CAAU,IAAA;AAAA,EACV,SAAA,CAAU;AACd,CAAC,CAAA;AAsDqC,IAAI,GAAA,CAAI,MAAA,CAAO,OAAO,SAAS,CAAA,CAAE,MAAA,CAAO,CAAC,MAAM,CAAC,uBAAA,CAAwB,GAAA,CAAI,CAAC,CAAC,CAAC;AAkY9G,SAAS,YAAY,KAAA,EAAO;AAC/B,EAAA,OAAQ,KAAA,KAAU,IAAA,IACd,OAAO,KAAA,KAAU,QAAA,IACjB,UAAU,KAAA,IACV,KAAA,CAAM,IAAA,KAAS,WAAA,IACf,QAAA,IAAY,KAAA;AACpB;AA4FA,IAAM,mBAAA,GAAsB;AAAA;AAAA,EAExB,MAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,UAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA;AAAA,EAEA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,aAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA;AAAA,EAEA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA;AAAA,EAEA,IAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA;AAAA,EAEA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA;AAAA,EAEA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA;AAAA,EAEA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA;AAAA,EAEA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA;AAAA,EAEA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA;AAAA,EAEA,KAAA;AAAA,EACA,KAAA;AAAA;AAAA,EAEA;AACJ,CAAA;AAyBO,IAAM,eAAA,GAAkB,mBAAA,CAAoB,GAAA,CAAI,CAAC,GAAA,KAAQ,IAAI,GAAG,CAAA,CAAE,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAoC5E,IAAM,uBAAA,uBAA8B,GAAA,CAAI;AAAA,EAC3C,cAAA;AAAA,EACA;AACJ,CAAC,CAAA;AASM,SAAS,iBAAiBA,SAAAA,EAAU;AACvC,EAAA,MAAM,QAAA,GAAWA,SAAAA,CAAS,OAAA,CAAQ,KAAA,EAAO,GAAG,EAAE,KAAA,CAAM,GAAG,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA;AACvE,EAAA,OAAO,SAAS,IAAA,CAAK,CAAC,MAAM,uBAAA,CAAwB,GAAA,CAAI,CAAC,CAAC,CAAA;AAC9D;AAuiBO,IAAM,oBAAA,GAAuB;AAAA;AAAA,EAEhC,OAAA,EAAS,SAAA;AAAA;AAAA,EAET,gBAAA,EAAkB,kBAAA;AAAA;AAAA,EAElB,QAAA,EAAU,UAAA;AAAA;AAAA,EAEV,iBAAA,EAAmB,mBAAA;AAAA;AAAA,EAEnB,KAAA,EAAO;AACX,CAAA;AC5kDO,SAAS,eAAA,CAAgB,MAAY,IAAA,EAAoB;AAC9D,EAAA,MAAA,CAAO,cAAA,CAAe,MAAM,oBAAA,EAAsB;AAAA,IAChD,KAAA,EAAO,IAAA;AAAA,IACP,QAAA,EAAU,KAAA;AAAA,IACV,YAAA,EAAc;AAAA,GACf,CAAA;AACH;AAMO,SAAS,SAAS,IAAA,EAAoB;AAC3C,EAAA,OAAO,IAAA,CAAK,kBAAA,EAAoB,IAAA,EAAK,IAAK,IAAA,CAAK,IAAA;AACjD;AASO,SAAS,mBAAA,CAAoB,MAAY,OAAA,EAA4C;AAC1F,EAAA,MAAM,IAAA,GAAO,OAAA,EAAS,IAAA,IAAQ,QAAA,CAAS,IAAI,CAAA;AAE3C,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,OAAO,UAAA,EAAW;AAAA,IACtB,IAAA;AAAA,IACA,IAAA;AAAA,IACA,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,MAAM,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,MAAS,IAAA,CAAK,IAAA;AAAA,IACpC,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,cAAc,IAAA,CAAK,YAAA;AAAA,IACnB,QAAQ,oBAAA,CAAqB;AAAA,GAC/B;AACF;AAUO,SAAS,kBAAkB,KAAA,EAAyC;AACzE,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,KAAA;AAE/B,EAAA,MAAM,WAAA,GAAc,oBAAoB,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAC,CAAA;AAEhE,EAAA,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,KAAM;AACzB,IAAA,MAAM,OAAA,GAAU,WAAA,CAAY,CAAC,CAAA,CAAE,IAAA;AAC/B,IAAA,eAAA,CAAgB,CAAA,CAAE,MAAM,OAAO,CAAA;AAC/B,IAAA,OAAO,EAAE,GAAG,CAAA,EAAG,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,OAAA,CAAQ,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,EAAI,IAAK,EAAE,IAAA,EAAK;AAAA,EACzE,CAAC,CAAA;AACH;AAQO,SAAS,WAAA,CACd,KAAA,EACA,MAAA,EACA,aAAA,EACiB;AACjB,EAAA,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,IACvB,GAAG,CAAA;AAAA,IACH,MAAA;AAAA,IACA,GAAI,aAAA,KAAkB,MAAA,GAAY,EAAC,GAAI,EAAE,aAAA;AAAc,GACzD,CAAE,CAAA;AACJ;;;AC7EA,IAAI,MAAM,EAAC;AACX,IAAI,MAAM,SAAU,CAAA,EAAG,EAAA,EAAI,GAAA,EAAK,UAAU,EAAA,EAAI;AAC1C,EAAA,IAAI,CAAA,GAAI,IAAI,MAAA,CAAO,GAAA,CAAI,EAAE,CAAA,KAAM,GAAA,CAAI,EAAE,CAAA,GAAI,GAAA,CAAI,eAAA,CAAgB,IAAI,IAAA,CAAK;AAAA,IAClE,CAAA,GAAI;AAAA,KACL,EAAE,IAAA,EAAM,iBAAA,EAAmB,CAAC,CAAA,CAAE,CAAA;AACjC,EAAA,CAAA,CAAE,SAAA,GAAY,SAAU,CAAA,EAAG;AACvB,IAAA,IAAI,CAAA,GAAI,CAAA,CAAE,IAAA,EAAM,EAAA,GAAK,CAAA,CAAE,GAAA;AACvB,IAAA,IAAI,EAAA,EAAI;AACJ,MAAA,IAAIC,IAAAA,GAAM,IAAI,KAAA,CAAM,EAAA,CAAG,CAAC,CAAC,CAAA;AACzB,MAAAA,IAAAA,CAAI,MAAM,CAAA,GAAI,EAAA,CAAG,CAAC,CAAA;AAClB,MAAAA,IAAAA,CAAI,KAAA,GAAQ,EAAA,CAAG,CAAC,CAAA;AAChB,MAAA,EAAA,CAAGA,MAAK,IAAI,CAAA;AAAA,IAChB,CAAA;AAEI,MAAA,EAAA,CAAG,MAAM,CAAC,CAAA;AAAA,EAClB,CAAA;AACA,EAAA,CAAA,CAAE,WAAA,CAAY,KAAK,QAAQ,CAAA;AAC3B,EAAA,OAAO,CAAA;AACX,CAAA,CAAA;AAGA,IAAI,EAAA,GAAK,UAAA;AAAT,IAAqB,GAAA,GAAM,WAAA;AAA3B,IAAwC,GAAA,GAAM,UAAA;AAE9C,IAAI,IAAA,GAAO,IAAI,EAAA,CAAG;AAAA,EAAC,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA;AAAA,EAAgB,CAAA;AAAA,EAAG,CAAA;AAAA;AAAA,EAAoB;AAAC,CAAC,CAAA;AAEhJ,IAAI,IAAA,GAAO,IAAI,EAAA,CAAG;AAAA,EAAC,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,CAAA;AAAA,EAAG,EAAA;AAAA,EAAI,EAAA;AAAA,EAAI,EAAA;AAAA,EAAI,EAAA;AAAA,EAAI,EAAA;AAAA,EAAI,EAAA;AAAA,EAAI,EAAA;AAAA,EAAI,EAAA;AAAA;AAAA,EAAiB,CAAA;AAAA,EAAG;AAAC,CAAC,CAAA;AAEvI,IAAI,IAAA,GAAO,IAAI,EAAA,CAAG,CAAC,IAAI,EAAA,EAAI,EAAA,EAAI,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,GAAG,EAAA,EAAI,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,IAAI,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,EAAE,CAAC,CAAA;AAEpF,IAAI,IAAA,GAAO,SAAU,EAAA,EAAI,KAAA,EAAO;AAC5B,EAAA,IAAI,CAAA,GAAI,IAAI,GAAA,CAAI,EAAE,CAAA;AAClB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,EAAE,CAAA,EAAG;AACzB,IAAA,CAAA,CAAE,CAAC,CAAA,GAAI,KAAA,IAAS,CAAA,IAAK,EAAA,CAAG,IAAI,CAAC,CAAA;AAAA,EACjC;AAEA,EAAA,IAAI,CAAA,GAAI,IAAI,GAAA,CAAI,CAAA,CAAE,EAAE,CAAC,CAAA;AACrB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,EAAE,CAAA,EAAG;AACzB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,GAAI,EAAE,CAAA,GAAI,CAAC,CAAA,EAAG,EAAE,CAAA,EAAG;AAClC,MAAA,CAAA,CAAE,CAAC,CAAA,GAAM,CAAA,GAAI,CAAA,CAAE,CAAC,KAAM,CAAA,GAAK,CAAA;AAAA,IAC/B;AAAA,EACJ;AACA,EAAA,OAAO,EAAE,GAAM,CAAA,EAAK;AACxB,CAAA;AACA,IAAI,EAAA,GAAK,IAAA,CAAK,IAAA,EAAM,CAAC,CAAA;AAArB,IAAwB,KAAK,EAAA,CAAG,CAAA;AAAhC,IAAmC,QAAQ,EAAA,CAAG,CAAA;AAE9C,EAAA,CAAG,EAAE,CAAA,GAAI,GAAA,EAAK,KAAA,CAAM,GAAG,CAAA,GAAI,EAAA;AAC3B,IAAI,EAAA,GAAK,IAAA,CAAK,IAAA,EAAM,CAAC,CAAA;AAArB,IAAwB,KAAK,EAAA,CAAG,CAAA;AAEhC,IAAI,GAAA,GAAM,IAAI,GAAA,CAAI,KAAK,CAAA;AACvB,KAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,EAAO,EAAE,CAAA,EAAG;AAExB,EAAA,CAAA,GAAA,CAAM,CAAA,GAAI,KAAA,KAAW,CAAA,GAAA,CAAO,CAAA,GAAI,KAAA,KAAW,CAAA;AAC/C,EAAA,CAAA,GAAA,CAAM,CAAA,GAAI,KAAA,KAAW,CAAA,GAAA,CAAO,CAAA,GAAI,KAAA,KAAW,CAAA;AAC3C,EAAA,CAAA,GAAA,CAAM,CAAA,GAAI,KAAA,KAAW,CAAA,GAAA,CAAO,CAAA,GAAI,IAAA,KAAW,CAAA;AAC3C,EAAA,GAAA,CAAI,CAAC,CAAA,GAAA,CAAA,CAAO,CAAA,GAAI,UAAW,CAAA,GAAA,CAAO,CAAA,GAAI,QAAW,CAAA,KAAO,CAAA;AAC5D;AAJQ,IAAA,CAAA;AAFC,IAAA,CAAA;AAUT,IAAI,IAAA,IAAQ,SAAU,EAAA,EAAI,EAAA,EAAI,CAAA,EAAG;AAC7B,EAAA,IAAI,IAAI,EAAA,CAAG,MAAA;AAEX,EAAA,IAAI,CAAA,GAAI,CAAA;AAER,EAAA,IAAI,CAAA,GAAI,IAAI,GAAA,CAAI,EAAE,CAAA;AAElB,EAAA,OAAO,CAAA,GAAI,CAAA,EAAG,EAAE,CAAA,EAAG;AACf,IAAA,IAAI,GAAG,CAAC,CAAA;AACJ,MAAA,EAAE,CAAA,CAAE,EAAA,CAAG,CAAC,CAAA,GAAI,CAAC,CAAA;AAAA,EACrB;AAEA,EAAA,IAAI,EAAA,GAAK,IAAI,GAAA,CAAI,EAAE,CAAA;AACnB,EAAA,KAAK,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,EAAE,CAAA,EAAG;AACrB,IAAA,EAAA,CAAG,CAAC,IAAK,EAAA,CAAG,CAAA,GAAI,CAAC,CAAA,GAAI,CAAA,CAAE,CAAA,GAAI,CAAC,CAAA,IAAM,CAAA;AAAA,EACtC;AACA,EAAA,IAAI,EAAA;AACJ,EAAA,IAAI,CAAA,EAAG;AAEH,IAAA,EAAA,GAAK,IAAI,GAAA,CAAI,CAAA,IAAK,EAAE,CAAA;AAEpB,IAAA,IAAI,MAAM,EAAA,GAAK,EAAA;AACf,IAAA,KAAK,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,EAAE,CAAA,EAAG;AAEpB,MAAA,IAAI,EAAA,CAAG,CAAC,CAAA,EAAG;AAEP,QAAA,IAAI,EAAA,GAAM,CAAA,IAAK,CAAA,GAAK,EAAA,CAAG,CAAC,CAAA;AAExB,QAAA,IAAI,GAAA,GAAM,EAAA,GAAK,EAAA,CAAG,CAAC,CAAA;AAEnB,QAAA,IAAI,IAAI,EAAA,CAAG,EAAA,CAAG,CAAC,CAAA,GAAI,CAAC,CAAA,EAAA,IAAO,GAAA;AAE3B,QAAA,KAAA,IAAS,CAAA,GAAI,KAAM,CAAA,IAAK,GAAA,IAAO,GAAI,CAAA,IAAK,CAAA,EAAG,EAAE,CAAA,EAAG;AAE5C,UAAA,EAAA,CAAG,GAAA,CAAI,CAAC,CAAA,IAAK,GAAG,CAAA,GAAI,EAAA;AAAA,QACxB;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ,CAAA,MACK;AACD,IAAA,EAAA,GAAK,IAAI,IAAI,CAAC,CAAA;AACd,IAAA,KAAK,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,EAAE,CAAA,EAAG;AACpB,MAAA,IAAI,EAAA,CAAG,CAAC,CAAA,EAAG;AACP,QAAA,EAAA,CAAG,CAAC,CAAA,GAAI,GAAA,CAAI,EAAA,CAAG,EAAA,CAAG,CAAC,CAAA,GAAI,CAAC,CAAA,EAAG,CAAA,IAAM,EAAA,GAAK,EAAA,CAAG,CAAC,CAAA;AAAA,MAC9C;AAAA,IACJ;AAAA,EACJ;AACA,EAAA,OAAO,EAAA;AACX,CAAA,CAAA;AAEA,IAAI,GAAA,GAAM,IAAI,EAAA,CAAG,GAAG,CAAA;AACpB,KAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,EAAK,EAAE,CAAA;AACvB,EAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AADJ,IAAA,CAAA;AAET,KAAS,CAAA,GAAI,GAAA,EAAK,CAAA,GAAI,GAAA,EAAK,EAAE,CAAA;AACzB,EAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AADJ,IAAA,CAAA;AAET,KAAS,CAAA,GAAI,GAAA,EAAK,CAAA,GAAI,GAAA,EAAK,EAAE,CAAA;AACzB,EAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AADJ,IAAA,CAAA;AAET,KAAS,CAAA,GAAI,GAAA,EAAK,CAAA,GAAI,GAAA,EAAK,EAAE,CAAA;AACzB,EAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AADJ,IAAA,CAAA;AAGT,IAAI,GAAA,GAAM,IAAI,EAAA,CAAG,EAAE,CAAA;AACnB,KAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,EAAE,CAAA;AACtB,EAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AADJ,IAAA,CAAA;AAGT,IAAyC,IAAA,mBAAqB,IAAA,CAAK,GAAA,EAAK,CAAA,EAAG,CAAC,CAAA;AAE5E,IAAyC,IAAA,mBAAqB,IAAA,CAAK,GAAA,EAAK,CAAA,EAAG,CAAC,CAAA;AAE5E,IAAI,GAAA,GAAM,SAAU,CAAA,EAAG;AACnB,EAAA,IAAI,CAAA,GAAI,EAAE,CAAC,CAAA;AACX,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,CAAA,CAAE,MAAA,EAAQ,EAAE,CAAA,EAAG;AAC/B,IAAA,IAAI,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA;AACP,MAAA,CAAA,GAAI,EAAE,CAAC,CAAA;AAAA,EACf;AACA,EAAA,OAAO,CAAA;AACX,CAAA;AAEA,IAAI,IAAA,GAAO,SAAU,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG;AAC1B,EAAA,IAAI,CAAA,GAAK,IAAI,CAAA,GAAK,CAAA;AAClB,EAAA,OAAA,CAAS,CAAA,CAAE,CAAC,CAAA,GAAK,CAAA,CAAE,IAAI,CAAC,CAAA,IAAK,CAAA,MAAQ,CAAA,GAAI,CAAA,CAAA,GAAM,CAAA;AACnD,CAAA;AAEA,IAAI,MAAA,GAAS,SAAU,CAAA,EAAG,CAAA,EAAG;AACzB,EAAA,IAAI,CAAA,GAAK,IAAI,CAAA,GAAK,CAAA;AAClB,EAAA,OAAA,CAAS,CAAA,CAAE,CAAC,CAAA,GAAK,CAAA,CAAE,CAAA,GAAI,CAAC,CAAA,IAAK,CAAA,GAAM,CAAA,CAAE,CAAA,GAAI,CAAC,CAAA,IAAK,QAAS,CAAA,GAAI,CAAA,CAAA;AAChE,CAAA;AAEA,IAAI,IAAA,GAAO,SAAU,CAAA,EAAG;AAAE,EAAA,OAAA,CAAS,CAAA,GAAI,KAAK,CAAA,GAAK,CAAA;AAAG,CAAA;AAGpD,IAAI,GAAA,GAAM,SAAU,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG;AACzB,EAAA,IAAI,CAAA,IAAK,QAAQ,CAAA,GAAI,CAAA;AACjB,IAAA,CAAA,GAAI,CAAA;AACR,EAAA,IAAI,CAAA,IAAK,IAAA,IAAQ,CAAA,GAAI,CAAA,CAAE,MAAA;AACnB,IAAA,CAAA,GAAI,CAAA,CAAE,MAAA;AAEV,EAAA,OAAO,IAAI,EAAA,CAAG,CAAA,CAAE,QAAA,CAAS,CAAA,EAAG,CAAC,CAAC,CAAA;AAClC,CAAA;AAsBA,IAAI,EAAA,GAAK;AAAA,EACL,gBAAA;AAAA,EACA,oBAAA;AAAA,EACA,wBAAA;AAAA,EACA,kBAAA;AAAA,EACA,iBAAA;AAAA,EACA,mBAAA;AAAA;AACA;AAAA,EACA,aAAA;AAAA,EACA,oBAAA;AAAA,EACA,sBAAA;AAAA,EACA,6BAAA;AAAA,EACA,mBAAA;AAAA,EACA,kBAAA;AAAA,EACA;AAAA;AAEJ,CAAA;AAEA,IAAI,GAAA,GAAM,SAAU,GAAA,EAAK,GAAA,EAAK,EAAA,EAAI;AAC9B,EAAA,IAAI,IAAI,IAAI,KAAA,CAAM,GAAA,IAAO,EAAA,CAAG,GAAG,CAAC,CAAA;AAChC,EAAA,CAAA,CAAE,IAAA,GAAO,GAAA;AACT,EAAA,IAAI,KAAA,CAAM,iBAAA;AACN,IAAA,KAAA,CAAM,iBAAA,CAAkB,GAAG,GAAG,CAAA;AAClC,EAAA,IAAI,CAAC,EAAA;AACD,IAAA,MAAM,CAAA;AACV,EAAA,OAAO,CAAA;AACX,CAAA;AAEA,IAAI,KAAA,GAAQ,SAAU,GAAA,EAAK,EAAA,EAAI,KAAK,IAAA,EAAM;AAEtC,EAAA,IAAI,KAAK,GAAA,CAAI,MAAA,EAAQ,EAAA,GAAK,IAAA,GAAO,KAAK,MAAA,GAAS,CAAA;AAC/C,EAAA,IAAI,CAAC,EAAA,IAAM,EAAA,CAAG,CAAA,IAAK,CAAC,EAAA,CAAG,CAAA;AACnB,IAAA,OAAO,GAAA,IAAO,IAAI,EAAA,CAAG,CAAC,CAAA;AAC1B,EAAA,IAAI,QAAQ,CAAC,GAAA;AAEb,EAAA,IAAI,MAAA,GAAS,KAAA,IAAS,EAAA,CAAG,CAAA,IAAK,CAAA;AAE9B,EAAA,IAAI,OAAO,EAAA,CAAG,CAAA;AAEd,EAAA,IAAI,KAAA;AACA,IAAA,GAAA,GAAM,IAAI,EAAA,CAAG,EAAA,GAAK,CAAC,CAAA;AAEvB,EAAA,IAAI,IAAA,GAAO,SAAUC,EAAAA,EAAG;AACpB,IAAA,IAAI,KAAK,GAAA,CAAI,MAAA;AAEb,IAAA,IAAIA,KAAI,EAAA,EAAI;AAER,MAAA,IAAI,IAAA,GAAO,IAAI,EAAA,CAAG,IAAA,CAAK,IAAI,EAAA,GAAK,CAAA,EAAGA,EAAC,CAAC,CAAA;AACrC,MAAA,IAAA,CAAK,IAAI,GAAG,CAAA;AACZ,MAAA,GAAA,GAAM,IAAA;AAAA,IACV;AAAA,EACJ,CAAA;AAEA,EAAA,IAAI,KAAA,GAAQ,GAAG,CAAA,IAAK,CAAA,EAAG,MAAM,EAAA,CAAG,CAAA,IAAK,CAAA,EAAG,EAAA,GAAK,EAAA,CAAG,CAAA,IAAK,GAAG,EAAA,GAAK,EAAA,CAAG,GAAG,EAAA,GAAK,EAAA,CAAG,GAAG,GAAA,GAAM,EAAA,CAAG,CAAA,EAAG,GAAA,GAAM,EAAA,CAAG,CAAA;AAEnG,EAAA,IAAI,OAAO,EAAA,GAAK,CAAA;AAChB,EAAA,GAAG;AACC,IAAA,IAAI,CAAC,EAAA,EAAI;AAEL,MAAA,KAAA,GAAQ,IAAA,CAAK,GAAA,EAAK,GAAA,EAAK,CAAC,CAAA;AAExB,MAAA,IAAI,IAAA,GAAO,IAAA,CAAK,GAAA,EAAK,GAAA,GAAM,GAAG,CAAC,CAAA;AAC/B,MAAA,GAAA,IAAO,CAAA;AACP,MAAA,IAAI,CAAC,IAAA,EAAM;AAEP,QAAA,IAAI,IAAI,IAAA,CAAK,GAAG,CAAA,GAAI,CAAA,EAAG,IAAI,GAAA,CAAI,CAAA,GAAI,CAAC,CAAA,GAAK,IAAI,CAAA,GAAI,CAAC,CAAA,IAAK,CAAA,EAAI,IAAI,CAAA,GAAI,CAAA;AACnE,QAAA,IAAI,IAAI,EAAA,EAAI;AACR,UAAA,IAAI,IAAA;AACA,YAAA,GAAA,CAAI,CAAC,CAAA;AACT,UAAA;AAAA,QACJ;AAEA,QAAA,IAAI,MAAA;AACA,UAAA,IAAA,CAAK,KAAK,CAAC,CAAA;AAEf,QAAA,GAAA,CAAI,IAAI,GAAA,CAAI,QAAA,CAAS,CAAA,EAAG,CAAC,GAAG,EAAE,CAAA;AAE9B,QAAA,EAAA,CAAG,CAAA,GAAI,MAAM,CAAA,EAAG,EAAA,CAAG,IAAI,GAAA,GAAM,CAAA,GAAI,CAAA,EAAG,EAAA,CAAG,CAAA,GAAI,KAAA;AAC3C,QAAA;AAAA,MACJ,WACS,IAAA,IAAQ,CAAA;AACb,QAAA,EAAA,GAAK,IAAA,EAAM,EAAA,GAAK,IAAA,EAAM,GAAA,GAAM,GAAG,GAAA,GAAM,CAAA;AAAA,WAAA,IAChC,QAAQ,CAAA,EAAG;AAEhB,QAAA,IAAI,IAAA,GAAO,IAAA,CAAK,GAAA,EAAK,GAAA,EAAK,EAAE,CAAA,GAAI,GAAA,EAAK,KAAA,GAAQ,IAAA,CAAK,GAAA,EAAK,GAAA,GAAM,EAAA,EAAI,EAAE,CAAA,GAAI,CAAA;AACvE,QAAA,IAAI,KAAK,IAAA,GAAO,IAAA,CAAK,KAAK,GAAA,GAAM,CAAA,EAAG,EAAE,CAAA,GAAI,CAAA;AACzC,QAAA,GAAA,IAAO,EAAA;AAEP,QAAA,IAAI,GAAA,GAAM,IAAI,EAAA,CAAG,EAAE,CAAA;AAEnB,QAAA,IAAI,GAAA,GAAM,IAAI,EAAA,CAAG,EAAE,CAAA;AACnB,QAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,EAAO,EAAE,CAAA,EAAG;AAE5B,UAAA,GAAA,CAAI,IAAA,CAAK,CAAC,CAAC,CAAA,GAAI,KAAK,GAAA,EAAK,GAAA,GAAM,CAAA,GAAI,CAAA,EAAG,CAAC,CAAA;AAAA,QAC3C;AACA,QAAA,GAAA,IAAO,KAAA,GAAQ,CAAA;AAEf,QAAA,IAAI,MAAM,GAAA,CAAI,GAAG,CAAA,EAAG,MAAA,GAAA,CAAU,KAAK,GAAA,IAAO,CAAA;AAE1C,QAAA,IAAI,GAAA,GAAM,IAAA,CAAK,GAAA,EAAK,GAAA,EAAK,CAAC,CAAA;AAC1B,QAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,IAAK;AACrB,UAAA,IAAI,IAAI,GAAA,CAAI,IAAA,CAAK,GAAA,EAAK,GAAA,EAAK,MAAM,CAAC,CAAA;AAElC,UAAA,GAAA,IAAO,CAAA,GAAI,EAAA;AAEX,UAAA,IAAI,IAAI,CAAA,IAAK,CAAA;AAEb,UAAA,IAAI,IAAI,EAAA,EAAI;AACR,YAAA,GAAA,CAAI,GAAG,CAAA,GAAI,CAAA;AAAA,UACf,CAAA,MACK;AAED,YAAA,IAAI,CAAA,GAAI,GAAG,CAAA,GAAI,CAAA;AACf,YAAA,IAAI,CAAA,IAAK,EAAA;AACL,cAAA,CAAA,GAAI,CAAA,GAAI,IAAA,CAAK,GAAA,EAAK,GAAA,EAAK,CAAC,CAAA,EAAG,GAAA,IAAO,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,CAAA,GAAI,CAAC,CAAA;AAAA,iBAAA,IAC7C,CAAA,IAAK,EAAA;AACV,cAAA,CAAA,GAAI,IAAI,IAAA,CAAK,GAAA,EAAK,GAAA,EAAK,CAAC,GAAG,GAAA,IAAO,CAAA;AAAA,iBAAA,IAC7B,CAAA,IAAK,EAAA;AACV,cAAA,CAAA,GAAI,KAAK,IAAA,CAAK,GAAA,EAAK,GAAA,EAAK,GAAG,GAAG,GAAA,IAAO,CAAA;AACzC,YAAA,OAAO,CAAA,EAAA;AACH,cAAA,GAAA,CAAI,GAAG,CAAA,GAAI,CAAA;AAAA,UACnB;AAAA,QACJ;AAEA,QAAA,IAAI,EAAA,GAAK,IAAI,QAAA,CAAS,CAAA,EAAG,IAAI,CAAA,EAAG,EAAA,GAAK,GAAA,CAAI,QAAA,CAAS,IAAI,CAAA;AAEtD,QAAA,GAAA,GAAM,IAAI,EAAE,CAAA;AAEZ,QAAA,GAAA,GAAM,IAAI,EAAE,CAAA;AACZ,QAAA,EAAA,GAAK,IAAA,CAAK,EAAA,EAAI,GAAA,EAAK,CAAC,CAAA;AACpB,QAAA,EAAA,GAAK,IAAA,CAAK,EAAA,EAAI,GAAA,EAAK,CAAC,CAAA;AAAA,MACxB,CAAA;AAEI,QAAA,GAAA,CAAI,CAAC,CAAA;AACT,MAAA,IAAI,MAAM,IAAA,EAAM;AACZ,QAAA,IAAI,IAAA;AACA,UAAA,GAAA,CAAI,CAAC,CAAA;AACT,QAAA;AAAA,MACJ;AAAA,IACJ;AAGA,IAAA,IAAI,MAAA;AACA,MAAA,IAAA,CAAK,KAAK,MAAM,CAAA;AACpB,IAAA,IAAI,OAAO,CAAA,IAAK,GAAA,IAAO,CAAA,EAAG,GAAA,GAAA,CAAO,KAAK,GAAA,IAAO,CAAA;AAC7C,IAAA,IAAI,IAAA,GAAO,GAAA;AACX,IAAA,SAAQ,OAAO,GAAA,EAAK;AAEhB,MAAA,IAAI,CAAA,GAAI,GAAG,MAAA,CAAO,GAAA,EAAK,GAAG,CAAA,GAAI,GAAG,CAAA,EAAG,GAAA,GAAM,CAAA,IAAK,CAAA;AAC/C,MAAA,GAAA,IAAO,CAAA,GAAI,EAAA;AACX,MAAA,IAAI,MAAM,IAAA,EAAM;AACZ,QAAA,IAAI,IAAA;AACA,UAAA,GAAA,CAAI,CAAC,CAAA;AACT,QAAA;AAAA,MACJ;AACA,MAAA,IAAI,CAAC,CAAA;AACD,QAAA,GAAA,CAAI,CAAC,CAAA;AACT,MAAA,IAAI,GAAA,GAAM,GAAA;AACN,QAAA,GAAA,CAAI,IAAI,CAAA,GAAI,GAAA;AAAA,WAAA,IACP,OAAO,GAAA,EAAK;AACjB,QAAA,IAAA,GAAO,KAAK,EAAA,GAAK,IAAA;AACjB,QAAA;AAAA,MACJ,CAAA,MACK;AACD,QAAA,IAAI,MAAM,GAAA,GAAM,GAAA;AAEhB,QAAA,IAAI,MAAM,GAAA,EAAK;AAEX,UAAA,IAAI,CAAA,GAAI,GAAA,GAAM,GAAA,EAAK,CAAA,GAAI,KAAK,CAAC,CAAA;AAC7B,UAAA,GAAA,GAAM,IAAA,CAAK,KAAK,GAAA,EAAA,CAAM,CAAA,IAAK,KAAK,CAAC,CAAA,GAAI,GAAG,CAAC,CAAA;AACzC,UAAA,GAAA,IAAO,CAAA;AAAA,QACX;AAEA,QAAA,IAAI,CAAA,GAAI,GAAG,MAAA,CAAO,GAAA,EAAK,GAAG,CAAA,GAAI,GAAG,CAAA,EAAG,IAAA,GAAO,CAAA,IAAK,CAAA;AAChD,QAAA,IAAI,CAAC,CAAA;AACD,UAAA,GAAA,CAAI,CAAC,CAAA;AACT,QAAA,GAAA,IAAO,CAAA,GAAI,EAAA;AACX,QAAA,IAAI,EAAA,GAAK,GAAG,IAAI,CAAA;AAChB,QAAA,IAAI,OAAO,CAAA,EAAG;AACV,UAAA,IAAI,CAAA,GAAI,KAAK,IAAI,CAAA;AACjB,UAAA,EAAA,IAAM,OAAO,GAAA,EAAK,GAAG,KAAK,CAAA,IAAK,CAAA,IAAK,GAAG,GAAA,IAAO,CAAA;AAAA,QAClD;AACA,QAAA,IAAI,MAAM,IAAA,EAAM;AACZ,UAAA,IAAI,IAAA;AACA,YAAA,GAAA,CAAI,CAAC,CAAA;AACT,UAAA;AAAA,QACJ;AACA,QAAA,IAAI,MAAA;AACA,UAAA,IAAA,CAAK,KAAK,MAAM,CAAA;AACpB,QAAA,IAAI,MAAM,EAAA,GAAK,GAAA;AACf,QAAA,IAAI,KAAK,EAAA,EAAI;AACT,UAAA,IAAI,QAAQ,EAAA,GAAK,EAAA,EAAI,OAAO,IAAA,CAAK,GAAA,CAAI,IAAI,GAAG,CAAA;AAC5C,UAAA,IAAI,QAAQ,EAAA,GAAK,CAAA;AACb,YAAA,GAAA,CAAI,CAAC,CAAA;AACT,UAAA,OAAO,EAAA,GAAK,MAAM,EAAE,EAAA;AAChB,YAAA,GAAA,CAAI,EAAE,CAAA,GAAI,IAAA,CAAK,KAAA,GAAQ,EAAE,CAAA;AAAA,QACjC;AACA,QAAA,OAAO,EAAA,GAAK,KAAK,EAAE,EAAA;AACf,UAAA,GAAA,CAAI,EAAE,CAAA,GAAI,GAAA,CAAI,EAAA,GAAK,EAAE,CAAA;AAAA,MAC7B;AAAA,IACJ;AACA,IAAA,EAAA,CAAG,CAAA,GAAI,IAAI,EAAA,CAAG,CAAA,GAAI,MAAM,EAAA,CAAG,CAAA,GAAI,EAAA,EAAI,EAAA,CAAG,CAAA,GAAI,KAAA;AAC1C,IAAA,IAAI,EAAA;AACA,MAAA,KAAA,GAAQ,CAAA,EAAG,GAAG,CAAA,GAAI,GAAA,EAAK,GAAG,CAAA,GAAI,EAAA,EAAI,GAAG,CAAA,GAAI,GAAA;AAAA,EACjD,SAAS,CAAC,KAAA;AAEV,EAAA,OAAO,EAAA,IAAM,GAAA,CAAI,MAAA,IAAU,KAAA,GAAQ,GAAA,CAAI,GAAA,EAAK,CAAA,EAAG,EAAE,CAAA,GAAI,GAAA,CAAI,QAAA,CAAS,CAAA,EAAG,EAAE,CAAA;AAC3E,CAAA;AAoOA,IAAI,EAAA,mBAAmB,IAAI,EAAA,CAAG,CAAC,CAAA;AAgM/B,IAAI,GAAA,GAAM,SAAU,CAAA,EAAG,CAAA,EAAG;AACtB,EAAA,IAAI,IAAI,EAAC;AACT,EAAA,KAAA,IAAS,CAAA,IAAK,CAAA;AACV,IAAA,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA;AACd,EAAA,KAAA,IAAS,CAAA,IAAK,CAAA;AACV,IAAA,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA;AACd,EAAA,OAAO,CAAA;AACX,CAAA;AAQA,IAAI,IAAA,GAAO,SAAU,EAAA,EAAI,KAAA,EAAOC,GAAAA,EAAI;AAChC,EAAA,IAAI,KAAK,EAAA,EAAG;AACZ,EAAA,IAAI,EAAA,GAAK,GAAG,QAAA,EAAS;AACrB,EAAA,IAAI,KAAK,EAAA,CAAG,KAAA,CAAM,GAAG,OAAA,CAAQ,GAAG,IAAI,CAAA,EAAG,EAAA,CAAG,WAAA,CAAY,GAAG,CAAC,CAAA,CAAE,OAAA,CAAQ,QAAQ,EAAE,CAAA,CAAE,MAAM,GAAG,CAAA;AACzF,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,EAAA,CAAG,MAAA,EAAQ,EAAE,CAAA,EAAG;AAChC,IAAA,IAAI,IAAI,EAAA,CAAG,CAAC,CAAA,EAAG,CAAA,GAAI,GAAG,CAAC,CAAA;AACvB,IAAA,IAAI,OAAO,KAAK,UAAA,EAAY;AACxB,MAAA,KAAA,IAAS,MAAM,CAAA,GAAI,GAAA;AACnB,MAAA,IAAI,IAAA,GAAO,EAAE,QAAA,EAAS;AACtB,MAAA,IAAI,EAAE,SAAA,EAAW;AAEb,QAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,eAAe,CAAA,IAAK,EAAA,EAAI;AACrC,UAAA,IAAI,KAAA,GAAQ,IAAA,CAAK,OAAA,CAAQ,GAAA,EAAK,CAAC,CAAA,GAAI,CAAA;AACnC,UAAA,KAAA,IAAS,KAAK,KAAA,CAAM,KAAA,EAAO,KAAK,OAAA,CAAQ,GAAA,EAAK,KAAK,CAAC,CAAA;AAAA,QACvD,CAAA,MACK;AACD,UAAA,KAAA,IAAS,IAAA;AACT,UAAA,KAAA,IAAS,KAAK,CAAA,CAAE,SAAA;AACZ,YAAA,KAAA,IAAS,GAAA,GAAM,IAAI,aAAA,GAAgB,CAAA,GAAI,MAAM,CAAA,CAAE,SAAA,CAAU,CAAC,CAAA,CAAE,QAAA,EAAS;AAAA,QAC7E;AAAA,MACJ,CAAA;AAEI,QAAA,KAAA,IAAS,IAAA;AAAA,IACjB,CAAA;AAEI,MAAAA,GAAAA,CAAG,CAAC,CAAA,GAAI,CAAA;AAAA,EAChB;AACA,EAAA,OAAO,KAAA;AACX,CAAA;AACA,IAAI,KAAK,EAAC;AAEV,IAAI,IAAA,GAAO,SAAU,CAAA,EAAG;AACpB,EAAA,IAAI,KAAK,EAAC;AACV,EAAA,KAAA,IAAS,KAAK,CAAA,EAAG;AACb,IAAA,IAAI,CAAA,CAAE,CAAC,CAAA,CAAE,MAAA,EAAQ;AACb,MAAA,EAAA,CAAG,IAAA,CAAA,CAAM,CAAA,CAAE,CAAC,CAAA,GAAI,IAAI,CAAA,CAAE,CAAC,CAAA,CAAE,WAAA,CAAY,CAAA,CAAE,CAAC,CAAC,GAAG,MAAM,CAAA;AAAA,IACtD;AAAA,EACJ;AACA,EAAA,OAAO,EAAA;AACX,CAAA;AAEA,IAAI,IAAA,GAAO,SAAU,GAAA,EAAK,IAAA,EAAM,IAAI,EAAA,EAAI;AACpC,EAAA,IAAI,CAAC,EAAA,CAAG,EAAE,CAAA,EAAG;AACT,IAAA,IAAI,QAAQ,EAAA,EAAI,IAAA,GAAO,EAAC,EAAG,CAAA,GAAI,IAAI,MAAA,GAAS,CAAA;AAC5C,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,EAAE,CAAA;AACrB,MAAA,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,EAAG,OAAO,IAAI,CAAA;AACpC,IAAA,EAAA,CAAG,EAAE,CAAA,GAAI,EAAE,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,EAAG,KAAA,EAAO,IAAI,CAAA,EAAG,CAAA,EAAG,IAAA,EAAK;AAAA,EACrD;AACA,EAAA,IAAIA,MAAK,GAAA,CAAI,IAAI,EAAA,CAAG,EAAE,EAAE,CAAC,CAAA;AACzB,EAAA,OAAO,EAAA,CAAG,EAAA,CAAG,EAAE,CAAA,CAAE,IAAI,yEAAA,GAA4E,IAAA,CAAK,QAAA,EAAS,GAAI,KAAK,EAAA,EAAIA,GAAAA,EAAI,IAAA,CAAKA,GAAE,GAAG,EAAE,CAAA;AAChJ,CAAA;AAEA,IAAI,SAAS,WAAY;AAAE,EAAA,OAAO,CAAC,IAAI,GAAA,EAAK,GAAA,EAAK,MAAM,IAAA,EAAM,IAAA,EAAM,EAAA,EAAI,EAAA,EAAI,IAAA,EAAM,IAAA,EAAM,KAAK,EAAA,EAAI,IAAA,EAAM,GAAA,EAAK,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,KAAK,GAAA,EAAK,KAAA,EAAO,WAAA,EAAa,GAAA,EAAK,IAAI,CAAA;AAAG,CAAA;AAWzK,IAAI,GAAA,GAAM,SAAU,GAAA,EAAK;AAAE,EAAA,OAAO,WAAA,CAAY,GAAA,EAAK,CAAC,GAAA,CAAI,MAAM,CAAC,CAAA;AAAG,CAAA;AAElE,IAAI,IAAA,GAAO,SAAU,CAAA,EAAG;AAAE,EAAA,OAAO,CAAA,IAAK;AAAA,IAClC,KAAK,CAAA,CAAE,IAAA,IAAQ,IAAI,EAAA,CAAG,EAAE,IAAI,CAAA;AAAA,IAC5B,YAAY,CAAA,CAAE;AAAA,GAClB;AAAG,CAAA;AAEH,IAAI,QAAQ,SAAU,GAAA,EAAK,MAAM,GAAA,EAAK,IAAA,EAAM,IAAI,EAAA,EAAI;AAChD,EAAA,IAAI,IAAI,IAAA,CAAK,GAAA,EAAK,MAAM,EAAA,EAAI,SAAUF,MAAKG,IAAAA,EAAK;AAC5C,IAAA,CAAA,CAAE,SAAA,EAAU;AACZ,IAAA,EAAA,CAAGH,MAAKG,IAAG,CAAA;AAAA,EACf,CAAC,CAAA;AACD,EAAA,CAAA,CAAE,WAAA,CAAY,CAAC,GAAA,EAAK,IAAI,CAAA,EAAG,IAAA,CAAK,OAAA,GAAU,CAAC,GAAA,CAAI,MAAM,CAAA,GAAI,EAAE,CAAA;AAC3D,EAAA,OAAO,WAAY;AAAE,IAAA,CAAA,CAAE,SAAA,EAAU;AAAA,EAAG,CAAA;AACxC,CAAA;AAiDA,IAAI,EAAA,GAAK,SAAU,CAAA,EAAG,CAAA,EAAG;AAAE,EAAA,OAAO,EAAE,CAAC,CAAA,GAAK,CAAA,CAAE,CAAA,GAAI,CAAC,CAAA,IAAK,CAAA;AAAI,CAAA;AAE1D,IAAI,EAAA,GAAK,SAAU,CAAA,EAAG,CAAA,EAAG;AAAE,EAAA,OAAA,CAAQ,EAAE,CAAC,CAAA,GAAK,CAAA,CAAE,CAAA,GAAI,CAAC,CAAA,IAAK,CAAA,GAAM,CAAA,CAAE,CAAA,GAAI,CAAC,CAAA,IAAK,EAAA,GAAO,EAAE,CAAA,GAAI,CAAC,KAAK,EAAA,MAAS,CAAA;AAAG,CAAA;AAExG,IAAI,EAAA,GAAK,SAAU,CAAA,EAAG,CAAA,EAAG;AAAE,EAAA,OAAO,EAAA,CAAG,GAAG,CAAC,CAAA,GAAK,GAAG,CAAA,EAAG,CAAA,GAAI,CAAC,CAAA,GAAI,UAAA;AAAa,CAAA;AA4PnE,SAAS,OAAA,CAAQ,IAAA,EAAM,IAAA,EAAM,EAAA,EAAI;AACpC,EAAA,IAAI,CAAC,EAAA;AACD,IAAA,EAAA,GAAK,IAAA,EAAM,OAAO,EAAC;AACvB,EAAA,IAAI,OAAO,EAAA,IAAM,UAAA;AACb,IAAA,GAAA,CAAI,CAAC,CAAA;AACT,EAAA,OAAO,KAAA,CAAM,MAAM,IAAA,EAAM;AAAA,IACrB;AAAA,GACJ,EAAG,SAAU,EAAA,EAAI;AAAE,IAAA,OAAO,GAAA,CAAI,WAAA,CAAY,EAAA,CAAG,IAAA,CAAK,CAAC,CAAA,EAAG,IAAA,CAAK,EAAA,CAAG,IAAA,CAAK,CAAC,CAAC,CAAC,CAAC,CAAA;AAAA,EAAG,CAAA,EAAG,GAAG,EAAE,CAAA;AACtF;AACO,SAAS,WAAA,CAAY,MAAM,IAAA,EAAM;AACpC,EAAA,OAAO,KAAA,CAAM,IAAA,EAAM,EAAE,CAAA,EAAG,CAAA,EAAE,EAAG,IAAA,IAAQ,IAAA,CAAK,GAAA,EAAK,IAAA,IAAQ,IAAA,CAAK,UAAU,CAAA;AAC1E;AAubA,IAAI,EAAA,GAAK,OAAO,WAAA,IAAe,WAAA,wBAAiC,WAAA,EAAY;AAE5E,IAAI,GAAA,GAAM,CAAA;AACV,IAAI;AACA,EAAA,EAAA,CAAG,MAAA,CAAO,EAAA,EAAI,EAAE,MAAA,EAAQ,MAAM,CAAA;AAC9B,EAAA,GAAA,GAAM,CAAA;AACV,CAAA,CAAA,OACO,CAAA,EAAG;AAAE;AAEZ,IAAI,KAAA,GAAQ,SAAU,CAAA,EAAG;AACrB,EAAA,KAAA,IAAS,CAAA,GAAI,EAAA,EAAI,CAAA,GAAI,CAAA,MAAK;AACtB,IAAA,IAAI,CAAA,GAAI,EAAE,CAAA,EAAG,CAAA;AACb,IAAA,IAAI,EAAA,GAAA,CAAM,CAAA,GAAI,GAAA,KAAQ,CAAA,GAAI,QAAQ,CAAA,GAAI,GAAA,CAAA;AACtC,IAAA,IAAI,CAAA,GAAI,KAAK,CAAA,CAAE,MAAA;AACX,MAAA,OAAO,EAAE,GAAG,CAAA,EAAG,CAAA,EAAG,IAAI,CAAA,EAAG,CAAA,GAAI,CAAC,CAAA,EAAE;AACpC,IAAA,IAAI,CAAC,EAAA;AACD,MAAA,CAAA,IAAK,MAAA,CAAO,aAAa,CAAC,CAAA;AAAA,SAAA,IACrB,MAAM,CAAA,EAAG;AACd,MAAA,CAAA,GAAA,CAAA,CAAM,CAAA,GAAI,EAAA,KAAO,EAAA,GAAA,CAAM,CAAA,CAAE,CAAA,EAAG,CAAA,GAAI,EAAA,KAAO,EAAA,GAAA,CAAM,CAAA,CAAE,CAAA,EAAG,CAAA,GAAI,EAAA,KAAO,CAAA,GAAK,EAAE,CAAA,EAAG,CAAA,GAAI,EAAA,IAAO,KAAA,EAC9E,CAAA,IAAK,MAAA,CAAO,YAAA,CAAa,KAAA,GAAS,CAAA,IAAK,EAAA,EAAK,KAAA,GAAS,CAAA,GAAI,IAAK,CAAA;AAAA,IACtE,WACS,EAAA,GAAK,CAAA;AACV,MAAA,CAAA,IAAK,MAAA,CAAO,cAAc,CAAA,GAAI,EAAA,KAAO,IAAK,CAAA,CAAE,CAAA,EAAG,IAAI,EAAG,CAAA;AAAA;AAEtD,MAAA,CAAA,IAAK,MAAA,CAAO,YAAA,CAAA,CAAc,CAAA,GAAI,EAAA,KAAO,EAAA,GAAA,CAAM,CAAA,CAAE,CAAA,EAAG,CAAA,GAAI,EAAA,KAAO,CAAA,GAAK,CAAA,CAAE,CAAA,EAAG,IAAI,EAAG,CAAA;AAAA,EACpF;AACJ,CAAA;AA4HO,SAAS,SAAA,CAAU,KAAK,MAAA,EAAQ;AACnC,EAAA,IAAI,MAAA,EAAQ;AACR,IAAA,IAAI,CAAA,GAAI,EAAA;AACR,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,QAAQ,CAAA,IAAK,KAAA;AACjC,MAAA,CAAA,IAAK,MAAA,CAAO,aAAa,KAAA,CAAM,IAAA,EAAM,IAAI,QAAA,CAAS,CAAA,EAAG,CAAA,GAAI,KAAK,CAAC,CAAA;AACnE,IAAA,OAAO,CAAA;AAAA,EACX,WACS,EAAA,EAAI;AACT,IAAA,OAAO,EAAA,CAAG,OAAO,GAAG,CAAA;AAAA,EACxB,CAAA,MACK;AACD,IAAA,IAAIC,GAAAA,GAAK,MAAM,GAAG,CAAA,EAAG,IAAIA,GAAAA,CAAG,CAAA,EAAG,IAAIA,GAAAA,CAAG,CAAA;AACtC,IAAA,IAAI,CAAA,CAAE,MAAA;AACF,MAAA,GAAA,CAAI,CAAC,CAAA;AACT,IAAA,OAAO,CAAA;AAAA,EACX;AACJ;AAKA,IAAI,IAAA,GAAO,SAAU,CAAA,EAAG,CAAA,EAAG;AAAE,EAAA,OAAO,CAAA,GAAI,EAAA,GAAK,EAAA,CAAG,CAAA,EAAG,CAAA,GAAI,EAAE,CAAA,GAAI,EAAA,CAAG,CAAA,EAAG,CAAA,GAAI,EAAE,CAAA;AAAG,CAAA;AAE5E,IAAI,EAAA,GAAK,SAAU,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG;AACxB,EAAA,IAAI,GAAA,GAAM,EAAA,CAAG,CAAA,EAAG,CAAA,GAAI,EAAE,CAAA,EAAG,GAAA,GAAM,EAAA,CAAG,CAAA,EAAG,CAAA,GAAI,EAAE,CAAA,EAAG,EAAA,GAAK,UAAU,CAAA,CAAE,QAAA,CAAS,CAAA,GAAI,EAAA,EAAI,CAAA,GAAI,EAAA,GAAK,GAAG,CAAA,EAAG,EAAE,EAAA,CAAG,CAAA,EAAG,CAAA,GAAI,CAAC,CAAA,GAAI,IAAA,CAAK,CAAA,EAAG,EAAA,GAAK,IAAI,EAAA,GAAK,GAAA;AACtI,EAAA,IAAIA,GAAAA,GAAK,KAAA,CAAM,CAAA,EAAG,EAAA,EAAI,KAAK,CAAA,EAAG,EAAA,CAAG,CAAA,EAAG,CAAA,GAAI,EAAE,CAAA,EAAG,EAAA,CAAG,CAAA,EAAG,IAAI,EAAE,CAAA,EAAG,EAAA,CAAG,CAAA,EAAG,CAAA,GAAI,EAAE,CAAC,CAAA,EAAG,KAAKA,GAAAA,CAAG,CAAC,CAAA,EAAG,EAAA,GAAKA,GAAAA,CAAG,CAAC,CAAA,EAAG,GAAA,GAAMA,IAAG,CAAC,CAAA;AAC9G,EAAA,OAAO,CAAC,EAAA,CAAG,CAAA,EAAG,CAAA,GAAI,EAAE,GAAG,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,GAAK,MAAM,EAAA,CAAG,CAAA,EAAG,CAAA,GAAI,EAAE,GAAG,GAAG,CAAA;AACpE,CAAA;AAEA,IAAI,KAAA,GAAQ,SAAU,CAAA,EAAG,CAAA,EAAG,GAAG,CAAA,EAAG,EAAA,EAAI,IAAI,GAAA,EAAK;AAC3C,EAAA,IAAI,GAAA,GAAM,EAAA,IAAM,UAAA,EAAY,GAAA,GAAM,EAAA,IAAM,YAAY,IAAA,GAAO,GAAA,IAAO,UAAA,EAAY,CAAA,GAAI,CAAA,GAAI,CAAA;AACtF,EAAA,IAAI,EAAA,GAAK,MAAM,GAAA,GAAM,IAAA;AACrB,EAAA,IAAI,KAAK,EAAA,EAAI;AACT,IAAA,OAAO,CAAA,GAAI,IAAI,CAAA,EAAG,CAAA,IAAK,IAAI,EAAA,CAAG,CAAA,EAAG,CAAA,GAAI,CAAC,CAAA,EAAG;AACrC,MAAA,IAAI,EAAA,CAAG,CAAA,EAAG,CAAC,CAAA,IAAK,CAAA,EAAG;AACf,QAAA,OAAO;AAAA,UACH,MAAM,EAAA,CAAG,CAAA,EAAG,IAAI,CAAA,GAAI,CAAA,GAAI,GAAG,CAAA,GAAI,EAAA;AAAA,UAC/B,GAAA,GAAM,EAAA,CAAG,CAAA,EAAG,CAAA,GAAI,CAAC,CAAA,GAAI,EAAA;AAAA,UACrB,IAAA,GAAO,GAAG,CAAA,EAAG,CAAA,GAAI,IAAI,CAAA,IAAK,GAAA,GAAM,IAAI,CAAA,GAAI,GAAA;AAAA,UACxC;AAAA,SACJ;AAAA,MACJ;AAAA,IACJ;AAEA,IAAA,IAAI,CAAA,GAAI,CAAA;AACJ,MAAA,GAAA,CAAI,EAAE,CAAA;AAAA,EACd;AACA,EAAA,OAAO,CAAC,EAAA,EAAI,EAAA,EAAI,GAAA,EAAK,CAAC,CAAA;AAC1B,CAAA;AAwrBA,IAAI,EAAA,GAAK,OAAO,cAAA,IAAkB,UAAA,GAAa,cAAA,GAAiB,OAAO,UAAA,IAAc,UAAA,GAAa,UAAA,GAAa,SAAU,EAAA,EAAI;AAAE,EAAA,EAAA,EAAG;AAAG,CAAA;AAC9H,SAAS,KAAA,CAAM,IAAA,EAAM,IAAA,EAAM,EAAA,EAAI;AAClC,EAAA,IAAI,CAAC,EAAA;AACD,IAAA,EAAA,GAAK,IAAA,EAAM,OAAO,EAAC;AACvB,EAAA,IAAI,OAAO,EAAA,IAAM,UAAA;AACb,IAAA,GAAA,CAAI,CAAC,CAAA;AACT,EAAA,IAAI,OAAO,EAAC;AACZ,EAAA,IAAI,OAAO,WAAY;AACnB,IAAA,KAAA,IAASC,EAAAA,GAAI,CAAA,EAAGA,EAAAA,GAAI,IAAA,CAAK,QAAQ,EAAEA,EAAAA;AAC/B,MAAA,IAAA,CAAKA,EAAC,CAAA,EAAE;AAAA,EAChB,CAAA;AACA,EAAA,IAAI,QAAQ,EAAC;AACb,EAAA,IAAI,GAAA,GAAM,SAAU,CAAA,EAAG,CAAA,EAAG;AACtB,IAAA,EAAA,CAAG,WAAY;AAAE,MAAA,EAAA,CAAG,GAAG,CAAC,CAAA;AAAA,IAAG,CAAC,CAAA;AAAA,EAChC,CAAA;AACA,EAAA,EAAA,CAAG,WAAY;AAAE,IAAA,GAAA,GAAM,EAAA;AAAA,EAAI,CAAC,CAAA;AAC5B,EAAA,IAAI,CAAA,GAAI,KAAK,MAAA,GAAS,EAAA;AACtB,EAAA,OAAO,GAAG,IAAA,EAAM,CAAC,CAAA,IAAK,SAAA,EAAW,EAAE,CAAA,EAAG;AAClC,IAAA,IAAI,CAAC,CAAA,IAAK,IAAA,CAAK,MAAA,GAAS,IAAI,KAAA,EAAO;AAC/B,MAAA,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,CAAA,EAAG,CAAC,GAAG,IAAI,CAAA;AACvB,MAAA,OAAO,IAAA;AAAA,IACX;AAAA,EACJ;AAEA,EAAA,IAAI,GAAA,GAAM,EAAA,CAAG,IAAA,EAAM,CAAA,GAAI,CAAC,CAAA;AACxB,EAAA,IAAI,GAAA,EAAK;AACL,IAAA,IAAI,CAAA,GAAI,GAAA;AACR,IAAA,IAAI,CAAA,GAAI,EAAA,CAAG,IAAA,EAAM,CAAA,GAAI,EAAE,CAAA;AACvB,IAAA,IAAI,CAAA,GAAI,EAAA,CAAG,IAAA,EAAM,CAAA,GAAI,EAAE,CAAA,IAAK,SAAA;AAC5B,IAAA,IAAI,CAAA,EAAG;AACH,MAAA,IAAI,EAAA,GAAK,EAAA,CAAG,IAAA,EAAM,CAAA,GAAI,EAAE,CAAA;AACxB,MAAA,CAAA,GAAI,EAAA,CAAG,IAAA,EAAM,EAAE,CAAA,IAAK,SAAA;AACpB,MAAA,IAAI,CAAA,EAAG;AACH,QAAA,CAAA,GAAI,GAAA,GAAM,EAAA,CAAG,IAAA,EAAM,EAAA,GAAK,EAAE,CAAA;AAC1B,QAAA,CAAA,GAAI,EAAA,CAAG,IAAA,EAAM,EAAA,GAAK,EAAE,CAAA;AAAA,MACxB;AAAA,IACJ;AACA,IAAA,IAAI,IAAA,GAAO,QAAQ,IAAA,CAAK,MAAA;AACxB,IAAA,IAAI,OAAA,GAAU,SAAUA,EAAAA,EAAG;AACvB,MAAA,IAAID,GAAAA,GAAK,EAAA,CAAG,IAAA,EAAM,CAAA,EAAG,CAAC,CAAA,EAAG,GAAA,GAAMA,GAAAA,CAAG,CAAC,CAAA,EAAG,EAAA,GAAKA,GAAAA,CAAG,CAAC,GAAG,EAAA,GAAKA,GAAAA,CAAG,CAAC,CAAA,EAAG,EAAA,GAAKA,GAAAA,CAAG,CAAC,CAAA,EAAG,KAAKA,GAAAA,CAAG,CAAC,CAAA,EAAG,GAAA,GAAMA,IAAG,CAAC,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,MAAM,GAAG,CAAA;AACrH,MAAA,CAAA,GAAI,EAAA;AACJ,MAAA,IAAI,GAAA,GAAM,SAAUE,EAAAA,EAAG,CAAA,EAAG;AACtB,QAAA,IAAIA,EAAAA,EAAG;AACH,UAAA,IAAA,EAAK;AACL,UAAA,GAAA,CAAIA,IAAG,IAAI,CAAA;AAAA,QACf,CAAA,MACK;AACD,UAAA,IAAI,CAAA;AACA,YAAA,KAAA,CAAM,EAAE,CAAA,GAAI,CAAA;AAChB,UAAA,IAAI,CAAC,EAAE,GAAA;AACH,YAAA,GAAA,CAAI,MAAM,KAAK,CAAA;AAAA,QACvB;AAAA,MACJ,CAAA;AACA,MAAA,IAAI,CAAC,QAAQ,IAAA,CAAK;AAAA,QACd,IAAA,EAAM,EAAA;AAAA,QACN,IAAA,EAAM,EAAA;AAAA,QACN,YAAA,EAAc,EAAA;AAAA,QACd,WAAA,EAAa;AAAA,OAChB,CAAA,EAAG;AACA,QAAA,IAAI,CAAC,GAAA;AACD,UAAA,GAAA,CAAI,MAAM,GAAA,CAAI,IAAA,EAAM,CAAA,EAAG,CAAA,GAAI,EAAE,CAAC,CAAA;AAAA,aAAA,IACzB,OAAO,CAAA,EAAG;AACf,UAAA,IAAI,IAAA,GAAO,IAAA,CAAK,QAAA,CAAS,CAAA,EAAG,IAAI,EAAE,CAAA;AAElC,UAAA,IAAI,EAAA,GAAK,MAAA,IAAU,EAAA,GAAK,GAAA,GAAM,EAAA,EAAI;AAC9B,YAAA,IAAI;AACA,cAAA,GAAA,CAAI,IAAA,EAAM,WAAA,CAAY,IAAA,EAAM,EAAE,GAAA,EAAK,IAAI,EAAA,CAAG,EAAE,CAAA,EAAG,CAAC,CAAA;AAAA,YACpD,SACOA,EAAAA,EAAG;AACN,cAAA,GAAA,CAAIA,IAAG,IAAI,CAAA;AAAA,YACf;AAAA,UACJ,CAAA;AAEI,YAAA,IAAA,CAAK,IAAA,CAAK,QAAQ,IAAA,EAAM,EAAE,MAAM,EAAA,EAAG,EAAG,GAAG,CAAC,CAAA;AAAA,QAClD,CAAA;AAEI,UAAA,GAAA,CAAI,IAAI,EAAA,EAAI,2BAAA,GAA8B,GAAA,EAAK,CAAC,GAAG,IAAI,CAAA;AAAA,MAC/D,CAAA;AAEI,QAAA,GAAA,CAAI,MAAM,IAAI,CAAA;AAAA,IACtB,CAAA;AACA,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,EAAE,CAAA,EAAG;AACxB,MAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IACb;AAAA,EACJ,CAAA;AAEI,IAAA,GAAA,CAAI,IAAA,EAAM,EAAE,CAAA;AAChB,EAAA,OAAO,IAAA;AACX;;;AC/jFA,eAAsB,kBAAkB,OAAA,EAA6C;AACnF,EAAA,IAAI;AACF,IAAA,MAAM,QAAQ,IAAI,UAAA,CAAW,MAAM,OAAA,CAAQ,aAAa,CAAA;AACxD,IAAA,MAAM,UAAU,MAAM,IAAI,OAAA,CAAkB,CAAC,SAAS,MAAA,KAAW;AAC/D,MAAA,KAAA,CAAM,KAAA,EAAO,CAACN,IAAAA,EAAK,IAAA,KAAUA,IAAAA,GAAM,OAAOA,IAAG,CAAA,GAAI,OAAA,CAAQ,IAAI,CAAE,CAAA;AAAA,IACjE,CAAC,CAAA;AAED,IAAA,MAAM,QAAgB,EAAC;AACvB,IAAA,MAAM,SAAmB,EAAC;AAE1B,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,IAAI,KAAK,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,EAAG;AAElD,MAAA,IAAI,KAAK,QAAA,CAAS,GAAG,CAAA,IAAK,IAAA,CAAK,WAAW,CAAA,EAAG;AAE7C,MAAA,MAAM,aAAA,GAAgB,cAAc,IAAI,CAAA;AAGxC,MAAA,IAAI,CAAC,aAAA,EAAe;AAClB,QAAA,MAAA,CAAO,IAAA,CAAK,CAAA,sBAAA,EAAyB,IAAI,CAAA,CAAE,CAAA;AAC3C,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,WAAW,aAAA,CAAc,KAAA,CAAM,GAAG,CAAA,CAAE,KAAI,IAAK,aAAA;AAKnD,MAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,CAAC,IAAI,UAAA,CAAW,IAAI,CAAC,CAAA,EAAG,QAAQ,CAAA;AAKtD,MAAA,eAAA,CAAgB,MAAM,aAAa,CAAA;AAEnC,MAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,IACjB;AAEA,IAAA,OAAO,EAAE,OAAO,MAAA,EAAO;AAAA,EACzB,SAAS,KAAA,EAAO;AACd,IAAA,OAAO;AAAA,MACL,OAAO,EAAC;AAAA,MACR,MAAA,EAAQ;AAAA,QACN,4BAA4B,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA;AACpF,KACF;AAAA,EACF;AACF;AAWO,SAAS,cAAc,IAAA,EAAsB;AAClD,EAAA,MAAM,aAAuB,EAAC;AAE9B,EAAA,KAAA,MAAW,OAAA,IAAW,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,EAAG;AACrC,IAAA,IAAI,OAAA,KAAY,EAAA,IAAM,OAAA,KAAY,GAAA,EAAK;AAEvC,IAAA,IAAI,YAAY,IAAA,EAAM;AAGpB,MAAA,UAAA,CAAW,GAAA,EAAI;AACf,MAAA;AAAA,IACF;AAEA,IAAA,UAAA,CAAW,KAAK,OAAO,CAAA;AAAA,EACzB;AAEA,EAAA,OAAO,UAAA,CAAW,KAAK,GAAG,CAAA;AAC5B;AAKO,SAAS,UAAU,IAAA,EAAqB;AAC7C,EAAA,OACE,IAAA,CAAK,IAAA,KAAS,iBAAA,IACd,IAAA,CAAK,IAAA,KAAS,8BAAA,IACd,IAAA,CAAK,IAAA,CAAK,WAAA,EAAY,CAAE,QAAA,CAAS,MAAM,CAAA;AAE3C;;;ACrDO,SAAS,cAAc,IAAA,EAAsC;AAClE,EAAA,OAAO,EAAE,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,IAAA,EAAM,KAAK,IAAA,EAAK;AAC5C;AAGO,SAAS,iBAAiB,KAAA,EAAuB;AACtD,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,EAAA;AAE/B,EAAA,MAAM,CAAC,KAAK,CAAA,GAAI,KAAA;AAChB,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,IAAK,SAAA,CAAU,KAAK,CAAA,EAAG,OAAO,KAAA,CAAM,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAW,EAAE,CAAA;AAGnF,EAAA,MAAM,IAAA,GAAO,MAAM,kBAAA,IAAsB,EAAA;AACzC,EAAA,OAAO,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,GAAI,IAAA,CAAK,MAAM,GAAG,CAAA,CAAE,CAAC,CAAA,GAAI,KAAA,CAAM,IAAA;AACzD;AAEA,SAAS,QAAQ,MAAA,EAOD;AACd,EAAA,MAAM,EAAE,KAAA,EAAO,OAAA,EAAS,MAAA,EAAQ,KAAA,GAAQ,EAAC,EAAG,UAAA,EAAY,UAAA,GAAa,KAAA,EAAM,GAAI,MAAA;AAC/E,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,OAAA;AAAA,IACP,KAAA;AAAA,IACA,UAAA;AAAA,IACA,UAAA;AAAA;AAAA;AAAA;AAAA,IAIA,MAAA,EAAQ,EAAE,KAAA,EAAO,OAAA,EAAS,GAAI,MAAA,EAAQ,MAAA,GAAS,EAAE,MAAA,EAAO,GAAI,EAAC;AAAG,GAClE;AACF;AASA,eAAsB,YAAA,CACpB,KAAA,EACA,EAAE,MAAA,EAAQ,UAAS,EACG;AAGtB,EAAA,IAAI,UAAA,GAAa,EAAA;AAEjB,EAAA,IAAI;AACF,IAAA,UAAA,GAAa,iBAAiB,KAAK,CAAA;AAGnC,IAAA,IAAI,KAAA;AACJ,IAAA,IAAI,MAAM,MAAA,KAAW,CAAA,IAAK,UAAU,KAAA,CAAM,CAAC,CAAC,CAAA,EAAG;AAC7C,MAAA,QAAA,GAAW,EAAE,KAAA,EAAO,eAAA,EAAiB,OAAA,EAAS,CAAA,WAAA,EAAc,MAAM,CAAC,CAAA,CAAE,IAAI,CAAA,GAAA,CAAA,EAAO,CAAA;AAChF,MAAA,MAAM,EAAE,OAAO,SAAA,EAAW,MAAA,KAAW,MAAM,iBAAA,CAAkB,KAAA,CAAM,CAAC,CAAC,CAAA;AACrE,MAAA,IAAI,OAAO,MAAA,GAAS,CAAA,EAAG,OAAA,CAAQ,IAAA,CAAK,0BAA0B,MAAM,CAAA;AACpE,MAAA,KAAA,GAAQ,SAAA;AAAA,IACV,CAAA,MAAO;AACL,MAAA,KAAA,GAAQ,KAAA;AAAA,IACV;AAIA,IAAA,MAAM,UAAA,GAAa,MAAM,IAAA,CAAK,CAAC,MAAM,gBAAA,CAAiB,QAAA,CAAS,CAAC,CAAC,CAAC,CAAA;AAIlE,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,KAAA,GAAQ,KAAA,CAAM,MAAA;AAAA,QACZ,CAAC,CAAA,KAAM,CAAC,QAAA,CAAS,CAAC,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAAE,KAAA,CAAM,GAAG,CAAA,CAAE,SAAS,cAAc;AAAA,OAC5E;AAAA,IACF;AAGA,IAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,UAAA,CAAW,KAAA,CAAM,GAAA,CAAI,QAAQ,CAAA,EAAG,EAAE,YAAA,EAAc,UAAA,EAAY,CAAC,CAAA;AAKlF,IAAA,MAAM,UAAA,GAAa,iBAAA;AAAA,MACjB,MAAM,MAAA,CAAO,CAAC,CAAA,KAAM,IAAA,CAAK,IAAI,QAAA,CAAS,CAAC,CAAC,CAAC,EAAE,GAAA,CAAI,CAAC,CAAA,KAAM,mBAAA,CAAoB,CAAC,CAAC;AAAA,KAC9E;AAIA,IAAA,IAAI,UAAA,CAAW,SAAS,CAAA,EAAG;AACzB,MAAA,MAAM,QAAA,GAAW,aACb,UAAA,CAAW,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,YAAA,IAAgB,CAAA,CAAE,KAAK,QAAA,CAAS,aAAa,CAAC,CAAA,GAChF,UAAA,CAAW,KAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,YAAY,CAAA;AAElD,MAAA,IAAI,CAAC,QAAA,EAAU;AACb,QAAA,MAAM,OAAA,GAAU,aACZ,8EAAA,GACA,iFAAA;AACJ,QAAA,OAAO,OAAA,CAAQ;AAAA,UACb,KAAA,EAAO,mBAAA;AAAA,UACP,OAAA;AAAA,UACA,UAAA;AAAA,UACA,UAAA;AAAA,UACA,KAAA,EAAO,WAAA,CAAY,UAAA,EAAY,oBAAA,CAAqB,mBAAmB,OAAO;AAAA,SAC/E,CAAA;AAAA,MACH;AAAA,IACF;AAIA,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,UAAA,EAAY,oBAAA,CAAqB,KAAK,CAAA;AAChE,MAAA,OAAO;AAAA,QACL,KAAA,EAAO,OAAA;AAAA,QACP,KAAA,EAAO,KAAA;AAAA,QACP,UAAA;AAAA,QACA,UAAA,EAAY,IAAA;AAAA,QACZ,MAAA,EAAQ;AAAA,UACN,KAAA,EAAO,OAAA;AAAA,UACP,OAAA,EAAS,GAAG,SAAA,CAAU,KAAA,CAAM,QAAQ,MAAA,EAAQ,OAAA,EAAS,IAAI,CAAC,CAAA,mCAAA;AAAA;AAC5D,OACF;AAAA,IACF;AAGA,IAAA,MAAM,aAAa,aAAA,CAAc,UAAA,CAAW,GAAA,CAAI,aAAa,GAAG,MAAM,CAAA;AAEtE,IAAA,MAAM,SAAA,GAAY,UAAA,CAAW,GAAA,CAAI,CAAC,MAAM,CAAA,MAAO;AAAA,MAC7C,GAAG,IAAA;AAAA,MACH,QAAQ,UAAA,CAAW,KAAA,CAAM,CAAC,CAAA,EAAG,UAAU,IAAA,CAAK,MAAA;AAAA,MAC5C,eAAe,UAAA,CAAW,KAAA,CAAM,CAAC,CAAA,EAAG,iBAAiB,IAAA,CAAK;AAAA,KAC5D,CAAE,CAAA;AAGF,IAAA,IAAI,CAAC,WAAW,SAAA,EAAW;AACzB,MAAA,OAAO,OAAA,CAAQ;AAAA,QACb,KAAA,EAAO,mBAAA;AAAA,QACP,OAAA,EAAS,GAAG,SAAA,CAAU,UAAA,CAAW,OAAO,MAAA,EAAQ,MAAA,EAAQ,OAAA,EAAS,IAAI,CAAC,CAAA,kBAAA,CAAA;AAAA,QACtE,MAAA,EAAQ,UAAA,CAAW,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA,EAAA,EAAK,CAAA,CAAE,OAAO,CAAA,CAAE,CAAA;AAAA,QAC9D,KAAA,EAAO,SAAA;AAAA,QACP;AAAA,OACD,CAAA;AAAA,IACH;AAEA,IAAA,MAAM,UAAA,GAAa,UAAU,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,MAAA,KAAW,oBAAA,CAAqB,KAAK,CAAA,CAAE,MAAA;AACpF,IAAA,MAAM,QAAA,GAAW,UAAA,CAAW,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA,EAAA,EAAK,CAAA,CAAE,OAAO,CAAA,CAAE,CAAA;AAEzE,IAAA,IAAI,aAAa,CAAA,EAAG;AAClB,MAAA,IAAI,UAAU,CAAA,EAAG,SAAA,CAAU,YAAY,MAAA,EAAQ,OAAA,EAAS,IAAI,CAAC,CAAA,MAAA,CAAA;AAC7D,MAAA,IAAI,UAAA,CAAW,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG;AAClC,QAAA,OAAA,IAAW,CAAA,EAAA,EAAK,UAAU,UAAA,CAAW,QAAA,CAAS,QAAQ,YAAA,EAAc,aAAA,EAAe,IAAI,CAAC,CAAA,UAAA,CAAA;AAAA,MAC1F;AACA,MAAA,OAAO;AAAA,QACL,KAAA,EAAO,OAAA;AAAA,QACP,KAAA,EAAO,SAAA;AAAA,QACP,UAAA;AAAA,QACA,UAAA,EAAY,KAAA;AAAA,QACZ,MAAA,EAAQ,EAAE,KAAA,EAAO,OAAA,EAAS,OAAA,EAAS,GAAI,QAAA,CAAS,MAAA,GAAS,EAAE,QAAA,EAAS,GAAI,EAAC;AAAG,OAC9E;AAAA,IACF;AAIA,IAAA,IAAI,WAAW,MAAA,CAAO,MAAA,KAAW,KAAK,UAAA,CAAW,QAAA,CAAS,SAAS,CAAA,EAAG;AACpE,MAAA,OAAO;AAAA,QACL,KAAA,EAAO,OAAA;AAAA,QACP,KAAA,EAAO,SAAA;AAAA,QACP,UAAA;AAAA,QACA,UAAA,EAAY,KAAA;AAAA,QACZ,MAAA,EAAQ;AAAA,UACN,KAAA,EAAO,oBAAA;AAAA,UACP,OAAA,EAAS,GAAG,SAAA,CAAU,UAAA,CAAW,SAAS,MAAA,EAAQ,MAAA,EAAQ,OAAA,EAAS,IAAI,CAAC,CAAA,0CAAA,CAAA;AAAA,UACxE;AAAA;AACF,OACF;AAAA,IACF;AAEA,IAAA,OAAO,OAAA,CAAQ;AAAA,MACb,KAAA,EAAO,gBAAA;AAAA,MACP,OAAA,EAAS,gDAAA;AAAA,MACT,KAAA,EAAO,SAAA;AAAA,MACP;AAAA,KACD,CAAA;AAAA,EACH,SAAS,KAAA,EAAO;AAGd,IAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,IAAA,MAAM,YAAA,GAAe,YAAY,KAAK,CAAA;AACtC,IAAA,OAAO,OAAA,CAAQ;AAAA,MACb,KAAA,EAAO,eAAe,mBAAA,GAAsB,mBAAA;AAAA,MAC5C,OAAA,EAAS,YAAA,GAAe,OAAA,GAAU,CAAA,yBAAA,EAA4B,OAAO,CAAA,CAAA;AAAA,MACrE;AAAA,KACD,CAAA;AAAA,EACH;AACF;;;AChOA,eAAsB,gBAAA,CACpB,KAAA,EACA,KAAA,EACA,WAAA,GAAc,EAAA,EACC;AACf,EAAA,IAAI;AACF,IAAA,IAAI,MAAM,MAAA,EAAQ;AAChB,MAAA,MAAM,OAAO,MAAM,IAAI,OAAA,CAAc,CAAC,SAAS,MAAA,KAAW;AACxD,QAAC,KAAA,CAA8B,IAAA,CAAK,OAAA,EAAS,MAAM,CAAA;AAAA,MACrD,CAAC,CAAA;AACD,MAAA,eAAA,CAAgB,IAAA,EAAM,cAAc,CAAA,EAAG,WAAW,IAAI,IAAA,CAAK,IAAI,CAAA,CAAA,GAAK,IAAA,CAAK,IAAI,CAAA;AAC7E,MAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AACf,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,CAAC,MAAM,WAAA,EAAa;AAExB,IAAA,KAAA,MAAW,KAAA,IAAS,MAAM,aAAA,CAAc,KAAiC,CAAA,EAAG;AAC1E,MAAA,IAAI,KAAA,CAAM,WAAA,IAAe,KAAA,CAAM,IAAA,KAAS,cAAA,EAAgB;AAIxD,MAAA,MAAM,SAAA,GAAY,KAAA,CAAM,WAAA,GACpB,WAAA,GACE,CAAA,EAAG,WAAW,CAAA,CAAA,EAAI,KAAA,CAAM,IAAI,CAAA,CAAA,GAC5B,KAAA,CAAM,IAAA,GACR,WAAA;AACJ,MAAA,MAAM,gBAAA,CAAiB,KAAA,EAAO,KAAA,EAAO,SAAS,CAAA;AAAA,IAChD;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,qCAAA,EAAwC,KAAA,CAAM,IAAI,KAAK,KAAK,CAAA;AAAA,EAC3E;AACF;AASA,eAAe,cAAc,SAAA,EAAiE;AAC5F,EAAA,MAAM,MAAA,GAAS,UAAU,YAAA,EAAa;AACtC,EAAA,MAAM,UAA6B,EAAC;AAEpC,EAAA,WAAS;AACP,IAAA,MAAM,QAAQ,MAAM,IAAI,OAAA,CAA2B,CAAC,SAAS,MAAA,KAAW;AACtE,MAAA,MAAA,CAAO,WAAA,CAAY,SAAS,MAAM,CAAA;AAAA,IACpC,CAAC,CAAA;AACD,IAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,OAAA;AAC/B,IAAA,OAAA,CAAQ,IAAA,CAAK,GAAG,KAAK,CAAA;AAAA,EACvB;AACF;;;ACwDA,IAAM,YAAA,GAA0B;AAAA,EAC9B,KAAA,EAAO,MAAA;AAAA,EACP,UAAA,EAAY,KAAA;AAAA,EACZ,OAAO,EAAC;AAAA,EACR,UAAA,EAAY,EAAA;AAAA,EACZ,MAAA,EAAQ,IAAA;AAAA,EACR,UAAA,EAAY;AACd,CAAA;AAEO,SAAS,OAAA,CAAQ,EAAE,IAAA,EAAK,EAA4B;AACzD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAoB,YAAY,CAAA;AAG1D,EAAA,MAAM,eAAA,GAAkB,OAAO,KAAK,CAAA;AAIpC,EAAA,MAAM,cAAA,GAAiB,OAAyB,IAAI,CAAA;AACpD,EAAA,MAAM,aAAA,GAAgB,OAAyB,IAAI,CAAA;AAEnD,EAAA,MAAM,YAAA,GAAe,MAAM,KAAA,KAAU,YAAA;AACrC,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,KAAU,OAAA;AACjC,EAAA,MAAM,aAAA,GAAgB,KAAA,CAAM,KAAA,KAAU,MAAA,IAAU,MAAM,KAAA,KAAU,OAAA;AAEhE,EAAA,MAAM,UAAA,GAAa,OAAA;AAAA,IACjB,MAAM,MAAM,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW,oBAAA,CAAqB,KAAK,CAAA;AAAA,IACvE,CAAC,MAAM,KAAK;AAAA,GACd;AAEA,EAAA,MAAM,iBAAA,GAAoB,WAAA,CAAY,MAAM,UAAA,CAAW,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AAEvF,EAAA,MAAMO,aAAAA,GAAe,WAAA;AAAA,IACnB,OAAO,QAAA,KAAqB;AAC1B,MAAA,IAAI,gBAAgB,OAAA,EAAS;AAC3B,QAAA,OAAA,CAAQ,KAAK,+DAA+D,CAAA;AAC5E,QAAA;AAAA,MACF;AACA,MAAA,IAAI,CAAC,QAAA,IAAY,QAAA,CAAS,MAAA,KAAW,CAAA,EAAG;AAExC,MAAA,eAAA,CAAgB,OAAA,GAAU,IAAA;AAC1B,MAAA,QAAA,CAAS;AAAA,QACP,GAAG,YAAA;AAAA,QACH,KAAA,EAAO,YAAA;AAAA,QACP,MAAA,EAAQ,EAAE,KAAA,EAAO,eAAA,EAAiB,SAAS,iCAAA;AAAkC,OAC9E,CAAA;AAED,MAAA,IAAI;AACF,QAAA,MAAM,OAAA,GAAU,MAAM,YAAA,CAAY,QAAA,EAAU;AAAA,UAC1C,MAAA,EAAQ,MAAM,IAAA,CAAK,SAAA,EAAU;AAAA,UAC7B,QAAA,EAAU,CAAC,MAAA,KAAW,QAAA,CAAS,CAAC,UAAU,EAAE,GAAG,IAAA,EAAM,MAAA,EAAO,CAAE;AAAA,SAC/D,CAAA;AAED,QAAA,QAAA,CAAS;AAAA,UACP,OAAO,OAAA,CAAQ,KAAA;AAAA,UACf,UAAA,EAAY,KAAA;AAAA,UACZ,OAAO,OAAA,CAAQ,KAAA;AAAA,UACf,YAAY,OAAA,CAAQ,UAAA;AAAA,UACpB,QAAQ,OAAA,CAAQ,MAAA;AAAA,UAChB,YAAY,OAAA,CAAQ;AAAA,SACrB,CAAA;AAAA,MACH,CAAA,SAAE;AACA,QAAA,eAAA,CAAgB,OAAA,GAAU,KAAA;AAAA,MAC5B;AAAA,IACF,CAAA;AAAA,IACA,CAAC,IAAI;AAAA,GACP;AAEA,EAAA,MAAM,KAAA,GAAQ,YAAY,MAAM;AAC9B,IAAA,QAAA,CAAS,YAAY,CAAA;AACrB,IAAA,eAAA,CAAgB,OAAA,GAAU,KAAA;AAAA,EAC5B,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,MAAM,cAAA,GAAiB,WAAA,CAAY,CAAC,CAAA,KAAuB;AACzD,IAAA,CAAA,CAAE,cAAA,EAAe;AACjB,IAAA,QAAA,CAAS,CAAC,IAAA,KAAU,IAAA,CAAK,UAAA,GAAa,IAAA,GAAO,EAAE,GAAG,IAAA,EAAM,UAAA,EAAY,IAAA,EAAO,CAAA;AAAA,EAC7E,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,eAAA,GAAkB,WAAA,CAAY,CAAC,CAAA,KAAuB;AAC1D,IAAA,CAAA,CAAE,cAAA,EAAe;AACjB,IAAA,QAAA,CAAS,CAAC,IAAA,KAAU,IAAA,CAAK,UAAA,GAAa,EAAE,GAAG,IAAA,EAAM,UAAA,EAAY,KAAA,EAAM,GAAI,IAAK,CAAA;AAAA,EAC9E,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,UAAA,GAAa,WAAA;AAAA,IACjB,OAAO,CAAA,KAAuB;AAC5B,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,QAAA,CAAS,CAAC,IAAA,KAAU,IAAA,CAAK,UAAA,GAAa,EAAE,GAAG,IAAA,EAAM,UAAA,EAAY,KAAA,EAAM,GAAI,IAAK,CAAA;AAE5E,MAAA,MAAM,QAAgB,EAAC;AACvB,MAAA,MAAM,cAA0D,EAAC;AAKjE,MAAA,KAAA,MAAW,QAAQ,KAAA,CAAM,IAAA,CAAK,CAAA,CAAE,YAAA,CAAa,KAAK,CAAA,EAAG;AACnD,QAAA,IAAI,IAAA,CAAK,SAAS,MAAA,EAAQ;AAC1B,QAAA,IAAI;AACF,UAAA,MAAM,KAAA,GAAQ,KAAK,gBAAA,IAAmB;AACtC,UAAA,IAAI,OAAO,WAAA,EAAa;AACtB,YAAA,WAAA,CAAY,KAAK,EAAE,KAAA,EAAO,IAAA,EAAM,KAAA,CAAM,MAAM,CAAA;AAAA,UAC9C,CAAA,MAAO;AACL,YAAA,MAAM,IAAA,GAAO,KAAK,SAAA,EAAU;AAC5B,YAAA,IAAI,IAAA,EAAM;AAER,cAAA,eAAA,CAAgB,IAAA,EAAM,KAAK,IAAI,CAAA;AAC/B,cAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,YACjB;AAAA,UACF;AAAA,QACF,SAAS,KAAA,EAAO;AACd,UAAA,OAAA,CAAQ,IAAA,CAAK,+BAA+B,KAAK,CAAA;AACjD,UAAA,MAAM,IAAA,GAAO,KAAK,SAAA,EAAU;AAC5B,UAAA,IAAI,IAAA,EAAM,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA;AAAA,QAC3B;AAAA,MACF;AAEA,MAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,WAAA,CAAY,GAAA,CAAI,CAAC,CAAA,KAAM,gBAAA,CAAiB,CAAA,CAAE,KAAA,EAAO,KAAA,EAAO,CAAA,CAAE,IAAI,CAAC,CAAC,CAAA;AAGlF,MAAA,IAAI,MAAM,MAAA,KAAW,CAAA,IAAK,EAAE,YAAA,CAAa,KAAA,CAAM,SAAS,CAAA,EAAG;AACzD,QAAA,KAAA,CAAM,KAAK,GAAG,KAAA,CAAM,KAAK,CAAA,CAAE,YAAA,CAAa,KAAK,CAAC,CAAA;AAAA,MAChD;AAEA,MAAA,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,MAAMA,cAAa,KAAK,CAAA;AAAA,IAChD,CAAA;AAAA,IACA,CAACA,aAAY;AAAA,GACf;AAEA,EAAA,MAAM,iBAAA,GAAoB,WAAA;AAAA,IACxB,CAAC,CAAA,KAA2C;AAC1C,MAAA,MAAM,QAAQ,KAAA,CAAM,IAAA,CAAK,EAAE,MAAA,CAAO,KAAA,IAAS,EAAE,CAAA;AAC7C,MAAA,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAGA,cAAa,KAAK,CAAA;AAExC,MAAA,CAAA,CAAE,OAAO,KAAA,GAAQ,EAAA;AAAA,IACnB,CAAA;AAAA,IACA,CAACA,aAAY;AAAA,GACf;AAIA,EAAA,MAAM,IAAA,GAAO,WAAA,CAAY,CAAC,IAAA,KAAsB;AAC9C,IAAA,MAAM,KAAA,GAAQ,IAAA,KAAS,OAAA,GAAU,aAAA,CAAc,UAAU,cAAA,CAAe,OAAA;AACxE,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN,CAAA,GAAA,EAAM,SAAS,OAAA,GAAU,OAAA,GAAU,QAAQ,CAAA,yCAAA,EAA4C,IAAA,KAAS,OAAA,GAAU,OAAA,GAAU,QAAQ,CAAA,uCAAA;AAAA,OAC9H;AACA,MAAA;AAAA,IACF;AACA,IAAA,KAAA,CAAM,KAAA,EAAM;AAAA,EACd,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,gBAAA,GAAmB,WAAA;AAAA,IACvB,CAAC,OAAA,KAAmC;AAClC,MAAA,MAAM,EAAE,SAAA,GAAY,IAAA,EAAK,GAAI,WAAW,EAAC;AACzC,MAAA,OAAO;AAAA,QACL,UAAA,EAAY,cAAA;AAAA,QACZ,WAAA,EAAa,eAAA;AAAA,QACb,MAAA,EAAQ,UAAA;AAAA;AAAA;AAAA,QAGR,GAAI,SAAA,IAAa,EAAE,OAAA,EAAS,MAAM,MAAK;AAAE,OAC3C;AAAA,IACF,CAAA;AAAA,IACA,CAAC,cAAA,EAAgB,eAAA,EAAiB,UAAA,EAAY,IAAI;AAAA,GACpD;AAEA,EAAA,MAAM,aAAA,GAAgB,WAAA;AAAA,IACpB,CAAC,IAAA,MAAuC;AAAA,MACtC,GAAA,EAAK,IAAA,KAAS,OAAA,GAAU,aAAA,GAAgB,cAAA;AAAA,MACxC,IAAA,EAAM,MAAA;AAAA,MACN,KAAA,EAAO,EAAE,OAAA,EAAS,MAAA,EAAO;AAAA,MACzB,QAAA,EAAU,IAAA;AAAA,MACV,GAAI,SAAS,OAAA,GAAU,EAAE,QAAQ,eAAA,EAAgB,GAAI,EAAE,eAAA,EAAiB,EAAA,EAAG;AAAA,MAC3E,QAAA,EAAU;AAAA,KACZ,CAAA;AAAA,IACA,CAAC,iBAAiB;AAAA,GACpB;AAEA,EAAA,OAAO;AAAA,IACL,OAAO,KAAA,CAAM,KAAA;AAAA,IACb,YAAA;AAAA,IACA,YAAY,KAAA,CAAM,UAAA;AAAA,IAClB,aAAA;AAAA,IACA,QAAA;AAAA,IACA,OAAO,KAAA,CAAM,KAAA;AAAA,IACb,YAAY,KAAA,CAAM,UAAA;AAAA,IAClB,QAAQ,KAAA,CAAM,MAAA;AAAA,IACd,YAAY,KAAA,CAAM,UAAA;AAAA,IAElB,gBAAA;AAAA,IACA,aAAA;AAAA,IAEA,IAAA;AAAA,IACA,YAAA,EAAAA,aAAAA;AAAA,IACA,KAAA;AAAA,IAEA,UAAA;AAAA,IACA;AAAA,GACF;AACF","file":"index.js","sourcesContent":["/**\n * @file Shared TypeScript types, constants, and utilities for the ShipStatic platform.\n * This package is the single source of truth for all shared data structures.\n */\n// =============================================================================\n// DEPLOYMENT TYPES\n// =============================================================================\n/**\n * Deployment status constants\n */\nexport const DeploymentStatus = {\n PENDING: 'pending',\n SUCCESS: 'success',\n FAILED: 'failed',\n DELETING: 'deleting',\n};\n/**\n * Where a deployment came from — the origin-tracking vocabulary.\n *\n * A closed set with many authors. It lived in the API's config until\n * 2026-08-06, where being server-side made it unenforceable in the one\n * direction that matters — every client wrote a bare string, and a value\n * outside the set was **silently dropped** by the server, so a typo did not\n * fail anywhere. It stopped recording where deploys came from and said nothing.\n *\n * **The origin law: origin is declared by whatever we control — our code where\n * we ship code, our URL where we ship only a URL.** One rule decides every\n * member here and every future one:\n *\n * - **Where the platform ships CODE, the code declares it.** `web`, `sdk`,\n * `cli`, `git`, `n8n` and `vsc` are surfaces this platform authors, so each\n * names itself in its own source and nothing external is needed to tell them\n * apart.\n * - **Where the platform ships only a URL, the URL declares it.** A\n * marketplace listing runs somebody else's client against a bare endpoint —\n * every one of them the same server speaking the same protocol, and\n * indistinguishable in a request. The only thing such a listing's traffic\n * has in common is the URL its users were handed, so the hosted MCP serves\n * one DOOR per listing and the door's path IS the value: `gpt`, `cld`,\n * `crs`.\n *\n * **A member names the most specific surface the platform can honestly\n * claim**, which is what makes the two FALLBACKS fallbacks rather than peers\n * of the named surfaces. `mcp` is any MCP host that was never handed a door of\n * its own; `api` is a call that reached the REST API naming nothing at all.\n * Guessing past either would be inventing attribution rather than recording\n * it, which is the one thing this vocabulary exists to prevent.\n *\n * Every member is three lowercase characters — the property that lets a\n * channel door's path and its attribution be spelled the same. The suite pins\n * both the width and the channel members by name.\n */\nexport const DeploymentVia = {\n /** The web dashboard. */\n WEB: 'web',\n /** A program embedding the SDK directly. */\n SDK: 'sdk',\n /** The `ship` CLI. */\n CLI: 'cli',\n /** Any MCP host with no door of its own — the stdio server included. The family fallback. */\n MCP: 'mcp',\n /** The GitHub Action. */\n GIT: 'git',\n /** The n8n community node. */\n N8N: 'n8n',\n /** Channel: the ChatGPT App listing → `mcp.<domain>/gpt`. */\n GPT: 'gpt',\n /** The VS Code extension. */\n VSC: 'vsc',\n /** Channel: the Claude connectors directory listing → `mcp.<domain>/cld`. */\n CLD: 'cld',\n /** Channel: the Cursor marketplace listing → `mcp.<domain>/crs`. */\n CRS: 'crs',\n /**\n * A deploy that reached the REST API naming no origin at all — the\n * platform-wide fallback, one altitude below `mcp`'s family fallback.\n *\n * **The API stamps it, since 2026-08-15.** A deploy that names no origin —\n * or names one this vocabulary does not know — is stored as `api`, so a\n * stored `null` now means only that the row predates attribution.\n *\n * It was declared one wave ahead of that decision, deliberately: vocabulary\n * must exist before a consumer can adopt it, and adding a member costs a\n * full constellation convoy, so the word shipped first and the server\n * adopted it with no convoy standing between the decision and the deploy.\n */\n API: 'api',\n};\n// =============================================================================\n// DOMAIN TYPES\n// =============================================================================\n/**\n * Domain status constants\n *\n * - PENDING: DNS not configured\n * - PARTIAL: DNS partially configured\n * - SUCCESS: DNS fully verified\n * - PAUSED: Domain paused due to plan enforcement (billing)\n */\nexport const DomainStatus = {\n PENDING: 'pending',\n PARTIAL: 'partial',\n SUCCESS: 'success',\n PAUSED: 'paused',\n};\n/**\n * The envelope an `Idempotency-Key` must fit, and how long a replay lasts.\n *\n * Format lives here rather than on the server alone by the format-vs-policy\n * rule: a client can decide offline whether a key is well-formed, and the\n * API would reject the same value the same way.\n */\nexport const IDEMPOTENCY_KEY_CONSTRAINTS = {\n /**\n * HTTP header name. Here for the same reason {@link CALLER.HEADER} is: a\n * wire header has two ends, and the package that owns the value's format\n * is the only place both ends can read its name from.\n */\n HEADER: 'Idempotency-Key',\n MAX_LENGTH: 256,\n /** How long a stored 201 stays replayable. */\n WINDOW_SECONDS: 24 * 60 * 60,\n};\n/**\n * Normalize a `via` value from any transport — trimmed, lowercased, and a\n * member of {@link DeploymentVia}, or `undefined`.\n *\n * A format rule by this package's own test: a client can decide offline\n * whether a value is well-formed, and the API reaches the same verdict on the\n * same input. It lived server-side until 2026-08-06, which meant clients could\n * only learn their label was unusable by noticing analytics had gone quiet.\n *\n * **Not knowing your `via` is not an error** — an unrecognized value yields\n * `undefined` rather than throwing, because origin tracking is telemetry and a\n * deploy must never fail over it. A caller that has an honest default should\n * prefer it (`normalizeVia(process.env.SHIP_VIA) ?? DeploymentVia.CLI`): the\n * deploy really did come from the CLI, so recording that beats recording\n * nothing.\n */\nexport function normalizeVia(value) {\n if (!value || typeof value !== 'string')\n return undefined;\n const via = value.trim().toLowerCase();\n return Object.values(DeploymentVia).includes(via)\n ? via\n : undefined;\n}\n/**\n * Validate an idempotency key, returning the trimmed value or `undefined`\n * when none was supplied. Throws {@link ShipError.validation} when the value\n * cannot be sent — the same verdict the API would reach, reached earlier.\n */\nexport function validateIdempotencyKey(value) {\n if (value === undefined || value === null)\n return undefined;\n if (typeof value !== 'string') {\n throw ShipError.validation('Idempotency key must be a string.');\n }\n const key = value.trim();\n if (!key) {\n throw ShipError.validation('Idempotency key must not be empty.');\n }\n if (key.length > IDEMPOTENCY_KEY_CONSTRAINTS.MAX_LENGTH) {\n throw ShipError.validation(`Idempotency key must be at most ${IDEMPOTENCY_KEY_CONSTRAINTS.MAX_LENGTH} characters.`);\n }\n return key;\n}\n// =============================================================================\n// ACCOUNT TYPES\n// =============================================================================\n/**\n * Account plan constants\n */\nexport const AccountPlan = {\n FREE: 'free',\n STANDARD: 'standard',\n SPONSORED: 'sponsored',\n ENTERPRISE: 'enterprise',\n SUSPENDED: 'suspended',\n TERMINATING: 'terminating',\n TERMINATED: 'terminated',\n};\n// =============================================================================\n// WIRE SURFACE\n// =============================================================================\n/**\n * Every path the public API answers on, declared once.\n *\n * The URL surface was written out in four places — the API's mounts, the\n * SDK's client, the dashboard's client, and the post-deploy smoke — so a\n * rename meant finding all four. The first three now read this table.\n *\n * The smoke (`cloudflare/api/smoke.mjs`) deliberately still spells its own:\n * five of its nine paths are `/admin/*`, which this table excludes by\n * design, and splitting one list between a registry and literals reads worse\n * than keeping it uniform.\n *\n * **What this guarantees, exactly.** Collection paths are mounted from here,\n * so producer and consumer cannot diverge. Item paths are declared here and\n * consumed by clients, but the API spells them relative to their mount\n * (`/:deployment/config`), so the table does not *generate* them — it is\n * held to them by `api/tests/architecture/api-paths.test.ts`, which fails if\n * any entry names a path no route answers. Some entries have no client yet\n * (`DEPLOYMENT_CONFIG`, `DOMAIN_PROPAGATION` — endpoints the SDK\n * deliberately does not reach); the fence is what keeps those honest rather\n * than merely asserted.\n *\n * **The operator surface is deliberately absent.** `/admin/*` paths belong\n * to `web/my`, for the same reason its row types do: this package is\n * published, and the operator surface is not public (see `CLAUDE.md`, \"Admin\n * types\"). A path here is a promise to every npm consumer; `/admin` is a\n * promise to one dashboard.\n *\n * Item paths are functions rather than templates so the key is interpolated\n * in one place, encoded the same way by every caller.\n */\nexport const API_PATHS = {\n DEPLOYMENTS: '/deployments',\n DEPLOYMENT: (deployment) => `/deployments/${deployment}`,\n DEPLOYMENT_CONFIG: (deployment) => `/deployments/${deployment}/config`,\n DOMAINS: '/domains',\n DOMAIN: (domain) => `/domains/${domain}`,\n DOMAIN_VERIFY: (domain) => `/domains/${domain}/verify`,\n DOMAIN_DNS: (domain) => `/domains/${domain}/dns`,\n DOMAIN_RECORDS: (domain) => `/domains/${domain}/records`,\n DOMAIN_SHARE: (domain) => `/domains/${domain}/share`,\n DOMAIN_PROPAGATION: (domain) => `/domains/${domain}/propagation`,\n DOMAINS_VALIDATE: '/domains/validate',\n TOKENS: '/tokens',\n TOKEN: (token) => `/tokens/${token}`,\n ACCOUNT: '/account',\n ACCOUNT_KEY: '/account/key',\n ACCOUNT_CLAIM: '/account/claim',\n ACTIVITIES: '/activities',\n LABELS: '/labels',\n LIMITS: '/limits',\n PING: '/ping',\n SETUP: '/setup',\n SPA_CHECK: '/spa-check',\n UPLOAD: '/upload',\n};\n/**\n * The deploy request's multipart field names — the other half of the wire\n * surface beside {@link API_PATHS}. `POST /deployments` (and the first-party\n * `/upload`) is multipart/form-data, and these are the names the API reads.\n *\n * Declared once because the body has three independent WRITERS — the SDK's\n * Node and browser body builders, and the n8n community node's hand-rolled\n * client (which cannot import this under n8n Cloud's zero-dependency rule,\n * and fences its restated copy instead) — and until this export every writer\n * restated the strings the API parses, with nothing comparing them.\n *\n * `FILES` carries one entry per file (the API reads it with `getAll`); every\n * other field is single. The `@internal` flags are serialized as the literal\n * string `'true'` and belong to first-party surfaces only.\n */\nexport const DEPLOY_FIELDS = {\n /** One entry per file — read with `getAll`. */\n FILES: 'files[]',\n /** JSON array of MD5 hex digests, index-aligned with `FILES`. */\n CHECKSUMS: 'checksums',\n /** JSON array of label strings. */\n LABELS: 'labels',\n /** The deploying surface's {@link DeploymentVia} member. */\n VIA: 'via',\n /** Plaintext password — the API hashes it server-side. */\n PASSWORD: 'password',\n /**\n * Requested lifetime in SECONDS — a duration, never an instant. The API\n * computes and stores the expiry, so the wire carries no client clock.\n * See {@link validateTtl}.\n */\n TTL: 'ttl',\n /** @internal Server-processing flag — first-party `/upload` only. */\n BUILD: 'build',\n /** @internal Server-processing flag — first-party `/upload` only. */\n PRERENDER: 'prerender',\n /** @internal Server-processing flag — first-party `/upload` only. */\n SPA: 'spa',\n /** @internal reCAPTCHA proof — `web/www`'s public uploader only. */\n CAPTCHA: 'captcha',\n};\n// =============================================================================\n// ERROR SYSTEM\n// =============================================================================\n/**\n * All possible error types in the ShipStatic platform.\n *\n * Developer-friendly key names map to stable wire-format string values.\n * Both the value and the type are exported under the same name so callers\n * can use `ErrorType.Validation` (value comparison) and `: ErrorType` (type\n * annotation) without ceremony — matching the pattern other status objects\n * (`DeploymentStatus`, `DomainStatus`, `AccountPlan`, `AuthMethod`) follow.\n */\nexport const ErrorType = {\n /**\n * Validation failed. Input shape is wrong.\n *\n * Carries 400 when an API judged it — including a client-side pre-check of a\n * rule the server enforces too, which keeps the error identical wherever it\n * was caught. **Statusless** when a client rejects something no API judges,\n * such as a CLI's own command grammar: `status` is documented \"(API\n * contexts)\" on `ErrorResponse`, so there is none to report.\n */\n Validation: 'validation_failed',\n /** Resource not found (404). */\n NotFound: 'not_found',\n /** Authenticated but not allowed (403). User lacks permission for this action. */\n Forbidden: 'forbidden',\n /** Rate limit exceeded (429). */\n RateLimit: 'rate_limit_exceeded',\n /** Authentication required or failed (401). Missing/invalid credentials. */\n Authentication: 'authentication_failed',\n /** Business rule violation. Catch-all for 4xx state-rule errors that aren't more specific. */\n Business: 'business_logic_error',\n /** API server error (500). Generic server-side fault. */\n Api: 'internal_server_error',\n /**\n * The platform is closed for maintenance (503). A deliberate operator\n * state, not a fault — nothing errored; the API is refusing work on\n * purpose, and deployed sites keep serving throughout.\n *\n * Distinct from `Api` at 503, which the platform already uses for a\n * dependency that failed (moderation unavailable). A consumer has to tell\n * \"we closed the door\" from \"something broke\": the two get opposite words\n * and opposite retry behaviour.\n */\n Maintenance: 'maintenance',\n /** Network/connection error. Client-side only — set by HTTP clients on fetch failure; never produced server-side. */\n Network: 'network_error',\n /**\n * A deadline expired before the exchange completed. Client-side only — set\n * by HTTP clients when a timeout signal fires; never produced server-side.\n *\n * A member of the NETWORK category rather than a sibling of it:\n * `isNetworkError()` answers \"nothing was exchanged\", which is true of a\n * deadline exactly as it is of a refused connection, so every consumer that\n * retries, declines to report, or declines to relay a wire message on that\n * category is already right about a timeout. The distinct TYPE exists for\n * the one decision the category cannot make — what to SAY. \"Check your\n * internet connection\" is the wrong sentence for a five-minute deploy\n * ceiling, and a surface can only tell the two apart by type.\n *\n * The same relationship every comparable SDK ships:\n * `APIConnectionTimeoutError extends APIConnectionError`.\n */\n Timeout: 'timeout_error',\n /** Operation was cancelled. Client-side only — set on `AbortSignal` abort; never produced server-side. */\n Cancelled: 'operation_cancelled',\n /** File operation error. Client-side only — set by SDK during local file processing; never produced server-side. */\n File: 'file_error',\n /** Configuration error. Client-side only — set by SDK during config parsing/validation; never produced server-side. */\n Config: 'config_error',\n};\n/**\n * Error types that originate exclusively on the client (HTTP clients, SDK\n * file processing, local config parsing). These never appear on the wire\n * from the server, so `fromHttpResponse` will not trust them even if a\n * misbehaving server claims one in `body.error`.\n */\nconst CLIENT_ONLY_ERROR_TYPES = new Set([\n ErrorType.Network,\n ErrorType.Timeout,\n ErrorType.Cancelled,\n ErrorType.File,\n ErrorType.Config,\n]);\n/**\n * Categorizes error types for the `isClientError` / `isNetworkError` /\n * `isAuthError` helpers. Each `Set` is typed against the wider `ErrorType`\n * union so `.has(error.type)` accepts any value from the union.\n */\nconst ERROR_CATEGORIES = {\n /**\n * Client-attributable types. Exhaustive over the 4xx-carrying types, and\n * over the statusless ones too — those are raised locally and have no\n * status for `isClientError`'s second arm to read, so omitting one makes it\n * read as a server fault. The rule is the membership test: every type in\n * `CLIENT_ONLY_ERROR_TYPES` except the two `isNetworkError` owns belongs\n * here.\n *\n * `Cancelled` was missing until 2026-07-29, which is exactly that failure:\n * a caller who aborted their own deploy was told \"server error: please try\n * again\" — the CLI's fallback for everything this set does not claim.\n *\n * `Timeout` is deliberately NOT here, and it is the sharper case, because\n * it is the one client-only type that is not the client's fault: the\n * caller set a ceiling, but what exhausted it was the network or the\n * server. Reading it as client-attributable would say the caller erred,\n * and it would silently disarm every consumer whose retry predicate\n * declines `isClientError()` — a deadline is precisely the failure worth\n * a second attempt.\n */\n client: new Set([\n ErrorType.Business,\n ErrorType.Cancelled,\n ErrorType.Config,\n ErrorType.File,\n ErrorType.Forbidden,\n ErrorType.NotFound,\n ErrorType.RateLimit,\n ErrorType.Validation,\n ]),\n /**\n * The exchange never happened. Two types, one category: a refused\n * connection and an expired deadline differ in what a surface should SAY\n * and in nothing else a consumer decides on — both are retryable, neither\n * carries a wire message to relay, neither is worth reporting as an\n * incident. See `ErrorType.Timeout` for why the type is distinct anyway.\n */\n network: new Set([ErrorType.Network, ErrorType.Timeout]),\n auth: new Set([ErrorType.Authentication]),\n};\n/**\n * Error types the server can legitimately produce on the wire. Used by\n * `ShipError.fromHttpResponse` to validate the body's `error` field before\n * trusting it as `ShipError.type`. Derived by exclusion from\n * `CLIENT_ONLY_ERROR_TYPES` so adding a new server-producible type to\n * `ErrorType` is automatically picked up.\n */\nconst SERVER_PRODUCIBLE_ERROR_TYPES = new Set(Object.values(ErrorType).filter((t) => !CLIENT_ONLY_ERROR_TYPES.has(t)));\n/**\n * Ceiling on a message adopted from a **non-JSON** error body — a foreign\n * responder's, never this platform's. Generous for the plain-text one-liners\n * intermediaries actually send (`error code: 1015`), far below a document.\n * Our own messages are never measured against it: a JSON body is the API's\n * contract, and truncating a long validation message would be the bug.\n */\nconst MAX_FOREIGN_MESSAGE_LENGTH = 200;\n/**\n * Did the runtime say the exchange never completed?\n *\n * Clients branch on the TYPE, never on message strings, so a misclassified\n * transport failure is a lie every consumer inherits — and the one that costs\n * most: `Api` claims a server answered when nothing was exchanged, and a\n * retrying caller will not retry it.\n *\n * **Every row below is a transcript, not a belief.** Captured 2026-08-12\n * against real runtimes — Node and Bun by direct run, the three engines by a\n * one-off playwright probe, workerd through miniflare. The capture scripts are\n * in `tests/errors.test.ts`, \"runtime failure shapes\".\n *\n * | runtime | connection refused / DNS failure | malformed URL |\n * |------------------|------------------------------------------------------|--------------------------------------------------|\n * | Node 22 / undici | `TypeError: fetch failed` | `TypeError: Failed to parse URL from …` |\n * | Bun 1.3.14 | `Error` `code:'ConnectionRefused'` | `TypeError` `code:'ERR_INVALID_URL'` |\n * | Chromium 151 | `TypeError: Failed to fetch` | `TypeError: …Failed to parse URL from …` |\n * | Firefox 153 | `TypeError: NetworkError when attempting to fetch …` | `TypeError: … is not a valid URL.` |\n * | WebKit 26.5 | `TypeError: Load failed` | `TypeError: URL is not valid or contains user …` |\n * | workerd | `Error: Network connection lost.` (DNS: `internal error; reference = …`) | `TypeError: Invalid URL: …` |\n *\n * Reading that table gives the rule, and it is the INVERSE of the obvious one.\n * The transport class is unbounded — every OS, TLS and DNS failure any engine\n * will ever name — while the class fetch raises for its own ARGUMENTS is\n * small, and every runtime names the URL when it complains about one. So the\n * bounded side is the one worth testing, and the residual risk points the safe\n * way: an unrecognised sentence lands on `Network`, which says only that\n * nothing was exchanged.\n *\n * That inversion is what fixes **WebKit**, whose `Load failed` carries no code\n * and no \"fetch\", and which every browser-SDK and `@shipstatic/drop` user on\n * Safari was hitting as `Api`. It also makes the six runtimes AGREE about a\n * malformed URL, which they did not before: the previous rule tested the\n * message for \"fetch\", and Chromium's and Firefox's URL complaints both\n * contain it, so the same mistake was `Network` on three engines and `Api` on\n * three.\n *\n * **workerd is the recorded gap.** It rejects with a plain `Error`, no code\n * and no shared sentence — and its two failure modes produce two unrelated\n * ones — so nothing here can classify it and it lands on `Api`. Left alone\n * rather than patched with a dialect string: the one consumer running ship in\n * that runtime (`cloudflare/mcp`) reaches the API through a service BINDING,\n * which is in-process and does not produce transport rejections at all.\n *\n * **The `TokenProvider` case stopped being a trade when clients gained\n * retries.** A caller's provider that throws a coded error is typed `Network`\n * here, which was recorded as \"both are wrong for it; `Network` is the cheaper\n * wrong\" — written when the classification decided only what a surface would\n * SAY. It now also decides whether the call is retried, and that turns the\n * cheaper wrong into the right answer: a `TokenProvider` is where minting and\n * refresh live, so the common one is an OAuth refresh over the network, and a\n * transient failure there is precisely what another attempt repairs.\n *\n * The residual cost is a deterministic provider fault — a genuinely missing\n * keychain entry — invoking the provider three times over a few hundred\n * milliseconds before failing with the same error. No request leaves the\n * process on any of them. That is the cheap direction of a bet whose other\n * side is a refused deploy, and suppressing it would need a way to mark\n * credential faults non-retryable: machinery with one holder, refused by the\n * estate's stopping rule. Provider failures that carry no code are `Api` and\n * are not retried at all, and a provider yielding nothing is `Authentication`\n * by the fail-closed invariant, which is likewise terminal.\n */\nfunction isTransportFailure(cause) {\n const code = cause.code;\n // Bun is the one runtime that puts a CODE on an argument error, so it is\n // excluded before the code arm can claim it.\n if (code === 'ERR_INVALID_URL')\n return false;\n // A string `code` is a runtime naming a transport-level failure. An\n // allowlist of codes was written first and rejected — the TLS row alone\n // would mean enumerating BoringSSL's certificate table, and a code nobody\n // guessed is precisely the bug this closes. A `DOMException`'s code is a\n // NUMBER, so aborts and timeouts never reach here.\n if (typeof code === 'string')\n return true;\n // WHATWG has fetch reject with a TypeError for BOTH halves — network error\n // and argument error — so among TypeErrors the URL is the discriminator.\n if (cause instanceof TypeError)\n return !/\\burl\\b/i.test(cause.message);\n // Anything else — an ordinary JS fault, or workerd — is not evidence.\n return false;\n}\n/**\n * Simple unified error class for both API and SDK\n */\nexport class ShipError extends Error {\n type;\n status;\n details;\n constructor(type, message, status, details) {\n super(message);\n this.type = type;\n this.status = status;\n this.details = details;\n this.name = 'ShipError';\n }\n /** Convert to wire format */\n toResponse() {\n // Strip authentication details when they carry an `internal` telemetry\n // tag (see `ShipError.authentication` JSDoc) — these are server-side\n // diagnostics like 'session_invalid' that must not leak to clients.\n const authDetails = this.details;\n const details = this.type === ErrorType.Authentication && authDetails?.internal ? undefined : this.details;\n return {\n error: this.type,\n message: this.message,\n status: this.status,\n details,\n };\n }\n /**\n * Construct a `ShipError` from an HTTP error response.\n *\n * Best-effort body parse for `{ message, error?, details? }`. Message\n * resolution: `body.message` → `body.error` → `\"<operationName> failed with\n * status <N>\"`.\n *\n * Type resolution: trusts `body.error` when it's a known server-producible\n * `ErrorType` (preserves the wire's intent — server's\n * `ShipError.validation(...)` round-trips back to `ErrorType.Validation`\n * on the client). Falls back to status-derived (401 → Authentication,\n * 403 → Forbidden, 429 → RateLimit, else → Api) for non-API responses\n * (CDN errors, intermediaries) or malformed bodies. Client-only types\n * (`Network`, `Timeout`, `Cancelled`, `File`, `Config`) are filtered out of the\n * trusted set — a misbehaving server claiming one of those is ignored.\n *\n * `operationName` (e.g. `\"Get account\"`) is used to compose the fallback\n * message. Defaults to `\"Request\"`. Same convention as `fromFetchError`.\n *\n * Async because it reads the response body. Returns rather than throws so\n * callers can compose; most will `throw await ShipError.fromHttpResponse(...)`.\n */\n static async fromHttpResponse(response, operationName) {\n let message;\n let details;\n let bodyType;\n try {\n const contentType = response.headers.get('content-type');\n if (contentType?.includes('application/json')) {\n const json = await response.json();\n if (json && typeof json === 'object') {\n const obj = json;\n if (typeof obj.message === 'string')\n message = obj.message;\n else if (typeof obj.error === 'string')\n message = obj.error;\n details = obj.details;\n if (typeof obj.error === 'string' && SERVER_PRODUCIBLE_ERROR_TYPES.has(obj.error)) {\n bodyType = obj.error;\n }\n }\n }\n else {\n // A non-JSON body did not come from this platform — every API error\n // is `ErrorResponse` JSON — so it is an intermediary's output, and\n // the two kinds it produces need opposite treatment. A CDN's plain\n // `error code: 1015` is the most useful thing there is to say. A\n // proxy's HTML error page is a *document*, not a message: adopting it\n // verbatim made a misconfigured `apiUrl` print 2,059 characters of\n // markup as the error. Trust it only when it reads as a message.\n const text = (await response.text()).trim();\n if (text && !text.startsWith('<') && text.length <= MAX_FOREIGN_MESSAGE_LENGTH) {\n message = text;\n }\n }\n }\n catch {\n // Body unreadable; fall through to operationName-derived message.\n }\n // Rate-limit (and 503) timing rides the `Retry-After` HEADER, which a\n // body-only reader would drop. Lift it into `details` as seconds so\n // consumers can back off from the typed error alone, without keeping the\n // raw Response around. Body-carried fields are preserved and win.\n const retryAfterHeader = response.headers.get('retry-after');\n if (retryAfterHeader !== null) {\n const value = retryAfterHeader.trim();\n const seconds = /^\\d+$/.test(value)\n ? Number(value)\n : Math.ceil((Date.parse(value) - Date.now()) / 1000);\n if (Number.isFinite(seconds) && seconds >= 0) {\n const existing = details && typeof details === 'object' ? details : {};\n if (existing.retryAfter === undefined) {\n details = { ...existing, retryAfter: seconds };\n }\n }\n }\n message = message || `${operationName || 'Request'} failed with status ${response.status}`;\n const type = bodyType ??\n (response.status === 401\n ? ErrorType.Authentication\n : response.status === 403\n ? ErrorType.Forbidden\n : response.status === 429\n ? ErrorType.RateLimit\n : ErrorType.Api);\n return new ShipError(type, message, response.status, details);\n }\n /**\n * Construct a `ShipError` from an error caught around a `fetch()` call.\n *\n * The mirror of `fromHttpResponse` for the *other* side of the HTTP error\n * story — the network layer failing (offline, CORS, abort) rather than the\n * server returning a non-OK response.\n *\n * Routing:\n * - Already a `ShipError` → returned as-is (caller's intent preserved)\n * - `AbortError` → `ShipError.cancelled(...)` — someone stopped it on purpose\n * - `TimeoutError` → `ShipError.timeout(...)` — a deadline expired; the\n * message names the timeout, and the type is in the network CATEGORY\n * because nothing was exchanged\n * - A transport failure → `ShipError.network(...)` — see `isTransportFailure`\n * for what each runtime offers as evidence\n * - Any other `Error` → `ShipError(Api, ...)` (no HTTP status — fetch never reached the server)\n * - Anything else (string, undefined, etc.) → `ShipError(Api, ...)`\n *\n * **Abort and timeout are read from `name` BEFORE any `instanceof Error`\n * gate.** A `DOMException` satisfies that gate in every runtime measured\n * (Node, Bun, Chromium, Firefox, WebKit, workerd — all six), but the\n * inheritance is a comparatively recent spec change and this classification\n * has no reason to depend on it: `name` is where the meaning lives, and\n * reading it first costs nothing. The suite plants a non-`Error`\n * `DOMException` shape to hold the arm, since no runtime on the table\n * produces one.\n *\n * A caller's own `AbortSignal.timeout()` is the reachable source of\n * `TimeoutError` — and the two are NOT interchangeable per runtime: WebKit\n * reports a fired `AbortSignal.timeout()` as `AbortError`, so on Safari a\n * deadline is indistinguishable from a cancellation and lands on\n * `Cancelled`. Recorded rather than worked around; `Cancelled` is honest\n * there, since the caller's signal is what stopped it.\n *\n * The optional `operationName` is composed into the message for context:\n * `\"Get account was cancelled\"`, `\"Get account failed: ...\"`. Defaults to\n * `\"Request\"` when omitted.\n */\n static fromFetchError(cause, operationName) {\n if (isShipError(cause))\n return cause;\n const op = operationName || 'Request';\n // Read by NAME, ahead of the Error gate — see the note above.\n const name = cause?.name;\n if (name === 'AbortError') {\n return ShipError.cancelled(`${op} was cancelled`);\n }\n if (name === 'TimeoutError') {\n // A deadline: not a fault, not a cancellation, and — since it has its\n // own type — no longer merely \"network\". Nothing was exchanged, which\n // is what keeps it in the network CATEGORY and therefore retryable; the\n // type is what lets a surface say \"timed out\" instead of sending\n // someone to check their Wi-Fi. The runtime's own sentence is dropped\n // rather than relayed: \"The operation was aborted due to timeout\" is\n // the mechanism, not the news.\n return ShipError.timeout(`${op} timed out`, { cause });\n }\n if (cause instanceof Error) {\n if (isTransportFailure(cause)) {\n return ShipError.network(`${op} failed: ${cause.message}`, { cause });\n }\n return new ShipError(ErrorType.Api, `${op} failed: ${cause.message}`);\n }\n return new ShipError(ErrorType.Api, `${op} failed: Unknown error`);\n }\n // Factory methods. Uniform shape `(message, details?)` with two principled\n // exceptions: `notFound` composes its message from (resource, id?), and\n // `business` / `api` accept an optional status because they're the\n // multi-status fallbacks.\n static validation(message, details) {\n return new ShipError(ErrorType.Validation, message, 400, details);\n }\n static notFound(resource, id) {\n const message = id ? `${resource} ${id} not found` : `${resource} not found`;\n return new ShipError(ErrorType.NotFound, message, 404);\n }\n static forbidden(message, details) {\n return new ShipError(ErrorType.Forbidden, message, 403, details);\n }\n static rateLimit(message = 'Too many requests', details) {\n return new ShipError(ErrorType.RateLimit, message, 429, details);\n }\n /**\n * Construct an Authentication (401) error.\n *\n * **Telemetry pattern — `details: { internal: '<tag>' }`.** When the\n * server creates an auth error with an `internal` key in `details`\n * (e.g. `{ internal: 'session_invalid' }`), `toResponse()` strips the\n * entire `details` object before serialization. This keeps the wire\n * response a clean \"Authentication failed\" while preserving granular\n * server-side telemetry (which strategy/check failed) for logs and tests.\n *\n * Use this pattern in API auth code; do not put client-visible info under\n * `internal`. Other `details` keys round-trip normally.\n */\n static authentication(message = 'Authentication required', details) {\n return new ShipError(ErrorType.Authentication, message, 401, details);\n }\n static business(message, status = 400, details) {\n return new ShipError(ErrorType.Business, message, status, details);\n }\n static network(message, details) {\n return new ShipError(ErrorType.Network, message, undefined, details);\n }\n /**\n * A deadline expired before the exchange completed.\n *\n * Statusless like its four client-only siblings: no exchange completed, so\n * there is no HTTP status to report. `isNetworkError()` is true — see\n * `ErrorType.Timeout` for why the category is shared and the type is not.\n */\n static timeout(message, details) {\n return new ShipError(ErrorType.Timeout, message, undefined, details);\n }\n static cancelled(message, details) {\n return new ShipError(ErrorType.Cancelled, message, undefined, details);\n }\n static file(message, details) {\n return new ShipError(ErrorType.File, message, undefined, details);\n }\n static config(message, details) {\n return new ShipError(ErrorType.Config, message, undefined, details);\n }\n static api(message, status = 500, details) {\n return new ShipError(ErrorType.Api, message, status, details);\n }\n /**\n * The platform is closed for maintenance (503).\n *\n * `message` is REQUIRED and has no default here. The API is the only\n * producer of that sentence, and a default in this file would be a second\n * owner of one fact — see CLAUDE.md, \"The Constellation Law\" (stopping\n * rule). It is also the one factory whose status is fixed rather than\n * defaulted: a maintenance refusal is 503 or it is not this error.\n */\n static maintenance(message, details) {\n return new ShipError(ErrorType.Maintenance, message, 503, details);\n }\n // Semantic-category guards. For specific-type checks, use\n // `error.type === ErrorType.X` directly or the generic `isType(t)`.\n /**\n * The caller is at fault — by HTTP's own definition of a 4xx, or by a type\n * that is client-attributable without ever having a status (`Config`,\n * `File`, raised locally by the SDK).\n *\n * Both arms are load-bearing, because type and status are independent\n * axes. `fromHttpResponse` trusts `body.error` only when it names a\n * server-producible type; a non-OK response without one is status-derived,\n * so a CDN 404 or any intermediary error arrives as `Api` — a server-fault\n * *type* carrying a client *status*. Judging by type alone would report it\n * as a platform failure and bury the server's own message.\n */\n isClientError() {\n if (ERROR_CATEGORIES.client.has(this.type))\n return true;\n return this.status !== undefined && this.status >= 400 && this.status < 500;\n }\n isNetworkError() {\n return ERROR_CATEGORIES.network.has(this.type);\n }\n isAuthError() {\n return ERROR_CATEGORIES.auth.has(this.type);\n }\n isType(errorType) {\n return this.type === errorType;\n }\n}\n/**\n * Type guard to check if an unknown value is a ShipError.\n *\n * Uses structural checking instead of instanceof to handle module duplication\n * in bundled applications where multiple copies of the ShipError class may exist.\n *\n * @example\n * if (isShipError(error)) {\n * console.log(error.status, error.message);\n * }\n */\nexport function isShipError(error) {\n return (error !== null &&\n typeof error === 'object' &&\n 'name' in error &&\n error.name === 'ShipError' &&\n 'status' in error);\n}\n// =============================================================================\n// EXTENSION MATCHING\n// =============================================================================\n/**\n * The rule for reading a file's extension: lowercase, after the last dot of\n * the last path segment. `null` when there is no extension to read.\n *\n * A leading dot names the file rather than its type, so `.gitignore` and\n * `.htaccess` have no extension — but `.env.exe` has `exe`.\n *\n * Segment-aware on purpose: the callers pass deploy PATHS, not basenames, and\n * a naive `lastIndexOf('.')` over `dir.v1/README` reads the extension\n * `v1/README` — safe only by accident, since no entry in a real blocklist\n * contains a slash, which is the kind of correctness nobody should have to\n * re-derive.\n *\n * **Private, and the reason is the asymmetry rather than any hazard.** Nothing\n * outside this file reads it: `isBlockedExtension` is the only question anyone\n * asks, and the API's refusal names the FILE, not its extension. Exporting a\n * pure function is harmless, which is exactly the argument that talks a\n * published package into surface it has not earned — and the costs do not\n * match, since adding an export later is free under the additive law while\n * removing one is a major. So it stays private until a caller exists. Its\n * behaviour is fenced through `isBlockedExtension`, which is where it is\n * observable.\n *\n * (`WEB_FILE_EXTENSIONS` above is private for a different reason — publishing\n * it would invite a wrong question. Both are private; only one is a hazard.)\n *\n * @example\n * fileExtension('virus.exe') // 'exe'\n * fileExtension('assets/style.CSS') // 'css'\n * fileExtension('dir.v1/README') // null\n * fileExtension('.gitignore') // null\n * fileExtension('file.') // null\n */\nfunction fileExtension(filename) {\n const basename = filename.replace(/\\\\/g, '/').split('/').pop() ?? '';\n const dotIndex = basename.lastIndexOf('.');\n if (dotIndex <= 0 || dotIndex === basename.length - 1)\n return null;\n return basename.slice(dotIndex + 1).toLowerCase();\n}\n/**\n * Whether a file is one the platform refuses to host.\n *\n * **The list is not this package's, and that separation is the point.** What\n * counts as a blocked extension is hosting POLICY — it evolves, it is enforced\n * at one security boundary, and `virus.exe` is a perfectly well-formed\n * filename that breaks nothing about the upload→serve round-trip. So the API\n * owns the list (`cloudflare/api/src/lib/blocklist.ts`) and delivers it as\n * `PlatformLimits.blockedExtensions`; a client passes what it was given.\n *\n * What lives here is the MATCHING RULE, and it earns its place by the\n * constellation law's own test. The list's drift is loud in both directions —\n * a stale client uploads a file the API refuses by name, on the first try.\n * A second *matcher* drifts SILENTLY in the one direction that matters: a\n * client stricter than the server refuses a legal file without the server ever\n * being asked, and no error names it. Two holders, silent drift, one owner.\n *\n * The `blocked` collection is required rather than defaulted: this predicate\n * guards a security boundary in the API, and a defaulted-empty argument there\n * would block nothing while reading as though it did. Callers holding a\n * possibly-absent wire field spell the fail-open themselves.\n *\n * @example\n * isBlockedExtension('virus.exe', ['exe']) // true\n * isBlockedExtension('virus.EXE', ['exe']) // true — case-insensitive\n * isBlockedExtension('style.css', ['exe']) // false\n * isBlockedExtension('README', ['exe']) // false — no extension\n */\nexport function isBlockedExtension(filename, blocked) {\n const ext = fileExtension(filename);\n if (ext === null)\n return false;\n return Array.isArray(blocked) ? blocked.includes(ext) : blocked.has(ext);\n}\n// =============================================================================\n// PICKER ACCEPT HINT\n// =============================================================================\n/**\n * The extensions a browser file picker offers by default, grouped by role.\n *\n * Private on purpose: the only published form is `WEB_FILE_ACCEPT`, the\n * attribute value itself. A published set would invite a call site to ask it\n * whether a file is allowed — which is the one thing this list must never\n * answer. See `WEB_FILE_ACCEPT`.\n *\n * Extensionless files (`LICENSE`, most `.well-known` entries) are inexpressible\n * in `accept`, and reach a deployment by folder pick, ZIP, or drag-and-drop.\n */\nconst WEB_FILE_EXTENSIONS = [\n // Markup & documents\n 'html',\n 'htm',\n 'xhtml',\n 'xml',\n 'txt',\n 'md',\n 'markdown',\n 'pdf',\n 'csv',\n // Data & config\n 'json',\n 'jsonc',\n 'webmanifest',\n 'map',\n 'toml',\n 'yaml',\n 'yml',\n 'rss',\n 'atom',\n // Styles\n 'css',\n 'scss',\n 'sass',\n 'less',\n // Scripts & modules\n 'js',\n 'mjs',\n 'cjs',\n 'jsx',\n 'ts',\n 'tsx',\n 'wasm',\n 'vue',\n 'svelte',\n // Images\n 'png',\n 'jpg',\n 'jpeg',\n 'gif',\n 'webp',\n 'avif',\n 'svg',\n 'ico',\n 'bmp',\n 'tif',\n 'tiff',\n 'heic',\n 'heif',\n // Fonts\n 'woff',\n 'woff2',\n 'ttf',\n 'otf',\n 'eot',\n // Audio\n 'mp3',\n 'wav',\n 'ogg',\n 'oga',\n 'opus',\n 'm4a',\n 'aac',\n 'flac',\n 'weba',\n // Video\n 'mp4',\n 'webm',\n 'ogv',\n 'mov',\n 'm4v',\n 'avi',\n // 3D models\n 'glb',\n 'gltf',\n 'usdz',\n // Text tracks\n 'vtt',\n 'srt',\n // Archive — a whole site in one file\n 'zip',\n];\n/**\n * The `accept` attribute value for a browser file picker offering web files.\n *\n * **This is a hint, never a rule.** The API's blocklist is the platform's gate\n * and the only thing that decides what may be hosted; this constant decides\n * what a *file dialog* shows first. The two are not two halves of one policy,\n * and this one must never be consulted to accept or reject a file.\n *\n * The distinction is structural, not stylistic. `accept` can express only an\n * allowlist, while the platform's rule is a blocklist — so this list is\n * necessarily *narrower* than what the platform hosts, and reading it as\n * authority would reject files the platform serves happily. It is also not\n * enforcement in the browser's own terms: every file dialog offers an\n * all-files escape, and **drag-and-drop ignores `accept` entirely**. The\n * dropzone and the picker must reach the same verdict on the same files, and\n * they do — because the verdict is `validateFiles`, downstream of both.\n *\n * The invariant that matters — the picker must never offer a file the platform\n * will refuse — is fenced where the authority lives, in the API's own suite\n * (`cloudflare/api/tests/lib/blocklist.test.ts`), which reads this published\n * string and holds it against the list it owns. It sat here until the\n * blocklist became the API's, and moving it was the price of that: a fence\n * belongs with whichever side can change and break it.\n */\nexport const WEB_FILE_ACCEPT = WEB_FILE_EXTENSIONS.map((ext) => `.${ext}`).join(',');\n// =============================================================================\n// FILENAME CHARACTER VALIDATION\n// =============================================================================\n/**\n * Characters that are unsafe in filenames for static hosting.\n *\n * Blocks only characters that genuinely break the upload→serve round-trip:\n * - # ? % URL round-trip breakers (fragment, query, encoding ambiguity)\n * - \\ Path separator confusion (upload splits on backslash)\n * - < > \" XSS vectors with zero legitimate use in filenames\n * - \\x00-\\x1f \\x7f Control characters (header injection, display corruption)\n *\n * Everything else is allowed — browser percent-encodes, Worker decodes, R2 matches.\n */\n// biome-ignore lint/suspicious/noControlCharactersInRegex: blocking control characters is this regex's purpose\nexport const UNSAFE_FILENAME_CHARS = /[\\x00-\\x1f\\x7f#?%\\\\<>\"]/;\n/**\n * Check if a filename contains unsafe characters.\n *\n * @example\n * hasUnsafeChars('saved_resource(1).html') // false — parentheses are safe\n * hasUnsafeChars('page[slug].js') // false — brackets are safe\n * hasUnsafeChars('file#anchor.html') // true — # breaks URL resolution\n * hasUnsafeChars('file<tag>.html') // true — < is an XSS vector\n */\nexport function hasUnsafeChars(filename) {\n return UNSAFE_FILENAME_CHARS.test(filename);\n}\n// =============================================================================\n// UNBUILT PROJECT MARKERS\n// =============================================================================\n/**\n * Path segment names that indicate an unbuilt project was uploaded instead of build output.\n * Used for early detection in CLI, browser, and server validation.\n */\nexport const UNBUILT_PROJECT_MARKERS = new Set([\n 'node_modules',\n 'package.json',\n]);\n/**\n * Check if a file path contains an unbuilt project marker.\n *\n * @example\n * hasUnbuiltMarker('node_modules/react/index.js') // true\n * hasUnbuiltMarker('package.json') // true\n * hasUnbuiltMarker('dist/index.html') // false\n */\nexport function hasUnbuiltMarker(filePath) {\n const segments = filePath.replace(/\\\\/g, '/').split('/').filter(Boolean);\n return segments.some((s) => UNBUILT_PROJECT_MARKERS.has(s));\n}\n// =============================================================================\n// CREDENTIAL SHAPES\n// =============================================================================\n// The one address for credential vocabulary: where human identity lives\n// (AUTH_BASE_PATH), how a request is authorized (AuthMethod), the shapes\n// that distinguish populations on the wire (API_KEY, DEPLOY_TOKEN,\n// OAUTH_TOKEN, CALLER), the two halves of the one Bearer slot\n// (readBearerValue reads it, classifyToken/TokenKind dispatch on what came\n// out), and the delegated-access scopes (OAuthScope).\n//\n// THE SHAPE LAW, in three clauses, over the `Authorization: Bearer` slot's\n// three populations below. The deployment claim code is the API's own\n// (`AUTH.CLAIM`, server-side: the API mints it and the API validates it, so\n// it has one holder and stays there) and shares only clause 1 — it is the\n// platform's one deliberately BARE secret, because it never enters the\n// Bearer slot: minted into one URL, consumed by one endpoint's one field,\n// its context names it and a prefix would restate its route.\n// `tests/validation-constants.test.ts` holds the clauses over this file's\n// populations; the API's suite holds its own.\n//\n// 1. ONE ENTROPY STANDARD. Every minted secret is `HEX_LENGTH` hex characters\n// — one width for the whole platform, so \"how long is a credential\" has a\n// single answer rather than one per population. Generators read the width\n// from the population's own constant, so a minted value and an accepted\n// value cannot differ.\n//\n// 2. EVERY BEARER POPULATION IS NAMED BY ITS PREFIX. A credential says what\n// it is before anything parses it — which is what lets `classifyToken`\n// below dispatch three populations sharing one `Authorization: Bearer`\n// slot, and what lets a value found in a log, a support ticket or a\n// pasted URL be recognised and revoked on sight. The OAuth access token\n// was this clause's one standing exception until 2026-08-14 — the\n// authorization server it was born on had no mint hook to give it a\n// prefix, and its successor does.\n//\n// 3. NO PREFIX IS A PREFIX OF ANOTHER. This is what makes the dispatch\n// order-independent, and it is the reason the populations are named on\n// different axes (`ship-` for the product, `deploy-` for the capability)\n// rather than sharing a stem. A `ship-` / `ship-deploy-` pair\n// reads tidier and is a trap: every deploy token would also match the\n// API-key branch, leaving correctness resting on the order of two `if`s.\n/**\n * Where human identity is mounted on the API host. The API mounts Better\n * Auth at this path (sign-in, sign-out, session reads, admin impersonation)\n * and the web console's auth client posts to it — shared here so the two\n * halves of the auth pair agree by construction, the same way both sides\n * already share the credential prefixes below.\n */\nexport const AUTH_BASE_PATH = '/auth';\n/**\n * The query marker a completed sign-in LANDS with.\n *\n * The API's magic-link verify leg stamps `?signing-in=1` onto its success\n * redirect, and the console boots into its wait screen on seeing it — two\n * repos, one spelling, which is why it lives here. Success is marked and the\n * error leg deliberately is NOT: the console gives the marker precedence, so\n * a marked error would render a wait that resolves to bare doors with the\n * error's sentence lost. If the spellings ever diverged the failure would be\n * invisible to every suite — email landings would flash the doors for one\n * round trip instead of waiting — which is exactly the silent-drift class\n * this constitution exists to delete.\n */\nexport const SIGN_IN_RETURN_PARAM = 'signing-in';\n/**\n * How a request (or recorded activity) was authorized.\n *\n * Client populations: `SESSION` (first-party cookie), `API_KEY` (`ship-`\n * key), `TOKEN` (`deploy-` deploy token), `AGENT` (anonymous public deploy —\n * no credential; the platform grants the public-account identity per\n * request), `OAUTH` (delegated access token). Server populations: `WEBHOOK`\n * (signed webhook processing), `SYSTEM` (scheduled/background jobs).\n */\nexport const AuthMethod = {\n SESSION: 'session',\n API_KEY: 'apiKey',\n TOKEN: 'token',\n AGENT: 'agent',\n OAUTH: 'oauth',\n WEBHOOK: 'webhook',\n SYSTEM: 'system',\n};\n/**\n * Shape constants for API keys (`ship-{32 hex chars}`).\n * Single source of truth used by validation utilities and auth middleware.\n */\nexport const API_KEY = {\n /** Prefix that identifies an API key. */\n PREFIX: 'ship-',\n /** Number of hex characters following the prefix. */\n HEX_LENGTH: 32,\n /** Total length of an API key including prefix (`PREFIX.length + HEX_LENGTH = 37`). */\n TOTAL_LENGTH: 37,\n /** Number of trailing characters used to display a redacted hint (e.g. last 4). */\n HINT_LENGTH: 4,\n};\n/**\n * Shape constants for deploy tokens (`deploy-{32 hex chars}`).\n * Single source of truth used by validation utilities and auth middleware.\n *\n * Deliberately the same width as `API_KEY`: both are minted by one generator\n * and classified by prefix alone, so a length that differed between them\n * would be a second thing to know about a credential whose prefix already\n * says what it is.\n */\nexport const DEPLOY_TOKEN = {\n /** Prefix that identifies a deploy token. */\n PREFIX: 'deploy-',\n /** Number of hex characters following the prefix. */\n HEX_LENGTH: 32,\n /** Total length of a deploy token including prefix (`PREFIX.length + HEX_LENGTH = 39`). */\n TOTAL_LENGTH: 39,\n};\n/**\n * Shape constants for OAuth access tokens (`oauth-{32 hex chars}`) — the\n * delegated population, minted by the platform's own authorization server\n * for a connected app acting on a user's behalf.\n *\n * Same width as the other two, and for the same reason: one entropy standard\n * across the platform, so \"how long is a credential\" has one answer.\n *\n * **This population is the access token alone.** Refresh tokens, authorization\n * codes and client secrets are deliberately NOT here and are deliberately not\n * prefixed by this constant: none of them ever enters the `Authorization:\n * Bearer` slot — a refresh token is posted as a form field to the token\n * endpoint, which knows what it is receiving — so `classifyToken` never sees\n * one and a prefix would name a population no dispatcher dispatches. The same\n * reasoning that keeps the deployment claim code bare.\n *\n * **The prefix must be applied at the MINT, never as a display wrapper.** The\n * authorization server hashes what it stores and the API hashes what it is\n * presented, so the prefix has to be inside the hashed string on both sides.\n * `@better-auth/oauth-provider` offers a `prefix.opaqueAccessToken` option\n * that prepends AFTER hashing and strips on its own read paths; using it would\n * store a hash of the UNPREFIXED token and silently break the platform's read\n * arm. The API therefore mints through `generateOpaqueAccessToken` — recorded\n * beside the config in `cloudflare/api/src/lib/auth/instance.ts`.\n */\nexport const OAUTH_TOKEN = {\n /** Prefix that identifies an OAuth access token. */\n PREFIX: 'oauth-',\n /** Number of hex characters following the prefix. */\n HEX_LENGTH: 32,\n /** Total length including prefix (`PREFIX.length + HEX_LENGTH = 38`). */\n TOTAL_LENGTH: 38,\n};\n/**\n * Shape constants for caller identifiers (the `X-Caller` instance-identity\n * header — rate-limit bucketing for multi-tenant orchestrators). The API\n * normalizes case and silently ignores malformed values (the header is\n * unauthenticated); clients validate at the boundary via `validateCaller`,\n * so a value the server would drop fails fast instead.\n */\nexport const CALLER = {\n /** HTTP header name. */\n HEADER: 'X-Caller',\n /** Maximum identifier length. */\n MAX_LENGTH: 128,\n /** Allowed characters: alphanumeric, dot, underscore, hyphen. */\n PATTERN: /^[a-zA-Z0-9._-]+$/,\n};\n/**\n * Token populations distinguishable by shape. The platform carries every\n * client token in one wire slot (`Authorization: Bearer <value>`) and\n * classifies by value, never by a side channel — this is the classifier.\n *\n * `API_KEY`, `DEPLOY_TOKEN` and `OAUTH` *are* `AuthMethod.API_KEY`,\n * `AuthMethod.TOKEN` and `AuthMethod.OAUTH` — the equality is structural, so\n * a classification flows straight into an auth method and the trio can never\n * drift.\n *\n * `OPAQUE` is any other value, and since 2026-08-14 it names NO population:\n * every credential this platform mints for the Bearer slot carries a prefix,\n * so an opaque bearer is a bearer we did not mint. It stays a member rather\n * than becoming a `null` return because a dispatcher with a total codomain\n * reads better than one with an absence in it — and because it is where a\n * future population would land before anyone gave it a shape, which is\n * exactly what the OAuth token itself did until its prefix existed.\n */\nexport const TokenKind = {\n API_KEY: AuthMethod.API_KEY,\n DEPLOY_TOKEN: AuthMethod.TOKEN,\n OAUTH: AuthMethod.OAUTH,\n OPAQUE: 'opaque',\n};\n/**\n * Classify a client token by shape. The single dispatch used by both sides\n * of the wire: API auth middleware (which population is this credential?)\n * and SDK validation (which format rules apply before sending?). Sharing it\n * is what guarantees client and server can never disagree on dispatch.\n */\nexport function classifyToken(token) {\n if (token.startsWith(API_KEY.PREFIX))\n return TokenKind.API_KEY;\n if (token.startsWith(DEPLOY_TOKEN.PREFIX))\n return TokenKind.DEPLOY_TOKEN;\n if (token.startsWith(OAUTH_TOKEN.PREFIX))\n return TokenKind.OAUTH;\n return TokenKind.OPAQUE;\n}\n/** The auth-scheme, lowercased — the form the comparison is made in. */\nconst BEARER_SCHEME = 'bearer ';\n/**\n * Read the credential out of an `Authorization` header value — the step\n * BEFORE `classifyToken`, and the other half of the one wire slot this\n * section owns.\n *\n * Returns the credential's own bytes, or `null` when the header carries a\n * foreign scheme or nothing after the scheme.\n *\n * **The scheme is folded; the credential is not.** RFC 7235 §2.1 makes the\n * auth-scheme case-insensitive, so `bearer`, `Bearer` and `BEARER` are the\n * same header. The value after it is opaque and is compared literally\n * everywhere it is used — `ship-`/`deploy-`/`oauth-` are lowercase hex, and\n * folding them would make a credential match values it is not.\n *\n * **This platform has paid for the rule twice, which is why it has an owner\n * rather than a convention.** A spec-conformant `bearer ship-…` client was\n * refused for as long as the API's scheme test was spelled case-sensitively;\n * and `@better-auth/oauth-provider` carries the same defect in four places\n * today (`startsWith(\"Bearer \")`), which is precisely why the platform folds\n * the scheme itself and hands the provider a bare token.\n *\n * **ABSENCE is deliberately not this function's business.** A missing header\n * and an unreadable one are different facts, and the callers that care split\n * on them: the API worker's middleware distinguishes `absent` (the only\n * anonymous path) from `unreadable` (a presented credential that is refused),\n * and collapsing the two here would take that distinction away from the layer\n * that needs it. Callers check for the header themselves and pass its value.\n *\n * **Why this lives in the constitution rather than in a worker's `shared/`.**\n * It is the same wire boundary `classifyToken` already owns — one reads the\n * slot, the other dispatches on what came out — and a rule with two holders\n * whose drift is silent earns exactly one owner regardless of what the\n * convoy costs. The estate's recorded refusal to own a `Bearer` CONSTANT\n * stands and is a different thing: that is RFC vocabulary, the same reason\n * this package owns no `\"POST\"`. A parser is not a spelling.\n */\nexport function readBearerValue(header) {\n if (header.slice(0, BEARER_SCHEME.length).toLowerCase() !== BEARER_SCHEME)\n return null;\n return header.slice(BEARER_SCHEME.length) || null;\n}\n/**\n * OAuth scope vocabulary for delegated third-party access tokens.\n * Single source of truth used by the authorization server (advertised in\n * `scopes_supported`), the API's scope-enforcement middleware, and consent UI\n * copy. The standard `offline_access` scope (refresh tokens) is not platform\n * vocabulary and is deliberately absent — the middleware never checks it.\n *\n * Deliberately absent by design: any `tokens:*` scope, `account:write`, or\n * admin scope — a delegated app must never mint credentials, delete the\n * account, or act as admin.\n */\nexport const OAuthScope = {\n ACCOUNT_READ: 'account:read',\n DEPLOYMENTS_READ: 'deployments:read',\n DEPLOYMENTS_WRITE: 'deployments:write',\n DOMAINS_READ: 'domains:read',\n DOMAINS_WRITE: 'domains:write',\n};\n// =============================================================================\n// DEPLOYMENT CONFIGURATION CONSTANTS\n// =============================================================================\nexport const DEPLOYMENT_CONFIG_FILENAME = 'ship.json';\n/** Default ship.json config for SPA routing. Single source of truth — used by both API and SDK. */\nexport const SPA_DEFAULT_CONFIG = {\n rewrites: [{ source: '/(.*)', destination: '/index.html' }],\n};\n/**\n * The `/spa-check` pre-flight's client-side envelope: which file is the\n * check's subject, and how large it may be before a client skips the call.\n *\n * One fact with three holders until this export — the API's config declared\n * the cap, the SDK's `checkSPA` hardcoded `100 * 1024`, and prose restated\n * \"100KB\". `INDEX_FILE` is the selection rule (the file whose content rides\n * `SPACheckRequest.index`), restated by every client that builds the request.\n *\n * Neither member is a validation boundary: a client over the cap simply\n * skips the pre-flight, because the server answers an oversized index\n * `isSPA: false` anyway. A consumer that cannot import this (n8n) needs no\n * size copy at all — outcome parity is the server's, not the client's.\n */\nexport const SPA_CHECK_CONSTRAINTS = {\n /** The file whose content is the check's subject. */\n INDEX_FILE: 'index.html',\n /** Skip the pre-flight above this size — the server would answer false. */\n MAX_INDEX_BYTES: 100 * 1024,\n};\n/**\n * Assert that a ship.json file is *syntactically* loadable. Syntax only —\n * never schema.\n *\n * ship.json is validated and compiled on the server, deliberately: the schema\n * and the compiler evolve, and a client that judged them would reject configs\n * a newer platform accepts. That reasoning bounds what a client may check to\n * the properties which are true of *every* past and future schema:\n *\n * 1. it parses as JSON — JSON syntax is frozen (RFC 8259), so text that\n * does not parse can never be a valid config;\n * 2. its top level is an object — ship.json is `{ ... }` in every version.\n *\n * Both are monotonic: neither can ever reject something the server would\n * accept. Everything beyond them (field names, types, rule semantics, which\n * keys are permitted) stays server-side, where it can change.\n *\n * The payoff is the common case. Hand-edited JSON fails on a trailing comma,\n * a `//` comment, single quotes, unquoted keys, or smart quotes pasted from\n * documentation — mistakes that otherwise cost a full upload round-trip to\n * discover. A UTF-8 BOM (Windows editors, PowerShell redirects) is stripped\n * before parsing rather than rejected, because the server accepts it too;\n * diverging there would reintroduce exactly the false rejection this\n * function exists to avoid.\n *\n * @throws {ShipError} `ErrorType.Config` — the same type the server's own\n * config rejection carries, so the error contract is identical wherever the\n * failure is detected.\n */\nexport function assertShipJsonSyntax(text) {\n const withoutBom = text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;\n let parsed;\n try {\n parsed = JSON.parse(withoutBom);\n }\n catch (error) {\n throw ShipError.config(`invalid JSON format in config: ${error.message}`, {\n filePath: DEPLOYMENT_CONFIG_FILENAME,\n });\n }\n if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw ShipError.config(`${DEPLOYMENT_CONFIG_FILENAME} must contain a JSON object`, {\n filePath: DEPLOYMENT_CONFIG_FILENAME,\n });\n }\n}\n// =============================================================================\n// VALIDATION UTILITIES\n// =============================================================================\n/**\n * Shared rule for prefixed credentials: `{PREFIX}{HEX_LENGTH hex chars}`.\n * The regex derives from the shape constants, so the validators can never\n * drift from the shapes `classifyToken` dispatches on.\n */\nfunction validatePrefixedCredential(value, shape, label) {\n if (!value.startsWith(shape.PREFIX)) {\n throw ShipError.validation(`${label} must start with \"${shape.PREFIX}\"`);\n }\n if (value.length !== shape.TOTAL_LENGTH) {\n throw ShipError.validation(`${label} must be ${shape.TOTAL_LENGTH} characters total (${shape.PREFIX} + ${shape.HEX_LENGTH} hex chars)`);\n }\n const hexPart = value.slice(shape.PREFIX.length);\n if (!new RegExp(`^[a-f0-9]{${shape.HEX_LENGTH}}$`, 'i').test(hexPart)) {\n throw ShipError.validation(`${label} must contain ${shape.HEX_LENGTH} hexadecimal characters after \"${shape.PREFIX}\" prefix`);\n }\n}\n/**\n * Validate API key format\n */\nexport function validateApiKey(apiKey) {\n validatePrefixedCredential(apiKey, API_KEY, 'API key');\n}\n/**\n * Validate deploy token format\n */\nexport function validateDeployToken(deployToken) {\n validatePrefixedCredential(deployToken, DEPLOY_TOKEN, 'Deploy token');\n}\n/**\n * Validate OAuth access token format\n */\nexport function validateOAuthToken(oauthToken) {\n validatePrefixedCredential(oauthToken, OAUTH_TOKEN, 'OAuth access token');\n}\n/**\n * Validate a client token of any population. Classifies by shape and applies\n * the matching format rules: all three prefixed populations are validated\n * strictly; an OPAQUE token only needs to be non-empty.\n *\n * **The OPAQUE arm stays permissive on purpose**, even though the platform no\n * longer mints an unprefixed credential. It is the fallback for a population\n * that does not exist yet, and a client refusing a shape the server would\n * accept is the one failure mode this boundary must never have — the server\n * decides, and it refuses an unrecognised bearer anyway. Unprefixed OAuth\n * tokens from before 2026-08-14 land here and are refused server-side, which\n * is correct: they were revoked by the change, not grandfathered.\n */\nexport function validateToken(token) {\n switch (classifyToken(token)) {\n case TokenKind.API_KEY:\n validateApiKey(token);\n return;\n case TokenKind.DEPLOY_TOKEN:\n validateDeployToken(token);\n return;\n case TokenKind.OAUTH:\n validateOAuthToken(token);\n return;\n case TokenKind.OPAQUE:\n if (!token)\n throw ShipError.validation('Token must be a non-empty string');\n }\n}\n/**\n * Validate a caller identifier against the `CALLER` shape. The server\n * silently ignores malformed values (the header is unauthenticated); clients\n * call this at configuration time so the drop never silently happens.\n */\nexport function validateCaller(caller) {\n if (!caller || caller.length > CALLER.MAX_LENGTH || !CALLER.PATTERN.test(caller)) {\n throw ShipError.validation(`Caller must be 1-${CALLER.MAX_LENGTH} characters: letters, digits, dots, underscores, or hyphens`);\n }\n}\n/**\n * Validate API URL format\n */\nexport function validateApiUrl(apiUrl) {\n try {\n const url = new URL(apiUrl);\n if (!['http:', 'https:'].includes(url.protocol)) {\n throw ShipError.validation('API URL must use http:// or https:// protocol');\n }\n if (url.pathname !== '/' && url.pathname !== '') {\n throw ShipError.validation('API URL must not contain a path');\n }\n if (url.search || url.hash) {\n throw ShipError.validation('API URL must not contain query parameters or fragments');\n }\n }\n catch (error) {\n if (isShipError(error)) {\n throw error;\n }\n throw ShipError.validation('API URL must be a valid URL');\n }\n}\n/**\n * Check if a string matches the deployment identifier pattern (word-word-alphanumeric7).\n * Example: \"happy-cat-abc1234.shipstatic.com\"\n */\nexport function isDeployment(input) {\n return /^[a-z]+-[a-z]+-[a-z0-9]{7}(\\.[a-z0-9.-]+)?$/i.test(input);\n}\n/**\n * The envelope a requested lifetime must fit — one word, one grammar, wherever\n * the platform lets a caller choose how long something lives.\n *\n * Two resources wear it: `TokenCreateOptions.ttl` and\n * `DeploymentUploadOptions.ttl`. It lives here rather than on the server by\n * the format-vs-policy rule — a client can decide offline whether a duration\n * is well-formed, and the API rejects the same value the same way. What is\n * NOT here is any per-plan ceiling: no such policy exists, and one delivered\n * speculatively through `/limits` would be an owner for a decision nobody has\n * made.\n */\nexport const TTL_CONSTRAINTS = {\n /**\n * Shortest requestable lifetime, in seconds. One rather than zero: a\n * deployment that expires the instant it is created is not a shorter lease,\n * it is a deploy that was never live, and `0` is how an unset variable\n * arrives.\n */\n MIN_SECONDS: 1,\n /** Longest requestable lifetime, in seconds — one year. */\n MAX_SECONDS: 365 * 24 * 60 * 60,\n};\n/**\n * Validate a requested lifetime in SECONDS and return it, or `undefined` when\n * none was asked for.\n *\n * **A duration, never an instant.** The caller says how long; the server owns\n * what time it is and stamps the expiry — so a client's clock, however wrong,\n * cannot shorten or extend a lease. That is the tokens precedent, and it is\n * why this rule measures a count of seconds rather than checking a timestamp\n * against `now`.\n *\n * Fractions are refused rather than rounded: a caller who wrote `1.5` meant\n * something the wire cannot carry, and silently choosing `1` or `2` for them\n * is a decision the platform has no standing to make.\n *\n * Single source of truth shared by the API (the tokens route and the deploy\n * schema), the SDK's request boundary, and the CLI's parser.\n */\nexport function validateTtl(value) {\n if (value === undefined || value === null)\n return undefined;\n if (typeof value !== 'number' || !Number.isFinite(value)) {\n throw ShipError.validation('TTL must be a number of seconds');\n }\n if (!Number.isInteger(value)) {\n throw ShipError.validation('TTL must be a whole number of seconds');\n }\n if (value < TTL_CONSTRAINTS.MIN_SECONDS || value > TTL_CONSTRAINTS.MAX_SECONDS) {\n throw ShipError.validation(`TTL must be between ${TTL_CONSTRAINTS.MIN_SECONDS} and ${TTL_CONSTRAINTS.MAX_SECONDS} seconds`);\n }\n return value;\n}\n// =============================================================================\n// PLATFORM CONSTANTS\n// =============================================================================\n/** Default API URL if not otherwise configured. */\nexport const DEFAULT_API = 'https://api.shipstatic.com';\n/**\n * The Node SDK's ambient configuration pair — the ONLY environment variables\n * the SDK reads, and therefore the COMPLETE list an embedding host must\n * scrub (per `npm/ship`'s strict-isolation contract, scrubbing is the host's\n * job, not the SDK's). A host that derives its scrub from this object's\n * values — as the VS Code extension's child-process env block does — picks\n * up a grown contract at the next pin bump instead of by remembered prose.\n *\n * Browser builds read no environment at all, and the CLI-only variables\n * (`SHIP_PASSWORD`, `SHIP_VIA`) are deliberately NOT here: they are the\n * CLI's operational levers, not the SDK's ambient contract — see\n * `npm/ship/CLAUDE.md`, \"CLI-only env vars\".\n */\nexport const SHIP_ENV = {\n /** The one credential slot — any platform token. */\n TOKEN: 'SHIP_TOKEN',\n /** The API endpoint override. */\n API_URL: 'SHIP_API_URL',\n};\n/**\n * Where a human creates an API key — the console deep link quoted by every\n * surface that teaches authentication (the CLI's config wizard, the VS Code\n * and n8n listings, the n8n rate-limit hint and credential copy). Written\n * out in five files across three repos until this export.\n *\n * Production-branded by design: published artifacts name the product, never\n * an environment (root `CLAUDE.md`, \"Environment-Aware URLs\").\n */\nexport const MY_API_KEY_URL = 'https://my.shipstatic.com/api-key';\n/**\n * How long an anonymous deployment lives before it expires.\n *\n * The lifetime of the public tier, and one fact with several readers. The API\n * stamps a deployment's `expires` from it and gives a claim code exactly the\n * same window — a live site with a dead claim link is a coherence bug, so the\n * two are one constant rather than two that agree. Both MCP transports quote\n * the duration in prose an agent reads, and derive it from here rather than\n * writing it out, which they did in eight places until this export existed.\n *\n * Seconds, spelled in the name: this platform has both second- and\n * millisecond-valued durations, and the pair is only safe when each says which\n * it is.\n */\nexport const PUBLIC_DEPLOYMENT_TTL_SECONDS = 3 * 24 * 60 * 60;\n// =============================================================================\n// FILE UPLOAD TYPES\n// =============================================================================\n/**\n * File status constants for validation state tracking\n */\nexport const FileValidationStatus = {\n /** File is pending validation */\n PENDING: 'pending',\n /** File failed during processing (before validation) */\n PROCESSING_ERROR: 'processing_error',\n /** File was excluded by validation warning (not an error) */\n EXCLUDED: 'excluded',\n /** File failed validation (blocks deployment) */\n VALIDATION_FAILED: 'validation_failed',\n /** File passed validation and is ready for deployment */\n READY: 'ready',\n};\n// =============================================================================\n// DOMAIN UTILITIES\n// =============================================================================\n/**\n * Check if a domain is a platform domain (subdomain of our platform).\n * Platform domains are free and don't require DNS verification.\n *\n * @example isPlatformDomain(\"www.shipstatic.com\", \"shipstatic.com\") → true\n * @example isPlatformDomain(\"example.com\", \"shipstatic.com\") → false\n */\nexport function isPlatformDomain(domain, platformDomain) {\n return domain.endsWith(`.${platformDomain}`);\n}\n/**\n * Check if a domain is a custom domain (not a platform subdomain).\n * Custom domains are billable and require DNS verification.\n *\n * @example isCustomDomain(\"example.com\", \"shipstatic.com\") → true\n * @example isCustomDomain(\"www.shipstatic.com\", \"shipstatic.com\") → false\n */\nexport function isCustomDomain(domain, platformDomain) {\n return !isPlatformDomain(domain, platformDomain);\n}\n/**\n * Extract subdomain from a platform domain.\n * Returns null if not a platform domain.\n *\n * @example extractSubdomain(\"www.shipstatic.com\", \"shipstatic.com\") → \"www\"\n * @example extractSubdomain(\"example.com\", \"shipstatic.com\") → null\n */\nexport function extractSubdomain(domain, platformDomain) {\n if (!isPlatformDomain(domain, platformDomain)) {\n return null;\n }\n return domain.slice(0, -(platformDomain.length + 1)); // +1 for the dot\n}\n/**\n * Generate HTTPS URL for a deployment hostname.\n */\nexport function generateDeploymentUrl(deployment) {\n return `https://${deployment}`;\n}\n/**\n * Generate HTTPS URL for a domain.\n */\nexport function generateDomainUrl(domain) {\n return `https://${domain}`;\n}\n// =============================================================================\n// LABEL UTILITIES\n// =============================================================================\n/**\n * Label validation constraints shared across UI and API.\n * These rules define the single source of truth for label validation.\n */\nexport const LABEL_CONSTRAINTS = {\n /** Minimum label length in characters */\n MIN_LENGTH: 3,\n /** Maximum label length in characters (concise labels, matches Stack Overflow's original limit) */\n MAX_LENGTH: 25,\n /** Maximum number of labels allowed per resource */\n MAX_COUNT: 10,\n /** Allowed separator characters between label segments */\n SEPARATORS: '._-',\n};\n/**\n * Label validation pattern.\n * Must start and end with alphanumeric (a-z, 0-9).\n * Can contain separators (. _ -) between segments, but not consecutive.\n *\n * Valid examples: 'production', 'v1.2.3', 'api_v2', 'us-east-1'\n * Invalid examples: 'ab' (too short), '-prod' (starts with separator), 'foo--bar' (consecutive separators)\n */\nexport const LABEL_PATTERN = /^[a-z0-9]+(?:[._-][a-z0-9]+)*$/;\n/**\n * Serialize labels array to JSON string for database storage.\n * Returns null for empty or undefined arrays.\n *\n * @example serializeLabels(['web', 'production']) → '[\"web\",\"production\"]'\n * @example serializeLabels([]) → null\n * @example serializeLabels(undefined) → null\n */\nexport function serializeLabels(labels) {\n if (!labels || labels.length === 0)\n return null;\n return JSON.stringify(labels);\n}\n/**\n * Deserialize labels from JSON string to array.\n * Always returns an array — empty array for null/empty/invalid input.\n *\n * @example deserializeLabels('[\"web\",\"production\"]') → ['web', 'production']\n * @example deserializeLabels(null) → []\n * @example deserializeLabels('') → []\n */\nexport function deserializeLabels(labelsJson) {\n if (!labelsJson)\n return [];\n try {\n const parsed = JSON.parse(labelsJson);\n return Array.isArray(parsed) ? parsed : [];\n }\n catch {\n return [];\n }\n}\n// =============================================================================\n// PASSWORD UTILITIES\n// =============================================================================\n/**\n * Length constraints for the optional deployment password\n * (`DeploymentUploadOptions.password`). Single source of truth shared across\n * platform consumers.\n */\nexport const PASSWORD_CONSTRAINTS = {\n /** Minimum password length in characters */\n MIN_LENGTH: 6,\n /** Maximum password length in characters */\n MAX_LENGTH: 128,\n};\n/**\n * Validate an optional deployment password and return it normalized.\n *\n * Absent (`undefined` / `null`) → returns `undefined`. Present → trim\n * leading/trailing whitespace, then validate against `PASSWORD_CONSTRAINTS`\n * length bounds (internal whitespace is significant and counts toward\n * length). Throws `ShipError.validation` on breach; returns the trimmed\n * value.\n *\n * The trim is canonical: at upload, the API hashes the trimmed value; at\n * unlock, the router trims submissions before hashing. Submission and storage\n * agree byte-for-byte. Length validation runs on the trimmed value because\n * that's the user's actual intent — and it disarms a class of invisible\n * foot-guns (trailing newlines from copy/paste, mobile auto-spacing,\n * password-manager artifacts).\n *\n * Single source of truth shared by SDK (client-side validation, return\n * ignored) and API (server-side enforcement, return threaded into config).\n * Length is part of the wire-format contract; strength rules, if added later,\n * stay server-side. See `CLAUDE.md` \"Validation: format vs policy\".\n */\nexport function validatePassword(value) {\n if (value === undefined || value === null)\n return undefined;\n if (typeof value !== 'string') {\n throw ShipError.validation('Password must be a string');\n }\n const trimmed = value.trim();\n if (trimmed.length < PASSWORD_CONSTRAINTS.MIN_LENGTH ||\n trimmed.length > PASSWORD_CONSTRAINTS.MAX_LENGTH) {\n throw ShipError.validation(`Password must be between ${PASSWORD_CONSTRAINTS.MIN_LENGTH} and ${PASSWORD_CONSTRAINTS.MAX_LENGTH} characters`);\n }\n return trimmed;\n}\n","/**\n * The `File` ↔ `ProcessedFile` boundary, and the path rules that govern it.\n */\nimport { optimizeDeployPaths } from '@shipstatic/ship';\nimport { FileValidationStatus, type FileValidationStatusType } from '@shipstatic/types';\nimport type { ProcessedFile } from './types';\n\n/**\n * Patch a File's `webkitRelativePath` so the Ship SDK reads our resolved deploy\n * path. The browser-set property is read-only, so it must be redefined;\n * `configurable: true` allows re-patching when prefixes are stripped later.\n */\nexport function setRelativePath(file: File, path: string): void {\n Object.defineProperty(file, 'webkitRelativePath', {\n value: path,\n writable: false,\n configurable: true,\n });\n}\n\n/**\n * The deploy path of a raw File: its folder-relative path when the browser gave\n * us one, otherwise its bare name. Every caller goes through here.\n */\nexport function filePath(file: File): string {\n return file.webkitRelativePath?.trim() || file.name;\n}\n\n/**\n * The single conversion point from `File` to `ProcessedFile`.\n *\n * `type` is the browser's own report: the platform derives Content-Type\n * server-side from the path, so there is nothing to gain from second-guessing it\n * here. MD5 is Ship's job, during upload.\n */\nexport function createProcessedFile(file: File, options?: { path?: string }): ProcessedFile {\n const path = options?.path || filePath(file);\n\n return {\n id: crypto.randomUUID(),\n file,\n path,\n size: file.size,\n name: path.split('/').pop() || file.name,\n type: file.type,\n lastModified: file.lastModified,\n status: FileValidationStatus.PENDING,\n };\n}\n\n/**\n * Strip the common directory prefix from a set of deploy paths.\n *\n * The path algorithm is Ship's `optimizeDeployPaths` — the single source of\n * truth for deploy-path normalization. The stripped path is written back onto\n * each underlying File, because Ship reads `webkitRelativePath` from the raw\n * File objects it is handed.\n */\nexport function stripCommonPrefix(files: ProcessedFile[]): ProcessedFile[] {\n if (files.length === 0) return files;\n\n const deployFiles = optimizeDeployPaths(files.map((f) => f.path));\n\n return files.map((f, i) => {\n const newPath = deployFiles[i].path;\n setRelativePath(f.file, newPath);\n return { ...f, path: newPath, name: newPath.split('/').pop() || f.name };\n });\n}\n\n/**\n * Stamp a status across a file set.\n *\n * Validation is atomic — every file carries the same verdict — so this is the\n * one place that shape is built.\n */\nexport function applyStatus(\n files: ProcessedFile[],\n status: FileValidationStatusType,\n statusMessage?: string,\n): ProcessedFile[] {\n return files.map((f) => ({\n ...f,\n status,\n ...(statusMessage === undefined ? {} : { statusMessage }),\n }));\n}\n","// DEFLATE is a complex format; to read this code, you should probably check the RFC first:\n// https://tools.ietf.org/html/rfc1951\n// You may also wish to take a look at the guide I made about this program:\n// https://gist.github.com/101arrowz/253f31eb5abc3d9275ab943003ffecad\n// Some of the following code is similar to that of UZIP.js:\n// https://github.com/photopea/UZIP.js\n// However, the vast majority of the codebase has diverged from UZIP.js to increase performance and reduce bundle size.\n// Sometimes 0 will appear where -1 would be more appropriate. This is because using a uint\n// is better for memory in most engines (I *think*).\nvar ch2 = {};\nvar wk = (function (c, id, msg, transfer, cb) {\n var w = new Worker(ch2[id] || (ch2[id] = URL.createObjectURL(new Blob([\n c + ';addEventListener(\"error\",function(e){e=e.error;postMessage({$e$:[e.message,e.code,e.stack]})})'\n ], { type: 'text/javascript' }))));\n w.onmessage = function (e) {\n var d = e.data, ed = d.$e$;\n if (ed) {\n var err = new Error(ed[0]);\n err['code'] = ed[1];\n err.stack = ed[2];\n cb(err, null);\n }\n else\n cb(null, d);\n };\n w.postMessage(msg, transfer);\n return w;\n});\n\n// aliases for shorter compressed code (most minifers don't do this)\nvar u8 = Uint8Array, u16 = Uint16Array, i32 = Int32Array;\n// fixed length extra bits\nvar fleb = new u8([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, /* unused */ 0, 0, /* impossible */ 0]);\n// fixed distance extra bits\nvar fdeb = new u8([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, /* unused */ 0, 0]);\n// code length index map\nvar clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);\n// get base, reverse index map from extra bits\nvar freb = function (eb, start) {\n var b = new u16(31);\n for (var i = 0; i < 31; ++i) {\n b[i] = start += 1 << eb[i - 1];\n }\n // numbers here are at max 18 bits\n var r = new i32(b[30]);\n for (var i = 1; i < 30; ++i) {\n for (var j = b[i]; j < b[i + 1]; ++j) {\n r[j] = ((j - b[i]) << 5) | i;\n }\n }\n return { b: b, r: r };\n};\nvar _a = freb(fleb, 2), fl = _a.b, revfl = _a.r;\n// we can ignore the fact that the other numbers are wrong; they never happen anyway\nfl[28] = 258, revfl[258] = 28;\nvar _b = freb(fdeb, 0), fd = _b.b, revfd = _b.r;\n// map of value to reverse (assuming 16 bits)\nvar rev = new u16(32768);\nfor (var i = 0; i < 32768; ++i) {\n // reverse table algorithm from SO\n var x = ((i & 0xAAAA) >> 1) | ((i & 0x5555) << 1);\n x = ((x & 0xCCCC) >> 2) | ((x & 0x3333) << 2);\n x = ((x & 0xF0F0) >> 4) | ((x & 0x0F0F) << 4);\n rev[i] = (((x & 0xFF00) >> 8) | ((x & 0x00FF) << 8)) >> 1;\n}\n// create huffman tree from u8 \"map\": index -> code length for code index\n// mb (max bits) must be at most 15\n// TODO: optimize/split up?\nvar hMap = (function (cd, mb, r) {\n var s = cd.length;\n // index\n var i = 0;\n // u16 \"map\": index -> # of codes with bit length = index\n var l = new u16(mb);\n // length of cd must be 288 (total # of codes)\n for (; i < s; ++i) {\n if (cd[i])\n ++l[cd[i] - 1];\n }\n // u16 \"map\": index -> minimum code for bit length = index\n var le = new u16(mb);\n for (i = 1; i < mb; ++i) {\n le[i] = (le[i - 1] + l[i - 1]) << 1;\n }\n var co;\n if (r) {\n // u16 \"map\": index -> number of actual bits, symbol for code\n co = new u16(1 << mb);\n // bits to remove for reverser\n var rvb = 15 - mb;\n for (i = 0; i < s; ++i) {\n // ignore 0 lengths\n if (cd[i]) {\n // num encoding both symbol and bits read\n var sv = (i << 4) | cd[i];\n // free bits\n var r_1 = mb - cd[i];\n // start value\n var v = le[cd[i] - 1]++ << r_1;\n // m is end value\n for (var m = v | ((1 << r_1) - 1); v <= m; ++v) {\n // every 16 bit value starting with the code yields the same result\n co[rev[v] >> rvb] = sv;\n }\n }\n }\n }\n else {\n co = new u16(s);\n for (i = 0; i < s; ++i) {\n if (cd[i]) {\n co[i] = rev[le[cd[i] - 1]++] >> (15 - cd[i]);\n }\n }\n }\n return co;\n});\n// fixed length tree\nvar flt = new u8(288);\nfor (var i = 0; i < 144; ++i)\n flt[i] = 8;\nfor (var i = 144; i < 256; ++i)\n flt[i] = 9;\nfor (var i = 256; i < 280; ++i)\n flt[i] = 7;\nfor (var i = 280; i < 288; ++i)\n flt[i] = 8;\n// fixed distance tree\nvar fdt = new u8(32);\nfor (var i = 0; i < 32; ++i)\n fdt[i] = 5;\n// fixed length map\nvar flm = /*#__PURE__*/ hMap(flt, 9, 0), flrm = /*#__PURE__*/ hMap(flt, 9, 1);\n// fixed distance map\nvar fdm = /*#__PURE__*/ hMap(fdt, 5, 0), fdrm = /*#__PURE__*/ hMap(fdt, 5, 1);\n// find max of array\nvar max = function (a) {\n var m = a[0];\n for (var i = 1; i < a.length; ++i) {\n if (a[i] > m)\n m = a[i];\n }\n return m;\n};\n// read d, starting at bit p and mask with m\nvar bits = function (d, p, m) {\n var o = (p / 8) | 0;\n return ((d[o] | (d[o + 1] << 8)) >> (p & 7)) & m;\n};\n// read d, starting at bit p continuing for at least 16 bits\nvar bits16 = function (d, p) {\n var o = (p / 8) | 0;\n return ((d[o] | (d[o + 1] << 8) | (d[o + 2] << 16)) >> (p & 7));\n};\n// get end of byte\nvar shft = function (p) { return ((p + 7) / 8) | 0; };\n// typed array slice - allows garbage collector to free original reference,\n// while being more compatible than .slice\nvar slc = function (v, s, e) {\n if (s == null || s < 0)\n s = 0;\n if (e == null || e > v.length)\n e = v.length;\n // can't use .constructor in case user-supplied\n return new u8(v.subarray(s, e));\n};\n/**\n * Codes for errors generated within this library\n */\nexport var FlateErrorCode = {\n UnexpectedEOF: 0,\n InvalidBlockType: 1,\n InvalidLengthLiteral: 2,\n InvalidDistance: 3,\n StreamFinished: 4,\n NoStreamHandler: 5,\n InvalidHeader: 6,\n NoCallback: 7,\n InvalidUTF8: 8,\n ExtraFieldTooLong: 9,\n InvalidDate: 10,\n FilenameTooLong: 11,\n StreamFinishing: 12,\n InvalidZipData: 13,\n UnknownCompressionMethod: 14\n};\n// error codes\nvar ec = [\n 'unexpected EOF',\n 'invalid block type',\n 'invalid length/literal',\n 'invalid distance',\n 'stream finished',\n 'no stream handler',\n , // determined by compression function\n 'no callback',\n 'invalid UTF-8 data',\n 'extra field too long',\n 'date not in range 1980-2099',\n 'filename too long',\n 'stream finishing',\n 'invalid zip data'\n // determined by unknown compression method\n];\n;\nvar err = function (ind, msg, nt) {\n var e = new Error(msg || ec[ind]);\n e.code = ind;\n if (Error.captureStackTrace)\n Error.captureStackTrace(e, err);\n if (!nt)\n throw e;\n return e;\n};\n// expands raw DEFLATE data\nvar inflt = function (dat, st, buf, dict) {\n // source length dict length\n var sl = dat.length, dl = dict ? dict.length : 0;\n if (!sl || st.f && !st.l)\n return buf || new u8(0);\n var noBuf = !buf;\n // have to estimate size\n var resize = noBuf || st.i != 2;\n // no state\n var noSt = st.i;\n // Assumes roughly 33% compression ratio average\n if (noBuf)\n buf = new u8(sl * 3);\n // ensure buffer can fit at least l elements\n var cbuf = function (l) {\n var bl = buf.length;\n // need to increase size to fit\n if (l > bl) {\n // Double or set to necessary, whichever is greater\n var nbuf = new u8(Math.max(bl * 2, l));\n nbuf.set(buf);\n buf = nbuf;\n }\n };\n // last chunk bitpos bytes\n var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;\n // total bits\n var tbts = sl * 8;\n do {\n if (!lm) {\n // BFINAL - this is only 1 when last chunk is next\n final = bits(dat, pos, 1);\n // type: 0 = no compression, 1 = fixed huffman, 2 = dynamic huffman\n var type = bits(dat, pos + 1, 3);\n pos += 3;\n if (!type) {\n // go to end of byte boundary\n var s = shft(pos) + 4, l = dat[s - 4] | (dat[s - 3] << 8), t = s + l;\n if (t > sl) {\n if (noSt)\n err(0);\n break;\n }\n // ensure size\n if (resize)\n cbuf(bt + l);\n // Copy over uncompressed data\n buf.set(dat.subarray(s, t), bt);\n // Get new bitpos, update byte count\n st.b = bt += l, st.p = pos = t * 8, st.f = final;\n continue;\n }\n else if (type == 1)\n lm = flrm, dm = fdrm, lbt = 9, dbt = 5;\n else if (type == 2) {\n // literal lengths\n var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;\n var tl = hLit + bits(dat, pos + 5, 31) + 1;\n pos += 14;\n // length+distance tree\n var ldt = new u8(tl);\n // code length tree\n var clt = new u8(19);\n for (var i = 0; i < hcLen; ++i) {\n // use index map to get real code\n clt[clim[i]] = bits(dat, pos + i * 3, 7);\n }\n pos += hcLen * 3;\n // code lengths bits\n var clb = max(clt), clbmsk = (1 << clb) - 1;\n // code lengths map\n var clm = hMap(clt, clb, 1);\n for (var i = 0; i < tl;) {\n var r = clm[bits(dat, pos, clbmsk)];\n // bits read\n pos += r & 15;\n // symbol\n var s = r >> 4;\n // code length to copy\n if (s < 16) {\n ldt[i++] = s;\n }\n else {\n // copy count\n var c = 0, n = 0;\n if (s == 16)\n n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];\n else if (s == 17)\n n = 3 + bits(dat, pos, 7), pos += 3;\n else if (s == 18)\n n = 11 + bits(dat, pos, 127), pos += 7;\n while (n--)\n ldt[i++] = c;\n }\n }\n // length tree distance tree\n var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);\n // max length bits\n lbt = max(lt);\n // max dist bits\n dbt = max(dt);\n lm = hMap(lt, lbt, 1);\n dm = hMap(dt, dbt, 1);\n }\n else\n err(1);\n if (pos > tbts) {\n if (noSt)\n err(0);\n break;\n }\n }\n // Make sure the buffer can hold this + the largest possible addition\n // Maximum chunk size (practically, theoretically infinite) is 2^17\n if (resize)\n cbuf(bt + 131072);\n var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;\n var lpos = pos;\n for (;; lpos = pos) {\n // bits read, code\n var c = lm[bits16(dat, pos) & lms], sym = c >> 4;\n pos += c & 15;\n if (pos > tbts) {\n if (noSt)\n err(0);\n break;\n }\n if (!c)\n err(2);\n if (sym < 256)\n buf[bt++] = sym;\n else if (sym == 256) {\n lpos = pos, lm = null;\n break;\n }\n else {\n var add = sym - 254;\n // no extra bits needed if less\n if (sym > 264) {\n // index\n var i = sym - 257, b = fleb[i];\n add = bits(dat, pos, (1 << b) - 1) + fl[i];\n pos += b;\n }\n // dist\n var d = dm[bits16(dat, pos) & dms], dsym = d >> 4;\n if (!d)\n err(3);\n pos += d & 15;\n var dt = fd[dsym];\n if (dsym > 3) {\n var b = fdeb[dsym];\n dt += bits16(dat, pos) & (1 << b) - 1, pos += b;\n }\n if (pos > tbts) {\n if (noSt)\n err(0);\n break;\n }\n if (resize)\n cbuf(bt + 131072);\n var end = bt + add;\n if (bt < dt) {\n var shift = dl - dt, dend = Math.min(dt, end);\n if (shift + bt < 0)\n err(3);\n for (; bt < dend; ++bt)\n buf[bt] = dict[shift + bt];\n }\n for (; bt < end; ++bt)\n buf[bt] = buf[bt - dt];\n }\n }\n st.l = lm, st.p = lpos, st.b = bt, st.f = final;\n if (lm)\n final = 1, st.m = lbt, st.d = dm, st.n = dbt;\n } while (!final);\n // don't reallocate for streams or user buffers\n return bt != buf.length && noBuf ? slc(buf, 0, bt) : buf.subarray(0, bt);\n};\n// starting at p, write the minimum number of bits that can hold v to d\nvar wbits = function (d, p, v) {\n v <<= p & 7;\n var o = (p / 8) | 0;\n d[o] |= v;\n d[o + 1] |= v >> 8;\n};\n// starting at p, write the minimum number of bits (>8) that can hold v to d\nvar wbits16 = function (d, p, v) {\n v <<= p & 7;\n var o = (p / 8) | 0;\n d[o] |= v;\n d[o + 1] |= v >> 8;\n d[o + 2] |= v >> 16;\n};\n// creates code lengths from a frequency table\nvar hTree = function (d, mb) {\n // Need extra info to make a tree\n var t = [];\n for (var i = 0; i < d.length; ++i) {\n if (d[i])\n t.push({ s: i, f: d[i] });\n }\n var s = t.length;\n var t2 = t.slice();\n if (!s)\n return { t: et, l: 0 };\n if (s == 1) {\n var v = new u8(t[0].s + 1);\n v[t[0].s] = 1;\n return { t: v, l: 1 };\n }\n t.sort(function (a, b) { return a.f - b.f; });\n // after i2 reaches last ind, will be stopped\n // freq must be greater than largest possible number of symbols\n t.push({ s: -1, f: 25001 });\n var l = t[0], r = t[1], i0 = 0, i1 = 1, i2 = 2;\n t[0] = { s: -1, f: l.f + r.f, l: l, r: r };\n // efficient algorithm from UZIP.js\n // i0 is lookbehind, i2 is lookahead - after processing two low-freq\n // symbols that combined have high freq, will start processing i2 (high-freq,\n // non-composite) symbols instead\n // see https://reddit.com/r/photopea/comments/ikekht/uzipjs_questions/\n while (i1 != s - 1) {\n l = t[t[i0].f < t[i2].f ? i0++ : i2++];\n r = t[i0 != i1 && t[i0].f < t[i2].f ? i0++ : i2++];\n t[i1++] = { s: -1, f: l.f + r.f, l: l, r: r };\n }\n var maxSym = t2[0].s;\n for (var i = 1; i < s; ++i) {\n if (t2[i].s > maxSym)\n maxSym = t2[i].s;\n }\n // code lengths\n var tr = new u16(maxSym + 1);\n // max bits in tree\n var mbt = ln(t[i1 - 1], tr, 0);\n if (mbt > mb) {\n // more algorithms from UZIP.js\n // TODO: find out how this code works (debt)\n // ind debt\n var i = 0, dt = 0;\n // left cost\n var lft = mbt - mb, cst = 1 << lft;\n t2.sort(function (a, b) { return tr[b.s] - tr[a.s] || a.f - b.f; });\n for (; i < s; ++i) {\n var i2_1 = t2[i].s;\n if (tr[i2_1] > mb) {\n dt += cst - (1 << (mbt - tr[i2_1]));\n tr[i2_1] = mb;\n }\n else\n break;\n }\n dt >>= lft;\n while (dt > 0) {\n var i2_2 = t2[i].s;\n if (tr[i2_2] < mb)\n dt -= 1 << (mb - tr[i2_2]++ - 1);\n else\n ++i;\n }\n for (; i >= 0 && dt; --i) {\n var i2_3 = t2[i].s;\n if (tr[i2_3] == mb) {\n --tr[i2_3];\n ++dt;\n }\n }\n mbt = mb;\n }\n return { t: new u8(tr), l: mbt };\n};\n// get the max length and assign length codes\nvar ln = function (n, l, d) {\n return n.s == -1\n ? Math.max(ln(n.l, l, d + 1), ln(n.r, l, d + 1))\n : (l[n.s] = d);\n};\n// length codes generation\nvar lc = function (c) {\n var s = c.length;\n // Note that the semicolon was intentional\n while (s && !c[--s])\n ;\n var cl = new u16(++s);\n // ind num streak\n var cli = 0, cln = c[0], cls = 1;\n var w = function (v) { cl[cli++] = v; };\n for (var i = 1; i <= s; ++i) {\n if (c[i] == cln && i != s)\n ++cls;\n else {\n if (!cln && cls > 2) {\n for (; cls > 138; cls -= 138)\n w(32754);\n if (cls > 2) {\n w(cls > 10 ? ((cls - 11) << 5) | 28690 : ((cls - 3) << 5) | 12305);\n cls = 0;\n }\n }\n else if (cls > 3) {\n w(cln), --cls;\n for (; cls > 6; cls -= 6)\n w(8304);\n if (cls > 2)\n w(((cls - 3) << 5) | 8208), cls = 0;\n }\n while (cls--)\n w(cln);\n cls = 1;\n cln = c[i];\n }\n }\n return { c: cl.subarray(0, cli), n: s };\n};\n// calculate the length of output from tree, code lengths\nvar clen = function (cf, cl) {\n var l = 0;\n for (var i = 0; i < cl.length; ++i)\n l += cf[i] * cl[i];\n return l;\n};\n// writes a fixed block\n// returns the new bit pos\nvar wfblk = function (out, pos, dat) {\n // no need to write 00 as type: TypedArray defaults to 0\n var s = dat.length;\n var o = shft(pos + 2);\n out[o] = s & 255;\n out[o + 1] = s >> 8;\n out[o + 2] = out[o] ^ 255;\n out[o + 3] = out[o + 1] ^ 255;\n for (var i = 0; i < s; ++i)\n out[o + i + 4] = dat[i];\n return (o + 4 + s) * 8;\n};\n// writes a block\nvar wblk = function (dat, out, final, syms, lf, df, eb, li, bs, bl, p) {\n wbits(out, p++, final);\n ++lf[256];\n var _a = hTree(lf, 15), dlt = _a.t, mlb = _a.l;\n var _b = hTree(df, 15), ddt = _b.t, mdb = _b.l;\n var _c = lc(dlt), lclt = _c.c, nlc = _c.n;\n var _d = lc(ddt), lcdt = _d.c, ndc = _d.n;\n var lcfreq = new u16(19);\n for (var i = 0; i < lclt.length; ++i)\n ++lcfreq[lclt[i] & 31];\n for (var i = 0; i < lcdt.length; ++i)\n ++lcfreq[lcdt[i] & 31];\n var _e = hTree(lcfreq, 7), lct = _e.t, mlcb = _e.l;\n var nlcc = 19;\n for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc)\n ;\n var flen = (bl + 5) << 3;\n var ftlen = clen(lf, flt) + clen(df, fdt) + eb;\n var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + 2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18];\n if (bs >= 0 && flen <= ftlen && flen <= dtlen)\n return wfblk(out, p, dat.subarray(bs, bs + bl));\n var lm, ll, dm, dl;\n wbits(out, p, 1 + (dtlen < ftlen)), p += 2;\n if (dtlen < ftlen) {\n lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt;\n var llm = hMap(lct, mlcb, 0);\n wbits(out, p, nlc - 257);\n wbits(out, p + 5, ndc - 1);\n wbits(out, p + 10, nlcc - 4);\n p += 14;\n for (var i = 0; i < nlcc; ++i)\n wbits(out, p + 3 * i, lct[clim[i]]);\n p += 3 * nlcc;\n var lcts = [lclt, lcdt];\n for (var it = 0; it < 2; ++it) {\n var clct = lcts[it];\n for (var i = 0; i < clct.length; ++i) {\n var len = clct[i] & 31;\n wbits(out, p, llm[len]), p += lct[len];\n if (len > 15)\n wbits(out, p, (clct[i] >> 5) & 127), p += clct[i] >> 12;\n }\n }\n }\n else {\n lm = flm, ll = flt, dm = fdm, dl = fdt;\n }\n for (var i = 0; i < li; ++i) {\n var sym = syms[i];\n if (sym > 255) {\n var len = (sym >> 18) & 31;\n wbits16(out, p, lm[len + 257]), p += ll[len + 257];\n if (len > 7)\n wbits(out, p, (sym >> 23) & 31), p += fleb[len];\n var dst = sym & 31;\n wbits16(out, p, dm[dst]), p += dl[dst];\n if (dst > 3)\n wbits16(out, p, (sym >> 5) & 8191), p += fdeb[dst];\n }\n else {\n wbits16(out, p, lm[sym]), p += ll[sym];\n }\n }\n wbits16(out, p, lm[256]);\n return p + ll[256];\n};\n// deflate options (nice << 13) | chain\nvar deo = /*#__PURE__*/ new i32([65540, 131080, 131088, 131104, 262176, 1048704, 1048832, 2114560, 2117632]);\n// empty\nvar et = /*#__PURE__*/ new u8(0);\n// compresses data into a raw DEFLATE buffer\nvar dflt = function (dat, lvl, plvl, pre, post, st) {\n var s = st.z || dat.length;\n var o = new u8(pre + s + 5 * (1 + Math.ceil(s / 7000)) + post);\n // writing to this writes to the output buffer\n var w = o.subarray(pre, o.length - post);\n var lst = st.l;\n var pos = (st.r || 0) & 7;\n if (lvl) {\n if (pos)\n w[0] = st.r >> 3;\n var opt = deo[lvl - 1];\n var n = opt >> 13, c = opt & 8191;\n var msk_1 = (1 << plvl) - 1;\n // prev 2-byte val map curr 2-byte val map\n var prev = st.p || new u16(32768), head = st.h || new u16(msk_1 + 1);\n var bs1_1 = Math.ceil(plvl / 3), bs2_1 = 2 * bs1_1;\n var hsh = function (i) { return (dat[i] ^ (dat[i + 1] << bs1_1) ^ (dat[i + 2] << bs2_1)) & msk_1; };\n // 24576 is an arbitrary number of maximum symbols per block\n // 424 buffer for last block\n var syms = new i32(25000);\n // length/literal freq distance freq\n var lf = new u16(288), df = new u16(32);\n // l/lcnt exbits index l/lind waitdx blkpos\n var lc_1 = 0, eb = 0, i = st.i || 0, li = 0, wi = st.w || 0, bs = 0;\n for (; i + 2 < s; ++i) {\n // hash value\n var hv = hsh(i);\n // index mod 32768 previous index mod\n var imod = i & 32767, pimod = head[hv];\n prev[imod] = pimod;\n head[hv] = imod;\n // We always should modify head and prev, but only add symbols if\n // this data is not yet processed (\"wait\" for wait index)\n if (wi <= i) {\n // bytes remaining\n var rem = s - i;\n if ((lc_1 > 7000 || li > 24576) && (rem > 423 || !lst)) {\n pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i - bs, pos);\n li = lc_1 = eb = 0, bs = i;\n for (var j = 0; j < 286; ++j)\n lf[j] = 0;\n for (var j = 0; j < 30; ++j)\n df[j] = 0;\n }\n // len dist chain\n var l = 2, d = 0, ch_1 = c, dif = imod - pimod & 32767;\n if (rem > 2 && hv == hsh(i - dif)) {\n var maxn = Math.min(n, rem) - 1;\n var maxd = Math.min(32767, i);\n // max possible length\n // not capped at dif because decompressors implement \"rolling\" index population\n var ml = Math.min(258, rem);\n while (dif <= maxd && --ch_1 && imod != pimod) {\n if (dat[i + l] == dat[i + l - dif]) {\n var nl = 0;\n for (; nl < ml && dat[i + nl] == dat[i + nl - dif]; ++nl)\n ;\n if (nl > l) {\n l = nl, d = dif;\n // break out early when we reach \"nice\" (we are satisfied enough)\n if (nl > maxn)\n break;\n // now, find the rarest 2-byte sequence within this\n // length of literals and search for that instead.\n // Much faster than just using the start\n var mmd = Math.min(dif, nl - 2);\n var md = 0;\n for (var j = 0; j < mmd; ++j) {\n var ti = i - dif + j & 32767;\n var pti = prev[ti];\n var cd = ti - pti & 32767;\n if (cd > md)\n md = cd, pimod = ti;\n }\n }\n }\n // check the previous match\n imod = pimod, pimod = prev[imod];\n dif += imod - pimod & 32767;\n }\n }\n // d will be nonzero only when a match was found\n if (d) {\n // store both dist and len data in one int32\n // Make sure this is recognized as a len/dist with 28th bit (2^28)\n syms[li++] = 268435456 | (revfl[l] << 18) | revfd[d];\n var lin = revfl[l] & 31, din = revfd[d] & 31;\n eb += fleb[lin] + fdeb[din];\n ++lf[257 + lin];\n ++df[din];\n wi = i + l;\n ++lc_1;\n }\n else {\n syms[li++] = dat[i];\n ++lf[dat[i]];\n }\n }\n }\n for (i = Math.max(i, wi); i < s; ++i) {\n syms[li++] = dat[i];\n ++lf[dat[i]];\n }\n pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i - bs, pos);\n if (!lst) {\n st.r = (pos & 7) | w[(pos / 8) | 0] << 3;\n // shft(pos) now 1 less if pos & 7 != 0\n pos -= 7;\n st.h = head, st.p = prev, st.i = i, st.w = wi;\n }\n }\n else {\n for (var i = st.w || 0; i < s + lst; i += 65535) {\n // end\n var e = i + 65535;\n if (e >= s) {\n // write final block\n w[(pos / 8) | 0] = lst;\n e = s;\n }\n pos = wfblk(w, pos + 1, dat.subarray(i, e));\n }\n st.i = s;\n }\n return slc(o, 0, pre + shft(pos) + post);\n};\n// CRC32 table\nvar crct = /*#__PURE__*/ (function () {\n var t = new Int32Array(256);\n for (var i = 0; i < 256; ++i) {\n var c = i, k = 9;\n while (--k)\n c = ((c & 1) && -306674912) ^ (c >>> 1);\n t[i] = c;\n }\n return t;\n})();\n// CRC32\nvar crc = function () {\n var c = -1;\n return {\n p: function (d) {\n // closures have awful performance\n var cr = c;\n for (var i = 0; i < d.length; ++i)\n cr = crct[(cr & 255) ^ d[i]] ^ (cr >>> 8);\n c = cr;\n },\n d: function () { return ~c; }\n };\n};\n// Adler32\nvar adler = function () {\n var a = 1, b = 0;\n return {\n p: function (d) {\n // closures have awful performance\n var n = a, m = b;\n var l = d.length | 0;\n for (var i = 0; i != l;) {\n var e = Math.min(i + 2655, l);\n for (; i < e; ++i)\n m += n += d[i];\n n = (n & 65535) + 15 * (n >> 16), m = (m & 65535) + 15 * (m >> 16);\n }\n a = n, b = m;\n },\n d: function () {\n a %= 65521, b %= 65521;\n return (a & 255) << 24 | (a & 0xFF00) << 8 | (b & 255) << 8 | (b >> 8);\n }\n };\n};\n;\n// deflate with opts\nvar dopt = function (dat, opt, pre, post, st) {\n if (!st) {\n st = { l: 1 };\n if (opt.dictionary) {\n var dict = opt.dictionary.subarray(-32768);\n var newDat = new u8(dict.length + dat.length);\n newDat.set(dict);\n newDat.set(dat, dict.length);\n dat = newDat;\n st.w = dict.length;\n }\n }\n return dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? (st.l ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : 20) : (12 + opt.mem), pre, post, st);\n};\n// Walmart object spread\nvar mrg = function (a, b) {\n var o = {};\n for (var k in a)\n o[k] = a[k];\n for (var k in b)\n o[k] = b[k];\n return o;\n};\n// worker clone\n// This is possibly the craziest part of the entire codebase, despite how simple it may seem.\n// The only parameter to this function is a closure that returns an array of variables outside of the function scope.\n// We're going to try to figure out the variable names used in the closure as strings because that is crucial for workerization.\n// We will return an object mapping of true variable name to value (basically, the current scope as a JS object).\n// The reason we can't just use the original variable names is minifiers mangling the toplevel scope.\n// This took me three weeks to figure out how to do.\nvar wcln = function (fn, fnStr, td) {\n var dt = fn();\n var st = fn.toString();\n var ks = st.slice(st.indexOf('[') + 1, st.lastIndexOf(']')).replace(/\\s+/g, '').split(',');\n for (var i = 0; i < dt.length; ++i) {\n var v = dt[i], k = ks[i];\n if (typeof v == 'function') {\n fnStr += ';' + k + '=';\n var st_1 = v.toString();\n if (v.prototype) {\n // for global objects\n if (st_1.indexOf('[native code]') != -1) {\n var spInd = st_1.indexOf(' ', 8) + 1;\n fnStr += st_1.slice(spInd, st_1.indexOf('(', spInd));\n }\n else {\n fnStr += st_1;\n for (var t in v.prototype)\n fnStr += ';' + k + '.prototype.' + t + '=' + v.prototype[t].toString();\n }\n }\n else\n fnStr += st_1;\n }\n else\n td[k] = v;\n }\n return fnStr;\n};\nvar ch = [];\n// clone bufs\nvar cbfs = function (v) {\n var tl = [];\n for (var k in v) {\n if (v[k].buffer) {\n tl.push((v[k] = new v[k].constructor(v[k])).buffer);\n }\n }\n return tl;\n};\n// use a worker to execute code\nvar wrkr = function (fns, init, id, cb) {\n if (!ch[id]) {\n var fnStr = '', td_1 = {}, m = fns.length - 1;\n for (var i = 0; i < m; ++i)\n fnStr = wcln(fns[i], fnStr, td_1);\n ch[id] = { c: wcln(fns[m], fnStr, td_1), e: td_1 };\n }\n var td = mrg({}, ch[id].e);\n return wk(ch[id].c + ';onmessage=function(e){for(var k in e.data)self[k]=e.data[k];onmessage=' + init.toString() + '}', id, td, cbfs(td), cb);\n};\n// base async inflate fn\nvar bInflt = function () { return [u8, u16, i32, fleb, fdeb, clim, fl, fd, flrm, fdrm, rev, ec, hMap, max, bits, bits16, shft, slc, err, inflt, inflateSync, pbf, gopt]; };\nvar bDflt = function () { return [u8, u16, i32, fleb, fdeb, clim, revfl, revfd, flm, flt, fdm, fdt, rev, deo, et, hMap, wbits, wbits16, hTree, ln, lc, clen, wfblk, wblk, shft, slc, dflt, dopt, deflateSync, pbf]; };\n// gzip extra\nvar gze = function () { return [gzh, gzhl, wbytes, crc, crct]; };\n// gunzip extra\nvar guze = function () { return [gzs, gzl]; };\n// zlib extra\nvar zle = function () { return [zlh, wbytes, adler]; };\n// unzlib extra\nvar zule = function () { return [zls]; };\n// post buf\nvar pbf = function (msg) { return postMessage(msg, [msg.buffer]); };\n// get opts\nvar gopt = function (o) { return o && {\n out: o.size && new u8(o.size),\n dictionary: o.dictionary\n}; };\n// async helper\nvar cbify = function (dat, opts, fns, init, id, cb) {\n var w = wrkr(fns, init, id, function (err, dat) {\n w.terminate();\n cb(err, dat);\n });\n w.postMessage([dat, opts], opts.consume ? [dat.buffer] : []);\n return function () { w.terminate(); };\n};\n// auto stream\nvar astrm = function (strm) {\n strm.ondata = function (dat, final) { return postMessage([dat, final], [dat.buffer]); };\n return function (ev) {\n if (ev.data[0]) {\n strm.push(ev.data[0], ev.data[1]);\n postMessage([ev.data[0].length]);\n }\n else\n strm.flush(ev.data[1]);\n };\n};\n// async stream attach\nvar astrmify = function (fns, strm, opts, init, id, flush, ext) {\n var t;\n var w = wrkr(fns, init, id, function (err, dat) {\n if (err)\n w.terminate(), strm.ondata.call(strm, err);\n else if (!Array.isArray(dat))\n ext(dat);\n else if (dat.length == 1) {\n strm.queuedSize -= dat[0];\n if (strm.ondrain)\n strm.ondrain(dat[0]);\n }\n else {\n if (dat[1])\n w.terminate();\n strm.ondata.call(strm, err, dat[0], dat[1]);\n }\n });\n w.postMessage(opts);\n strm.queuedSize = 0;\n strm.push = function (d, f) {\n if (!strm.ondata)\n err(5);\n if (t)\n strm.ondata(err(4, 0, 1), null, !!f);\n strm.queuedSize += d.length;\n // can fail for cross-realm Uint8Array, but ok - only a small performance penalty\n w.postMessage([d, t = f], d.buffer instanceof ArrayBuffer ? [d.buffer] : []);\n };\n strm.terminate = function () { w.terminate(); };\n if (flush) {\n strm.flush = function (sync) { w.postMessage([0, sync]); };\n }\n};\n// read 2 bytes\nvar b2 = function (d, b) { return d[b] | (d[b + 1] << 8); };\n// read 4 bytes\nvar b4 = function (d, b) { return (d[b] | (d[b + 1] << 8) | (d[b + 2] << 16) | (d[b + 3] << 24)) >>> 0; };\n// read 8 bytes\nvar b8 = function (d, b) { return b4(d, b) + (b4(d, b + 4) * 4294967296); };\n// write bytes\nvar wbytes = function (d, b, v) {\n for (; v; ++b)\n d[b] = v, v >>>= 8;\n};\n// gzip header\nvar gzh = function (c, o) {\n var fn = o.filename;\n c[0] = 31, c[1] = 139, c[2] = 8, c[8] = o.level < 2 ? 4 : o.level == 9 ? 2 : 0, c[9] = 3; // assume Unix\n if (o.mtime != 0)\n wbytes(c, 4, Math.floor(new Date(o.mtime || Date.now()) / 1000));\n if (fn) {\n c[3] = 8;\n for (var i = 0; i <= fn.length; ++i)\n c[i + 10] = fn.charCodeAt(i);\n }\n};\n// gzip footer: -8 to -4 = CRC, -4 to -0 is length\n// gzip start\nvar gzs = function (d) {\n if (d[0] != 31 || d[1] != 139 || d[2] != 8)\n err(6, 'invalid gzip data');\n var flg = d[3];\n var st = 10;\n if (flg & 4)\n st += (d[10] | d[11] << 8) + 2;\n for (var zs = (flg >> 3 & 1) + (flg >> 4 & 1); zs > 0; zs -= !d[st++])\n ;\n return st + (flg & 2);\n};\n// gzip length\nvar gzl = function (d) {\n var l = d.length;\n return (d[l - 4] | d[l - 3] << 8 | d[l - 2] << 16 | d[l - 1] << 24) >>> 0;\n};\n// gzip header length\nvar gzhl = function (o) { return 10 + (o.filename ? o.filename.length + 1 : 0); };\n// zlib header\nvar zlh = function (c, o) {\n var lv = o.level, fl = lv == 0 ? 0 : lv < 6 ? 1 : lv == 9 ? 3 : 2;\n c[0] = 120, c[1] = (fl << 6) | (o.dictionary && 32);\n c[1] |= 31 - ((c[0] << 8) | c[1]) % 31;\n if (o.dictionary) {\n var h = adler();\n h.p(o.dictionary);\n wbytes(c, 2, h.d());\n }\n};\n// zlib start\nvar zls = function (d, dict) {\n if ((d[0] & 15) != 8 || (d[0] >> 4) > 7 || ((d[0] << 8 | d[1]) % 31))\n err(6, 'invalid zlib data');\n if ((d[1] >> 5 & 1) == +!dict)\n err(6, 'invalid zlib data: ' + (d[1] & 32 ? 'need' : 'unexpected') + ' dictionary');\n return (d[1] >> 3 & 4) + 2;\n};\nfunction StrmOpt(opts, cb) {\n if (typeof opts == 'function')\n cb = opts, opts = {};\n this.ondata = cb;\n return opts;\n}\n/**\n * Streaming DEFLATE compression\n */\nvar Deflate = /*#__PURE__*/ (function () {\n function Deflate(opts, cb) {\n if (typeof opts == 'function')\n cb = opts, opts = {};\n this.ondata = cb;\n this.o = opts || {};\n this.s = { l: 0, i: 32768, w: 32768, z: 32768 };\n // Buffer length must always be 0 mod 32768 for index calculations to be correct when modifying head and prev\n // 98304 = 32768 (lookback) + 65536 (common chunk size)\n this.b = new u8(98304);\n if (this.o.dictionary) {\n var dict = this.o.dictionary.subarray(-32768);\n this.b.set(dict, 32768 - dict.length);\n this.s.i = 32768 - dict.length;\n }\n }\n Deflate.prototype.p = function (c, f) {\n this.ondata(dopt(c, this.o, 0, 0, this.s), f);\n };\n /**\n * Pushes a chunk to be deflated\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Deflate.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n if (this.s.l)\n err(4);\n var endLen = chunk.length + this.s.z;\n if (endLen > this.b.length) {\n if (endLen > 2 * this.b.length - 32768) {\n var newBuf = new u8(endLen & -32768);\n newBuf.set(this.b.subarray(0, this.s.z));\n this.b = newBuf;\n }\n var split = this.b.length - this.s.z;\n this.b.set(chunk.subarray(0, split), this.s.z);\n this.s.z = this.b.length;\n this.p(this.b, false);\n this.b.set(this.b.subarray(-32768));\n this.b.set(chunk.subarray(split), 32768);\n this.s.z = chunk.length - split + 32768;\n this.s.i = 32766, this.s.w = 32768;\n }\n else {\n this.b.set(chunk, this.s.z);\n this.s.z += chunk.length;\n }\n this.s.l = final & 1;\n if (this.s.z > this.s.w + 8191 || final) {\n this.p(this.b, final || false);\n this.s.w = this.s.i, this.s.i -= 2;\n }\n if (final) {\n // cleanup unneeded buffers/state to reduce memory usage\n this.s = this.o = {};\n this.b = et;\n }\n };\n /**\n * Flushes buffered uncompressed data. Useful to immediately retrieve the\n * deflated output for small inputs.\n * @param sync Whether to flush to a byte boundary. A sync flush takes 4-5\n * extra bytes, but guarantees all pushed data is immediately\n * decompressible. A separate DEFLATE stream may be concatenated\n * with the current output after a sync flush.\n */\n Deflate.prototype.flush = function (sync) {\n if (!this.ondata)\n err(5);\n if (this.s.l)\n err(4);\n this.p(this.b, false);\n this.s.w = this.s.i, this.s.i -= 2;\n // could technically skip writing the type-0 block for (this.s.r & 7) == 0,\n // but the deterministic trailer (00 00 FF FF) is useful in some situations\n if (sync) {\n var c = new u8(6);\n c[0] = this.s.r >> 3;\n // write empty, non-final type-0 block\n var ep = wfblk(c, this.s.r, et);\n this.s.r = 0;\n this.ondata(c.subarray(0, ep >> 3), false);\n }\n };\n return Deflate;\n}());\nexport { Deflate };\n/**\n * Asynchronous streaming DEFLATE compression\n */\nvar AsyncDeflate = /*#__PURE__*/ (function () {\n function AsyncDeflate(opts, cb) {\n astrmify([\n bDflt,\n function () { return [astrm, Deflate]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Deflate(ev.data);\n onmessage = astrm(strm);\n }, 6, 1);\n }\n return AsyncDeflate;\n}());\nexport { AsyncDeflate };\nexport function deflate(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bDflt,\n ], function (ev) { return pbf(deflateSync(ev.data[0], ev.data[1])); }, 0, cb);\n}\n/**\n * Compresses data with DEFLATE without any wrapper\n * @param data The data to compress\n * @param opts The compression options\n * @returns The deflated version of the data\n */\nexport function deflateSync(data, opts) {\n return dopt(data, opts || {}, 0, 0);\n}\n/**\n * Streaming DEFLATE decompression\n */\nvar Inflate = /*#__PURE__*/ (function () {\n function Inflate(opts, cb) {\n // no StrmOpt here to avoid adding to workerizer\n if (typeof opts == 'function')\n cb = opts, opts = {};\n this.ondata = cb;\n var dict = opts && opts.dictionary && opts.dictionary.subarray(-32768);\n this.s = { i: 0, b: dict ? dict.length : 0 };\n this.o = new u8(32768);\n this.p = new u8(0);\n if (dict)\n this.o.set(dict);\n }\n Inflate.prototype.e = function (c) {\n if (!this.ondata)\n err(5);\n if (this.d)\n err(4);\n if (!this.p.length)\n this.p = c;\n else if (c.length) {\n var n = new u8(this.p.length + c.length);\n n.set(this.p), n.set(c, this.p.length), this.p = n;\n }\n };\n Inflate.prototype.c = function (final) {\n this.s.i = +(this.d = final || false);\n var bts = this.s.b;\n var dt = inflt(this.p, this.s, this.o);\n this.ondata(slc(dt, bts, this.s.b), this.d);\n this.o = slc(dt, this.s.b - 32768), this.s.b = this.o.length;\n this.p = slc(this.p, (this.s.p / 8) | 0), this.s.p &= 7;\n };\n /**\n * Pushes a chunk to be inflated\n * @param chunk The chunk to push\n * @param final Whether this is the final chunk\n */\n Inflate.prototype.push = function (chunk, final) {\n this.e(chunk), this.c(final);\n };\n return Inflate;\n}());\nexport { Inflate };\n/**\n * Asynchronous streaming DEFLATE decompression\n */\nvar AsyncInflate = /*#__PURE__*/ (function () {\n function AsyncInflate(opts, cb) {\n astrmify([\n bInflt,\n function () { return [astrm, Inflate]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Inflate(ev.data);\n onmessage = astrm(strm);\n }, 7, 0);\n }\n return AsyncInflate;\n}());\nexport { AsyncInflate };\nexport function inflate(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bInflt\n ], function (ev) { return pbf(inflateSync(ev.data[0], gopt(ev.data[1]))); }, 1, cb);\n}\nexport function inflateSync(data, opts) {\n return inflt(data, { i: 2 }, opts && opts.out, opts && opts.dictionary);\n}\n// before you yell at me for not just using extends, my reason is that TS inheritance is hard to workerize.\n/**\n * Streaming GZIP compression\n */\nvar Gzip = /*#__PURE__*/ (function () {\n function Gzip(opts, cb) {\n this.c = crc();\n this.l = 0;\n this.v = 1;\n Deflate.call(this, opts, cb);\n }\n /**\n * Pushes a chunk to be GZIPped\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Gzip.prototype.push = function (chunk, final) {\n this.c.p(chunk);\n this.l += chunk.length;\n Deflate.prototype.push.call(this, chunk, final);\n };\n Gzip.prototype.p = function (c, f) {\n var raw = dopt(c, this.o, this.v && gzhl(this.o), f && 8, this.s);\n if (this.v)\n gzh(raw, this.o), this.v = 0;\n if (f)\n wbytes(raw, raw.length - 8, this.c.d()), wbytes(raw, raw.length - 4, this.l);\n this.ondata(raw, f);\n };\n /**\n * Flushes buffered uncompressed data. Useful to immediately retrieve the\n * GZIPped output for small inputs.\n * @param sync Whether to flush to a byte boundary. A sync flush takes 4-5\n * extra bytes, but guarantees all pushed data is immediately\n * decompressible.\n */\n Gzip.prototype.flush = function (sync) {\n Deflate.prototype.flush.call(this, sync);\n };\n return Gzip;\n}());\nexport { Gzip };\n/**\n * Asynchronous streaming GZIP compression\n */\nvar AsyncGzip = /*#__PURE__*/ (function () {\n function AsyncGzip(opts, cb) {\n astrmify([\n bDflt,\n gze,\n function () { return [astrm, Deflate, Gzip]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Gzip(ev.data);\n onmessage = astrm(strm);\n }, 8, 1);\n }\n return AsyncGzip;\n}());\nexport { AsyncGzip };\nexport function gzip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bDflt,\n gze,\n function () { return [gzipSync]; }\n ], function (ev) { return pbf(gzipSync(ev.data[0], ev.data[1])); }, 2, cb);\n}\n/**\n * Compresses data with GZIP\n * @param data The data to compress\n * @param opts The compression options\n * @returns The gzipped version of the data\n */\nexport function gzipSync(data, opts) {\n if (!opts)\n opts = {};\n var c = crc(), l = data.length;\n c.p(data);\n var d = dopt(data, opts, gzhl(opts), 8), s = d.length;\n return gzh(d, opts), wbytes(d, s - 8, c.d()), wbytes(d, s - 4, l), d;\n}\n/**\n * Streaming single or multi-member GZIP decompression\n */\nvar Gunzip = /*#__PURE__*/ (function () {\n function Gunzip(opts, cb) {\n this.v = 1;\n this.r = 0;\n Inflate.call(this, opts, cb);\n }\n /**\n * Pushes a chunk to be GUNZIPped\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Gunzip.prototype.push = function (chunk, final) {\n Inflate.prototype.e.call(this, chunk);\n this.r += chunk.length;\n if (this.v) {\n var p = this.p.subarray(this.v - 1);\n var s = p.length > 3 ? gzs(p) : 4;\n if (s > p.length) {\n if (!final)\n return;\n }\n else if (this.v > 1 && this.onmember) {\n this.onmember(this.r - p.length);\n }\n this.p = p.subarray(s), this.v = 0;\n }\n // necessary to prevent TS from using the closure value\n // This allows for workerization to function correctly\n Inflate.prototype.c.call(this, 0);\n // process concatenated GZIP\n if (this.s.f && !this.s.l) {\n this.v = shft(this.s.p) + 9;\n this.s = { i: 0 };\n this.o = new u8(0);\n this.push(new u8(0), final);\n }\n else if (final) {\n Inflate.prototype.c.call(this, final);\n }\n };\n return Gunzip;\n}());\nexport { Gunzip };\n/**\n * Asynchronous streaming single or multi-member GZIP decompression\n */\nvar AsyncGunzip = /*#__PURE__*/ (function () {\n function AsyncGunzip(opts, cb) {\n var _this = this;\n astrmify([\n bInflt,\n guze,\n function () { return [astrm, Inflate, Gunzip]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Gunzip(ev.data);\n strm.onmember = function (offset) { return postMessage(offset); };\n onmessage = astrm(strm);\n }, 9, 0, function (offset) { return _this.onmember && _this.onmember(offset); });\n }\n return AsyncGunzip;\n}());\nexport { AsyncGunzip };\nexport function gunzip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bInflt,\n guze,\n function () { return [gunzipSync]; }\n ], function (ev) { return pbf(gunzipSync(ev.data[0], ev.data[1])); }, 3, cb);\n}\nexport function gunzipSync(data, opts) {\n var st = gzs(data);\n if (st + 8 > data.length)\n err(6, 'invalid gzip data');\n return inflt(data.subarray(st, -8), { i: 2 }, opts && opts.out || new u8(gzl(data)), opts && opts.dictionary);\n}\n/**\n * Streaming Zlib compression\n */\nvar Zlib = /*#__PURE__*/ (function () {\n function Zlib(opts, cb) {\n this.c = adler();\n this.v = 1;\n Deflate.call(this, opts, cb);\n }\n /**\n * Pushes a chunk to be zlibbed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Zlib.prototype.push = function (chunk, final) {\n this.c.p(chunk);\n Deflate.prototype.push.call(this, chunk, final);\n };\n Zlib.prototype.p = function (c, f) {\n var raw = dopt(c, this.o, this.v && (this.o.dictionary ? 6 : 2), f && 4, this.s);\n if (this.v)\n zlh(raw, this.o), this.v = 0;\n if (f)\n wbytes(raw, raw.length - 4, this.c.d());\n this.ondata(raw, f);\n };\n /**\n * Flushes buffered uncompressed data. Useful to immediately retrieve the\n * zlibbed output for small inputs.\n * @param sync Whether to flush to a byte boundary. A sync flush takes 4-5\n * extra bytes, but guarantees all pushed data is immediately\n * decompressible.\n */\n Zlib.prototype.flush = function (sync) {\n Deflate.prototype.flush.call(this, sync);\n };\n return Zlib;\n}());\nexport { Zlib };\n/**\n * Asynchronous streaming Zlib compression\n */\nvar AsyncZlib = /*#__PURE__*/ (function () {\n function AsyncZlib(opts, cb) {\n astrmify([\n bDflt,\n zle,\n function () { return [astrm, Deflate, Zlib]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Zlib(ev.data);\n onmessage = astrm(strm);\n }, 10, 1);\n }\n return AsyncZlib;\n}());\nexport { AsyncZlib };\nexport function zlib(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bDflt,\n zle,\n function () { return [zlibSync]; }\n ], function (ev) { return pbf(zlibSync(ev.data[0], ev.data[1])); }, 4, cb);\n}\n/**\n * Compress data with Zlib\n * @param data The data to compress\n * @param opts The compression options\n * @returns The zlib-compressed version of the data\n */\nexport function zlibSync(data, opts) {\n if (!opts)\n opts = {};\n var a = adler();\n a.p(data);\n var d = dopt(data, opts, opts.dictionary ? 6 : 2, 4);\n return zlh(d, opts), wbytes(d, d.length - 4, a.d()), d;\n}\n/**\n * Streaming Zlib decompression\n */\nvar Unzlib = /*#__PURE__*/ (function () {\n function Unzlib(opts, cb) {\n Inflate.call(this, opts, cb);\n this.v = opts && opts.dictionary ? 2 : 1;\n }\n /**\n * Pushes a chunk to be unzlibbed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Unzlib.prototype.push = function (chunk, final) {\n Inflate.prototype.e.call(this, chunk);\n if (this.v) {\n if (this.p.length < 6 && !final)\n return;\n this.p = this.p.subarray(zls(this.p, this.v - 1)), this.v = 0;\n }\n if (final) {\n if (this.p.length < 4)\n err(6, 'invalid zlib data');\n this.p = this.p.subarray(0, -4);\n }\n // necessary to prevent TS from using the closure value\n // This allows for workerization to function correctly\n Inflate.prototype.c.call(this, final);\n };\n return Unzlib;\n}());\nexport { Unzlib };\n/**\n * Asynchronous streaming Zlib decompression\n */\nvar AsyncUnzlib = /*#__PURE__*/ (function () {\n function AsyncUnzlib(opts, cb) {\n astrmify([\n bInflt,\n zule,\n function () { return [astrm, Inflate, Unzlib]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Unzlib(ev.data);\n onmessage = astrm(strm);\n }, 11, 0);\n }\n return AsyncUnzlib;\n}());\nexport { AsyncUnzlib };\nexport function unzlib(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bInflt,\n zule,\n function () { return [unzlibSync]; }\n ], function (ev) { return pbf(unzlibSync(ev.data[0], gopt(ev.data[1]))); }, 5, cb);\n}\nexport function unzlibSync(data, opts) {\n return inflt(data.subarray(zls(data, opts && opts.dictionary), -4), { i: 2 }, opts && opts.out, opts && opts.dictionary);\n}\n// Default algorithm for compression (used because having a known output size allows faster decompression)\nexport { gzip as compress, AsyncGzip as AsyncCompress };\nexport { gzipSync as compressSync, Gzip as Compress };\n/**\n * Streaming GZIP, Zlib, or raw DEFLATE decompression\n */\nvar Decompress = /*#__PURE__*/ (function () {\n function Decompress(opts, cb) {\n this.o = StrmOpt.call(this, opts, cb) || {};\n this.G = Gunzip;\n this.I = Inflate;\n this.Z = Unzlib;\n }\n // init substream\n // overriden by AsyncDecompress\n Decompress.prototype.i = function () {\n var _this = this;\n this.s.ondata = function (dat, final) {\n _this.ondata(dat, final);\n };\n };\n /**\n * Pushes a chunk to be decompressed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Decompress.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n if (!this.s) {\n if (this.p && this.p.length) {\n var n = new u8(this.p.length + chunk.length);\n n.set(this.p), n.set(chunk, this.p.length);\n }\n else\n this.p = chunk;\n if (this.p.length > 2) {\n this.s = (this.p[0] == 31 && this.p[1] == 139 && this.p[2] == 8)\n ? new this.G(this.o)\n : ((this.p[0] & 15) != 8 || (this.p[0] >> 4) > 7 || ((this.p[0] << 8 | this.p[1]) % 31))\n ? new this.I(this.o)\n : new this.Z(this.o);\n this.i();\n this.s.push(this.p, final);\n this.p = null;\n }\n }\n else\n this.s.push(chunk, final);\n };\n return Decompress;\n}());\nexport { Decompress };\n/**\n * Asynchronous streaming GZIP, Zlib, or raw DEFLATE decompression\n */\nvar AsyncDecompress = /*#__PURE__*/ (function () {\n function AsyncDecompress(opts, cb) {\n Decompress.call(this, opts, cb);\n this.queuedSize = 0;\n this.G = AsyncGunzip;\n this.I = AsyncInflate;\n this.Z = AsyncUnzlib;\n }\n AsyncDecompress.prototype.i = function () {\n var _this = this;\n this.s.ondata = function (err, dat, final) {\n _this.ondata(err, dat, final);\n };\n this.s.ondrain = function (size) {\n _this.queuedSize -= size;\n if (_this.ondrain)\n _this.ondrain(size);\n };\n };\n /**\n * Pushes a chunk to be decompressed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n AsyncDecompress.prototype.push = function (chunk, final) {\n this.queuedSize += chunk.length;\n Decompress.prototype.push.call(this, chunk, final);\n };\n return AsyncDecompress;\n}());\nexport { AsyncDecompress };\nexport function decompress(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return (data[0] == 31 && data[1] == 139 && data[2] == 8)\n ? gunzip(data, opts, cb)\n : ((data[0] & 15) != 8 || (data[0] >> 4) > 7 || ((data[0] << 8 | data[1]) % 31))\n ? inflate(data, opts, cb)\n : unzlib(data, opts, cb);\n}\n/**\n * Expands compressed GZIP, Zlib, or raw DEFLATE data, automatically detecting the format\n * @param data The data to decompress\n * @param opts The decompression options\n * @returns The decompressed version of the data\n */\nexport function decompressSync(data, opts) {\n return (data[0] == 31 && data[1] == 139 && data[2] == 8)\n ? gunzipSync(data, opts)\n : ((data[0] & 15) != 8 || (data[0] >> 4) > 7 || ((data[0] << 8 | data[1]) % 31))\n ? inflateSync(data, opts)\n : unzlibSync(data, opts);\n}\n// flatten a directory structure\nvar fltn = function (d, p, t, o) {\n for (var k in d) {\n var val = d[k], n = p + k, op = o;\n if (Array.isArray(val))\n op = mrg(o, val[1]), val = val[0];\n if (ArrayBuffer.isView(val))\n t[n] = [val, op];\n else {\n t[n += '/'] = [new u8(0), op];\n fltn(val, n, t, o);\n }\n }\n};\n// text encoder\nvar te = typeof TextEncoder != 'undefined' && /*#__PURE__*/ new TextEncoder();\n// text decoder\nvar td = typeof TextDecoder != 'undefined' && /*#__PURE__*/ new TextDecoder();\n// text decoder stream\nvar tds = 0;\ntry {\n td.decode(et, { stream: true });\n tds = 1;\n}\ncatch (e) { }\n// decode UTF8\nvar dutf8 = function (d) {\n for (var r = '', i = 0;;) {\n var c = d[i++];\n var eb = (c > 127) + (c > 223) + (c > 239);\n if (i + eb > d.length)\n return { s: r, r: slc(d, i - 1) };\n if (!eb)\n r += String.fromCharCode(c);\n else if (eb == 3) {\n c = ((c & 15) << 18 | (d[i++] & 63) << 12 | (d[i++] & 63) << 6 | (d[i++] & 63)) - 65536,\n r += String.fromCharCode(55296 | (c >> 10), 56320 | (c & 1023));\n }\n else if (eb & 1)\n r += String.fromCharCode((c & 31) << 6 | (d[i++] & 63));\n else\n r += String.fromCharCode((c & 15) << 12 | (d[i++] & 63) << 6 | (d[i++] & 63));\n }\n};\n/**\n * Streaming UTF-8 decoding\n */\nvar DecodeUTF8 = /*#__PURE__*/ (function () {\n /**\n * Creates a UTF-8 decoding stream\n * @param cb The callback to call whenever data is decoded\n */\n function DecodeUTF8(cb) {\n this.ondata = cb;\n if (tds)\n this.t = new TextDecoder();\n else\n this.p = et;\n }\n /**\n * Pushes a chunk to be decoded from UTF-8 binary\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n DecodeUTF8.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n final = !!final;\n if (this.t) {\n this.ondata(this.t.decode(chunk, { stream: true }), final);\n if (final) {\n if (this.t.decode().length)\n err(8);\n this.t = null;\n }\n return;\n }\n if (!this.p)\n err(4);\n var dat = new u8(this.p.length + chunk.length);\n dat.set(this.p);\n dat.set(chunk, this.p.length);\n var _a = dutf8(dat), s = _a.s, r = _a.r;\n if (final) {\n if (r.length)\n err(8);\n this.p = null;\n }\n else\n this.p = r;\n this.ondata(s, final);\n };\n return DecodeUTF8;\n}());\nexport { DecodeUTF8 };\n/**\n * Streaming UTF-8 encoding\n */\nvar EncodeUTF8 = /*#__PURE__*/ (function () {\n /**\n * Creates a UTF-8 decoding stream\n * @param cb The callback to call whenever data is encoded\n */\n function EncodeUTF8(cb) {\n this.ondata = cb;\n }\n /**\n * Pushes a chunk to be encoded to UTF-8\n * @param chunk The string data to push\n * @param final Whether this is the last chunk\n */\n EncodeUTF8.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n if (this.d)\n err(4);\n this.ondata(strToU8(chunk), this.d = final || false);\n };\n return EncodeUTF8;\n}());\nexport { EncodeUTF8 };\n/**\n * Converts a string into a Uint8Array for use with compression/decompression methods\n * @param str The string to encode\n * @param latin1 Whether or not to interpret the data as Latin-1. This should\n * not need to be true unless decoding a binary string.\n * @returns The string encoded in UTF-8/Latin-1 binary\n */\nexport function strToU8(str, latin1) {\n if (latin1) {\n var ar_1 = new u8(str.length);\n for (var i = 0; i < str.length; ++i)\n ar_1[i] = str.charCodeAt(i);\n return ar_1;\n }\n if (te)\n return te.encode(str);\n var l = str.length;\n var ar = new u8(str.length + (str.length >> 1));\n var ai = 0;\n var w = function (v) { ar[ai++] = v; };\n for (var i = 0; i < l; ++i) {\n if (ai + 5 > ar.length) {\n var n = new u8(ai + 8 + ((l - i) << 1));\n n.set(ar);\n ar = n;\n }\n var c = str.charCodeAt(i);\n if (c < 128 || latin1)\n w(c);\n else if (c < 2048)\n w(192 | (c >> 6)), w(128 | (c & 63));\n else if (c > 55295 && c < 57344)\n c = 65536 + (c & 1023 << 10) | (str.charCodeAt(++i) & 1023),\n w(240 | (c >> 18)), w(128 | ((c >> 12) & 63)), w(128 | ((c >> 6) & 63)), w(128 | (c & 63));\n else\n w(224 | (c >> 12)), w(128 | ((c >> 6) & 63)), w(128 | (c & 63));\n }\n return slc(ar, 0, ai);\n}\n/**\n * Converts a Uint8Array to a string\n * @param dat The data to decode to string\n * @param latin1 Whether or not to interpret the data as Latin-1. This should\n * not need to be true unless encoding to binary string.\n * @returns The original UTF-8/Latin-1 string\n */\nexport function strFromU8(dat, latin1) {\n if (latin1) {\n var r = '';\n for (var i = 0; i < dat.length; i += 16384)\n r += String.fromCharCode.apply(null, dat.subarray(i, i + 16384));\n return r;\n }\n else if (td) {\n return td.decode(dat);\n }\n else {\n var _a = dutf8(dat), s = _a.s, r = _a.r;\n if (r.length)\n err(8);\n return s;\n }\n}\n;\n// deflate bit flag\nvar dbf = function (l) { return l == 1 ? 3 : l < 6 ? 2 : l == 9 ? 1 : 0; };\n// skip local zip header\nvar slzh = function (d, b) { return b + 30 + b2(d, b + 26) + b2(d, b + 28); };\n// read zip header\nvar zh = function (d, b, z) {\n var fnl = b2(d, b + 28), efl = b2(d, b + 30), fn = strFromU8(d.subarray(b + 46, b + 46 + fnl), !(b2(d, b + 8) & 2048)), es = b + 46 + fnl;\n var _a = z64hs(d, es, efl, z, b4(d, b + 20), b4(d, b + 24), b4(d, b + 42)), sc = _a[0], su = _a[1], off = _a[2];\n return [b2(d, b + 10), sc, su, fn, es + efl + b2(d, b + 32), off];\n};\n// read zip64 header sizes\nvar z64hs = function (d, b, l, z, sc, su, off) {\n var nsc = sc == 4294967295, nsu = su == 4294967295, noff = off == 4294967295, e = b + l;\n var nf = nsc + nsu + noff;\n if (z && nf) {\n for (; b + 4 < e; b += 4 + b2(d, b + 2)) {\n if (b2(d, b) == 1) {\n return [\n nsc ? b8(d, b + 4 + 8 * nsu) : sc,\n nsu ? b8(d, b + 4) : su,\n noff ? b8(d, b + 4 + 8 * (nsu + nsc)) : off,\n 1\n ];\n }\n }\n // z == 2 for unknown whether or not zip64\n if (z < 2)\n err(13);\n }\n return [sc, su, off, 0];\n};\n// extra field length\nvar exfl = function (ex) {\n var le = 0;\n if (ex) {\n for (var k in ex) {\n var l = ex[k].length;\n if (l > 65535)\n err(9);\n le += l + 4;\n }\n }\n return le;\n};\n// write zip header\nvar wzh = function (d, b, f, fn, u, c, ce, co) {\n var fl = fn.length, ex = f.extra, col = co && co.length;\n var exl = exfl(ex);\n wbytes(d, b, ce != null ? 0x2014B50 : 0x4034B50), b += 4;\n if (ce != null)\n d[b++] = 20, d[b++] = f.os;\n d[b] = 20, b += 2; // spec compliance? what's that?\n d[b++] = (f.flag << 1) | (c < 0 && 8), d[b++] = u && 8;\n d[b++] = f.compression & 255, d[b++] = f.compression >> 8;\n var dt = new Date(f.mtime == null ? Date.now() : f.mtime), y = dt.getFullYear() - 1980;\n if (y < 0 || y > 119)\n err(10);\n wbytes(d, b, (y << 25) | ((dt.getMonth() + 1) << 21) | (dt.getDate() << 16) | (dt.getHours() << 11) | (dt.getMinutes() << 5) | (dt.getSeconds() >> 1)), b += 4;\n if (c != -1) {\n wbytes(d, b, f.crc);\n wbytes(d, b + 4, c < 0 ? -c - 2 : c);\n wbytes(d, b + 8, f.size);\n }\n wbytes(d, b + 12, fl);\n wbytes(d, b + 14, exl), b += 16;\n if (ce != null) {\n wbytes(d, b, col);\n wbytes(d, b + 6, f.attrs);\n wbytes(d, b + 10, ce), b += 14;\n }\n d.set(fn, b);\n b += fl;\n if (exl) {\n for (var k in ex) {\n var exf = ex[k], l = exf.length;\n wbytes(d, b, +k);\n wbytes(d, b + 2, l);\n d.set(exf, b + 4), b += 4 + l;\n }\n }\n if (col)\n d.set(co, b), b += col;\n return b;\n};\n// write zip footer (end of central directory)\nvar wzf = function (o, b, c, d, e) {\n wbytes(o, b, 0x6054B50); // skip disk\n wbytes(o, b + 8, c);\n wbytes(o, b + 10, c);\n wbytes(o, b + 12, d);\n wbytes(o, b + 16, e);\n};\n/**\n * A pass-through stream to keep data uncompressed in a ZIP archive.\n */\nvar ZipPassThrough = /*#__PURE__*/ (function () {\n /**\n * Creates a pass-through stream that can be added to ZIP archives\n * @param filename The filename to associate with this data stream\n */\n function ZipPassThrough(filename) {\n this.filename = filename;\n this.c = crc();\n this.size = 0;\n this.compression = 0;\n }\n /**\n * Processes a chunk and pushes to the output stream. You can override this\n * method in a subclass for custom behavior, but by default this passes\n * the data through. You must call this.ondata(err, chunk, final) at some\n * point in this method.\n * @param chunk The chunk to process\n * @param final Whether this is the last chunk\n */\n ZipPassThrough.prototype.process = function (chunk, final) {\n this.ondata(null, chunk, final);\n };\n /**\n * Pushes a chunk to be added. If you are subclassing this with a custom\n * compression algorithm, note that you must push data from the source\n * file only, pre-compression.\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n ZipPassThrough.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n this.c.p(chunk);\n this.size += chunk.length;\n if (final)\n this.crc = this.c.d();\n // we shouldn't really do this cast, but properly handling ArrayBufferLike\n // makes the API unergonomic with Buffer\n this.process(chunk, final || false);\n };\n return ZipPassThrough;\n}());\nexport { ZipPassThrough };\n// I don't extend because TypeScript extension adds 1kB of runtime bloat\n/**\n * Streaming DEFLATE compression for ZIP archives. Prefer using AsyncZipDeflate\n * for better performance\n */\nvar ZipDeflate = /*#__PURE__*/ (function () {\n /**\n * Creates a DEFLATE stream that can be added to ZIP archives\n * @param filename The filename to associate with this data stream\n * @param opts The compression options\n */\n function ZipDeflate(filename, opts) {\n var _this = this;\n if (!opts)\n opts = {};\n ZipPassThrough.call(this, filename);\n this.d = new Deflate(opts, function (dat, final) {\n _this.ondata(null, dat, final);\n });\n this.compression = 8;\n this.flag = dbf(opts.level);\n }\n ZipDeflate.prototype.process = function (chunk, final) {\n try {\n this.d.push(chunk, final);\n }\n catch (e) {\n this.ondata(e, null, final);\n }\n };\n /**\n * Pushes a chunk to be deflated\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n ZipDeflate.prototype.push = function (chunk, final) {\n ZipPassThrough.prototype.push.call(this, chunk, final);\n };\n return ZipDeflate;\n}());\nexport { ZipDeflate };\n/**\n * Asynchronous streaming DEFLATE compression for ZIP archives\n */\nvar AsyncZipDeflate = /*#__PURE__*/ (function () {\n /**\n * Creates an asynchronous DEFLATE stream that can be added to ZIP archives\n * @param filename The filename to associate with this data stream\n * @param opts The compression options\n */\n function AsyncZipDeflate(filename, opts) {\n var _this = this;\n if (!opts)\n opts = {};\n ZipPassThrough.call(this, filename);\n this.d = new AsyncDeflate(opts, function (err, dat, final) {\n _this.ondata(err, dat, final);\n });\n this.compression = 8;\n this.flag = dbf(opts.level);\n this.terminate = this.d.terminate;\n }\n AsyncZipDeflate.prototype.process = function (chunk, final) {\n this.d.push(chunk, final);\n };\n /**\n * Pushes a chunk to be deflated\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n AsyncZipDeflate.prototype.push = function (chunk, final) {\n ZipPassThrough.prototype.push.call(this, chunk, final);\n };\n return AsyncZipDeflate;\n}());\nexport { AsyncZipDeflate };\n// TODO: Better tree shaking\n/**\n * A zippable archive to which files can incrementally be added\n */\nvar Zip = /*#__PURE__*/ (function () {\n /**\n * Creates an empty ZIP archive to which files can be added\n * @param cb The callback to call whenever data for the generated ZIP archive\n * is available\n */\n function Zip(cb) {\n this.ondata = cb;\n this.u = [];\n this.d = 1;\n }\n /**\n * Adds a file to the ZIP archive\n * @param file The file stream to add\n */\n Zip.prototype.add = function (file) {\n var _this = this;\n if (!this.ondata)\n err(5);\n // finishing or finished\n if (this.d & 2)\n this.ondata(err(4 + (this.d & 1) * 8, 0, 1), null, false);\n else {\n var f = strToU8(file.filename), fl_1 = f.length;\n var com = file.comment, o = com && strToU8(com);\n var u = fl_1 != file.filename.length || (o && (com.length != o.length));\n var hl_1 = fl_1 + exfl(file.extra) + 30;\n if (fl_1 > 65535)\n this.ondata(err(11, 0, 1), null, false);\n var header = new u8(hl_1);\n wzh(header, 0, file, f, u, -1);\n var chks_1 = [header];\n var pAll_1 = function () {\n for (var _i = 0, chks_2 = chks_1; _i < chks_2.length; _i++) {\n var chk = chks_2[_i];\n _this.ondata(null, chk, false);\n }\n chks_1 = [];\n };\n var tr_1 = this.d;\n this.d = 0;\n var ind_1 = this.u.length;\n var uf_1 = mrg(file, {\n f: f,\n u: u,\n o: o,\n t: function () {\n if (file.terminate)\n file.terminate();\n },\n r: function () {\n pAll_1();\n if (tr_1) {\n var nxt = _this.u[ind_1 + 1];\n if (nxt)\n nxt.r();\n else\n _this.d = 1;\n }\n tr_1 = 1;\n }\n });\n var cl_1 = 0;\n file.ondata = function (err, dat, final) {\n if (err) {\n _this.ondata(err, dat, final);\n _this.terminate();\n }\n else {\n cl_1 += dat.length;\n chks_1.push(dat);\n if (final) {\n var dd = new u8(16);\n wbytes(dd, 0, 0x8074B50);\n wbytes(dd, 4, file.crc);\n wbytes(dd, 8, cl_1);\n wbytes(dd, 12, file.size);\n chks_1.push(dd);\n uf_1.c = cl_1, uf_1.b = hl_1 + cl_1 + 16, uf_1.crc = file.crc, uf_1.size = file.size;\n if (tr_1)\n uf_1.r();\n tr_1 = 1;\n }\n else if (tr_1)\n pAll_1();\n }\n };\n this.u.push(uf_1);\n }\n };\n /**\n * Ends the process of adding files and prepares to emit the final chunks.\n * This *must* be called after adding all desired files for the resulting\n * ZIP file to work properly.\n */\n Zip.prototype.end = function () {\n var _this = this;\n if (this.d & 2) {\n this.ondata(err(4 + (this.d & 1) * 8, 0, 1), null, true);\n return;\n }\n if (this.d)\n this.e();\n else\n this.u.push({\n r: function () {\n if (!(_this.d & 1))\n return;\n _this.u.splice(-1, 1);\n _this.e();\n },\n t: function () { }\n });\n this.d = 3;\n };\n Zip.prototype.e = function () {\n var bt = 0, l = 0, tl = 0;\n for (var _i = 0, _a = this.u; _i < _a.length; _i++) {\n var f = _a[_i];\n tl += 46 + f.f.length + exfl(f.extra) + (f.o ? f.o.length : 0);\n }\n var out = new u8(tl + 22);\n for (var _b = 0, _c = this.u; _b < _c.length; _b++) {\n var f = _c[_b];\n wzh(out, bt, f, f.f, f.u, -f.c - 2, l, f.o);\n bt += 46 + f.f.length + exfl(f.extra) + (f.o ? f.o.length : 0), l += f.b;\n }\n wzf(out, bt, this.u.length, tl, l);\n this.ondata(null, out, true);\n this.d = 2;\n };\n /**\n * A method to terminate any internal workers used by the stream. Subsequent\n * calls to add() will fail.\n */\n Zip.prototype.terminate = function () {\n for (var _i = 0, _a = this.u; _i < _a.length; _i++) {\n var f = _a[_i];\n f.t();\n }\n this.d = 2;\n };\n return Zip;\n}());\nexport { Zip };\nexport function zip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n var r = {};\n fltn(data, '', r, opts);\n var k = Object.keys(r);\n var lft = k.length, o = 0, tot = 0;\n var slft = lft, files = new Array(lft);\n var term = [];\n var tAll = function () {\n for (var i = 0; i < term.length; ++i)\n term[i]();\n };\n var cbd = function (a, b) {\n mt(function () { cb(a, b); });\n };\n mt(function () { cbd = cb; });\n var cbf = function () {\n var out = new u8(tot + 22), oe = o, cdl = tot - o;\n tot = 0;\n for (var i = 0; i < slft; ++i) {\n var f = files[i];\n try {\n var l = f.c.length;\n wzh(out, tot, f, f.f, f.u, l);\n var badd = 30 + f.f.length + exfl(f.extra);\n var loc = tot + badd;\n out.set(f.c, loc);\n wzh(out, o, f, f.f, f.u, l, tot, f.m), o += 16 + badd + (f.m ? f.m.length : 0), tot = loc + l;\n }\n catch (e) {\n return cbd(e, null);\n }\n }\n wzf(out, o, files.length, cdl, oe);\n cbd(null, out);\n };\n if (!lft)\n cbf();\n var _loop_1 = function (i) {\n var fn = k[i];\n var _a = r[fn], file = _a[0], p = _a[1];\n var c = crc(), size = file.length;\n c.p(file);\n var f = strToU8(fn), s = f.length;\n var com = p.comment, m = com && strToU8(com), ms = m && m.length;\n var exl = exfl(p.extra);\n var compression = p.level == 0 ? 0 : 8;\n var cbl = function (e, d) {\n if (e) {\n tAll();\n cbd(e, null);\n }\n else {\n var l = d.length;\n files[i] = mrg(p, {\n size: size,\n crc: c.d(),\n c: d,\n f: f,\n m: m,\n u: s != fn.length || (m && (com.length != ms)),\n compression: compression\n });\n o += 30 + s + exl + l;\n tot += 76 + 2 * (s + exl) + (ms || 0) + l;\n if (!--lft)\n cbf();\n }\n };\n if (s > 65535)\n cbl(err(11, 0, 1), null);\n if (!compression)\n cbl(null, file);\n else if (size < 160000) {\n try {\n cbl(null, deflateSync(file, p));\n }\n catch (e) {\n cbl(e, null);\n }\n }\n else\n term.push(deflate(file, p, cbl));\n };\n // Cannot use lft because it can decrease\n for (var i = 0; i < slft; ++i) {\n _loop_1(i);\n }\n return tAll;\n}\n/**\n * Synchronously creates a ZIP file. Prefer using `zip` for better performance\n * with more than one file.\n * @param data The directory structure for the ZIP archive\n * @param opts The main options, merged with per-file options\n * @returns The generated ZIP archive\n */\nexport function zipSync(data, opts) {\n if (!opts)\n opts = {};\n var r = {};\n var files = [];\n fltn(data, '', r, opts);\n var o = 0;\n var tot = 0;\n for (var fn in r) {\n var _a = r[fn], file = _a[0], p = _a[1];\n var compression = p.level == 0 ? 0 : 8;\n var f = strToU8(fn), s = f.length;\n var com = p.comment, m = com && strToU8(com), ms = m && m.length;\n var exl = exfl(p.extra);\n if (s > 65535)\n err(11);\n var d = compression ? deflateSync(file, p) : file, l = d.length;\n var c = crc();\n c.p(file);\n files.push(mrg(p, {\n size: file.length,\n crc: c.d(),\n c: d,\n f: f,\n m: m,\n u: s != fn.length || (m && (com.length != ms)),\n o: o,\n compression: compression\n }));\n o += 30 + s + exl + l;\n tot += 76 + 2 * (s + exl) + (ms || 0) + l;\n }\n var out = new u8(tot + 22), oe = o, cdl = tot - o;\n for (var i = 0; i < files.length; ++i) {\n var f = files[i];\n wzh(out, f.o, f, f.f, f.u, f.c.length);\n var badd = 30 + f.f.length + exfl(f.extra);\n out.set(f.c, f.o + badd);\n wzh(out, o, f, f.f, f.u, f.c.length, f.o, f.m), o += 16 + badd + (f.m ? f.m.length : 0);\n }\n wzf(out, o, files.length, cdl, oe);\n return out;\n}\n/**\n * Streaming pass-through decompression for ZIP archives\n */\nvar UnzipPassThrough = /*#__PURE__*/ (function () {\n function UnzipPassThrough() {\n }\n UnzipPassThrough.prototype.push = function (chunk, final) {\n // same as ZipPassThrough: cast to retain Buffer ergonomics\n this.ondata(null, chunk, final);\n };\n UnzipPassThrough.compression = 0;\n return UnzipPassThrough;\n}());\nexport { UnzipPassThrough };\n/**\n * Streaming DEFLATE decompression for ZIP archives. Prefer AsyncZipInflate for\n * better performance.\n */\nvar UnzipInflate = /*#__PURE__*/ (function () {\n /**\n * Creates a DEFLATE decompression that can be used in ZIP archives\n */\n function UnzipInflate() {\n var _this = this;\n this.i = new Inflate(function (dat, final) {\n _this.ondata(null, dat, final);\n });\n }\n UnzipInflate.prototype.push = function (chunk, final) {\n try {\n this.i.push(chunk, final);\n }\n catch (e) {\n this.ondata(e, null, final);\n }\n };\n UnzipInflate.compression = 8;\n return UnzipInflate;\n}());\nexport { UnzipInflate };\n/**\n * Asynchronous streaming DEFLATE decompression for ZIP archives\n */\nvar AsyncUnzipInflate = /*#__PURE__*/ (function () {\n /**\n * Creates a DEFLATE decompression that can be used in ZIP archives\n */\n function AsyncUnzipInflate(_, sz) {\n var _this = this;\n if (sz < 320000) {\n this.i = new Inflate(function (dat, final) {\n _this.ondata(null, dat, final);\n });\n }\n else {\n this.i = new AsyncInflate(function (err, dat, final) {\n _this.ondata(err, dat, final);\n });\n this.terminate = this.i.terminate;\n }\n }\n AsyncUnzipInflate.prototype.push = function (chunk, final) {\n if (this.i.terminate)\n chunk = slc(chunk, 0);\n this.i.push(chunk, final);\n };\n AsyncUnzipInflate.compression = 8;\n return AsyncUnzipInflate;\n}());\nexport { AsyncUnzipInflate };\n/**\n * A ZIP archive decompression stream that emits files as they are discovered\n */\nvar Unzip = /*#__PURE__*/ (function () {\n /**\n * Creates a ZIP decompression stream\n * @param cb The callback to call whenever a file in the ZIP archive is found\n */\n function Unzip(cb) {\n this.onfile = cb;\n this.k = [];\n this.o = {\n 0: UnzipPassThrough\n };\n this.p = et;\n }\n /**\n * Pushes a chunk to be unzipped\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Unzip.prototype.push = function (chunk, final) {\n var _this = this;\n if (!this.onfile)\n err(5);\n if (!this.p)\n err(4);\n if (this.c > 0) {\n var len = Math.min(this.c, chunk.length);\n var toAdd = chunk.subarray(0, len);\n this.c -= len;\n if (this.d)\n this.d.push(toAdd, !this.c);\n else\n this.k[0].push(toAdd);\n chunk = chunk.subarray(len);\n if (chunk.length)\n return this.push(chunk, final);\n }\n else {\n var f = 0, i = 0, is = void 0, buf = void 0;\n if (!this.p.length)\n buf = chunk;\n else if (!chunk.length)\n buf = this.p;\n else {\n buf = new u8(this.p.length + chunk.length);\n buf.set(this.p), buf.set(chunk, this.p.length);\n }\n var l = buf.length, oc = this.c, add = oc && this.d;\n var _loop_2 = function () {\n var sig = b4(buf, i);\n if (sig == 0x4034B50) {\n f = 1, is = i;\n this_1.d = null;\n this_1.c = 0;\n var bf = b2(buf, i + 6), cmp_1 = b2(buf, i + 8), u = bf & 2048, dd = bf & 8, fnl = b2(buf, i + 26), es = b2(buf, i + 28);\n if (l > i + 30 + fnl + es) {\n var chks_3 = [];\n this_1.k.unshift(chks_3);\n f = 2;\n var lsc = b4(buf, i + 18), lsu = b4(buf, i + 22);\n var fn_1 = strFromU8(buf.subarray(i + 30, i += 30 + fnl), !u);\n var _a = z64hs(buf, i, es, 2, lsc, lsu, 0), sc_1 = _a[0], su_1 = _a[1], z64 = _a[3];\n if (dd)\n sc_1 = -1 - z64;\n i += es;\n this_1.c = sc_1;\n var d_1;\n var file_1 = {\n name: fn_1,\n compression: cmp_1,\n start: function () {\n if (!file_1.ondata)\n err(5);\n if (!sc_1)\n file_1.ondata(null, et, true);\n else {\n var ctr = _this.o[cmp_1];\n if (!ctr)\n file_1.ondata(err(14, 'unknown compression type ' + cmp_1, 1), null, false);\n d_1 = sc_1 < 0 ? new ctr(fn_1) : new ctr(fn_1, sc_1, su_1);\n d_1.ondata = function (err, dat, final) { file_1.ondata(err, dat, final); };\n for (var _i = 0, chks_4 = chks_3; _i < chks_4.length; _i++) {\n var dat = chks_4[_i];\n d_1.push(dat, false);\n }\n if (_this.k[0] == chks_3 && _this.c)\n _this.d = d_1;\n else\n d_1.push(et, true);\n }\n },\n terminate: function () {\n if (d_1 && d_1.terminate)\n d_1.terminate();\n }\n };\n if (sc_1 >= 0)\n file_1.size = sc_1, file_1.originalSize = su_1;\n this_1.onfile(file_1);\n }\n return \"break\";\n }\n else if (oc) {\n if (sig == 0x8074B50) {\n is = i += 12 + (oc == -2 && 8), f = 3, this_1.c = 0;\n return \"break\";\n }\n else if (sig == 0x2014B50) {\n is = i -= 4, f = 3, this_1.c = 0;\n return \"break\";\n }\n }\n };\n var this_1 = this;\n for (; i < l - 4; ++i) {\n var state_1 = _loop_2();\n if (state_1 === \"break\")\n break;\n }\n this.p = et;\n if (oc < 0) {\n var dat = f ? buf.subarray(0, is - 12 - (oc == -2 && 8) - (b4(buf, is - 16) == 0x8074B50 && 4)) : buf.subarray(0, i);\n if (add)\n add.push(dat, !!f);\n else\n this.k[+(f == 2)].push(dat);\n }\n if (f & 2)\n return this.push(buf.subarray(i), final);\n this.p = buf.subarray(i);\n }\n if (final) {\n if (this.c)\n err(13);\n this.p = null;\n }\n };\n /**\n * Registers a decoder with the stream, allowing for files compressed with\n * the compression type provided to be expanded correctly\n * @param decoder The decoder constructor\n */\n Unzip.prototype.register = function (decoder) {\n this.o[decoder.compression] = decoder;\n };\n return Unzip;\n}());\nexport { Unzip };\nvar mt = typeof queueMicrotask == 'function' ? queueMicrotask : typeof setTimeout == 'function' ? setTimeout : function (fn) { fn(); };\nexport function unzip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n var term = [];\n var tAll = function () {\n for (var i = 0; i < term.length; ++i)\n term[i]();\n };\n var files = {};\n var cbd = function (a, b) {\n mt(function () { cb(a, b); });\n };\n mt(function () { cbd = cb; });\n var e = data.length - 22;\n for (; b4(data, e) != 0x6054B50; --e) {\n if (!e || data.length - e > 65558) {\n cbd(err(13, 0, 1), null);\n return tAll;\n }\n }\n ;\n var lft = b2(data, e + 8);\n if (lft) {\n var c = lft;\n var o = b4(data, e + 16);\n var z = b4(data, e - 20) == 0x7064B50;\n if (z) {\n var ze = b4(data, e - 12);\n z = b4(data, ze) == 0x6064B50;\n if (z) {\n c = lft = b4(data, ze + 32);\n o = b4(data, ze + 48);\n }\n }\n var fltr = opts && opts.filter;\n var _loop_3 = function (i) {\n var _a = zh(data, o, z), c_1 = _a[0], sc = _a[1], su = _a[2], fn = _a[3], no = _a[4], off = _a[5], b = slzh(data, off);\n o = no;\n var cbl = function (e, d) {\n if (e) {\n tAll();\n cbd(e, null);\n }\n else {\n if (d)\n files[fn] = d;\n if (!--lft)\n cbd(null, files);\n }\n };\n if (!fltr || fltr({\n name: fn,\n size: sc,\n originalSize: su,\n compression: c_1\n })) {\n if (!c_1)\n cbl(null, slc(data, b, b + sc));\n else if (c_1 == 8) {\n var infl = data.subarray(b, b + sc);\n // Synchronously decompress under 512KB, or barely-compressed data\n if (su < 524288 || sc > 0.8 * su) {\n try {\n cbl(null, inflateSync(infl, { out: new u8(su) }));\n }\n catch (e) {\n cbl(e, null);\n }\n }\n else\n term.push(inflate(infl, { size: su }, cbl));\n }\n else\n cbl(err(14, 'unknown compression type ' + c_1, 1), null);\n }\n else\n cbl(null, null);\n };\n for (var i = 0; i < c; ++i) {\n _loop_3(i);\n }\n }\n else\n cbd(null, {});\n return tAll;\n}\n/**\n * Synchronously decompresses a ZIP archive. Prefer using `unzip` for better\n * performance with more than one file.\n * @param data The raw compressed ZIP file\n * @param opts The ZIP extraction options\n * @returns The decompressed files\n */\nexport function unzipSync(data, opts) {\n var files = {};\n var e = data.length - 22;\n for (; b4(data, e) != 0x6054B50; --e) {\n if (!e || data.length - e > 65558)\n err(13);\n }\n ;\n var c = b2(data, e + 8);\n if (!c)\n return {};\n var o = b4(data, e + 16);\n var z = b4(data, e - 20) == 0x7064B50;\n if (z) {\n var ze = b4(data, e - 12);\n z = b4(data, ze) == 0x6064B50;\n if (z) {\n c = b4(data, ze + 32);\n o = b4(data, ze + 48);\n }\n }\n var fltr = opts && opts.filter;\n for (var i = 0; i < c; ++i) {\n var _a = zh(data, o, z), c_2 = _a[0], sc = _a[1], su = _a[2], fn = _a[3], no = _a[4], off = _a[5], b = slzh(data, off);\n o = no;\n if (!fltr || fltr({\n name: fn,\n size: sc,\n originalSize: su,\n compression: c_2\n })) {\n if (!c_2)\n files[fn] = slc(data, b, b + sc);\n else if (c_2 == 8)\n files[fn] = inflateSync(data.subarray(b, b + sc), { out: new u8(su) });\n else\n err(14, 'unknown compression type ' + c_2);\n }\n }\n return files;\n}\n","/**\n * ZIP extraction — archive bytes in, regular File objects out.\n */\nimport { type Unzipped, unzip } from 'fflate';\nimport { setRelativePath } from './files';\n\nexport interface ZipExtractionResult {\n /** Extracted files as regular File objects */\n files: File[];\n /** Any errors encountered during extraction */\n errors: string[];\n}\n\n/**\n * Extracts all files from a ZIP archive.\n *\n * Uses fflate's ASYNCHRONOUS `unzip`, which inflates off the main thread. The\n * synchronous variant would block the tab for the duration — unacceptable on\n * this package's headline interaction, where a large folder is the normal case.\n */\nexport async function extractZipToFiles(zipFile: File): Promise<ZipExtractionResult> {\n try {\n const bytes = new Uint8Array(await zipFile.arrayBuffer());\n const entries = await new Promise<Unzipped>((resolve, reject) => {\n unzip(bytes, (err, data) => (err ? reject(err) : resolve(data)));\n });\n\n const files: File[] = [];\n const errors: string[] = [];\n\n for (const [path, data] of Object.entries(entries)) {\n // Skip directory entries\n if (path.endsWith('/') && data.length === 0) continue;\n\n const sanitizedPath = normalizePath(path);\n\n // Empty after normalization (e.g. all \"../..\") has no servable address\n if (!sanitizedPath) {\n errors.push(`Skipped invalid path: ${path}`);\n continue;\n }\n\n const filename = sanitizedPath.split('/').pop() || sanitizedPath;\n\n // Copy to own ArrayBuffer (fflate shares backing buffers across entries).\n // No `type` is set: the platform derives Content-Type from the path\n // server-side, and nothing between here and the wire reads it.\n const file = new File([new Uint8Array(data)], filename);\n\n // Set webkitRelativePath to the full path — same contract as drag-and-drop\n // files. This unifies the path mechanism: every file source carries its\n // deploy path on webkitRelativePath and its bare name on file.name.\n setRelativePath(file, sanitizedPath);\n\n files.push(file);\n }\n\n return { files, errors };\n } catch (error) {\n return {\n files: [],\n errors: [\n `Failed to load ZIP file: ${error instanceof Error ? error.message : String(error)}`,\n ],\n };\n }\n}\n\n/**\n * Sanitize and normalize an archive entry path to prevent directory traversal.\n * Removes: .., ., leading/trailing slashes, absolute paths, and empty segments.\n *\n * @example\n * normalizePath('../../etc/passwd') → 'etc/passwd'\n * normalizePath('foo/./bar/../baz.txt') → 'foo/baz.txt'\n * normalizePath('/absolute/path.txt') → 'absolute/path.txt'\n */\nexport function normalizePath(path: string): string {\n const normalized: string[] = [];\n\n for (const segment of path.split('/')) {\n if (segment === '' || segment === '.') continue;\n\n if (segment === '..') {\n // Pop only when there is somewhere to go back to — this is what prevents\n // traversal above the archive root.\n normalized.pop();\n continue;\n }\n\n normalized.push(segment);\n }\n\n return normalized.join('/');\n}\n\n/**\n * Check if a file is a ZIP file based on MIME type or extension\n */\nexport function isZipFile(file: File): boolean {\n return (\n file.type === 'application/zip' ||\n file.type === 'application/x-zip-compressed' ||\n file.name.toLowerCase().endsWith('.zip')\n );\n}\n","/**\n * The drop pipeline — everything between \"here are some Files\" and \"here is a\n * verdict\", with no React in sight.\n *\n * It takes `PlatformLimits` rather than a `Ship` client, which is what makes it\n * a plain function: source-name detection, ZIP extraction, unbuilt-project\n * detection, junk filtering, path normalization, entry-point and limit\n * validation, all reachable by direct call. `useDrop` is a state machine over\n * this; a non-React consumer can call it directly.\n */\nimport { filterJunk, pluralize, validateFiles } from '@shipstatic/ship';\nimport {\n FileValidationStatus,\n hasUnbuiltMarker,\n isShipError,\n type PlatformLimits,\n type ValidatableFile,\n} from '@shipstatic/types';\nimport { applyStatus, createProcessedFile, filePath, stripCommonPrefix } from './files';\nimport type { DropStatus, ProcessedFile } from './types';\nimport { extractZipToFiles, isZipFile } from './zip';\n\nexport interface ProcessFilesOptions {\n /** Platform limits, from `ship.getLimits()` */\n limits: PlatformLimits;\n /** Progress reporter for long steps */\n onStatus?: (status: DropStatus) => void;\n}\n\n/**\n * The verdict. Mirrors the hook's state minus `isDragging`, which is a pointer\n * concern the pipeline knows nothing about.\n *\n * Ready files are `files.filter(f => f.status === FileValidationStatus.READY)` — kept as\n * one derivation rather than a second field that could disagree with the first.\n */\nexport interface DropOutcome {\n phase: 'ready' | 'error';\n files: ProcessedFile[];\n sourceName: string;\n status: DropStatus;\n needsBuild: boolean;\n}\n\n/**\n * The exact shape drop hands to Ship's validator.\n *\n * **The deploy path is the name.** Server-side validation runs on full paths, so\n * sending the basename would validate a different string than the platform will.\n * `ProcessedFile` is not passed through directly even though it satisfies\n * `ValidatableFile`, because its `name` is the display basename.\n */\nexport function toValidatable(file: ProcessedFile): ValidatableFile {\n return { name: file.path, size: file.size };\n}\n\n/** A friendly name for whatever the user dropped. */\nexport function detectSourceName(files: File[]): string {\n if (files.length === 0) return '';\n\n const [first] = files;\n if (files.length === 1 && isZipFile(first)) return first.name.replace(/\\.zip$/i, '');\n\n // A folder drop/selection carries its root in webkitRelativePath\n const path = first.webkitRelativePath || '';\n return path.includes('/') ? path.split('/')[0] : first.name;\n}\n\nfunction failure(params: {\n title: string;\n details: string;\n errors?: string[];\n files?: ProcessedFile[];\n sourceName: string;\n needsBuild?: boolean;\n}): DropOutcome {\n const { title, details, errors, files = [], sourceName, needsBuild = false } = params;\n return {\n phase: 'error',\n files,\n sourceName,\n needsBuild,\n // `details` carries the single user-facing message; `errors` is for per-item\n // breakdowns. Omitted when empty, otherwise consumers that render both\n // fields show the message twice.\n status: { title, details, ...(errors?.length ? { errors } : {}) },\n };\n}\n\n/**\n * Run the pipeline.\n *\n * Never throws: an unbuilt project rejected by `filterJunk`, a missing entry\n * point, a file over the limit, and an unexpected host-object failure all come\n * back as an `error` outcome. Callers need no try/catch.\n */\nexport async function processFiles(\n input: File[],\n { limits, onStatus }: ProcessFilesOptions,\n): Promise<DropOutcome> {\n // Assigned inside the try: reading `webkitRelativePath` touches host objects,\n // and the no-throw guarantee has to cover the very first one.\n let sourceName = '';\n\n try {\n sourceName = detectSourceName(input);\n\n // Step 1: a lone ZIP is extracted; ZIPs among several files stay as files\n let files: File[];\n if (input.length === 1 && isZipFile(input[0])) {\n onStatus?.({ title: 'Extracting...', details: `Extracting ${input[0].name}...` });\n const { files: extracted, errors } = await extractZipToFiles(input[0]);\n if (errors.length > 0) console.warn('ZIP extraction errors:', errors);\n files = extracted;\n } else {\n files = input;\n }\n\n // Step 2: unbuilt-project detection. When the server will build, source\n // files are legitimate input rather than a mistake.\n const needsBuild = files.some((f) => hasUnbuiltMarker(filePath(f)));\n\n // Strip node_modules for build uploads. Drag-drop skips it during traversal;\n // the folder picker (webkitdirectory) hands it over anyway.\n if (needsBuild) {\n files = files.filter(\n (f) => !filePath(f).replace(/\\\\/g, '/').split('/').includes('node_modules'),\n );\n }\n\n // Step 3: junk filtering (throws ShipError on an unbuilt project unless allowed)\n const kept = new Set(filterJunk(files.map(filePath), { allowUnbuilt: needsBuild }));\n\n // Step 4: convert to ProcessedFile, then strip the common directory prefix.\n // Empty files are kept — validation marks them EXCLUDED with a warning\n // rather than failing the deploy.\n const finalFiles = stripCommonPrefix(\n files.filter((f) => kept.has(filePath(f))).map((f) => createProcessedFile(f)),\n );\n\n // Step 5: entry point. A built site must serve index.html from the root; an\n // unbuilt project may keep it anywhere, since the build decides the output.\n if (finalFiles.length > 0) {\n const hasIndex = needsBuild\n ? finalFiles.some((f) => f.path === 'index.html' || f.path.endsWith('/index.html'))\n : finalFiles.some((f) => f.path === 'index.html');\n\n if (!hasIndex) {\n const details = needsBuild\n ? 'No index.html found — every web project needs an index.html entry point'\n : 'No index.html at root — the entry point must be in the top-level directory';\n return failure({\n title: 'Validation Failed',\n details,\n sourceName,\n needsBuild,\n files: applyStatus(finalFiles, FileValidationStatus.VALIDATION_FAILED, details),\n });\n }\n }\n\n // Step 6: build uploads skip deploy validation — the build service validates\n // its own output, and source files are not deploy output.\n if (needsBuild) {\n const ready = applyStatus(finalFiles, FileValidationStatus.READY);\n return {\n phase: 'ready',\n files: ready,\n sourceName,\n needsBuild: true,\n status: {\n title: 'Ready',\n details: `${pluralize(ready.length, 'file', 'files', true)} ready — project will be built`,\n },\n };\n }\n\n // Step 7: validate against platform limits\n const validation = validateFiles(finalFiles.map(toValidatable), limits);\n\n const validated = finalFiles.map((file, i) => ({\n ...file,\n status: validation.files[i]?.status ?? file.status,\n statusMessage: validation.files[i]?.statusMessage ?? file.statusMessage,\n }));\n\n // Atomic validation: any error fails the whole set\n if (!validation.canDeploy) {\n return failure({\n title: 'Validation Failed',\n details: `${pluralize(validation.errors.length, 'file', 'files', true)} failed validation`,\n errors: validation.errors.map((e) => `${e.file}: ${e.message}`),\n files: validated,\n sourceName,\n });\n }\n\n const readyCount = validated.filter((f) => f.status === FileValidationStatus.READY).length;\n const warnings = validation.warnings.map((w) => `${w.file}: ${w.message}`);\n\n if (readyCount > 0) {\n let details = `${pluralize(readyCount, 'file', 'files', true)} ready`;\n if (validation.warnings.length > 0) {\n details += ` (${pluralize(validation.warnings.length, 'empty file', 'empty files', true)} excluded)`;\n }\n return {\n phase: 'ready',\n files: validated,\n sourceName,\n needsBuild: false,\n status: { title: 'Ready', details, ...(warnings.length ? { warnings } : {}) },\n };\n }\n\n // Nothing deployable. Warnings alone (e.g. every file empty) is not an error\n // state — no ready files already disables the deploy action.\n if (validation.errors.length === 0 && validation.warnings.length > 0) {\n return {\n phase: 'ready',\n files: validated,\n sourceName,\n needsBuild: false,\n status: {\n title: 'All files excluded',\n details: `${pluralize(validation.warnings.length, 'file', 'files', true)} excluded (empty files cannot be deployed)`,\n warnings,\n },\n };\n }\n\n return failure({\n title: 'No Valid Files',\n details: 'None of the provided files could be processed.',\n files: validated,\n sourceName,\n });\n } catch (error) {\n // A ShipError here is a validation rejection thrown by filterJunk (unbuilt\n // project); anything else is an unexpected processing failure.\n const message = error instanceof Error ? error.message : String(error);\n const isValidation = isShipError(error);\n return failure({\n title: isValidation ? 'Validation Failed' : 'Processing Failed',\n details: isValidation ? message : `Failed to process files: ${message}`,\n sourceName,\n });\n }\n}\n","/**\n * `FileSystemEntry` traversal — the drag-and-drop folder API.\n *\n * This module is alone in its file for a testing reason that is also an\n * architectural one: `FileSystemEntry` objects cannot be constructed. They come\n * from a real user gesture over real OS paths, so no browser — Chromium\n * included — lets a test produce one. Every OTHER module in this package is\n * exercised against real platform objects; this is the single boundary where a\n * fake is unavoidable, and keeping it to one file keeps that statement true.\n */\nimport { setRelativePath } from './files';\n\n/**\n * Recursively collect Files from a dropped entry, setting `webkitRelativePath`\n * so folder structure survives.\n *\n * `node_modules` directories are skipped wholesale — never part of a valid\n * deployment, and traversing one costs real time on a source-project drop\n * (50K+ files).\n *\n * Unreadable entries are logged and skipped rather than failing the drop: a\n * partially readable folder still deploys.\n */\nexport async function traverseFileTree(\n entry: FileSystemEntry,\n files: File[],\n currentPath = '',\n): Promise<void> {\n try {\n if (entry.isFile) {\n const file = await new Promise<File>((resolve, reject) => {\n (entry as FileSystemFileEntry).file(resolve, reject);\n });\n setRelativePath(file, currentPath ? `${currentPath}/${file.name}` : file.name);\n files.push(file);\n return;\n }\n\n if (!entry.isDirectory) return;\n\n for (const child of await readDirectory(entry as FileSystemDirectoryEntry)) {\n if (child.isDirectory && child.name === 'node_modules') continue;\n\n // Entering a directory extends the path; a file's own name is appended by\n // the branch above, so it inherits the current path unchanged.\n const childPath = child.isDirectory\n ? currentPath\n ? `${currentPath}/${child.name}`\n : child.name\n : currentPath;\n await traverseFileTree(child, files, childPath);\n }\n } catch (error) {\n console.warn(`Error traversing file tree for entry ${entry.name}:`, error);\n }\n}\n\n/**\n * Read a directory to exhaustion.\n *\n * `readEntries` yields at most 100 entries per call and signals the end with an\n * empty batch, so a single call silently truncates any larger folder. Looping\n * until empty is the contract, not an optimization.\n */\nasync function readDirectory(directory: FileSystemDirectoryEntry): Promise<FileSystemEntry[]> {\n const reader = directory.createReader();\n const entries: FileSystemEntry[] = [];\n\n for (;;) {\n const batch = await new Promise<FileSystemEntry[]>((resolve, reject) => {\n reader.readEntries(resolve, reject);\n });\n if (batch.length === 0) return entries;\n entries.push(...batch);\n }\n}\n","/**\n * Headless drop hook for file upload workflows.\n *\n * This file owns React state, DOM events, and prop getters — nothing else. The\n * rules live in `./process` as a plain function.\n *\n * ```tsx\n * const drop = useDrop({ ship });\n *\n * <div {...drop.getDropzoneProps()}>\n * <input {...drop.getInputProps()} />\n * {drop.isDragging ? 'Drop here' : 'Click to upload'}\n * </div>\n * ```\n */\nimport type { Ship } from '@shipstatic/ship';\nimport { FileValidationStatus, WEB_FILE_ACCEPT } from '@shipstatic/types';\nimport { useCallback, useMemo, useRef, useState } from 'react';\nimport { traverseFileTree } from './entries';\nimport { setRelativePath } from './files';\nimport { processFiles as runPipeline } from './process';\nimport type { DropPhase, DropStatus, ProcessedFile } from './types';\n\nexport interface DropOptions {\n /**\n * The Ship client, for platform limits.\n *\n * Typed as only what drop calls, mirroring the SDK's own resource-factory\n * doctrine — a real `Ship` satisfies it, and nothing else has to be faked.\n */\n ship: Pick<Ship, 'getLimits'>;\n}\n\n/** Options for `getDropzoneProps()` */\nexport interface DropzonePropsOptions {\n /** Whether clicking the dropzone opens the file picker (default: true) */\n clickable?: boolean;\n}\n\n/**\n * Which picker `getInputProps()` describes and `open()` opens.\n *\n * **Folder is the default**, so a bare `getInputProps()` / `open()` — and the\n * dropzone's own click — address the folder picker exactly as they always have.\n *\n * The singular/plural mix is deliberate: you pick one folder or many files, and\n * these are the words the buttons above them carry.\n */\nexport type PickerMode = 'folder' | 'files';\n\n/**\n * The hidden input to spread onto an `<input>`.\n *\n * One shape for both modes, because exactly one attribute distinguishes them:\n * `webkitdirectory` makes the dialog a folder picker, and `accept` biases a file\n * picker's default view. Never both — a folder picker ignores `accept`, so\n * emitting it there would advertise a filter that does not apply.\n */\nexport interface DropInputProps {\n ref: React.RefObject<HTMLInputElement | null>;\n type: 'file';\n style: { display: string };\n multiple: boolean;\n /** Folder mode only — the attribute that makes it a folder picker. */\n webkitdirectory?: string;\n /**\n * Files mode only. A HINT, not a gate: every dialog offers an all-files\n * escape and drag-and-drop ignores `accept` outright, so the verdict on any\n * file is `validateFiles` downstream — the same one the dropzone reaches.\n */\n accept?: string;\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;\n}\n\nexport interface DropReturn {\n /** Current phase of the lifecycle */\n phase: DropPhase;\n /** Whether files are being processed (extraction, validation) */\n isProcessing: boolean;\n /** Whether the user is currently dragging over the dropzone */\n isDragging: boolean;\n /** Whether the dropzone is idle or holding a ready set */\n isInteractive: boolean;\n /** Whether an error occurred during processing */\n hasError: boolean;\n /** All processed files */\n files: ProcessedFile[];\n /** Friendly name of what was dropped (ZIP name, folder name, or filename) */\n sourceName: string;\n /** Current status for display */\n status: DropStatus | null;\n /** Whether the dropped files need server-side building before deployment */\n needsBuild: boolean;\n\n /** Props to spread on the dropzone element (drag & drop, optionally click) */\n getDropzoneProps: (options?: DropzonePropsOptions) => {\n onDragOver: (e: React.DragEvent) => void;\n onDragLeave: (e: React.DragEvent) => void;\n onDrop: (e: React.DragEvent) => void;\n onClick?: () => void;\n };\n /**\n * Props to spread on a hidden file input element, one per picker mode.\n *\n * Each mode owns its own element and its own ref, so a UI offering both\n * renders both inputs — `open(mode)` clicks whichever is mounted.\n */\n getInputProps: (mode?: PickerMode) => DropInputProps;\n\n /** Programmatically trigger a picker (default: the folder picker) */\n open: (mode?: PickerMode) => void;\n /** Process files directly (advanced — loses folder traversal) */\n processFiles: (files: File[]) => Promise<void>;\n /** Reset state and clear all files */\n reset: () => void;\n\n /** Only the files that passed validation */\n validFiles: ProcessedFile[];\n /** Raw File objects ready for Ship SDK upload */\n getFilesForUpload: () => File[];\n}\n\ninterface DropState {\n phase: DropPhase;\n isDragging: boolean;\n files: ProcessedFile[];\n sourceName: string;\n status: DropStatus | null;\n needsBuild: boolean;\n}\n\nconst initialState: DropState = {\n phase: 'idle',\n isDragging: false,\n files: [],\n sourceName: '',\n status: null,\n needsBuild: false,\n};\n\nexport function useDrop({ ship }: DropOptions): DropReturn {\n const [state, setState] = useState<DropState>(initialState);\n\n // Synchronous re-entry guard — React state is too late to gate a second drop\n const isProcessingRef = useRef(false);\n // One ref per picker: an <input> is either a folder picker or a file picker,\n // and toggling `webkitdirectory` on a live node to reuse a single element\n // would mean writing an attribute behind React's back.\n const folderInputRef = useRef<HTMLInputElement>(null);\n const filesInputRef = useRef<HTMLInputElement>(null);\n\n const isProcessing = state.phase === 'processing';\n const hasError = state.phase === 'error';\n const isInteractive = state.phase === 'idle' || state.phase === 'ready';\n\n const validFiles = useMemo(\n () => state.files.filter((f) => f.status === FileValidationStatus.READY),\n [state.files],\n );\n\n const getFilesForUpload = useCallback(() => validFiles.map((f) => f.file), [validFiles]);\n\n const processFiles = useCallback(\n async (newFiles: File[]) => {\n if (isProcessingRef.current) {\n console.warn('File processing already in progress. Ignoring duplicate call.');\n return;\n }\n if (!newFiles || newFiles.length === 0) return;\n\n isProcessingRef.current = true;\n setState({\n ...initialState,\n phase: 'processing',\n status: { title: 'Processing...', details: 'Validating and preparing files.' },\n });\n\n try {\n const outcome = await runPipeline(newFiles, {\n limits: await ship.getLimits(),\n onStatus: (status) => setState((prev) => ({ ...prev, status })),\n });\n\n setState({\n phase: outcome.phase,\n isDragging: false,\n files: outcome.files,\n sourceName: outcome.sourceName,\n status: outcome.status,\n needsBuild: outcome.needsBuild,\n });\n } finally {\n isProcessingRef.current = false;\n }\n },\n [ship],\n );\n\n const reset = useCallback(() => {\n setState(initialState);\n isProcessingRef.current = false;\n }, []);\n\n // Dragging is orthogonal to the phase: the flag flips, the phase is untouched.\n const handleDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n setState((prev) => (prev.isDragging ? prev : { ...prev, isDragging: true }));\n }, []);\n\n const handleDragLeave = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n setState((prev) => (prev.isDragging ? { ...prev, isDragging: false } : prev));\n }, []);\n\n const handleDrop = useCallback(\n async (e: React.DragEvent) => {\n e.preventDefault();\n setState((prev) => (prev.isDragging ? { ...prev, isDragging: false } : prev));\n\n const files: File[] = [];\n const directories: { entry: FileSystemEntry; path: string }[] = [];\n\n // `dataTransfer.items` is only valid synchronously — the browser\n // invalidates the list at the first await, so every entry is captured here\n // and traversed afterwards.\n for (const item of Array.from(e.dataTransfer.items)) {\n if (item.kind !== 'file') continue;\n try {\n const entry = item.webkitGetAsEntry?.();\n if (entry?.isDirectory) {\n directories.push({ entry, path: entry.name });\n } else {\n const file = item.getAsFile();\n if (file) {\n // Root files carry their own name as path, matching traverseFileTree\n setRelativePath(file, file.name);\n files.push(file);\n }\n }\n } catch (error) {\n console.warn('Error processing drop item:', error);\n const file = item.getAsFile();\n if (file) files.push(file);\n }\n }\n\n await Promise.all(directories.map((d) => traverseFileTree(d.entry, files, d.path)));\n\n // Browsers without webkitGetAsEntry still populate dataTransfer.files\n if (files.length === 0 && e.dataTransfer.files.length > 0) {\n files.push(...Array.from(e.dataTransfer.files));\n }\n\n if (files.length > 0) await processFiles(files);\n },\n [processFiles],\n );\n\n const handleInputChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const files = Array.from(e.target.files || []);\n if (files.length > 0) processFiles(files);\n // Clear the input so re-selecting the same folder fires onChange again\n e.target.value = '';\n },\n [processFiles],\n );\n\n // `files` is the exception, so any other value — including a stray argument —\n // resolves to the folder picker, and the default is written once.\n const open = useCallback((mode?: PickerMode) => {\n const input = mode === 'files' ? filesInputRef.current : folderInputRef.current;\n if (!input) {\n console.warn(\n `No ${mode === 'files' ? 'files' : 'folder'} input is mounted. Spread getInputProps('${mode === 'files' ? 'files' : 'folder'}') onto an <input> to open this picker.`,\n );\n return;\n }\n input.click();\n }, []);\n\n const getDropzoneProps = useCallback(\n (options?: DropzonePropsOptions) => {\n const { clickable = true } = options ?? {};\n return {\n onDragOver: handleDragOver,\n onDragLeave: handleDragLeave,\n onDrop: handleDrop,\n // Wrapped rather than passed by reference: `open` takes a mode, and a\n // click handler would hand it a MouseEvent.\n ...(clickable && { onClick: () => open() }),\n };\n },\n [handleDragOver, handleDragLeave, handleDrop, open],\n );\n\n const getInputProps = useCallback(\n (mode?: PickerMode): DropInputProps => ({\n ref: mode === 'files' ? filesInputRef : folderInputRef,\n type: 'file' as const,\n style: { display: 'none' },\n multiple: true,\n ...(mode === 'files' ? { accept: WEB_FILE_ACCEPT } : { webkitdirectory: '' }),\n onChange: handleInputChange,\n }),\n [handleInputChange],\n );\n\n return {\n phase: state.phase,\n isProcessing,\n isDragging: state.isDragging,\n isInteractive,\n hasError,\n files: state.files,\n sourceName: state.sourceName,\n status: state.status,\n needsBuild: state.needsBuild,\n\n getDropzoneProps,\n getInputProps,\n\n open,\n processFiles,\n reset,\n\n validFiles,\n getFilesForUpload,\n };\n}\n"]}
1
+ {"version":3,"sources":["../node_modules/.pnpm/@shipstatic+types@2.13.0-beta.1/node_modules/@shipstatic/types/dist/index.js","../src/files.ts","../node_modules/.pnpm/fflate@0.8.3/node_modules/fflate/esm/browser.js","../src/zip.ts","../src/process.ts","../src/entries.ts","../src/useDrop.ts"],"names":["filePath","err","l","td","dat","_a","i","e","processFiles"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @file Shared TypeScript types, constants, and utilities for the ShipStatic platform.\n * This package is the single source of truth for all shared data structures.\n */\n// =============================================================================\n// DEPLOYMENT TYPES\n// =============================================================================\n/**\n * Deployment status constants\n */\nexport const DeploymentStatus = {\n PENDING: 'pending',\n SUCCESS: 'success',\n FAILED: 'failed',\n DELETING: 'deleting',\n};\n/**\n * Where a deployment came from — the origin-tracking vocabulary.\n *\n * A closed set with many authors. It lived in the API's config until\n * 2026-08-06, where being server-side made it unenforceable in the one\n * direction that matters — every client wrote a bare string, and a value\n * outside the set was **silently dropped** by the server, so a typo did not\n * fail anywhere. It stopped recording where deploys came from and said nothing.\n *\n * **The origin law: origin is declared by whatever we control — our code where\n * we ship code, our URL where we ship only a URL.** One rule decides every\n * member here and every future one:\n *\n * - **Where the platform ships CODE, the code declares it.** `web`, `sdk`,\n * `cli`, `git`, `n8n` and `vsc` are surfaces this platform authors, so each\n * names itself in its own source and nothing external is needed to tell them\n * apart.\n * - **Where the platform ships only a URL, the URL declares it.** A\n * marketplace listing runs somebody else's client against a bare endpoint —\n * every one of them the same server speaking the same protocol, and\n * indistinguishable in a request. The only thing such a listing's traffic\n * has in common is the URL its users were handed, so the hosted MCP serves\n * one DOOR per listing and the door's path IS the value: `gpt`, `cld`,\n * `crs`.\n *\n * **A member names the most specific surface the platform can honestly\n * claim**, which is what makes the two FALLBACKS fallbacks rather than peers\n * of the named surfaces. `mcp` is any MCP host that was never handed a door of\n * its own; `api` is a call that reached the REST API naming nothing at all.\n * Guessing past either would be inventing attribution rather than recording\n * it, which is the one thing this vocabulary exists to prevent.\n *\n * Every member is three lowercase characters — the property that lets a\n * channel door's path and its attribution be spelled the same. The suite pins\n * both the width and the channel members by name.\n */\nexport const DeploymentVia = {\n /** The web dashboard. */\n WEB: 'web',\n /** A program embedding the SDK directly. */\n SDK: 'sdk',\n /** The `ship` CLI. */\n CLI: 'cli',\n /** Any MCP host with no door of its own — the stdio server included. The family fallback. */\n MCP: 'mcp',\n /** The GitHub Action. */\n GIT: 'git',\n /** The n8n community node. */\n N8N: 'n8n',\n /** Channel: the ChatGPT App listing → `mcp.<domain>/gpt`. */\n GPT: 'gpt',\n /** The VS Code extension. */\n VSC: 'vsc',\n /** Channel: the Claude connectors directory listing → `mcp.<domain>/cld`. */\n CLD: 'cld',\n /** Channel: the Cursor marketplace listing → `mcp.<domain>/crs`. */\n CRS: 'crs',\n /**\n * A deploy that reached the REST API naming no origin at all — the\n * platform-wide fallback, one altitude below `mcp`'s family fallback.\n *\n * **The API stamps it, since 2026-08-15.** A deploy that names no origin —\n * or names one this vocabulary does not know — is stored as `api`, so a\n * stored `null` now means only that the row predates attribution.\n *\n * It was declared one wave ahead of that decision, deliberately: vocabulary\n * must exist before a consumer can adopt it, and adding a member costs a\n * full constellation convoy, so the word shipped first and the server\n * adopted it with no convoy standing between the decision and the deploy.\n */\n API: 'api',\n};\n// =============================================================================\n// DOMAIN TYPES\n// =============================================================================\n/**\n * Domain status constants\n *\n * - PENDING: DNS not configured\n * - PARTIAL: DNS partially configured\n * - SUCCESS: DNS fully verified\n * - PAUSED: Domain paused due to plan enforcement (billing)\n */\nexport const DomainStatus = {\n PENDING: 'pending',\n PARTIAL: 'partial',\n SUCCESS: 'success',\n PAUSED: 'paused',\n};\n/**\n * The envelope an `Idempotency-Key` must fit, and how long a replay lasts.\n *\n * Format lives here rather than on the server alone by the format-vs-policy\n * rule: a client can decide offline whether a key is well-formed, and the\n * API would reject the same value the same way.\n */\nexport const IDEMPOTENCY_KEY_CONSTRAINTS = {\n /**\n * HTTP header name. Here for the same reason {@link CALLER.HEADER} is: a\n * wire header has two ends, and the package that owns the value's format\n * is the only place both ends can read its name from.\n */\n HEADER: 'Idempotency-Key',\n MAX_LENGTH: 256,\n /** How long a stored 201 stays replayable. */\n WINDOW_SECONDS: 24 * 60 * 60,\n};\n/**\n * Normalize a `via` value from any transport — trimmed, lowercased, and a\n * member of {@link DeploymentVia}, or `undefined`.\n *\n * A format rule by this package's own test: a client can decide offline\n * whether a value is well-formed, and the API reaches the same verdict on the\n * same input. It lived server-side until 2026-08-06, which meant clients could\n * only learn their label was unusable by noticing analytics had gone quiet.\n *\n * **Not knowing your `via` is not an error** — an unrecognized value yields\n * `undefined` rather than throwing, because origin tracking is telemetry and a\n * deploy must never fail over it. A caller that has an honest default should\n * prefer it (`normalizeVia(process.env.SHIP_VIA) ?? DeploymentVia.CLI`): the\n * deploy really did come from the CLI, so recording that beats recording\n * nothing.\n */\nexport function normalizeVia(value) {\n if (!value || typeof value !== 'string')\n return undefined;\n const via = value.trim().toLowerCase();\n return Object.values(DeploymentVia).includes(via)\n ? via\n : undefined;\n}\n/**\n * Validate an idempotency key, returning the trimmed value or `undefined`\n * when none was supplied. Throws {@link ShipError.validation} when the value\n * cannot be sent — the same verdict the API would reach, reached earlier.\n */\nexport function validateIdempotencyKey(value) {\n if (value === undefined || value === null)\n return undefined;\n if (typeof value !== 'string') {\n throw ShipError.validation('Idempotency key must be a string.');\n }\n const key = value.trim();\n if (!key) {\n throw ShipError.validation('Idempotency key must not be empty.');\n }\n if (key.length > IDEMPOTENCY_KEY_CONSTRAINTS.MAX_LENGTH) {\n throw ShipError.validation(`Idempotency key must be at most ${IDEMPOTENCY_KEY_CONSTRAINTS.MAX_LENGTH} characters.`);\n }\n return key;\n}\n// =============================================================================\n// ACCOUNT TYPES\n// =============================================================================\n/**\n * Every plan an account can hold — the platform's whole plan vocabulary, in\n * one place, and nothing about what a plan is WORTH.\n *\n * A plan is a TIER and nothing else. Whether an account may act is a separate\n * fact (`Account.suspended`; deletion ends the session outright), so an\n * account keeps its tier through suspension and into deletion.\n *\n * - **Free** — `free`.\n * - **Billed** — `pro`. The one plan a customer can buy; the only plan Stripe\n * knows about, and the only one the platform never sets by hand — it is\n * derived from the Stripe subscription.\n * - **Granted** — `scale`, `sponsored`. Paid plans the operator confers by\n * hand; no Stripe subscription, no Checkout, no Stripe object at all.\n *\n * The numbers each plan confers — caps, sizes — are POLICY and are delivered\n * by the API (`GET /plans`, `GET /account`, `GET /limits`), never published\n * here: a price or a cap in a published package is pinned to whatever version\n * a client installed (`CLAUDE.md`, \"Validation: format vs policy\").\n */\nexport const AccountPlan = {\n FREE: 'free',\n PRO: 'pro',\n SCALE: 'scale',\n SPONSORED: 'sponsored',\n};\n// =============================================================================\n// WIRE SURFACE\n// =============================================================================\n/**\n * Every path the public API answers on, declared once.\n *\n * The URL surface was written out in four places — the API's mounts, the\n * SDK's client, the dashboard's client, and the post-deploy smoke — so a\n * rename meant finding all four. The first three now read this table.\n *\n * The smoke (`cloudflare/api/smoke.mjs`) deliberately still spells its own:\n * five of its nine paths are `/admin/*`, which this table excludes by\n * design, and splitting one list between a registry and literals reads worse\n * than keeping it uniform.\n *\n * **What this guarantees, exactly.** Collection paths are mounted from here,\n * so producer and consumer cannot diverge. Item paths are declared here and\n * consumed by clients, but the API spells them relative to their mount\n * (`/:deployment/config`), so the table does not *generate* them — it is\n * held to them by `api/tests/architecture/api-paths.test.ts`, which fails if\n * any entry names a path no route answers. Some entries have no client yet\n * (`DEPLOYMENT_CONFIG`, `DOMAIN_PROPAGATION` — endpoints the SDK\n * deliberately does not reach); the fence is what keeps those honest rather\n * than merely asserted.\n *\n * **The operator surface is deliberately absent.** `/admin/*` paths belong\n * to `web/my`, for the same reason its row types do: this package is\n * published, and the operator surface is not public (see `CLAUDE.md`, \"Admin\n * types\"). A path here is a promise to every npm consumer; `/admin` is a\n * promise to one dashboard.\n *\n * Item paths are functions rather than templates so the key is interpolated\n * in one place, encoded the same way by every caller.\n */\nexport const API_PATHS = {\n DEPLOYMENTS: '/deployments',\n DEPLOYMENT: (deployment) => `/deployments/${deployment}`,\n DEPLOYMENT_CONFIG: (deployment) => `/deployments/${deployment}/config`,\n DOMAINS: '/domains',\n DOMAIN: (domain) => `/domains/${domain}`,\n DOMAIN_VERIFY: (domain) => `/domains/${domain}/verify`,\n DOMAIN_DNS: (domain) => `/domains/${domain}/dns`,\n DOMAIN_RECORDS: (domain) => `/domains/${domain}/records`,\n DOMAIN_SHARE: (domain) => `/domains/${domain}/share`,\n DOMAIN_PROPAGATION: (domain) => `/domains/${domain}/propagation`,\n DOMAINS_VALIDATE: '/domains/validate',\n TOKENS: '/tokens',\n TOKEN: (token) => `/tokens/${token}`,\n ACCOUNT: '/account',\n ACCOUNT_KEY: '/account/key',\n ACCOUNT_CLAIM: '/account/claim',\n ACTIVITIES: '/activities',\n LABELS: '/labels',\n LIMITS: '/limits',\n PLANS: '/plans',\n PING: '/ping',\n SETUP: '/setup',\n SPA_CHECK: '/spa-check',\n UPLOAD: '/upload',\n};\n/**\n * The deploy request's multipart field names — the other half of the wire\n * surface beside {@link API_PATHS}. `POST /deployments` (and the first-party\n * `/upload`) is multipart/form-data, and these are the names the API reads.\n *\n * Declared once because the body has three independent WRITERS — the SDK's\n * Node and browser body builders, and the n8n community node's hand-rolled\n * client (which cannot import this under n8n Cloud's zero-dependency rule,\n * and fences its restated copy instead) — and until this export every writer\n * restated the strings the API parses, with nothing comparing them.\n *\n * `FILES` carries one entry per file (the API reads it with `getAll`); every\n * other field is single. The `@internal` flags are serialized as the literal\n * string `'true'` and belong to first-party surfaces only.\n */\nexport const DEPLOY_FIELDS = {\n /** One entry per file — read with `getAll`. */\n FILES: 'files[]',\n /** JSON array of MD5 hex digests, index-aligned with `FILES`. */\n CHECKSUMS: 'checksums',\n /** JSON array of label strings. */\n LABELS: 'labels',\n /** The deploying surface's {@link DeploymentVia} member. */\n VIA: 'via',\n /** Plaintext password — the API hashes it server-side. */\n PASSWORD: 'password',\n /**\n * Requested lifetime in SECONDS — a duration, never an instant. The API\n * computes and stores the expiry, so the wire carries no client clock.\n * See {@link validateTtl}.\n */\n TTL: 'ttl',\n /** @internal Server-processing flag — first-party `/upload` only. */\n BUILD: 'build',\n /** @internal Server-processing flag — first-party `/upload` only. */\n PRERENDER: 'prerender',\n /** @internal Server-processing flag — first-party `/upload` only. */\n SPA: 'spa',\n /** @internal reCAPTCHA proof — `web/www`'s public uploader only. */\n CAPTCHA: 'captcha',\n};\n// =============================================================================\n// ERROR SYSTEM\n// =============================================================================\n/**\n * All possible error types in the ShipStatic platform.\n *\n * Developer-friendly key names map to stable wire-format string values.\n * Both the value and the type are exported under the same name so callers\n * can use `ErrorType.Validation` (value comparison) and `: ErrorType` (type\n * annotation) without ceremony — matching the pattern other status objects\n * (`DeploymentStatus`, `DomainStatus`, `AccountPlan`, `AuthMethod`) follow.\n */\nexport const ErrorType = {\n /**\n * Validation failed. Input shape is wrong.\n *\n * Carries 400 when an API judged it — including a client-side pre-check of a\n * rule the server enforces too, which keeps the error identical wherever it\n * was caught. **Statusless** when a client rejects something no API judges,\n * such as a CLI's own command grammar: `status` is documented \"(API\n * contexts)\" on `ErrorResponse`, so there is none to report.\n */\n Validation: 'validation_failed',\n /** Resource not found (404). */\n NotFound: 'not_found',\n /** Authenticated but not allowed (403). User lacks permission for this action. */\n Forbidden: 'forbidden',\n /** Rate limit exceeded (429). */\n RateLimit: 'rate_limit_exceeded',\n /** Authentication required or failed (401). Missing/invalid credentials. */\n Authentication: 'authentication_failed',\n /** Business rule violation. Catch-all for 4xx state-rule errors that aren't more specific. */\n Business: 'business_logic_error',\n /** API server error (500). Generic server-side fault. */\n Api: 'internal_server_error',\n /**\n * The platform is closed for maintenance (503). A deliberate operator\n * state, not a fault — nothing errored; the API is refusing work on\n * purpose, and deployed sites keep serving throughout.\n *\n * Distinct from `Api` at 503, which the platform already uses for a\n * dependency that failed (moderation unavailable). A consumer has to tell\n * \"we closed the door\" from \"something broke\": the two get opposite words\n * and opposite retry behaviour.\n */\n Maintenance: 'maintenance',\n /** Network/connection error. Client-side only — set by HTTP clients on fetch failure; never produced server-side. */\n Network: 'network_error',\n /**\n * A deadline expired before the exchange completed. Client-side only — set\n * by HTTP clients when a timeout signal fires; never produced server-side.\n *\n * A member of the NETWORK category rather than a sibling of it:\n * `isNetworkError()` answers \"nothing was exchanged\", which is true of a\n * deadline exactly as it is of a refused connection, so every consumer that\n * retries, declines to report, or declines to relay a wire message on that\n * category is already right about a timeout. The distinct TYPE exists for\n * the one decision the category cannot make — what to SAY. \"Check your\n * internet connection\" is the wrong sentence for a five-minute deploy\n * ceiling, and a surface can only tell the two apart by type.\n *\n * The same relationship every comparable SDK ships:\n * `APIConnectionTimeoutError extends APIConnectionError`.\n */\n Timeout: 'timeout_error',\n /** Operation was cancelled. Client-side only — set on `AbortSignal` abort; never produced server-side. */\n Cancelled: 'operation_cancelled',\n /** File operation error. Client-side only — set by SDK during local file processing; never produced server-side. */\n File: 'file_error',\n /** Configuration error. Client-side only — set by SDK during config parsing/validation; never produced server-side. */\n Config: 'config_error',\n};\n/**\n * Error types that originate exclusively on the client (HTTP clients, SDK\n * file processing, local config parsing). These never appear on the wire\n * from the server, so `fromHttpResponse` will not trust them even if a\n * misbehaving server claims one in `body.error`.\n */\nconst CLIENT_ONLY_ERROR_TYPES = new Set([\n ErrorType.Network,\n ErrorType.Timeout,\n ErrorType.Cancelled,\n ErrorType.File,\n ErrorType.Config,\n]);\n/**\n * Categorizes error types for the `isClientError` / `isNetworkError` /\n * `isAuthError` helpers. Each `Set` is typed against the wider `ErrorType`\n * union so `.has(error.type)` accepts any value from the union.\n */\nconst ERROR_CATEGORIES = {\n /**\n * Client-attributable types. Exhaustive over the 4xx-carrying types, and\n * over the statusless ones too — those are raised locally and have no\n * status for `isClientError`'s second arm to read, so omitting one makes it\n * read as a server fault. The rule is the membership test: every type in\n * `CLIENT_ONLY_ERROR_TYPES` except the two `isNetworkError` owns belongs\n * here.\n *\n * `Cancelled` was missing until 2026-07-29, which is exactly that failure:\n * a caller who aborted their own deploy was told \"server error: please try\n * again\" — the CLI's fallback for everything this set does not claim.\n *\n * `Timeout` is deliberately NOT here, and it is the sharper case, because\n * it is the one client-only type that is not the client's fault: the\n * caller set a ceiling, but what exhausted it was the network or the\n * server. Reading it as client-attributable would say the caller erred,\n * and it would silently disarm every consumer whose retry predicate\n * declines `isClientError()` — a deadline is precisely the failure worth\n * a second attempt.\n */\n client: new Set([\n ErrorType.Business,\n ErrorType.Cancelled,\n ErrorType.Config,\n ErrorType.File,\n ErrorType.Forbidden,\n ErrorType.NotFound,\n ErrorType.RateLimit,\n ErrorType.Validation,\n ]),\n /**\n * The exchange never happened. Two types, one category: a refused\n * connection and an expired deadline differ in what a surface should SAY\n * and in nothing else a consumer decides on — both are retryable, neither\n * carries a wire message to relay, neither is worth reporting as an\n * incident. See `ErrorType.Timeout` for why the type is distinct anyway.\n */\n network: new Set([ErrorType.Network, ErrorType.Timeout]),\n auth: new Set([ErrorType.Authentication]),\n};\n/**\n * Error types the server can legitimately produce on the wire. Used by\n * `ShipError.fromHttpResponse` to validate the body's `error` field before\n * trusting it as `ShipError.type`. Derived by exclusion from\n * `CLIENT_ONLY_ERROR_TYPES` so adding a new server-producible type to\n * `ErrorType` is automatically picked up.\n */\nconst SERVER_PRODUCIBLE_ERROR_TYPES = new Set(Object.values(ErrorType).filter((t) => !CLIENT_ONLY_ERROR_TYPES.has(t)));\n/**\n * Ceiling on a message adopted from a **non-JSON** error body — a foreign\n * responder's, never this platform's. Generous for the plain-text one-liners\n * intermediaries actually send (`error code: 1015`), far below a document.\n * Our own messages are never measured against it: a JSON body is the API's\n * contract, and truncating a long validation message would be the bug.\n */\nconst MAX_FOREIGN_MESSAGE_LENGTH = 200;\n/**\n * Did the runtime say the exchange never completed?\n *\n * Clients branch on the TYPE, never on message strings, so a misclassified\n * transport failure is a lie every consumer inherits — and the one that costs\n * most: `Api` claims a server answered when nothing was exchanged, and a\n * retrying caller will not retry it.\n *\n * **Every row below is a transcript, not a belief.** Captured 2026-08-12\n * against real runtimes — Node and Bun by direct run, the three engines by a\n * one-off playwright probe, workerd through miniflare. The capture scripts are\n * in `tests/errors.test.ts`, \"runtime failure shapes\".\n *\n * | runtime | connection refused / DNS failure | malformed URL |\n * |------------------|------------------------------------------------------|--------------------------------------------------|\n * | Node 22 / undici | `TypeError: fetch failed` | `TypeError: Failed to parse URL from …` |\n * | Bun 1.3.14 | `Error` `code:'ConnectionRefused'` | `TypeError` `code:'ERR_INVALID_URL'` |\n * | Chromium 151 | `TypeError: Failed to fetch` | `TypeError: …Failed to parse URL from …` |\n * | Firefox 153 | `TypeError: NetworkError when attempting to fetch …` | `TypeError: … is not a valid URL.` |\n * | WebKit 26.5 | `TypeError: Load failed` | `TypeError: URL is not valid or contains user …` |\n * | workerd | `Error: Network connection lost.` (DNS: `internal error; reference = …`) | `TypeError: Invalid URL: …` |\n *\n * Reading that table gives the rule, and it is the INVERSE of the obvious one.\n * The transport class is unbounded — every OS, TLS and DNS failure any engine\n * will ever name — while the class fetch raises for its own ARGUMENTS is\n * small, and every runtime names the URL when it complains about one. So the\n * bounded side is the one worth testing, and the residual risk points the safe\n * way: an unrecognised sentence lands on `Network`, which says only that\n * nothing was exchanged.\n *\n * That inversion is what fixes **WebKit**, whose `Load failed` carries no code\n * and no \"fetch\", and which every browser-SDK and `@shipstatic/drop` user on\n * Safari was hitting as `Api`. It also makes the six runtimes AGREE about a\n * malformed URL, which they did not before: the previous rule tested the\n * message for \"fetch\", and Chromium's and Firefox's URL complaints both\n * contain it, so the same mistake was `Network` on three engines and `Api` on\n * three.\n *\n * **workerd is the recorded gap.** It rejects with a plain `Error`, no code\n * and no shared sentence — and its two failure modes produce two unrelated\n * ones — so nothing here can classify it and it lands on `Api`. Left alone\n * rather than patched with a dialect string: the one consumer running ship in\n * that runtime (`cloudflare/mcp`) reaches the API through a service BINDING,\n * which is in-process and does not produce transport rejections at all.\n *\n * **The `TokenProvider` case stopped being a trade when clients gained\n * retries.** A caller's provider that throws a coded error is typed `Network`\n * here, which was recorded as \"both are wrong for it; `Network` is the cheaper\n * wrong\" — written when the classification decided only what a surface would\n * SAY. It now also decides whether the call is retried, and that turns the\n * cheaper wrong into the right answer: a `TokenProvider` is where minting and\n * refresh live, so the common one is an OAuth refresh over the network, and a\n * transient failure there is precisely what another attempt repairs.\n *\n * The residual cost is a deterministic provider fault — a genuinely missing\n * keychain entry — invoking the provider three times over a few hundred\n * milliseconds before failing with the same error. No request leaves the\n * process on any of them. That is the cheap direction of a bet whose other\n * side is a refused deploy, and suppressing it would need a way to mark\n * credential faults non-retryable: machinery with one holder, refused by the\n * estate's stopping rule. Provider failures that carry no code are `Api` and\n * are not retried at all, and a provider yielding nothing is `Authentication`\n * by the fail-closed invariant, which is likewise terminal.\n */\nfunction isTransportFailure(cause) {\n const code = cause.code;\n // Bun is the one runtime that puts a CODE on an argument error, so it is\n // excluded before the code arm can claim it.\n if (code === 'ERR_INVALID_URL')\n return false;\n // A string `code` is a runtime naming a transport-level failure. An\n // allowlist of codes was written first and rejected — the TLS row alone\n // would mean enumerating BoringSSL's certificate table, and a code nobody\n // guessed is precisely the bug this closes. A `DOMException`'s code is a\n // NUMBER, so aborts and timeouts never reach here.\n if (typeof code === 'string')\n return true;\n // WHATWG has fetch reject with a TypeError for BOTH halves — network error\n // and argument error — so among TypeErrors the URL is the discriminator.\n if (cause instanceof TypeError)\n return !/\\burl\\b/i.test(cause.message);\n // Anything else — an ordinary JS fault, or workerd — is not evidence.\n return false;\n}\n/**\n * Simple unified error class for both API and SDK\n */\nexport class ShipError extends Error {\n type;\n status;\n details;\n constructor(type, message, status, details) {\n super(message);\n this.type = type;\n this.status = status;\n this.details = details;\n this.name = 'ShipError';\n }\n /** Convert to wire format */\n toResponse() {\n // Strip authentication details when they carry an `internal` telemetry\n // tag (see `ShipError.authentication` JSDoc) — these are server-side\n // diagnostics like 'session_invalid' that must not leak to clients.\n const authDetails = this.details;\n const details = this.type === ErrorType.Authentication && authDetails?.internal ? undefined : this.details;\n return {\n error: this.type,\n message: this.message,\n status: this.status,\n details,\n };\n }\n /**\n * Construct a `ShipError` from an HTTP error response.\n *\n * Best-effort body parse for `{ message, error?, details? }`. Message\n * resolution: `body.message` → `body.error` → `\"<operationName> failed with\n * status <N>\"`.\n *\n * Type resolution: trusts `body.error` when it's a known server-producible\n * `ErrorType` (preserves the wire's intent — server's\n * `ShipError.validation(...)` round-trips back to `ErrorType.Validation`\n * on the client). Falls back to status-derived (401 → Authentication,\n * 403 → Forbidden, 429 → RateLimit, else → Api) for non-API responses\n * (CDN errors, intermediaries) or malformed bodies. Client-only types\n * (`Network`, `Timeout`, `Cancelled`, `File`, `Config`) are filtered out of the\n * trusted set — a misbehaving server claiming one of those is ignored.\n *\n * `operationName` (e.g. `\"Get account\"`) is used to compose the fallback\n * message. Defaults to `\"Request\"`. Same convention as `fromFetchError`.\n *\n * Async because it reads the response body. Returns rather than throws so\n * callers can compose; most will `throw await ShipError.fromHttpResponse(...)`.\n */\n static async fromHttpResponse(response, operationName) {\n let message;\n let details;\n let bodyType;\n try {\n const contentType = response.headers.get('content-type');\n if (contentType?.includes('application/json')) {\n const json = await response.json();\n if (json && typeof json === 'object') {\n const obj = json;\n if (typeof obj.message === 'string')\n message = obj.message;\n else if (typeof obj.error === 'string')\n message = obj.error;\n details = obj.details;\n if (typeof obj.error === 'string' && SERVER_PRODUCIBLE_ERROR_TYPES.has(obj.error)) {\n bodyType = obj.error;\n }\n }\n }\n else {\n // A non-JSON body did not come from this platform — every API error\n // is `ErrorResponse` JSON — so it is an intermediary's output, and\n // the two kinds it produces need opposite treatment. A CDN's plain\n // `error code: 1015` is the most useful thing there is to say. A\n // proxy's HTML error page is a *document*, not a message: adopting it\n // verbatim made a misconfigured `apiUrl` print 2,059 characters of\n // markup as the error. Trust it only when it reads as a message.\n const text = (await response.text()).trim();\n if (text && !text.startsWith('<') && text.length <= MAX_FOREIGN_MESSAGE_LENGTH) {\n message = text;\n }\n }\n }\n catch {\n // Body unreadable; fall through to operationName-derived message.\n }\n // Rate-limit (and 503) timing rides the `Retry-After` HEADER, which a\n // body-only reader would drop. Lift it into `details` as seconds so\n // consumers can back off from the typed error alone, without keeping the\n // raw Response around. Body-carried fields are preserved and win.\n const retryAfterHeader = response.headers.get('retry-after');\n if (retryAfterHeader !== null) {\n const value = retryAfterHeader.trim();\n const seconds = /^\\d+$/.test(value)\n ? Number(value)\n : Math.ceil((Date.parse(value) - Date.now()) / 1000);\n if (Number.isFinite(seconds) && seconds >= 0) {\n const existing = details && typeof details === 'object' ? details : {};\n if (existing.retryAfter === undefined) {\n details = { ...existing, retryAfter: seconds };\n }\n }\n }\n message = message || `${operationName || 'Request'} failed with status ${response.status}`;\n const type = bodyType ??\n (response.status === 401\n ? ErrorType.Authentication\n : response.status === 403\n ? ErrorType.Forbidden\n : response.status === 429\n ? ErrorType.RateLimit\n : ErrorType.Api);\n return new ShipError(type, message, response.status, details);\n }\n /**\n * Construct a `ShipError` from an error caught around a `fetch()` call.\n *\n * The mirror of `fromHttpResponse` for the *other* side of the HTTP error\n * story — the network layer failing (offline, CORS, abort) rather than the\n * server returning a non-OK response.\n *\n * Routing:\n * - Already a `ShipError` → returned as-is (caller's intent preserved)\n * - `AbortError` → `ShipError.cancelled(...)` — someone stopped it on purpose\n * - `TimeoutError` → `ShipError.timeout(...)` — a deadline expired; the\n * message names the timeout, and the type is in the network CATEGORY\n * because nothing was exchanged\n * - A transport failure → `ShipError.network(...)` — see `isTransportFailure`\n * for what each runtime offers as evidence\n * - Any other `Error` → `ShipError(Api, ...)` (no HTTP status — fetch never reached the server)\n * - Anything else (string, undefined, etc.) → `ShipError(Api, ...)`\n *\n * **Abort and timeout are read from `name` BEFORE any `instanceof Error`\n * gate.** A `DOMException` satisfies that gate in every runtime measured\n * (Node, Bun, Chromium, Firefox, WebKit, workerd — all six), but the\n * inheritance is a comparatively recent spec change and this classification\n * has no reason to depend on it: `name` is where the meaning lives, and\n * reading it first costs nothing. The suite plants a non-`Error`\n * `DOMException` shape to hold the arm, since no runtime on the table\n * produces one.\n *\n * A caller's own `AbortSignal.timeout()` is the reachable source of\n * `TimeoutError` — and the two are NOT interchangeable per runtime: WebKit\n * reports a fired `AbortSignal.timeout()` as `AbortError`, so on Safari a\n * deadline is indistinguishable from a cancellation and lands on\n * `Cancelled`. Recorded rather than worked around; `Cancelled` is honest\n * there, since the caller's signal is what stopped it.\n *\n * The optional `operationName` is composed into the message for context:\n * `\"Get account was cancelled\"`, `\"Get account failed: ...\"`. Defaults to\n * `\"Request\"` when omitted.\n */\n static fromFetchError(cause, operationName) {\n if (isShipError(cause))\n return cause;\n const op = operationName || 'Request';\n // Read by NAME, ahead of the Error gate — see the note above.\n const name = cause?.name;\n if (name === 'AbortError') {\n return ShipError.cancelled(`${op} was cancelled`);\n }\n if (name === 'TimeoutError') {\n // A deadline: not a fault, not a cancellation, and — since it has its\n // own type — no longer merely \"network\". Nothing was exchanged, which\n // is what keeps it in the network CATEGORY and therefore retryable; the\n // type is what lets a surface say \"timed out\" instead of sending\n // someone to check their Wi-Fi. The runtime's own sentence is dropped\n // rather than relayed: \"The operation was aborted due to timeout\" is\n // the mechanism, not the news.\n return ShipError.timeout(`${op} timed out`, { cause });\n }\n if (cause instanceof Error) {\n if (isTransportFailure(cause)) {\n return ShipError.network(`${op} failed: ${cause.message}`, { cause });\n }\n return new ShipError(ErrorType.Api, `${op} failed: ${cause.message}`);\n }\n return new ShipError(ErrorType.Api, `${op} failed: Unknown error`);\n }\n // Factory methods. Uniform shape `(message, details?)` with two principled\n // exceptions: `notFound` composes its message from (resource, id?), and\n // `business` / `api` accept an optional status because they're the\n // multi-status fallbacks.\n static validation(message, details) {\n return new ShipError(ErrorType.Validation, message, 400, details);\n }\n static notFound(resource, id) {\n const message = id ? `${resource} ${id} not found` : `${resource} not found`;\n return new ShipError(ErrorType.NotFound, message, 404);\n }\n static forbidden(message, details) {\n return new ShipError(ErrorType.Forbidden, message, 403, details);\n }\n static rateLimit(message = 'Too many requests', details) {\n return new ShipError(ErrorType.RateLimit, message, 429, details);\n }\n /**\n * Construct an Authentication (401) error.\n *\n * **Telemetry pattern — `details: { internal: '<tag>' }`.** When the\n * server creates an auth error with an `internal` key in `details`\n * (e.g. `{ internal: 'session_invalid' }`), `toResponse()` strips the\n * entire `details` object before serialization. This keeps the wire\n * response a clean \"Authentication failed\" while preserving granular\n * server-side telemetry (which strategy/check failed) for logs and tests.\n *\n * Use this pattern in API auth code; do not put client-visible info under\n * `internal`. Other `details` keys round-trip normally.\n */\n static authentication(message = 'Authentication required', details) {\n return new ShipError(ErrorType.Authentication, message, 401, details);\n }\n static business(message, status = 400, details) {\n return new ShipError(ErrorType.Business, message, status, details);\n }\n static network(message, details) {\n return new ShipError(ErrorType.Network, message, undefined, details);\n }\n /**\n * A deadline expired before the exchange completed.\n *\n * Statusless like its four client-only siblings: no exchange completed, so\n * there is no HTTP status to report. `isNetworkError()` is true — see\n * `ErrorType.Timeout` for why the category is shared and the type is not.\n */\n static timeout(message, details) {\n return new ShipError(ErrorType.Timeout, message, undefined, details);\n }\n static cancelled(message, details) {\n return new ShipError(ErrorType.Cancelled, message, undefined, details);\n }\n static file(message, details) {\n return new ShipError(ErrorType.File, message, undefined, details);\n }\n static config(message, details) {\n return new ShipError(ErrorType.Config, message, undefined, details);\n }\n static api(message, status = 500, details) {\n return new ShipError(ErrorType.Api, message, status, details);\n }\n /**\n * The platform is closed for maintenance (503).\n *\n * `message` is REQUIRED and has no default here. The API is the only\n * producer of that sentence, and a default in this file would be a second\n * owner of one fact — see CLAUDE.md, \"The Constellation Law\" (stopping\n * rule). It is also the one factory whose status is fixed rather than\n * defaulted: a maintenance refusal is 503 or it is not this error.\n */\n static maintenance(message, details) {\n return new ShipError(ErrorType.Maintenance, message, 503, details);\n }\n // Semantic-category guards. For specific-type checks, use\n // `error.type === ErrorType.X` directly or the generic `isType(t)`.\n /**\n * The caller is at fault — by HTTP's own definition of a 4xx, or by a type\n * that is client-attributable without ever having a status (`Config`,\n * `File`, raised locally by the SDK).\n *\n * Both arms are load-bearing, because type and status are independent\n * axes. `fromHttpResponse` trusts `body.error` only when it names a\n * server-producible type; a non-OK response without one is status-derived,\n * so a CDN 404 or any intermediary error arrives as `Api` — a server-fault\n * *type* carrying a client *status*. Judging by type alone would report it\n * as a platform failure and bury the server's own message.\n */\n isClientError() {\n if (ERROR_CATEGORIES.client.has(this.type))\n return true;\n return this.status !== undefined && this.status >= 400 && this.status < 500;\n }\n isNetworkError() {\n return ERROR_CATEGORIES.network.has(this.type);\n }\n isAuthError() {\n return ERROR_CATEGORIES.auth.has(this.type);\n }\n isType(errorType) {\n return this.type === errorType;\n }\n}\n/**\n * Type guard to check if an unknown value is a ShipError.\n *\n * Uses structural checking instead of instanceof to handle module duplication\n * in bundled applications where multiple copies of the ShipError class may exist.\n *\n * @example\n * if (isShipError(error)) {\n * console.log(error.status, error.message);\n * }\n */\nexport function isShipError(error) {\n return (error !== null &&\n typeof error === 'object' &&\n 'name' in error &&\n error.name === 'ShipError' &&\n 'status' in error);\n}\n// =============================================================================\n// EXTENSION MATCHING\n// =============================================================================\n/**\n * The rule for reading a file's extension: lowercase, after the last dot of\n * the last path segment. `null` when there is no extension to read.\n *\n * A leading dot names the file rather than its type, so `.gitignore` and\n * `.htaccess` have no extension — but `.env.exe` has `exe`.\n *\n * Segment-aware on purpose: the callers pass deploy PATHS, not basenames, and\n * a naive `lastIndexOf('.')` over `dir.v1/README` reads the extension\n * `v1/README` — safe only by accident, since no entry in a real blocklist\n * contains a slash, which is the kind of correctness nobody should have to\n * re-derive.\n *\n * **Private, and the reason is the asymmetry rather than any hazard.** Nothing\n * outside this file reads it: `isBlockedExtension` is the only question anyone\n * asks, and the API's refusal names the FILE, not its extension. Exporting a\n * pure function is harmless, which is exactly the argument that talks a\n * published package into surface it has not earned — and the costs do not\n * match, since adding an export later is free under the additive law while\n * removing one is a major. So it stays private until a caller exists. Its\n * behaviour is fenced through `isBlockedExtension`, which is where it is\n * observable.\n *\n * (`WEB_FILE_EXTENSIONS` above is private for a different reason — publishing\n * it would invite a wrong question. Both are private; only one is a hazard.)\n *\n * @example\n * fileExtension('virus.exe') // 'exe'\n * fileExtension('assets/style.CSS') // 'css'\n * fileExtension('dir.v1/README') // null\n * fileExtension('.gitignore') // null\n * fileExtension('file.') // null\n */\nfunction fileExtension(filename) {\n const basename = filename.replace(/\\\\/g, '/').split('/').pop() ?? '';\n const dotIndex = basename.lastIndexOf('.');\n if (dotIndex <= 0 || dotIndex === basename.length - 1)\n return null;\n return basename.slice(dotIndex + 1).toLowerCase();\n}\n/**\n * Whether a file is one the platform refuses to host.\n *\n * **The list is not this package's, and that separation is the point.** What\n * counts as a blocked extension is hosting POLICY — it evolves, it is enforced\n * at one security boundary, and `virus.exe` is a perfectly well-formed\n * filename that breaks nothing about the upload→serve round-trip. So the API\n * owns the list (`cloudflare/api/src/lib/blocklist.ts`) and delivers it as\n * `PlatformLimits.blockedExtensions`; a client passes what it was given.\n *\n * What lives here is the MATCHING RULE, and it earns its place by the\n * constellation law's own test. The list's drift is loud in both directions —\n * a stale client uploads a file the API refuses by name, on the first try.\n * A second *matcher* drifts SILENTLY in the one direction that matters: a\n * client stricter than the server refuses a legal file without the server ever\n * being asked, and no error names it. Two holders, silent drift, one owner.\n *\n * The `blocked` collection is required rather than defaulted: this predicate\n * guards a security boundary in the API, and a defaulted-empty argument there\n * would block nothing while reading as though it did. Callers holding a\n * possibly-absent wire field spell the fail-open themselves.\n *\n * @example\n * isBlockedExtension('virus.exe', ['exe']) // true\n * isBlockedExtension('virus.EXE', ['exe']) // true — case-insensitive\n * isBlockedExtension('style.css', ['exe']) // false\n * isBlockedExtension('README', ['exe']) // false — no extension\n */\nexport function isBlockedExtension(filename, blocked) {\n const ext = fileExtension(filename);\n if (ext === null)\n return false;\n return Array.isArray(blocked) ? blocked.includes(ext) : blocked.has(ext);\n}\n// =============================================================================\n// PICKER ACCEPT HINT\n// =============================================================================\n/**\n * The extensions a browser file picker offers by default, grouped by role.\n *\n * Private on purpose: the only published form is `WEB_FILE_ACCEPT`, the\n * attribute value itself. A published set would invite a call site to ask it\n * whether a file is allowed — which is the one thing this list must never\n * answer. See `WEB_FILE_ACCEPT`.\n *\n * Extensionless files (`LICENSE`, most `.well-known` entries) are inexpressible\n * in `accept`, and reach a deployment by folder pick, ZIP, or drag-and-drop.\n */\nconst WEB_FILE_EXTENSIONS = [\n // Markup & documents\n 'html',\n 'htm',\n 'xhtml',\n 'xml',\n 'txt',\n 'md',\n 'markdown',\n 'pdf',\n 'csv',\n // Data & config\n 'json',\n 'jsonc',\n 'webmanifest',\n 'map',\n 'toml',\n 'yaml',\n 'yml',\n 'rss',\n 'atom',\n // Styles\n 'css',\n 'scss',\n 'sass',\n 'less',\n // Scripts & modules\n 'js',\n 'mjs',\n 'cjs',\n 'jsx',\n 'ts',\n 'tsx',\n 'wasm',\n 'vue',\n 'svelte',\n // Images\n 'png',\n 'jpg',\n 'jpeg',\n 'gif',\n 'webp',\n 'avif',\n 'svg',\n 'ico',\n 'bmp',\n 'tif',\n 'tiff',\n 'heic',\n 'heif',\n // Fonts\n 'woff',\n 'woff2',\n 'ttf',\n 'otf',\n 'eot',\n // Audio\n 'mp3',\n 'wav',\n 'ogg',\n 'oga',\n 'opus',\n 'm4a',\n 'aac',\n 'flac',\n 'weba',\n // Video\n 'mp4',\n 'webm',\n 'ogv',\n 'mov',\n 'm4v',\n 'avi',\n // 3D models\n 'glb',\n 'gltf',\n 'usdz',\n // Text tracks\n 'vtt',\n 'srt',\n // Archive — a whole site in one file\n 'zip',\n];\n/**\n * The `accept` attribute value for a browser file picker offering web files.\n *\n * **This is a hint, never a rule.** The API's blocklist is the platform's gate\n * and the only thing that decides what may be hosted; this constant decides\n * what a *file dialog* shows first. The two are not two halves of one policy,\n * and this one must never be consulted to accept or reject a file.\n *\n * The distinction is structural, not stylistic. `accept` can express only an\n * allowlist, while the platform's rule is a blocklist — so this list is\n * necessarily *narrower* than what the platform hosts, and reading it as\n * authority would reject files the platform serves happily. It is also not\n * enforcement in the browser's own terms: every file dialog offers an\n * all-files escape, and **drag-and-drop ignores `accept` entirely**. The\n * dropzone and the picker must reach the same verdict on the same files, and\n * they do — because the verdict is `validateFiles`, downstream of both.\n *\n * The invariant that matters — the picker must never offer a file the platform\n * will refuse — is fenced where the authority lives, in the API's own suite\n * (`cloudflare/api/tests/lib/blocklist.test.ts`), which reads this published\n * string and holds it against the list it owns. It sat here until the\n * blocklist became the API's, and moving it was the price of that: a fence\n * belongs with whichever side can change and break it.\n */\nexport const WEB_FILE_ACCEPT = WEB_FILE_EXTENSIONS.map((ext) => `.${ext}`).join(',');\n// =============================================================================\n// FILENAME CHARACTER VALIDATION\n// =============================================================================\n/**\n * Characters that are unsafe in filenames for static hosting.\n *\n * Blocks only characters that genuinely break the upload→serve round-trip:\n * - # ? % URL round-trip breakers (fragment, query, encoding ambiguity)\n * - \\ Path separator confusion (upload splits on backslash)\n * - < > \" XSS vectors with zero legitimate use in filenames\n * - \\x00-\\x1f \\x7f Control characters (header injection, display corruption)\n *\n * Everything else is allowed — browser percent-encodes, Worker decodes, R2 matches.\n */\n// biome-ignore lint/suspicious/noControlCharactersInRegex: blocking control characters is this regex's purpose\nexport const UNSAFE_FILENAME_CHARS = /[\\x00-\\x1f\\x7f#?%\\\\<>\"]/;\n/**\n * Check if a filename contains unsafe characters.\n *\n * @example\n * hasUnsafeChars('saved_resource(1).html') // false — parentheses are safe\n * hasUnsafeChars('page[slug].js') // false — brackets are safe\n * hasUnsafeChars('file#anchor.html') // true — # breaks URL resolution\n * hasUnsafeChars('file<tag>.html') // true — < is an XSS vector\n */\nexport function hasUnsafeChars(filename) {\n return UNSAFE_FILENAME_CHARS.test(filename);\n}\n// =============================================================================\n// UNBUILT PROJECT MARKERS\n// =============================================================================\n/**\n * Path segment names that indicate an unbuilt project was uploaded instead of build output.\n * Used for early detection in CLI, browser, and server validation.\n */\nexport const UNBUILT_PROJECT_MARKERS = new Set([\n 'node_modules',\n 'package.json',\n]);\n/**\n * Check if a file path contains an unbuilt project marker.\n *\n * @example\n * hasUnbuiltMarker('node_modules/react/index.js') // true\n * hasUnbuiltMarker('package.json') // true\n * hasUnbuiltMarker('dist/index.html') // false\n */\nexport function hasUnbuiltMarker(filePath) {\n const segments = filePath.replace(/\\\\/g, '/').split('/').filter(Boolean);\n return segments.some((s) => UNBUILT_PROJECT_MARKERS.has(s));\n}\n// =============================================================================\n// CREDENTIAL SHAPES\n// =============================================================================\n// The one address for credential vocabulary: where human identity lives\n// (AUTH_BASE_PATH), how a request is authorized (AuthMethod), the shapes\n// that distinguish populations on the wire (API_KEY, DEPLOY_TOKEN,\n// OAUTH_TOKEN, CALLER), the two halves of the one Bearer slot\n// (readBearerValue reads it, classifyToken/TokenKind dispatch on what came\n// out), and the delegated-access scopes (OAuthScope).\n//\n// THE SHAPE LAW, in three clauses, over the `Authorization: Bearer` slot's\n// three populations below. The deployment claim code is the API's own\n// (`AUTH.CLAIM`, server-side: the API mints it and the API validates it, so\n// it has one holder and stays there) and shares only clause 1 — it is the\n// platform's one deliberately BARE secret, because it never enters the\n// Bearer slot: minted into one URL, consumed by one endpoint's one field,\n// its context names it and a prefix would restate its route.\n// `tests/validation-constants.test.ts` holds the clauses over this file's\n// populations; the API's suite holds its own.\n//\n// 1. ONE ENTROPY STANDARD. Every minted secret is `HEX_LENGTH` hex characters\n// — one width for the whole platform, so \"how long is a credential\" has a\n// single answer rather than one per population. Generators read the width\n// from the population's own constant, so a minted value and an accepted\n// value cannot differ.\n//\n// 2. EVERY BEARER POPULATION IS NAMED BY ITS PREFIX. A credential says what\n// it is before anything parses it — which is what lets `classifyToken`\n// below dispatch three populations sharing one `Authorization: Bearer`\n// slot, and what lets a value found in a log, a support ticket or a\n// pasted URL be recognised and revoked on sight. The OAuth access token\n// was this clause's one standing exception until 2026-08-14 — the\n// authorization server it was born on had no mint hook to give it a\n// prefix, and its successor does.\n//\n// 3. NO PREFIX IS A PREFIX OF ANOTHER. This is what makes the dispatch\n// order-independent, and it is the reason the populations are named on\n// different axes (`ship-` for the product, `deploy-` for the capability)\n// rather than sharing a stem. A `ship-` / `ship-deploy-` pair\n// reads tidier and is a trap: every deploy token would also match the\n// API-key branch, leaving correctness resting on the order of two `if`s.\n/**\n * Where human identity is mounted on the API host. The API mounts Better\n * Auth at this path (sign-in, sign-out, session reads, admin impersonation)\n * and the web console's auth client posts to it — shared here so the two\n * halves of the auth pair agree by construction, the same way both sides\n * already share the credential prefixes below.\n */\nexport const AUTH_BASE_PATH = '/auth';\n/**\n * The query marker a completed sign-in LANDS with.\n *\n * The API's magic-link verify leg stamps `?signing-in=1` onto its success\n * redirect, and the console boots into its wait screen on seeing it — two\n * repos, one spelling, which is why it lives here. Success is marked and the\n * error leg deliberately is NOT: the console gives the marker precedence, so\n * a marked error would render a wait that resolves to bare doors with the\n * error's sentence lost. If the spellings ever diverged the failure would be\n * invisible to every suite — email landings would flash the doors for one\n * round trip instead of waiting — which is exactly the silent-drift class\n * this constitution exists to delete.\n */\nexport const SIGN_IN_RETURN_PARAM = 'signing-in';\n/**\n * How a request (or recorded activity) was authorized.\n *\n * Client populations: `SESSION` (first-party cookie), `API_KEY` (`ship-`\n * key), `TOKEN` (`deploy-` deploy token), `AGENT` (anonymous public deploy —\n * no credential; the platform grants the public-account identity per\n * request), `OAUTH` (delegated access token). Server populations: `WEBHOOK`\n * (signed webhook processing), `SYSTEM` (scheduled/background jobs).\n */\nexport const AuthMethod = {\n SESSION: 'session',\n API_KEY: 'apiKey',\n TOKEN: 'token',\n AGENT: 'agent',\n OAUTH: 'oauth',\n WEBHOOK: 'webhook',\n SYSTEM: 'system',\n};\n/**\n * Shape constants for API keys (`ship-{32 hex chars}`).\n * Single source of truth used by validation utilities and auth middleware.\n */\nexport const API_KEY = {\n /** Prefix that identifies an API key. */\n PREFIX: 'ship-',\n /** Number of hex characters following the prefix. */\n HEX_LENGTH: 32,\n /** Total length of an API key including prefix (`PREFIX.length + HEX_LENGTH = 37`). */\n TOTAL_LENGTH: 37,\n /** Number of trailing characters used to display a redacted hint (e.g. last 4). */\n HINT_LENGTH: 4,\n};\n/**\n * Shape constants for deploy tokens (`deploy-{32 hex chars}`).\n * Single source of truth used by validation utilities and auth middleware.\n *\n * Deliberately the same width as `API_KEY`: both are minted by one generator\n * and classified by prefix alone, so a length that differed between them\n * would be a second thing to know about a credential whose prefix already\n * says what it is.\n */\nexport const DEPLOY_TOKEN = {\n /** Prefix that identifies a deploy token. */\n PREFIX: 'deploy-',\n /** Number of hex characters following the prefix. */\n HEX_LENGTH: 32,\n /** Total length of a deploy token including prefix (`PREFIX.length + HEX_LENGTH = 39`). */\n TOTAL_LENGTH: 39,\n};\n/**\n * Shape constants for OAuth access tokens (`oauth-{32 hex chars}`) — the\n * delegated population, minted by the platform's own authorization server\n * for a connected app acting on a user's behalf.\n *\n * Same width as the other two, and for the same reason: one entropy standard\n * across the platform, so \"how long is a credential\" has one answer.\n *\n * **This population is the access token alone.** Refresh tokens, authorization\n * codes and client secrets are deliberately NOT here and are deliberately not\n * prefixed by this constant: none of them ever enters the `Authorization:\n * Bearer` slot — a refresh token is posted as a form field to the token\n * endpoint, which knows what it is receiving — so `classifyToken` never sees\n * one and a prefix would name a population no dispatcher dispatches. The same\n * reasoning that keeps the deployment claim code bare.\n *\n * **The prefix must be applied at the MINT, never as a display wrapper.** The\n * authorization server hashes what it stores and the API hashes what it is\n * presented, so the prefix has to be inside the hashed string on both sides.\n * `@better-auth/oauth-provider` offers a `prefix.opaqueAccessToken` option\n * that prepends AFTER hashing and strips on its own read paths; using it would\n * store a hash of the UNPREFIXED token and silently break the platform's read\n * arm. The API therefore mints through `generateOpaqueAccessToken` — recorded\n * beside the config in `cloudflare/api/src/lib/auth/instance.ts`.\n */\nexport const OAUTH_TOKEN = {\n /** Prefix that identifies an OAuth access token. */\n PREFIX: 'oauth-',\n /** Number of hex characters following the prefix. */\n HEX_LENGTH: 32,\n /** Total length including prefix (`PREFIX.length + HEX_LENGTH = 38`). */\n TOTAL_LENGTH: 38,\n};\n/**\n * Shape constants for caller identifiers (the `X-Caller` instance-identity\n * header — rate-limit bucketing for multi-tenant orchestrators). The API\n * normalizes case and silently ignores malformed values (the header is\n * unauthenticated); clients validate at the boundary via `validateCaller`,\n * so a value the server would drop fails fast instead.\n */\nexport const CALLER = {\n /** HTTP header name. */\n HEADER: 'X-Caller',\n /** Maximum identifier length. */\n MAX_LENGTH: 128,\n /** Allowed characters: alphanumeric, dot, underscore, hyphen. */\n PATTERN: /^[a-zA-Z0-9._-]+$/,\n};\n/**\n * Token populations distinguishable by shape. The platform carries every\n * client token in one wire slot (`Authorization: Bearer <value>`) and\n * classifies by value, never by a side channel — this is the classifier.\n *\n * `API_KEY`, `DEPLOY_TOKEN` and `OAUTH` *are* `AuthMethod.API_KEY`,\n * `AuthMethod.TOKEN` and `AuthMethod.OAUTH` — the equality is structural, so\n * a classification flows straight into an auth method and the trio can never\n * drift.\n *\n * `OPAQUE` is any other value, and since 2026-08-14 it names NO population:\n * every credential this platform mints for the Bearer slot carries a prefix,\n * so an opaque bearer is a bearer we did not mint. It stays a member rather\n * than becoming a `null` return because a dispatcher with a total codomain\n * reads better than one with an absence in it — and because it is where a\n * future population would land before anyone gave it a shape, which is\n * exactly what the OAuth token itself did until its prefix existed.\n */\nexport const TokenKind = {\n API_KEY: AuthMethod.API_KEY,\n DEPLOY_TOKEN: AuthMethod.TOKEN,\n OAUTH: AuthMethod.OAUTH,\n OPAQUE: 'opaque',\n};\n/**\n * Classify a client token by shape. The single dispatch used by both sides\n * of the wire: API auth middleware (which population is this credential?)\n * and SDK validation (which format rules apply before sending?). Sharing it\n * is what guarantees client and server can never disagree on dispatch.\n */\nexport function classifyToken(token) {\n if (token.startsWith(API_KEY.PREFIX))\n return TokenKind.API_KEY;\n if (token.startsWith(DEPLOY_TOKEN.PREFIX))\n return TokenKind.DEPLOY_TOKEN;\n if (token.startsWith(OAUTH_TOKEN.PREFIX))\n return TokenKind.OAUTH;\n return TokenKind.OPAQUE;\n}\n/** The auth-scheme, lowercased — the form the comparison is made in. */\nconst BEARER_SCHEME = 'bearer ';\n/**\n * Read the credential out of an `Authorization` header value — the step\n * BEFORE `classifyToken`, and the other half of the one wire slot this\n * section owns.\n *\n * Returns the credential's own bytes, or `null` when the header carries a\n * foreign scheme or nothing after the scheme.\n *\n * **The scheme is folded; the credential is not.** RFC 7235 §2.1 makes the\n * auth-scheme case-insensitive, so `bearer`, `Bearer` and `BEARER` are the\n * same header. The value after it is opaque and is compared literally\n * everywhere it is used — `ship-`/`deploy-`/`oauth-` are lowercase hex, and\n * folding them would make a credential match values it is not.\n *\n * **This platform has paid for the rule twice, which is why it has an owner\n * rather than a convention.** A spec-conformant `bearer ship-…` client was\n * refused for as long as the API's scheme test was spelled case-sensitively;\n * and `@better-auth/oauth-provider` carries the same defect in four places\n * today (`startsWith(\"Bearer \")`), which is precisely why the platform folds\n * the scheme itself and hands the provider a bare token.\n *\n * **ABSENCE is deliberately not this function's business.** A missing header\n * and an unreadable one are different facts, and the callers that care split\n * on them: the API worker's middleware distinguishes `absent` (the only\n * anonymous path) from `unreadable` (a presented credential that is refused),\n * and collapsing the two here would take that distinction away from the layer\n * that needs it. Callers check for the header themselves and pass its value.\n *\n * **Why this lives in the constitution rather than in a worker's `shared/`.**\n * It is the same wire boundary `classifyToken` already owns — one reads the\n * slot, the other dispatches on what came out — and a rule with two holders\n * whose drift is silent earns exactly one owner regardless of what the\n * convoy costs. The estate's recorded refusal to own a `Bearer` CONSTANT\n * stands and is a different thing: that is RFC vocabulary, the same reason\n * this package owns no `\"POST\"`. A parser is not a spelling.\n */\nexport function readBearerValue(header) {\n if (header.slice(0, BEARER_SCHEME.length).toLowerCase() !== BEARER_SCHEME)\n return null;\n return header.slice(BEARER_SCHEME.length) || null;\n}\n/**\n * OAuth scope vocabulary for delegated third-party access tokens.\n * Single source of truth used by the authorization server (advertised in\n * `scopes_supported`), the API's scope-enforcement middleware, and consent UI\n * copy. The standard `offline_access` scope (refresh tokens) is not platform\n * vocabulary and is deliberately absent — the middleware never checks it.\n *\n * Deliberately absent by design: any `tokens:*` scope, `account:write`, or\n * admin scope — a delegated app must never mint credentials, delete the\n * account, or act as admin.\n */\nexport const OAuthScope = {\n ACCOUNT_READ: 'account:read',\n DEPLOYMENTS_READ: 'deployments:read',\n DEPLOYMENTS_WRITE: 'deployments:write',\n DOMAINS_READ: 'domains:read',\n DOMAINS_WRITE: 'domains:write',\n};\n// =============================================================================\n// DEPLOYMENT CONFIGURATION CONSTANTS\n// =============================================================================\nexport const DEPLOYMENT_CONFIG_FILENAME = 'ship.json';\n/** Default ship.json config for SPA routing. Single source of truth — used by both API and SDK. */\nexport const SPA_DEFAULT_CONFIG = {\n rewrites: [{ source: '/(.*)', destination: '/index.html' }],\n};\n/**\n * The `/spa-check` pre-flight's client-side envelope: which file is the\n * check's subject, and how large it may be before a client skips the call.\n *\n * One fact with three holders until this export — the API's config declared\n * the cap, the SDK's `checkSPA` hardcoded `100 * 1024`, and prose restated\n * \"100KB\". `INDEX_FILE` is the selection rule (the file whose content rides\n * `SPACheckRequest.index`), restated by every client that builds the request.\n *\n * Neither member is a validation boundary: a client over the cap simply\n * skips the pre-flight, because the server answers an oversized index\n * `isSPA: false` anyway. A consumer that cannot import this (n8n) needs no\n * size copy at all — outcome parity is the server's, not the client's.\n */\nexport const SPA_CHECK_CONSTRAINTS = {\n /** The file whose content is the check's subject. */\n INDEX_FILE: 'index.html',\n /** Skip the pre-flight above this size — the server would answer false. */\n MAX_INDEX_BYTES: 100 * 1024,\n};\n/**\n * Assert that a ship.json file is *syntactically* loadable. Syntax only —\n * never schema.\n *\n * ship.json is validated and compiled on the server, deliberately: the schema\n * and the compiler evolve, and a client that judged them would reject configs\n * a newer platform accepts. That reasoning bounds what a client may check to\n * the properties which are true of *every* past and future schema:\n *\n * 1. it parses as JSON — JSON syntax is frozen (RFC 8259), so text that\n * does not parse can never be a valid config;\n * 2. its top level is an object — ship.json is `{ ... }` in every version.\n *\n * Both are monotonic: neither can ever reject something the server would\n * accept. Everything beyond them (field names, types, rule semantics, which\n * keys are permitted) stays server-side, where it can change.\n *\n * The payoff is the common case. Hand-edited JSON fails on a trailing comma,\n * a `//` comment, single quotes, unquoted keys, or smart quotes pasted from\n * documentation — mistakes that otherwise cost a full upload round-trip to\n * discover. A UTF-8 BOM (Windows editors, PowerShell redirects) is stripped\n * before parsing rather than rejected, because the server accepts it too;\n * diverging there would reintroduce exactly the false rejection this\n * function exists to avoid.\n *\n * @throws {ShipError} `ErrorType.Config` — the same type the server's own\n * config rejection carries, so the error contract is identical wherever the\n * failure is detected.\n */\nexport function assertShipJsonSyntax(text) {\n const withoutBom = text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;\n let parsed;\n try {\n parsed = JSON.parse(withoutBom);\n }\n catch (error) {\n throw ShipError.config(`invalid JSON format in config: ${error.message}`, {\n filePath: DEPLOYMENT_CONFIG_FILENAME,\n });\n }\n if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw ShipError.config(`${DEPLOYMENT_CONFIG_FILENAME} must contain a JSON object`, {\n filePath: DEPLOYMENT_CONFIG_FILENAME,\n });\n }\n}\n// =============================================================================\n// VALIDATION UTILITIES\n// =============================================================================\n/**\n * Shared rule for prefixed credentials: `{PREFIX}{HEX_LENGTH hex chars}`.\n * The regex derives from the shape constants, so the validators can never\n * drift from the shapes `classifyToken` dispatches on.\n */\nfunction validatePrefixedCredential(value, shape, label) {\n if (!value.startsWith(shape.PREFIX)) {\n throw ShipError.validation(`${label} must start with \"${shape.PREFIX}\"`);\n }\n if (value.length !== shape.TOTAL_LENGTH) {\n throw ShipError.validation(`${label} must be ${shape.TOTAL_LENGTH} characters total (${shape.PREFIX} + ${shape.HEX_LENGTH} hex chars)`);\n }\n const hexPart = value.slice(shape.PREFIX.length);\n if (!new RegExp(`^[a-f0-9]{${shape.HEX_LENGTH}}$`, 'i').test(hexPart)) {\n throw ShipError.validation(`${label} must contain ${shape.HEX_LENGTH} hexadecimal characters after \"${shape.PREFIX}\" prefix`);\n }\n}\n/**\n * Validate API key format\n */\nexport function validateApiKey(apiKey) {\n validatePrefixedCredential(apiKey, API_KEY, 'API key');\n}\n/**\n * Validate deploy token format\n */\nexport function validateDeployToken(deployToken) {\n validatePrefixedCredential(deployToken, DEPLOY_TOKEN, 'Deploy token');\n}\n/**\n * Validate OAuth access token format\n */\nexport function validateOAuthToken(oauthToken) {\n validatePrefixedCredential(oauthToken, OAUTH_TOKEN, 'OAuth access token');\n}\n/**\n * Validate a client token of any population. Classifies by shape and applies\n * the matching format rules: all three prefixed populations are validated\n * strictly; an OPAQUE token only needs to be non-empty.\n *\n * **The OPAQUE arm stays permissive on purpose**, even though the platform no\n * longer mints an unprefixed credential. It is the fallback for a population\n * that does not exist yet, and a client refusing a shape the server would\n * accept is the one failure mode this boundary must never have — the server\n * decides, and it refuses an unrecognised bearer anyway. Unprefixed OAuth\n * tokens from before 2026-08-14 land here and are refused server-side, which\n * is correct: they were revoked by the change, not grandfathered.\n */\nexport function validateToken(token) {\n switch (classifyToken(token)) {\n case TokenKind.API_KEY:\n validateApiKey(token);\n return;\n case TokenKind.DEPLOY_TOKEN:\n validateDeployToken(token);\n return;\n case TokenKind.OAUTH:\n validateOAuthToken(token);\n return;\n case TokenKind.OPAQUE:\n if (!token)\n throw ShipError.validation('Token must be a non-empty string');\n }\n}\n/**\n * Validate a caller identifier against the `CALLER` shape. The server\n * silently ignores malformed values (the header is unauthenticated); clients\n * call this at configuration time so the drop never silently happens.\n */\nexport function validateCaller(caller) {\n if (!caller || caller.length > CALLER.MAX_LENGTH || !CALLER.PATTERN.test(caller)) {\n throw ShipError.validation(`Caller must be 1-${CALLER.MAX_LENGTH} characters: letters, digits, dots, underscores, or hyphens`);\n }\n}\n/**\n * Validate API URL format\n */\nexport function validateApiUrl(apiUrl) {\n try {\n const url = new URL(apiUrl);\n if (!['http:', 'https:'].includes(url.protocol)) {\n throw ShipError.validation('API URL must use http:// or https:// protocol');\n }\n if (url.pathname !== '/' && url.pathname !== '') {\n throw ShipError.validation('API URL must not contain a path');\n }\n if (url.search || url.hash) {\n throw ShipError.validation('API URL must not contain query parameters or fragments');\n }\n }\n catch (error) {\n if (isShipError(error)) {\n throw error;\n }\n throw ShipError.validation('API URL must be a valid URL');\n }\n}\n/**\n * Check if a string matches the deployment identifier pattern (word-word-alphanumeric7).\n * Example: \"happy-cat-abc1234.shipstatic.com\"\n */\nexport function isDeployment(input) {\n return /^[a-z]+-[a-z]+-[a-z0-9]{7}(\\.[a-z0-9.-]+)?$/i.test(input);\n}\n/**\n * The envelope a requested lifetime must fit — one word, one grammar, wherever\n * the platform lets a caller choose how long something lives.\n *\n * Two resources wear it: `TokenCreateOptions.ttl` and\n * `DeploymentUploadOptions.ttl`. It lives here rather than on the server by\n * the format-vs-policy rule — a client can decide offline whether a duration\n * is well-formed, and the API rejects the same value the same way. What is\n * NOT here is any per-plan ceiling: no such policy exists, and one delivered\n * speculatively through `/limits` would be an owner for a decision nobody has\n * made.\n */\nexport const TTL_CONSTRAINTS = {\n /**\n * Shortest requestable lifetime, in seconds. One rather than zero: a\n * deployment that expires the instant it is created is not a shorter lease,\n * it is a deploy that was never live, and `0` is how an unset variable\n * arrives.\n */\n MIN_SECONDS: 1,\n /** Longest requestable lifetime, in seconds — one year. */\n MAX_SECONDS: 365 * 24 * 60 * 60,\n};\n/**\n * Validate a requested lifetime in SECONDS and return it, or `undefined` when\n * none was asked for.\n *\n * **A duration, never an instant.** The caller says how long; the server owns\n * what time it is and stamps the expiry — so a client's clock, however wrong,\n * cannot shorten or extend a lease. That is the tokens precedent, and it is\n * why this rule measures a count of seconds rather than checking a timestamp\n * against `now`.\n *\n * Fractions are refused rather than rounded: a caller who wrote `1.5` meant\n * something the wire cannot carry, and silently choosing `1` or `2` for them\n * is a decision the platform has no standing to make.\n *\n * Single source of truth shared by the API (the tokens route and the deploy\n * schema), the SDK's request boundary, and the CLI's parser.\n */\nexport function validateTtl(value) {\n if (value === undefined || value === null)\n return undefined;\n if (typeof value !== 'number' || !Number.isFinite(value)) {\n throw ShipError.validation('TTL must be a number of seconds');\n }\n if (!Number.isInteger(value)) {\n throw ShipError.validation('TTL must be a whole number of seconds');\n }\n if (value < TTL_CONSTRAINTS.MIN_SECONDS || value > TTL_CONSTRAINTS.MAX_SECONDS) {\n throw ShipError.validation(`TTL must be between ${TTL_CONSTRAINTS.MIN_SECONDS} and ${TTL_CONSTRAINTS.MAX_SECONDS} seconds`);\n }\n return value;\n}\n// =============================================================================\n// PLATFORM CONSTANTS\n// =============================================================================\n/** Default API URL if not otherwise configured. */\nexport const DEFAULT_API = 'https://api.shipstatic.com';\n/**\n * The Node SDK's ambient configuration pair — the ONLY environment variables\n * the SDK reads, and therefore the COMPLETE list an embedding host must\n * scrub (per `npm/ship`'s strict-isolation contract, scrubbing is the host's\n * job, not the SDK's). A host that derives its scrub from this object's\n * values — as the VS Code extension's child-process env block does — picks\n * up a grown contract at the next pin bump instead of by remembered prose.\n *\n * Browser builds read no environment at all, and the CLI-only variables\n * (`SHIP_PASSWORD`, `SHIP_VIA`) are deliberately NOT here: they are the\n * CLI's operational levers, not the SDK's ambient contract — see\n * `npm/ship/CLAUDE.md`, \"CLI-only env vars\".\n */\nexport const SHIP_ENV = {\n /** The one credential slot — any platform token. */\n TOKEN: 'SHIP_TOKEN',\n /** The API endpoint override. */\n API_URL: 'SHIP_API_URL',\n};\n/**\n * Where a human creates an API key — the console deep link quoted by every\n * surface that teaches authentication (the CLI's config wizard, the VS Code\n * and n8n listings, the n8n rate-limit hint and credential copy). Written\n * out in five files across three repos until this export.\n *\n * Production-branded by design: published artifacts name the product, never\n * an environment (root `CLAUDE.md`, \"Environment-Aware URLs\").\n */\nexport const MY_API_KEY_URL = 'https://my.shipstatic.com/api-key';\n/**\n * How long an anonymous deployment lives before it expires.\n *\n * The lifetime of the public tier, and one fact with several readers. The API\n * stamps a deployment's `expires` from it and gives a claim code exactly the\n * same window — a live site with a dead claim link is a coherence bug, so the\n * two are one constant rather than two that agree. Both MCP transports quote\n * the duration in prose an agent reads, and derive it from here rather than\n * writing it out, which they did in eight places until this export existed.\n *\n * Seconds, spelled in the name: this platform has both second- and\n * millisecond-valued durations, and the pair is only safe when each says which\n * it is.\n */\nexport const PUBLIC_DEPLOYMENT_TTL_SECONDS = 3 * 24 * 60 * 60;\n// =============================================================================\n// FILE UPLOAD TYPES\n// =============================================================================\n/**\n * File status constants for validation state tracking\n */\nexport const FileValidationStatus = {\n /** File is pending validation */\n PENDING: 'pending',\n /** File failed during processing (before validation) */\n PROCESSING_ERROR: 'processing_error',\n /** File was excluded by validation warning (not an error) */\n EXCLUDED: 'excluded',\n /** File failed validation (blocks deployment) */\n VALIDATION_FAILED: 'validation_failed',\n /** File passed validation and is ready for deployment */\n READY: 'ready',\n};\n// =============================================================================\n// DOMAIN UTILITIES\n// =============================================================================\n/**\n * Check if a domain is a platform domain (subdomain of our platform).\n * Platform domains are free and don't require DNS verification.\n *\n * @example isPlatformDomain(\"www.shipstatic.com\", \"shipstatic.com\") → true\n * @example isPlatformDomain(\"example.com\", \"shipstatic.com\") → false\n */\nexport function isPlatformDomain(domain, platformDomain) {\n return domain.endsWith(`.${platformDomain}`);\n}\n/**\n * Check if a domain is a custom domain (not a platform subdomain).\n * Custom domains are billable and require DNS verification.\n *\n * @example isCustomDomain(\"example.com\", \"shipstatic.com\") → true\n * @example isCustomDomain(\"www.shipstatic.com\", \"shipstatic.com\") → false\n */\nexport function isCustomDomain(domain, platformDomain) {\n return !isPlatformDomain(domain, platformDomain);\n}\n/**\n * Extract subdomain from a platform domain.\n * Returns null if not a platform domain.\n *\n * @example extractSubdomain(\"www.shipstatic.com\", \"shipstatic.com\") → \"www\"\n * @example extractSubdomain(\"example.com\", \"shipstatic.com\") → null\n */\nexport function extractSubdomain(domain, platformDomain) {\n if (!isPlatformDomain(domain, platformDomain)) {\n return null;\n }\n return domain.slice(0, -(platformDomain.length + 1)); // +1 for the dot\n}\n/**\n * Generate HTTPS URL for a deployment hostname.\n */\nexport function generateDeploymentUrl(deployment) {\n return `https://${deployment}`;\n}\n/**\n * Generate HTTPS URL for a domain.\n */\nexport function generateDomainUrl(domain) {\n return `https://${domain}`;\n}\n// =============================================================================\n// LABEL UTILITIES\n// =============================================================================\n/**\n * Label validation constraints shared across UI and API.\n * These rules define the single source of truth for label validation.\n */\nexport const LABEL_CONSTRAINTS = {\n /** Minimum label length in characters */\n MIN_LENGTH: 3,\n /** Maximum label length in characters (concise labels, matches Stack Overflow's original limit) */\n MAX_LENGTH: 25,\n /** Maximum number of labels allowed per resource */\n MAX_COUNT: 10,\n /** Allowed separator characters between label segments */\n SEPARATORS: '._-',\n};\n/**\n * Label validation pattern.\n * Must start and end with alphanumeric (a-z, 0-9).\n * Can contain separators (. _ -) between segments, but not consecutive.\n *\n * Valid examples: 'production', 'v1.2.3', 'api_v2', 'us-east-1'\n * Invalid examples: 'ab' (too short), '-prod' (starts with separator), 'foo--bar' (consecutive separators)\n */\nexport const LABEL_PATTERN = /^[a-z0-9]+(?:[._-][a-z0-9]+)*$/;\n/**\n * Serialize labels array to JSON string for database storage.\n * Returns null for empty or undefined arrays.\n *\n * @example serializeLabels(['web', 'production']) → '[\"web\",\"production\"]'\n * @example serializeLabels([]) → null\n * @example serializeLabels(undefined) → null\n */\nexport function serializeLabels(labels) {\n if (!labels || labels.length === 0)\n return null;\n return JSON.stringify(labels);\n}\n/**\n * Deserialize labels from JSON string to array.\n * Always returns an array — empty array for null/empty/invalid input.\n *\n * @example deserializeLabels('[\"web\",\"production\"]') → ['web', 'production']\n * @example deserializeLabels(null) → []\n * @example deserializeLabels('') → []\n */\nexport function deserializeLabels(labelsJson) {\n if (!labelsJson)\n return [];\n try {\n const parsed = JSON.parse(labelsJson);\n return Array.isArray(parsed) ? parsed : [];\n }\n catch {\n return [];\n }\n}\n// =============================================================================\n// PASSWORD UTILITIES\n// =============================================================================\n/**\n * Length constraints for the optional deployment password\n * (`DeploymentUploadOptions.password`). Single source of truth shared across\n * platform consumers.\n */\nexport const PASSWORD_CONSTRAINTS = {\n /** Minimum password length in characters */\n MIN_LENGTH: 6,\n /** Maximum password length in characters */\n MAX_LENGTH: 128,\n};\n/**\n * Validate an optional deployment password and return it normalized.\n *\n * Absent (`undefined` / `null`) → returns `undefined`. Present → trim\n * leading/trailing whitespace, then validate against `PASSWORD_CONSTRAINTS`\n * length bounds (internal whitespace is significant and counts toward\n * length). Throws `ShipError.validation` on breach; returns the trimmed\n * value.\n *\n * The trim is canonical: at upload, the API hashes the trimmed value; at\n * unlock, the router trims submissions before hashing. Submission and storage\n * agree byte-for-byte. Length validation runs on the trimmed value because\n * that's the user's actual intent — and it disarms a class of invisible\n * foot-guns (trailing newlines from copy/paste, mobile auto-spacing,\n * password-manager artifacts).\n *\n * Single source of truth shared by SDK (client-side validation, return\n * ignored) and API (server-side enforcement, return threaded into config).\n * Length is part of the wire-format contract; strength rules, if added later,\n * stay server-side. See `CLAUDE.md` \"Validation: format vs policy\".\n */\nexport function validatePassword(value) {\n if (value === undefined || value === null)\n return undefined;\n if (typeof value !== 'string') {\n throw ShipError.validation('Password must be a string');\n }\n const trimmed = value.trim();\n if (trimmed.length < PASSWORD_CONSTRAINTS.MIN_LENGTH ||\n trimmed.length > PASSWORD_CONSTRAINTS.MAX_LENGTH) {\n throw ShipError.validation(`Password must be between ${PASSWORD_CONSTRAINTS.MIN_LENGTH} and ${PASSWORD_CONSTRAINTS.MAX_LENGTH} characters`);\n }\n return trimmed;\n}\n","/**\n * The `File` ↔ `ProcessedFile` boundary, and the path rules that govern it.\n */\nimport { optimizeDeployPaths } from '@shipstatic/ship';\nimport { FileValidationStatus, type FileValidationStatusType } from '@shipstatic/types';\nimport type { ProcessedFile } from './types';\n\n/**\n * Patch a File's `webkitRelativePath` so the Ship SDK reads our resolved deploy\n * path. The browser-set property is read-only, so it must be redefined;\n * `configurable: true` allows re-patching when prefixes are stripped later.\n */\nexport function setRelativePath(file: File, path: string): void {\n Object.defineProperty(file, 'webkitRelativePath', {\n value: path,\n writable: false,\n configurable: true,\n });\n}\n\n/**\n * The deploy path of a raw File: its folder-relative path when the browser gave\n * us one, otherwise its bare name. Every caller goes through here.\n */\nexport function filePath(file: File): string {\n return file.webkitRelativePath?.trim() || file.name;\n}\n\n/**\n * The single conversion point from `File` to `ProcessedFile`.\n *\n * `type` is the browser's own report: the platform derives Content-Type\n * server-side from the path, so there is nothing to gain from second-guessing it\n * here. MD5 is Ship's job, during upload.\n */\nexport function createProcessedFile(file: File, options?: { path?: string }): ProcessedFile {\n const path = options?.path || filePath(file);\n\n return {\n id: crypto.randomUUID(),\n file,\n path,\n size: file.size,\n name: path.split('/').pop() || file.name,\n type: file.type,\n lastModified: file.lastModified,\n status: FileValidationStatus.PENDING,\n };\n}\n\n/**\n * Strip the common directory prefix from a set of deploy paths.\n *\n * The path algorithm is Ship's `optimizeDeployPaths` — the single source of\n * truth for deploy-path normalization. The stripped path is written back onto\n * each underlying File, because Ship reads `webkitRelativePath` from the raw\n * File objects it is handed.\n */\nexport function stripCommonPrefix(files: ProcessedFile[]): ProcessedFile[] {\n if (files.length === 0) return files;\n\n const deployFiles = optimizeDeployPaths(files.map((f) => f.path));\n\n return files.map((f, i) => {\n const newPath = deployFiles[i].path;\n setRelativePath(f.file, newPath);\n return { ...f, path: newPath, name: newPath.split('/').pop() || f.name };\n });\n}\n\n/**\n * Stamp a status across a file set.\n *\n * Validation is atomic — every file carries the same verdict — so this is the\n * one place that shape is built.\n */\nexport function applyStatus(\n files: ProcessedFile[],\n status: FileValidationStatusType,\n statusMessage?: string,\n): ProcessedFile[] {\n return files.map((f) => ({\n ...f,\n status,\n ...(statusMessage === undefined ? {} : { statusMessage }),\n }));\n}\n","// DEFLATE is a complex format; to read this code, you should probably check the RFC first:\n// https://tools.ietf.org/html/rfc1951\n// You may also wish to take a look at the guide I made about this program:\n// https://gist.github.com/101arrowz/253f31eb5abc3d9275ab943003ffecad\n// Some of the following code is similar to that of UZIP.js:\n// https://github.com/photopea/UZIP.js\n// However, the vast majority of the codebase has diverged from UZIP.js to increase performance and reduce bundle size.\n// Sometimes 0 will appear where -1 would be more appropriate. This is because using a uint\n// is better for memory in most engines (I *think*).\nvar ch2 = {};\nvar wk = (function (c, id, msg, transfer, cb) {\n var w = new Worker(ch2[id] || (ch2[id] = URL.createObjectURL(new Blob([\n c + ';addEventListener(\"error\",function(e){e=e.error;postMessage({$e$:[e.message,e.code,e.stack]})})'\n ], { type: 'text/javascript' }))));\n w.onmessage = function (e) {\n var d = e.data, ed = d.$e$;\n if (ed) {\n var err = new Error(ed[0]);\n err['code'] = ed[1];\n err.stack = ed[2];\n cb(err, null);\n }\n else\n cb(null, d);\n };\n w.postMessage(msg, transfer);\n return w;\n});\n\n// aliases for shorter compressed code (most minifers don't do this)\nvar u8 = Uint8Array, u16 = Uint16Array, i32 = Int32Array;\n// fixed length extra bits\nvar fleb = new u8([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, /* unused */ 0, 0, /* impossible */ 0]);\n// fixed distance extra bits\nvar fdeb = new u8([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, /* unused */ 0, 0]);\n// code length index map\nvar clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);\n// get base, reverse index map from extra bits\nvar freb = function (eb, start) {\n var b = new u16(31);\n for (var i = 0; i < 31; ++i) {\n b[i] = start += 1 << eb[i - 1];\n }\n // numbers here are at max 18 bits\n var r = new i32(b[30]);\n for (var i = 1; i < 30; ++i) {\n for (var j = b[i]; j < b[i + 1]; ++j) {\n r[j] = ((j - b[i]) << 5) | i;\n }\n }\n return { b: b, r: r };\n};\nvar _a = freb(fleb, 2), fl = _a.b, revfl = _a.r;\n// we can ignore the fact that the other numbers are wrong; they never happen anyway\nfl[28] = 258, revfl[258] = 28;\nvar _b = freb(fdeb, 0), fd = _b.b, revfd = _b.r;\n// map of value to reverse (assuming 16 bits)\nvar rev = new u16(32768);\nfor (var i = 0; i < 32768; ++i) {\n // reverse table algorithm from SO\n var x = ((i & 0xAAAA) >> 1) | ((i & 0x5555) << 1);\n x = ((x & 0xCCCC) >> 2) | ((x & 0x3333) << 2);\n x = ((x & 0xF0F0) >> 4) | ((x & 0x0F0F) << 4);\n rev[i] = (((x & 0xFF00) >> 8) | ((x & 0x00FF) << 8)) >> 1;\n}\n// create huffman tree from u8 \"map\": index -> code length for code index\n// mb (max bits) must be at most 15\n// TODO: optimize/split up?\nvar hMap = (function (cd, mb, r) {\n var s = cd.length;\n // index\n var i = 0;\n // u16 \"map\": index -> # of codes with bit length = index\n var l = new u16(mb);\n // length of cd must be 288 (total # of codes)\n for (; i < s; ++i) {\n if (cd[i])\n ++l[cd[i] - 1];\n }\n // u16 \"map\": index -> minimum code for bit length = index\n var le = new u16(mb);\n for (i = 1; i < mb; ++i) {\n le[i] = (le[i - 1] + l[i - 1]) << 1;\n }\n var co;\n if (r) {\n // u16 \"map\": index -> number of actual bits, symbol for code\n co = new u16(1 << mb);\n // bits to remove for reverser\n var rvb = 15 - mb;\n for (i = 0; i < s; ++i) {\n // ignore 0 lengths\n if (cd[i]) {\n // num encoding both symbol and bits read\n var sv = (i << 4) | cd[i];\n // free bits\n var r_1 = mb - cd[i];\n // start value\n var v = le[cd[i] - 1]++ << r_1;\n // m is end value\n for (var m = v | ((1 << r_1) - 1); v <= m; ++v) {\n // every 16 bit value starting with the code yields the same result\n co[rev[v] >> rvb] = sv;\n }\n }\n }\n }\n else {\n co = new u16(s);\n for (i = 0; i < s; ++i) {\n if (cd[i]) {\n co[i] = rev[le[cd[i] - 1]++] >> (15 - cd[i]);\n }\n }\n }\n return co;\n});\n// fixed length tree\nvar flt = new u8(288);\nfor (var i = 0; i < 144; ++i)\n flt[i] = 8;\nfor (var i = 144; i < 256; ++i)\n flt[i] = 9;\nfor (var i = 256; i < 280; ++i)\n flt[i] = 7;\nfor (var i = 280; i < 288; ++i)\n flt[i] = 8;\n// fixed distance tree\nvar fdt = new u8(32);\nfor (var i = 0; i < 32; ++i)\n fdt[i] = 5;\n// fixed length map\nvar flm = /*#__PURE__*/ hMap(flt, 9, 0), flrm = /*#__PURE__*/ hMap(flt, 9, 1);\n// fixed distance map\nvar fdm = /*#__PURE__*/ hMap(fdt, 5, 0), fdrm = /*#__PURE__*/ hMap(fdt, 5, 1);\n// find max of array\nvar max = function (a) {\n var m = a[0];\n for (var i = 1; i < a.length; ++i) {\n if (a[i] > m)\n m = a[i];\n }\n return m;\n};\n// read d, starting at bit p and mask with m\nvar bits = function (d, p, m) {\n var o = (p / 8) | 0;\n return ((d[o] | (d[o + 1] << 8)) >> (p & 7)) & m;\n};\n// read d, starting at bit p continuing for at least 16 bits\nvar bits16 = function (d, p) {\n var o = (p / 8) | 0;\n return ((d[o] | (d[o + 1] << 8) | (d[o + 2] << 16)) >> (p & 7));\n};\n// get end of byte\nvar shft = function (p) { return ((p + 7) / 8) | 0; };\n// typed array slice - allows garbage collector to free original reference,\n// while being more compatible than .slice\nvar slc = function (v, s, e) {\n if (s == null || s < 0)\n s = 0;\n if (e == null || e > v.length)\n e = v.length;\n // can't use .constructor in case user-supplied\n return new u8(v.subarray(s, e));\n};\n/**\n * Codes for errors generated within this library\n */\nexport var FlateErrorCode = {\n UnexpectedEOF: 0,\n InvalidBlockType: 1,\n InvalidLengthLiteral: 2,\n InvalidDistance: 3,\n StreamFinished: 4,\n NoStreamHandler: 5,\n InvalidHeader: 6,\n NoCallback: 7,\n InvalidUTF8: 8,\n ExtraFieldTooLong: 9,\n InvalidDate: 10,\n FilenameTooLong: 11,\n StreamFinishing: 12,\n InvalidZipData: 13,\n UnknownCompressionMethod: 14\n};\n// error codes\nvar ec = [\n 'unexpected EOF',\n 'invalid block type',\n 'invalid length/literal',\n 'invalid distance',\n 'stream finished',\n 'no stream handler',\n , // determined by compression function\n 'no callback',\n 'invalid UTF-8 data',\n 'extra field too long',\n 'date not in range 1980-2099',\n 'filename too long',\n 'stream finishing',\n 'invalid zip data'\n // determined by unknown compression method\n];\n;\nvar err = function (ind, msg, nt) {\n var e = new Error(msg || ec[ind]);\n e.code = ind;\n if (Error.captureStackTrace)\n Error.captureStackTrace(e, err);\n if (!nt)\n throw e;\n return e;\n};\n// expands raw DEFLATE data\nvar inflt = function (dat, st, buf, dict) {\n // source length dict length\n var sl = dat.length, dl = dict ? dict.length : 0;\n if (!sl || st.f && !st.l)\n return buf || new u8(0);\n var noBuf = !buf;\n // have to estimate size\n var resize = noBuf || st.i != 2;\n // no state\n var noSt = st.i;\n // Assumes roughly 33% compression ratio average\n if (noBuf)\n buf = new u8(sl * 3);\n // ensure buffer can fit at least l elements\n var cbuf = function (l) {\n var bl = buf.length;\n // need to increase size to fit\n if (l > bl) {\n // Double or set to necessary, whichever is greater\n var nbuf = new u8(Math.max(bl * 2, l));\n nbuf.set(buf);\n buf = nbuf;\n }\n };\n // last chunk bitpos bytes\n var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;\n // total bits\n var tbts = sl * 8;\n do {\n if (!lm) {\n // BFINAL - this is only 1 when last chunk is next\n final = bits(dat, pos, 1);\n // type: 0 = no compression, 1 = fixed huffman, 2 = dynamic huffman\n var type = bits(dat, pos + 1, 3);\n pos += 3;\n if (!type) {\n // go to end of byte boundary\n var s = shft(pos) + 4, l = dat[s - 4] | (dat[s - 3] << 8), t = s + l;\n if (t > sl) {\n if (noSt)\n err(0);\n break;\n }\n // ensure size\n if (resize)\n cbuf(bt + l);\n // Copy over uncompressed data\n buf.set(dat.subarray(s, t), bt);\n // Get new bitpos, update byte count\n st.b = bt += l, st.p = pos = t * 8, st.f = final;\n continue;\n }\n else if (type == 1)\n lm = flrm, dm = fdrm, lbt = 9, dbt = 5;\n else if (type == 2) {\n // literal lengths\n var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;\n var tl = hLit + bits(dat, pos + 5, 31) + 1;\n pos += 14;\n // length+distance tree\n var ldt = new u8(tl);\n // code length tree\n var clt = new u8(19);\n for (var i = 0; i < hcLen; ++i) {\n // use index map to get real code\n clt[clim[i]] = bits(dat, pos + i * 3, 7);\n }\n pos += hcLen * 3;\n // code lengths bits\n var clb = max(clt), clbmsk = (1 << clb) - 1;\n // code lengths map\n var clm = hMap(clt, clb, 1);\n for (var i = 0; i < tl;) {\n var r = clm[bits(dat, pos, clbmsk)];\n // bits read\n pos += r & 15;\n // symbol\n var s = r >> 4;\n // code length to copy\n if (s < 16) {\n ldt[i++] = s;\n }\n else {\n // copy count\n var c = 0, n = 0;\n if (s == 16)\n n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];\n else if (s == 17)\n n = 3 + bits(dat, pos, 7), pos += 3;\n else if (s == 18)\n n = 11 + bits(dat, pos, 127), pos += 7;\n while (n--)\n ldt[i++] = c;\n }\n }\n // length tree distance tree\n var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);\n // max length bits\n lbt = max(lt);\n // max dist bits\n dbt = max(dt);\n lm = hMap(lt, lbt, 1);\n dm = hMap(dt, dbt, 1);\n }\n else\n err(1);\n if (pos > tbts) {\n if (noSt)\n err(0);\n break;\n }\n }\n // Make sure the buffer can hold this + the largest possible addition\n // Maximum chunk size (practically, theoretically infinite) is 2^17\n if (resize)\n cbuf(bt + 131072);\n var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;\n var lpos = pos;\n for (;; lpos = pos) {\n // bits read, code\n var c = lm[bits16(dat, pos) & lms], sym = c >> 4;\n pos += c & 15;\n if (pos > tbts) {\n if (noSt)\n err(0);\n break;\n }\n if (!c)\n err(2);\n if (sym < 256)\n buf[bt++] = sym;\n else if (sym == 256) {\n lpos = pos, lm = null;\n break;\n }\n else {\n var add = sym - 254;\n // no extra bits needed if less\n if (sym > 264) {\n // index\n var i = sym - 257, b = fleb[i];\n add = bits(dat, pos, (1 << b) - 1) + fl[i];\n pos += b;\n }\n // dist\n var d = dm[bits16(dat, pos) & dms], dsym = d >> 4;\n if (!d)\n err(3);\n pos += d & 15;\n var dt = fd[dsym];\n if (dsym > 3) {\n var b = fdeb[dsym];\n dt += bits16(dat, pos) & (1 << b) - 1, pos += b;\n }\n if (pos > tbts) {\n if (noSt)\n err(0);\n break;\n }\n if (resize)\n cbuf(bt + 131072);\n var end = bt + add;\n if (bt < dt) {\n var shift = dl - dt, dend = Math.min(dt, end);\n if (shift + bt < 0)\n err(3);\n for (; bt < dend; ++bt)\n buf[bt] = dict[shift + bt];\n }\n for (; bt < end; ++bt)\n buf[bt] = buf[bt - dt];\n }\n }\n st.l = lm, st.p = lpos, st.b = bt, st.f = final;\n if (lm)\n final = 1, st.m = lbt, st.d = dm, st.n = dbt;\n } while (!final);\n // don't reallocate for streams or user buffers\n return bt != buf.length && noBuf ? slc(buf, 0, bt) : buf.subarray(0, bt);\n};\n// starting at p, write the minimum number of bits that can hold v to d\nvar wbits = function (d, p, v) {\n v <<= p & 7;\n var o = (p / 8) | 0;\n d[o] |= v;\n d[o + 1] |= v >> 8;\n};\n// starting at p, write the minimum number of bits (>8) that can hold v to d\nvar wbits16 = function (d, p, v) {\n v <<= p & 7;\n var o = (p / 8) | 0;\n d[o] |= v;\n d[o + 1] |= v >> 8;\n d[o + 2] |= v >> 16;\n};\n// creates code lengths from a frequency table\nvar hTree = function (d, mb) {\n // Need extra info to make a tree\n var t = [];\n for (var i = 0; i < d.length; ++i) {\n if (d[i])\n t.push({ s: i, f: d[i] });\n }\n var s = t.length;\n var t2 = t.slice();\n if (!s)\n return { t: et, l: 0 };\n if (s == 1) {\n var v = new u8(t[0].s + 1);\n v[t[0].s] = 1;\n return { t: v, l: 1 };\n }\n t.sort(function (a, b) { return a.f - b.f; });\n // after i2 reaches last ind, will be stopped\n // freq must be greater than largest possible number of symbols\n t.push({ s: -1, f: 25001 });\n var l = t[0], r = t[1], i0 = 0, i1 = 1, i2 = 2;\n t[0] = { s: -1, f: l.f + r.f, l: l, r: r };\n // efficient algorithm from UZIP.js\n // i0 is lookbehind, i2 is lookahead - after processing two low-freq\n // symbols that combined have high freq, will start processing i2 (high-freq,\n // non-composite) symbols instead\n // see https://reddit.com/r/photopea/comments/ikekht/uzipjs_questions/\n while (i1 != s - 1) {\n l = t[t[i0].f < t[i2].f ? i0++ : i2++];\n r = t[i0 != i1 && t[i0].f < t[i2].f ? i0++ : i2++];\n t[i1++] = { s: -1, f: l.f + r.f, l: l, r: r };\n }\n var maxSym = t2[0].s;\n for (var i = 1; i < s; ++i) {\n if (t2[i].s > maxSym)\n maxSym = t2[i].s;\n }\n // code lengths\n var tr = new u16(maxSym + 1);\n // max bits in tree\n var mbt = ln(t[i1 - 1], tr, 0);\n if (mbt > mb) {\n // more algorithms from UZIP.js\n // TODO: find out how this code works (debt)\n // ind debt\n var i = 0, dt = 0;\n // left cost\n var lft = mbt - mb, cst = 1 << lft;\n t2.sort(function (a, b) { return tr[b.s] - tr[a.s] || a.f - b.f; });\n for (; i < s; ++i) {\n var i2_1 = t2[i].s;\n if (tr[i2_1] > mb) {\n dt += cst - (1 << (mbt - tr[i2_1]));\n tr[i2_1] = mb;\n }\n else\n break;\n }\n dt >>= lft;\n while (dt > 0) {\n var i2_2 = t2[i].s;\n if (tr[i2_2] < mb)\n dt -= 1 << (mb - tr[i2_2]++ - 1);\n else\n ++i;\n }\n for (; i >= 0 && dt; --i) {\n var i2_3 = t2[i].s;\n if (tr[i2_3] == mb) {\n --tr[i2_3];\n ++dt;\n }\n }\n mbt = mb;\n }\n return { t: new u8(tr), l: mbt };\n};\n// get the max length and assign length codes\nvar ln = function (n, l, d) {\n return n.s == -1\n ? Math.max(ln(n.l, l, d + 1), ln(n.r, l, d + 1))\n : (l[n.s] = d);\n};\n// length codes generation\nvar lc = function (c) {\n var s = c.length;\n // Note that the semicolon was intentional\n while (s && !c[--s])\n ;\n var cl = new u16(++s);\n // ind num streak\n var cli = 0, cln = c[0], cls = 1;\n var w = function (v) { cl[cli++] = v; };\n for (var i = 1; i <= s; ++i) {\n if (c[i] == cln && i != s)\n ++cls;\n else {\n if (!cln && cls > 2) {\n for (; cls > 138; cls -= 138)\n w(32754);\n if (cls > 2) {\n w(cls > 10 ? ((cls - 11) << 5) | 28690 : ((cls - 3) << 5) | 12305);\n cls = 0;\n }\n }\n else if (cls > 3) {\n w(cln), --cls;\n for (; cls > 6; cls -= 6)\n w(8304);\n if (cls > 2)\n w(((cls - 3) << 5) | 8208), cls = 0;\n }\n while (cls--)\n w(cln);\n cls = 1;\n cln = c[i];\n }\n }\n return { c: cl.subarray(0, cli), n: s };\n};\n// calculate the length of output from tree, code lengths\nvar clen = function (cf, cl) {\n var l = 0;\n for (var i = 0; i < cl.length; ++i)\n l += cf[i] * cl[i];\n return l;\n};\n// writes a fixed block\n// returns the new bit pos\nvar wfblk = function (out, pos, dat) {\n // no need to write 00 as type: TypedArray defaults to 0\n var s = dat.length;\n var o = shft(pos + 2);\n out[o] = s & 255;\n out[o + 1] = s >> 8;\n out[o + 2] = out[o] ^ 255;\n out[o + 3] = out[o + 1] ^ 255;\n for (var i = 0; i < s; ++i)\n out[o + i + 4] = dat[i];\n return (o + 4 + s) * 8;\n};\n// writes a block\nvar wblk = function (dat, out, final, syms, lf, df, eb, li, bs, bl, p) {\n wbits(out, p++, final);\n ++lf[256];\n var _a = hTree(lf, 15), dlt = _a.t, mlb = _a.l;\n var _b = hTree(df, 15), ddt = _b.t, mdb = _b.l;\n var _c = lc(dlt), lclt = _c.c, nlc = _c.n;\n var _d = lc(ddt), lcdt = _d.c, ndc = _d.n;\n var lcfreq = new u16(19);\n for (var i = 0; i < lclt.length; ++i)\n ++lcfreq[lclt[i] & 31];\n for (var i = 0; i < lcdt.length; ++i)\n ++lcfreq[lcdt[i] & 31];\n var _e = hTree(lcfreq, 7), lct = _e.t, mlcb = _e.l;\n var nlcc = 19;\n for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc)\n ;\n var flen = (bl + 5) << 3;\n var ftlen = clen(lf, flt) + clen(df, fdt) + eb;\n var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + 2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18];\n if (bs >= 0 && flen <= ftlen && flen <= dtlen)\n return wfblk(out, p, dat.subarray(bs, bs + bl));\n var lm, ll, dm, dl;\n wbits(out, p, 1 + (dtlen < ftlen)), p += 2;\n if (dtlen < ftlen) {\n lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt;\n var llm = hMap(lct, mlcb, 0);\n wbits(out, p, nlc - 257);\n wbits(out, p + 5, ndc - 1);\n wbits(out, p + 10, nlcc - 4);\n p += 14;\n for (var i = 0; i < nlcc; ++i)\n wbits(out, p + 3 * i, lct[clim[i]]);\n p += 3 * nlcc;\n var lcts = [lclt, lcdt];\n for (var it = 0; it < 2; ++it) {\n var clct = lcts[it];\n for (var i = 0; i < clct.length; ++i) {\n var len = clct[i] & 31;\n wbits(out, p, llm[len]), p += lct[len];\n if (len > 15)\n wbits(out, p, (clct[i] >> 5) & 127), p += clct[i] >> 12;\n }\n }\n }\n else {\n lm = flm, ll = flt, dm = fdm, dl = fdt;\n }\n for (var i = 0; i < li; ++i) {\n var sym = syms[i];\n if (sym > 255) {\n var len = (sym >> 18) & 31;\n wbits16(out, p, lm[len + 257]), p += ll[len + 257];\n if (len > 7)\n wbits(out, p, (sym >> 23) & 31), p += fleb[len];\n var dst = sym & 31;\n wbits16(out, p, dm[dst]), p += dl[dst];\n if (dst > 3)\n wbits16(out, p, (sym >> 5) & 8191), p += fdeb[dst];\n }\n else {\n wbits16(out, p, lm[sym]), p += ll[sym];\n }\n }\n wbits16(out, p, lm[256]);\n return p + ll[256];\n};\n// deflate options (nice << 13) | chain\nvar deo = /*#__PURE__*/ new i32([65540, 131080, 131088, 131104, 262176, 1048704, 1048832, 2114560, 2117632]);\n// empty\nvar et = /*#__PURE__*/ new u8(0);\n// compresses data into a raw DEFLATE buffer\nvar dflt = function (dat, lvl, plvl, pre, post, st) {\n var s = st.z || dat.length;\n var o = new u8(pre + s + 5 * (1 + Math.ceil(s / 7000)) + post);\n // writing to this writes to the output buffer\n var w = o.subarray(pre, o.length - post);\n var lst = st.l;\n var pos = (st.r || 0) & 7;\n if (lvl) {\n if (pos)\n w[0] = st.r >> 3;\n var opt = deo[lvl - 1];\n var n = opt >> 13, c = opt & 8191;\n var msk_1 = (1 << plvl) - 1;\n // prev 2-byte val map curr 2-byte val map\n var prev = st.p || new u16(32768), head = st.h || new u16(msk_1 + 1);\n var bs1_1 = Math.ceil(plvl / 3), bs2_1 = 2 * bs1_1;\n var hsh = function (i) { return (dat[i] ^ (dat[i + 1] << bs1_1) ^ (dat[i + 2] << bs2_1)) & msk_1; };\n // 24576 is an arbitrary number of maximum symbols per block\n // 424 buffer for last block\n var syms = new i32(25000);\n // length/literal freq distance freq\n var lf = new u16(288), df = new u16(32);\n // l/lcnt exbits index l/lind waitdx blkpos\n var lc_1 = 0, eb = 0, i = st.i || 0, li = 0, wi = st.w || 0, bs = 0;\n for (; i + 2 < s; ++i) {\n // hash value\n var hv = hsh(i);\n // index mod 32768 previous index mod\n var imod = i & 32767, pimod = head[hv];\n prev[imod] = pimod;\n head[hv] = imod;\n // We always should modify head and prev, but only add symbols if\n // this data is not yet processed (\"wait\" for wait index)\n if (wi <= i) {\n // bytes remaining\n var rem = s - i;\n if ((lc_1 > 7000 || li > 24576) && (rem > 423 || !lst)) {\n pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i - bs, pos);\n li = lc_1 = eb = 0, bs = i;\n for (var j = 0; j < 286; ++j)\n lf[j] = 0;\n for (var j = 0; j < 30; ++j)\n df[j] = 0;\n }\n // len dist chain\n var l = 2, d = 0, ch_1 = c, dif = imod - pimod & 32767;\n if (rem > 2 && hv == hsh(i - dif)) {\n var maxn = Math.min(n, rem) - 1;\n var maxd = Math.min(32767, i);\n // max possible length\n // not capped at dif because decompressors implement \"rolling\" index population\n var ml = Math.min(258, rem);\n while (dif <= maxd && --ch_1 && imod != pimod) {\n if (dat[i + l] == dat[i + l - dif]) {\n var nl = 0;\n for (; nl < ml && dat[i + nl] == dat[i + nl - dif]; ++nl)\n ;\n if (nl > l) {\n l = nl, d = dif;\n // break out early when we reach \"nice\" (we are satisfied enough)\n if (nl > maxn)\n break;\n // now, find the rarest 2-byte sequence within this\n // length of literals and search for that instead.\n // Much faster than just using the start\n var mmd = Math.min(dif, nl - 2);\n var md = 0;\n for (var j = 0; j < mmd; ++j) {\n var ti = i - dif + j & 32767;\n var pti = prev[ti];\n var cd = ti - pti & 32767;\n if (cd > md)\n md = cd, pimod = ti;\n }\n }\n }\n // check the previous match\n imod = pimod, pimod = prev[imod];\n dif += imod - pimod & 32767;\n }\n }\n // d will be nonzero only when a match was found\n if (d) {\n // store both dist and len data in one int32\n // Make sure this is recognized as a len/dist with 28th bit (2^28)\n syms[li++] = 268435456 | (revfl[l] << 18) | revfd[d];\n var lin = revfl[l] & 31, din = revfd[d] & 31;\n eb += fleb[lin] + fdeb[din];\n ++lf[257 + lin];\n ++df[din];\n wi = i + l;\n ++lc_1;\n }\n else {\n syms[li++] = dat[i];\n ++lf[dat[i]];\n }\n }\n }\n for (i = Math.max(i, wi); i < s; ++i) {\n syms[li++] = dat[i];\n ++lf[dat[i]];\n }\n pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i - bs, pos);\n if (!lst) {\n st.r = (pos & 7) | w[(pos / 8) | 0] << 3;\n // shft(pos) now 1 less if pos & 7 != 0\n pos -= 7;\n st.h = head, st.p = prev, st.i = i, st.w = wi;\n }\n }\n else {\n for (var i = st.w || 0; i < s + lst; i += 65535) {\n // end\n var e = i + 65535;\n if (e >= s) {\n // write final block\n w[(pos / 8) | 0] = lst;\n e = s;\n }\n pos = wfblk(w, pos + 1, dat.subarray(i, e));\n }\n st.i = s;\n }\n return slc(o, 0, pre + shft(pos) + post);\n};\n// CRC32 table\nvar crct = /*#__PURE__*/ (function () {\n var t = new Int32Array(256);\n for (var i = 0; i < 256; ++i) {\n var c = i, k = 9;\n while (--k)\n c = ((c & 1) && -306674912) ^ (c >>> 1);\n t[i] = c;\n }\n return t;\n})();\n// CRC32\nvar crc = function () {\n var c = -1;\n return {\n p: function (d) {\n // closures have awful performance\n var cr = c;\n for (var i = 0; i < d.length; ++i)\n cr = crct[(cr & 255) ^ d[i]] ^ (cr >>> 8);\n c = cr;\n },\n d: function () { return ~c; }\n };\n};\n// Adler32\nvar adler = function () {\n var a = 1, b = 0;\n return {\n p: function (d) {\n // closures have awful performance\n var n = a, m = b;\n var l = d.length | 0;\n for (var i = 0; i != l;) {\n var e = Math.min(i + 2655, l);\n for (; i < e; ++i)\n m += n += d[i];\n n = (n & 65535) + 15 * (n >> 16), m = (m & 65535) + 15 * (m >> 16);\n }\n a = n, b = m;\n },\n d: function () {\n a %= 65521, b %= 65521;\n return (a & 255) << 24 | (a & 0xFF00) << 8 | (b & 255) << 8 | (b >> 8);\n }\n };\n};\n;\n// deflate with opts\nvar dopt = function (dat, opt, pre, post, st) {\n if (!st) {\n st = { l: 1 };\n if (opt.dictionary) {\n var dict = opt.dictionary.subarray(-32768);\n var newDat = new u8(dict.length + dat.length);\n newDat.set(dict);\n newDat.set(dat, dict.length);\n dat = newDat;\n st.w = dict.length;\n }\n }\n return dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? (st.l ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : 20) : (12 + opt.mem), pre, post, st);\n};\n// Walmart object spread\nvar mrg = function (a, b) {\n var o = {};\n for (var k in a)\n o[k] = a[k];\n for (var k in b)\n o[k] = b[k];\n return o;\n};\n// worker clone\n// This is possibly the craziest part of the entire codebase, despite how simple it may seem.\n// The only parameter to this function is a closure that returns an array of variables outside of the function scope.\n// We're going to try to figure out the variable names used in the closure as strings because that is crucial for workerization.\n// We will return an object mapping of true variable name to value (basically, the current scope as a JS object).\n// The reason we can't just use the original variable names is minifiers mangling the toplevel scope.\n// This took me three weeks to figure out how to do.\nvar wcln = function (fn, fnStr, td) {\n var dt = fn();\n var st = fn.toString();\n var ks = st.slice(st.indexOf('[') + 1, st.lastIndexOf(']')).replace(/\\s+/g, '').split(',');\n for (var i = 0; i < dt.length; ++i) {\n var v = dt[i], k = ks[i];\n if (typeof v == 'function') {\n fnStr += ';' + k + '=';\n var st_1 = v.toString();\n if (v.prototype) {\n // for global objects\n if (st_1.indexOf('[native code]') != -1) {\n var spInd = st_1.indexOf(' ', 8) + 1;\n fnStr += st_1.slice(spInd, st_1.indexOf('(', spInd));\n }\n else {\n fnStr += st_1;\n for (var t in v.prototype)\n fnStr += ';' + k + '.prototype.' + t + '=' + v.prototype[t].toString();\n }\n }\n else\n fnStr += st_1;\n }\n else\n td[k] = v;\n }\n return fnStr;\n};\nvar ch = [];\n// clone bufs\nvar cbfs = function (v) {\n var tl = [];\n for (var k in v) {\n if (v[k].buffer) {\n tl.push((v[k] = new v[k].constructor(v[k])).buffer);\n }\n }\n return tl;\n};\n// use a worker to execute code\nvar wrkr = function (fns, init, id, cb) {\n if (!ch[id]) {\n var fnStr = '', td_1 = {}, m = fns.length - 1;\n for (var i = 0; i < m; ++i)\n fnStr = wcln(fns[i], fnStr, td_1);\n ch[id] = { c: wcln(fns[m], fnStr, td_1), e: td_1 };\n }\n var td = mrg({}, ch[id].e);\n return wk(ch[id].c + ';onmessage=function(e){for(var k in e.data)self[k]=e.data[k];onmessage=' + init.toString() + '}', id, td, cbfs(td), cb);\n};\n// base async inflate fn\nvar bInflt = function () { return [u8, u16, i32, fleb, fdeb, clim, fl, fd, flrm, fdrm, rev, ec, hMap, max, bits, bits16, shft, slc, err, inflt, inflateSync, pbf, gopt]; };\nvar bDflt = function () { return [u8, u16, i32, fleb, fdeb, clim, revfl, revfd, flm, flt, fdm, fdt, rev, deo, et, hMap, wbits, wbits16, hTree, ln, lc, clen, wfblk, wblk, shft, slc, dflt, dopt, deflateSync, pbf]; };\n// gzip extra\nvar gze = function () { return [gzh, gzhl, wbytes, crc, crct]; };\n// gunzip extra\nvar guze = function () { return [gzs, gzl]; };\n// zlib extra\nvar zle = function () { return [zlh, wbytes, adler]; };\n// unzlib extra\nvar zule = function () { return [zls]; };\n// post buf\nvar pbf = function (msg) { return postMessage(msg, [msg.buffer]); };\n// get opts\nvar gopt = function (o) { return o && {\n out: o.size && new u8(o.size),\n dictionary: o.dictionary\n}; };\n// async helper\nvar cbify = function (dat, opts, fns, init, id, cb) {\n var w = wrkr(fns, init, id, function (err, dat) {\n w.terminate();\n cb(err, dat);\n });\n w.postMessage([dat, opts], opts.consume ? [dat.buffer] : []);\n return function () { w.terminate(); };\n};\n// auto stream\nvar astrm = function (strm) {\n strm.ondata = function (dat, final) { return postMessage([dat, final], [dat.buffer]); };\n return function (ev) {\n if (ev.data[0]) {\n strm.push(ev.data[0], ev.data[1]);\n postMessage([ev.data[0].length]);\n }\n else\n strm.flush(ev.data[1]);\n };\n};\n// async stream attach\nvar astrmify = function (fns, strm, opts, init, id, flush, ext) {\n var t;\n var w = wrkr(fns, init, id, function (err, dat) {\n if (err)\n w.terminate(), strm.ondata.call(strm, err);\n else if (!Array.isArray(dat))\n ext(dat);\n else if (dat.length == 1) {\n strm.queuedSize -= dat[0];\n if (strm.ondrain)\n strm.ondrain(dat[0]);\n }\n else {\n if (dat[1])\n w.terminate();\n strm.ondata.call(strm, err, dat[0], dat[1]);\n }\n });\n w.postMessage(opts);\n strm.queuedSize = 0;\n strm.push = function (d, f) {\n if (!strm.ondata)\n err(5);\n if (t)\n strm.ondata(err(4, 0, 1), null, !!f);\n strm.queuedSize += d.length;\n // can fail for cross-realm Uint8Array, but ok - only a small performance penalty\n w.postMessage([d, t = f], d.buffer instanceof ArrayBuffer ? [d.buffer] : []);\n };\n strm.terminate = function () { w.terminate(); };\n if (flush) {\n strm.flush = function (sync) { w.postMessage([0, sync]); };\n }\n};\n// read 2 bytes\nvar b2 = function (d, b) { return d[b] | (d[b + 1] << 8); };\n// read 4 bytes\nvar b4 = function (d, b) { return (d[b] | (d[b + 1] << 8) | (d[b + 2] << 16) | (d[b + 3] << 24)) >>> 0; };\n// read 8 bytes\nvar b8 = function (d, b) { return b4(d, b) + (b4(d, b + 4) * 4294967296); };\n// write bytes\nvar wbytes = function (d, b, v) {\n for (; v; ++b)\n d[b] = v, v >>>= 8;\n};\n// gzip header\nvar gzh = function (c, o) {\n var fn = o.filename;\n c[0] = 31, c[1] = 139, c[2] = 8, c[8] = o.level < 2 ? 4 : o.level == 9 ? 2 : 0, c[9] = 3; // assume Unix\n if (o.mtime != 0)\n wbytes(c, 4, Math.floor(new Date(o.mtime || Date.now()) / 1000));\n if (fn) {\n c[3] = 8;\n for (var i = 0; i <= fn.length; ++i)\n c[i + 10] = fn.charCodeAt(i);\n }\n};\n// gzip footer: -8 to -4 = CRC, -4 to -0 is length\n// gzip start\nvar gzs = function (d) {\n if (d[0] != 31 || d[1] != 139 || d[2] != 8)\n err(6, 'invalid gzip data');\n var flg = d[3];\n var st = 10;\n if (flg & 4)\n st += (d[10] | d[11] << 8) + 2;\n for (var zs = (flg >> 3 & 1) + (flg >> 4 & 1); zs > 0; zs -= !d[st++])\n ;\n return st + (flg & 2);\n};\n// gzip length\nvar gzl = function (d) {\n var l = d.length;\n return (d[l - 4] | d[l - 3] << 8 | d[l - 2] << 16 | d[l - 1] << 24) >>> 0;\n};\n// gzip header length\nvar gzhl = function (o) { return 10 + (o.filename ? o.filename.length + 1 : 0); };\n// zlib header\nvar zlh = function (c, o) {\n var lv = o.level, fl = lv == 0 ? 0 : lv < 6 ? 1 : lv == 9 ? 3 : 2;\n c[0] = 120, c[1] = (fl << 6) | (o.dictionary && 32);\n c[1] |= 31 - ((c[0] << 8) | c[1]) % 31;\n if (o.dictionary) {\n var h = adler();\n h.p(o.dictionary);\n wbytes(c, 2, h.d());\n }\n};\n// zlib start\nvar zls = function (d, dict) {\n if ((d[0] & 15) != 8 || (d[0] >> 4) > 7 || ((d[0] << 8 | d[1]) % 31))\n err(6, 'invalid zlib data');\n if ((d[1] >> 5 & 1) == +!dict)\n err(6, 'invalid zlib data: ' + (d[1] & 32 ? 'need' : 'unexpected') + ' dictionary');\n return (d[1] >> 3 & 4) + 2;\n};\nfunction StrmOpt(opts, cb) {\n if (typeof opts == 'function')\n cb = opts, opts = {};\n this.ondata = cb;\n return opts;\n}\n/**\n * Streaming DEFLATE compression\n */\nvar Deflate = /*#__PURE__*/ (function () {\n function Deflate(opts, cb) {\n if (typeof opts == 'function')\n cb = opts, opts = {};\n this.ondata = cb;\n this.o = opts || {};\n this.s = { l: 0, i: 32768, w: 32768, z: 32768 };\n // Buffer length must always be 0 mod 32768 for index calculations to be correct when modifying head and prev\n // 98304 = 32768 (lookback) + 65536 (common chunk size)\n this.b = new u8(98304);\n if (this.o.dictionary) {\n var dict = this.o.dictionary.subarray(-32768);\n this.b.set(dict, 32768 - dict.length);\n this.s.i = 32768 - dict.length;\n }\n }\n Deflate.prototype.p = function (c, f) {\n this.ondata(dopt(c, this.o, 0, 0, this.s), f);\n };\n /**\n * Pushes a chunk to be deflated\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Deflate.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n if (this.s.l)\n err(4);\n var endLen = chunk.length + this.s.z;\n if (endLen > this.b.length) {\n if (endLen > 2 * this.b.length - 32768) {\n var newBuf = new u8(endLen & -32768);\n newBuf.set(this.b.subarray(0, this.s.z));\n this.b = newBuf;\n }\n var split = this.b.length - this.s.z;\n this.b.set(chunk.subarray(0, split), this.s.z);\n this.s.z = this.b.length;\n this.p(this.b, false);\n this.b.set(this.b.subarray(-32768));\n this.b.set(chunk.subarray(split), 32768);\n this.s.z = chunk.length - split + 32768;\n this.s.i = 32766, this.s.w = 32768;\n }\n else {\n this.b.set(chunk, this.s.z);\n this.s.z += chunk.length;\n }\n this.s.l = final & 1;\n if (this.s.z > this.s.w + 8191 || final) {\n this.p(this.b, final || false);\n this.s.w = this.s.i, this.s.i -= 2;\n }\n if (final) {\n // cleanup unneeded buffers/state to reduce memory usage\n this.s = this.o = {};\n this.b = et;\n }\n };\n /**\n * Flushes buffered uncompressed data. Useful to immediately retrieve the\n * deflated output for small inputs.\n * @param sync Whether to flush to a byte boundary. A sync flush takes 4-5\n * extra bytes, but guarantees all pushed data is immediately\n * decompressible. A separate DEFLATE stream may be concatenated\n * with the current output after a sync flush.\n */\n Deflate.prototype.flush = function (sync) {\n if (!this.ondata)\n err(5);\n if (this.s.l)\n err(4);\n this.p(this.b, false);\n this.s.w = this.s.i, this.s.i -= 2;\n // could technically skip writing the type-0 block for (this.s.r & 7) == 0,\n // but the deterministic trailer (00 00 FF FF) is useful in some situations\n if (sync) {\n var c = new u8(6);\n c[0] = this.s.r >> 3;\n // write empty, non-final type-0 block\n var ep = wfblk(c, this.s.r, et);\n this.s.r = 0;\n this.ondata(c.subarray(0, ep >> 3), false);\n }\n };\n return Deflate;\n}());\nexport { Deflate };\n/**\n * Asynchronous streaming DEFLATE compression\n */\nvar AsyncDeflate = /*#__PURE__*/ (function () {\n function AsyncDeflate(opts, cb) {\n astrmify([\n bDflt,\n function () { return [astrm, Deflate]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Deflate(ev.data);\n onmessage = astrm(strm);\n }, 6, 1);\n }\n return AsyncDeflate;\n}());\nexport { AsyncDeflate };\nexport function deflate(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bDflt,\n ], function (ev) { return pbf(deflateSync(ev.data[0], ev.data[1])); }, 0, cb);\n}\n/**\n * Compresses data with DEFLATE without any wrapper\n * @param data The data to compress\n * @param opts The compression options\n * @returns The deflated version of the data\n */\nexport function deflateSync(data, opts) {\n return dopt(data, opts || {}, 0, 0);\n}\n/**\n * Streaming DEFLATE decompression\n */\nvar Inflate = /*#__PURE__*/ (function () {\n function Inflate(opts, cb) {\n // no StrmOpt here to avoid adding to workerizer\n if (typeof opts == 'function')\n cb = opts, opts = {};\n this.ondata = cb;\n var dict = opts && opts.dictionary && opts.dictionary.subarray(-32768);\n this.s = { i: 0, b: dict ? dict.length : 0 };\n this.o = new u8(32768);\n this.p = new u8(0);\n if (dict)\n this.o.set(dict);\n }\n Inflate.prototype.e = function (c) {\n if (!this.ondata)\n err(5);\n if (this.d)\n err(4);\n if (!this.p.length)\n this.p = c;\n else if (c.length) {\n var n = new u8(this.p.length + c.length);\n n.set(this.p), n.set(c, this.p.length), this.p = n;\n }\n };\n Inflate.prototype.c = function (final) {\n this.s.i = +(this.d = final || false);\n var bts = this.s.b;\n var dt = inflt(this.p, this.s, this.o);\n this.ondata(slc(dt, bts, this.s.b), this.d);\n this.o = slc(dt, this.s.b - 32768), this.s.b = this.o.length;\n this.p = slc(this.p, (this.s.p / 8) | 0), this.s.p &= 7;\n };\n /**\n * Pushes a chunk to be inflated\n * @param chunk The chunk to push\n * @param final Whether this is the final chunk\n */\n Inflate.prototype.push = function (chunk, final) {\n this.e(chunk), this.c(final);\n };\n return Inflate;\n}());\nexport { Inflate };\n/**\n * Asynchronous streaming DEFLATE decompression\n */\nvar AsyncInflate = /*#__PURE__*/ (function () {\n function AsyncInflate(opts, cb) {\n astrmify([\n bInflt,\n function () { return [astrm, Inflate]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Inflate(ev.data);\n onmessage = astrm(strm);\n }, 7, 0);\n }\n return AsyncInflate;\n}());\nexport { AsyncInflate };\nexport function inflate(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bInflt\n ], function (ev) { return pbf(inflateSync(ev.data[0], gopt(ev.data[1]))); }, 1, cb);\n}\nexport function inflateSync(data, opts) {\n return inflt(data, { i: 2 }, opts && opts.out, opts && opts.dictionary);\n}\n// before you yell at me for not just using extends, my reason is that TS inheritance is hard to workerize.\n/**\n * Streaming GZIP compression\n */\nvar Gzip = /*#__PURE__*/ (function () {\n function Gzip(opts, cb) {\n this.c = crc();\n this.l = 0;\n this.v = 1;\n Deflate.call(this, opts, cb);\n }\n /**\n * Pushes a chunk to be GZIPped\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Gzip.prototype.push = function (chunk, final) {\n this.c.p(chunk);\n this.l += chunk.length;\n Deflate.prototype.push.call(this, chunk, final);\n };\n Gzip.prototype.p = function (c, f) {\n var raw = dopt(c, this.o, this.v && gzhl(this.o), f && 8, this.s);\n if (this.v)\n gzh(raw, this.o), this.v = 0;\n if (f)\n wbytes(raw, raw.length - 8, this.c.d()), wbytes(raw, raw.length - 4, this.l);\n this.ondata(raw, f);\n };\n /**\n * Flushes buffered uncompressed data. Useful to immediately retrieve the\n * GZIPped output for small inputs.\n * @param sync Whether to flush to a byte boundary. A sync flush takes 4-5\n * extra bytes, but guarantees all pushed data is immediately\n * decompressible.\n */\n Gzip.prototype.flush = function (sync) {\n Deflate.prototype.flush.call(this, sync);\n };\n return Gzip;\n}());\nexport { Gzip };\n/**\n * Asynchronous streaming GZIP compression\n */\nvar AsyncGzip = /*#__PURE__*/ (function () {\n function AsyncGzip(opts, cb) {\n astrmify([\n bDflt,\n gze,\n function () { return [astrm, Deflate, Gzip]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Gzip(ev.data);\n onmessage = astrm(strm);\n }, 8, 1);\n }\n return AsyncGzip;\n}());\nexport { AsyncGzip };\nexport function gzip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bDflt,\n gze,\n function () { return [gzipSync]; }\n ], function (ev) { return pbf(gzipSync(ev.data[0], ev.data[1])); }, 2, cb);\n}\n/**\n * Compresses data with GZIP\n * @param data The data to compress\n * @param opts The compression options\n * @returns The gzipped version of the data\n */\nexport function gzipSync(data, opts) {\n if (!opts)\n opts = {};\n var c = crc(), l = data.length;\n c.p(data);\n var d = dopt(data, opts, gzhl(opts), 8), s = d.length;\n return gzh(d, opts), wbytes(d, s - 8, c.d()), wbytes(d, s - 4, l), d;\n}\n/**\n * Streaming single or multi-member GZIP decompression\n */\nvar Gunzip = /*#__PURE__*/ (function () {\n function Gunzip(opts, cb) {\n this.v = 1;\n this.r = 0;\n Inflate.call(this, opts, cb);\n }\n /**\n * Pushes a chunk to be GUNZIPped\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Gunzip.prototype.push = function (chunk, final) {\n Inflate.prototype.e.call(this, chunk);\n this.r += chunk.length;\n if (this.v) {\n var p = this.p.subarray(this.v - 1);\n var s = p.length > 3 ? gzs(p) : 4;\n if (s > p.length) {\n if (!final)\n return;\n }\n else if (this.v > 1 && this.onmember) {\n this.onmember(this.r - p.length);\n }\n this.p = p.subarray(s), this.v = 0;\n }\n // necessary to prevent TS from using the closure value\n // This allows for workerization to function correctly\n Inflate.prototype.c.call(this, 0);\n // process concatenated GZIP\n if (this.s.f && !this.s.l) {\n this.v = shft(this.s.p) + 9;\n this.s = { i: 0 };\n this.o = new u8(0);\n this.push(new u8(0), final);\n }\n else if (final) {\n Inflate.prototype.c.call(this, final);\n }\n };\n return Gunzip;\n}());\nexport { Gunzip };\n/**\n * Asynchronous streaming single or multi-member GZIP decompression\n */\nvar AsyncGunzip = /*#__PURE__*/ (function () {\n function AsyncGunzip(opts, cb) {\n var _this = this;\n astrmify([\n bInflt,\n guze,\n function () { return [astrm, Inflate, Gunzip]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Gunzip(ev.data);\n strm.onmember = function (offset) { return postMessage(offset); };\n onmessage = astrm(strm);\n }, 9, 0, function (offset) { return _this.onmember && _this.onmember(offset); });\n }\n return AsyncGunzip;\n}());\nexport { AsyncGunzip };\nexport function gunzip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bInflt,\n guze,\n function () { return [gunzipSync]; }\n ], function (ev) { return pbf(gunzipSync(ev.data[0], ev.data[1])); }, 3, cb);\n}\nexport function gunzipSync(data, opts) {\n var st = gzs(data);\n if (st + 8 > data.length)\n err(6, 'invalid gzip data');\n return inflt(data.subarray(st, -8), { i: 2 }, opts && opts.out || new u8(gzl(data)), opts && opts.dictionary);\n}\n/**\n * Streaming Zlib compression\n */\nvar Zlib = /*#__PURE__*/ (function () {\n function Zlib(opts, cb) {\n this.c = adler();\n this.v = 1;\n Deflate.call(this, opts, cb);\n }\n /**\n * Pushes a chunk to be zlibbed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Zlib.prototype.push = function (chunk, final) {\n this.c.p(chunk);\n Deflate.prototype.push.call(this, chunk, final);\n };\n Zlib.prototype.p = function (c, f) {\n var raw = dopt(c, this.o, this.v && (this.o.dictionary ? 6 : 2), f && 4, this.s);\n if (this.v)\n zlh(raw, this.o), this.v = 0;\n if (f)\n wbytes(raw, raw.length - 4, this.c.d());\n this.ondata(raw, f);\n };\n /**\n * Flushes buffered uncompressed data. Useful to immediately retrieve the\n * zlibbed output for small inputs.\n * @param sync Whether to flush to a byte boundary. A sync flush takes 4-5\n * extra bytes, but guarantees all pushed data is immediately\n * decompressible.\n */\n Zlib.prototype.flush = function (sync) {\n Deflate.prototype.flush.call(this, sync);\n };\n return Zlib;\n}());\nexport { Zlib };\n/**\n * Asynchronous streaming Zlib compression\n */\nvar AsyncZlib = /*#__PURE__*/ (function () {\n function AsyncZlib(opts, cb) {\n astrmify([\n bDflt,\n zle,\n function () { return [astrm, Deflate, Zlib]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Zlib(ev.data);\n onmessage = astrm(strm);\n }, 10, 1);\n }\n return AsyncZlib;\n}());\nexport { AsyncZlib };\nexport function zlib(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bDflt,\n zle,\n function () { return [zlibSync]; }\n ], function (ev) { return pbf(zlibSync(ev.data[0], ev.data[1])); }, 4, cb);\n}\n/**\n * Compress data with Zlib\n * @param data The data to compress\n * @param opts The compression options\n * @returns The zlib-compressed version of the data\n */\nexport function zlibSync(data, opts) {\n if (!opts)\n opts = {};\n var a = adler();\n a.p(data);\n var d = dopt(data, opts, opts.dictionary ? 6 : 2, 4);\n return zlh(d, opts), wbytes(d, d.length - 4, a.d()), d;\n}\n/**\n * Streaming Zlib decompression\n */\nvar Unzlib = /*#__PURE__*/ (function () {\n function Unzlib(opts, cb) {\n Inflate.call(this, opts, cb);\n this.v = opts && opts.dictionary ? 2 : 1;\n }\n /**\n * Pushes a chunk to be unzlibbed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Unzlib.prototype.push = function (chunk, final) {\n Inflate.prototype.e.call(this, chunk);\n if (this.v) {\n if (this.p.length < 6 && !final)\n return;\n this.p = this.p.subarray(zls(this.p, this.v - 1)), this.v = 0;\n }\n if (final) {\n if (this.p.length < 4)\n err(6, 'invalid zlib data');\n this.p = this.p.subarray(0, -4);\n }\n // necessary to prevent TS from using the closure value\n // This allows for workerization to function correctly\n Inflate.prototype.c.call(this, final);\n };\n return Unzlib;\n}());\nexport { Unzlib };\n/**\n * Asynchronous streaming Zlib decompression\n */\nvar AsyncUnzlib = /*#__PURE__*/ (function () {\n function AsyncUnzlib(opts, cb) {\n astrmify([\n bInflt,\n zule,\n function () { return [astrm, Inflate, Unzlib]; }\n ], this, StrmOpt.call(this, opts, cb), function (ev) {\n var strm = new Unzlib(ev.data);\n onmessage = astrm(strm);\n }, 11, 0);\n }\n return AsyncUnzlib;\n}());\nexport { AsyncUnzlib };\nexport function unzlib(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bInflt,\n zule,\n function () { return [unzlibSync]; }\n ], function (ev) { return pbf(unzlibSync(ev.data[0], gopt(ev.data[1]))); }, 5, cb);\n}\nexport function unzlibSync(data, opts) {\n return inflt(data.subarray(zls(data, opts && opts.dictionary), -4), { i: 2 }, opts && opts.out, opts && opts.dictionary);\n}\n// Default algorithm for compression (used because having a known output size allows faster decompression)\nexport { gzip as compress, AsyncGzip as AsyncCompress };\nexport { gzipSync as compressSync, Gzip as Compress };\n/**\n * Streaming GZIP, Zlib, or raw DEFLATE decompression\n */\nvar Decompress = /*#__PURE__*/ (function () {\n function Decompress(opts, cb) {\n this.o = StrmOpt.call(this, opts, cb) || {};\n this.G = Gunzip;\n this.I = Inflate;\n this.Z = Unzlib;\n }\n // init substream\n // overriden by AsyncDecompress\n Decompress.prototype.i = function () {\n var _this = this;\n this.s.ondata = function (dat, final) {\n _this.ondata(dat, final);\n };\n };\n /**\n * Pushes a chunk to be decompressed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Decompress.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n if (!this.s) {\n if (this.p && this.p.length) {\n var n = new u8(this.p.length + chunk.length);\n n.set(this.p), n.set(chunk, this.p.length);\n }\n else\n this.p = chunk;\n if (this.p.length > 2) {\n this.s = (this.p[0] == 31 && this.p[1] == 139 && this.p[2] == 8)\n ? new this.G(this.o)\n : ((this.p[0] & 15) != 8 || (this.p[0] >> 4) > 7 || ((this.p[0] << 8 | this.p[1]) % 31))\n ? new this.I(this.o)\n : new this.Z(this.o);\n this.i();\n this.s.push(this.p, final);\n this.p = null;\n }\n }\n else\n this.s.push(chunk, final);\n };\n return Decompress;\n}());\nexport { Decompress };\n/**\n * Asynchronous streaming GZIP, Zlib, or raw DEFLATE decompression\n */\nvar AsyncDecompress = /*#__PURE__*/ (function () {\n function AsyncDecompress(opts, cb) {\n Decompress.call(this, opts, cb);\n this.queuedSize = 0;\n this.G = AsyncGunzip;\n this.I = AsyncInflate;\n this.Z = AsyncUnzlib;\n }\n AsyncDecompress.prototype.i = function () {\n var _this = this;\n this.s.ondata = function (err, dat, final) {\n _this.ondata(err, dat, final);\n };\n this.s.ondrain = function (size) {\n _this.queuedSize -= size;\n if (_this.ondrain)\n _this.ondrain(size);\n };\n };\n /**\n * Pushes a chunk to be decompressed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n AsyncDecompress.prototype.push = function (chunk, final) {\n this.queuedSize += chunk.length;\n Decompress.prototype.push.call(this, chunk, final);\n };\n return AsyncDecompress;\n}());\nexport { AsyncDecompress };\nexport function decompress(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return (data[0] == 31 && data[1] == 139 && data[2] == 8)\n ? gunzip(data, opts, cb)\n : ((data[0] & 15) != 8 || (data[0] >> 4) > 7 || ((data[0] << 8 | data[1]) % 31))\n ? inflate(data, opts, cb)\n : unzlib(data, opts, cb);\n}\n/**\n * Expands compressed GZIP, Zlib, or raw DEFLATE data, automatically detecting the format\n * @param data The data to decompress\n * @param opts The decompression options\n * @returns The decompressed version of the data\n */\nexport function decompressSync(data, opts) {\n return (data[0] == 31 && data[1] == 139 && data[2] == 8)\n ? gunzipSync(data, opts)\n : ((data[0] & 15) != 8 || (data[0] >> 4) > 7 || ((data[0] << 8 | data[1]) % 31))\n ? inflateSync(data, opts)\n : unzlibSync(data, opts);\n}\n// flatten a directory structure\nvar fltn = function (d, p, t, o) {\n for (var k in d) {\n var val = d[k], n = p + k, op = o;\n if (Array.isArray(val))\n op = mrg(o, val[1]), val = val[0];\n if (ArrayBuffer.isView(val))\n t[n] = [val, op];\n else {\n t[n += '/'] = [new u8(0), op];\n fltn(val, n, t, o);\n }\n }\n};\n// text encoder\nvar te = typeof TextEncoder != 'undefined' && /*#__PURE__*/ new TextEncoder();\n// text decoder\nvar td = typeof TextDecoder != 'undefined' && /*#__PURE__*/ new TextDecoder();\n// text decoder stream\nvar tds = 0;\ntry {\n td.decode(et, { stream: true });\n tds = 1;\n}\ncatch (e) { }\n// decode UTF8\nvar dutf8 = function (d) {\n for (var r = '', i = 0;;) {\n var c = d[i++];\n var eb = (c > 127) + (c > 223) + (c > 239);\n if (i + eb > d.length)\n return { s: r, r: slc(d, i - 1) };\n if (!eb)\n r += String.fromCharCode(c);\n else if (eb == 3) {\n c = ((c & 15) << 18 | (d[i++] & 63) << 12 | (d[i++] & 63) << 6 | (d[i++] & 63)) - 65536,\n r += String.fromCharCode(55296 | (c >> 10), 56320 | (c & 1023));\n }\n else if (eb & 1)\n r += String.fromCharCode((c & 31) << 6 | (d[i++] & 63));\n else\n r += String.fromCharCode((c & 15) << 12 | (d[i++] & 63) << 6 | (d[i++] & 63));\n }\n};\n/**\n * Streaming UTF-8 decoding\n */\nvar DecodeUTF8 = /*#__PURE__*/ (function () {\n /**\n * Creates a UTF-8 decoding stream\n * @param cb The callback to call whenever data is decoded\n */\n function DecodeUTF8(cb) {\n this.ondata = cb;\n if (tds)\n this.t = new TextDecoder();\n else\n this.p = et;\n }\n /**\n * Pushes a chunk to be decoded from UTF-8 binary\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n DecodeUTF8.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n final = !!final;\n if (this.t) {\n this.ondata(this.t.decode(chunk, { stream: true }), final);\n if (final) {\n if (this.t.decode().length)\n err(8);\n this.t = null;\n }\n return;\n }\n if (!this.p)\n err(4);\n var dat = new u8(this.p.length + chunk.length);\n dat.set(this.p);\n dat.set(chunk, this.p.length);\n var _a = dutf8(dat), s = _a.s, r = _a.r;\n if (final) {\n if (r.length)\n err(8);\n this.p = null;\n }\n else\n this.p = r;\n this.ondata(s, final);\n };\n return DecodeUTF8;\n}());\nexport { DecodeUTF8 };\n/**\n * Streaming UTF-8 encoding\n */\nvar EncodeUTF8 = /*#__PURE__*/ (function () {\n /**\n * Creates a UTF-8 decoding stream\n * @param cb The callback to call whenever data is encoded\n */\n function EncodeUTF8(cb) {\n this.ondata = cb;\n }\n /**\n * Pushes a chunk to be encoded to UTF-8\n * @param chunk The string data to push\n * @param final Whether this is the last chunk\n */\n EncodeUTF8.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n if (this.d)\n err(4);\n this.ondata(strToU8(chunk), this.d = final || false);\n };\n return EncodeUTF8;\n}());\nexport { EncodeUTF8 };\n/**\n * Converts a string into a Uint8Array for use with compression/decompression methods\n * @param str The string to encode\n * @param latin1 Whether or not to interpret the data as Latin-1. This should\n * not need to be true unless decoding a binary string.\n * @returns The string encoded in UTF-8/Latin-1 binary\n */\nexport function strToU8(str, latin1) {\n if (latin1) {\n var ar_1 = new u8(str.length);\n for (var i = 0; i < str.length; ++i)\n ar_1[i] = str.charCodeAt(i);\n return ar_1;\n }\n if (te)\n return te.encode(str);\n var l = str.length;\n var ar = new u8(str.length + (str.length >> 1));\n var ai = 0;\n var w = function (v) { ar[ai++] = v; };\n for (var i = 0; i < l; ++i) {\n if (ai + 5 > ar.length) {\n var n = new u8(ai + 8 + ((l - i) << 1));\n n.set(ar);\n ar = n;\n }\n var c = str.charCodeAt(i);\n if (c < 128 || latin1)\n w(c);\n else if (c < 2048)\n w(192 | (c >> 6)), w(128 | (c & 63));\n else if (c > 55295 && c < 57344)\n c = 65536 + (c & 1023 << 10) | (str.charCodeAt(++i) & 1023),\n w(240 | (c >> 18)), w(128 | ((c >> 12) & 63)), w(128 | ((c >> 6) & 63)), w(128 | (c & 63));\n else\n w(224 | (c >> 12)), w(128 | ((c >> 6) & 63)), w(128 | (c & 63));\n }\n return slc(ar, 0, ai);\n}\n/**\n * Converts a Uint8Array to a string\n * @param dat The data to decode to string\n * @param latin1 Whether or not to interpret the data as Latin-1. This should\n * not need to be true unless encoding to binary string.\n * @returns The original UTF-8/Latin-1 string\n */\nexport function strFromU8(dat, latin1) {\n if (latin1) {\n var r = '';\n for (var i = 0; i < dat.length; i += 16384)\n r += String.fromCharCode.apply(null, dat.subarray(i, i + 16384));\n return r;\n }\n else if (td) {\n return td.decode(dat);\n }\n else {\n var _a = dutf8(dat), s = _a.s, r = _a.r;\n if (r.length)\n err(8);\n return s;\n }\n}\n;\n// deflate bit flag\nvar dbf = function (l) { return l == 1 ? 3 : l < 6 ? 2 : l == 9 ? 1 : 0; };\n// skip local zip header\nvar slzh = function (d, b) { return b + 30 + b2(d, b + 26) + b2(d, b + 28); };\n// read zip header\nvar zh = function (d, b, z) {\n var fnl = b2(d, b + 28), efl = b2(d, b + 30), fn = strFromU8(d.subarray(b + 46, b + 46 + fnl), !(b2(d, b + 8) & 2048)), es = b + 46 + fnl;\n var _a = z64hs(d, es, efl, z, b4(d, b + 20), b4(d, b + 24), b4(d, b + 42)), sc = _a[0], su = _a[1], off = _a[2];\n return [b2(d, b + 10), sc, su, fn, es + efl + b2(d, b + 32), off];\n};\n// read zip64 header sizes\nvar z64hs = function (d, b, l, z, sc, su, off) {\n var nsc = sc == 4294967295, nsu = su == 4294967295, noff = off == 4294967295, e = b + l;\n var nf = nsc + nsu + noff;\n if (z && nf) {\n for (; b + 4 < e; b += 4 + b2(d, b + 2)) {\n if (b2(d, b) == 1) {\n return [\n nsc ? b8(d, b + 4 + 8 * nsu) : sc,\n nsu ? b8(d, b + 4) : su,\n noff ? b8(d, b + 4 + 8 * (nsu + nsc)) : off,\n 1\n ];\n }\n }\n // z == 2 for unknown whether or not zip64\n if (z < 2)\n err(13);\n }\n return [sc, su, off, 0];\n};\n// extra field length\nvar exfl = function (ex) {\n var le = 0;\n if (ex) {\n for (var k in ex) {\n var l = ex[k].length;\n if (l > 65535)\n err(9);\n le += l + 4;\n }\n }\n return le;\n};\n// write zip header\nvar wzh = function (d, b, f, fn, u, c, ce, co) {\n var fl = fn.length, ex = f.extra, col = co && co.length;\n var exl = exfl(ex);\n wbytes(d, b, ce != null ? 0x2014B50 : 0x4034B50), b += 4;\n if (ce != null)\n d[b++] = 20, d[b++] = f.os;\n d[b] = 20, b += 2; // spec compliance? what's that?\n d[b++] = (f.flag << 1) | (c < 0 && 8), d[b++] = u && 8;\n d[b++] = f.compression & 255, d[b++] = f.compression >> 8;\n var dt = new Date(f.mtime == null ? Date.now() : f.mtime), y = dt.getFullYear() - 1980;\n if (y < 0 || y > 119)\n err(10);\n wbytes(d, b, (y << 25) | ((dt.getMonth() + 1) << 21) | (dt.getDate() << 16) | (dt.getHours() << 11) | (dt.getMinutes() << 5) | (dt.getSeconds() >> 1)), b += 4;\n if (c != -1) {\n wbytes(d, b, f.crc);\n wbytes(d, b + 4, c < 0 ? -c - 2 : c);\n wbytes(d, b + 8, f.size);\n }\n wbytes(d, b + 12, fl);\n wbytes(d, b + 14, exl), b += 16;\n if (ce != null) {\n wbytes(d, b, col);\n wbytes(d, b + 6, f.attrs);\n wbytes(d, b + 10, ce), b += 14;\n }\n d.set(fn, b);\n b += fl;\n if (exl) {\n for (var k in ex) {\n var exf = ex[k], l = exf.length;\n wbytes(d, b, +k);\n wbytes(d, b + 2, l);\n d.set(exf, b + 4), b += 4 + l;\n }\n }\n if (col)\n d.set(co, b), b += col;\n return b;\n};\n// write zip footer (end of central directory)\nvar wzf = function (o, b, c, d, e) {\n wbytes(o, b, 0x6054B50); // skip disk\n wbytes(o, b + 8, c);\n wbytes(o, b + 10, c);\n wbytes(o, b + 12, d);\n wbytes(o, b + 16, e);\n};\n/**\n * A pass-through stream to keep data uncompressed in a ZIP archive.\n */\nvar ZipPassThrough = /*#__PURE__*/ (function () {\n /**\n * Creates a pass-through stream that can be added to ZIP archives\n * @param filename The filename to associate with this data stream\n */\n function ZipPassThrough(filename) {\n this.filename = filename;\n this.c = crc();\n this.size = 0;\n this.compression = 0;\n }\n /**\n * Processes a chunk and pushes to the output stream. You can override this\n * method in a subclass for custom behavior, but by default this passes\n * the data through. You must call this.ondata(err, chunk, final) at some\n * point in this method.\n * @param chunk The chunk to process\n * @param final Whether this is the last chunk\n */\n ZipPassThrough.prototype.process = function (chunk, final) {\n this.ondata(null, chunk, final);\n };\n /**\n * Pushes a chunk to be added. If you are subclassing this with a custom\n * compression algorithm, note that you must push data from the source\n * file only, pre-compression.\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n ZipPassThrough.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n this.c.p(chunk);\n this.size += chunk.length;\n if (final)\n this.crc = this.c.d();\n // we shouldn't really do this cast, but properly handling ArrayBufferLike\n // makes the API unergonomic with Buffer\n this.process(chunk, final || false);\n };\n return ZipPassThrough;\n}());\nexport { ZipPassThrough };\n// I don't extend because TypeScript extension adds 1kB of runtime bloat\n/**\n * Streaming DEFLATE compression for ZIP archives. Prefer using AsyncZipDeflate\n * for better performance\n */\nvar ZipDeflate = /*#__PURE__*/ (function () {\n /**\n * Creates a DEFLATE stream that can be added to ZIP archives\n * @param filename The filename to associate with this data stream\n * @param opts The compression options\n */\n function ZipDeflate(filename, opts) {\n var _this = this;\n if (!opts)\n opts = {};\n ZipPassThrough.call(this, filename);\n this.d = new Deflate(opts, function (dat, final) {\n _this.ondata(null, dat, final);\n });\n this.compression = 8;\n this.flag = dbf(opts.level);\n }\n ZipDeflate.prototype.process = function (chunk, final) {\n try {\n this.d.push(chunk, final);\n }\n catch (e) {\n this.ondata(e, null, final);\n }\n };\n /**\n * Pushes a chunk to be deflated\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n ZipDeflate.prototype.push = function (chunk, final) {\n ZipPassThrough.prototype.push.call(this, chunk, final);\n };\n return ZipDeflate;\n}());\nexport { ZipDeflate };\n/**\n * Asynchronous streaming DEFLATE compression for ZIP archives\n */\nvar AsyncZipDeflate = /*#__PURE__*/ (function () {\n /**\n * Creates an asynchronous DEFLATE stream that can be added to ZIP archives\n * @param filename The filename to associate with this data stream\n * @param opts The compression options\n */\n function AsyncZipDeflate(filename, opts) {\n var _this = this;\n if (!opts)\n opts = {};\n ZipPassThrough.call(this, filename);\n this.d = new AsyncDeflate(opts, function (err, dat, final) {\n _this.ondata(err, dat, final);\n });\n this.compression = 8;\n this.flag = dbf(opts.level);\n this.terminate = this.d.terminate;\n }\n AsyncZipDeflate.prototype.process = function (chunk, final) {\n this.d.push(chunk, final);\n };\n /**\n * Pushes a chunk to be deflated\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n AsyncZipDeflate.prototype.push = function (chunk, final) {\n ZipPassThrough.prototype.push.call(this, chunk, final);\n };\n return AsyncZipDeflate;\n}());\nexport { AsyncZipDeflate };\n// TODO: Better tree shaking\n/**\n * A zippable archive to which files can incrementally be added\n */\nvar Zip = /*#__PURE__*/ (function () {\n /**\n * Creates an empty ZIP archive to which files can be added\n * @param cb The callback to call whenever data for the generated ZIP archive\n * is available\n */\n function Zip(cb) {\n this.ondata = cb;\n this.u = [];\n this.d = 1;\n }\n /**\n * Adds a file to the ZIP archive\n * @param file The file stream to add\n */\n Zip.prototype.add = function (file) {\n var _this = this;\n if (!this.ondata)\n err(5);\n // finishing or finished\n if (this.d & 2)\n this.ondata(err(4 + (this.d & 1) * 8, 0, 1), null, false);\n else {\n var f = strToU8(file.filename), fl_1 = f.length;\n var com = file.comment, o = com && strToU8(com);\n var u = fl_1 != file.filename.length || (o && (com.length != o.length));\n var hl_1 = fl_1 + exfl(file.extra) + 30;\n if (fl_1 > 65535)\n this.ondata(err(11, 0, 1), null, false);\n var header = new u8(hl_1);\n wzh(header, 0, file, f, u, -1);\n var chks_1 = [header];\n var pAll_1 = function () {\n for (var _i = 0, chks_2 = chks_1; _i < chks_2.length; _i++) {\n var chk = chks_2[_i];\n _this.ondata(null, chk, false);\n }\n chks_1 = [];\n };\n var tr_1 = this.d;\n this.d = 0;\n var ind_1 = this.u.length;\n var uf_1 = mrg(file, {\n f: f,\n u: u,\n o: o,\n t: function () {\n if (file.terminate)\n file.terminate();\n },\n r: function () {\n pAll_1();\n if (tr_1) {\n var nxt = _this.u[ind_1 + 1];\n if (nxt)\n nxt.r();\n else\n _this.d = 1;\n }\n tr_1 = 1;\n }\n });\n var cl_1 = 0;\n file.ondata = function (err, dat, final) {\n if (err) {\n _this.ondata(err, dat, final);\n _this.terminate();\n }\n else {\n cl_1 += dat.length;\n chks_1.push(dat);\n if (final) {\n var dd = new u8(16);\n wbytes(dd, 0, 0x8074B50);\n wbytes(dd, 4, file.crc);\n wbytes(dd, 8, cl_1);\n wbytes(dd, 12, file.size);\n chks_1.push(dd);\n uf_1.c = cl_1, uf_1.b = hl_1 + cl_1 + 16, uf_1.crc = file.crc, uf_1.size = file.size;\n if (tr_1)\n uf_1.r();\n tr_1 = 1;\n }\n else if (tr_1)\n pAll_1();\n }\n };\n this.u.push(uf_1);\n }\n };\n /**\n * Ends the process of adding files and prepares to emit the final chunks.\n * This *must* be called after adding all desired files for the resulting\n * ZIP file to work properly.\n */\n Zip.prototype.end = function () {\n var _this = this;\n if (this.d & 2) {\n this.ondata(err(4 + (this.d & 1) * 8, 0, 1), null, true);\n return;\n }\n if (this.d)\n this.e();\n else\n this.u.push({\n r: function () {\n if (!(_this.d & 1))\n return;\n _this.u.splice(-1, 1);\n _this.e();\n },\n t: function () { }\n });\n this.d = 3;\n };\n Zip.prototype.e = function () {\n var bt = 0, l = 0, tl = 0;\n for (var _i = 0, _a = this.u; _i < _a.length; _i++) {\n var f = _a[_i];\n tl += 46 + f.f.length + exfl(f.extra) + (f.o ? f.o.length : 0);\n }\n var out = new u8(tl + 22);\n for (var _b = 0, _c = this.u; _b < _c.length; _b++) {\n var f = _c[_b];\n wzh(out, bt, f, f.f, f.u, -f.c - 2, l, f.o);\n bt += 46 + f.f.length + exfl(f.extra) + (f.o ? f.o.length : 0), l += f.b;\n }\n wzf(out, bt, this.u.length, tl, l);\n this.ondata(null, out, true);\n this.d = 2;\n };\n /**\n * A method to terminate any internal workers used by the stream. Subsequent\n * calls to add() will fail.\n */\n Zip.prototype.terminate = function () {\n for (var _i = 0, _a = this.u; _i < _a.length; _i++) {\n var f = _a[_i];\n f.t();\n }\n this.d = 2;\n };\n return Zip;\n}());\nexport { Zip };\nexport function zip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n var r = {};\n fltn(data, '', r, opts);\n var k = Object.keys(r);\n var lft = k.length, o = 0, tot = 0;\n var slft = lft, files = new Array(lft);\n var term = [];\n var tAll = function () {\n for (var i = 0; i < term.length; ++i)\n term[i]();\n };\n var cbd = function (a, b) {\n mt(function () { cb(a, b); });\n };\n mt(function () { cbd = cb; });\n var cbf = function () {\n var out = new u8(tot + 22), oe = o, cdl = tot - o;\n tot = 0;\n for (var i = 0; i < slft; ++i) {\n var f = files[i];\n try {\n var l = f.c.length;\n wzh(out, tot, f, f.f, f.u, l);\n var badd = 30 + f.f.length + exfl(f.extra);\n var loc = tot + badd;\n out.set(f.c, loc);\n wzh(out, o, f, f.f, f.u, l, tot, f.m), o += 16 + badd + (f.m ? f.m.length : 0), tot = loc + l;\n }\n catch (e) {\n return cbd(e, null);\n }\n }\n wzf(out, o, files.length, cdl, oe);\n cbd(null, out);\n };\n if (!lft)\n cbf();\n var _loop_1 = function (i) {\n var fn = k[i];\n var _a = r[fn], file = _a[0], p = _a[1];\n var c = crc(), size = file.length;\n c.p(file);\n var f = strToU8(fn), s = f.length;\n var com = p.comment, m = com && strToU8(com), ms = m && m.length;\n var exl = exfl(p.extra);\n var compression = p.level == 0 ? 0 : 8;\n var cbl = function (e, d) {\n if (e) {\n tAll();\n cbd(e, null);\n }\n else {\n var l = d.length;\n files[i] = mrg(p, {\n size: size,\n crc: c.d(),\n c: d,\n f: f,\n m: m,\n u: s != fn.length || (m && (com.length != ms)),\n compression: compression\n });\n o += 30 + s + exl + l;\n tot += 76 + 2 * (s + exl) + (ms || 0) + l;\n if (!--lft)\n cbf();\n }\n };\n if (s > 65535)\n cbl(err(11, 0, 1), null);\n if (!compression)\n cbl(null, file);\n else if (size < 160000) {\n try {\n cbl(null, deflateSync(file, p));\n }\n catch (e) {\n cbl(e, null);\n }\n }\n else\n term.push(deflate(file, p, cbl));\n };\n // Cannot use lft because it can decrease\n for (var i = 0; i < slft; ++i) {\n _loop_1(i);\n }\n return tAll;\n}\n/**\n * Synchronously creates a ZIP file. Prefer using `zip` for better performance\n * with more than one file.\n * @param data The directory structure for the ZIP archive\n * @param opts The main options, merged with per-file options\n * @returns The generated ZIP archive\n */\nexport function zipSync(data, opts) {\n if (!opts)\n opts = {};\n var r = {};\n var files = [];\n fltn(data, '', r, opts);\n var o = 0;\n var tot = 0;\n for (var fn in r) {\n var _a = r[fn], file = _a[0], p = _a[1];\n var compression = p.level == 0 ? 0 : 8;\n var f = strToU8(fn), s = f.length;\n var com = p.comment, m = com && strToU8(com), ms = m && m.length;\n var exl = exfl(p.extra);\n if (s > 65535)\n err(11);\n var d = compression ? deflateSync(file, p) : file, l = d.length;\n var c = crc();\n c.p(file);\n files.push(mrg(p, {\n size: file.length,\n crc: c.d(),\n c: d,\n f: f,\n m: m,\n u: s != fn.length || (m && (com.length != ms)),\n o: o,\n compression: compression\n }));\n o += 30 + s + exl + l;\n tot += 76 + 2 * (s + exl) + (ms || 0) + l;\n }\n var out = new u8(tot + 22), oe = o, cdl = tot - o;\n for (var i = 0; i < files.length; ++i) {\n var f = files[i];\n wzh(out, f.o, f, f.f, f.u, f.c.length);\n var badd = 30 + f.f.length + exfl(f.extra);\n out.set(f.c, f.o + badd);\n wzh(out, o, f, f.f, f.u, f.c.length, f.o, f.m), o += 16 + badd + (f.m ? f.m.length : 0);\n }\n wzf(out, o, files.length, cdl, oe);\n return out;\n}\n/**\n * Streaming pass-through decompression for ZIP archives\n */\nvar UnzipPassThrough = /*#__PURE__*/ (function () {\n function UnzipPassThrough() {\n }\n UnzipPassThrough.prototype.push = function (chunk, final) {\n // same as ZipPassThrough: cast to retain Buffer ergonomics\n this.ondata(null, chunk, final);\n };\n UnzipPassThrough.compression = 0;\n return UnzipPassThrough;\n}());\nexport { UnzipPassThrough };\n/**\n * Streaming DEFLATE decompression for ZIP archives. Prefer AsyncZipInflate for\n * better performance.\n */\nvar UnzipInflate = /*#__PURE__*/ (function () {\n /**\n * Creates a DEFLATE decompression that can be used in ZIP archives\n */\n function UnzipInflate() {\n var _this = this;\n this.i = new Inflate(function (dat, final) {\n _this.ondata(null, dat, final);\n });\n }\n UnzipInflate.prototype.push = function (chunk, final) {\n try {\n this.i.push(chunk, final);\n }\n catch (e) {\n this.ondata(e, null, final);\n }\n };\n UnzipInflate.compression = 8;\n return UnzipInflate;\n}());\nexport { UnzipInflate };\n/**\n * Asynchronous streaming DEFLATE decompression for ZIP archives\n */\nvar AsyncUnzipInflate = /*#__PURE__*/ (function () {\n /**\n * Creates a DEFLATE decompression that can be used in ZIP archives\n */\n function AsyncUnzipInflate(_, sz) {\n var _this = this;\n if (sz < 320000) {\n this.i = new Inflate(function (dat, final) {\n _this.ondata(null, dat, final);\n });\n }\n else {\n this.i = new AsyncInflate(function (err, dat, final) {\n _this.ondata(err, dat, final);\n });\n this.terminate = this.i.terminate;\n }\n }\n AsyncUnzipInflate.prototype.push = function (chunk, final) {\n if (this.i.terminate)\n chunk = slc(chunk, 0);\n this.i.push(chunk, final);\n };\n AsyncUnzipInflate.compression = 8;\n return AsyncUnzipInflate;\n}());\nexport { AsyncUnzipInflate };\n/**\n * A ZIP archive decompression stream that emits files as they are discovered\n */\nvar Unzip = /*#__PURE__*/ (function () {\n /**\n * Creates a ZIP decompression stream\n * @param cb The callback to call whenever a file in the ZIP archive is found\n */\n function Unzip(cb) {\n this.onfile = cb;\n this.k = [];\n this.o = {\n 0: UnzipPassThrough\n };\n this.p = et;\n }\n /**\n * Pushes a chunk to be unzipped\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Unzip.prototype.push = function (chunk, final) {\n var _this = this;\n if (!this.onfile)\n err(5);\n if (!this.p)\n err(4);\n if (this.c > 0) {\n var len = Math.min(this.c, chunk.length);\n var toAdd = chunk.subarray(0, len);\n this.c -= len;\n if (this.d)\n this.d.push(toAdd, !this.c);\n else\n this.k[0].push(toAdd);\n chunk = chunk.subarray(len);\n if (chunk.length)\n return this.push(chunk, final);\n }\n else {\n var f = 0, i = 0, is = void 0, buf = void 0;\n if (!this.p.length)\n buf = chunk;\n else if (!chunk.length)\n buf = this.p;\n else {\n buf = new u8(this.p.length + chunk.length);\n buf.set(this.p), buf.set(chunk, this.p.length);\n }\n var l = buf.length, oc = this.c, add = oc && this.d;\n var _loop_2 = function () {\n var sig = b4(buf, i);\n if (sig == 0x4034B50) {\n f = 1, is = i;\n this_1.d = null;\n this_1.c = 0;\n var bf = b2(buf, i + 6), cmp_1 = b2(buf, i + 8), u = bf & 2048, dd = bf & 8, fnl = b2(buf, i + 26), es = b2(buf, i + 28);\n if (l > i + 30 + fnl + es) {\n var chks_3 = [];\n this_1.k.unshift(chks_3);\n f = 2;\n var lsc = b4(buf, i + 18), lsu = b4(buf, i + 22);\n var fn_1 = strFromU8(buf.subarray(i + 30, i += 30 + fnl), !u);\n var _a = z64hs(buf, i, es, 2, lsc, lsu, 0), sc_1 = _a[0], su_1 = _a[1], z64 = _a[3];\n if (dd)\n sc_1 = -1 - z64;\n i += es;\n this_1.c = sc_1;\n var d_1;\n var file_1 = {\n name: fn_1,\n compression: cmp_1,\n start: function () {\n if (!file_1.ondata)\n err(5);\n if (!sc_1)\n file_1.ondata(null, et, true);\n else {\n var ctr = _this.o[cmp_1];\n if (!ctr)\n file_1.ondata(err(14, 'unknown compression type ' + cmp_1, 1), null, false);\n d_1 = sc_1 < 0 ? new ctr(fn_1) : new ctr(fn_1, sc_1, su_1);\n d_1.ondata = function (err, dat, final) { file_1.ondata(err, dat, final); };\n for (var _i = 0, chks_4 = chks_3; _i < chks_4.length; _i++) {\n var dat = chks_4[_i];\n d_1.push(dat, false);\n }\n if (_this.k[0] == chks_3 && _this.c)\n _this.d = d_1;\n else\n d_1.push(et, true);\n }\n },\n terminate: function () {\n if (d_1 && d_1.terminate)\n d_1.terminate();\n }\n };\n if (sc_1 >= 0)\n file_1.size = sc_1, file_1.originalSize = su_1;\n this_1.onfile(file_1);\n }\n return \"break\";\n }\n else if (oc) {\n if (sig == 0x8074B50) {\n is = i += 12 + (oc == -2 && 8), f = 3, this_1.c = 0;\n return \"break\";\n }\n else if (sig == 0x2014B50) {\n is = i -= 4, f = 3, this_1.c = 0;\n return \"break\";\n }\n }\n };\n var this_1 = this;\n for (; i < l - 4; ++i) {\n var state_1 = _loop_2();\n if (state_1 === \"break\")\n break;\n }\n this.p = et;\n if (oc < 0) {\n var dat = f ? buf.subarray(0, is - 12 - (oc == -2 && 8) - (b4(buf, is - 16) == 0x8074B50 && 4)) : buf.subarray(0, i);\n if (add)\n add.push(dat, !!f);\n else\n this.k[+(f == 2)].push(dat);\n }\n if (f & 2)\n return this.push(buf.subarray(i), final);\n this.p = buf.subarray(i);\n }\n if (final) {\n if (this.c)\n err(13);\n this.p = null;\n }\n };\n /**\n * Registers a decoder with the stream, allowing for files compressed with\n * the compression type provided to be expanded correctly\n * @param decoder The decoder constructor\n */\n Unzip.prototype.register = function (decoder) {\n this.o[decoder.compression] = decoder;\n };\n return Unzip;\n}());\nexport { Unzip };\nvar mt = typeof queueMicrotask == 'function' ? queueMicrotask : typeof setTimeout == 'function' ? setTimeout : function (fn) { fn(); };\nexport function unzip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n var term = [];\n var tAll = function () {\n for (var i = 0; i < term.length; ++i)\n term[i]();\n };\n var files = {};\n var cbd = function (a, b) {\n mt(function () { cb(a, b); });\n };\n mt(function () { cbd = cb; });\n var e = data.length - 22;\n for (; b4(data, e) != 0x6054B50; --e) {\n if (!e || data.length - e > 65558) {\n cbd(err(13, 0, 1), null);\n return tAll;\n }\n }\n ;\n var lft = b2(data, e + 8);\n if (lft) {\n var c = lft;\n var o = b4(data, e + 16);\n var z = b4(data, e - 20) == 0x7064B50;\n if (z) {\n var ze = b4(data, e - 12);\n z = b4(data, ze) == 0x6064B50;\n if (z) {\n c = lft = b4(data, ze + 32);\n o = b4(data, ze + 48);\n }\n }\n var fltr = opts && opts.filter;\n var _loop_3 = function (i) {\n var _a = zh(data, o, z), c_1 = _a[0], sc = _a[1], su = _a[2], fn = _a[3], no = _a[4], off = _a[5], b = slzh(data, off);\n o = no;\n var cbl = function (e, d) {\n if (e) {\n tAll();\n cbd(e, null);\n }\n else {\n if (d)\n files[fn] = d;\n if (!--lft)\n cbd(null, files);\n }\n };\n if (!fltr || fltr({\n name: fn,\n size: sc,\n originalSize: su,\n compression: c_1\n })) {\n if (!c_1)\n cbl(null, slc(data, b, b + sc));\n else if (c_1 == 8) {\n var infl = data.subarray(b, b + sc);\n // Synchronously decompress under 512KB, or barely-compressed data\n if (su < 524288 || sc > 0.8 * su) {\n try {\n cbl(null, inflateSync(infl, { out: new u8(su) }));\n }\n catch (e) {\n cbl(e, null);\n }\n }\n else\n term.push(inflate(infl, { size: su }, cbl));\n }\n else\n cbl(err(14, 'unknown compression type ' + c_1, 1), null);\n }\n else\n cbl(null, null);\n };\n for (var i = 0; i < c; ++i) {\n _loop_3(i);\n }\n }\n else\n cbd(null, {});\n return tAll;\n}\n/**\n * Synchronously decompresses a ZIP archive. Prefer using `unzip` for better\n * performance with more than one file.\n * @param data The raw compressed ZIP file\n * @param opts The ZIP extraction options\n * @returns The decompressed files\n */\nexport function unzipSync(data, opts) {\n var files = {};\n var e = data.length - 22;\n for (; b4(data, e) != 0x6054B50; --e) {\n if (!e || data.length - e > 65558)\n err(13);\n }\n ;\n var c = b2(data, e + 8);\n if (!c)\n return {};\n var o = b4(data, e + 16);\n var z = b4(data, e - 20) == 0x7064B50;\n if (z) {\n var ze = b4(data, e - 12);\n z = b4(data, ze) == 0x6064B50;\n if (z) {\n c = b4(data, ze + 32);\n o = b4(data, ze + 48);\n }\n }\n var fltr = opts && opts.filter;\n for (var i = 0; i < c; ++i) {\n var _a = zh(data, o, z), c_2 = _a[0], sc = _a[1], su = _a[2], fn = _a[3], no = _a[4], off = _a[5], b = slzh(data, off);\n o = no;\n if (!fltr || fltr({\n name: fn,\n size: sc,\n originalSize: su,\n compression: c_2\n })) {\n if (!c_2)\n files[fn] = slc(data, b, b + sc);\n else if (c_2 == 8)\n files[fn] = inflateSync(data.subarray(b, b + sc), { out: new u8(su) });\n else\n err(14, 'unknown compression type ' + c_2);\n }\n }\n return files;\n}\n","/**\n * ZIP extraction — archive bytes in, regular File objects out.\n */\nimport { type Unzipped, unzip } from 'fflate';\nimport { setRelativePath } from './files';\n\nexport interface ZipExtractionResult {\n /** Extracted files as regular File objects */\n files: File[];\n /** Any errors encountered during extraction */\n errors: string[];\n}\n\n/**\n * Extracts all files from a ZIP archive.\n *\n * Uses fflate's ASYNCHRONOUS `unzip`, which inflates off the main thread. The\n * synchronous variant would block the tab for the duration — unacceptable on\n * this package's headline interaction, where a large folder is the normal case.\n */\nexport async function extractZipToFiles(zipFile: File): Promise<ZipExtractionResult> {\n try {\n const bytes = new Uint8Array(await zipFile.arrayBuffer());\n const entries = await new Promise<Unzipped>((resolve, reject) => {\n unzip(bytes, (err, data) => (err ? reject(err) : resolve(data)));\n });\n\n const files: File[] = [];\n const errors: string[] = [];\n\n for (const [path, data] of Object.entries(entries)) {\n // Skip directory entries\n if (path.endsWith('/') && data.length === 0) continue;\n\n const sanitizedPath = normalizePath(path);\n\n // Empty after normalization (e.g. all \"../..\") has no servable address\n if (!sanitizedPath) {\n errors.push(`Skipped invalid path: ${path}`);\n continue;\n }\n\n const filename = sanitizedPath.split('/').pop() || sanitizedPath;\n\n // Copy to own ArrayBuffer (fflate shares backing buffers across entries).\n // No `type` is set: the platform derives Content-Type from the path\n // server-side, and nothing between here and the wire reads it.\n const file = new File([new Uint8Array(data)], filename);\n\n // Set webkitRelativePath to the full path — same contract as drag-and-drop\n // files. This unifies the path mechanism: every file source carries its\n // deploy path on webkitRelativePath and its bare name on file.name.\n setRelativePath(file, sanitizedPath);\n\n files.push(file);\n }\n\n return { files, errors };\n } catch (error) {\n return {\n files: [],\n errors: [\n `Failed to load ZIP file: ${error instanceof Error ? error.message : String(error)}`,\n ],\n };\n }\n}\n\n/**\n * Sanitize and normalize an archive entry path to prevent directory traversal.\n * Removes: .., ., leading/trailing slashes, absolute paths, and empty segments.\n *\n * @example\n * normalizePath('../../etc/passwd') → 'etc/passwd'\n * normalizePath('foo/./bar/../baz.txt') → 'foo/baz.txt'\n * normalizePath('/absolute/path.txt') → 'absolute/path.txt'\n */\nexport function normalizePath(path: string): string {\n const normalized: string[] = [];\n\n for (const segment of path.split('/')) {\n if (segment === '' || segment === '.') continue;\n\n if (segment === '..') {\n // Pop only when there is somewhere to go back to — this is what prevents\n // traversal above the archive root.\n normalized.pop();\n continue;\n }\n\n normalized.push(segment);\n }\n\n return normalized.join('/');\n}\n\n/**\n * Check if a file is a ZIP file based on MIME type or extension\n */\nexport function isZipFile(file: File): boolean {\n return (\n file.type === 'application/zip' ||\n file.type === 'application/x-zip-compressed' ||\n file.name.toLowerCase().endsWith('.zip')\n );\n}\n","/**\n * The drop pipeline — everything between \"here are some Files\" and \"here is a\n * verdict\", with no React in sight.\n *\n * It takes `PlatformLimits` rather than a `Ship` client, which is what makes it\n * a plain function: source-name detection, ZIP extraction, unbuilt-project\n * detection, junk filtering, path normalization, entry-point and limit\n * validation, all reachable by direct call. `useDrop` is a state machine over\n * this; a non-React consumer can call it directly.\n */\nimport { filterJunk, pluralize, validateFiles } from '@shipstatic/ship';\nimport {\n FileValidationStatus,\n hasUnbuiltMarker,\n isShipError,\n type PlatformLimits,\n type ValidatableFile,\n} from '@shipstatic/types';\nimport { applyStatus, createProcessedFile, filePath, stripCommonPrefix } from './files';\nimport type { DropStatus, ProcessedFile } from './types';\nimport { extractZipToFiles, isZipFile } from './zip';\n\nexport interface ProcessFilesOptions {\n /** Platform limits, from `ship.getLimits()` */\n limits: PlatformLimits;\n /** Progress reporter for long steps */\n onStatus?: (status: DropStatus) => void;\n}\n\n/**\n * The verdict. Mirrors the hook's state minus `isDragging`, which is a pointer\n * concern the pipeline knows nothing about.\n *\n * Ready files are `files.filter(f => f.status === FileValidationStatus.READY)` — kept as\n * one derivation rather than a second field that could disagree with the first.\n */\nexport interface DropOutcome {\n phase: 'ready' | 'error';\n files: ProcessedFile[];\n sourceName: string;\n status: DropStatus;\n needsBuild: boolean;\n}\n\n/**\n * The exact shape drop hands to Ship's validator.\n *\n * **The deploy path is the name.** Server-side validation runs on full paths, so\n * sending the basename would validate a different string than the platform will.\n * `ProcessedFile` is not passed through directly even though it satisfies\n * `ValidatableFile`, because its `name` is the display basename.\n */\nexport function toValidatable(file: ProcessedFile): ValidatableFile {\n return { name: file.path, size: file.size };\n}\n\n/** A friendly name for whatever the user dropped. */\nexport function detectSourceName(files: File[]): string {\n if (files.length === 0) return '';\n\n const [first] = files;\n if (files.length === 1 && isZipFile(first)) return first.name.replace(/\\.zip$/i, '');\n\n // A folder drop/selection carries its root in webkitRelativePath\n const path = first.webkitRelativePath || '';\n return path.includes('/') ? path.split('/')[0] : first.name;\n}\n\nfunction failure(params: {\n title: string;\n details: string;\n errors?: string[];\n files?: ProcessedFile[];\n sourceName: string;\n needsBuild?: boolean;\n}): DropOutcome {\n const { title, details, errors, files = [], sourceName, needsBuild = false } = params;\n return {\n phase: 'error',\n files,\n sourceName,\n needsBuild,\n // `details` carries the single user-facing message; `errors` is for per-item\n // breakdowns. Omitted when empty, otherwise consumers that render both\n // fields show the message twice.\n status: { title, details, ...(errors?.length ? { errors } : {}) },\n };\n}\n\n/**\n * Run the pipeline.\n *\n * Never throws: an unbuilt project rejected by `filterJunk`, a missing entry\n * point, a file over the limit, and an unexpected host-object failure all come\n * back as an `error` outcome. Callers need no try/catch.\n */\nexport async function processFiles(\n input: File[],\n { limits, onStatus }: ProcessFilesOptions,\n): Promise<DropOutcome> {\n // Assigned inside the try: reading `webkitRelativePath` touches host objects,\n // and the no-throw guarantee has to cover the very first one.\n let sourceName = '';\n\n try {\n sourceName = detectSourceName(input);\n\n // Step 1: a lone ZIP is extracted; ZIPs among several files stay as files\n let files: File[];\n if (input.length === 1 && isZipFile(input[0])) {\n onStatus?.({ title: 'Extracting...', details: `Extracting ${input[0].name}...` });\n const { files: extracted, errors } = await extractZipToFiles(input[0]);\n if (errors.length > 0) console.warn('ZIP extraction errors:', errors);\n files = extracted;\n } else {\n files = input;\n }\n\n // Step 2: unbuilt-project detection. When the server will build, source\n // files are legitimate input rather than a mistake.\n const needsBuild = files.some((f) => hasUnbuiltMarker(filePath(f)));\n\n // Strip node_modules for build uploads. Drag-drop skips it during traversal;\n // the folder picker (webkitdirectory) hands it over anyway.\n if (needsBuild) {\n files = files.filter(\n (f) => !filePath(f).replace(/\\\\/g, '/').split('/').includes('node_modules'),\n );\n }\n\n // Step 3: junk filtering (throws ShipError on an unbuilt project unless allowed)\n const kept = new Set(filterJunk(files.map(filePath), { allowUnbuilt: needsBuild }));\n\n // Step 4: convert to ProcessedFile, then strip the common directory prefix.\n // Empty files are kept — validation marks them EXCLUDED with a warning\n // rather than failing the deploy.\n const finalFiles = stripCommonPrefix(\n files.filter((f) => kept.has(filePath(f))).map((f) => createProcessedFile(f)),\n );\n\n // Step 5: entry point. A built site must serve index.html from the root; an\n // unbuilt project may keep it anywhere, since the build decides the output.\n if (finalFiles.length > 0) {\n const hasIndex = needsBuild\n ? finalFiles.some((f) => f.path === 'index.html' || f.path.endsWith('/index.html'))\n : finalFiles.some((f) => f.path === 'index.html');\n\n if (!hasIndex) {\n const details = needsBuild\n ? 'No index.html found — every web project needs an index.html entry point'\n : 'No index.html at root — the entry point must be in the top-level directory';\n return failure({\n title: 'Validation Failed',\n details,\n sourceName,\n needsBuild,\n files: applyStatus(finalFiles, FileValidationStatus.VALIDATION_FAILED, details),\n });\n }\n }\n\n // Step 6: build uploads skip deploy validation — the build service validates\n // its own output, and source files are not deploy output.\n if (needsBuild) {\n const ready = applyStatus(finalFiles, FileValidationStatus.READY);\n return {\n phase: 'ready',\n files: ready,\n sourceName,\n needsBuild: true,\n status: {\n title: 'Ready',\n details: `${pluralize(ready.length, 'file', 'files', true)} ready — project will be built`,\n },\n };\n }\n\n // Step 7: validate against platform limits\n const validation = validateFiles(finalFiles.map(toValidatable), limits);\n\n const validated = finalFiles.map((file, i) => ({\n ...file,\n status: validation.files[i]?.status ?? file.status,\n statusMessage: validation.files[i]?.statusMessage ?? file.statusMessage,\n }));\n\n // Atomic validation: any error fails the whole set\n if (!validation.canDeploy) {\n return failure({\n title: 'Validation Failed',\n details: `${pluralize(validation.errors.length, 'file', 'files', true)} failed validation`,\n errors: validation.errors.map((e) => `${e.file}: ${e.message}`),\n files: validated,\n sourceName,\n });\n }\n\n const readyCount = validated.filter((f) => f.status === FileValidationStatus.READY).length;\n const warnings = validation.warnings.map((w) => `${w.file}: ${w.message}`);\n\n if (readyCount > 0) {\n let details = `${pluralize(readyCount, 'file', 'files', true)} ready`;\n if (validation.warnings.length > 0) {\n details += ` (${pluralize(validation.warnings.length, 'empty file', 'empty files', true)} excluded)`;\n }\n return {\n phase: 'ready',\n files: validated,\n sourceName,\n needsBuild: false,\n status: { title: 'Ready', details, ...(warnings.length ? { warnings } : {}) },\n };\n }\n\n // Nothing deployable. Warnings alone (e.g. every file empty) is not an error\n // state — no ready files already disables the deploy action.\n if (validation.errors.length === 0 && validation.warnings.length > 0) {\n return {\n phase: 'ready',\n files: validated,\n sourceName,\n needsBuild: false,\n status: {\n title: 'All files excluded',\n details: `${pluralize(validation.warnings.length, 'file', 'files', true)} excluded (empty files cannot be deployed)`,\n warnings,\n },\n };\n }\n\n return failure({\n title: 'No Valid Files',\n details: 'None of the provided files could be processed.',\n files: validated,\n sourceName,\n });\n } catch (error) {\n // A ShipError here is a validation rejection thrown by filterJunk (unbuilt\n // project); anything else is an unexpected processing failure.\n const message = error instanceof Error ? error.message : String(error);\n const isValidation = isShipError(error);\n return failure({\n title: isValidation ? 'Validation Failed' : 'Processing Failed',\n details: isValidation ? message : `Failed to process files: ${message}`,\n sourceName,\n });\n }\n}\n","/**\n * `FileSystemEntry` traversal — the drag-and-drop folder API.\n *\n * This module is alone in its file for a testing reason that is also an\n * architectural one: `FileSystemEntry` objects cannot be constructed. They come\n * from a real user gesture over real OS paths, so no browser — Chromium\n * included — lets a test produce one. Every OTHER module in this package is\n * exercised against real platform objects; this is the single boundary where a\n * fake is unavoidable, and keeping it to one file keeps that statement true.\n */\nimport { setRelativePath } from './files';\n\n/**\n * Recursively collect Files from a dropped entry, setting `webkitRelativePath`\n * so folder structure survives.\n *\n * `node_modules` directories are skipped wholesale — never part of a valid\n * deployment, and traversing one costs real time on a source-project drop\n * (50K+ files).\n *\n * Unreadable entries are logged and skipped rather than failing the drop: a\n * partially readable folder still deploys.\n */\nexport async function traverseFileTree(\n entry: FileSystemEntry,\n files: File[],\n currentPath = '',\n): Promise<void> {\n try {\n if (entry.isFile) {\n const file = await new Promise<File>((resolve, reject) => {\n (entry as FileSystemFileEntry).file(resolve, reject);\n });\n setRelativePath(file, currentPath ? `${currentPath}/${file.name}` : file.name);\n files.push(file);\n return;\n }\n\n if (!entry.isDirectory) return;\n\n for (const child of await readDirectory(entry as FileSystemDirectoryEntry)) {\n if (child.isDirectory && child.name === 'node_modules') continue;\n\n // Entering a directory extends the path; a file's own name is appended by\n // the branch above, so it inherits the current path unchanged.\n const childPath = child.isDirectory\n ? currentPath\n ? `${currentPath}/${child.name}`\n : child.name\n : currentPath;\n await traverseFileTree(child, files, childPath);\n }\n } catch (error) {\n console.warn(`Error traversing file tree for entry ${entry.name}:`, error);\n }\n}\n\n/**\n * Read a directory to exhaustion.\n *\n * `readEntries` yields at most 100 entries per call and signals the end with an\n * empty batch, so a single call silently truncates any larger folder. Looping\n * until empty is the contract, not an optimization.\n */\nasync function readDirectory(directory: FileSystemDirectoryEntry): Promise<FileSystemEntry[]> {\n const reader = directory.createReader();\n const entries: FileSystemEntry[] = [];\n\n for (;;) {\n const batch = await new Promise<FileSystemEntry[]>((resolve, reject) => {\n reader.readEntries(resolve, reject);\n });\n if (batch.length === 0) return entries;\n entries.push(...batch);\n }\n}\n","/**\n * Headless drop hook for file upload workflows.\n *\n * This file owns React state, DOM events, and prop getters — nothing else. The\n * rules live in `./process` as a plain function.\n *\n * ```tsx\n * const drop = useDrop({ ship });\n *\n * <div {...drop.getDropzoneProps()}>\n * <input {...drop.getInputProps()} />\n * {drop.isDragging ? 'Drop here' : 'Click to upload'}\n * </div>\n * ```\n */\nimport type { Ship } from '@shipstatic/ship';\nimport { FileValidationStatus, WEB_FILE_ACCEPT } from '@shipstatic/types';\nimport { useCallback, useMemo, useRef, useState } from 'react';\nimport { traverseFileTree } from './entries';\nimport { setRelativePath } from './files';\nimport { processFiles as runPipeline } from './process';\nimport type { DropPhase, DropStatus, ProcessedFile } from './types';\n\nexport interface DropOptions {\n /**\n * The Ship client, for platform limits.\n *\n * Typed as only what drop calls, mirroring the SDK's own resource-factory\n * doctrine — a real `Ship` satisfies it, and nothing else has to be faked.\n */\n ship: Pick<Ship, 'getLimits'>;\n}\n\n/** Options for `getDropzoneProps()` */\nexport interface DropzonePropsOptions {\n /** Whether clicking the dropzone opens the file picker (default: true) */\n clickable?: boolean;\n}\n\n/**\n * Which picker `getInputProps()` describes and `open()` opens.\n *\n * **Folder is the default**, so a bare `getInputProps()` / `open()` — and the\n * dropzone's own click — address the folder picker exactly as they always have.\n *\n * The singular/plural mix is deliberate: you pick one folder or many files, and\n * these are the words the buttons above them carry.\n */\nexport type PickerMode = 'folder' | 'files';\n\n/**\n * The hidden input to spread onto an `<input>`.\n *\n * One shape for both modes, because exactly one attribute distinguishes them:\n * `webkitdirectory` makes the dialog a folder picker, and `accept` biases a file\n * picker's default view. Never both — a folder picker ignores `accept`, so\n * emitting it there would advertise a filter that does not apply.\n */\nexport interface DropInputProps {\n ref: React.RefObject<HTMLInputElement | null>;\n type: 'file';\n style: { display: string };\n multiple: boolean;\n /** Folder mode only — the attribute that makes it a folder picker. */\n webkitdirectory?: string;\n /**\n * Files mode only. A HINT, not a gate: every dialog offers an all-files\n * escape and drag-and-drop ignores `accept` outright, so the verdict on any\n * file is `validateFiles` downstream — the same one the dropzone reaches.\n */\n accept?: string;\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;\n}\n\nexport interface DropReturn {\n /** Current phase of the lifecycle */\n phase: DropPhase;\n /** Whether files are being processed (extraction, validation) */\n isProcessing: boolean;\n /** Whether the user is currently dragging over the dropzone */\n isDragging: boolean;\n /** Whether the dropzone is idle or holding a ready set */\n isInteractive: boolean;\n /** Whether an error occurred during processing */\n hasError: boolean;\n /** All processed files */\n files: ProcessedFile[];\n /** Friendly name of what was dropped (ZIP name, folder name, or filename) */\n sourceName: string;\n /** Current status for display */\n status: DropStatus | null;\n /** Whether the dropped files need server-side building before deployment */\n needsBuild: boolean;\n\n /** Props to spread on the dropzone element (drag & drop, optionally click) */\n getDropzoneProps: (options?: DropzonePropsOptions) => {\n onDragOver: (e: React.DragEvent) => void;\n onDragLeave: (e: React.DragEvent) => void;\n onDrop: (e: React.DragEvent) => void;\n onClick?: () => void;\n };\n /**\n * Props to spread on a hidden file input element, one per picker mode.\n *\n * Each mode owns its own element and its own ref, so a UI offering both\n * renders both inputs — `open(mode)` clicks whichever is mounted.\n */\n getInputProps: (mode?: PickerMode) => DropInputProps;\n\n /** Programmatically trigger a picker (default: the folder picker) */\n open: (mode?: PickerMode) => void;\n /** Process files directly (advanced — loses folder traversal) */\n processFiles: (files: File[]) => Promise<void>;\n /** Reset state and clear all files */\n reset: () => void;\n\n /** Only the files that passed validation */\n validFiles: ProcessedFile[];\n /** Raw File objects ready for Ship SDK upload */\n getFilesForUpload: () => File[];\n}\n\ninterface DropState {\n phase: DropPhase;\n isDragging: boolean;\n files: ProcessedFile[];\n sourceName: string;\n status: DropStatus | null;\n needsBuild: boolean;\n}\n\nconst initialState: DropState = {\n phase: 'idle',\n isDragging: false,\n files: [],\n sourceName: '',\n status: null,\n needsBuild: false,\n};\n\nexport function useDrop({ ship }: DropOptions): DropReturn {\n const [state, setState] = useState<DropState>(initialState);\n\n // Synchronous re-entry guard — React state is too late to gate a second drop\n const isProcessingRef = useRef(false);\n // One ref per picker: an <input> is either a folder picker or a file picker,\n // and toggling `webkitdirectory` on a live node to reuse a single element\n // would mean writing an attribute behind React's back.\n const folderInputRef = useRef<HTMLInputElement>(null);\n const filesInputRef = useRef<HTMLInputElement>(null);\n\n const isProcessing = state.phase === 'processing';\n const hasError = state.phase === 'error';\n const isInteractive = state.phase === 'idle' || state.phase === 'ready';\n\n const validFiles = useMemo(\n () => state.files.filter((f) => f.status === FileValidationStatus.READY),\n [state.files],\n );\n\n const getFilesForUpload = useCallback(() => validFiles.map((f) => f.file), [validFiles]);\n\n const processFiles = useCallback(\n async (newFiles: File[]) => {\n if (isProcessingRef.current) {\n console.warn('File processing already in progress. Ignoring duplicate call.');\n return;\n }\n if (!newFiles || newFiles.length === 0) return;\n\n isProcessingRef.current = true;\n setState({\n ...initialState,\n phase: 'processing',\n status: { title: 'Processing...', details: 'Validating and preparing files.' },\n });\n\n try {\n const outcome = await runPipeline(newFiles, {\n limits: await ship.getLimits(),\n onStatus: (status) => setState((prev) => ({ ...prev, status })),\n });\n\n setState({\n phase: outcome.phase,\n isDragging: false,\n files: outcome.files,\n sourceName: outcome.sourceName,\n status: outcome.status,\n needsBuild: outcome.needsBuild,\n });\n } finally {\n isProcessingRef.current = false;\n }\n },\n [ship],\n );\n\n const reset = useCallback(() => {\n setState(initialState);\n isProcessingRef.current = false;\n }, []);\n\n // Dragging is orthogonal to the phase: the flag flips, the phase is untouched.\n const handleDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n setState((prev) => (prev.isDragging ? prev : { ...prev, isDragging: true }));\n }, []);\n\n const handleDragLeave = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n setState((prev) => (prev.isDragging ? { ...prev, isDragging: false } : prev));\n }, []);\n\n const handleDrop = useCallback(\n async (e: React.DragEvent) => {\n e.preventDefault();\n setState((prev) => (prev.isDragging ? { ...prev, isDragging: false } : prev));\n\n const files: File[] = [];\n const directories: { entry: FileSystemEntry; path: string }[] = [];\n\n // `dataTransfer.items` is only valid synchronously — the browser\n // invalidates the list at the first await, so every entry is captured here\n // and traversed afterwards.\n for (const item of Array.from(e.dataTransfer.items)) {\n if (item.kind !== 'file') continue;\n try {\n const entry = item.webkitGetAsEntry?.();\n if (entry?.isDirectory) {\n directories.push({ entry, path: entry.name });\n } else {\n const file = item.getAsFile();\n if (file) {\n // Root files carry their own name as path, matching traverseFileTree\n setRelativePath(file, file.name);\n files.push(file);\n }\n }\n } catch (error) {\n console.warn('Error processing drop item:', error);\n const file = item.getAsFile();\n if (file) files.push(file);\n }\n }\n\n await Promise.all(directories.map((d) => traverseFileTree(d.entry, files, d.path)));\n\n // Browsers without webkitGetAsEntry still populate dataTransfer.files\n if (files.length === 0 && e.dataTransfer.files.length > 0) {\n files.push(...Array.from(e.dataTransfer.files));\n }\n\n if (files.length > 0) await processFiles(files);\n },\n [processFiles],\n );\n\n const handleInputChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const files = Array.from(e.target.files || []);\n if (files.length > 0) processFiles(files);\n // Clear the input so re-selecting the same folder fires onChange again\n e.target.value = '';\n },\n [processFiles],\n );\n\n // `files` is the exception, so any other value — including a stray argument —\n // resolves to the folder picker, and the default is written once.\n const open = useCallback((mode?: PickerMode) => {\n const input = mode === 'files' ? filesInputRef.current : folderInputRef.current;\n if (!input) {\n console.warn(\n `No ${mode === 'files' ? 'files' : 'folder'} input is mounted. Spread getInputProps('${mode === 'files' ? 'files' : 'folder'}') onto an <input> to open this picker.`,\n );\n return;\n }\n input.click();\n }, []);\n\n const getDropzoneProps = useCallback(\n (options?: DropzonePropsOptions) => {\n const { clickable = true } = options ?? {};\n return {\n onDragOver: handleDragOver,\n onDragLeave: handleDragLeave,\n onDrop: handleDrop,\n // Wrapped rather than passed by reference: `open` takes a mode, and a\n // click handler would hand it a MouseEvent.\n ...(clickable && { onClick: () => open() }),\n };\n },\n [handleDragOver, handleDragLeave, handleDrop, open],\n );\n\n const getInputProps = useCallback(\n (mode?: PickerMode): DropInputProps => ({\n ref: mode === 'files' ? filesInputRef : folderInputRef,\n type: 'file' as const,\n style: { display: 'none' },\n multiple: true,\n ...(mode === 'files' ? { accept: WEB_FILE_ACCEPT } : { webkitdirectory: '' }),\n onChange: handleInputChange,\n }),\n [handleInputChange],\n );\n\n return {\n phase: state.phase,\n isProcessing,\n isDragging: state.isDragging,\n isInteractive,\n hasError,\n files: state.files,\n sourceName: state.sourceName,\n status: state.status,\n needsBuild: state.needsBuild,\n\n getDropzoneProps,\n getInputProps,\n\n open,\n processFiles,\n reset,\n\n validFiles,\n getFilesForUpload,\n };\n}\n"]}