fundus 0.5.0 → 0.6.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 (201) hide show
  1. package/README.md +132 -130
  2. package/build/client/_app/immutable/assets/2.CtqoikFs.css +1 -0
  3. package/build/client/_app/immutable/assets/2.CtqoikFs.css.br +0 -0
  4. package/build/client/_app/immutable/assets/2.CtqoikFs.css.gz +0 -0
  5. package/build/client/_app/immutable/assets/LibraryContextMenu.CVIa_uFP.css +1 -0
  6. package/build/client/_app/immutable/assets/LibraryContextMenu.CVIa_uFP.css.br +0 -0
  7. package/build/client/_app/immutable/assets/LibraryContextMenu.CVIa_uFP.css.gz +0 -0
  8. package/build/client/_app/immutable/chunks/{CN-G-m-B.js → BT3jFrxa.js} +1 -1
  9. package/build/client/_app/immutable/chunks/BT3jFrxa.js.br +1 -0
  10. package/build/client/_app/immutable/chunks/BT3jFrxa.js.gz +0 -0
  11. package/build/client/_app/immutable/chunks/CPFeEkfP.js +108 -0
  12. package/build/client/_app/immutable/chunks/CPFeEkfP.js.br +0 -0
  13. package/build/client/_app/immutable/chunks/CPFeEkfP.js.gz +0 -0
  14. package/build/client/_app/immutable/chunks/CQrHfI-c.js +1 -0
  15. package/build/client/_app/immutable/chunks/CQrHfI-c.js.br +0 -0
  16. package/build/client/_app/immutable/chunks/CQrHfI-c.js.gz +0 -0
  17. package/build/client/_app/immutable/chunks/D0BLX4Qd.js +1 -0
  18. package/build/client/_app/immutable/chunks/D0BLX4Qd.js.br +0 -0
  19. package/build/client/_app/immutable/chunks/D0BLX4Qd.js.gz +0 -0
  20. package/build/client/_app/immutable/chunks/D24lHNM9.js +1 -0
  21. package/build/client/_app/immutable/chunks/D24lHNM9.js.br +0 -0
  22. package/build/client/_app/immutable/chunks/D24lHNM9.js.gz +0 -0
  23. package/build/client/_app/immutable/entry/{app.fVDDVV_y.js → app.DmVWkUml.js} +2 -2
  24. package/build/client/_app/immutable/entry/app.DmVWkUml.js.br +0 -0
  25. package/build/client/_app/immutable/entry/app.DmVWkUml.js.gz +0 -0
  26. package/build/client/_app/immutable/entry/start.Dsf5wSaR.js +1 -0
  27. package/build/client/_app/immutable/entry/start.Dsf5wSaR.js.br +0 -0
  28. package/build/client/_app/immutable/entry/start.Dsf5wSaR.js.gz +0 -0
  29. package/build/client/_app/immutable/nodes/0.l-jE2v4o.js +2 -0
  30. package/build/client/_app/immutable/nodes/0.l-jE2v4o.js.br +0 -0
  31. package/build/client/_app/immutable/nodes/0.l-jE2v4o.js.gz +0 -0
  32. package/build/client/_app/immutable/nodes/{1.DEw3d5yL.js → 1.CRPVOtEh.js} +1 -1
  33. package/build/client/_app/immutable/nodes/1.CRPVOtEh.js.br +3 -0
  34. package/build/client/_app/immutable/nodes/1.CRPVOtEh.js.gz +0 -0
  35. package/build/client/_app/immutable/nodes/2.8Si6qHSH.js +3 -0
  36. package/build/client/_app/immutable/nodes/2.8Si6qHSH.js.br +0 -0
  37. package/build/client/_app/immutable/nodes/2.8Si6qHSH.js.gz +0 -0
  38. package/build/client/_app/immutable/nodes/3.CdI42Umt.js +1 -0
  39. package/build/client/_app/immutable/nodes/3.CdI42Umt.js.br +0 -0
  40. package/build/client/_app/immutable/nodes/3.CdI42Umt.js.gz +0 -0
  41. package/build/client/_app/immutable/nodes/4.mMkL80q1.js +2 -0
  42. package/build/client/_app/immutable/nodes/4.mMkL80q1.js.br +0 -0
  43. package/build/client/_app/immutable/nodes/4.mMkL80q1.js.gz +0 -0
  44. package/build/client/_app/version.json +1 -1
  45. package/build/client/_app/version.json.br +0 -0
  46. package/build/client/_app/version.json.gz +0 -0
  47. package/build/handler.js +7 -7
  48. package/build/index.js +7 -7
  49. package/build/server/chunks/chunks/{context.js-bXe5hzjI.js → context.js-FvYkJDOy.js} +15 -7
  50. package/build/server/chunks/chunks/context.js-FvYkJDOy.js.map +1 -0
  51. package/build/server/chunks/chunks/{contract.js-sHny3b-s.js → contract.js-DGMufT2e.js} +191 -178
  52. package/build/server/chunks/chunks/contract.js-DGMufT2e.js.map +1 -0
  53. package/build/server/chunks/chunks/{core.js-Clg1CHb6.js → core.js-DNIuZ9y-.js} +88 -2
  54. package/build/server/chunks/chunks/core.js-DNIuZ9y-.js.map +1 -0
  55. package/build/server/chunks/chunks/{exports.js-FRj9eAnR.js → exports.js-Bepiq5XZ.js} +2 -2
  56. package/build/server/chunks/chunks/{exports.js-FRj9eAnR.js.map → exports.js-Bepiq5XZ.js.map} +1 -1
  57. package/build/server/chunks/chunks/{http.js--6sDZFfm.js → http.js-DWYlsbZd.js} +2 -2
  58. package/build/server/chunks/chunks/{http.js--6sDZFfm.js.map → http.js-DWYlsbZd.js.map} +1 -1
  59. package/build/server/chunks/chunks/{internal.js-D2Tk-vi1.js → internal.js-Cy01GWTk.js} +3 -3
  60. package/build/server/chunks/chunks/{internal.js-D2Tk-vi1.js.map → internal.js-Cy01GWTk.js.map} +1 -1
  61. package/build/server/chunks/chunks/internal2.js-BlXt2rfE.js.map +1 -1
  62. package/build/server/chunks/chunks/manifest-membership.js-CJnQXrL4.js +213 -0
  63. package/build/server/chunks/chunks/manifest-membership.js-CJnQXrL4.js.map +1 -0
  64. package/build/server/chunks/chunks/raw-reconciliation.js-_D9lZ_sc.js +11 -0
  65. package/build/server/chunks/chunks/raw-reconciliation.js-_D9lZ_sc.js.map +1 -0
  66. package/build/server/chunks/chunks/{raw-reconciliation.js-DOFtjkgu.js → raw-reconciliation2.js-C2No1QIL.js} +3 -34
  67. package/build/server/chunks/chunks/raw-reconciliation2.js-C2No1QIL.js.map +1 -0
  68. package/build/server/chunks/chunks/{shared.js-hvokB2mY.js → shared.js-b0LBJ1Hx.js} +2 -2
  69. package/build/server/chunks/chunks/{shared.js-hvokB2mY.js.map → shared.js-b0LBJ1Hx.js.map} +1 -1
  70. package/build/server/chunks/chunks/{utils.js-VGlYdWt0.js → utils.js-CecFjHB0.js} +3 -3
  71. package/build/server/chunks/chunks/{utils.js-VGlYdWt0.js.map → utils.js-CecFjHB0.js.map} +1 -1
  72. package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-CkSErIdC.js → _server.ts.js-Bmyh2WUa.js} +7 -6
  73. package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-CkSErIdC.js.map → _server.ts.js-Bmyh2WUa.js.map} +1 -1
  74. package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-Csnt5ISN.js → _server.ts.js-hoRG5JRv.js} +8 -7
  75. package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-Csnt5ISN.js.map → _server.ts.js-hoRG5JRv.js.map} +1 -1
  76. package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/{_server.ts.js-BVEQaFEu.js → _server.ts.js-BdO9kwrn.js} +8 -7
  77. package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/{_server.ts.js-BVEQaFEu.js.map → _server.ts.js-BdO9kwrn.js.map} +1 -1
  78. package/build/server/chunks/entries/endpoints/api/assets/_id_/reimport/{_server.ts.js-DIaT5h8R.js → _server.ts.js-BojOH5gj.js} +8 -7
  79. package/build/server/chunks/entries/endpoints/api/assets/_id_/reimport/{_server.ts.js-DIaT5h8R.js.map → _server.ts.js-BojOH5gj.js.map} +1 -1
  80. package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-CgCr-jFC.js → _server.ts.js-DWIptU3K.js} +8 -7
  81. package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-CgCr-jFC.js.map → _server.ts.js-DWIptU3K.js.map} +1 -1
  82. package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-BCvv4wq4.js → _server.ts.js-CaiOgcPc.js} +8 -7
  83. package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-BCvv4wq4.js.map → _server.ts.js-CaiOgcPc.js.map} +1 -1
  84. package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-GbxbM9uI.js → _server.ts.js-Bug1Y1W9.js} +8 -7
  85. package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-GbxbM9uI.js.map → _server.ts.js-Bug1Y1W9.js.map} +1 -1
  86. package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-BGjOvpRm.js → _server.ts.js-B9N7cPff.js} +8 -7
  87. package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-BGjOvpRm.js.map → _server.ts.js-B9N7cPff.js.map} +1 -1
  88. package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-CJuzJXPs.js → _server.ts.js-CiWdcZEv.js} +8 -7
  89. package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-CJuzJXPs.js.map → _server.ts.js-CiWdcZEv.js.map} +1 -1
  90. package/build/server/chunks/entries/endpoints/api/imports/{_server.ts.js-BYp42p6V.js → _server.ts.js-CNqGzdRB.js} +8 -7
  91. package/build/server/chunks/entries/endpoints/api/imports/{_server.ts.js-BYp42p6V.js.map → _server.ts.js-CNqGzdRB.js.map} +1 -1
  92. package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-l_tkhnQ-.js → _server.ts.js-BHwcGKE_.js} +8 -7
  93. package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-l_tkhnQ-.js.map → _server.ts.js-BHwcGKE_.js.map} +1 -1
  94. package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-B-VXO3Xr.js → _server.ts.js-CPoTCXQk.js} +8 -7
  95. package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-B-VXO3Xr.js.map → _server.ts.js-CPoTCXQk.js.map} +1 -1
  96. package/build/server/chunks/entries/endpoints/api/raw/adopt/{_server.ts.js-DV7s20GV.js → _server.ts.js-iDOU2RdK.js} +8 -7
  97. package/build/server/chunks/entries/endpoints/api/raw/adopt/{_server.ts.js-DV7s20GV.js.map → _server.ts.js-iDOU2RdK.js.map} +1 -1
  98. package/build/server/chunks/entries/endpoints/api/raw/edited/accept/{_server.ts.js-CYgOpWYC.js → _server.ts.js-DikbQm3f.js} +8 -7
  99. package/build/server/chunks/entries/endpoints/api/raw/edited/accept/{_server.ts.js-CYgOpWYC.js.map → _server.ts.js-DikbQm3f.js.map} +1 -1
  100. package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/{_server.ts.js-7loll6HR.js → _server.ts.js-DTdHkWuR.js} +8 -7
  101. package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/{_server.ts.js-7loll6HR.js.map → _server.ts.js-DTdHkWuR.js.map} +1 -1
  102. package/build/server/chunks/entries/endpoints/api/reconcile/{_server.ts.js-CdxeTMZj.js → _server.ts.js-Cn8hwP5P.js} +8 -7
  103. package/build/server/chunks/entries/endpoints/api/reconcile/{_server.ts.js-CdxeTMZj.js.map → _server.ts.js-Cn8hwP5P.js.map} +1 -1
  104. package/build/server/chunks/entries/endpoints/api/reveal/{_server.ts.js-CZWIskM4.js → _server.ts.js-BdUCIBJ_.js} +8 -7
  105. package/build/server/chunks/entries/endpoints/api/reveal/{_server.ts.js-CZWIskM4.js.map → _server.ts.js-BdUCIBJ_.js.map} +1 -1
  106. package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-CZFfpJkl.js → _server.ts.js-CBLdZJZB.js} +8 -7
  107. package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-CZFfpJkl.js.map → _server.ts.js-CBLdZJZB.js.map} +1 -1
  108. package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-DB3i4juR.js → _server.ts.js-DVtQlFHS.js} +7 -6
  109. package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-DB3i4juR.js.map → _server.ts.js-DVtQlFHS.js.map} +1 -1
  110. package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-BqarqenW.js → _server.ts.js-CY_gjOPq.js} +8 -7
  111. package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-BqarqenW.js.map → _server.ts.js-CY_gjOPq.js.map} +1 -1
  112. package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-CXbrUCmh.js → _server.ts.js-BOfjGM87.js} +8 -7
  113. package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-CXbrUCmh.js.map → _server.ts.js-BOfjGM87.js.map} +1 -1
  114. package/build/server/chunks/entries/{hooks.server.js-6Yf-GF0J.js → hooks.server.js-BH0-wX67.js} +7 -6
  115. package/build/server/chunks/entries/{hooks.server.js-6Yf-GF0J.js.map → hooks.server.js-BH0-wX67.js.map} +1 -1
  116. package/build/server/chunks/{handler-DHAu99Rv.js → handler-DMnHzDi5.js} +5 -5
  117. package/build/server/chunks/{handler-DHAu99Rv.js.map → handler-DMnHzDi5.js.map} +1 -1
  118. package/build/server/chunks/{index.js-Bm1XIAPD.js → index.js-BbOitM8j.js} +5 -5
  119. package/build/server/chunks/{index.js-Bm1XIAPD.js.map → index.js-BbOitM8j.js.map} +1 -1
  120. package/build/server/chunks/{manifest.js-CCc26-hb.js → manifest.js-EeQkh4Qe.js} +28 -28
  121. package/build/server/chunks/{manifest.js-CCc26-hb.js.map → manifest.js-EeQkh4Qe.js.map} +1 -1
  122. package/build/server/chunks/nodes/0.js-CS9Xzs-1.js +11 -0
  123. package/build/server/chunks/nodes/0.js-CS9Xzs-1.js.map +1 -0
  124. package/build/server/chunks/nodes/1.js-GmjtwLZL.js +7 -0
  125. package/build/server/chunks/nodes/{1.js-CXgbNa8h.js.map → 1.js-GmjtwLZL.js.map} +1 -1
  126. package/build/server/chunks/nodes/2.js-Pip0Abb-.js +7 -0
  127. package/build/server/chunks/nodes/2.js-Pip0Abb-.js.map +1 -0
  128. package/build/server/chunks/nodes/3.js-CJKDeQST.js +7 -0
  129. package/build/server/chunks/nodes/3.js-CJKDeQST.js.map +1 -0
  130. package/build/server/chunks/nodes/4.js-CtmXxVg2.js +7 -0
  131. package/build/server/chunks/nodes/{4.js-BUgaRCEY.js.map → 4.js-CtmXxVg2.js.map} +1 -1
  132. package/dist/core/index.d.ts +2 -2
  133. package/dist/core/index.js +1 -1
  134. package/dist/core/plugins/slice.d.ts +28 -4
  135. package/dist/core/plugins/slice.js +50 -0
  136. package/dist/server/library-store.d.ts +1 -1
  137. package/dist/server/library-store.js +5 -1
  138. package/dist/server/operations.js +20 -1
  139. package/dist/server/plugins/slice.d.ts +3 -2
  140. package/dist/server/plugins/slice.js +21 -9
  141. package/dist/server/processing/slice-processing.d.ts +14 -0
  142. package/dist/server/processing/slice-processing.js +148 -0
  143. package/package.json +1 -1
  144. package/build/client/_app/immutable/assets/2.DLP0pEak.css +0 -1
  145. package/build/client/_app/immutable/assets/2.DLP0pEak.css.br +0 -0
  146. package/build/client/_app/immutable/assets/2.DLP0pEak.css.gz +0 -0
  147. package/build/client/_app/immutable/assets/LibraryContextMenu.CVb-Lqdf.css +0 -1
  148. package/build/client/_app/immutable/assets/LibraryContextMenu.CVb-Lqdf.css.br +0 -0
  149. package/build/client/_app/immutable/assets/LibraryContextMenu.CVb-Lqdf.css.gz +0 -0
  150. package/build/client/_app/immutable/chunks/B1UabfW7.js +0 -1
  151. package/build/client/_app/immutable/chunks/B1UabfW7.js.br +0 -0
  152. package/build/client/_app/immutable/chunks/B1UabfW7.js.gz +0 -0
  153. package/build/client/_app/immutable/chunks/BmCZn5E-.js +0 -108
  154. package/build/client/_app/immutable/chunks/BmCZn5E-.js.br +0 -0
  155. package/build/client/_app/immutable/chunks/BmCZn5E-.js.gz +0 -0
  156. package/build/client/_app/immutable/chunks/BoEHtxM8.js +0 -1
  157. package/build/client/_app/immutable/chunks/BoEHtxM8.js.br +0 -0
  158. package/build/client/_app/immutable/chunks/BoEHtxM8.js.gz +0 -0
  159. package/build/client/_app/immutable/chunks/C-T1_s5P.js +0 -1
  160. package/build/client/_app/immutable/chunks/C-T1_s5P.js.br +0 -0
  161. package/build/client/_app/immutable/chunks/C-T1_s5P.js.gz +0 -0
  162. package/build/client/_app/immutable/chunks/CN-G-m-B.js.br +0 -4
  163. package/build/client/_app/immutable/chunks/CN-G-m-B.js.gz +0 -0
  164. package/build/client/_app/immutable/chunks/D5sQSsUv.js +0 -1
  165. package/build/client/_app/immutable/chunks/D5sQSsUv.js.br +0 -0
  166. package/build/client/_app/immutable/chunks/D5sQSsUv.js.gz +0 -0
  167. package/build/client/_app/immutable/entry/app.fVDDVV_y.js.br +0 -0
  168. package/build/client/_app/immutable/entry/app.fVDDVV_y.js.gz +0 -0
  169. package/build/client/_app/immutable/entry/start.BiWgLLju.js +0 -1
  170. package/build/client/_app/immutable/entry/start.BiWgLLju.js.br +0 -1
  171. package/build/client/_app/immutable/entry/start.BiWgLLju.js.gz +0 -0
  172. package/build/client/_app/immutable/nodes/0.BLnSe7Ya.js +0 -2
  173. package/build/client/_app/immutable/nodes/0.BLnSe7Ya.js.br +0 -0
  174. package/build/client/_app/immutable/nodes/0.BLnSe7Ya.js.gz +0 -0
  175. package/build/client/_app/immutable/nodes/1.DEw3d5yL.js.br +0 -0
  176. package/build/client/_app/immutable/nodes/1.DEw3d5yL.js.gz +0 -0
  177. package/build/client/_app/immutable/nodes/2.DnVTXPVk.js +0 -3
  178. package/build/client/_app/immutable/nodes/2.DnVTXPVk.js.br +0 -0
  179. package/build/client/_app/immutable/nodes/2.DnVTXPVk.js.gz +0 -0
  180. package/build/client/_app/immutable/nodes/3.1Hco6zU7.js +0 -1
  181. package/build/client/_app/immutable/nodes/3.1Hco6zU7.js.br +0 -0
  182. package/build/client/_app/immutable/nodes/3.1Hco6zU7.js.gz +0 -0
  183. package/build/client/_app/immutable/nodes/4.CKbcoBw2.js +0 -2
  184. package/build/client/_app/immutable/nodes/4.CKbcoBw2.js.br +0 -0
  185. package/build/client/_app/immutable/nodes/4.CKbcoBw2.js.gz +0 -0
  186. package/build/server/chunks/chunks/asset-id.js-CFsW8jeL.js +0 -48
  187. package/build/server/chunks/chunks/asset-id.js-CFsW8jeL.js.map +0 -1
  188. package/build/server/chunks/chunks/context.js-bXe5hzjI.js.map +0 -1
  189. package/build/server/chunks/chunks/contract.js-sHny3b-s.js.map +0 -1
  190. package/build/server/chunks/chunks/core.js-Clg1CHb6.js.map +0 -1
  191. package/build/server/chunks/chunks/raw-reconciliation.js-DOFtjkgu.js.map +0 -1
  192. package/build/server/chunks/chunks/raw-reconciliation2.js-DFwky2ou.js +0 -11
  193. package/build/server/chunks/chunks/raw-reconciliation2.js-DFwky2ou.js.map +0 -1
  194. package/build/server/chunks/nodes/0.js-Bpzcq6LZ.js +0 -11
  195. package/build/server/chunks/nodes/0.js-Bpzcq6LZ.js.map +0 -1
  196. package/build/server/chunks/nodes/1.js-CXgbNa8h.js +0 -7
  197. package/build/server/chunks/nodes/2.js-D56ryWAu.js +0 -7
  198. package/build/server/chunks/nodes/2.js-D56ryWAu.js.map +0 -1
  199. package/build/server/chunks/nodes/3.js-DMaZRwrN.js +0 -7
  200. package/build/server/chunks/nodes/3.js-DMaZRwrN.js.map +0 -1
  201. package/build/server/chunks/nodes/4.js-BUgaRCEY.js +0 -7
