@mohasinac/appkit 4.52.4 → 4.53.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 (633) hide show
  1. package/dist/.build-stamp.json +4 -4
  2. package/dist/_internal/client/features/sticker-trace/canvas-codec.d.ts +2 -0
  3. package/dist/_internal/client/features/sticker-trace/canvas-codec.js +148 -0
  4. package/dist/_internal/server/features/auctions/actions.js +1 -1
  5. package/dist/_internal/server/features/categories/data.js +23 -7
  6. package/dist/_internal/server/features/checkout/actions.js +10 -3
  7. package/dist/_internal/server/features/checkout/data.d.ts +15 -0
  8. package/dist/_internal/server/features/checkout/data.js +20 -3
  9. package/dist/_internal/server/features/lottery/actions.js +9 -1
  10. package/dist/_internal/server/features/lottery/og.d.ts +40 -0
  11. package/dist/_internal/server/features/lottery/og.js +79 -0
  12. package/dist/_internal/server/features/messages/actions.js +4 -0
  13. package/dist/_internal/server/features/offers/adapters.js +17 -3
  14. package/dist/_internal/server/features/orders/actions.js +7 -2
  15. package/dist/_internal/server/features/raffle/actions.d.ts +19 -0
  16. package/dist/_internal/server/features/raffle/actions.js +25 -0
  17. package/dist/_internal/server/features/reviews/actions.js +1 -1
  18. package/dist/_internal/server/features/reviews/data.d.ts +1 -1
  19. package/dist/_internal/server/features/search/index-build/artifact-store.d.ts +89 -0
  20. package/dist/_internal/server/features/search/index-build/artifact-store.js +208 -0
  21. package/dist/_internal/server/features/search/index-build/build.d.ts +57 -0
  22. package/dist/_internal/server/features/search/index-build/build.js +285 -0
  23. package/dist/_internal/server/features/search/index-build/sources.d.ts +53 -0
  24. package/dist/_internal/server/features/search/index-build/sources.js +385 -0
  25. package/dist/_internal/server/features/search/search-sources.d.ts +0 -15
  26. package/dist/_internal/server/features/search/search-sources.js +142 -7
  27. package/dist/_internal/server/features/seo/robots.js +21 -1
  28. package/dist/_internal/server/features/seo/sitemap.js +1 -1
  29. package/dist/_internal/server/features/shared/listing-data-factory.js +16 -4
  30. package/dist/_internal/server/features/site-settings/adapters.d.ts +1 -1
  31. package/dist/_internal/server/features/site-settings/adapters.js +26 -0
  32. package/dist/_internal/server/features/sticker-trace/actions.d.ts +109 -0
  33. package/dist/_internal/server/features/sticker-trace/actions.js +172 -0
  34. package/dist/_internal/server/features/sticker-trace/adapters.d.ts +80 -0
  35. package/dist/_internal/server/features/sticker-trace/adapters.js +174 -0
  36. package/dist/_internal/server/features/sticker-trace/build-cut-file.d.ts +26 -0
  37. package/dist/_internal/server/features/sticker-trace/build-cut-file.js +127 -0
  38. package/dist/_internal/server/features/sticker-trace/coordinator.d.ts +27 -0
  39. package/dist/_internal/server/features/sticker-trace/coordinator.js +169 -0
  40. package/dist/_internal/server/features/sticker-trace/fanout.d.ts +43 -0
  41. package/dist/_internal/server/features/sticker-trace/fanout.js +180 -0
  42. package/dist/_internal/server/features/sticker-trace/finalizer.d.ts +25 -0
  43. package/dist/_internal/server/features/sticker-trace/finalizer.js +123 -0
  44. package/dist/_internal/server/features/sticker-trace/mosaic-inputs.d.ts +30 -0
  45. package/dist/_internal/server/features/sticker-trace/mosaic-inputs.js +112 -0
  46. package/dist/_internal/server/features/sticker-trace/progress.d.ts +81 -0
  47. package/dist/_internal/server/features/sticker-trace/progress.js +198 -0
  48. package/dist/_internal/server/features/sticker-trace/promote.d.ts +23 -0
  49. package/dist/_internal/server/features/sticker-trace/promote.js +193 -0
  50. package/dist/_internal/server/features/sticker-trace/shard.d.ts +50 -0
  51. package/dist/_internal/server/features/sticker-trace/shard.js +174 -0
  52. package/dist/_internal/server/features/sticker-trace/sheet-actions.d.ts +141 -0
  53. package/dist/_internal/server/features/sticker-trace/sheet-actions.js +279 -0
  54. package/dist/_internal/server/features/sticker-trace/storage.d.ts +135 -0
  55. package/dist/_internal/server/features/sticker-trace/storage.js +282 -0
  56. package/dist/_internal/server/functions/scheduled.d.ts +2 -1
  57. package/dist/_internal/server/functions/scheduled.js +25 -1
  58. package/dist/_internal/server/jobs/core/_event-ref.d.ts +51 -0
  59. package/dist/_internal/server/jobs/core/_event-ref.js +63 -0
  60. package/dist/_internal/server/jobs/core/assignSpinPrize.d.ts +18 -0
  61. package/dist/_internal/server/jobs/core/assignSpinPrize.js +77 -16
  62. package/dist/_internal/server/jobs/core/auctionSettlement.js +13 -4
  63. package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +44 -15
  64. package/dist/_internal/server/jobs/core/bundleStockSync.js +3 -4
  65. package/dist/_internal/server/jobs/core/cleanupRtdbEvents.js +44 -0
  66. package/dist/_internal/server/jobs/core/event-draw-reasons.d.ts +78 -0
  67. package/dist/_internal/server/jobs/core/event-draw-reasons.js +133 -0
  68. package/dist/_internal/server/jobs/core/listingProcessor.js +28 -8
  69. package/dist/_internal/server/jobs/core/onOrderCreate.js +12 -1
  70. package/dist/_internal/server/jobs/core/onScamReportCreate.js +13 -2
  71. package/dist/_internal/server/jobs/core/onScamReportRejected.js +8 -2
  72. package/dist/_internal/server/jobs/core/onScamReportVerified.js +8 -2
  73. package/dist/_internal/server/jobs/core/onStoreWrite.js +11 -4
  74. package/dist/_internal/server/jobs/core/prizeDrawAssignWinner.js +5 -4
  75. package/dist/_internal/server/jobs/core/prizeDrawExpiryReveal.js +1 -4
  76. package/dist/_internal/server/jobs/core/prizeDrawSoldOutReveal.js +1 -2
  77. package/dist/_internal/server/jobs/core/promotions.js +7 -4
  78. package/dist/_internal/server/jobs/core/searchIndexBuild.d.ts +7 -0
  79. package/dist/_internal/server/jobs/core/searchIndexBuild.js +211 -0
  80. package/dist/_internal/server/jobs/core/triggerEventRaffle.d.ts +35 -0
  81. package/dist/_internal/server/jobs/core/triggerEventRaffle.js +213 -31
  82. package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +20 -14
  83. package/dist/_internal/server/jobs/handlers/assignSpinPrize.d.ts +8 -0
  84. package/dist/_internal/server/jobs/handlers/assignSpinPrize.js +15 -15
  85. package/dist/_internal/server/jobs/handlers/index.d.ts +1 -0
  86. package/dist/_internal/server/jobs/handlers/index.js +1 -0
  87. package/dist/_internal/server/jobs/handlers/onCategoryWrite.js +18 -0
  88. package/dist/_internal/server/jobs/handlers/onProductWrite.js +18 -0
  89. package/dist/_internal/server/jobs/handlers/onReviewWrite.js +18 -0
  90. package/dist/_internal/server/jobs/handlers/onScamReportUpdate.js +18 -0
  91. package/dist/_internal/server/jobs/handlers/onStoreWrite.js +18 -0
  92. package/dist/_internal/server/jobs/handlers/searchIndexBuild.d.ts +2 -0
  93. package/dist/_internal/server/jobs/handlers/searchIndexBuild.js +2 -0
  94. package/dist/_internal/server/jobs/handlers/triggerEventRaffle.d.ts +8 -0
  95. package/dist/_internal/server/jobs/handlers/triggerEventRaffle.js +15 -6
  96. package/dist/_internal/shared/actions/action-registry.js +29 -0
  97. package/dist/_internal/shared/cache/revalidate-targets.d.ts +0 -1
  98. package/dist/_internal/shared/cache/revalidate-targets.js +10 -8
  99. package/dist/_internal/shared/features/events/config.d.ts +14 -0
  100. package/dist/_internal/shared/features/events/config.js +14 -0
  101. package/dist/_internal/shared/features/notifications/action-url.js +8 -0
  102. package/dist/_internal/shared/features/site-settings/types.d.ts +11 -0
  103. package/dist/_internal/shared/features/sticker-trace/codec.d.ts +81 -0
  104. package/dist/_internal/shared/features/sticker-trace/codec.js +30 -0
  105. package/dist/_internal/shared/features/sticker-trace/config.d.ts +81 -0
  106. package/dist/_internal/shared/features/sticker-trace/config.js +177 -0
  107. package/dist/_internal/shared/features/sticker-trace/cut-contour.d.ts +20 -0
  108. package/dist/_internal/shared/features/sticker-trace/cut-contour.js +60 -0
  109. package/dist/_internal/shared/features/sticker-trace/export/build-export-set.d.ts +65 -0
  110. package/dist/_internal/shared/features/sticker-trace/export/build-export-set.js +176 -0
  111. package/dist/_internal/shared/features/sticker-trace/export/cut-svg.d.ts +56 -0
  112. package/dist/_internal/shared/features/sticker-trace/export/cut-svg.js +120 -0
  113. package/dist/_internal/shared/features/sticker-trace/export/machine-profiles.d.ts +92 -0
  114. package/dist/_internal/shared/features/sticker-trace/export/machine-profiles.js +153 -0
  115. package/dist/_internal/shared/features/sticker-trace/export/nesting.d.ts +51 -0
  116. package/dist/_internal/shared/features/sticker-trace/export/nesting.js +110 -0
  117. package/dist/_internal/shared/features/sticker-trace/export/page-sizes.d.ts +68 -0
  118. package/dist/_internal/shared/features/sticker-trace/export/page-sizes.js +223 -0
  119. package/dist/_internal/shared/features/sticker-trace/export/part-tiling.d.ts +51 -0
  120. package/dist/_internal/shared/features/sticker-trace/export/part-tiling.js +178 -0
  121. package/dist/_internal/shared/features/sticker-trace/export/simplify-budget.d.ts +26 -0
  122. package/dist/_internal/shared/features/sticker-trace/export/simplify-budget.js +134 -0
  123. package/dist/_internal/shared/features/sticker-trace/export/vectorise-art.d.ts +40 -0
  124. package/dist/_internal/shared/features/sticker-trace/export/vectorise-art.js +195 -0
  125. package/dist/_internal/shared/features/sticker-trace/index.d.ts +2 -0
  126. package/dist/_internal/shared/features/sticker-trace/index.js +59 -0
  127. package/dist/_internal/shared/features/sticker-trace/math/catmull-rom.d.ts +11 -0
  128. package/dist/_internal/shared/features/sticker-trace/math/catmull-rom.js +66 -0
  129. package/dist/_internal/shared/features/sticker-trace/math/edt.d.ts +27 -0
  130. package/dist/_internal/shared/features/sticker-trace/math/edt.js +165 -0
  131. package/dist/_internal/shared/features/sticker-trace/math/label.d.ts +15 -0
  132. package/dist/_internal/shared/features/sticker-trace/math/label.js +156 -0
  133. package/dist/_internal/shared/features/sticker-trace/math/marching-squares.d.ts +16 -0
  134. package/dist/_internal/shared/features/sticker-trace/math/marching-squares.js +242 -0
  135. package/dist/_internal/shared/features/sticker-trace/math/morphology.d.ts +46 -0
  136. package/dist/_internal/shared/features/sticker-trace/math/morphology.js +168 -0
  137. package/dist/_internal/shared/features/sticker-trace/math/rasterize-path.d.ts +88 -0
  138. package/dist/_internal/shared/features/sticker-trace/math/rasterize-path.js +286 -0
  139. package/dist/_internal/shared/features/sticker-trace/math/rdp.d.ts +10 -0
  140. package/dist/_internal/shared/features/sticker-trace/math/rdp.js +74 -0
  141. package/dist/_internal/shared/features/sticker-trace/resume.d.ts +50 -0
  142. package/dist/_internal/shared/features/sticker-trace/resume.js +160 -0
  143. package/dist/_internal/shared/features/sticker-trace/trace/cluster.d.ts +20 -0
  144. package/dist/_internal/shared/features/sticker-trace/trace/cluster.js +132 -0
  145. package/dist/_internal/shared/features/sticker-trace/trace/cross-profile.d.ts +28 -0
  146. package/dist/_internal/shared/features/sticker-trace/trace/cross-profile.js +120 -0
  147. package/dist/_internal/shared/features/sticker-trace/trace/flood.d.ts +21 -0
  148. package/dist/_internal/shared/features/sticker-trace/trace/flood.js +104 -0
  149. package/dist/_internal/shared/features/sticker-trace/trace/geometry.d.ts +3 -0
  150. package/dist/_internal/shared/features/sticker-trace/trace/geometry.js +140 -0
  151. package/dist/_internal/shared/features/sticker-trace/trace/line-filter.d.ts +15 -0
  152. package/dist/_internal/shared/features/sticker-trace/trace/line-filter.js +138 -0
  153. package/dist/_internal/shared/features/sticker-trace/trace/merge.d.ts +27 -0
  154. package/dist/_internal/shared/features/sticker-trace/trace/merge.js +187 -0
  155. package/dist/_internal/shared/features/sticker-trace/trace/paper.d.ts +32 -0
  156. package/dist/_internal/shared/features/sticker-trace/trace/paper.js +147 -0
  157. package/dist/_internal/shared/features/sticker-trace/trace/prefilter.d.ts +30 -0
  158. package/dist/_internal/shared/features/sticker-trace/trace/prefilter.js +125 -0
  159. package/dist/_internal/shared/features/sticker-trace/trace/quantise.d.ts +10 -0
  160. package/dist/_internal/shared/features/sticker-trace/trace/quantise.js +153 -0
  161. package/dist/_internal/shared/features/sticker-trace/trace/ridge.d.ts +88 -0
  162. package/dist/_internal/shared/features/sticker-trace/trace/ridge.js +344 -0
  163. package/dist/_internal/shared/features/sticker-trace/trace/segment.d.ts +10 -0
  164. package/dist/_internal/shared/features/sticker-trace/trace/segment.js +251 -0
  165. package/dist/_internal/shared/features/sticker-trace/types.d.ts +197 -0
  166. package/dist/_internal/shared/features/sticker-trace/types.js +49 -0
  167. package/dist/_internal/shared/listing-types/_registry.d.ts +11 -0
  168. package/dist/_internal/shared/listing-types/art/config.d.ts +1 -0
  169. package/dist/_internal/shared/listing-types/art/config.js +1 -0
  170. package/dist/_internal/shared/listing-types/auction/config.d.ts +1 -0
  171. package/dist/_internal/shared/listing-types/auction/config.js +1 -0
  172. package/dist/_internal/shared/listing-types/classified/config.d.ts +1 -0
  173. package/dist/_internal/shared/listing-types/classified/config.js +1 -0
  174. package/dist/_internal/shared/listing-types/digital-code/config.d.ts +1 -0
  175. package/dist/_internal/shared/listing-types/digital-code/config.js +1 -0
  176. package/dist/_internal/shared/listing-types/feature-flags.d.ts +7 -0
  177. package/dist/_internal/shared/listing-types/feature-flags.js +9 -0
  178. package/dist/_internal/shared/listing-types/live/config.d.ts +1 -0
  179. package/dist/_internal/shared/listing-types/live/config.js +1 -0
  180. package/dist/_internal/shared/listing-types/pre-order/config.d.ts +1 -0
  181. package/dist/_internal/shared/listing-types/pre-order/config.js +1 -0
  182. package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +1 -0
  183. package/dist/_internal/shared/listing-types/prize-draw/config.js +1 -0
  184. package/dist/_internal/shared/listing-types/standard/config.d.ts +1 -0
  185. package/dist/_internal/shared/listing-types/standard/config.js +1 -0
  186. package/dist/_internal/shared/listing-types/stickers/config.d.ts +1 -0
  187. package/dist/_internal/shared/listing-types/stickers/config.js +1 -0
  188. package/dist/_internal/shared/media/limits.d.ts +12 -2
  189. package/dist/_internal/shared/media/limits.js +12 -2
  190. package/dist/_internal/shared/search/artifact-url.d.ts +35 -0
  191. package/dist/_internal/shared/search/artifact-url.js +119 -0
  192. package/dist/_internal/shared/search/index-record.d.ts +68 -0
  193. package/dist/_internal/shared/search/index-record.js +96 -0
  194. package/dist/_internal/shared/search/match.d.ts +65 -0
  195. package/dist/_internal/shared/search/match.js +263 -0
  196. package/dist/client.d.ts +8 -7
  197. package/dist/client.js +12 -5
  198. package/dist/configs/eslint.js +22 -2
  199. package/dist/constants/api-endpoints.d.ts +68 -0
  200. package/dist/constants/api-endpoints.js +32 -0
  201. package/dist/constants/field-names.d.ts +7 -1
  202. package/dist/constants/field-names.js +36 -1
  203. package/dist/contracts/repository.d.ts +8 -7
  204. package/dist/contracts/search.d.ts +2 -2
  205. package/dist/contracts/table.d.ts +3 -3
  206. package/dist/contracts/table.js +3 -3
  207. package/dist/core/contact-submissions.repository.js +2 -2
  208. package/dist/core/integration-keys.js +7 -1
  209. package/dist/core/newsletter.repository.js +2 -2
  210. package/dist/core/site-config.js +1 -1
  211. package/dist/errors/error-codes.d.ts +30 -0
  212. package/dist/errors/error-codes.js +30 -0
  213. package/dist/errors/error-display-map.js +40 -1
  214. package/dist/features/account/api/[userId]/addresses/route.js +1 -1
  215. package/dist/features/account/components/UserBidsView.js +1 -1
  216. package/dist/features/account/components/index.d.ts +0 -8
  217. package/dist/features/account/components/index.js +0 -4
  218. package/dist/features/addresses/repository/addresses.repository.d.ts +17 -6
  219. package/dist/features/addresses/repository/addresses.repository.js +65 -9
  220. package/dist/features/addresses/schemas/firestore.d.ts +17 -6
  221. package/dist/features/admin/actions/notification-actions.js +15 -6
  222. package/dist/features/admin/api/bids/route.js +1 -1
  223. package/dist/features/admin/api/coupons/route.js +1 -1
  224. package/dist/features/admin/api/products/route.js +1 -1
  225. package/dist/features/admin/api/reviews/route.js +1 -1
  226. package/dist/features/admin/components/AdminAdEditorView.js +19 -5
  227. package/dist/features/admin/components/AdminAuditLogView.js +1 -1
  228. package/dist/features/admin/components/AdminBlogEditorView.js +0 -1
  229. package/dist/features/admin/components/AdminBlogView.js +1 -1
  230. package/dist/features/admin/components/AdminBrandsView.js +17 -1
  231. package/dist/features/admin/components/AdminCategoryEditorView.js +0 -1
  232. package/dist/features/admin/components/AdminContactView.js +1 -1
  233. package/dist/features/admin/components/AdminEmployeeEditorView.js +1 -3
  234. package/dist/features/admin/components/AdminNewsletterView.js +1 -1
  235. package/dist/features/admin/components/AdminOrdersView.js +9 -2
  236. package/dist/features/admin/components/AdminPayoutsView.js +1 -1
  237. package/dist/features/admin/components/AdminPrizeDrawsView.js +11 -0
  238. package/dist/features/admin/components/AdminProductEditorView.d.ts +10 -1
  239. package/dist/features/admin/components/AdminProductEditorView.js +24 -37
  240. package/dist/features/admin/components/AdminProductsView.js +10 -3
  241. package/dist/features/admin/components/AdminScammersView.js +1 -1
  242. package/dist/features/admin/components/AdminSectionsView.js +21 -5
  243. package/dist/features/admin/components/AdminSessionsView.js +1 -1
  244. package/dist/features/admin/components/AdminSublistingCategoriesView.js +22 -1
  245. package/dist/features/admin/components/AdminTeamView.js +1 -1
  246. package/dist/features/admin/components/AdminTesterChecklistItemEditorView.js +0 -1
  247. package/dist/features/admin/components/AdminUsersView.js +1 -1
  248. package/dist/features/admin/components/DataListingView.d.ts +2 -1
  249. package/dist/features/admin/components/DataListingView.js +9 -4
  250. package/dist/features/admin/components/analytics/AdminPageViewsReportView.js +0 -2
  251. package/dist/features/admin/hooks/useAdminListing.d.ts +1 -1
  252. package/dist/features/admin/repository/site-settings.repository.js +8 -3
  253. package/dist/features/admin/schemas/firestore.d.ts +62 -1
  254. package/dist/features/admin/schemas/firestore.js +32 -0
  255. package/dist/features/admin/types/index.d.ts +1 -1
  256. package/dist/features/auctions/actions/bid-actions.d.ts +2 -2
  257. package/dist/features/auctions/actions/bid-actions.js +16 -4
  258. package/dist/features/auctions/api/route.js +1 -1
  259. package/dist/features/auctions/components/AuctionBottomActions.js +4 -0
  260. package/dist/features/auctions/repository/bid.repository.d.ts +46 -4
  261. package/dist/features/auctions/repository/bid.repository.js +114 -13
  262. package/dist/features/auctions/schemas/firestore.d.ts +24 -4
  263. package/dist/features/auctions/schemas/firestore.js +1 -0
  264. package/dist/features/auth/actions/profile-actions.js +30 -4
  265. package/dist/features/auth/components/index.d.ts +0 -1
  266. package/dist/features/auth/components/index.js +0 -1
  267. package/dist/features/auth/repository/session.repository.d.ts +17 -3
  268. package/dist/features/auth/repository/session.repository.js +46 -5
  269. package/dist/features/auth/repository/token.repository.d.ts +27 -4
  270. package/dist/features/auth/repository/token.repository.js +65 -11
  271. package/dist/features/auth/repository/user.repository.d.ts +33 -7
  272. package/dist/features/auth/repository/user.repository.js +100 -15
  273. package/dist/features/auth/schemas/firestore.d.ts +63 -12
  274. package/dist/features/auth/schemas/firestore.js +11 -0
  275. package/dist/features/before-after/api/route.js +1 -1
  276. package/dist/features/blog/components/BlogListView.js +16 -3
  277. package/dist/features/blog/components/BlogPostView.js +1 -1
  278. package/dist/features/blog/schemas/index.d.ts +2 -2
  279. package/dist/features/cart/api/route.js +1 -1
  280. package/dist/features/catalogue/repository/catalogue.repository.d.ts +7 -7
  281. package/dist/features/catalogue/repository/catalogue.repository.js +28 -10
  282. package/dist/features/catalogue/schemas/firestore.d.ts +11 -0
  283. package/dist/features/categories/api/route.js +10 -10
  284. package/dist/features/categories/components/CategoryDetailPageView.js +35 -5
  285. package/dist/features/categories/components/CategorySelectorCreate.js +0 -1
  286. package/dist/features/categories/components/index.d.ts +0 -2
  287. package/dist/features/categories/components/index.js +0 -1
  288. package/dist/features/categories/repository/categories.repository.d.ts +1 -0
  289. package/dist/features/categories/repository/categories.repository.js +31 -1
  290. package/dist/features/categories/schemas/index.d.ts +2 -2
  291. package/dist/features/categories/utils/taxonomy-visual.d.ts +21 -0
  292. package/dist/features/categories/utils/taxonomy-visual.js +58 -0
  293. package/dist/features/checkout/actions/checkout-value-otp-actions.js +8 -1
  294. package/dist/features/collections/api/[slug]/route.js +3 -3
  295. package/dist/features/collections/api/route.js +1 -1
  296. package/dist/features/consultation/api/route.js +1 -1
  297. package/dist/features/consultation/repository/consultations.repository.js +1 -1
  298. package/dist/features/consultation/types/index.d.ts +1 -1
  299. package/dist/features/contact/components/ContactForm.js +1 -3
  300. package/dist/features/corporate/api/route.js +1 -1
  301. package/dist/features/corporate/repository/corporate.repository.js +1 -1
  302. package/dist/features/corporate/types/index.d.ts +1 -1
  303. package/dist/features/cron/jobs/auction-expiry.job.js +1 -1
  304. package/dist/features/cron/jobs/preorder-reminder.job.js +1 -1
  305. package/dist/features/events/actions/event-actions.d.ts +14 -0
  306. package/dist/features/events/actions/event-actions.js +82 -3
  307. package/dist/features/events/api/[id]/route.js +2 -2
  308. package/dist/features/events/components/AdminEventEditorView.js +22 -3
  309. package/dist/features/events/components/AdminEventsView.js +32 -8
  310. package/dist/features/events/components/EventRafflesSection.d.ts +34 -1
  311. package/dist/features/events/components/EventRafflesSection.js +52 -3
  312. package/dist/features/events/components/SpinWheelView.d.ts +2 -2
  313. package/dist/features/events/components/SpinWheelView.js +41 -4
  314. package/dist/features/events/repository/event-entry.repository.d.ts +14 -2
  315. package/dist/features/events/repository/event-entry.repository.js +41 -7
  316. package/dist/features/events/schemas/firestore.d.ts +17 -4
  317. package/dist/features/events/types/index.d.ts +37 -0
  318. package/dist/features/faq/repository/faqs.repository.js +1 -1
  319. package/dist/features/faq/schemas/index.d.ts +5 -2
  320. package/dist/features/faq/schemas/index.js +6 -0
  321. package/dist/features/faq/types/index.d.ts +0 -1
  322. package/dist/features/grouped/components/GroupedListingEditorView.js +17 -2
  323. package/dist/features/homepage/api/carousel/[id]/route.js +1 -1
  324. package/dist/features/homepage/api/carousel/route.js +4 -4
  325. package/dist/features/homepage/api/route.js +2 -2
  326. package/dist/features/homepage/api/sections/route.js +1 -1
  327. package/dist/features/homepage/components/AnnouncementBar.d.ts +1 -9
  328. package/dist/features/homepage/components/AnnouncementBar.js +13 -19
  329. package/dist/features/homepage/components/MarketplaceHomepageView.js +6 -1
  330. package/dist/features/homepage/components/index.d.ts +0 -2
  331. package/dist/features/homepage/components/index.js +0 -1
  332. package/dist/features/homepage/repository/homepage.repository.js +1 -1
  333. package/dist/features/homepage/schemas/firestore.d.ts +6 -0
  334. package/dist/features/homepage/schemas/index.d.ts +10 -10
  335. package/dist/features/layout/AppLayoutShell.d.ts +12 -3
  336. package/dist/features/layout/AppLayoutShell.js +65 -13
  337. package/dist/features/layout/BottomActionsContext.d.ts +16 -0
  338. package/dist/features/layout/BottomActionsContext.js +5 -0
  339. package/dist/features/layout/BottomChrome.js +48 -9
  340. package/dist/features/layout/BottomNavbar.d.ts +14 -0
  341. package/dist/features/layout/BottomNavbar.js +43 -3
  342. package/dist/features/layout/MainNavbar.d.ts +11 -0
  343. package/dist/features/layout/NavbarLayout.d.ts +3 -0
  344. package/dist/features/layout/NavbarLayout.js +88 -11
  345. package/dist/features/layout/SideActionDock.d.ts +1 -0
  346. package/dist/features/layout/SideActionDock.js +219 -0
  347. package/dist/features/layout/TitleBarLayout.d.ts +1 -3
  348. package/dist/features/layout/TitleBarLayout.js +3 -4
  349. package/dist/features/layout/cta-anchor.d.ts +31 -0
  350. package/dist/features/layout/cta-anchor.js +31 -0
  351. package/dist/features/layout/hooks/useBottomActions.d.ts +7 -0
  352. package/dist/features/layout/hooks/useBottomActions.js +6 -1
  353. package/dist/features/layout/index.d.ts +9 -1
  354. package/dist/features/layout/index.js +9 -1
  355. package/dist/features/layout/useCtaReveal.d.ts +24 -0
  356. package/dist/features/layout/useCtaReveal.js +82 -0
  357. package/dist/features/layout/useHoldToOpen.d.ts +41 -0
  358. package/dist/features/layout/useHoldToOpen.js +84 -0
  359. package/dist/features/lottery/repository/lottery-entry.repository.d.ts +18 -3
  360. package/dist/features/lottery/repository/lottery-entry.repository.js +48 -6
  361. package/dist/features/lottery/schemas/firestore.d.ts +33 -5
  362. package/dist/features/loyalty/api/balance/route.js +1 -1
  363. package/dist/features/loyalty/api/history/route.js +1 -1
  364. package/dist/features/media/MediaImage.js +0 -1
  365. package/dist/features/media/MediaPickerModal.js +7 -1
  366. package/dist/features/media/modals/ImageEditor.js +5 -1
  367. package/dist/features/media/modals/VideoThumbnailSelector.js +17 -1
  368. package/dist/features/media/repository/media-assets.repository.d.ts +19 -0
  369. package/dist/features/media/upload/CameraCapture.js +16 -1
  370. package/dist/features/media/upload/ImageUpload.js +42 -4
  371. package/dist/features/media/upload/MediaUploadField.js +69 -13
  372. package/dist/features/media/upload/downscale-image.d.ts +56 -0
  373. package/dist/features/media/upload/downscale-image.js +150 -0
  374. package/dist/features/messages/components/ConversationThreadView.js +45 -2
  375. package/dist/features/messages/components/MessageSellerButton.d.ts +15 -1
  376. package/dist/features/messages/components/MessageSellerButton.js +10 -2
  377. package/dist/features/messages/schemas/firestore.d.ts +15 -0
  378. package/dist/features/orders/hooks/useOrders.js +4 -2
  379. package/dist/features/orders/repository/orders.repository.d.ts +15 -4
  380. package/dist/features/orders/repository/orders.repository.js +52 -20
  381. package/dist/features/orders/schemas/firestore.d.ts +15 -4
  382. package/dist/features/orders/schemas/index.d.ts +8 -8
  383. package/dist/features/orders/types/index.d.ts +2 -2
  384. package/dist/features/payments/repository/payments.repository.js +2 -2
  385. package/dist/features/payments/repository/payout.repository.d.ts +23 -6
  386. package/dist/features/payments/repository/payout.repository.js +63 -23
  387. package/dist/features/payments/repository/saved-payment-methods.repository.d.ts +17 -6
  388. package/dist/features/payments/repository/saved-payment-methods.repository.js +59 -11
  389. package/dist/features/payments/schemas/firestore.d.ts +14 -3
  390. package/dist/features/payments/schemas/saved-methods-firestore.d.ts +12 -1
  391. package/dist/features/pre-orders/api/[slug]/route.js +1 -1
  392. package/dist/features/pre-orders/api/admin/route.js +1 -1
  393. package/dist/features/pre-orders/api/route.js +1 -1
  394. package/dist/features/pre-orders/repository/pre-orders.repository.d.ts +3 -3
  395. package/dist/features/pre-orders/repository/pre-orders.repository.js +6 -6
  396. package/dist/features/products/api/[id]/route.js +1 -1
  397. package/dist/features/products/components/ListingBottomActions.js +4 -0
  398. package/dist/features/products/components/ProductDetailPageView.js +2 -1
  399. package/dist/features/products/components/ProductGalleryClient.js +2 -2
  400. package/dist/features/products/components/ProductGrid.js +12 -1
  401. package/dist/features/products/components/index.d.ts +0 -2
  402. package/dist/features/products/components/index.js +0 -1
  403. package/dist/features/products/config/listing-type-listing-config.d.ts +0 -3
  404. package/dist/features/products/config/listing-type-listing-config.js +27 -2
  405. package/dist/features/products/constants/listing-tabs.d.ts +9 -0
  406. package/dist/features/products/constants/listing-tabs.js +3 -2
  407. package/dist/features/products/hooks/useProducts.js +2 -2
  408. package/dist/features/products/repository/products.repository.js +13 -1
  409. package/dist/features/products/schemas/index.d.ts +2 -2
  410. package/dist/features/products/types/index.d.ts +1 -1
  411. package/dist/features/promotions/api/route.js +1 -1
  412. package/dist/features/reviews/actions/review-actions.d.ts +6 -6
  413. package/dist/features/reviews/actions/review-actions.js +22 -8
  414. package/dist/features/reviews/components/ReviewDetailPageView.js +13 -1
  415. package/dist/features/reviews/components/ReviewsIndexPageView.js +21 -4
  416. package/dist/features/reviews/repository/reviews.repository.d.ts +19 -7
  417. package/dist/features/reviews/repository/reviews.repository.js +63 -12
  418. package/dist/features/reviews/schemas/firestore.d.ts +13 -2
  419. package/dist/features/reviews/schemas/index.d.ts +2 -2
  420. package/dist/features/scams/actions/scam-actions.js +16 -4
  421. package/dist/features/search/components/SearchResultsPageView.js +2 -1
  422. package/dist/features/search/hooks/useSearchIndex.d.ts +34 -0
  423. package/dist/features/search/hooks/useSearchIndex.js +172 -0
  424. package/dist/features/search/repository/search.repository.js +2 -2
  425. package/dist/features/seller/actions/offer-actions.d.ts +5 -5
  426. package/dist/features/seller/actions/offer-actions.js +38 -8
  427. package/dist/features/seller/actions/seller-actions.js +34 -7
  428. package/dist/features/seller/api/coupons/route.js +1 -1
  429. package/dist/features/seller/api/products/route.js +1 -1
  430. package/dist/features/seller/api/store/route.js +1 -1
  431. package/dist/features/seller/components/SellerBidsView.js +1 -1
  432. package/dist/features/seller/components/SellerCouponsView.js +1 -1
  433. package/dist/features/seller/components/SellerListingTypeView.js +9 -1
  434. package/dist/features/seller/components/SellerOrdersView.js +1 -1
  435. package/dist/features/seller/components/SellerPayoutSettingsView.js +0 -1
  436. package/dist/features/seller/components/SellerPayoutsView.js +1 -1
  437. package/dist/features/seller/components/SellerProductShell.js +0 -1
  438. package/dist/features/seller/components/SellerProductsView.js +1 -1
  439. package/dist/features/seller/components/SellerShippingView.js +0 -1
  440. package/dist/features/seller/components/SellerStorefrontView.js +0 -1
  441. package/dist/features/seller/components/index.d.ts +0 -4
  442. package/dist/features/seller/components/index.js +0 -2
  443. package/dist/features/seller/repository/offer.repository.d.ts +15 -3
  444. package/dist/features/seller/repository/offer.repository.js +43 -7
  445. package/dist/features/seller/schemas/firestore.d.ts +14 -3
  446. package/dist/features/seller/schemas/index.d.ts +4 -4
  447. package/dist/features/seller/schemas/order-forms.d.ts +39 -0
  448. package/dist/features/seller/schemas/order-forms.js +37 -0
  449. package/dist/features/shell/FormShell.js +6 -2
  450. package/dist/features/shell/QuickFormDrawer.js +15 -1
  451. package/dist/features/shipments/components/AdminShipmentEditorView.js +0 -1
  452. package/dist/features/shipments/components/AdminShipmentsView.js +1 -1
  453. package/dist/features/sticker-trace/components/StickerCommitPanel.d.ts +30 -0
  454. package/dist/features/sticker-trace/components/StickerCommitPanel.js +93 -0
  455. package/dist/features/sticker-trace/components/StickerPrintPanel.d.ts +33 -0
  456. package/dist/features/sticker-trace/components/StickerPrintPanel.js +104 -0
  457. package/dist/features/sticker-trace/components/StickerRetryPanel.d.ts +20 -0
  458. package/dist/features/sticker-trace/components/StickerRetryPanel.js +128 -0
  459. package/dist/features/sticker-trace/components/StickerRunHistoryPanel.d.ts +45 -0
  460. package/dist/features/sticker-trace/components/StickerRunHistoryPanel.js +84 -0
  461. package/dist/features/sticker-trace/components/StickerTraceStudio.d.ts +27 -0
  462. package/dist/features/sticker-trace/components/StickerTraceStudio.js +171 -0
  463. package/dist/features/sticker-trace/constants/help-content.d.ts +23 -0
  464. package/dist/features/sticker-trace/constants/help-content.js +172 -0
  465. package/dist/features/sticker-trace/hooks/useLiveTrace.d.ts +27 -0
  466. package/dist/features/sticker-trace/hooks/useLiveTrace.js +160 -0
  467. package/dist/features/sticker-trace/hooks/useStickerTraceProgress.d.ts +22 -0
  468. package/dist/features/sticker-trace/hooks/useStickerTraceProgress.js +106 -0
  469. package/dist/features/sticker-trace/repository/sticker-sheets.repository.d.ts +113 -0
  470. package/dist/features/sticker-trace/repository/sticker-sheets.repository.js +146 -0
  471. package/dist/features/sticker-trace/repository/sticker-trace-runs.repository.d.ts +132 -0
  472. package/dist/features/sticker-trace/repository/sticker-trace-runs.repository.js +174 -0
  473. package/dist/features/sticker-trace/schemas/firestore.d.ts +248 -0
  474. package/dist/features/sticker-trace/schemas/firestore.js +79 -0
  475. package/dist/features/sticker-trace/server.d.ts +8 -0
  476. package/dist/features/sticker-trace/server.js +51 -0
  477. package/dist/features/stores/actions/store-query-actions.d.ts +2 -2
  478. package/dist/features/stores/actions/store-query-actions.js +7 -2
  479. package/dist/features/stores/api/[storeSlug]/auctions/route.js +3 -3
  480. package/dist/features/stores/api/[storeSlug]/products/route.js +3 -3
  481. package/dist/features/stores/api/[storeSlug]/reviews/route.js +1 -1
  482. package/dist/features/stores/api/[storeSlug]/route.js +1 -1
  483. package/dist/features/stores/components/StoreNavTabs.js +17 -2
  484. package/dist/features/stores/manifest.js +8 -4
  485. package/dist/features/support/repository/support.repository.d.ts +14 -3
  486. package/dist/features/support/repository/support.repository.js +93 -13
  487. package/dist/features/support/schemas/firestore.d.ts +16 -5
  488. package/dist/features/tester/seed-data/authored/admin__events-raffles-spin.js +61 -19
  489. package/dist/features/tester/seed-data/authored/buying__browsing-search.js +19 -3
  490. package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.d.ts +2 -0
  491. package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.js +243 -0
  492. package/dist/features/tester/seed-data/authored/content-discovery__events.js +36 -10
  493. package/dist/features/tester/seed-data/authored/content-discovery__overflowing-pill-rows.d.ts +2 -0
  494. package/dist/features/tester/seed-data/authored/content-discovery__overflowing-pill-rows.js +209 -0
  495. package/dist/features/tester/seed-data/authored/design-ux__header-brand-mark-centring.d.ts +2 -0
  496. package/dist/features/tester/seed-data/authored/design-ux__header-brand-mark-centring.js +90 -0
  497. package/dist/features/tester/seed-data/authored/design-ux__header-controls-and-messages.d.ts +2 -0
  498. package/dist/features/tester/seed-data/authored/design-ux__header-controls-and-messages.js +85 -0
  499. package/dist/features/tester/seed-data/authored/index.js +10 -0
  500. package/dist/features/tester/seed-data/authored/selling__media-limits.js +19 -17
  501. package/dist/features/tester/seed-data/authored/selling__product-upload-details.js +10 -5
  502. package/dist/features/tester/seed-data/authored/tools__sticker-tracer.d.ts +2 -0
  503. package/dist/features/tester/seed-data/authored/tools__sticker-tracer.js +283 -0
  504. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +235 -22
  505. package/dist/index.d.ts +10 -23
  506. package/dist/index.js +27 -19
  507. package/dist/next/api/routeHandler.js +9 -0
  508. package/dist/next/routing/require-record.d.ts +13 -0
  509. package/dist/next/routing/require-record.js +62 -0
  510. package/dist/next/routing/route-map.d.ts +4 -4
  511. package/dist/next/routing/route-map.js +25 -3
  512. package/dist/providers/db-firebase/base.d.ts +4 -2
  513. package/dist/providers/db-firebase/base.js +21 -5
  514. package/dist/providers/db-firebase/base.repository.d.ts +11 -9
  515. package/dist/providers/db-firebase/base.repository.js +19 -0
  516. package/dist/providers/db-firebase/rtdb-paths.d.ts +12 -0
  517. package/dist/providers/db-firebase/rtdb-paths.js +12 -0
  518. package/dist/react/ErrorBoundary.js +6 -1
  519. package/dist/react/hooks/realtime-event-constants.d.ts +1 -0
  520. package/dist/react/hooks/realtime-event-constants.js +8 -0
  521. package/dist/react/hooks/useEntityDelete.js +5 -1
  522. package/dist/react/hooks/useMessage.js +5 -1
  523. package/dist/repositories/index.d.ts +2 -2
  524. package/dist/repositories/index.js +6 -1
  525. package/dist/schemas/registry.d.ts +13 -20
  526. package/dist/schemas/registry.js +31 -14
  527. package/dist/schemas/webhooks/google-oauth.d.ts +2 -2
  528. package/dist/security/encrypted.d.ts +117 -0
  529. package/dist/security/encrypted.js +100 -0
  530. package/dist/security/index.d.ts +5 -2
  531. package/dist/security/index.js +16 -2
  532. package/dist/security/pii-accessors.d.ts +71 -0
  533. package/dist/security/pii-accessors.js +150 -0
  534. package/dist/security/pii-encrypt.d.ts +0 -8
  535. package/dist/security/pii-encrypt.js +22 -15
  536. package/dist/security/pii-mask.d.ts +18 -0
  537. package/dist/security/pii-mask.js +27 -0
  538. package/dist/seed/_helpers/search-txt-wrappers.d.ts +6 -6
  539. package/dist/seed/_helpers/search-txt-wrappers.js +22 -0
  540. package/dist/seed/addresses-seed-data.d.ts +2 -2
  541. package/dist/seed/authenticity-knowledge-seed-data.d.ts +34 -0
  542. package/dist/seed/authenticity-knowledge-seed-data.js +1277 -0
  543. package/dist/seed/bids-seed-data.d.ts +2 -2
  544. package/dist/seed/bids-seed-data.js +23 -2
  545. package/dist/seed/events-seed-data.d.ts +2 -2
  546. package/dist/seed/events-seed-data.js +5 -0
  547. package/dist/seed/faq-seed-data.js +175 -5
  548. package/dist/seed/homepage-sections-seed-data.js +39 -23
  549. package/dist/seed/index.d.ts +1 -0
  550. package/dist/seed/index.js +1 -0
  551. package/dist/seed/lottery-entries-seed-data.d.ts +2 -2
  552. package/dist/seed/offers-seed-data.d.ts +2 -2
  553. package/dist/seed/offers-seed-data.js +1 -1
  554. package/dist/seed/orders-seed-data.d.ts +2 -2
  555. package/dist/seed/payouts-seed-data.d.ts +2 -2
  556. package/dist/seed/payouts-seed-data.js +1 -1
  557. package/dist/seed/reviews-seed-data.d.ts +1 -2
  558. package/dist/seed/seed-purpose.js +7 -0
  559. package/dist/seed/sessions-seed-data.d.ts +2 -2
  560. package/dist/seed/sessions-seed-data.js +5 -0
  561. package/dist/seed/site-settings-seed-data.js +1 -1
  562. package/dist/seed/support-tickets-seed-data.d.ts +2 -2
  563. package/dist/seed/support-tickets-seed-data.js +1 -1
  564. package/dist/seed/users-seed-data.d.ts +2 -2
  565. package/dist/seed/users-seed-data.js +1 -1
  566. package/dist/seo/json-ld.js +5 -1
  567. package/dist/server.d.ts +18 -3
  568. package/dist/server.js +59 -3
  569. package/dist/styles.css +237 -1
  570. package/dist/tailwind-utilities.css +1 -1
  571. package/dist/ui/components/Button.js +7 -1
  572. package/dist/ui/components/FilterChipGroup.d.ts +11 -0
  573. package/dist/ui/components/FilterChipGroup.js +1 -1
  574. package/dist/ui/components/ImageGallery.js +6 -1
  575. package/dist/ui/components/ListingLayout.js +14 -8
  576. package/dist/ui/components/OverflowRow.d.ts +92 -0
  577. package/dist/ui/components/OverflowRow.js +203 -0
  578. package/dist/ui/components/OverflowRow.style.css +235 -0
  579. package/dist/ui/components/RecordDetailModal.js +14 -1
  580. package/dist/ui/components/RowActionMenu.js +5 -1
  581. package/dist/ui/components/SideDrawer.js +5 -1
  582. package/dist/ui/components/SideModal.js +9 -1
  583. package/dist/ui/components/TabBarShell.d.ts +12 -1
  584. package/dist/ui/components/TabBarShell.js +3 -2
  585. package/dist/ui/components/Tabs.js +36 -24
  586. package/dist/ui/components/Toast.d.ts +3 -24
  587. package/dist/ui/components/Toast.js +2 -19
  588. package/dist/ui/components/TopBannerPortal.d.ts +15 -0
  589. package/dist/ui/components/TopBannerPortal.js +19 -0
  590. package/dist/ui/components/UnsavedChangesModal.js +5 -1
  591. package/dist/ui/components/index.style.css +1 -0
  592. package/dist/ui/components/row-collapse.d.ts +15 -0
  593. package/dist/ui/components/row-collapse.js +127 -0
  594. package/dist/ui/components/toast-context.d.ts +63 -0
  595. package/dist/ui/components/toast-context.js +48 -0
  596. package/dist/ui/components/top-banner-slot.d.ts +37 -0
  597. package/dist/ui/components/top-banner-slot.js +45 -0
  598. package/dist/ui/icons/icon-registry.d.ts +6 -0
  599. package/dist/ui/icons/icon-registry.js +17 -1
  600. package/dist/ui/index.d.ts +2 -0
  601. package/dist/ui/index.js +1 -0
  602. package/dist/utils/array.helper.d.ts +2 -2
  603. package/dist/utils/array.helper.js +5 -5
  604. package/dist/utils/id-generators.d.ts +6 -0
  605. package/dist/utils/id-generators.js +10 -0
  606. package/dist/utils/media-url.js +0 -2
  607. package/dist/utils/search-txt-builders.d.ts +28 -4
  608. package/dist/utils/search-txt-builders.js +41 -1
  609. package/dist/validation/schemas.d.ts +8 -8
  610. package/package.json +6 -2
  611. package/scripts/seed-cli.mjs +3 -0
  612. package/dist/features/account/components/UserAddressesView.d.ts +0 -13
  613. package/dist/features/account/components/UserAddressesView.js +0 -5
  614. package/dist/features/account/components/UserNotificationsView.d.ts +0 -15
  615. package/dist/features/account/components/UserNotificationsView.js +0 -12
  616. package/dist/features/account/components/UserSettingsView.d.ts +0 -16
  617. package/dist/features/account/components/UserSettingsView.js +0 -13
  618. package/dist/features/account/components/UserSupportView.d.ts +0 -3
  619. package/dist/features/account/components/UserSupportView.js +0 -166
  620. package/dist/features/admin/components/DemoSeedView.d.ts +0 -11
  621. package/dist/features/admin/components/DemoSeedView.js +0 -5
  622. package/dist/features/auth/components/AuthStatusPanel.d.ts +0 -10
  623. package/dist/features/auth/components/AuthStatusPanel.js +0 -22
  624. package/dist/features/categories/components/CategoryProductsView.d.ts +0 -45
  625. package/dist/features/categories/components/CategoryProductsView.js +0 -21
  626. package/dist/features/homepage/components/HowItWorksInfoView.d.ts +0 -36
  627. package/dist/features/homepage/components/HowItWorksInfoView.js +0 -10
  628. package/dist/features/layout/BottomActions.d.ts +0 -1
  629. package/dist/features/layout/BottomActions.js +0 -311
  630. package/dist/features/products/components/ProductsView.d.ts +0 -6
  631. package/dist/features/products/components/ProductsView.js +0 -5
  632. package/dist/features/seller/components/SellerStoreView.d.ts +0 -8
  633. package/dist/features/seller/components/SellerStoreView.js +0 -8
