@higgsfield/video-editor-mcp 1.0.7 → 1.1.1-dev.0

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.
Files changed (189) hide show
  1. package/THIRD_PARTY_NOTICES.md +24 -24
  2. package/dist/cli.mjs +134 -125
  3. package/dist/index.html +136 -133
  4. package/dist/launcher.mjs +90 -90
  5. package/dist/server.mjs +1553 -1389
  6. package/node_modules/@higgsfield/higgsedit/README.md +181 -1
  7. package/node_modules/@higgsfield/higgsedit/dist/capture-page.js +902 -314
  8. package/node_modules/@higgsfield/higgsedit/dist/chunk-2JYLVSVV.mjs +1594 -0
  9. package/node_modules/@higgsfield/higgsedit/dist/chunk-2WKNH7OL.mjs +16 -0
  10. package/node_modules/@higgsfield/higgsedit/dist/{chunk-OMKZ5BXM.mjs → chunk-5LTTL3Q3.mjs} +1 -1
  11. package/node_modules/@higgsfield/higgsedit/dist/chunk-7PYXSJS7.mjs +717 -0
  12. package/node_modules/@higgsfield/higgsedit/dist/{chunk-MLJAIZGP.mjs → chunk-BH2QF635.mjs} +33 -326
  13. package/node_modules/@higgsfield/higgsedit/dist/{chunk-WZR5PZM7.mjs → chunk-BV5COOQZ.mjs} +250 -161
  14. package/node_modules/@higgsfield/higgsedit/dist/{chunk-HTCYVKFX.mjs → chunk-C3GSB3XZ.mjs} +8 -7
  15. package/node_modules/@higgsfield/higgsedit/dist/{chunk-CYH2EUQV.mjs → chunk-DVN4LUXV.mjs} +13 -4
  16. package/node_modules/@higgsfield/higgsedit/dist/chunk-F4CMIG5G.mjs +36 -0
  17. package/node_modules/@higgsfield/higgsedit/dist/chunk-IEPPEDEU.mjs +33 -0
  18. package/node_modules/@higgsfield/higgsedit/dist/{chunk-UVAZ6I6U.mjs → chunk-KIWGVAPJ.mjs} +16 -12
  19. package/node_modules/@higgsfield/higgsedit/dist/{chunk-L6QDNSL3.mjs → chunk-L5LWBA6A.mjs} +5 -5
  20. package/node_modules/@higgsfield/higgsedit/dist/chunk-LMQR3DHT.mjs +37 -0
  21. package/node_modules/@higgsfield/higgsedit/dist/chunk-LTKMGZ6T.mjs +58 -0
  22. package/node_modules/@higgsfield/higgsedit/dist/{chunk-VI6IV6JP.mjs → chunk-MV2JTTBQ.mjs} +65 -47
  23. package/node_modules/@higgsfield/higgsedit/dist/{chunk-4D6AXU4B.mjs → chunk-NARTAWRN.mjs} +50 -30
  24. package/node_modules/@higgsfield/higgsedit/dist/{chunk-27NBQ5FA.mjs → chunk-NUXTKQNM.mjs} +33 -21
  25. package/node_modules/@higgsfield/higgsedit/dist/chunk-OCIZ36XD.mjs +40 -0
  26. package/node_modules/@higgsfield/higgsedit/dist/{chunk-MK6PL7N4.mjs → chunk-OF6RMSM2.mjs} +19 -17
  27. package/node_modules/@higgsfield/higgsedit/dist/{chunk-6BETMESC.mjs → chunk-P2BGHTRR.mjs} +2 -2
  28. package/node_modules/@higgsfield/higgsedit/dist/{chunk-EKFC4S4M.mjs → chunk-PAHMD6SU.mjs} +5 -0
  29. package/node_modules/@higgsfield/higgsedit/dist/{chunk-QVLAEV3U.mjs → chunk-PFQYUJQL.mjs} +3 -4
  30. package/node_modules/@higgsfield/higgsedit/dist/chunk-QJTILFBS.mjs +335 -0
  31. package/node_modules/@higgsfield/higgsedit/dist/chunk-QQ3GGKDN.mjs +21 -0
  32. package/node_modules/@higgsfield/higgsedit/dist/chunk-TH7TK67K.mjs +23 -0
  33. package/node_modules/@higgsfield/higgsedit/dist/{chunk-SIMO6I3D.mjs → chunk-UDL5AHKO.mjs} +163 -158
  34. package/node_modules/@higgsfield/higgsedit/dist/chunk-UMWOUQN3.mjs +60 -0
  35. package/node_modules/@higgsfield/higgsedit/dist/{chunk-3AIM3THH.mjs → chunk-VLM5EOWJ.mjs} +4 -4
  36. package/node_modules/@higgsfield/higgsedit/dist/chunk-WENFTPXQ.mjs +403 -0
  37. package/node_modules/@higgsfield/higgsedit/dist/chunk-YLVXQIPX.mjs +464 -0
  38. package/node_modules/@higgsfield/higgsedit/dist/editor/.vite/manifest.json +559 -506
  39. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/agent-corner-bottom-q4hZltI-.svg +431 -0
  40. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/agent-corner-top-BJYI-I24.svg +431 -0
  41. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/confirmation-BTnwl3LS.css +1 -0
  42. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/drag-Bt_t4HZO.css +1 -0
  43. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/local-B3OTAV_A.css +1 -0
  44. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/menubar-2Y1Y2XJt.css +1 -0
  45. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/model-DdE4hCgf.css +1 -0
  46. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/{IconText1-CzbCrP7v.css → notifications-B08L1jSe.css} +1 -1
  47. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/{panel-g852pZf_.css → panel-BRN_AbBM.css} +1 -1
  48. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/panel-CYELNqrv.css +1 -0
  49. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/panel-DYLpT6oA.css +1 -0
  50. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/panel-v84HaGTZ.css +1 -0
  51. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconChainLink1-Bxb1Or0F.js +1 -0
  52. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/{IconCheckmark2Medium-daaES9uF.js → IconCheckmark2Medium-hegaz9mQ.js} +1 -1
  53. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/{IconChevronDownSmall-BhTBJk26.js → IconChevronDownSmall-DaruzJwU.js} +1 -1
  54. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconClosedCaptioning-BPqcqKsD.js +1 -0
  55. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/{IconCrossMedium-acfnCXOM.js → IconCrossMedium-BsPFJzc6.js} +1 -1
  56. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconOpenaiFilled-D1fzthmi.js +1 -0
  57. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/{IconPause-pTeVSvUe.js → IconPause-ClNg8pao.js} +1 -1
  58. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/{IconPlayFilled-CwdgIuDG.js → IconPlayFilled-CHb-7GSx.js} +1 -1
  59. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconSparklesSoftFilled-o7o33KRn.js +1 -0
  60. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/ai-composer-B9h-eaki.js +567 -0
  61. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/auto-layout-BO20Tg4B.js +1 -0
  62. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/{button-CjG6GcgF.js → button-Cg0U0zpV.js} +1 -1
  63. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/canvas-Bw4CVzfw.js +1 -0
  64. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/capabilities-BCd4-zPF.js +1 -0
  65. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/commands-QeSqAbCt.js +1 -0
  66. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/components-tXMtIZNL.js +51 -0
  67. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/confirmation-CO2PHR_z.js +1 -0
  68. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/dom-6aoQn29n.js +1 -0
  69. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/drag-Dw8b_vO2.js +1 -0
  70. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/{editing-CjWbiCxv.js → editing-Cy-SaOyB.js} +1 -1
  71. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/edits-CqLBqir0.js +1 -0
  72. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/export-dialog-BjBskOe3.js +2 -0
  73. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/factories-Bw_iQrUL.js +1 -0
  74. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/id3-CSR0NCRI.js +2 -0
  75. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/import-DP49i4ke.js +1 -0
  76. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/import-error-CMz9sLPe.js +1 -0
  77. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/ingest-DsmIc415.js +1 -0
  78. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/jsx-runtime-B5yqYJvp.js +1 -0
  79. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/{media-Bwjxu-0U.js → media-DQw6vU_T.js} +1 -1
  80. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/menubar-D31srALX.js +1 -0
  81. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/meters-D0nZVEJs.js +1 -0
  82. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/mode-DEG6doKF.js +1 -0
  83. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/model-Duf9fszJ.js +2 -0
  84. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/model-DyAkLA69.js +1 -0
  85. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/notifications-DqWZNIrK.js +9 -0
  86. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/palette-HT83gWgL.js +1 -0
  87. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-B5Mvm6dg.js +7 -0
  88. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-BC90wyvd.js +1 -0
  89. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-Bw_ZJ2JI.js +3 -0
  90. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-DNS060Nt.js +3 -0
  91. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-DSgxIrEq.js +2 -0
  92. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-DgBttE5O.js +1 -0
  93. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-assets-_T2bHsHW.js +771 -0
  94. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-inspector-DfHvAt5X.js +2 -0
  95. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-nBZvHlkA.js +1 -0
  96. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-timeline-DsCpJVSt.js +327 -0
  97. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-viewport-CEhZwZ67.js +280 -0
  98. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/projects-2_tW9Do7.js +1 -0
  99. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/react-dom-1uB7Vbbb.js +1 -0
  100. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/schemas-CddYAOcj.js +64 -0
  101. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/session-BpFeKAI2.js +1 -0
  102. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/src-BLG3tYBa.js +2 -0
  103. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/styles-e2n2A_JN.js +284 -0
  104. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/supercomputer-CuV0zYKd.js +24 -0
  105. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/tabs-XeAgs9cs.js +1 -0
  106. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/toggle-DbNEaSIl.js +1 -0
  107. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/transport-C8Ll3qFl.js +69 -0
  108. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/transport-bar-Dv1LPFbu.js +1 -0
  109. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/useOpenInteractionType-HWSfSsp2.js +1 -0
  110. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/useRenderElement-D4SOg3N_.js +1 -0
  111. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/value-EB7YmAdS.js +1 -0
  112. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/writeback-support-fj5rA9k3.js +1 -0
  113. package/node_modules/@higgsfield/higgsedit/dist/editor/editor-B-WAkLt7.js +372 -0
  114. package/node_modules/@higgsfield/higgsedit/dist/higgsedit.mjs +39 -24
  115. package/node_modules/@higgsfield/higgsedit/dist/jsx/hooks.d.ts +26 -0
  116. package/node_modules/@higgsfield/higgsedit/dist/jsx/index.d.ts +17 -0
  117. package/node_modules/@higgsfield/higgsedit/dist/jsx/inspect.d.ts +42 -0
  118. package/node_modules/@higgsfield/higgsedit/dist/jsx/jsx-runtime.d.ts +28 -0
  119. package/node_modules/@higgsfield/higgsedit/dist/jsx/svg.d.ts +9 -0
  120. package/node_modules/@higgsfield/higgsedit/dist/jsx/time.d.ts +6 -0
  121. package/node_modules/@higgsfield/higgsedit/dist/jsx/types.d.ts +420 -0
  122. package/node_modules/@higgsfield/higgsedit/package.json +28 -20
  123. package/package.json +4 -3
  124. package/plugin/.codex-plugin/plugin.json +1 -1
  125. package/plugin/plugin.json +1 -1
  126. package/plugin/skills/video-editing/references/caption-titling.md +1 -1
  127. package/plugin/skills/video-editing/references/local-setup.md +3 -3
  128. package/node_modules/@higgsfield/higgsedit/dist/chunk-C6SASQHE.mjs +0 -424
  129. package/node_modules/@higgsfield/higgsedit/dist/chunk-FZ5U36SQ.mjs +0 -83
  130. package/node_modules/@higgsfield/higgsedit/dist/chunk-QLPCYN6K.mjs +0 -292
  131. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/edit-drag-D2EV5ddd.css +0 -1
  132. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/editor-CuRHT75g.css +0 -1
  133. package/node_modules/@higgsfield/higgsedit/dist/editor/assets/panel-DnuQD7ja.css +0 -1
  134. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/FieldControl-B0fenhBJ.js +0 -2
  135. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconChainLink1-Cwv1X7hi.js +0 -1
  136. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconEyeOpen-BqTT9_VV.js +0 -1
  137. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconEyeSlash-Whv58c1m.js +0 -1
  138. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconPencil-Dr17k_7e.js +0 -1
  139. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconPlay-BroH3ziH.js +0 -1
  140. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconPlusSmall-43T9aE3d.js +0 -1
  141. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconText1-BaP_p9DW.js +0 -1
  142. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/IconTrashCan-DX2w2AIC.js +0 -1
  143. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/ai-composer-C-l0eIdP.js +0 -560
  144. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/captions-Cd-bDG3G.js +0 -1
  145. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/clip-highlight-DpAvcA4x.js +0 -1
  146. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/components-e3ZbUVns.js +0 -1
  147. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/disposables-CwUPjcuA.js +0 -1
  148. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/drag-HLBkto5o.js +0 -1
  149. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/dropdown-BJ04G_X3.js +0 -1
  150. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/edit-drag-Bg6LggKC.js +0 -1
  151. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/edits-a2IixhrN.js +0 -1
  152. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/export-dialog-4I4gqI5V.js +0 -2
  153. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/face-tracker-DzVfjVOO.js +0 -1
  154. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/fit-imported-media-CaCB0x0b.js +0 -1
  155. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/generation-queue-DuL2F4-_.js +0 -1
  156. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/import-error-CMARA0Hy.js +0 -1
  157. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/jsx-runtime-B-hcVAMW.js +0 -1
  158. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/menubar-Bs26OdwP.js +0 -1
  159. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/meters-YEr9OQjq.js +0 -1
  160. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/paints-DS2Msf91.js +0 -67
  161. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/palette-CcS9IcAC.js +0 -1
  162. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-7M3uQokX.js +0 -1
  163. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-BBK1NyG-.js +0 -1
  164. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-CHZTs7By.js +0 -4
  165. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-DaSOa3MP.js +0 -2
  166. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-DlK3RYVo.js +0 -1
  167. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-Dst5OKWu.js +0 -2
  168. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-H_ZoDiKK.js +0 -2
  169. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-Rn9Z7Eek.js +0 -3
  170. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-assets-FAghGFG3.js +0 -678
  171. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-inspector-DEqULBNF.js +0 -260
  172. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-timeline-0GYNz1uc.js +0 -333
  173. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/panel-viewport-DOWjJi5-.js +0 -317
  174. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/projects-BBJc7h5_.js +0 -2
  175. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/session-B9sZaFKC.js +0 -1
  176. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/supercomputer-CX-LCL6Y.js +0 -24
  177. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/tabs-CvKQ-eas.js +0 -1
  178. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/toggle-CrzrwiDZ.js +0 -1
  179. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/transport-BgRfk-Qq.js +0 -69
  180. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/transport-bar-C9nqAfE2.js +0 -1
  181. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/typography-C5-w9LOu-kD3uLKkf.js +0 -1
  182. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/useOpenInteractionType-DbrQ6Ehu.js +0 -1
  183. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/useRenderElement-bbxXdYq0.js +0 -1
  184. package/node_modules/@higgsfield/higgsedit/dist/editor/chunks/writeback-support-BZfNpkmB.js +0 -1
  185. package/node_modules/@higgsfield/higgsedit/dist/editor/editor-Csn2_T_e.js +0 -293
  186. package/node_modules/@higgsfield/higgsedit/dist/export-settings.mjs +0 -75
  187. package/node_modules/@higgsfield/higgsedit/dist/history.mjs +0 -295
  188. package/node_modules/@higgsfield/higgsedit/dist/media-upload.mjs +0 -381
  189. package/node_modules/@higgsfield/higgsedit/dist/proxy.mjs +0 -170