package/README.md CHANGED
@@ -1,22 +1,59 @@
1
1
  # Fundus
2
2
 
3
- Fundus is an AI-first, end-to-end asset management platform for Svelte mobile
4
- apps. It gives developers and coding agents one local workflow to import,
5
- organize, process, deliver, and render production assets.
3
+ > **Fundus** /ˈfʊndʊs/ _German noun_ a stock, collection, or reservoir to draw
4
+ > from.
5
+
6
+ [![npm](https://img.shields.io/npm/v/fundus.svg)](https://www.npmjs.com/package/fundus)
7
+ [![CI](https://github.com/grischaerbe/fundus/actions/workflows/CI.yaml/badge.svg)](https://github.com/grischaerbe/fundus/actions/workflows/CI.yaml)
8
+
9
+ Fundus is a local, typed asset pipeline for SvelteKit. It turns source images,
10
+ slices, video, chroma-key video, and audio into optimized files and generated
11
+ TypeScript manifests. One package contains the visual editor, headless CLI,
12
+ Sharp and FFmpeg processing, and Svelte 5 runtime components.
13
+
14
+ Originals stay intact. Outputs are deterministic and git-friendly. No mystery
15
+ CDN, no dashboard account, no `final-final-2x-really-final.png` archaeology.
16
+
17
+ ## Why Fundus?
18
+
19
+ - **One source of truth.** The editor and CLI mutate the same local library and
20
+ run the same processing pipeline.
21
+ - **Typed delivery.** Assets become properties such as `main.logo`; a rename or
22
+ deletion becomes a compiler error instead of a broken URL in production.
23
+ - **Explicit budgets.** Manifests define what ships and preloads for a screen,
24
+ route, or feature. Unassigned assets do not quietly hitch a ride.
25
+ - **Boring builds.** Raw inputs, optimized proxies, and generated modules can
26
+ all live in git. `fundus check` proves they agree without writing anything.
27
+
28
+ ## The workflow
29
+
30
+ ```text
31
+ file or Figma node
32
+
33
+ raw original + library record
34
+
35
+ type, parameters, manifest membership
36
+
37
+ optimized proxy + typed manifest
38
+
39
+ Svelte component
40
+ ```
6
41
 
7
- ## Features
42
+ 1. Import in the editor or CLI, or place a supported file in the raw directory.
43
+ 2. Choose its stable id, asset type, processing settings, folder, and manifest.
44
+ 3. Fundus saves the library, processes affected assets, and regenerates manifest
45
+ modules as one operation.
46
+ 4. Import the generated manifest in Svelte and render the typed entry.
47
+ 5. Run `fundus check` in CI to catch stale proxies, invalid references,
48
+ out-of-sync modules, and unresolved raw-file drift.
8
49
 
9
- - AI-ready CLI with structured JSON output for reliable agent workflows
10
- - Local visual editor for managing assets, folders, manifests, and processing
11
- - Images, slices, video, chroma-key video, and audio in one pipeline
12
- - Automatic optimization with Sharp and FFmpeg
13
- - Typed manifests that turn missing assets into compile-time errors
14
- - Svelte 5 components for rendering assets as authored
15
- - Deterministic, git-friendly output with originals kept intact
50
+ Only manifest members and the assets they reference are processed and shipped.
51
+ Manifests also preload and release their complete delivery set.
16
52
 
17
- ## Install and run
53
+ ## Quick start
18
54
 
19
- Fundus requires Node.js 20.19 or newer. From your Svelte project:
55
+ Fundus requires Node.js 20.19 or newer, Svelte 5, and an existing SvelteKit
56
+ project.
20
57
 
21
58
  ```bash
22
59
  npm install fundus
@@ -24,156 +61,121 @@ npx fundus init
24
61
  npx fundus start
25
62
  ```
26
63
 
27
- `fundus init` creates `fundus.config.ts` and an asset library with a default
28
- `main` manifest. It refuses to run if a Fundus config already exists. `fundus
29
- start` launches the packaged SvelteKit Node application on
30
- `http://127.0.0.1:7583`; the client-rendered editor, asset API, and raw/proxy file
31
- endpoints share one local origin. Fundus opens the editor in your default browser
32
- once the server is ready. Pass `--port 8080` to choose another port, or
33
- `--no-open` to start without opening a browser.
64
+ `init` creates `fundus.config.ts`, a local library, a raw asset directory, and a
65
+ default manifest named `main`. `start` opens the editor at
66
+ `http://127.0.0.1:7583`; add `--no-open` or `--port 8080` when appropriate.
34
67
 
35
- For editor development against a host project, provide its absolute path:
68
+ Add assets, assign them to `main`, then use the generated module:
36
69
 
37
- ```bash
38
- FUNDUS_PROJECT_ROOT=/absolute/path/to/host npm run dev
70
+ ```svelte
71
+ <script lang="ts">
72
+ import { Image, Slice } from 'fundus';
73
+ import { main } from '$lib/fundus/main.generated';
74
+ </script>
75
+
76
+ <Image src={main.logo} alt="Acme" />
77
+ <Slice src={main.dialogFrame} />
39
78
  ```
40
79
 
41
- To verify the complete consumer setup against a freshly generated SvelteKit
42
- app, run:
80
+ For changes made outside the editor:
43
81
 
44
82
  ```bash
45
- npm run smoke:e2e
83
+ npx fundus build # write current proxies and manifest modules
84
+ npx fundus check # verify without writing; ideal for CI
46
85
  ```
47
86
 
48
- This uses the current `sv` CLI, installs a locally packed Fundus artifact, runs
49
- `fundus init`, checks and builds both projects, boots the generated host, and
50
- boots the packaged editor and API, opens the editor in your default browser, and
51
- keeps it running until you press Ctrl+C. The generated host remains under the
52
- gitignored `.fundus-e2e/app` directory for inspection and is recreated on every
53
- run. Set `SV_VERSION` to test a specific CLI release instead of `latest`.
87
+ Commit the config, library, raw originals, processed proxies, and generated
88
+ modules. With the default config, those live in `fundus.config.ts`, `assets/`,
89
+ `static/fundus/`, and `src/lib/fundus/`.
54
90
 
55
- Build optimized assets and generated manifests, then verify everything is in
56
- sync:
91
+ ## Supported assets
92
+
93
+ | Type | Processing | Runtime |
94
+ | ---------------- | ------------------------------------------------ | --------------------------------------- |
95
+ | Image | WebP, PNG, AVIF, or JPEG; optional width | `<Image>` |
96
+ | Slice | 1-, 3-, or 9-slice; optional stretch compression | `<Slice>` |
97
+ | Video | H.264 MP4; optional width cap | `<Video>` |
98
+ | Chroma-key video | H.264 MP4 with WebGL2 keying, mask, and fallback | `<ChromaKeyVideo>` |
99
+ | Audio | Opus/WebM or AAC/M4A | Your audio engine via `audioSourceOf()` |
100
+
101
+ Named presets in `fundus.config.ts` keep encoding choices consistent. Each asset
102
+ currently produces one processed proxy, which is often exactly what an app wants
103
+ and refreshingly unlike configuring a small television network.
104
+
105
+ ## Editor and CLI
106
+
107
+ Use the editor for visual work: organize assets, author slices and chroma keys,
108
+ tune processing, manage manifests, and inspect delivered bytes.
109
+
110
+ Use the CLI for scripts, CI, and coding agents:
57
111
 
58
112
  ```bash
59
- npx fundus build
113
+ npx fundus state --json
114
+ npx fundus asset ingest ./exports/panel.png --type slice --manifests main
115
+ npx fundus asset replace panel ./exports/panel-v2.png
60
116
  npx fundus check
61
117
  ```
62
118
 
63
- ### Import from Figma
119
+ Every command except `start` supports `--json` and emits one JSON document on
120
+ stdout. Run `npx fundus --help` or `npx fundus asset ingest --help` for the full
121
+ surface.
122
+
123
+ Fundus serializes writes inside one editor server, but does not lock across
124
+ processes. Do not run mutating CLI commands while the editor is changing the
125
+ same project. Two writers remain one writer too many.
64
126
 
65
- Fundus separates acquisition from asset processing: a file or Figma importer
66
- materializes a raw file, then the selected Image or Slice asset type processes
67
- it through the same existing pipeline. Raw files remain committed, offline
68
- build inputs; builds and checks never contact Figma.
127
+ ## Figma import
69
128
 
70
- Create a Figma personal access token with `file_content:read`, pass it through
71
- the server-side config, and choose **Import from Figma** in the editor. Prefer
72
- an environment variable so the secret is never committed:
129
+ Fundus can import one selected Figma node as a PNG at 1x–4x and process it as an
130
+ Image or Slice. Create a personal access token with `file_content:read` and keep
131
+ it in an environment variable:
73
132
 
74
133
  ```ts
134
+ import { defineConfig } from 'fundus/config';
135
+
75
136
  export default defineConfig({
76
- // existing paths…
137
+ // paths created by `fundus init`...
77
138
  import: {
78
139
  figma: {
79
140
  token: process.env.FIGMA_ACCESS_TOKEN,
80
- defaults: { scale: 3 }
141
+ defaults: { scale: 2 }
81
142
  }
82
143
  }
83
144
  });
84
145
  ```
85
146
 
86
- Fundus never exposes this token through editor state, API responses, or the
87
- library file. The default scale is optional and falls back to 2.
147
+ ```bash
148
+ npx fundus asset ingest 'https://www.figma.com/design/abc/UI?node-id=12-34' \
149
+ --from figma --type slice --id navigationPanel --scale 3
150
+ npx fundus asset reimport navigationPanel
151
+ ```
88
152
 
89
- The editor, API, and CLI use the same importer pipeline and configuration. In
90
- the CLI, acquisition is explicit: ordinary file ingest remains the default,
91
- while `--from figma` requires a selection link, asset type, and id:
153
+ For Slice assets, the pixel ratio defaults to the chosen Figma export scale.
154
+ Changing the saved link or scale and reimporting synchronizes that ratio, while
155
+ refreshing the unchanged source preserves a manually authored value. The editor
156
+ offers Figma import from both its main controls and folder context menus.
92
157
 
93
- ```sh
94
- fundus asset ingest ./exports/navigation_panel.png --type slice
95
- fundus asset ingest 'https://www.figma.com/design/abc/UI?node-id=12-34' \
96
- --from figma --type slice --id navigationPanel --scale 3
158
+ Fundus persists the stable Figma file and node identifiers, never the token or
159
+ temporary URL. The downloaded original stays local, so builds remain offline.
160
+ Replacing or accepting an external edit to it intentionally disconnects the
161
+ Figma source.
97
162
 
98
- fundus asset reimport navigationPanel
99
- fundus asset reimport navigationPanel --scale 4
100
- fundus asset reimport navigationPanel \
101
- --figma-link 'https://www.figma.com/design/def/UI?node-id=56-78'
102
- ```
163
+ ## Is Fundus for me?
103
164
 
104
- Omit `--scale` to use `import.figma.defaults.scale`. During re-import, link and
105
- scale overrides are independent; an omitted value stays unchanged.
106
-
107
- The MVP imports one node from a Figma design, file, or prototype selection
108
- link as PNG at 1x–4x (2x by default unless configured). Select Image or Slice
109
- independently of the importer. Figma export scale is not Slice `pixelRatio`;
110
- initial Slice parameters conservatively start at pixel ratio 1.
111
-
112
- Fundus stores only the file key, node id, PNG format, and scale. The token and
113
- temporary download URL are never persisted. Re-import renders the same stable
114
- node id again while preserving the asset id, type, parameters, folder, and
115
- manifest memberships. Renaming or editing a Figma node normally preserves its
116
- id; deleting/recreating it or copying it to another file does not.
117
-
118
- Local raw-file drift blocks re-import instead of being overwritten. Applying
119
- an external edit or manually replacing the raw file disconnects the Figma
120
- source. Figma rate limits are surfaced without automatic retries, and Figma
121
- may downscale exports above 32 megapixels.
122
-
123
- The first persisted Figma source upgrades that project library lazily from
124
- version 1 to version 2. Source-free projects remain version 1, but older Fundus
125
- versions cannot open a library after this upgrade.
126
-
127
- ### External raw-file management
128
-
129
- You can also add, move, edit, or delete files directly in the configured raw
130
- directory. The editor reconciles the directory when it starts and whenever its
131
- window regains focus. Unambiguous same-content moves are adopted automatically,
132
- and externally deleted records disappear silently; ordinary validation still
133
- reports references that now point at a deleted asset.
134
-
135
- New files with a supported extension and edited managed files appear in the
136
- editor's ingestion queue. Choose any compatible asset type, then import a new
137
- file or reimport an edited one. Reimporting resets and reseeds its parameters;
138
- applying the external edit instead keeps its current type and parameters while
139
- accepting the new content hash. Either choice disconnects a repeatable import
140
- source because the accepted local bytes become authoritative. Regular files
141
- whose extension no registered asset type accepts are ignored entirely.
142
-
143
- `fundus check` is the read-only CI gate for this workflow. Unmanaged, missing,
144
- edited, invalid, symlinked, and otherwise unsafe raw entries are hard errors
145
- even with `--allow-warnings`. Ambiguous duplicate-content moves are not guessed;
146
- reconciliation treats them as a deletion plus new ingestion items.
147
-
148
- Externally named raw files may contain NFC-normalized Unicode and spaces. For
149
- portable repositories Fundus rejects traversal and separators, control or
150
- Windows-reserved characters and names, trailing dots/whitespace, `.gitkeep`,
151
- portable case/normalization collisions, and Fundus transaction names. New
152
- external subfolders are registered and mirrored with `.gitkeep` when a file is
153
- adopted or moved into them.
154
-
155
- Fundus serializes requests inside one running editor server. It does not provide
156
- cross-process filesystem locking, so do not run editor and CLI mutations at the
157
- same time.
158
-
159
- Replace an asset's source file without changing its id, type, parameters,
160
- folder, or manifest memberships from the editor's asset inspector, or via CLI:
165
+ Fundus fits SvelteKit apps that keep product assets in git and want repeatable
166
+ processing, typed references, visual authoring, and agent-friendly automation.
161
167
 
162
- ```bash
163
- npx fundus asset replace navigationPanel ./exports/navigation-panel-v2.png
164
- ```
168
+ It is not a cloud DAM, CDN, hosted collaboration service, or runtime media CMS.
169
+ It does not currently handle SVG, fonts, responsive `srcset` generation,
170
+ platform variants, or concurrent writers. Figma support is deliberate one-node
171
+ import and reimport, not two-way sync.
165
172
 
166
- Use the generated manifests with Fundus runtime components:
173
+ ## Contributing
167
174
 
168
- ```svelte
169
- <script lang="ts">
170
- import { Image, Slice } from 'fundus';
171
- import { appAssets } from '$lib/fundus/app-assets.generated';
172
- </script>
175
+ Run `npm install`, `npm test`, `npm run check`, and `npm run lint`. Public
176
+ package changes also need `npm run changeset`. See [CHANGELOG.md](CHANGELOG.md)
177
+ for release history and [RELEASING.md](RELEASING.md) for publishing notes.
173
178
 
174
- <Image src={appAssets.logo} />
175
- <Slice src={appAssets.panel} />
176
- ```
179
+ ## License
177
180
 
178
- Fundus keeps the full asset workflow in your project, under your control, and
179
- ready for people and agents to build with together.
181
+ Fundus does not currently include a license file.
@@ -0,0 +1 @@
1
+ .submenu-anchor.svelte-13hq4tl{position:relative}button.svelte-13hq4tl{width:100%;color:var(--text);font:inherit;text-align:left;white-space:nowrap;background:0 0;border:0;border-radius:4px;padding:6px 8px}button.svelte-13hq4tl:hover,button.svelte-13hq4tl:focus-visible{background:var(--accent-soft);outline:none}.submenu-anchor.svelte-13hq4tl:has(.submenu:where(.svelte-13hq4tl))>.submenu-trigger:where(.svelte-13hq4tl){background:var(--accent-soft);outline:none}.submenu-trigger.svelte-13hq4tl{justify-content:space-between;align-items:center;gap:12px;display:flex}.arrow.svelte-13hq4tl{color:var(--text-faint);font-size:16px;line-height:12px}.submenu.svelte-13hq4tl{z-index:1;background:var(--panel-raised);border:1px solid var(--border);border-radius:6px;min-width:168px;max-width:320px;padding:4px;position:absolute;top:-5px;left:calc(100% - 4px);overflow-y:auto;box-shadow:0 8px 24px #00000073}.submenu.opens-left.svelte-13hq4tl{left:auto;right:calc(100% - 4px)}.submenu.svelte-13hq4tl button:where(.svelte-13hq4tl){text-overflow:ellipsis;overflow:hidden}hr.svelte-13hq4tl{background:var(--border);border:0;height:1px;margin:4px 8px}.context-menu.svelte-109nkvw{z-index:200;background:var(--panel-raised);border:1px solid var(--border);border-radius:6px;width:168px;padding:4px;position:fixed;box-shadow:0 8px 24px #00000073}button.svelte-109nkvw{width:100%;color:var(--text);font:inherit;text-align:left;background:0 0;border:0;border-radius:4px;padding:6px 8px}button.svelte-109nkvw:hover,button.svelte-109nkvw:focus-visible{background:var(--accent-soft);outline:none}button.danger.svelte-109nkvw{color:var(--danger)}hr.svelte-109nkvw{background:var(--border);border:0;height:1px;margin:4px 8px}.manifest-label.svelte-1b4m5oj{align-items:center;gap:4px;min-width:0;display:inline-flex}.emoji.svelte-1b4m5oj{flex:none;line-height:1}.name.svelte-1b4m5oj{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.chip.svelte-1b4m5oj{background:color-mix(in srgb, var(--manifest-color) 20%, transparent);color:var(--manifest-color);border-radius:4px;padding:0 5px;font-size:10px}.chip.passive.svelte-1b4m5oj{border:1px dashed var(--manifest-color);background:0 0}.library-view.svelte-1uha8ag{flex:1;min-height:0;display:flex}.page.svelte-1uha8ag{flex:1;min-height:0;padding:16px;position:relative;overflow-y:auto}.selection-bar.svelte-1uha8ag,.filter-bar.svelte-1uha8ag{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.selection-bar.svelte-1uha8ag{margin-bottom:8px}.filter-bar.svelte-1uha8ag{margin-bottom:16px}.selection-summary.svelte-1uha8ag{color:var(--accent);white-space:nowrap;font-weight:600}.toggle.svelte-1uha8ag{color:var(--text-dim);align-items:center;gap:6px;display:inline-flex}.search.svelte-1uha8ag{align-items:center;gap:5px;width:220px;padding:0 6px;display:flex}.search.svelte-1uha8ag:focus-within{border-color:var(--accent)}.search-icon.svelte-1uha8ag{fill:none;width:14px;height:14px;stroke:var(--text-faint);stroke-width:1.5px;stroke-linecap:round;flex:none}.search-input.svelte-1uha8ag{min-width:0;height:100%;color:var(--text);font:inherit;background:0 0;border:0;outline:none;flex:1;padding:0}.search.svelte-1uha8ag kbd:where(.svelte-1uha8ag){border:1px solid var(--border);color:var(--text-faint);border-radius:3px;flex:none;padding:1px 4px;font:9px/14px system-ui,sans-serif}.import.svelte-1uha8ag{background:var(--accent);color:var(--text);margin-left:auto}.section.svelte-1uha8ag{margin-bottom:24px}.section.svelte-1uha8ag:last-child{margin-bottom:0}.section-emoji.svelte-1uha8ag{margin-right:6px}.grid.svelte-1uha8ag,.folder-grid.svelte-1uha8ag{grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:8px;display:grid}.folder-card.svelte-1uha8ag{background:var(--panel);border:1px solid var(--border-soft);min-width:0;height:60px;color:var(--text);text-align:left;border-radius:8px;align-items:center;gap:10px;padding:8px 10px;display:flex}.folder-card.svelte-1uha8ag:hover,.folder-card.svelte-1uha8ag:focus-visible{border-color:var(--accent);outline:none}.folder-card.drop-target.svelte-1uha8ag{border-color:var(--accent);background:var(--accent-soft);box-shadow:0 0 0 1px var(--accent)}.folder-card.dragging-folder.svelte-1uha8ag{opacity:.55}.folder-card-icon.svelte-1uha8ag{color:var(--text-dim);flex:none;align-items:center;display:flex}.folder-card-details.svelte-1uha8ag{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.folder-card-details.svelte-1uha8ag strong:where(.svelte-1uha8ag){text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.folder-card-details.svelte-1uha8ag span:where(.svelte-1uha8ag),.folder-card-arrow.svelte-1uha8ag{color:var(--text-faint)}.folder-card-arrow.svelte-1uha8ag{flex:none;font-size:18px}.card.svelte-1uha8ag{background:var(--panel);border:1px solid var(--border-soft);border-radius:8px;flex-direction:column;gap:8px;padding:8px;display:flex;position:relative}.card.selected.svelte-1uha8ag{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}.asset-select.svelte-1uha8ag{z-index:1;width:16px;height:16px;accent-color:var(--accent);position:absolute;top:12px;left:12px}.card.svelte-1uha8ag:hover{border-color:var(--accent)}.thumbnail.svelte-1uha8ag{border-radius:var(--radius);justify-content:center;align-items:center;height:96px;display:flex;overflow:hidden}.meta.svelte-1uha8ag{align-items:center;gap:6px;min-width:0;display:flex}.id.svelte-1uha8ag{text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.type-badge.svelte-1uha8ag{color:var(--text-dim);border:1px solid var(--border);border-radius:4px;flex:none;margin-left:auto;padding:0 5px;font-size:10px}.badges.svelte-1uha8ag{flex-wrap:wrap;gap:4px;min-height:16px;display:flex}.badge.svelte-1uha8ag{border-radius:4px;padding:0 5px;font-size:10px}.badge.warning.svelte-1uha8ag{background:var(--warning-soft);color:var(--warning)}.empty.svelte-1uha8ag{color:var(--text-dim);text-align:center;padding:48px}.dialog-row.svelte-1uha8ag{align-items:center;gap:8px;display:flex}.dialog-row.svelte-1uha8ag span:where(.svelte-1uha8ag){width:44px;color:var(--text-dim)}.dialog-row.svelte-1uha8ag input:where(.svelte-1uha8ag){flex:1}.dialog-text.svelte-1uha8ag,.dialog-warning.svelte-1uha8ag{margin:8px 0 0}.dialog-warning.svelte-1uha8ag{color:var(--warning)}.drop-hint.svelte-1uha8ag{border:2px dashed var(--accent);color:var(--accent);pointer-events:none;background:#0d99ff14;border-radius:12px;justify-content:center;align-items:center;font-size:14px;display:flex;position:fixed;inset:48px 8px 8px}
@@ -0,0 +1 @@
1
+ .playback.svelte-nchstv{align-items:center;gap:6px;width:100%;display:flex}.btn.svelte-nchstv{background:var(--panel-raised);border-radius:var(--radius);width:28px;height:28px;color:var(--text);border:1px solid #0000;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.btn.svelte-nchstv:hover:not(:disabled){border-color:var(--border)}.btn.svelte-nchstv:focus-visible{border-color:var(--accent);outline:none}.btn.svelte-nchstv:disabled{opacity:.4;cursor:not-allowed}.btn.active.svelte-nchstv{background:var(--accent-soft);color:var(--accent)}.btn.svelte-nchstv svg:where(.svelte-nchstv){width:16px;height:16px;display:block}.time.svelte-nchstv{color:var(--text-dim);font-variant-numeric:tabular-nums;flex:none;font-size:11px}.volume-group.svelte-nchstv{align-items:center;gap:6px;margin-left:auto;display:inline-flex}.range.svelte-nchstv{appearance:none;background:var(--panel-raised);cursor:pointer;border-radius:999px;height:4px}.range.scrub.svelte-nchstv{flex:1;min-width:0;margin:0 2px}.range.volume.svelte-nchstv{flex:none;width:72px}.range.svelte-nchstv:disabled{opacity:.4;cursor:not-allowed}.range.svelte-nchstv::-webkit-slider-thumb{appearance:none;background:var(--accent);border:none;border-radius:50%;width:12px;height:12px}.range.svelte-nchstv::-moz-range-thumb{background:var(--accent);border:none;border-radius:50%;width:12px;height:12px}.range.svelte-nchstv:focus-visible{outline:none}.range.svelte-nchstv:focus-visible::-webkit-slider-thumb{box-shadow:0 0 0 3px var(--accent-soft)}.range.svelte-nchstv:focus-visible::-moz-range-thumb{box-shadow:0 0 0 3px var(--accent-soft)}.audio-waveform.svelte-1liihyn{flex-direction:column;gap:8px;width:100%;height:100%;min-height:0;display:flex}.wave.svelte-1liihyn{cursor:pointer;touch-action:none;flex:1;width:100%;min-height:0;display:block}.footer.svelte-1liihyn{flex:none;align-items:center;display:flex}.stage.svelte-1ww4cvx{border:1px solid var(--border);border-radius:8px;flex:1;justify-content:center;align-items:center;min-height:0;display:flex;overflow:auto}.audio-frame.svelte-1ww4cvx{width:min(90%,480px);height:128px}p.svelte-1ww4cvx{color:var(--text-dim)}.icon.svelte-jamecx{display:block}.scrub-number.svelte-nhap92{flex:1;min-width:0;display:flex;position:relative}.input.svelte-nhap92{width:100%;min-width:0;color:var(--text);font-variant-numeric:tabular-nums;appearance:textfield;background:0 0;border:none;outline:none;flex:1;margin:0;padding:0;font-size:11px}.scrub-number.with-suffix.svelte-nhap92 .input:where(.svelte-nhap92){flex:none}.suffix.svelte-nhap92{color:var(--text-dim);font-variant-numeric:tabular-nums;-webkit-user-select:none;user-select:none;flex:none;margin-left:2px;font-size:11px}.scrub-number.right.svelte-nhap92 .input:where(.svelte-nhap92){text-align:right}.input.svelte-nhap92::-webkit-outer-spin-button{appearance:none;margin:0}.input.svelte-nhap92::-webkit-inner-spin-button{appearance:none;margin:0}.scrub-surface.svelte-nhap92{cursor:ew-resize;touch-action:none;position:absolute;inset:0}.number-field.svelte-368zap{flex-direction:column;gap:4px;min-width:0;display:flex}.caption.svelte-368zap{letter-spacing:.27px;color:#ffffffb2;-webkit-user-select:none;user-select:none;font-size:9px;font-weight:500;line-height:14px}.number-input.svelte-368zap{border-radius:4px;align-items:center;gap:4px;min-width:0;height:24px;padding:0 6px 0 0;display:flex;position:relative;overflow:hidden}.number-input.svelte-368zap:focus-within{border-color:var(--accent)}.fill.svelte-368zap{pointer-events:none;z-index:0;background:#4a4a4a;height:100%;position:absolute;top:0;left:0}.icon-slot.svelte-368zap{z-index:1;width:24px;height:24px;color:var(--text-dim);-webkit-user-select:none;user-select:none;flex:none;justify-content:center;align-items:center;font-size:11px;font-weight:500;display:flex;position:relative}.number-input.svelte-368zap .scrub-number{z-index:1}h3.svelte-1ol624f{letter-spacing:0;text-transform:none;color:#fff;margin:0 0 10px;font-size:11px;font-weight:400}.select-field.svelte-bczi6w{flex-direction:column;gap:4px;min-width:0;display:flex}.caption.svelte-bczi6w{letter-spacing:.27px;color:#ffffffb2;-webkit-user-select:none;user-select:none;font-size:9px;font-weight:500;line-height:14px}.select-input.svelte-bczi6w{border-radius:4px;align-items:center;gap:4px;min-width:0;height:24px;padding:0 6px 0 0;display:flex}.select-input.svelte-bczi6w:focus-within{border-color:var(--accent)}.icon-slot.svelte-bczi6w{width:24px;height:24px;color:var(--text-dim);-webkit-user-select:none;user-select:none;flex:none;justify-content:center;align-items:center;font-size:11px;font-weight:500;display:flex}select.svelte-bczi6w{width:100%;min-width:0;height:100%;color:var(--text);background:0 0;border:none;outline:none;flex:1;margin:0;padding:0;font-size:11px}section.svelte-m9vwwu{border-bottom:1px solid var(--border-soft);padding:12px}.hint.svelte-m9vwwu{color:var(--text-faint);margin:4px 0 0;font-size:11px}.info.svelte-m9vwwu{font-variant-numeric:tabular-nums;margin:0}.file.svelte-m9vwwu{color:var(--text-dim);word-break:break-all}section.svelte-1by8n8t{border-bottom:1px solid var(--border-soft);padding:12px}.field.svelte-1by8n8t{margin-bottom:8px}.fundus-slice.svelte-1820t2z{width:100%;height:100%;position:relative;overflow:hidden}.fundus-slice--overdraw.svelte-1820t2z{overflow:visible}.fundus-slice__cell.svelte-1820t2z{position:absolute;overflow:hidden}.fundus-slice__cell.svelte-1820t2z img:where(.svelte-1820t2z){pointer-events:none;-webkit-user-select:none;user-select:none;max-width:none;max-height:none;position:absolute}.fundus-slice-canvas.svelte-xdsbrz{width:100%;height:100%;position:relative}canvas.svelte-xdsbrz{pointer-events:none;display:block;position:absolute}.fundus-chroma-key-video.svelte-r30mxh{width:100%;height:100%;position:relative}canvas.svelte-r30mxh,img.svelte-r30mxh{width:100%;height:100%;display:block}video.svelte-r30mxh{visibility:hidden;pointer-events:none;width:100%;height:100%;position:absolute;inset:0}.stage.svelte-10eps7e{border:1px solid var(--border);border-radius:8px;flex:1;justify-content:center;align-items:center;min-height:0;display:flex;overflow:auto}.stage.svelte-10eps7e img{object-fit:contain;max-width:90%;max-height:90%}img.svelte-gdduef{object-fit:contain;max-width:100%;max-height:100%}section.svelte-1yd7n22{border-bottom:1px solid var(--border-soft);padding:12px}.modes.svelte-1yd7n22{flex-direction:column;gap:4px;display:flex}.modes.svelte-1yd7n22 button:where(.svelte-1yd7n22){text-align:left;background:var(--panel-raised);color:var(--text);border-radius:var(--radius);border:1px solid #0000;padding:6px 10px}.modes.svelte-1yd7n22 button:where(.svelte-1yd7n22):hover{border-color:var(--border)}.modes.svelte-1yd7n22 button.on:where(.svelte-1yd7n22){background:var(--accent-soft);border-color:var(--accent);color:var(--accent);font-weight:600}.insets.svelte-1yd7n22{grid-template-columns:1fr 1fr;gap:8px;min-width:0;display:grid}.insets.single.svelte-1yd7n22{grid-template-columns:1fr}.preview-panel.svelte-1mjaycs{flex-direction:column;height:100%;min-height:0;display:flex}.bar.svelte-1mjaycs{flex:none;align-items:center;gap:10px;padding:8px 0;display:flex}.size.svelte-1mjaycs{color:var(--text-dim);font-variant-numeric:tabular-nums}.backends.svelte-1mjaycs{background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);gap:2px;margin-left:auto;padding:2px;display:inline-flex}.backends.svelte-1mjaycs button:where(.svelte-1mjaycs){color:var(--text-dim);background:0 0;border:none;border-radius:4px;padding:2px 8px}.backends.svelte-1mjaycs button.on:where(.svelte-1mjaycs){background:var(--accent-soft);color:var(--accent);font-weight:600}.reset.svelte-1mjaycs{background:var(--panel-raised);border:1px solid var(--border);color:var(--text);border-radius:var(--radius);padding:4px 10px}.reset.svelte-1mjaycs:hover{border-color:var(--accent)}.stage.svelte-1mjaycs{border:1px solid var(--border);border-radius:var(--radius-large);flex:1;min-height:0;padding:24px;overflow:auto}.box.svelte-1mjaycs{position:relative;box-shadow:0 0 0 1px #ffffff1f}.box.svelte-1mjaycs .fill{position:absolute;inset:0}.handle.svelte-1mjaycs{touch-action:none;background:0 0;position:absolute}.handle.edge-right.svelte-1mjaycs{cursor:ew-resize;width:10px;height:100%;top:0;right:-4px}.handle.edge-bottom.svelte-1mjaycs{cursor:ns-resize;width:100%;height:10px;bottom:-4px;left:0}.handle.corner.svelte-1mjaycs{cursor:nwse-resize;background:var(--accent);width:16px;height:16px;box-shadow:0 0 0 2px var(--canvas);border-radius:3px;bottom:-6px;right:-6px}.canvas.svelte-1jfrg6d{flex-direction:column;height:100%;min-height:0;display:flex}.toolbar.svelte-1jfrg6d{flex:none;align-items:center;gap:8px;padding:8px 0;display:flex}.toolbar.svelte-1jfrg6d button:where(.svelte-1jfrg6d){background:var(--panel-raised);border:1px solid var(--border);color:var(--text);border-radius:var(--radius);padding:4px 10px}.toolbar.svelte-1jfrg6d button:where(.svelte-1jfrg6d):hover{border-color:var(--accent)}.toolbar.svelte-1jfrg6d button.active:where(.svelte-1jfrg6d){background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}.zoom.svelte-1jfrg6d{text-align:center;min-width:44px;color:var(--text-dim);font-variant-numeric:tabular-nums}.dims.svelte-1jfrg6d{color:var(--text-dim);font-variant-numeric:tabular-nums;margin-left:auto}.viewport.svelte-1jfrg6d{touch-action:none;cursor:grab;border:1px solid var(--border);border-radius:var(--radius-large);flex:1;min-height:0;position:relative;overflow:hidden}.viewport.panning.svelte-1jfrg6d{cursor:grabbing}.image-wrap.svelte-1jfrg6d{transform-origin:0 0;position:absolute;top:0;left:0;box-shadow:0 0 0 1px #ffffff14}.image-wrap.svelte-1jfrg6d img:where(.svelte-1jfrg6d){width:100%;height:100%;image-rendering:pixelated;pointer-events:none;-webkit-user-select:none;user-select:none;display:block}.center-rect.svelte-1jfrg6d{pointer-events:none;position:absolute}.center-rect.side-edges.svelte-1jfrg6d{border-left:1px dashed #0d99ff99;border-right:1px dashed #0d99ff99}.center-rect.cap-edges.svelte-1jfrg6d{border-top:1px dashed #0d99ff99;border-bottom:1px dashed #0d99ff99}.overdraw-band.svelte-1jfrg6d{pointer-events:none;background:#38bdf829;position:absolute}.line.svelte-1jfrg6d{background:var(--accent);touch-action:none;position:absolute}.line.overdraw-line.svelte-1jfrg6d{background:#38bdf8 padding-box content-box}.line.overdraw-line.svelte-1jfrg6d .tag:where(.svelte-1jfrg6d){background:#38bdf8}.line.v.svelte-1jfrg6d{cursor:ew-resize;box-sizing:content-box;background-clip:content-box;width:1px;height:100%;margin-left:-.5px;padding:0 7px;top:0;transform:translate(-7px)}.line.h.svelte-1jfrg6d{cursor:ns-resize;box-sizing:content-box;background-clip:content-box;width:100%;height:1px;margin-top:-.5px;padding:7px 0;left:0;transform:translateY(-7px)}.line.active.svelte-1jfrg6d{background-color:var(--text);background-clip:content-box}.tag.svelte-1jfrg6d{background:var(--accent);color:var(--text);font-variant-numeric:tabular-nums;pointer-events:none;border-radius:4px;padding:1px 5px;font-size:11px;font-weight:600;position:absolute}.line.v.svelte-1jfrg6d .tag:where(.svelte-1jfrg6d){top:4px;left:50%;transform:translate(-50%)}.line.h.svelte-1jfrg6d .tag:where(.svelte-1jfrg6d){top:50%;left:4px;transform:translateY(-50%)}.line.v.overdraw-line.svelte-1jfrg6d .tag:where(.svelte-1jfrg6d){top:auto;bottom:4px}.line.h.overdraw-line.svelte-1jfrg6d .tag:where(.svelte-1jfrg6d){left:auto;right:4px}.editor.svelte-1ea2lvt{flex-direction:column;flex:1;min-height:0;display:flex}.tabs.svelte-1ea2lvt{flex:none;gap:4px;margin-bottom:4px;display:inline-flex}.tabs.svelte-1ea2lvt button:where(.svelte-1ea2lvt){border-radius:var(--radius);color:var(--text-dim);background:0 0;border:none;padding:4px 10px}.tabs.svelte-1ea2lvt button.on:where(.svelte-1ea2lvt){background:var(--accent-soft);color:var(--accent)}.pane.svelte-1ea2lvt{flex:1;min-height:0}.empty.svelte-1ea2lvt{color:var(--text-dim);flex:1;justify-content:center;align-items:center;display:flex}section.svelte-ij1927{border-bottom:1px solid var(--border-soft);padding:12px}.field.svelte-ij1927{margin-bottom:8px}.stage.svelte-qls820{border:1px solid var(--border);border-radius:8px;flex:1;justify-content:center;align-items:center;min-height:0;display:flex;overflow:auto}.preview-column.svelte-qls820{flex-direction:column;align-items:center;gap:8px;display:flex}.video-frame.svelte-qls820{width:min(90%,480px)}.video-frame.svelte-qls820 video{width:100%;height:100%}p.svelte-qls820{color:var(--text-dim)}video.svelte-ejgo9x{object-fit:contain;max-width:100%;max-height:100%}.picker.svelte-56kutb{flex-direction:column;gap:4px;min-width:0;margin-bottom:8px;display:flex}.caption.svelte-56kutb{letter-spacing:.27px;color:#ffffffb2;-webkit-user-select:none;user-select:none;font-size:9px;font-weight:500;line-height:14px}.reference-input.svelte-56kutb{border-radius:4px;align-items:center;min-width:0;height:24px;padding:0;display:flex;position:relative}.reference-input.svelte-56kutb:focus-within{border-color:var(--accent)}.current.svelte-56kutb{min-width:0;height:100%;color:var(--text);text-align:left;background:0 0;border:none;outline:none;flex:1;align-items:center;gap:4px;padding:0 6px 0 0;display:flex}.current.empty.svelte-56kutb{color:var(--text-faint)}.preview-slot.svelte-56kutb{box-sizing:border-box;background:#4a4a4a;border-radius:3px 0 0 3px;flex:none;justify-content:center;align-items:center;width:24px;height:24px;margin-left:-1px;padding:2px;display:flex;overflow:hidden}.preview.svelte-56kutb{object-fit:contain;width:100%;height:100%}.missing-preview.svelte-56kutb{color:var(--warning);font-weight:700}.clear.svelte-56kutb{border:none;border-left:1px solid var(--border-soft);width:24px;height:24px;color:var(--text-dim);background:0 0;border-radius:0 3px 3px 0;outline:none;flex:none;padding:0}.clear.svelte-56kutb:hover{color:var(--danger)}.id.svelte-56kutb,.placeholder.svelte-56kutb{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.dangling.svelte-56kutb{color:var(--warning)}.dropdown.svelte-56kutb{z-index:10;background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);max-height:240px;padding:4px;position:absolute;top:calc(100% + 4px);left:0;right:0;overflow-y:auto;box-shadow:0 8px 24px #00000080}.option.svelte-56kutb{border-radius:var(--radius);width:100%;color:var(--text);text-align:left;background:0 0;border:none;align-items:center;gap:6px;padding:4px 6px;display:flex}.option.svelte-56kutb .thumbnail:where(.svelte-56kutb){object-fit:contain;background:var(--canvas);border-radius:3px;flex:none;width:24px;height:24px}.option.svelte-56kutb:hover{background:var(--panel-raised)}.option.selected.svelte-56kutb{background:var(--accent-soft);color:var(--accent)}.hint.svelte-56kutb{color:var(--text-faint);margin:4px;font-size:11px}.color-field.svelte-gjs979{flex-direction:column;gap:4px;min-width:0;display:flex}.caption.svelte-gjs979{letter-spacing:.27px;color:#ffffffb2;-webkit-user-select:none;user-select:none;font-size:9px;font-weight:500;line-height:14px}.color-input.svelte-gjs979{border-radius:4px;align-items:center;gap:4px;min-width:0;height:24px;padding:0 6px 0 0;display:flex}.color-input.svelte-gjs979:focus-within{border-color:var(--accent)}.swatch-slot.svelte-gjs979{flex:none;justify-content:center;align-items:center;width:24px;height:24px;display:flex}.swatch.svelte-gjs979{cursor:pointer;background:0 0;border:1px solid #ffffff3d;border-radius:3px;width:16px;height:16px;margin:0;padding:0;overflow:hidden}.swatch.svelte-gjs979::-webkit-color-swatch-wrapper{padding:0}.swatch.svelte-gjs979::-webkit-color-swatch{border:none}.hex-input.svelte-gjs979{width:100%;min-width:0;color:var(--text);font-variant-numeric:tabular-nums;text-transform:uppercase;background:0 0;border:none;outline:none;flex:1;margin:0;padding:0;font-size:11px}section.svelte-rsjkek{border-bottom:1px solid var(--border-soft);padding:12px}.field.svelte-rsjkek{margin-bottom:8px}.stage.svelte-1y3xro5{border:1px solid var(--border);border-radius:8px;flex:1;justify-content:center;align-items:center;min-height:0;display:flex;overflow:auto}.preview-column.svelte-1y3xro5{flex-direction:column;align-items:center;gap:8px;display:flex}.compare-row.svelte-1y3xro5{justify-content:center;align-items:flex-start;gap:16px;width:100%;max-width:760px;display:flex}figure.svelte-1y3xro5{flex-direction:column;flex:1 1 0;align-items:center;gap:6px;min-width:0;margin:0;display:flex}figcaption.svelte-1y3xro5{text-transform:uppercase;letter-spacing:.06em;color:var(--text-faint);font-size:10px}.video-frame.svelte-1y3xro5{width:100%}.video-frame.svelte-1y3xro5 video{width:100%;height:100%}p.svelte-1y3xro5{color:var(--text-dim)}section.svelte-3jblpy{border-bottom:1px solid var(--border-soft);padding:12px}.field.svelte-3jblpy{margin-bottom:8px}.backdrop.svelte-1f5yh58{z-index:100;background:#0000008c;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.dialog.svelte-1f5yh58{background:var(--panel);border:1px solid var(--border);border-radius:8px;width:360px;padding:16px;box-shadow:0 12px 32px #00000080}h2.svelte-1f5yh58{margin:0 0 4px;font-size:12px}.file-name.svelte-1f5yh58{color:var(--text-dim);font-variant-numeric:tabular-nums;margin:0}.destination.svelte-1f5yh58{color:var(--text-faint);margin:2px 0 16px}.row.svelte-1f5yh58{align-items:center;gap:8px;margin-bottom:8px;display:flex}.label.svelte-1f5yh58{width:64px;color:var(--text-dim);flex:none}.row.svelte-1f5yh58 input:where(.svelte-1f5yh58){flex:1}.row.manifests.svelte-1f5yh58{align-items:flex-start}.row.manifests.svelte-1f5yh58>.label:where(.svelte-1f5yh58){line-height:28px}.manifest-list.svelte-1f5yh58{flex:1;max-height:132px;overflow-y:auto}.empty-manifests.svelte-1f5yh58{color:var(--text-faint);margin:0;font-size:11px}.segmented.svelte-1f5yh58{border:1px solid var(--border);border-radius:var(--radius);display:inline-flex;overflow:hidden}.segmented.svelte-1f5yh58 button:where(.svelte-1f5yh58){background:var(--panel-raised);color:var(--text-dim);border:none;padding:4px 12px}.segmented.svelte-1f5yh58 button.on:where(.svelte-1f5yh58){background:var(--accent);color:var(--text)}.hint.svelte-1f5yh58{color:var(--text-dim);margin:4px 0 0;font-size:11px}.hint.warn.svelte-1f5yh58,.error.svelte-1f5yh58{color:var(--warning)}.actions.svelte-1f5yh58{justify-content:flex-end;gap:8px;margin-top:16px;display:flex}.backdrop.svelte-n5o24b{z-index:100;background:#0000008c;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.dialog.svelte-n5o24b{border:1px solid var(--border);background:var(--panel);border-radius:8px;width:420px;padding:16px;box-shadow:0 12px 32px #00000080}h2.svelte-n5o24b{margin:0 0 4px;font-size:12px}.destination.svelte-n5o24b{color:var(--text-faint);margin:0 0 16px}.row.svelte-n5o24b{gap:12px;display:flex}.field.svelte-n5o24b{color:var(--text-dim);flex-direction:column;flex:1;gap:4px;margin-bottom:10px;display:flex}.field.wide.svelte-n5o24b{width:100%}.warning.svelte-n5o24b{color:var(--warning);margin:6px 0 0;font-size:11px}.actions.svelte-n5o24b{justify-content:flex-end;gap:8px;margin-top:16px;display:flex}.directory.svelte-ftwms1{background:var(--panel);border-right:1px solid var(--border);flex-direction:column;width:220px;min-width:180px;max-width:320px;min-height:0;display:flex}header.svelte-ftwms1{border-bottom:1px solid var(--border-soft);align-items:center;height:40px;padding:0 8px 0 12px;display:flex}header.svelte-ftwms1 strong:where(.svelte-ftwms1){font-size:11px}.actions.svelte-ftwms1{margin-left:auto;display:flex}.icon-button.svelte-ftwms1{width:24px;height:24px;color:var(--text-dim);border-radius:var(--radius-small);background:0 0;border:0}.icon-button.svelte-ftwms1:hover:not(:disabled){background:var(--panel-raised);color:var(--text)}.icon-button.danger.svelte-ftwms1:hover:not(:disabled){color:var(--danger)}.icon-button.svelte-ftwms1:disabled{opacity:.3;cursor:default}.tree.svelte-ftwms1{padding:6px 4px;overflow:auto}.folder-row.svelte-ftwms1,.asset-row.svelte-ftwms1{padding-left:calc((var(--depth) + 2) * 14px);display:flex}.row.svelte-ftwms1{color:var(--text-dim);border-radius:var(--radius-small);text-align:left;background:0 0;border:0;align-items:center;gap:6px;min-width:0;height:28px;display:flex}.row.special.svelte-ftwms1{width:100%;padding:0 8px}.row.folder.svelte-ftwms1{flex:1;padding:0 8px 0 2px}.row.asset.svelte-ftwms1{cursor:grab;flex:1;padding:0 8px 0 2px}.row.asset.svelte-ftwms1:active{cursor:grabbing}.row.svelte-ftwms1:hover,.row.selected.svelte-ftwms1{background:var(--panel-raised);color:var(--text)}.row.asset.current.svelte-ftwms1,.row.selected.svelte-ftwms1{background:var(--accent-soft);color:var(--accent)}.row.drop-target.svelte-ftwms1{outline:1px solid var(--accent);background:var(--accent-soft)}.glyph.svelte-ftwms1{width:14px;color:var(--text-faint);flex:none;justify-content:center;align-items:center;display:flex}.asset-glyph.svelte-ftwms1{font-size:7px}.asset-warning.svelte-ftwms1{color:var(--warning);flex:none;margin-left:auto}.label.svelte-ftwms1{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.count.svelte-ftwms1{color:var(--text-faint);margin-left:auto;font-size:10px}.dialog-row.svelte-ftwms1{align-items:center;gap:8px;display:flex}.dialog-row.svelte-ftwms1 span:where(.svelte-ftwms1){width:44px;color:var(--text-dim)}.dialog-row.svelte-ftwms1 input:where(.svelte-ftwms1){flex:1}.dialog-path.svelte-ftwms1,.dialog-text.svelte-ftwms1,.dialog-warning.svelte-ftwms1{margin:8px 0 0}.dialog-path.svelte-ftwms1{color:var(--text-faint)}.dialog-warning.svelte-ftwms1{color:var(--warning)}.context-menu.svelte-10jgqdh{z-index:200;background:var(--panel-raised);border:1px solid var(--border);border-radius:6px;width:168px;padding:4px;position:fixed;box-shadow:0 8px 24px #00000073}button.svelte-10jgqdh{width:100%;color:var(--text);font:inherit;text-align:left;background:0 0;border:0;border-radius:4px;padding:6px 8px}button.svelte-10jgqdh:hover,button.svelte-10jgqdh:focus-visible{background:var(--accent-soft);outline:none}button.danger.svelte-10jgqdh{color:var(--danger)}hr.svelte-10jgqdh{background:var(--border);border:0;height:1px;margin:4px 8px}
@@ -1 +1 @@
1
- import"./D65cSBhe.js";import{a as e,r as t}from"./B1UabfW7.js";var n={get data(){return e.data},get error(){return e.error},get form(){return e.form},get params(){return e.params},get route(){return e.route},get state(){return e.state},get status(){return e.status},get url(){return e.url}};t.updated.check;var r=n;export{r as t};
1
+ import"./D65cSBhe.js";import{a as e,r as t}from"./D24lHNM9.js";var n={get data(){return e.data},get error(){return e.error},get form(){return e.form},get params(){return e.params},get route(){return e.route},get state(){return e.state},get status(){return e.status},get url(){return e.url}};t.updated.check;var r=n;export{r as t};
@@ -0,0 +1 @@
1
+ I@d�Z��Kf��Jb��.��ʬmT����I