@@ -0,0 +1,156 @@
1
+ /*
2
+ * WHY: Segmentation ends with "which pixels belong to the same sticker". That is
3
+ * connected-component labelling, and it is needed three times — once for
4
+ * the parts themselves, once to find the background region the flood
5
+ * reached, and once to cluster parts into physical sheets.
6
+ * WHAT: Two-pass CCL over a binary mask with union-find, returning labels plus
7
+ * per-component area and bounding box in one walk.
8
+ *
9
+ * 4-connectivity, deliberately. Under 8-connectivity two stickers touching at a
10
+ * single diagonal pixel — which a hysteresis-linked ridge map produces fairly
11
+ * often — merge into one component and therefore one cut path, and the sheet
12
+ * leaves the cutter in one piece. Losing a genuine 1px diagonal bridge inside a
13
+ * sticker is the cheaper error, and the bridge closing (see trace/segment)
14
+ * repairs that case on purpose.
15
+ *
16
+ * EXPORTS: LabelResult, ComponentStats, labelComponents
17
+ *
18
+ * @tag domain:sticker-trace
19
+ * @tag layer:shared
20
+ * @tag pattern:none
21
+ * @tag access:isomorphic
22
+ * @tag consumers:segment,cluster,flood,geometry
23
+ * @tag sideEffects:none
24
+ */
25
+ /**
26
+ * Union-find with path halving and union by size.
27
+ *
28
+ * Path halving rather than full compression because it is a single extra array
29
+ * write in the find loop and gets the same near-constant amortised behaviour —
30
+ * on a 9 MP raster the difference in allocation churn is worth more than the
31
+ * theoretical constant.
32
+ */
33
+ class UnionFind {
34
+ constructor(capacity) {
35
+ this.parent = new Int32Array(capacity);
36
+ this.size = new Int32Array(capacity);
37
+ }
38
+ make(x) {
39
+ this.parent[x] = x;
40
+ this.size[x] = 1;
41
+ }
42
+ find(x) {
43
+ let root = x;
44
+ while (this.parent[root] !== root) {
45
+ this.parent[root] = this.parent[this.parent[root]];
46
+ root = this.parent[root];
47
+ }
48
+ return root;
49
+ }
50
+ union(a, b) {
51
+ let ra = this.find(a);
52
+ let rb = this.find(b);
53
+ if (ra === rb)
54
+ return;
55
+ if (this.size[ra] < this.size[rb]) {
56
+ const t = ra;
57
+ ra = rb;
58
+ rb = t;
59
+ }
60
+ this.parent[rb] = ra;
61
+ this.size[ra] = this.size[ra] + this.size[rb];
62
+ }
63
+ }
64
+ export function labelComponents(mask, width, height) {
65
+ const labels = new Int32Array(width * height);
66
+ // Worst case is a checkerboard: every other pixel its own provisional label.
67
+ const uf = new UnionFind(Math.ceil((width * height) / 2) + 2);
68
+ let next = 1;
69
+ // Pass 1 — provisional labels, recording equivalences.
70
+ for (let y = 0; y < height; y++) {
71
+ const row = y * width;
72
+ for (let x = 0; x < width; x++) {
73
+ const i = row + x;
74
+ if (!mask[i])
75
+ continue;
76
+ const left = x > 0 && mask[i - 1] ? labels[i - 1] : 0;
77
+ const up = y > 0 && mask[i - width] ? labels[i - width] : 0;
78
+ if (left && up) {
79
+ labels[i] = left;
80
+ if (left !== up)
81
+ uf.union(left, up);
82
+ }
83
+ else if (left) {
84
+ labels[i] = left;
85
+ }
86
+ else if (up) {
87
+ labels[i] = up;
88
+ }
89
+ else {
90
+ uf.make(next);
91
+ labels[i] = next;
92
+ next++;
93
+ }
94
+ }
95
+ }
96
+ // Pass 2 — resolve to roots, renumber densely, and accumulate stats in the
97
+ // same walk. A separate stats pass would be a second full traversal of a
98
+ // 9 MP buffer for numbers we already have in hand.
99
+ const remap = new Int32Array(next);
100
+ const areas = [];
101
+ const minX = [];
102
+ const minY = [];
103
+ const maxX = [];
104
+ const maxY = [];
105
+ const border = [];
106
+ let count = 0;
107
+ for (let y = 0; y < height; y++) {
108
+ const row = y * width;
109
+ for (let x = 0; x < width; x++) {
110
+ const i = row + x;
111
+ if (!labels[i])
112
+ continue;
113
+ const root = uf.find(labels[i]);
114
+ let dense = remap[root];
115
+ if (dense === 0) {
116
+ count++;
117
+ dense = count;
118
+ remap[root] = dense;
119
+ areas.push(0);
120
+ minX.push(x);
121
+ minY.push(y);
122
+ maxX.push(x);
123
+ maxY.push(y);
124
+ border.push(false);
125
+ }
126
+ labels[i] = dense;
127
+ const k = dense - 1;
128
+ areas[k] = areas[k] + 1;
129
+ if (x < minX[k])
130
+ minX[k] = x;
131
+ if (y < minY[k])
132
+ minY[k] = y;
133
+ if (x > maxX[k])
134
+ maxX[k] = x;
135
+ if (y > maxY[k])
136
+ maxY[k] = y;
137
+ if (x === 0 || y === 0 || x === width - 1 || y === height - 1)
138
+ border[k] = true;
139
+ }
140
+ }
141
+ const stats = [];
142
+ for (let k = 0; k < count; k++) {
143
+ stats.push({
144
+ label: k + 1,
145
+ area: areas[k],
146
+ bbox: {
147
+ x: minX[k],
148
+ y: minY[k],
149
+ width: maxX[k] - minX[k] + 1,
150
+ height: maxY[k] - minY[k] + 1,
151
+ },
152
+ touchesBorder: border[k],
153
+ });
154
+ }
155
+ return { labels, count, stats };
156
+ }
@@ -0,0 +1,16 @@
1
+ import type { Point } from "../types";
2
+ export interface Ring {
3
+ readonly points: readonly Point[];
4
+ /** Signed area; positive is counter-clockwise in image coordinates. */
5
+ readonly signedArea: number;
6
+ /** True when the ring closed back on itself, which every valid cut path must. */
7
+ readonly closed: boolean;
8
+ }
9
+ /**
10
+ * Extract every closed ring at `iso`.
11
+ *
12
+ * `field` may be the binary mask itself or a blurred copy; both are read as
13
+ * numbers, and the iso level decides. Rings shorter than 8 points are dropped —
14
+ * at this scale they are single-pixel speckle, never a sticker.
15
+ */
16
+ export declare function traceContours(field: Uint8Array | Float32Array, width: number, height: number, iso?: number): Ring[];
@@ -0,0 +1,242 @@
1
+ /*
2
+ * WHY: A cut path is a closed outline, and the segmentation produces a raster
3
+ * mask. Turning one into the other has to be exact about closure: a ring
4
+ * that fails to close is a cut the machine starts and never finishes, and
5
+ * a ring that self-intersects is a nick in the sticker.
6
+ * WHAT: Marching squares at an iso level, linked into guaranteed-closed rings.
7
+ *
8
+ * Linking is done by EDGE IDENTITY, not by coordinate proximity. Each cell
9
+ * boundary crossing lands on one specific grid edge, and adjacent cells
10
+ * produce the identical edge id — so chaining is exact integer bookkeeping
11
+ * rather than "are these two floats close enough", which is the usual source
12
+ * of a contour that almost closes.
13
+ *
14
+ * EXPORTS: Ring, traceContours
15
+ *
16
+ * @tag domain:sticker-trace
17
+ * @tag layer:shared
18
+ * @tag pattern:none
19
+ * @tag access:isomorphic
20
+ * @tag consumers:geometry
21
+ * @tag sideEffects:none
22
+ */
23
+ /**
24
+ * Grid edges are identified rather than located.
25
+ *
26
+ * A horizontal edge spans (x,y)->(x+1,y); a vertical edge spans (x,y)->(x,y+1).
27
+ * Two cells sharing a boundary compute the SAME id, which is what makes ring
28
+ * assembly exact.
29
+ */
30
+ function hEdge(x, y, width) {
31
+ return (y * width + x) * 2;
32
+ }
33
+ function vEdge(x, y, width) {
34
+ return (y * width + x) * 2 + 1;
35
+ }
36
+ /**
37
+ * Where the iso level crosses between two samples.
38
+ *
39
+ * On a binary mask this always returns the midpoint, which is the correct
40
+ * half-pixel "crack" between set and unset. On a smoothed field it returns a
41
+ * genuine sub-pixel position — which is the entire difference the `precise`
42
+ * and `max` tiers buy, and why they blur before tracing rather than tracing
43
+ * harder.
44
+ */
45
+ function lerp(a, b, iso) {
46
+ const d = b - a;
47
+ if (Math.abs(d) < 1e-9)
48
+ return 0.5;
49
+ const t = (iso - a) / d;
50
+ return t < 0 ? 0 : t > 1 ? 1 : t;
51
+ }
52
+ /**
53
+ * Cases 5 and 10 are the SADDLES: two diagonal corners inside, two outside.
54
+ *
55
+ * Both have two geometrically valid pairings, and the one chosen decides
56
+ * whether the two regions pinch together at this cell or stay apart. Choosing
57
+ * inconsistently across neighbouring cells produces rings that cross
58
+ * themselves, which survives every later stage — RDP simplifies it, the Bézier
59
+ * fit smooths it, and it emerges as a cut path that doubles back.
60
+ *
61
+ * Resolve by the cell's MEAN, which keeps the choice continuous with the
62
+ * surrounding field instead of arbitrary.
63
+ *
64
+ * 🛑 The two codes take OPPOSITE pairings for the same centre value — they are
65
+ * mirror configurations. Sharing one branch without the inversion would join
66
+ * the wrong corners on half of all saddles, and the output would still be a
67
+ * plausible set of closed rings.
68
+ *
69
+ * Extracted from the switch rather than inlined: at that depth it tripped
70
+ * `audit-code-quality`'s DEEP_NESTING, and the two cases had independently
71
+ * re-derived the same mean.
72
+ *
73
+ * 🛑 MEASURED 2026-10-18: this branch is NOT REACHED by any of the reference
74
+ * scans, at `standard` or at `precise`. Inverting the rule on purpose changed
75
+ * nothing — not part counts, not total Bézier node counts, not closure — on
76
+ * five scans at both tiers. The reason is upstream: `close` and
77
+ * `curvatureSmooth` eliminate the checkerboard-like local patterns a true
78
+ * diagonal saddle requires, and `softenForSubPixel`'s blur removes what little
79
+ * survives.
80
+ *
81
+ * So the correctness of the inversion rests on INSPECTION (all four
82
+ * code×centre combinations hand-checked), never on measurement. Do not read
83
+ * the corpus harness agreeing with itself as evidence about this function.
84
+ * It is kept because a future tier that traces a less-smoothed field, or any
85
+ * path that skips the cleaning stages, reaches it immediately — and because
86
+ * the failure it prevents is a self-crossing cut path, which survives RDP and
87
+ * the Bézier fit and emerges looking like a plausible outline.
88
+ */
89
+ function connectSaddle(code, corners, iso, edges, connect) {
90
+ const mean = (corners.tl + corners.tr + corners.br + corners.bl) / 4;
91
+ const centreInside = mean >= iso;
92
+ const joinLeftToTop = code === 5 ? centreInside : !centreInside;
93
+ if (joinLeftToTop) {
94
+ connect(edges.left, edges.top);
95
+ connect(edges.bottom, edges.right);
96
+ }
97
+ else {
98
+ connect(edges.left, edges.bottom);
99
+ connect(edges.top, edges.right);
100
+ }
101
+ }
102
+ /**
103
+ * Extract every closed ring at `iso`.
104
+ *
105
+ * `field` may be the binary mask itself or a blurred copy; both are read as
106
+ * numbers, and the iso level decides. Rings shorter than 8 points are dropped —
107
+ * at this scale they are single-pixel speckle, never a sticker.
108
+ */
109
+ export function traceContours(field, width, height, iso = 0.5) {
110
+ // edge id -> the interpolated point on that edge
111
+ const points = new Map();
112
+ // edge id -> the edge ids it is connected to (at most 2)
113
+ const links = new Map();
114
+ const connect = (a, b) => {
115
+ const la = links.get(a);
116
+ if (la)
117
+ la.push(b);
118
+ else
119
+ links.set(a, [b]);
120
+ const lb = links.get(b);
121
+ if (lb)
122
+ lb.push(a);
123
+ else
124
+ links.set(b, [a]);
125
+ };
126
+ const at = (x, y) => field[y * width + x];
127
+ for (let y = 0; y < height - 1; y++) {
128
+ for (let x = 0; x < width - 1; x++) {
129
+ const tl = at(x, y);
130
+ const tr = at(x + 1, y);
131
+ const br = at(x + 1, y + 1);
132
+ const bl = at(x, y + 1);
133
+ const code = (tl >= iso ? 8 : 0) | (tr >= iso ? 4 : 0) | (br >= iso ? 2 : 0) | (bl >= iso ? 1 : 0);
134
+ if (code === 0 || code === 15)
135
+ continue;
136
+ const top = hEdge(x, y, width);
137
+ const right = vEdge(x + 1, y, width);
138
+ const bottom = hEdge(x, y + 1, width);
139
+ const left = vEdge(x, y, width);
140
+ if (!points.has(top))
141
+ points.set(top, { x: x + lerp(tl, tr, iso), y });
142
+ if (!points.has(right))
143
+ points.set(right, { x: x + 1, y: y + lerp(tr, br, iso) });
144
+ if (!points.has(bottom))
145
+ points.set(bottom, { x: x + lerp(bl, br, iso), y: y + 1 });
146
+ if (!points.has(left))
147
+ points.set(left, { x, y: y + lerp(tl, bl, iso) });
148
+ switch (code) {
149
+ case 1:
150
+ case 14:
151
+ connect(left, bottom);
152
+ break;
153
+ case 2:
154
+ case 13:
155
+ connect(bottom, right);
156
+ break;
157
+ case 3:
158
+ case 12:
159
+ connect(left, right);
160
+ break;
161
+ case 4:
162
+ case 11:
163
+ connect(top, right);
164
+ break;
165
+ case 6:
166
+ case 9:
167
+ connect(top, bottom);
168
+ break;
169
+ case 7:
170
+ case 8:
171
+ connect(left, top);
172
+ break;
173
+ /*
174
+ * The two saddles — see `connectSaddle` for why they are not one case.
175
+ *
176
+ * Split rather than shared so each passes a LITERAL: `code` is a
177
+ * `number` here (it comes out of a bitwise OR), so a shared
178
+ * `case 5: case 10:` would not narrow it and the helper would have to
179
+ * accept `number` — making 7 a representable argument for a function
180
+ * that has no correct answer for it.
181
+ */
182
+ case 5:
183
+ connectSaddle(5, { tl, tr, br, bl }, iso, { top, right, bottom, left }, connect);
184
+ break;
185
+ case 10:
186
+ connectSaddle(10, { tl, tr, br, bl }, iso, { top, right, bottom, left }, connect);
187
+ break;
188
+ default:
189
+ break;
190
+ }
191
+ }
192
+ }
193
+ const visited = new Set();
194
+ const rings = [];
195
+ for (const startEdge of links.keys()) {
196
+ if (visited.has(startEdge))
197
+ continue;
198
+ const chain = [];
199
+ let current = startEdge;
200
+ let previous = -1;
201
+ let closed = false;
202
+ for (;;) {
203
+ visited.add(current);
204
+ const p = points.get(current);
205
+ if (p)
206
+ chain.push(p);
207
+ const neighbours = links.get(current);
208
+ if (!neighbours)
209
+ break;
210
+ let nextEdge = -1;
211
+ for (const n of neighbours) {
212
+ if (n === previous)
213
+ continue;
214
+ if (n === startEdge && chain.length > 2) {
215
+ closed = true;
216
+ break;
217
+ }
218
+ if (!visited.has(n)) {
219
+ nextEdge = n;
220
+ break;
221
+ }
222
+ }
223
+ if (closed || nextEdge === -1)
224
+ break;
225
+ previous = current;
226
+ current = nextEdge;
227
+ }
228
+ if (chain.length < 8)
229
+ continue;
230
+ rings.push({ points: chain, signedArea: shoelace(chain), closed });
231
+ }
232
+ return rings;
233
+ }
234
+ function shoelace(points) {
235
+ let sum = 0;
236
+ for (let i = 0; i < points.length; i++) {
237
+ const a = points[i];
238
+ const b = points[(i + 1) % points.length];
239
+ sum += a.x * b.y - b.x * a.y;
240
+ }
241
+ return sum / 2;
242
+ }
@@ -0,0 +1,46 @@
1
+ /** Outward offset by a true Euclidean radius, in pixels. */
2
+ export declare function dilate(mask: Uint8Array, width: number, height: number, radius: number): Uint8Array;
3
+ /**
4
+ * Inward offset. Note this erodes against the mask's complement, so pixels
5
+ * outside the raster count as background — a component touching the edge
6
+ * erodes inward from that edge too, which is what the de-halo pass wants.
7
+ */
8
+ export declare function erode(mask: Uint8Array, width: number, height: number, radius: number): Uint8Array;
9
+ /** Erode then dilate — removes speckle smaller than the disc. */
10
+ export declare function open(mask: Uint8Array, width: number, height: number, radius: number): Uint8Array;
11
+ /**
12
+ * Dilate then erode — bridges channels narrower than 2*radius.
13
+ *
14
+ * This is how a sticker that thresholding split in two is rejoined: a white
15
+ * band reaching the sticker's outer edge is not an enclosed hole, so no
16
+ * hole-filling can recover it, and the sticker would otherwise arrive as two
17
+ * components with two cut paths. The radius must sit between the widest
18
+ * intra-sticker band and the narrowest real gap between neighbours — measure
19
+ * both before changing it.
20
+ */
21
+ export declare function close(mask: Uint8Array, width: number, height: number, radius: number): Uint8Array;
22
+ /**
23
+ * Curvature-smooth a silhouette.
24
+ *
25
+ * A scan rings at every ink/paper boundary, and thresholding that gradient
26
+ * freezes the ringing into the mask as comb teeth a few tenths of a millimetre
27
+ * deep. A blade traces every one of them.
28
+ *
29
+ * 🛑 This is NOT an open/close pair at the same radius, and the difference is
30
+ * the point. Blurring then re-thresholding at 0.5 is a curvature flow: it
31
+ * erases high-frequency teeth while leaving the edge where it was. An
32
+ * open/close pair at the same radius rounds REAL corners much harder for the
33
+ * same despeckling — on these sheets that visibly blunts the points of every
34
+ * claw-shaped sticker.
35
+ */
36
+ export declare function curvatureSmooth(mask: Uint8Array, width: number, height: number, radius: number): Uint8Array;
37
+ /**
38
+ * The radius of the largest disc that fits inside the component — i.e. half its
39
+ * narrowest neck.
40
+ *
41
+ * Cricut's minimum reliable detail is 0.25in; a part whose neck is below that
42
+ * tears rather than cuts. Measuring it is one EDT over the component mask and
43
+ * a max, so it is cheap enough to report for every part rather than only on
44
+ * request.
45
+ */
46
+ export declare function minFeatureRadius(mask: Uint8Array, width: number, height: number): number;
@@ -0,0 +1,168 @@
1
+ /*
2
+ * WHY: The old Python tracer used scipy's structuring elements, and the two
3
+ * operations that mattered most — the bleed offset and the curvature
4
+ * smoothing — were both documented there as needing a TRUE disc rather
5
+ * than a square kernel, because a blade rounds convex corners the way a
6
+ * circle does and not the way a 3x3 box does.
7
+ * WHAT: Morphology expressed as distance-transform thresholds, which gives an
8
+ * exact disc of any radius at no extra cost and in O(n) regardless of
9
+ * radius — a separable box kernel cannot do the first and a naive disc
10
+ * kernel cannot do the second.
11
+ *
12
+ * The identity this file rests on: dilate(mask, r) is exactly "every pixel
13
+ * within r of a set pixel", i.e. edt(¬mask) <= r. Erosion is the dual on the
14
+ * complement. Open and close are then the usual compositions, and because the
15
+ * radius never enters a loop bound, a 20px disc costs the same as a 2px one.
16
+ *
17
+ * EXPORTS: dilate, erode, open, close, curvatureSmooth, minFeatureRadius
18
+ *
19
+ * @tag domain:sticker-trace
20
+ * @tag layer:shared
21
+ * @tag pattern:none
22
+ * @tag access:isomorphic
23
+ * @tag consumers:segment,geometry,ridge,flood
24
+ * @tag sideEffects:none
25
+ */
26
+ import { edtSquared } from "./edt.js";
27
+ function invert(mask) {
28
+ const out = new Uint8Array(mask.length);
29
+ for (let i = 0; i < mask.length; i++)
30
+ out[i] = mask[i] ? 0 : 1;
31
+ return out;
32
+ }
33
+ /** Outward offset by a true Euclidean radius, in pixels. */
34
+ export function dilate(mask, width, height, radius) {
35
+ if (radius <= 0)
36
+ return mask.slice();
37
+ const dist = edtSquared(mask, width, height);
38
+ const r2 = radius * radius;
39
+ const out = new Uint8Array(mask.length);
40
+ for (let i = 0; i < out.length; i++)
41
+ out[i] = dist[i] <= r2 ? 1 : 0;
42
+ return out;
43
+ }
44
+ /**
45
+ * Inward offset. Note this erodes against the mask's complement, so pixels
46
+ * outside the raster count as background — a component touching the edge
47
+ * erodes inward from that edge too, which is what the de-halo pass wants.
48
+ */
49
+ export function erode(mask, width, height, radius) {
50
+ if (radius <= 0)
51
+ return mask.slice();
52
+ const dist = edtSquared(invert(mask), width, height);
53
+ const r2 = radius * radius;
54
+ const out = new Uint8Array(mask.length);
55
+ for (let i = 0; i < out.length; i++)
56
+ out[i] = dist[i] > r2 ? 1 : 0;
57
+ return out;
58
+ }
59
+ /** Erode then dilate — removes speckle smaller than the disc. */
60
+ export function open(mask, width, height, radius) {
61
+ if (radius <= 0)
62
+ return mask.slice();
63
+ return dilate(erode(mask, width, height, radius), width, height, radius);
64
+ }
65
+ /**
66
+ * Dilate then erode — bridges channels narrower than 2*radius.
67
+ *
68
+ * This is how a sticker that thresholding split in two is rejoined: a white
69
+ * band reaching the sticker's outer edge is not an enclosed hole, so no
70
+ * hole-filling can recover it, and the sticker would otherwise arrive as two
71
+ * components with two cut paths. The radius must sit between the widest
72
+ * intra-sticker band and the narrowest real gap between neighbours — measure
73
+ * both before changing it.
74
+ */
75
+ export function close(mask, width, height, radius) {
76
+ if (radius <= 0)
77
+ return mask.slice();
78
+ return erode(dilate(mask, width, height, radius), width, height, radius);
79
+ }
80
+ /**
81
+ * Curvature-smooth a silhouette.
82
+ *
83
+ * A scan rings at every ink/paper boundary, and thresholding that gradient
84
+ * freezes the ringing into the mask as comb teeth a few tenths of a millimetre
85
+ * deep. A blade traces every one of them.
86
+ *
87
+ * 🛑 This is NOT an open/close pair at the same radius, and the difference is
88
+ * the point. Blurring then re-thresholding at 0.5 is a curvature flow: it
89
+ * erases high-frequency teeth while leaving the edge where it was. An
90
+ * open/close pair at the same radius rounds REAL corners much harder for the
91
+ * same despeckling — on these sheets that visibly blunts the points of every
92
+ * claw-shaped sticker.
93
+ */
94
+ export function curvatureSmooth(mask, width, height, radius) {
95
+ if (radius < 0.5)
96
+ return mask.slice();
97
+ const pre = open(mask, width, height, radius * 0.5);
98
+ const blurred = gaussianBlur(pre, width, height, radius);
99
+ const out = new Uint8Array(mask.length);
100
+ for (let i = 0; i < out.length; i++)
101
+ out[i] = blurred[i] >= 0.5 ? 1 : 0;
102
+ return out;
103
+ }
104
+ /**
105
+ * Separable Gaussian over a binary mask, returning floats in 0..1.
106
+ *
107
+ * Separable because a 2-D kernel at radius 6 is 169 multiplies per pixel
108
+ * against 26 for two 1-D passes, and on a 9 MP raster that is the difference
109
+ * between a noticeable pause and none.
110
+ */
111
+ function gaussianBlur(mask, width, height, sigma) {
112
+ const radius = Math.max(1, Math.ceil(sigma * 3));
113
+ const kernel = new Float32Array(radius * 2 + 1);
114
+ const denom = 2 * sigma * sigma;
115
+ let sum = 0;
116
+ for (let i = -radius; i <= radius; i++) {
117
+ const v = Math.exp(-(i * i) / denom);
118
+ kernel[i + radius] = v;
119
+ sum += v;
120
+ }
121
+ for (let i = 0; i < kernel.length; i++)
122
+ kernel[i] = kernel[i] / sum;
123
+ const tmp = new Float32Array(width * height);
124
+ const out = new Float32Array(width * height);
125
+ for (let y = 0; y < height; y++) {
126
+ const row = y * width;
127
+ for (let x = 0; x < width; x++) {
128
+ let acc = 0;
129
+ for (let k = -radius; k <= radius; k++) {
130
+ // Clamp at the edge rather than wrapping or zero-padding: zero-padding
131
+ // pulls the silhouette inward at the raster border, which on a scan
132
+ // whose sheet runs to the edge would shave the outermost stickers.
133
+ const sx = Math.min(width - 1, Math.max(0, x + k));
134
+ acc += mask[row + sx] * kernel[k + radius];
135
+ }
136
+ tmp[row + x] = acc;
137
+ }
138
+ }
139
+ for (let x = 0; x < width; x++) {
140
+ for (let y = 0; y < height; y++) {
141
+ let acc = 0;
142
+ for (let k = -radius; k <= radius; k++) {
143
+ const sy = Math.min(height - 1, Math.max(0, y + k));
144
+ acc += tmp[sy * width + x] * kernel[k + radius];
145
+ }
146
+ out[y * width + x] = acc;
147
+ }
148
+ }
149
+ return out;
150
+ }
151
+ /**
152
+ * The radius of the largest disc that fits inside the component — i.e. half its
153
+ * narrowest neck.
154
+ *
155
+ * Cricut's minimum reliable detail is 0.25in; a part whose neck is below that
156
+ * tears rather than cuts. Measuring it is one EDT over the component mask and
157
+ * a max, so it is cheap enough to report for every part rather than only on
158
+ * request.
159
+ */
160
+ export function minFeatureRadius(mask, width, height) {
161
+ const dist = edtSquared(invert(mask), width, height);
162
+ let max = 0;
163
+ for (let i = 0; i < dist.length; i++) {
164
+ if (mask[i] && dist[i] > max)
165
+ max = dist[i];
166
+ }
167
+ return Math.sqrt(max);
168
+ }