@@ -0,0 +1,717 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __higgseditRequire } from "node:module";
3
+ import { fileURLToPath as __higgseditPath } from "node:url";
4
+ const require = __higgseditRequire(import.meta.url);
5
+ const __filename = __higgseditPath(import.meta.url);
6
+ const __dirname = __filename.slice(0, __filename.lastIndexOf("/"));
7
+ import {
8
+ SOURCE_FILE,
9
+ SyncError,
10
+ bundlePackages,
11
+ compileFile,
12
+ measureSync
13
+ } from "./chunk-UDL5AHKO.mjs";
14
+ import {
15
+ fontFiles,
16
+ inside,
17
+ readSources
18
+ } from "./chunk-LTKMGZ6T.mjs";
19
+ import {
20
+ FONT_CATEGORIES,
21
+ FONT_LIMIT,
22
+ cachedFonts,
23
+ listFonts
24
+ } from "./chunk-NUXTKQNM.mjs";
25
+ import {
26
+ GoogleFontsUnavailable,
27
+ googleFace,
28
+ googleFontsDir,
29
+ googleFontsOff
30
+ } from "./chunk-2VKQHJMM.mjs";
31
+
32
+ // src/assets.ts
33
+ import { join } from "node:path";
34
+ var PACKAGED = true;
35
+ function packagedAsset(name) {
36
+ return globalThis.higgseditAssets?.[name] ?? join(import.meta.dirname, name);
37
+ }
38
+
39
+ // src/media-upload.ts
40
+ import { randomUUID } from "node:crypto";
41
+ import {
42
+ constants,
43
+ linkSync,
44
+ lstatSync,
45
+ mkdirSync,
46
+ mkdtempSync,
47
+ realpathSync,
48
+ readdirSync,
49
+ renameSync,
50
+ rmdirSync,
51
+ statSync
52
+ } from "node:fs";
53
+ import { open, rm } from "node:fs/promises";
54
+ import { extname, join as join2 } from "node:path";
55
+ var json = (res, status, body) => {
56
+ res.statusCode = status;
57
+ res.setHeader("content-type", "application/json");
58
+ res.end(JSON.stringify(body));
59
+ };
60
+ var MEDIA_UPLOAD_PART_BYTES = 2 << 20;
61
+ var MEDIA_UPLOAD_TEMP_PREFIX = ".higgsedit-upload-";
62
+ function isPrivateMediaUploadPath(path) {
63
+ return path.split(/[/\\]/).some((part) => part.toUpperCase().startsWith(MEDIA_UPLOAD_TEMP_PREFIX.toUpperCase()));
64
+ }
65
+ var defaults = {
66
+ maxBytes: 8 * 1024 ** 3,
67
+ idleMs: 6e4,
68
+ totalMs: 30 * 6e4,
69
+ maxConcurrent: 4
70
+ };
71
+ var envKeys = {
72
+ maxBytes: "HIGGSEDIT_MEDIA_MAX_BYTES",
73
+ idleMs: "HIGGSEDIT_MEDIA_IDLE_MS",
74
+ totalMs: "HIGGSEDIT_MEDIA_TOTAL_MS",
75
+ maxConcurrent: "HIGGSEDIT_MEDIA_MAX_CONCURRENT"
76
+ };
77
+ var UploadError = class extends Error {
78
+ constructor(message, status) {
79
+ super(message);
80
+ this.status = status;
81
+ }
82
+ status;
83
+ };
84
+ var MediaUploads = class {
85
+ active = /* @__PURE__ */ new Map();
86
+ root;
87
+ rootIdentity;
88
+ closed = false;
89
+ limits;
90
+ constructor(dir, limits = {}) {
91
+ this.root = realpathSync(dir);
92
+ this.rootIdentity = lstatSync(this.root);
93
+ this.limits = { ...defaults };
94
+ for (const key of Object.keys(defaults)) {
95
+ const value = limits[key] ?? (process.env[envKeys[key]] ? Number(process.env[envKeys[key]]) : defaults[key]);
96
+ if (!Number.isSafeInteger(value) || value <= 0)
97
+ throw new Error(`${envKeys[key]} must be a positive safe integer`);
98
+ this.limits[key] = value;
99
+ }
100
+ }
101
+ get busy() {
102
+ return this.active.size > 0;
103
+ }
104
+ async close() {
105
+ this.closed = true;
106
+ await Promise.all(
107
+ [...this.active.values()].map((u) => this.dispose(u, new UploadError("editor closed", 503)))
108
+ );
109
+ }
110
+ checkMedia() {
111
+ const root = lstatSync(this.root);
112
+ if (root.isSymbolicLink() || root.dev !== this.rootIdentity.dev || root.ino !== this.rootIdentity.ino)
113
+ throw new UploadError("project directory changed during upload", 400);
114
+ const media = join2(this.root, "media");
115
+ mkdirSync(media, { recursive: true });
116
+ const st = lstatSync(media);
117
+ if (!st.isDirectory() || st.isSymbolicLink() || realpathSync(media) !== media)
118
+ throw new UploadError("media must be a real project directory, not a symlink", 400);
119
+ return media;
120
+ }
121
+ async begin(name) {
122
+ if (!name || name.startsWith(".") || /[/\\]/.test(name) || [...name].some((c) => c.charCodeAt(0) < 32 || c.charCodeAt(0) === 127) || Buffer.byteLength(name) > 240)
123
+ throw new UploadError("invalid media filename", 400);
124
+ if (this.closed) throw new UploadError("editor closed", 503);
125
+ if (this.active.size >= this.limits.maxConcurrent)
126
+ throw new UploadError("too many active media uploads; try again after one finishes", 429);
127
+ const directory = lstatSync(this.checkMedia());
128
+ const temp = mkdtempSync(join2(this.checkMedia(), MEDIA_UPLOAD_TEMP_PREFIX));
129
+ const u = {
130
+ id: randomUUID(),
131
+ name,
132
+ temp,
133
+ directory,
134
+ staging: lstatSync(temp),
135
+ bytes: 0,
136
+ busy: true,
137
+ abort: new AbortController()
138
+ };
139
+ this.active.set(u.id, u);
140
+ try {
141
+ u.file = await open(
142
+ join2(temp, "body"),
143
+ constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY | constants.O_NOFOLLOW,
144
+ 384
145
+ );
146
+ if (u.abort.signal.aborted) {
147
+ await u.file.close();
148
+ u.abort.signal.throwIfAborted();
149
+ }
150
+ u.total = setTimeout(() => {
151
+ void this.dispose(u, new UploadError("media upload exceeded its total time limit", 408));
152
+ }, this.limits.totalMs);
153
+ u.total.unref();
154
+ u.busy = false;
155
+ this.touch(u);
156
+ return u;
157
+ } catch (error) {
158
+ await this.dispose(u, error);
159
+ throw error;
160
+ }
161
+ }
162
+ touch(u) {
163
+ clearTimeout(u.idle);
164
+ u.idle = setTimeout(() => {
165
+ void this.dispose(u, new UploadError("media upload stalled", 408));
166
+ }, this.limits.idleMs);
167
+ u.idle.unref();
168
+ }
169
+ dispose(u, reason = new UploadError("media upload cancelled", 499)) {
170
+ if (u.cleanup) return u.cleanup;
171
+ u.abort.abort(reason);
172
+ clearTimeout(u.idle);
173
+ clearTimeout(u.total);
174
+ u.cleanup = (async () => {
175
+ let failure;
176
+ try {
177
+ await u.file?.close();
178
+ } catch (error) {
179
+ failure = error;
180
+ }
181
+ try {
182
+ let current;
183
+ try {
184
+ current = lstatSync(u.temp);
185
+ } catch (error) {
186
+ if (error.code !== "ENOENT") throw error;
187
+ }
188
+ if (current?.isDirectory() && !current.isSymbolicLink() && current.dev === u.staging.dev && current.ino === u.staging.ino)
189
+ await rm(u.temp, { recursive: true, force: true });
190
+ } catch (error) {
191
+ failure ??= error;
192
+ }
193
+ this.active.delete(u.id);
194
+ if (failure) throw failure;
195
+ })();
196
+ void u.cleanup.catch(() => {
197
+ });
198
+ return u.cleanup;
199
+ }
200
+ declared(req, maximum) {
201
+ const length = req.headers["content-length"];
202
+ if (length !== void 0 && (!/^\d+$/.test(length) || !Number.isSafeInteger(Number(length)) || Number(length) > maximum)) {
203
+ throw new UploadError(`media upload exceeds the ${maximum} byte limit`, 413);
204
+ }
205
+ }
206
+ async append(u, req, maxPart) {
207
+ this.declared(req, Math.min(maxPart, this.limits.maxBytes - u.bytes));
208
+ let partBytes = 0;
209
+ const signal = u.abort.signal;
210
+ while (true) {
211
+ signal.throwIfAborted();
212
+ if (req.aborted || req.destroyed && !req.complete)
213
+ throw new UploadError("media upload disconnected", 499);
214
+ const bytes = req.read();
215
+ if (bytes === null) {
216
+ if (req.readableEnded) break;
217
+ await new Promise((resolve, reject) => {
218
+ const clean = () => {
219
+ req.off("readable", ready);
220
+ req.off("end", ready);
221
+ req.off("error", fail);
222
+ req.off("aborted", disconnected);
223
+ signal.removeEventListener("abort", aborted);
224
+ };
225
+ const ready = () => {
226
+ clean();
227
+ resolve();
228
+ };
229
+ const fail = (error) => {
230
+ clean();
231
+ reject(error);
232
+ };
233
+ const disconnected = () => fail(new UploadError("media upload disconnected", 499));
234
+ const aborted = () => fail(signal.reason);
235
+ req.once("readable", ready);
236
+ req.once("end", ready);
237
+ req.once("error", fail);
238
+ req.once("aborted", disconnected);
239
+ signal.addEventListener("abort", aborted, { once: true });
240
+ if (signal.aborted) aborted();
241
+ });
242
+ continue;
243
+ }
244
+ partBytes += bytes.byteLength;
245
+ if (partBytes > maxPart || u.bytes + bytes.byteLength > this.limits.maxBytes)
246
+ throw new UploadError(`media upload exceeds the ${this.limits.maxBytes} byte limit`, 413);
247
+ this.touch(u);
248
+ for (let offset = 0; offset < bytes.byteLength; ) {
249
+ signal.throwIfAborted();
250
+ const { bytesWritten } = await u.file.write(bytes, offset, bytes.byteLength - offset);
251
+ if (!bytesWritten) throw new Error("could not write media upload");
252
+ offset += bytesWritten;
253
+ }
254
+ u.bytes += bytes.byteLength;
255
+ this.touch(u);
256
+ }
257
+ signal.throwIfAborted();
258
+ }
259
+ async publish(u) {
260
+ await u.file.sync();
261
+ u.abort.signal.throwIfAborted();
262
+ const written = await u.file.stat();
263
+ u.abort.signal.throwIfAborted();
264
+ const media = this.checkMedia();
265
+ const directory = lstatSync(media);
266
+ const staging = lstatSync(u.temp);
267
+ const current = lstatSync(join2(u.temp, "body"));
268
+ if (directory.dev !== u.directory.dev || directory.ino !== u.directory.ino || staging.isSymbolicLink() || staging.dev !== u.staging.dev || staging.ino !== u.staging.ino || !current.isFile() || current.isSymbolicLink() || current.dev !== written.dev || current.ino !== written.ino || current.size !== u.bytes)
269
+ throw new UploadError("media upload destination changed", 409);
270
+ const ext = extname(u.name);
271
+ const stem = u.name.slice(0, u.name.length - ext.length);
272
+ for (let suffix = 1; suffix <= 1e4; suffix++) {
273
+ const name = suffix === 1 ? u.name : `${stem}-${suffix}${ext}`;
274
+ try {
275
+ linkSync(join2(u.temp, "body"), join2(media, name));
276
+ } catch (error) {
277
+ const code = error.code;
278
+ if (code === "EEXIST") continue;
279
+ if (!["ENOTSUP", "EOPNOTSUPP", "EPERM", "EXDEV", "ENOSYS"].includes(code ?? ""))
280
+ throw error;
281
+ const reserved = mkdtempSync(join2(media, "import-"));
282
+ try {
283
+ renameSync(join2(u.temp, "body"), join2(reserved, u.name));
284
+ } catch (failure) {
285
+ try {
286
+ rmdirSync(reserved);
287
+ } catch {
288
+ }
289
+ throw failure;
290
+ }
291
+ return { src: `./media/${reserved.slice(media.length + 1)}/${u.name}`, byteSize: u.bytes };
292
+ }
293
+ return { src: `./media/${name}`, byteSize: u.bytes };
294
+ }
295
+ throw new UploadError("too many media files with this name", 409);
296
+ }
297
+ async handle(req, res, url) {
298
+ if (isPrivateMediaUploadPath(decodeURIComponent(url.pathname))) {
299
+ json(res, 403, { error: "private upload" });
300
+ return true;
301
+ }
302
+ if (url.pathname === "/api/media/capabilities" && req.method === "GET") {
303
+ json(res, 200, {
304
+ streaming: true,
305
+ version: 1,
306
+ maxBytes: this.limits.maxBytes,
307
+ partBytes: MEDIA_UPLOAD_PART_BYTES,
308
+ maxConcurrent: this.limits.maxConcurrent
309
+ });
310
+ return true;
311
+ }
312
+ const direct = (url.pathname === "/api/media" || url.pathname === "/api/media/stream") && req.method === "POST";
313
+ const begin = url.pathname === "/api/media/uploads" && req.method === "POST";
314
+ const part = /^\/api\/media\/uploads\/([a-f0-9-]{36})$/.exec(url.pathname);
315
+ if (!direct && !begin && !part) return false;
316
+ let u;
317
+ let owns = false;
318
+ const disconnected = () => {
319
+ if (u && !res.writableFinished)
320
+ void this.dispose(u, new UploadError("media upload disconnected", 499));
321
+ };
322
+ res.once("close", disconnected);
323
+ try {
324
+ if (direct || begin) {
325
+ this.declared(req, direct ? this.limits.maxBytes : 0);
326
+ if (begin && req.headers["transfer-encoding"])
327
+ throw new UploadError("upload session creation takes no body", 400);
328
+ u = await this.begin(url.searchParams.get("name") ?? "");
329
+ if (res.destroyed) throw new UploadError("media upload disconnected", 499);
330
+ if (begin) {
331
+ json(res, 201, {
332
+ id: u.id,
333
+ maxBytes: this.limits.maxBytes,
334
+ partBytes: MEDIA_UPLOAD_PART_BYTES
335
+ });
336
+ return true;
337
+ }
338
+ } else {
339
+ u = this.active.get(part[1]);
340
+ if (req.method !== "PUT") {
341
+ this.declared(req, 0);
342
+ if (req.headers["transfer-encoding"])
343
+ throw new UploadError("upload finalization and cancellation take no body", 400);
344
+ }
345
+ if (!u) throw new UploadError("media upload not found or expired", 404);
346
+ if (req.method === "DELETE") {
347
+ await this.dispose(u);
348
+ json(res, 200, { ok: true });
349
+ return true;
350
+ }
351
+ if (u.busy) throw new UploadError("media upload already has a request in progress", 409);
352
+ if (req.method !== "PUT" && req.method !== "POST")
353
+ throw new UploadError("unsupported upload method", 405);
354
+ if (req.method === "PUT" && (!/^\d+$/.test(url.searchParams.get("offset") ?? "") || Number(url.searchParams.get("offset")) !== u.bytes))
355
+ throw new UploadError("media upload offset does not match", 409);
356
+ }
357
+ u.busy = true;
358
+ owns = true;
359
+ if (direct || req.method === "PUT")
360
+ await this.append(u, req, direct ? this.limits.maxBytes : MEDIA_UPLOAD_PART_BYTES);
361
+ if (direct || req.method === "POST") {
362
+ const result = await this.publish(u);
363
+ await this.dispose(u);
364
+ json(res, 200, result);
365
+ } else {
366
+ u.busy = false;
367
+ this.touch(u);
368
+ json(res, 200, { offset: u.bytes });
369
+ }
370
+ } catch (error) {
371
+ if (u && (owns || direct || begin)) await this.dispose(u, error);
372
+ if (!res.destroyed) {
373
+ if (!req.complete) {
374
+ res.setHeader("connection", "close");
375
+ res.once("finish", () => req.destroy());
376
+ }
377
+ json(res, error instanceof UploadError ? error.status : 500, {
378
+ error: error instanceof Error ? error.message : "media upload failed"
379
+ });
380
+ }
381
+ } finally {
382
+ res.off("close", disconnected);
383
+ }
384
+ return true;
385
+ }
386
+ };
387
+ function listMediaFiles(media) {
388
+ let entries;
389
+ try {
390
+ entries = readdirSync(media, { withFileTypes: true });
391
+ } catch (error) {
392
+ if (error.code === "ENOENT") return [];
393
+ throw error;
394
+ }
395
+ const files = [];
396
+ for (const entry of entries) {
397
+ if (entry.isFile() && !entry.name.startsWith("."))
398
+ files.push({
399
+ src: `./media/${entry.name}`,
400
+ byteSize: statSync(join2(media, entry.name)).size
401
+ });
402
+ else if (entry.isDirectory() && /^import-[a-zA-Z0-9]{6}$/.test(entry.name)) {
403
+ for (const child of readdirSync(join2(media, entry.name), { withFileTypes: true })) {
404
+ if (child.isFile() && !child.name.startsWith("."))
405
+ files.push({
406
+ src: `./media/${entry.name}/${child.name}`,
407
+ byteSize: statSync(join2(media, entry.name, child.name)).size
408
+ });
409
+ }
410
+ }
411
+ }
412
+ return files.toSorted((a, b) => a.src.localeCompare(b.src));
413
+ }
414
+
415
+ // src/server.ts
416
+ import { createHash } from "node:crypto";
417
+ import { createReadStream, readFileSync, statSync as statSync2 } from "node:fs";
418
+ import { createServer } from "node:http";
419
+ import { extname as extname2 } from "node:path";
420
+
421
+ // src/bundle.ts
422
+ import { readFile } from "node:fs/promises";
423
+ import { join as join3 } from "node:path";
424
+ var PAGE_SRC = join3(import.meta.dirname, "../../../packages/editor-document/src");
425
+ var cache = /* @__PURE__ */ new Map();
426
+ function pageBundle(entry) {
427
+ let bundle = cache.get(entry);
428
+ if (!bundle) {
429
+ if (PACKAGED) {
430
+ bundle = readFile(packagedAsset("capture-page.js"), "utf8");
431
+ cache.set(entry, bundle);
432
+ return bundle;
433
+ }
434
+ bundle = import("esbuild").then(({ build }) => build({
435
+ entryPoints: [join3(PAGE_SRC, `${entry}.ts`)],
436
+ bundle: true,
437
+ write: false,
438
+ format: "esm",
439
+ platform: "browser",
440
+ target: "chrome120",
441
+ minify: false,
442
+ sourcemap: false,
443
+ logLevel: "silent",
444
+ define: { "process.env.NODE_ENV": '"production"', "process.env.BABEL_TYPES_8_BREAKING": "false" },
445
+ alias: { assert: join3(PAGE_SRC, "shims/assert.cjs") },
446
+ banner: { js: "globalThis.process ??= { env: {}, cwd: () => '/', platform: 'browser' };" }
447
+ })).then((r) => r.outputFiles[0].text);
448
+ cache.set(entry, bundle);
449
+ }
450
+ return bundle;
451
+ }
452
+
453
+ // src/fonts/route.ts
454
+ import { relative, sep } from "node:path";
455
+ var FILE = "/__higgsedit/fonts/file/";
456
+ var MAX_LIMIT = 200;
457
+ var count = (raw, fallback, max) => {
458
+ const n = Number.parseInt(raw ?? "", 10);
459
+ return Number.isFinite(n) ? Math.min(Math.max(n, 0), max) : fallback;
460
+ };
461
+ function json2(res, status, body) {
462
+ res.statusCode = status;
463
+ res.setHeader("content-type", "application/json");
464
+ res.end(JSON.stringify(body));
465
+ }
466
+ async function fontsRoute(req, res, path, url, sendFile2) {
467
+ if (path === "/__higgsedit/fonts/list") {
468
+ await listRoute(res, url);
469
+ return true;
470
+ }
471
+ if (path === "/__higgsedit/fonts/google") {
472
+ const family = url.searchParams.get("family") ?? "";
473
+ const weight = Number(url.searchParams.get("weight") ?? 400);
474
+ const style = url.searchParams.get("style") === "italic" ? "italic" : "normal";
475
+ try {
476
+ const face = family ? await googleFace(family, Number.isFinite(weight) ? weight : 400, style) : null;
477
+ if (!face) {
478
+ json2(res, 200, null);
479
+ return true;
480
+ }
481
+ const file = relative(googleFontsDir(), face.file).split(sep).map(encodeURIComponent).join("/");
482
+ const answer = { family: face.family, weight: face.weight, style: face.style, url: `${FILE}${file}` };
483
+ json2(res, 200, answer);
484
+ } catch (error) {
485
+ if (error instanceof GoogleFontsUnavailable) json2(res, 200, { unavailable: error.message });
486
+ else json2(res, 503, { error: error.message });
487
+ }
488
+ return true;
489
+ }
490
+ if (path.startsWith(FILE)) {
491
+ const file = inside(googleFontsDir(), path.slice(FILE.length));
492
+ if (!file) {
493
+ res.statusCode = 403;
494
+ res.end("outside the font cache");
495
+ return true;
496
+ }
497
+ sendFile2(req, res, file);
498
+ return true;
499
+ }
500
+ return false;
501
+ }
502
+ async function listRoute(res, url) {
503
+ const p = url.searchParams;
504
+ const category = p.get("category") || void 0;
505
+ if (category && !FONT_CATEGORIES.includes(category)) {
506
+ json2(res, 400, { error: `unknown category ${category}: ${FONT_CATEGORIES.join(", ")}` });
507
+ return;
508
+ }
509
+ const query = {
510
+ family: p.get("family") ?? "",
511
+ ...category ? { category } : {},
512
+ cached: p.get("cached") === "1" || p.get("cached") === "true",
513
+ limit: Math.max(1, count(p.get("limit"), FONT_LIMIT, MAX_LIMIT)),
514
+ offset: count(p.get("offset"), 0, Number.MAX_SAFE_INTEGER)
515
+ };
516
+ try {
517
+ const list = await listFonts(query);
518
+ const families = list.families.map((f) => ({ family: f.family, category: f.category, popularity: f.popularity, weights: f.weights, italics: f.italics, cached: f.cached }));
519
+ json2(res, 200, { families, total: list.total, offset: query.offset, catalogue: list.catalogue });
520
+ } catch (error) {
521
+ if (!(error instanceof GoogleFontsUnavailable)) throw error;
522
+ const cached = googleFontsOff() ? { families: [], total: 0 } : await cachedFonts(query);
523
+ json2(res, 200, { ...cached, offset: query.offset, unavailable: error.message });
524
+ }
525
+ }
526
+
527
+ // src/server.ts
528
+ var TYPES = {
529
+ ".html": "text/html; charset=utf-8",
530
+ ".js": "text/javascript; charset=utf-8",
531
+ ".css": "text/css; charset=utf-8",
532
+ ".woff2": "font/woff2",
533
+ ".woff": "font/woff",
534
+ ".ttf": "font/ttf",
535
+ ".webp": "image/webp",
536
+ ".gif": "image/gif",
537
+ ".json": "application/json",
538
+ ".srt": "application/x-subrip; charset=utf-8",
539
+ ".vtt": "text/vtt; charset=utf-8",
540
+ ".mp4": "video/mp4",
541
+ ".mov": "video/quicktime",
542
+ ".webm": "video/webm",
543
+ ".png": "image/png",
544
+ ".jpg": "image/jpeg",
545
+ ".jpeg": "image/jpeg",
546
+ ".svg": "image/svg+xml",
547
+ ".tsx": "text/plain; charset=utf-8",
548
+ ".ts": "text/plain; charset=utf-8"
549
+ };
550
+ function sendFile(req, res, file) {
551
+ let size;
552
+ let etag;
553
+ let modified;
554
+ try {
555
+ const st = statSync2(file, { bigint: true });
556
+ if (!st.isFile()) throw new Error("not a file");
557
+ size = Number(st.size);
558
+ etag = `"${createHash("sha256").update(`${st.dev}:${st.ino}:${st.size}:${st.mtimeNs}:${st.ctimeNs}`).digest("hex")}"`;
559
+ modified = Math.floor(Number(st.mtimeNs > st.ctimeNs ? st.mtimeNs : st.ctimeNs) / 1e9) * 1e3;
560
+ } catch {
561
+ res.statusCode = 404;
562
+ res.end("not found");
563
+ return;
564
+ }
565
+ res.setHeader("content-type", TYPES[extname2(file).toLowerCase()] ?? "application/octet-stream");
566
+ res.setHeader("accept-ranges", "bytes");
567
+ res.setHeader("cache-control", "no-cache");
568
+ res.setHeader("etag", etag);
569
+ res.setHeader("last-modified", new Date(modified).toUTCString());
570
+ const readable = req.method === "GET" || req.method === "HEAD";
571
+ const noneMatch = req.headers["if-none-match"];
572
+ const unmodified = noneMatch !== void 0 ? noneMatch.split(",").some((value) => value.trim() === "*" || value.trim().replace(/^W\//, "") === etag) : Date.parse(req.headers["if-modified-since"] ?? "") >= modified;
573
+ if (readable && unmodified) {
574
+ res.statusCode = 304;
575
+ res.end();
576
+ return;
577
+ }
578
+ const ifRange = req.headers["if-range"];
579
+ const sameRange = !ifRange || ifRange === etag || modified <= Date.now() - 6e4 && typeof ifRange === "string" && Date.parse(ifRange) === modified;
580
+ const range = req.method === "GET" && sameRange ? /^bytes=(\d*)-(\d*)$/.exec(req.headers.range ?? "") : null;
581
+ if (range) {
582
+ const start = range[1] ? Number(range[1]) : Math.max(0, size - Number(range[2]));
583
+ const end = range[1] && range[2] ? Math.min(Number(range[2]), size - 1) : size - 1;
584
+ if (!range[1] && !Number(range[2]) || !Number.isSafeInteger(start) || !Number.isSafeInteger(end) || start > end || start >= size) {
585
+ res.statusCode = 416;
586
+ res.setHeader("content-range", `bytes */${size}`);
587
+ res.end();
588
+ return;
589
+ }
590
+ res.statusCode = 206;
591
+ res.setHeader("content-range", `bytes ${start}-${end}/${size}`);
592
+ res.setHeader("content-length", end - start + 1);
593
+ stream(file, res, { start, end });
594
+ return;
595
+ }
596
+ res.setHeader("content-length", size);
597
+ if (req.method === "HEAD") {
598
+ res.end();
599
+ return;
600
+ }
601
+ stream(file, res);
602
+ }
603
+ function stream(file, res, range) {
604
+ if (file.startsWith("/$bunfs/")) {
605
+ const bytes = readFileSync(file);
606
+ res.end(range ? bytes.subarray(range.start, range.end + 1) : bytes);
607
+ return;
608
+ }
609
+ createReadStream(file, range).on("error", () => res.destroy()).pipe(res);
610
+ }
611
+ var json3 = (res, status, body) => {
612
+ res.statusCode = status;
613
+ res.setHeader("content-type", "application/json");
614
+ res.end(JSON.stringify(body));
615
+ };
616
+ function readBody(req) {
617
+ return new Promise((resolve, reject) => {
618
+ const chunks = [];
619
+ req.on("data", (c) => chunks.push(c));
620
+ req.on("end", () => resolve(Buffer.concat(chunks)));
621
+ req.on("error", reject);
622
+ });
623
+ }
624
+ var CAPTURE_HTML = `<!doctype html><meta charset="utf-8"><title>higgsedit capture</title><script type="module" src="/__higgsedit/capture-page.js"></script>`;
625
+ async function startServer(dir, handlers = [], port = 0) {
626
+ const compiled = /* @__PURE__ */ new Map();
627
+ const compileSources = (files) => {
628
+ const modules = {};
629
+ try {
630
+ for (const [file, code] of Object.entries(files)) {
631
+ if (!SOURCE_FILE.test(file) || file.endsWith(".d.ts")) continue;
632
+ let hit = compiled.get(file);
633
+ if (hit?.code !== code) compiled.set(file, hit = { code, out: compileFile(file, code, { sourceMaps: false }) });
634
+ modules[file] = hit.out;
635
+ }
636
+ } catch (error) {
637
+ return { error: error.message };
638
+ }
639
+ return { modules };
640
+ };
641
+ const server = createServer((req, res) => {
642
+ const url = new URL(req.url ?? "/", "http://localhost");
643
+ void (async () => {
644
+ for (const handler of handlers) if (await handler(req, res, url)) return;
645
+ const path = decodeURIComponent(url.pathname);
646
+ if (path === "/__higgsedit/capture.html") {
647
+ res.setHeader("content-type", TYPES[".html"]);
648
+ res.end(CAPTURE_HTML);
649
+ return;
650
+ }
651
+ if (path === "/__higgsedit/capture-page.js") {
652
+ res.setHeader("content-type", TYPES[".js"]);
653
+ res.end(await pageBundle("capture-page"));
654
+ return;
655
+ }
656
+ if (path.startsWith("/__higgsedit/fonts/") && await fontsRoute(req, res, path, url, sendFile)) return;
657
+ if (path === "/__higgsedit/sync") {
658
+ try {
659
+ json3(res, 200, await measureSync(dir, url.searchParams.get("src") ?? "", url.searchParams.get("target") ?? ""));
660
+ } catch (error) {
661
+ if (!(error instanceof SyncError)) throw error;
662
+ json3(res, 422, { error: error.message, kind: error.kind });
663
+ }
664
+ return;
665
+ }
666
+ if (path === "/api/files") {
667
+ const files = readSources(dir);
668
+ json3(res, 200, { files, ...compileSources(files), fonts: fontFiles(dir), packages: (await bundlePackages(dir)).code });
669
+ return;
670
+ }
671
+ if (path.startsWith("/project/")) {
672
+ if (isPrivateMediaUploadPath(path)) {
673
+ res.statusCode = 403;
674
+ res.end("private upload");
675
+ return;
676
+ }
677
+ const file = inside(dir, path.slice("/project/".length));
678
+ if (!file) {
679
+ res.statusCode = 403;
680
+ res.end("outside the project");
681
+ return;
682
+ }
683
+ sendFile(req, res, file);
684
+ return;
685
+ }
686
+ res.statusCode = 404;
687
+ res.end("not found");
688
+ })().catch((error) => {
689
+ if (!res.headersSent) json3(res, 500, { error: error instanceof Error ? error.message : String(error) });
690
+ else res.destroy();
691
+ });
692
+ });
693
+ await new Promise((resolve) => server.listen(port, "127.0.0.1", resolve));
694
+ const address = server.address();
695
+ const origin = `http://127.0.0.1:${typeof address === "object" && address ? address.port : port}`;
696
+ return {
697
+ server,
698
+ origin,
699
+ close: () => new Promise((resolve) => {
700
+ server.closeAllConnections();
701
+ server.close(() => resolve());
702
+ })
703
+ };
704
+ }
705
+
706
+ export {
707
+ PACKAGED,
708
+ packagedAsset,
709
+ pageBundle,
710
+ MEDIA_UPLOAD_TEMP_PREFIX,
711
+ MediaUploads,
712
+ listMediaFiles,
713
+ sendFile,
714
+ json3 as json,
715
+ readBody,
716
+ startServer
717
+ };