@mohasinac/appkit 4.52.5 → 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.
- package/dist/.build-stamp.json +4 -4
- package/dist/_internal/client/features/sticker-trace/canvas-codec.d.ts +2 -0
- package/dist/_internal/client/features/sticker-trace/canvas-codec.js +148 -0
- package/dist/_internal/server/features/auctions/actions.js +1 -1
- package/dist/_internal/server/features/categories/data.js +23 -7
- package/dist/_internal/server/features/checkout/actions.js +10 -3
- package/dist/_internal/server/features/checkout/data.d.ts +15 -0
- package/dist/_internal/server/features/checkout/data.js +20 -3
- package/dist/_internal/server/features/lottery/actions.js +9 -1
- package/dist/_internal/server/features/lottery/og.d.ts +40 -0
- package/dist/_internal/server/features/lottery/og.js +79 -0
- package/dist/_internal/server/features/messages/actions.js +4 -0
- package/dist/_internal/server/features/offers/adapters.js +17 -3
- package/dist/_internal/server/features/orders/actions.js +7 -2
- package/dist/_internal/server/features/raffle/actions.d.ts +19 -0
- package/dist/_internal/server/features/raffle/actions.js +25 -0
- package/dist/_internal/server/features/reviews/actions.js +1 -1
- package/dist/_internal/server/features/reviews/data.d.ts +1 -1
- package/dist/_internal/server/features/search/index-build/artifact-store.d.ts +89 -0
- package/dist/_internal/server/features/search/index-build/artifact-store.js +208 -0
- package/dist/_internal/server/features/search/index-build/build.d.ts +57 -0
- package/dist/_internal/server/features/search/index-build/build.js +285 -0
- package/dist/_internal/server/features/search/index-build/sources.d.ts +53 -0
- package/dist/_internal/server/features/search/index-build/sources.js +385 -0
- package/dist/_internal/server/features/search/search-sources.d.ts +0 -15
- package/dist/_internal/server/features/search/search-sources.js +142 -7
- package/dist/_internal/server/features/seo/robots.js +21 -1
- package/dist/_internal/server/features/seo/sitemap.js +1 -1
- package/dist/_internal/server/features/shared/listing-data-factory.js +16 -4
- package/dist/_internal/server/features/site-settings/adapters.d.ts +1 -1
- package/dist/_internal/server/features/site-settings/adapters.js +26 -0
- package/dist/_internal/server/features/sticker-trace/actions.d.ts +109 -0
- package/dist/_internal/server/features/sticker-trace/actions.js +172 -0
- package/dist/_internal/server/features/sticker-trace/adapters.d.ts +80 -0
- package/dist/_internal/server/features/sticker-trace/adapters.js +174 -0
- package/dist/_internal/server/features/sticker-trace/build-cut-file.d.ts +26 -0
- package/dist/_internal/server/features/sticker-trace/build-cut-file.js +127 -0
- package/dist/_internal/server/features/sticker-trace/coordinator.d.ts +27 -0
- package/dist/_internal/server/features/sticker-trace/coordinator.js +169 -0
- package/dist/_internal/server/features/sticker-trace/fanout.d.ts +43 -0
- package/dist/_internal/server/features/sticker-trace/fanout.js +180 -0
- package/dist/_internal/server/features/sticker-trace/finalizer.d.ts +25 -0
- package/dist/_internal/server/features/sticker-trace/finalizer.js +123 -0
- package/dist/_internal/server/features/sticker-trace/mosaic-inputs.d.ts +30 -0
- package/dist/_internal/server/features/sticker-trace/mosaic-inputs.js +112 -0
- package/dist/_internal/server/features/sticker-trace/progress.d.ts +81 -0
- package/dist/_internal/server/features/sticker-trace/progress.js +198 -0
- package/dist/_internal/server/features/sticker-trace/promote.d.ts +23 -0
- package/dist/_internal/server/features/sticker-trace/promote.js +193 -0
- package/dist/_internal/server/features/sticker-trace/shard.d.ts +50 -0
- package/dist/_internal/server/features/sticker-trace/shard.js +174 -0
- package/dist/_internal/server/features/sticker-trace/sheet-actions.d.ts +141 -0
- package/dist/_internal/server/features/sticker-trace/sheet-actions.js +279 -0
- package/dist/_internal/server/features/sticker-trace/storage.d.ts +135 -0
- package/dist/_internal/server/features/sticker-trace/storage.js +282 -0
- package/dist/_internal/server/functions/scheduled.d.ts +2 -1
- package/dist/_internal/server/functions/scheduled.js +25 -1
- package/dist/_internal/server/jobs/core/_event-ref.d.ts +51 -0
- package/dist/_internal/server/jobs/core/_event-ref.js +63 -0
- package/dist/_internal/server/jobs/core/assignSpinPrize.d.ts +18 -0
- package/dist/_internal/server/jobs/core/assignSpinPrize.js +77 -16
- package/dist/_internal/server/jobs/core/auctionSettlement.js +13 -4
- package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +44 -15
- package/dist/_internal/server/jobs/core/bundleStockSync.js +3 -4
- package/dist/_internal/server/jobs/core/cleanupRtdbEvents.js +44 -0
- package/dist/_internal/server/jobs/core/event-draw-reasons.d.ts +78 -0
- package/dist/_internal/server/jobs/core/event-draw-reasons.js +133 -0
- package/dist/_internal/server/jobs/core/listingProcessor.js +28 -8
- package/dist/_internal/server/jobs/core/onOrderCreate.js +12 -1
- package/dist/_internal/server/jobs/core/onScamReportCreate.js +13 -2
- package/dist/_internal/server/jobs/core/onScamReportRejected.js +8 -2
- package/dist/_internal/server/jobs/core/onScamReportVerified.js +8 -2
- package/dist/_internal/server/jobs/core/onStoreWrite.js +11 -4
- package/dist/_internal/server/jobs/core/prizeDrawAssignWinner.js +5 -4
- package/dist/_internal/server/jobs/core/prizeDrawExpiryReveal.js +1 -4
- package/dist/_internal/server/jobs/core/prizeDrawSoldOutReveal.js +1 -2
- package/dist/_internal/server/jobs/core/promotions.js +7 -4
- package/dist/_internal/server/jobs/core/searchIndexBuild.d.ts +7 -0
- package/dist/_internal/server/jobs/core/searchIndexBuild.js +211 -0
- package/dist/_internal/server/jobs/core/triggerEventRaffle.d.ts +35 -0
- package/dist/_internal/server/jobs/core/triggerEventRaffle.js +213 -31
- package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +20 -14
- package/dist/_internal/server/jobs/handlers/assignSpinPrize.d.ts +8 -0
- package/dist/_internal/server/jobs/handlers/assignSpinPrize.js +15 -15
- package/dist/_internal/server/jobs/handlers/index.d.ts +1 -0
- package/dist/_internal/server/jobs/handlers/index.js +1 -0
- package/dist/_internal/server/jobs/handlers/onCategoryWrite.js +18 -0
- package/dist/_internal/server/jobs/handlers/onProductWrite.js +18 -0
- package/dist/_internal/server/jobs/handlers/onReviewWrite.js +18 -0
- package/dist/_internal/server/jobs/handlers/onScamReportUpdate.js +18 -0
- package/dist/_internal/server/jobs/handlers/onStoreWrite.js +18 -0
- package/dist/_internal/server/jobs/handlers/searchIndexBuild.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/searchIndexBuild.js +2 -0
- package/dist/_internal/server/jobs/handlers/triggerEventRaffle.d.ts +8 -0
- package/dist/_internal/server/jobs/handlers/triggerEventRaffle.js +15 -6
- package/dist/_internal/shared/actions/action-registry.js +29 -0
- package/dist/_internal/shared/cache/revalidate-targets.d.ts +0 -1
- package/dist/_internal/shared/cache/revalidate-targets.js +10 -8
- package/dist/_internal/shared/features/events/config.d.ts +14 -0
- package/dist/_internal/shared/features/events/config.js +14 -0
- package/dist/_internal/shared/features/notifications/action-url.js +8 -0
- package/dist/_internal/shared/features/site-settings/types.d.ts +11 -0
- package/dist/_internal/shared/features/sticker-trace/codec.d.ts +81 -0
- package/dist/_internal/shared/features/sticker-trace/codec.js +30 -0
- package/dist/_internal/shared/features/sticker-trace/config.d.ts +81 -0
- package/dist/_internal/shared/features/sticker-trace/config.js +177 -0
- package/dist/_internal/shared/features/sticker-trace/cut-contour.d.ts +20 -0
- package/dist/_internal/shared/features/sticker-trace/cut-contour.js +60 -0
- package/dist/_internal/shared/features/sticker-trace/export/build-export-set.d.ts +65 -0
- package/dist/_internal/shared/features/sticker-trace/export/build-export-set.js +176 -0
- package/dist/_internal/shared/features/sticker-trace/export/cut-svg.d.ts +56 -0
- package/dist/_internal/shared/features/sticker-trace/export/cut-svg.js +120 -0
- package/dist/_internal/shared/features/sticker-trace/export/machine-profiles.d.ts +92 -0
- package/dist/_internal/shared/features/sticker-trace/export/machine-profiles.js +153 -0
- package/dist/_internal/shared/features/sticker-trace/export/nesting.d.ts +51 -0
- package/dist/_internal/shared/features/sticker-trace/export/nesting.js +110 -0
- package/dist/_internal/shared/features/sticker-trace/export/page-sizes.d.ts +68 -0
- package/dist/_internal/shared/features/sticker-trace/export/page-sizes.js +223 -0
- package/dist/_internal/shared/features/sticker-trace/export/part-tiling.d.ts +51 -0
- package/dist/_internal/shared/features/sticker-trace/export/part-tiling.js +178 -0
- package/dist/_internal/shared/features/sticker-trace/export/simplify-budget.d.ts +26 -0
- package/dist/_internal/shared/features/sticker-trace/export/simplify-budget.js +134 -0
- package/dist/_internal/shared/features/sticker-trace/export/vectorise-art.d.ts +40 -0
- package/dist/_internal/shared/features/sticker-trace/export/vectorise-art.js +195 -0
- package/dist/_internal/shared/features/sticker-trace/index.d.ts +2 -0
- package/dist/_internal/shared/features/sticker-trace/index.js +59 -0
- package/dist/_internal/shared/features/sticker-trace/math/catmull-rom.d.ts +11 -0
- package/dist/_internal/shared/features/sticker-trace/math/catmull-rom.js +66 -0
- package/dist/_internal/shared/features/sticker-trace/math/edt.d.ts +27 -0
- package/dist/_internal/shared/features/sticker-trace/math/edt.js +165 -0
- package/dist/_internal/shared/features/sticker-trace/math/label.d.ts +15 -0
- package/dist/_internal/shared/features/sticker-trace/math/label.js +156 -0
- package/dist/_internal/shared/features/sticker-trace/math/marching-squares.d.ts +16 -0
- package/dist/_internal/shared/features/sticker-trace/math/marching-squares.js +242 -0
- package/dist/_internal/shared/features/sticker-trace/math/morphology.d.ts +46 -0
- package/dist/_internal/shared/features/sticker-trace/math/morphology.js +168 -0
- package/dist/_internal/shared/features/sticker-trace/math/rasterize-path.d.ts +88 -0
- package/dist/_internal/shared/features/sticker-trace/math/rasterize-path.js +286 -0
- package/dist/_internal/shared/features/sticker-trace/math/rdp.d.ts +10 -0
- package/dist/_internal/shared/features/sticker-trace/math/rdp.js +74 -0
- package/dist/_internal/shared/features/sticker-trace/resume.d.ts +50 -0
- package/dist/_internal/shared/features/sticker-trace/resume.js +160 -0
- package/dist/_internal/shared/features/sticker-trace/trace/cluster.d.ts +20 -0
- package/dist/_internal/shared/features/sticker-trace/trace/cluster.js +132 -0
- package/dist/_internal/shared/features/sticker-trace/trace/cross-profile.d.ts +28 -0
- package/dist/_internal/shared/features/sticker-trace/trace/cross-profile.js +120 -0
- package/dist/_internal/shared/features/sticker-trace/trace/flood.d.ts +21 -0
- package/dist/_internal/shared/features/sticker-trace/trace/flood.js +104 -0
- package/dist/_internal/shared/features/sticker-trace/trace/geometry.d.ts +3 -0
- package/dist/_internal/shared/features/sticker-trace/trace/geometry.js +140 -0
- package/dist/_internal/shared/features/sticker-trace/trace/line-filter.d.ts +15 -0
- package/dist/_internal/shared/features/sticker-trace/trace/line-filter.js +138 -0
- package/dist/_internal/shared/features/sticker-trace/trace/merge.d.ts +27 -0
- package/dist/_internal/shared/features/sticker-trace/trace/merge.js +187 -0
- package/dist/_internal/shared/features/sticker-trace/trace/paper.d.ts +32 -0
- package/dist/_internal/shared/features/sticker-trace/trace/paper.js +147 -0
- package/dist/_internal/shared/features/sticker-trace/trace/prefilter.d.ts +30 -0
- package/dist/_internal/shared/features/sticker-trace/trace/prefilter.js +125 -0
- package/dist/_internal/shared/features/sticker-trace/trace/quantise.d.ts +10 -0
- package/dist/_internal/shared/features/sticker-trace/trace/quantise.js +153 -0
- package/dist/_internal/shared/features/sticker-trace/trace/ridge.d.ts +88 -0
- package/dist/_internal/shared/features/sticker-trace/trace/ridge.js +344 -0
- package/dist/_internal/shared/features/sticker-trace/trace/segment.d.ts +10 -0
- package/dist/_internal/shared/features/sticker-trace/trace/segment.js +251 -0
- package/dist/_internal/shared/features/sticker-trace/types.d.ts +197 -0
- package/dist/_internal/shared/features/sticker-trace/types.js +49 -0
- package/dist/_internal/shared/listing-types/_registry.d.ts +11 -0
- package/dist/_internal/shared/listing-types/art/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/art/config.js +1 -0
- package/dist/_internal/shared/listing-types/auction/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/auction/config.js +1 -0
- package/dist/_internal/shared/listing-types/classified/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/classified/config.js +1 -0
- package/dist/_internal/shared/listing-types/digital-code/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/digital-code/config.js +1 -0
- package/dist/_internal/shared/listing-types/feature-flags.d.ts +7 -0
- package/dist/_internal/shared/listing-types/feature-flags.js +9 -0
- package/dist/_internal/shared/listing-types/live/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/live/config.js +1 -0
- package/dist/_internal/shared/listing-types/pre-order/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/pre-order/config.js +1 -0
- package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/prize-draw/config.js +1 -0
- package/dist/_internal/shared/listing-types/standard/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/standard/config.js +1 -0
- package/dist/_internal/shared/listing-types/stickers/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/stickers/config.js +1 -0
- package/dist/_internal/shared/media/limits.d.ts +12 -2
- package/dist/_internal/shared/media/limits.js +12 -2
- package/dist/_internal/shared/search/artifact-url.d.ts +35 -0
- package/dist/_internal/shared/search/artifact-url.js +119 -0
- package/dist/_internal/shared/search/index-record.d.ts +68 -0
- package/dist/_internal/shared/search/index-record.js +96 -0
- package/dist/_internal/shared/search/match.d.ts +65 -0
- package/dist/_internal/shared/search/match.js +263 -0
- package/dist/client.d.ts +8 -7
- package/dist/client.js +12 -5
- package/dist/configs/eslint.js +22 -2
- package/dist/constants/api-endpoints.d.ts +68 -0
- package/dist/constants/api-endpoints.js +32 -0
- package/dist/constants/field-names.d.ts +7 -1
- package/dist/constants/field-names.js +36 -1
- package/dist/contracts/repository.d.ts +8 -7
- package/dist/contracts/search.d.ts +2 -2
- package/dist/contracts/table.d.ts +3 -3
- package/dist/contracts/table.js +3 -3
- package/dist/core/contact-submissions.repository.js +2 -2
- package/dist/core/integration-keys.js +7 -1
- package/dist/core/newsletter.repository.js +2 -2
- package/dist/core/site-config.js +1 -1
- package/dist/errors/error-codes.d.ts +30 -0
- package/dist/errors/error-codes.js +30 -0
- package/dist/errors/error-display-map.js +40 -1
- package/dist/features/account/api/[userId]/addresses/route.js +1 -1
- package/dist/features/account/components/UserBidsView.js +1 -1
- package/dist/features/account/components/index.d.ts +0 -8
- package/dist/features/account/components/index.js +0 -4
- package/dist/features/addresses/repository/addresses.repository.d.ts +17 -6
- package/dist/features/addresses/repository/addresses.repository.js +65 -9
- package/dist/features/addresses/schemas/firestore.d.ts +17 -6
- package/dist/features/admin/actions/notification-actions.js +15 -6
- package/dist/features/admin/api/bids/route.js +1 -1
- package/dist/features/admin/api/coupons/route.js +1 -1
- package/dist/features/admin/api/products/route.js +1 -1
- package/dist/features/admin/api/reviews/route.js +1 -1
- package/dist/features/admin/components/AdminAdEditorView.js +19 -5
- package/dist/features/admin/components/AdminAuditLogView.js +1 -1
- package/dist/features/admin/components/AdminBlogEditorView.js +0 -1
- package/dist/features/admin/components/AdminBlogView.js +1 -1
- package/dist/features/admin/components/AdminBrandsView.js +17 -1
- package/dist/features/admin/components/AdminCategoryEditorView.js +0 -1
- package/dist/features/admin/components/AdminContactView.js +1 -1
- package/dist/features/admin/components/AdminEmployeeEditorView.js +1 -3
- package/dist/features/admin/components/AdminNewsletterView.js +1 -1
- package/dist/features/admin/components/AdminOrdersView.js +9 -2
- package/dist/features/admin/components/AdminPayoutsView.js +1 -1
- package/dist/features/admin/components/AdminPrizeDrawsView.js +11 -0
- package/dist/features/admin/components/AdminProductEditorView.d.ts +10 -1
- package/dist/features/admin/components/AdminProductEditorView.js +24 -37
- package/dist/features/admin/components/AdminProductsView.js +10 -3
- package/dist/features/admin/components/AdminScammersView.js +1 -1
- package/dist/features/admin/components/AdminSectionsView.js +21 -5
- package/dist/features/admin/components/AdminSessionsView.js +1 -1
- package/dist/features/admin/components/AdminSublistingCategoriesView.js +22 -1
- package/dist/features/admin/components/AdminTeamView.js +1 -1
- package/dist/features/admin/components/AdminTesterChecklistItemEditorView.js +0 -1
- package/dist/features/admin/components/AdminUsersView.js +1 -1
- package/dist/features/admin/components/DataListingView.d.ts +2 -1
- package/dist/features/admin/components/DataListingView.js +9 -4
- package/dist/features/admin/components/analytics/AdminPageViewsReportView.js +0 -2
- package/dist/features/admin/hooks/useAdminListing.d.ts +1 -1
- package/dist/features/admin/repository/site-settings.repository.js +8 -3
- package/dist/features/admin/schemas/firestore.d.ts +62 -1
- package/dist/features/admin/schemas/firestore.js +32 -0
- package/dist/features/admin/types/index.d.ts +1 -1
- package/dist/features/auctions/actions/bid-actions.d.ts +2 -2
- package/dist/features/auctions/actions/bid-actions.js +16 -4
- package/dist/features/auctions/api/route.js +1 -1
- package/dist/features/auctions/components/AuctionBottomActions.js +4 -0
- package/dist/features/auctions/repository/bid.repository.d.ts +46 -4
- package/dist/features/auctions/repository/bid.repository.js +114 -13
- package/dist/features/auctions/schemas/firestore.d.ts +24 -4
- package/dist/features/auctions/schemas/firestore.js +1 -0
- package/dist/features/auth/actions/profile-actions.js +30 -4
- package/dist/features/auth/components/index.d.ts +0 -1
- package/dist/features/auth/components/index.js +0 -1
- package/dist/features/auth/repository/session.repository.d.ts +17 -3
- package/dist/features/auth/repository/session.repository.js +46 -5
- package/dist/features/auth/repository/token.repository.d.ts +27 -4
- package/dist/features/auth/repository/token.repository.js +65 -11
- package/dist/features/auth/repository/user.repository.d.ts +33 -7
- package/dist/features/auth/repository/user.repository.js +100 -15
- package/dist/features/auth/schemas/firestore.d.ts +63 -12
- package/dist/features/auth/schemas/firestore.js +11 -0
- package/dist/features/before-after/api/route.js +1 -1
- package/dist/features/blog/components/BlogListView.js +16 -3
- package/dist/features/blog/components/BlogPostView.js +1 -1
- package/dist/features/blog/schemas/index.d.ts +2 -2
- package/dist/features/cart/api/route.js +1 -1
- package/dist/features/catalogue/repository/catalogue.repository.d.ts +7 -7
- package/dist/features/catalogue/repository/catalogue.repository.js +28 -10
- package/dist/features/catalogue/schemas/firestore.d.ts +11 -0
- package/dist/features/categories/api/route.js +10 -10
- package/dist/features/categories/components/CategoryDetailPageView.js +35 -5
- package/dist/features/categories/components/CategorySelectorCreate.js +0 -1
- package/dist/features/categories/components/index.d.ts +0 -2
- package/dist/features/categories/components/index.js +0 -1
- package/dist/features/categories/repository/categories.repository.d.ts +1 -0
- package/dist/features/categories/repository/categories.repository.js +31 -1
- package/dist/features/categories/schemas/index.d.ts +2 -2
- package/dist/features/categories/utils/taxonomy-visual.d.ts +21 -0
- package/dist/features/categories/utils/taxonomy-visual.js +58 -0
- package/dist/features/checkout/actions/checkout-value-otp-actions.js +8 -1
- package/dist/features/collections/api/[slug]/route.js +3 -3
- package/dist/features/collections/api/route.js +1 -1
- package/dist/features/consultation/api/route.js +1 -1
- package/dist/features/consultation/repository/consultations.repository.js +1 -1
- package/dist/features/consultation/types/index.d.ts +1 -1
- package/dist/features/contact/components/ContactForm.js +1 -3
- package/dist/features/corporate/api/route.js +1 -1
- package/dist/features/corporate/repository/corporate.repository.js +1 -1
- package/dist/features/corporate/types/index.d.ts +1 -1
- package/dist/features/cron/jobs/auction-expiry.job.js +1 -1
- package/dist/features/cron/jobs/preorder-reminder.job.js +1 -1
- package/dist/features/events/actions/event-actions.d.ts +14 -0
- package/dist/features/events/actions/event-actions.js +82 -3
- package/dist/features/events/api/[id]/route.js +2 -2
- package/dist/features/events/components/AdminEventEditorView.js +22 -3
- package/dist/features/events/components/AdminEventsView.js +32 -8
- package/dist/features/events/components/EventRafflesSection.d.ts +34 -1
- package/dist/features/events/components/EventRafflesSection.js +52 -3
- package/dist/features/events/components/SpinWheelView.d.ts +2 -2
- package/dist/features/events/components/SpinWheelView.js +41 -4
- package/dist/features/events/repository/event-entry.repository.d.ts +14 -2
- package/dist/features/events/repository/event-entry.repository.js +41 -7
- package/dist/features/events/schemas/firestore.d.ts +17 -4
- package/dist/features/events/types/index.d.ts +37 -0
- package/dist/features/faq/repository/faqs.repository.js +1 -1
- package/dist/features/faq/schemas/index.d.ts +5 -2
- package/dist/features/faq/schemas/index.js +6 -0
- package/dist/features/faq/types/index.d.ts +0 -1
- package/dist/features/grouped/components/GroupedListingEditorView.js +17 -2
- package/dist/features/homepage/api/carousel/[id]/route.js +1 -1
- package/dist/features/homepage/api/carousel/route.js +4 -4
- package/dist/features/homepage/api/route.js +2 -2
- package/dist/features/homepage/api/sections/route.js +1 -1
- package/dist/features/homepage/components/AnnouncementBar.d.ts +1 -9
- package/dist/features/homepage/components/AnnouncementBar.js +13 -19
- package/dist/features/homepage/components/MarketplaceHomepageView.js +6 -1
- package/dist/features/homepage/components/index.d.ts +0 -2
- package/dist/features/homepage/components/index.js +0 -1
- package/dist/features/homepage/repository/homepage.repository.js +1 -1
- package/dist/features/homepage/schemas/firestore.d.ts +6 -0
- package/dist/features/homepage/schemas/index.d.ts +10 -10
- package/dist/features/layout/AppLayoutShell.d.ts +11 -0
- package/dist/features/layout/AppLayoutShell.js +64 -12
- package/dist/features/layout/BottomActionsContext.d.ts +16 -0
- package/dist/features/layout/BottomActionsContext.js +5 -0
- package/dist/features/layout/BottomChrome.js +48 -9
- package/dist/features/layout/BottomNavbar.d.ts +14 -0
- package/dist/features/layout/BottomNavbar.js +43 -3
- package/dist/features/layout/MainNavbar.d.ts +11 -0
- package/dist/features/layout/NavbarLayout.d.ts +3 -0
- package/dist/features/layout/NavbarLayout.js +88 -11
- package/dist/features/layout/SideActionDock.d.ts +1 -0
- package/dist/features/layout/SideActionDock.js +219 -0
- package/dist/features/layout/TitleBarLayout.js +1 -1
- package/dist/features/layout/cta-anchor.d.ts +31 -0
- package/dist/features/layout/cta-anchor.js +31 -0
- package/dist/features/layout/hooks/useBottomActions.d.ts +7 -0
- package/dist/features/layout/hooks/useBottomActions.js +6 -1
- package/dist/features/layout/index.d.ts +9 -1
- package/dist/features/layout/index.js +9 -1
- package/dist/features/layout/useCtaReveal.d.ts +24 -0
- package/dist/features/layout/useCtaReveal.js +82 -0
- package/dist/features/layout/useHoldToOpen.d.ts +41 -0
- package/dist/features/layout/useHoldToOpen.js +84 -0
- package/dist/features/lottery/repository/lottery-entry.repository.d.ts +18 -3
- package/dist/features/lottery/repository/lottery-entry.repository.js +48 -6
- package/dist/features/lottery/schemas/firestore.d.ts +33 -5
- package/dist/features/loyalty/api/balance/route.js +1 -1
- package/dist/features/loyalty/api/history/route.js +1 -1
- package/dist/features/media/MediaImage.js +0 -1
- package/dist/features/media/MediaPickerModal.js +7 -1
- package/dist/features/media/modals/ImageEditor.js +5 -1
- package/dist/features/media/modals/VideoThumbnailSelector.js +17 -1
- package/dist/features/media/repository/media-assets.repository.d.ts +19 -0
- package/dist/features/media/upload/CameraCapture.js +16 -1
- package/dist/features/media/upload/ImageUpload.js +42 -4
- package/dist/features/media/upload/MediaUploadField.js +69 -13
- package/dist/features/media/upload/downscale-image.d.ts +56 -0
- package/dist/features/media/upload/downscale-image.js +150 -0
- package/dist/features/messages/components/ConversationThreadView.js +45 -2
- package/dist/features/messages/components/MessageSellerButton.d.ts +15 -1
- package/dist/features/messages/components/MessageSellerButton.js +10 -2
- package/dist/features/messages/schemas/firestore.d.ts +15 -0
- package/dist/features/orders/hooks/useOrders.js +4 -2
- package/dist/features/orders/repository/orders.repository.d.ts +15 -4
- package/dist/features/orders/repository/orders.repository.js +52 -20
- package/dist/features/orders/schemas/firestore.d.ts +15 -4
- package/dist/features/orders/schemas/index.d.ts +8 -8
- package/dist/features/orders/types/index.d.ts +2 -2
- package/dist/features/payments/repository/payments.repository.js +2 -2
- package/dist/features/payments/repository/payout.repository.d.ts +23 -6
- package/dist/features/payments/repository/payout.repository.js +63 -23
- package/dist/features/payments/repository/saved-payment-methods.repository.d.ts +17 -6
- package/dist/features/payments/repository/saved-payment-methods.repository.js +59 -11
- package/dist/features/payments/schemas/firestore.d.ts +14 -3
- package/dist/features/payments/schemas/saved-methods-firestore.d.ts +12 -1
- package/dist/features/pre-orders/api/[slug]/route.js +1 -1
- package/dist/features/pre-orders/api/admin/route.js +1 -1
- package/dist/features/pre-orders/api/route.js +1 -1
- package/dist/features/pre-orders/repository/pre-orders.repository.d.ts +3 -3
- package/dist/features/pre-orders/repository/pre-orders.repository.js +6 -6
- package/dist/features/products/api/[id]/route.js +1 -1
- package/dist/features/products/components/ListingBottomActions.js +4 -0
- package/dist/features/products/components/ProductDetailPageView.js +2 -1
- package/dist/features/products/components/ProductGalleryClient.js +2 -2
- package/dist/features/products/components/ProductGrid.js +12 -1
- package/dist/features/products/components/index.d.ts +0 -2
- package/dist/features/products/components/index.js +0 -1
- package/dist/features/products/config/listing-type-listing-config.d.ts +0 -3
- package/dist/features/products/config/listing-type-listing-config.js +27 -2
- package/dist/features/products/constants/listing-tabs.d.ts +9 -0
- package/dist/features/products/constants/listing-tabs.js +3 -2
- package/dist/features/products/hooks/useProducts.js +2 -2
- package/dist/features/products/repository/products.repository.js +13 -1
- package/dist/features/products/schemas/index.d.ts +2 -2
- package/dist/features/products/types/index.d.ts +1 -1
- package/dist/features/promotions/api/route.js +1 -1
- package/dist/features/reviews/actions/review-actions.d.ts +6 -6
- package/dist/features/reviews/actions/review-actions.js +22 -8
- package/dist/features/reviews/components/ReviewDetailPageView.js +13 -1
- package/dist/features/reviews/components/ReviewsIndexPageView.js +21 -4
- package/dist/features/reviews/repository/reviews.repository.d.ts +19 -7
- package/dist/features/reviews/repository/reviews.repository.js +63 -12
- package/dist/features/reviews/schemas/firestore.d.ts +13 -2
- package/dist/features/reviews/schemas/index.d.ts +2 -2
- package/dist/features/scams/actions/scam-actions.js +16 -4
- package/dist/features/search/components/SearchResultsPageView.js +2 -1
- package/dist/features/search/hooks/useSearchIndex.d.ts +34 -0
- package/dist/features/search/hooks/useSearchIndex.js +172 -0
- package/dist/features/search/repository/search.repository.js +2 -2
- package/dist/features/seller/actions/offer-actions.d.ts +5 -5
- package/dist/features/seller/actions/offer-actions.js +38 -8
- package/dist/features/seller/actions/seller-actions.js +34 -7
- package/dist/features/seller/api/coupons/route.js +1 -1
- package/dist/features/seller/api/products/route.js +1 -1
- package/dist/features/seller/api/store/route.js +1 -1
- package/dist/features/seller/components/SellerBidsView.js +1 -1
- package/dist/features/seller/components/SellerCouponsView.js +1 -1
- package/dist/features/seller/components/SellerListingTypeView.js +9 -1
- package/dist/features/seller/components/SellerOrdersView.js +1 -1
- package/dist/features/seller/components/SellerPayoutSettingsView.js +0 -1
- package/dist/features/seller/components/SellerPayoutsView.js +1 -1
- package/dist/features/seller/components/SellerProductShell.js +0 -1
- package/dist/features/seller/components/SellerProductsView.js +1 -1
- package/dist/features/seller/components/SellerShippingView.js +0 -1
- package/dist/features/seller/components/SellerStorefrontView.js +0 -1
- package/dist/features/seller/components/index.d.ts +0 -4
- package/dist/features/seller/components/index.js +0 -2
- package/dist/features/seller/repository/offer.repository.d.ts +15 -3
- package/dist/features/seller/repository/offer.repository.js +43 -7
- package/dist/features/seller/schemas/firestore.d.ts +14 -3
- package/dist/features/seller/schemas/index.d.ts +4 -4
- package/dist/features/seller/schemas/order-forms.d.ts +39 -0
- package/dist/features/seller/schemas/order-forms.js +37 -0
- package/dist/features/shell/FormShell.js +6 -2
- package/dist/features/shell/QuickFormDrawer.js +15 -1
- package/dist/features/shipments/components/AdminShipmentEditorView.js +0 -1
- package/dist/features/shipments/components/AdminShipmentsView.js +1 -1
- package/dist/features/sticker-trace/components/StickerCommitPanel.d.ts +30 -0
- package/dist/features/sticker-trace/components/StickerCommitPanel.js +93 -0
- package/dist/features/sticker-trace/components/StickerPrintPanel.d.ts +33 -0
- package/dist/features/sticker-trace/components/StickerPrintPanel.js +104 -0
- package/dist/features/sticker-trace/components/StickerRetryPanel.d.ts +20 -0
- package/dist/features/sticker-trace/components/StickerRetryPanel.js +128 -0
- package/dist/features/sticker-trace/components/StickerRunHistoryPanel.d.ts +45 -0
- package/dist/features/sticker-trace/components/StickerRunHistoryPanel.js +84 -0
- package/dist/features/sticker-trace/components/StickerTraceStudio.d.ts +27 -0
- package/dist/features/sticker-trace/components/StickerTraceStudio.js +171 -0
- package/dist/features/sticker-trace/constants/help-content.d.ts +23 -0
- package/dist/features/sticker-trace/constants/help-content.js +172 -0
- package/dist/features/sticker-trace/hooks/useLiveTrace.d.ts +27 -0
- package/dist/features/sticker-trace/hooks/useLiveTrace.js +160 -0
- package/dist/features/sticker-trace/hooks/useStickerTraceProgress.d.ts +22 -0
- package/dist/features/sticker-trace/hooks/useStickerTraceProgress.js +106 -0
- package/dist/features/sticker-trace/repository/sticker-sheets.repository.d.ts +113 -0
- package/dist/features/sticker-trace/repository/sticker-sheets.repository.js +146 -0
- package/dist/features/sticker-trace/repository/sticker-trace-runs.repository.d.ts +132 -0
- package/dist/features/sticker-trace/repository/sticker-trace-runs.repository.js +174 -0
- package/dist/features/sticker-trace/schemas/firestore.d.ts +248 -0
- package/dist/features/sticker-trace/schemas/firestore.js +79 -0
- package/dist/features/sticker-trace/server.d.ts +8 -0
- package/dist/features/sticker-trace/server.js +51 -0
- package/dist/features/stores/actions/store-query-actions.d.ts +2 -2
- package/dist/features/stores/actions/store-query-actions.js +7 -2
- package/dist/features/stores/api/[storeSlug]/auctions/route.js +3 -3
- package/dist/features/stores/api/[storeSlug]/products/route.js +3 -3
- package/dist/features/stores/api/[storeSlug]/reviews/route.js +1 -1
- package/dist/features/stores/api/[storeSlug]/route.js +1 -1
- package/dist/features/stores/components/StoreNavTabs.js +17 -2
- package/dist/features/stores/manifest.js +8 -4
- package/dist/features/support/repository/support.repository.d.ts +14 -3
- package/dist/features/support/repository/support.repository.js +93 -13
- package/dist/features/support/schemas/firestore.d.ts +16 -5
- package/dist/features/tester/seed-data/authored/admin__events-raffles-spin.js +61 -19
- package/dist/features/tester/seed-data/authored/buying__browsing-search.js +19 -3
- package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.js +243 -0
- package/dist/features/tester/seed-data/authored/content-discovery__events.js +36 -10
- package/dist/features/tester/seed-data/authored/content-discovery__overflowing-pill-rows.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__overflowing-pill-rows.js +209 -0
- package/dist/features/tester/seed-data/authored/design-ux__header-brand-mark-centring.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/design-ux__header-brand-mark-centring.js +90 -0
- package/dist/features/tester/seed-data/authored/index.js +8 -0
- package/dist/features/tester/seed-data/authored/selling__media-limits.js +19 -17
- package/dist/features/tester/seed-data/authored/selling__product-upload-details.js +10 -5
- package/dist/features/tester/seed-data/authored/tools__sticker-tracer.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/tools__sticker-tracer.js +283 -0
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +192 -22
- package/dist/index.d.ts +10 -23
- package/dist/index.js +27 -19
- package/dist/next/api/routeHandler.js +9 -0
- package/dist/next/routing/require-record.d.ts +13 -0
- package/dist/next/routing/require-record.js +62 -0
- package/dist/next/routing/route-map.d.ts +4 -4
- package/dist/next/routing/route-map.js +25 -3
- package/dist/providers/db-firebase/base.d.ts +4 -2
- package/dist/providers/db-firebase/base.js +21 -5
- package/dist/providers/db-firebase/base.repository.d.ts +11 -9
- package/dist/providers/db-firebase/base.repository.js +19 -0
- package/dist/providers/db-firebase/rtdb-paths.d.ts +12 -0
- package/dist/providers/db-firebase/rtdb-paths.js +12 -0
- package/dist/react/ErrorBoundary.js +6 -1
- package/dist/react/hooks/realtime-event-constants.d.ts +1 -0
- package/dist/react/hooks/realtime-event-constants.js +8 -0
- package/dist/react/hooks/useEntityDelete.js +5 -1
- package/dist/react/hooks/useMessage.js +5 -1
- package/dist/repositories/index.d.ts +2 -2
- package/dist/repositories/index.js +6 -1
- package/dist/schemas/registry.d.ts +13 -20
- package/dist/schemas/registry.js +31 -14
- package/dist/schemas/webhooks/google-oauth.d.ts +2 -2
- package/dist/security/encrypted.d.ts +117 -0
- package/dist/security/encrypted.js +100 -0
- package/dist/security/index.d.ts +5 -2
- package/dist/security/index.js +16 -2
- package/dist/security/pii-accessors.d.ts +71 -0
- package/dist/security/pii-accessors.js +150 -0
- package/dist/security/pii-encrypt.d.ts +0 -8
- package/dist/security/pii-encrypt.js +22 -15
- package/dist/security/pii-mask.d.ts +18 -0
- package/dist/security/pii-mask.js +27 -0
- package/dist/seed/_helpers/search-txt-wrappers.d.ts +6 -6
- package/dist/seed/_helpers/search-txt-wrappers.js +22 -0
- package/dist/seed/addresses-seed-data.d.ts +2 -2
- package/dist/seed/authenticity-knowledge-seed-data.d.ts +34 -0
- package/dist/seed/authenticity-knowledge-seed-data.js +1277 -0
- package/dist/seed/bids-seed-data.d.ts +2 -2
- package/dist/seed/bids-seed-data.js +23 -2
- package/dist/seed/events-seed-data.d.ts +2 -2
- package/dist/seed/events-seed-data.js +5 -0
- package/dist/seed/faq-seed-data.js +175 -5
- package/dist/seed/homepage-sections-seed-data.js +39 -23
- package/dist/seed/index.d.ts +1 -0
- package/dist/seed/index.js +1 -0
- package/dist/seed/lottery-entries-seed-data.d.ts +2 -2
- package/dist/seed/offers-seed-data.d.ts +2 -2
- package/dist/seed/offers-seed-data.js +1 -1
- package/dist/seed/orders-seed-data.d.ts +2 -2
- package/dist/seed/payouts-seed-data.d.ts +2 -2
- package/dist/seed/payouts-seed-data.js +1 -1
- package/dist/seed/reviews-seed-data.d.ts +1 -2
- package/dist/seed/seed-purpose.js +7 -0
- package/dist/seed/sessions-seed-data.d.ts +2 -2
- package/dist/seed/sessions-seed-data.js +5 -0
- package/dist/seed/site-settings-seed-data.js +1 -1
- package/dist/seed/support-tickets-seed-data.d.ts +2 -2
- package/dist/seed/support-tickets-seed-data.js +1 -1
- package/dist/seed/users-seed-data.d.ts +2 -2
- package/dist/seed/users-seed-data.js +1 -1
- package/dist/seo/json-ld.js +5 -1
- package/dist/server.d.ts +18 -3
- package/dist/server.js +59 -3
- package/dist/styles.css +237 -1
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/components/Button.js +7 -1
- package/dist/ui/components/FilterChipGroup.d.ts +11 -0
- package/dist/ui/components/FilterChipGroup.js +1 -1
- package/dist/ui/components/ImageGallery.js +6 -1
- package/dist/ui/components/ListingLayout.js +14 -8
- package/dist/ui/components/OverflowRow.d.ts +92 -0
- package/dist/ui/components/OverflowRow.js +203 -0
- package/dist/ui/components/OverflowRow.style.css +235 -0
- package/dist/ui/components/RecordDetailModal.js +14 -1
- package/dist/ui/components/RowActionMenu.js +5 -1
- package/dist/ui/components/SideDrawer.js +5 -1
- package/dist/ui/components/SideModal.js +9 -1
- package/dist/ui/components/TabBarShell.d.ts +12 -1
- package/dist/ui/components/TabBarShell.js +3 -2
- package/dist/ui/components/Tabs.js +36 -24
- package/dist/ui/components/Toast.d.ts +3 -24
- package/dist/ui/components/Toast.js +2 -19
- package/dist/ui/components/TopBannerPortal.d.ts +15 -0
- package/dist/ui/components/TopBannerPortal.js +19 -0
- package/dist/ui/components/UnsavedChangesModal.js +5 -1
- package/dist/ui/components/index.style.css +1 -0
- package/dist/ui/components/row-collapse.d.ts +15 -0
- package/dist/ui/components/row-collapse.js +127 -0
- package/dist/ui/components/toast-context.d.ts +63 -0
- package/dist/ui/components/toast-context.js +48 -0
- package/dist/ui/components/top-banner-slot.d.ts +37 -0
- package/dist/ui/components/top-banner-slot.js +45 -0
- package/dist/ui/icons/icon-registry.d.ts +6 -0
- package/dist/ui/icons/icon-registry.js +17 -1
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.js +1 -0
- package/dist/utils/array.helper.d.ts +2 -2
- package/dist/utils/array.helper.js +5 -5
- package/dist/utils/id-generators.d.ts +6 -0
- package/dist/utils/id-generators.js +10 -0
- package/dist/utils/media-url.js +0 -2
- package/dist/utils/search-txt-builders.d.ts +28 -4
- package/dist/utils/search-txt-builders.js +41 -1
- package/dist/validation/schemas.d.ts +8 -8
- package/package.json +6 -2
- package/scripts/seed-cli.mjs +3 -0
- package/dist/features/account/components/UserAddressesView.d.ts +0 -13
- package/dist/features/account/components/UserAddressesView.js +0 -5
- package/dist/features/account/components/UserNotificationsView.d.ts +0 -15
- package/dist/features/account/components/UserNotificationsView.js +0 -12
- package/dist/features/account/components/UserSettingsView.d.ts +0 -16
- package/dist/features/account/components/UserSettingsView.js +0 -13
- package/dist/features/account/components/UserSupportView.d.ts +0 -3
- package/dist/features/account/components/UserSupportView.js +0 -166
- package/dist/features/admin/components/DemoSeedView.d.ts +0 -11
- package/dist/features/admin/components/DemoSeedView.js +0 -5
- package/dist/features/auth/components/AuthStatusPanel.d.ts +0 -10
- package/dist/features/auth/components/AuthStatusPanel.js +0 -22
- package/dist/features/categories/components/CategoryProductsView.d.ts +0 -45
- package/dist/features/categories/components/CategoryProductsView.js +0 -21
- package/dist/features/homepage/components/HowItWorksInfoView.d.ts +0 -36
- package/dist/features/homepage/components/HowItWorksInfoView.js +0 -10
- package/dist/features/layout/BottomActions.d.ts +0 -1
- package/dist/features/layout/BottomActions.js +0 -311
- package/dist/features/products/components/ProductsView.d.ts +0 -6
- package/dist/features/products/components/ProductsView.js +0 -5
- package/dist/features/seller/components/SellerStoreView.d.ts +0 -8
- package/dist/features/seller/components/SellerStoreView.js +0 -8
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { CutPath, Point, Rect } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Max deviation between the curve and its polyline, in DESTINATION pixels.
|
|
4
|
+
*
|
|
5
|
+
* 🛑 MEASURED, and the first value chosen here was wrong. A circle of r=8 has
|
|
6
|
+
* a known area (pi*r^2 = 201.06), so the fill can be checked against it:
|
|
7
|
+
*
|
|
8
|
+
* tol 0.25 17 pts area 196.09 -2.47%
|
|
9
|
+
* tol 0.10 33 pts area 200.02 -0.52%
|
|
10
|
+
* tol 0.05 57 pts area 200.74 -0.16% <- chosen
|
|
11
|
+
* tol 0.01 129 pts area 201.18 +0.06%
|
|
12
|
+
* tol 0.002 257 pts area 201.25 +0.10%
|
|
13
|
+
*
|
|
14
|
+
* A polyline inscribed in a convex curve always UNDER-covers — chords cut
|
|
15
|
+
* corners — so the bias is one-directional and shrinks the sticker rather than
|
|
16
|
+
* growing it. At 0.25 that is a systematic 2.5% area loss, which is far more
|
|
17
|
+
* than anti-aliasing can hide. 0.05 costs 57 points against 17 and lands inside
|
|
18
|
+
* a fifth of a percent; 0.01 buys another 0.1pp for 2.3x the points, which the
|
|
19
|
+
* cut cannot express.
|
|
20
|
+
*/
|
|
21
|
+
export declare const FLATTEN_TOLERANCE_PX = 0.05;
|
|
22
|
+
/**
|
|
23
|
+
* Sub-scanlines per pixel row.
|
|
24
|
+
*
|
|
25
|
+
* 🛑 This knob does NOT control accuracy, and I assumed it did. Measured on the
|
|
26
|
+
* same circle, area error barely moves and moves the WRONG way — S=1 -1.96%,
|
|
27
|
+
* S=4 -2.47%, S=16 -2.54%, S=32 -2.55% — because total coverage is set by the
|
|
28
|
+
* polyline, not by how finely the rows are sampled. The earlier claim here that
|
|
29
|
+
* "16 was measurably no better" was written before any of this was measured;
|
|
30
|
+
* it happened to be true and was not evidence.
|
|
31
|
+
*
|
|
32
|
+
* What subsampling actually buys is edge SMOOTHNESS, which an area total cannot
|
|
33
|
+
* see at all: a stair-stepped edge and a smooth one can sum to the same
|
|
34
|
+
* coverage. 4 gives five distinguishable levels from vertical coverage while the
|
|
35
|
+
* horizontal span ends stay exact, so a near-vertical edge is continuous and a
|
|
36
|
+
* near-horizontal one is quantised to fifths. Raising it is cheap if a printed
|
|
37
|
+
* part ever shows banding on shallow diagonals — judge that by eye, not by this
|
|
38
|
+
* area check.
|
|
39
|
+
*/
|
|
40
|
+
export declare const SUBSAMPLES_PER_ROW = 4;
|
|
41
|
+
/**
|
|
42
|
+
* Flatten a cut path into a closed polyline, transformed into mask space.
|
|
43
|
+
*
|
|
44
|
+
* `scale` maps the working raster the path was traced on to full resolution,
|
|
45
|
+
* and `origin` is the part's bbox corner — so the returned points are already
|
|
46
|
+
* relative to the mask's own (0,0). Doing the transform HERE rather than per
|
|
47
|
+
* sample is what keeps the inner scanline loop free of it.
|
|
48
|
+
*/
|
|
49
|
+
export declare function flattenPath(path: CutPath, scale: number, origin: {
|
|
50
|
+
x: number;
|
|
51
|
+
y: number;
|
|
52
|
+
}): Point[];
|
|
53
|
+
/**
|
|
54
|
+
* Rasterise one closed path into an alpha mask of `size`.
|
|
55
|
+
*
|
|
56
|
+
* Returns `width * height` bytes, 0..255, row-major — the shape
|
|
57
|
+
* `encodePngRegion` writes straight into the alpha channel.
|
|
58
|
+
*/
|
|
59
|
+
export declare function rasterizePathAlpha(points: readonly Point[], size: {
|
|
60
|
+
width: number;
|
|
61
|
+
height: number;
|
|
62
|
+
}): Uint8Array;
|
|
63
|
+
/**
|
|
64
|
+
* Rasterise one part's path into an alpha mask covering `bbox`.
|
|
65
|
+
*
|
|
66
|
+
* This matches `ShardDeps.rasterise` exactly: `(path, bbox)`, no ordinal and
|
|
67
|
+
* no scale.
|
|
68
|
+
*
|
|
69
|
+
* 🛑 The scale is DERIVED from the path's own extent onto `bbox`, and that is
|
|
70
|
+
* the only self-consistent option available. The path is in working-raster
|
|
71
|
+
* coordinates while `bbox` is already full-resolution, so a mapping is
|
|
72
|
+
* unavoidable — and the two candidates were: take `scale` as a fourth argument,
|
|
73
|
+
* or derive it. Taking it would mean the shard computes
|
|
74
|
+
* `sheet.widthPx / workingSize.width` and the binding computes it again from
|
|
75
|
+
* its own copy of the geometry, which is two derivations of one number and
|
|
76
|
+
* exactly the drift Root Cause #75 is about. Deriving it here also guarantees
|
|
77
|
+
* the mask FILLS the region it was given, which is what the caller needs:
|
|
78
|
+
* `bbox` comes from the component mask while the path comes from marching
|
|
79
|
+
* squares, so the two can differ by a fraction of a pixel and a mask that
|
|
80
|
+
* merely scaled by a shared factor could leave an empty row at one edge.
|
|
81
|
+
*
|
|
82
|
+
* 🛑 A FIRST DRAFT of this was `makePartRasteriser(geometry)`, keyed on
|
|
83
|
+
* ordinal. It was written against a stale signature and deleted: the real
|
|
84
|
+
* contract hands over the path, and its own comment explains why — an ordinal
|
|
85
|
+
* "could only be implemented by re-reading geometry.json for every part, sixty
|
|
86
|
+
* extra downloads per shard for data the caller already holds."
|
|
87
|
+
*/
|
|
88
|
+
export declare function rasterisePartToBox(path: CutPath, bbox: Rect): Promise<Uint8Array>;
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: A cut path is Bézier geometry, but a part's PNG needs an alpha mask —
|
|
3
|
+
* and the mask has to agree with the cut file exactly, or the printed
|
|
4
|
+
* sticker and the blade disagree about where its edge is.
|
|
5
|
+
* WHAT: Flatten cubics to a polyline, then scanline-fill with coverage alpha.
|
|
6
|
+
*
|
|
7
|
+
* TWO DECISIONS THE CUT QUALITY DEPENDS ON, both made here and stated:
|
|
8
|
+
*
|
|
9
|
+
* 🛑 1. FILL RULE: NONZERO.
|
|
10
|
+
*
|
|
11
|
+
* A kiss cut is one closed outer boundary with no interior holes — cutting a
|
|
12
|
+
* hole would make the sticker fall apart on the backing — so on today's data
|
|
13
|
+
* nonzero and even-odd are IDENTICAL. Nonzero is chosen anyway because it is
|
|
14
|
+
* SVG's default, and the cut SVG exporter will emit these same paths: if the
|
|
15
|
+
* two rules ever disagreed (a self-intersecting trace, or a future part that
|
|
16
|
+
* genuinely has a hole), the mask and the cut file must still describe the same
|
|
17
|
+
* region. Picking the renderer's rule means they cannot drift.
|
|
18
|
+
*
|
|
19
|
+
* 🛑 2. EDGES ARE ANTI-ALIASED, by coverage.
|
|
20
|
+
*
|
|
21
|
+
* A hard 0/255 mask leaves visible stair-stepping along every diagonal and
|
|
22
|
+
* curve — on a printed sticker that reads as a jagged edge, and it is exactly
|
|
23
|
+
* the artifact a Bézier trace exists to avoid. So each pixel's alpha is the
|
|
24
|
+
* FRACTION of it inside the path: vertical supersampling across sub-scanlines
|
|
25
|
+
* plus exact horizontal span ends. Costs ~4x the scanline work for an edge
|
|
26
|
+
* that survives printing.
|
|
27
|
+
*
|
|
28
|
+
* Pure: no codec, no node, no DOM. Enforced by audit-sticker-trace-purity.
|
|
29
|
+
*
|
|
30
|
+
* EXPORTS: flattenPath, rasterizePathAlpha, rasterisePartToBox,
|
|
31
|
+
* FLATTEN_TOLERANCE_PX, SUBSAMPLES_PER_ROW
|
|
32
|
+
*
|
|
33
|
+
* @tag domain:sticker-trace
|
|
34
|
+
* @tag layer:shared
|
|
35
|
+
* @tag pattern:none
|
|
36
|
+
* @tag access:isomorphic
|
|
37
|
+
* @tag consumers:shard,canvas-codec
|
|
38
|
+
* @tag sideEffects:none
|
|
39
|
+
*/
|
|
40
|
+
/**
|
|
41
|
+
* Max deviation between the curve and its polyline, in DESTINATION pixels.
|
|
42
|
+
*
|
|
43
|
+
* 🛑 MEASURED, and the first value chosen here was wrong. A circle of r=8 has
|
|
44
|
+
* a known area (pi*r^2 = 201.06), so the fill can be checked against it:
|
|
45
|
+
*
|
|
46
|
+
* tol 0.25 17 pts area 196.09 -2.47%
|
|
47
|
+
* tol 0.10 33 pts area 200.02 -0.52%
|
|
48
|
+
* tol 0.05 57 pts area 200.74 -0.16% <- chosen
|
|
49
|
+
* tol 0.01 129 pts area 201.18 +0.06%
|
|
50
|
+
* tol 0.002 257 pts area 201.25 +0.10%
|
|
51
|
+
*
|
|
52
|
+
* A polyline inscribed in a convex curve always UNDER-covers — chords cut
|
|
53
|
+
* corners — so the bias is one-directional and shrinks the sticker rather than
|
|
54
|
+
* growing it. At 0.25 that is a systematic 2.5% area loss, which is far more
|
|
55
|
+
* than anti-aliasing can hide. 0.05 costs 57 points against 17 and lands inside
|
|
56
|
+
* a fifth of a percent; 0.01 buys another 0.1pp for 2.3x the points, which the
|
|
57
|
+
* cut cannot express.
|
|
58
|
+
*/
|
|
59
|
+
export const FLATTEN_TOLERANCE_PX = 0.05;
|
|
60
|
+
/**
|
|
61
|
+
* Sub-scanlines per pixel row.
|
|
62
|
+
*
|
|
63
|
+
* 🛑 This knob does NOT control accuracy, and I assumed it did. Measured on the
|
|
64
|
+
* same circle, area error barely moves and moves the WRONG way — S=1 -1.96%,
|
|
65
|
+
* S=4 -2.47%, S=16 -2.54%, S=32 -2.55% — because total coverage is set by the
|
|
66
|
+
* polyline, not by how finely the rows are sampled. The earlier claim here that
|
|
67
|
+
* "16 was measurably no better" was written before any of this was measured;
|
|
68
|
+
* it happened to be true and was not evidence.
|
|
69
|
+
*
|
|
70
|
+
* What subsampling actually buys is edge SMOOTHNESS, which an area total cannot
|
|
71
|
+
* see at all: a stair-stepped edge and a smooth one can sum to the same
|
|
72
|
+
* coverage. 4 gives five distinguishable levels from vertical coverage while the
|
|
73
|
+
* horizontal span ends stay exact, so a near-vertical edge is continuous and a
|
|
74
|
+
* near-horizontal one is quantised to fifths. Raising it is cheap if a printed
|
|
75
|
+
* part ever shows banding on shallow diagonals — judge that by eye, not by this
|
|
76
|
+
* area check.
|
|
77
|
+
*/
|
|
78
|
+
export const SUBSAMPLES_PER_ROW = 4;
|
|
79
|
+
/** Flat-enough test: the control points' distance from the chord. */
|
|
80
|
+
function isFlatEnough(p0, c1, c2, p1, tol) {
|
|
81
|
+
const dx = p1.x - p0.x;
|
|
82
|
+
const dy = p1.y - p0.y;
|
|
83
|
+
const len = Math.hypot(dx, dy);
|
|
84
|
+
if (len < 1e-9) {
|
|
85
|
+
// Degenerate chord: fall back to control-point spread, or a cusp would
|
|
86
|
+
// recurse to the depth cap and emit a needlessly dense polyline.
|
|
87
|
+
return Math.hypot(c1.x - p0.x, c1.y - p0.y) + Math.hypot(c2.x - p1.x, c2.y - p1.y) < tol;
|
|
88
|
+
}
|
|
89
|
+
const d1 = Math.abs((c1.x - p0.x) * dy - (c1.y - p0.y) * dx) / len;
|
|
90
|
+
const d2 = Math.abs((c2.x - p0.x) * dy - (c2.y - p0.y) * dx) / len;
|
|
91
|
+
return Math.max(d1, d2) <= tol;
|
|
92
|
+
}
|
|
93
|
+
function subdivide(p0, c1, c2, p1, tol, depth, out) {
|
|
94
|
+
/*
|
|
95
|
+
* Depth 16 is a guard, not a tuning knob. Adaptive subdivision terminates on
|
|
96
|
+
* real curves; the cap exists so a NaN or an infinity in the geometry cannot
|
|
97
|
+
* spin forever — which would hang a shard rather than fail it.
|
|
98
|
+
*/
|
|
99
|
+
if (depth >= 16 || isFlatEnough(p0, c1, c2, p1, tol)) {
|
|
100
|
+
out.push(p1);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const mid = (a, b) => ({ x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 });
|
|
104
|
+
const p01 = mid(p0, c1);
|
|
105
|
+
const p12 = mid(c1, c2);
|
|
106
|
+
const p23 = mid(c2, p1);
|
|
107
|
+
const p012 = mid(p01, p12);
|
|
108
|
+
const p123 = mid(p12, p23);
|
|
109
|
+
const m = mid(p012, p123);
|
|
110
|
+
subdivide(p0, p01, p012, m, tol, depth + 1, out);
|
|
111
|
+
subdivide(m, p123, p23, p1, tol, depth + 1, out);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Flatten a cut path into a closed polyline, transformed into mask space.
|
|
115
|
+
*
|
|
116
|
+
* `scale` maps the working raster the path was traced on to full resolution,
|
|
117
|
+
* and `origin` is the part's bbox corner — so the returned points are already
|
|
118
|
+
* relative to the mask's own (0,0). Doing the transform HERE rather than per
|
|
119
|
+
* sample is what keeps the inner scanline loop free of it.
|
|
120
|
+
*/
|
|
121
|
+
export function flattenPath(path, scale, origin) {
|
|
122
|
+
const tx = (p) => ({ x: p.x * scale - origin.x, y: p.y * scale - origin.y });
|
|
123
|
+
const pts = [tx(path.start)];
|
|
124
|
+
let current = path.start;
|
|
125
|
+
for (const seg of path.segments) {
|
|
126
|
+
subdivide(tx(current), tx(seg.c1), tx(seg.c2), tx(seg.to), FLATTEN_TOLERANCE_PX, 0, pts);
|
|
127
|
+
current = seg.to;
|
|
128
|
+
}
|
|
129
|
+
return pts;
|
|
130
|
+
}
|
|
131
|
+
function buildEdges(points) {
|
|
132
|
+
const edges = [];
|
|
133
|
+
for (let i = 0; i < points.length; i++) {
|
|
134
|
+
const a = points[i];
|
|
135
|
+
const b = points[(i + 1) % points.length];
|
|
136
|
+
// Horizontal edges contribute no crossings and would divide by zero.
|
|
137
|
+
if (a.y === b.y)
|
|
138
|
+
continue;
|
|
139
|
+
edges.push(a.y < b.y
|
|
140
|
+
? { x0: a.x, y0: a.y, x1: b.x, y1: b.y, dir: 1 }
|
|
141
|
+
: { x0: b.x, y0: b.y, x1: a.x, y1: a.y, dir: -1 });
|
|
142
|
+
}
|
|
143
|
+
return edges;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Rasterise one closed path into an alpha mask of `size`.
|
|
147
|
+
*
|
|
148
|
+
* Returns `width * height` bytes, 0..255, row-major — the shape
|
|
149
|
+
* `encodePngRegion` writes straight into the alpha channel.
|
|
150
|
+
*/
|
|
151
|
+
export function rasterizePathAlpha(points, size) {
|
|
152
|
+
const { width, height } = size;
|
|
153
|
+
const alpha = new Uint8Array(width * height);
|
|
154
|
+
const edges = buildEdges(points);
|
|
155
|
+
if (edges.length === 0)
|
|
156
|
+
return alpha;
|
|
157
|
+
// Float accumulator per row: coverage sums across sub-scanlines before the
|
|
158
|
+
// single rounding at the end. Rounding per sub-scanline would quantise four
|
|
159
|
+
// times and lose most of the anti-aliasing.
|
|
160
|
+
const cov = new Float32Array(width);
|
|
161
|
+
const xs = [];
|
|
162
|
+
for (let y = 0; y < height; y++) {
|
|
163
|
+
cov.fill(0);
|
|
164
|
+
for (let s = 0; s < SUBSAMPLES_PER_ROW; s++) {
|
|
165
|
+
const sy = y + (s + 0.5) / SUBSAMPLES_PER_ROW;
|
|
166
|
+
xs.length = 0;
|
|
167
|
+
for (const e of edges) {
|
|
168
|
+
// Half-open [y0, y1): a vertex shared by two edges is counted once, so
|
|
169
|
+
// a crossing exactly on a sub-scanline cannot double-count and punch a
|
|
170
|
+
// hole in the fill.
|
|
171
|
+
if (sy < e.y0 || sy >= e.y1)
|
|
172
|
+
continue;
|
|
173
|
+
const t = (sy - e.y0) / (e.y1 - e.y0);
|
|
174
|
+
xs.push({ x: e.x0 + t * (e.x1 - e.x0), dir: e.dir });
|
|
175
|
+
}
|
|
176
|
+
if (xs.length < 2)
|
|
177
|
+
continue;
|
|
178
|
+
xs.sort((a, b) => a.x - b.x);
|
|
179
|
+
// NONZERO: accumulate winding, and a span is inside wherever it is != 0.
|
|
180
|
+
let winding = 0;
|
|
181
|
+
for (let i = 0; i < xs.length - 1; i++) {
|
|
182
|
+
winding += xs[i].dir;
|
|
183
|
+
if (winding === 0)
|
|
184
|
+
continue;
|
|
185
|
+
addSpan(cov, xs[i].x, xs[i + 1].x, width);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const row = y * width;
|
|
189
|
+
for (let x = 0; x < width; x++) {
|
|
190
|
+
const v = cov[x] / SUBSAMPLES_PER_ROW;
|
|
191
|
+
alpha[row + x] = v <= 0 ? 0 : v >= 1 ? 255 : Math.round(v * 255);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return alpha;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Add one horizontal span's coverage, with EXACT fractional ends.
|
|
198
|
+
*
|
|
199
|
+
* This is what makes a near-vertical edge smooth: the partial pixels at each
|
|
200
|
+
* end get their real fraction rather than being rounded in or out, so the
|
|
201
|
+
* horizontal resolution is continuous even though the vertical is sampled.
|
|
202
|
+
*/
|
|
203
|
+
function addSpan(cov, xStart, xEnd, width) {
|
|
204
|
+
let a = xStart;
|
|
205
|
+
let b = xEnd;
|
|
206
|
+
if (b <= a)
|
|
207
|
+
return;
|
|
208
|
+
if (b <= 0 || a >= width)
|
|
209
|
+
return;
|
|
210
|
+
if (a < 0)
|
|
211
|
+
a = 0;
|
|
212
|
+
if (b > width)
|
|
213
|
+
b = width;
|
|
214
|
+
const first = Math.floor(a);
|
|
215
|
+
const last = Math.ceil(b) - 1;
|
|
216
|
+
if (first === last) {
|
|
217
|
+
cov[first] = cov[first] + (b - a);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
cov[first] = cov[first] + (first + 1 - a);
|
|
221
|
+
for (let x = first + 1; x < last; x++)
|
|
222
|
+
cov[x] = cov[x] + 1;
|
|
223
|
+
cov[last] = cov[last] + (b - last);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Rasterise one part's path into an alpha mask covering `bbox`.
|
|
227
|
+
*
|
|
228
|
+
* This matches `ShardDeps.rasterise` exactly: `(path, bbox)`, no ordinal and
|
|
229
|
+
* no scale.
|
|
230
|
+
*
|
|
231
|
+
* 🛑 The scale is DERIVED from the path's own extent onto `bbox`, and that is
|
|
232
|
+
* the only self-consistent option available. The path is in working-raster
|
|
233
|
+
* coordinates while `bbox` is already full-resolution, so a mapping is
|
|
234
|
+
* unavoidable — and the two candidates were: take `scale` as a fourth argument,
|
|
235
|
+
* or derive it. Taking it would mean the shard computes
|
|
236
|
+
* `sheet.widthPx / workingSize.width` and the binding computes it again from
|
|
237
|
+
* its own copy of the geometry, which is two derivations of one number and
|
|
238
|
+
* exactly the drift Root Cause #75 is about. Deriving it here also guarantees
|
|
239
|
+
* the mask FILLS the region it was given, which is what the caller needs:
|
|
240
|
+
* `bbox` comes from the component mask while the path comes from marching
|
|
241
|
+
* squares, so the two can differ by a fraction of a pixel and a mask that
|
|
242
|
+
* merely scaled by a shared factor could leave an empty row at one edge.
|
|
243
|
+
*
|
|
244
|
+
* 🛑 A FIRST DRAFT of this was `makePartRasteriser(geometry)`, keyed on
|
|
245
|
+
* ordinal. It was written against a stale signature and deleted: the real
|
|
246
|
+
* contract hands over the path, and its own comment explains why — an ordinal
|
|
247
|
+
* "could only be implemented by re-reading geometry.json for every part, sixty
|
|
248
|
+
* extra downloads per shard for data the caller already holds."
|
|
249
|
+
*/
|
|
250
|
+
export async function rasterisePartToBox(path, bbox) {
|
|
251
|
+
if (bbox.width <= 0 || bbox.height <= 0)
|
|
252
|
+
return new Uint8Array(0);
|
|
253
|
+
// The path's extent in its own (working) coordinates.
|
|
254
|
+
const raw = flattenPath(path, 1, { x: 0, y: 0 });
|
|
255
|
+
let minX = Infinity;
|
|
256
|
+
let minY = Infinity;
|
|
257
|
+
let maxX = -Infinity;
|
|
258
|
+
let maxY = -Infinity;
|
|
259
|
+
for (const p of raw) {
|
|
260
|
+
if (p.x < minX)
|
|
261
|
+
minX = p.x;
|
|
262
|
+
if (p.y < minY)
|
|
263
|
+
minY = p.y;
|
|
264
|
+
if (p.x > maxX)
|
|
265
|
+
maxX = p.x;
|
|
266
|
+
if (p.y > maxY)
|
|
267
|
+
maxY = p.y;
|
|
268
|
+
}
|
|
269
|
+
const spanX = maxX - minX;
|
|
270
|
+
const spanY = maxY - minY;
|
|
271
|
+
if (!(spanX > 0) || !(spanY > 0))
|
|
272
|
+
return new Uint8Array(bbox.width * bbox.height);
|
|
273
|
+
/*
|
|
274
|
+
* ONE uniform factor, from the larger span. A per-axis fit would stretch the
|
|
275
|
+
* sticker to fill its own bounding box, which is wrong by up to a pixel on a
|
|
276
|
+
* part whose bbox was rounded outward — and a stretched cut outline no longer
|
|
277
|
+
* matches the artwork it was traced from.
|
|
278
|
+
*/
|
|
279
|
+
const scale = Math.max(bbox.width / spanX, bbox.height / spanY);
|
|
280
|
+
// Centre the scaled path inside the box, so any rounding slack is split
|
|
281
|
+
// between the two edges rather than all landing on one.
|
|
282
|
+
const originX = minX * scale - (bbox.width - spanX * scale) / 2;
|
|
283
|
+
const originY = minY * scale - (bbox.height - spanY * scale) / 2;
|
|
284
|
+
const points = flattenPath(path, scale, { x: originX, y: originY });
|
|
285
|
+
return rasterizePathAlpha(points, { width: bbox.width, height: bbox.height });
|
|
286
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Point } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Drop points that lie within `epsilon` of the chord they sit on.
|
|
4
|
+
*
|
|
5
|
+
* `epsilon` is in the same units as the points — callers pass a millimetre
|
|
6
|
+
* tolerance converted to pixels, so the tolerance means the same physical thing
|
|
7
|
+
* at every scan resolution. That is why the Cricut exporter can re-simplify to
|
|
8
|
+
* a node budget independently: both speak the same units.
|
|
9
|
+
*/
|
|
10
|
+
export declare function simplifyRdp(points: readonly Point[], epsilon: number): Point[];
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: A traced ring from a 3000px raster carries ten thousand points, one per
|
|
3
|
+
* pixel crack. Emitting that as a cut path makes the blade chatter, bloats
|
|
4
|
+
* the SVG past what Design Space will open, and encodes scanner noise as
|
|
5
|
+
* geometry. Simplifying first is what makes the curve fit meaningful.
|
|
6
|
+
* WHAT: Ramer-Douglas-Peucker, iterative.
|
|
7
|
+
*
|
|
8
|
+
* Iterative rather than recursive on purpose: a ten-thousand-point contour
|
|
9
|
+
* recurses deep enough to blow the stack, and it does so only on the largest
|
|
10
|
+
* stickers — i.e. in production, on the sheets that matter, having passed every
|
|
11
|
+
* smaller test.
|
|
12
|
+
*
|
|
13
|
+
* EXPORTS: simplifyRdp
|
|
14
|
+
*
|
|
15
|
+
* @tag domain:sticker-trace
|
|
16
|
+
* @tag layer:shared
|
|
17
|
+
* @tag pattern:none
|
|
18
|
+
* @tag access:isomorphic
|
|
19
|
+
* @tag consumers:geometry,export/cricut-svg
|
|
20
|
+
* @tag sideEffects:none
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Drop points that lie within `epsilon` of the chord they sit on.
|
|
24
|
+
*
|
|
25
|
+
* `epsilon` is in the same units as the points — callers pass a millimetre
|
|
26
|
+
* tolerance converted to pixels, so the tolerance means the same physical thing
|
|
27
|
+
* at every scan resolution. That is why the Cricut exporter can re-simplify to
|
|
28
|
+
* a node budget independently: both speak the same units.
|
|
29
|
+
*/
|
|
30
|
+
export function simplifyRdp(points, epsilon) {
|
|
31
|
+
const n = points.length;
|
|
32
|
+
if (n < 3 || epsilon <= 0)
|
|
33
|
+
return points.slice();
|
|
34
|
+
const keep = new Uint8Array(n);
|
|
35
|
+
keep[0] = 1;
|
|
36
|
+
keep[n - 1] = 1;
|
|
37
|
+
const stack = [[0, n - 1]];
|
|
38
|
+
while (stack.length > 0) {
|
|
39
|
+
const [i, j] = stack.pop();
|
|
40
|
+
if (j <= i + 1)
|
|
41
|
+
continue;
|
|
42
|
+
const a = points[i];
|
|
43
|
+
const b = points[j];
|
|
44
|
+
const dx = b.x - a.x;
|
|
45
|
+
const dy = b.y - a.y;
|
|
46
|
+
const len = Math.hypot(dx, dy);
|
|
47
|
+
let worst = -1;
|
|
48
|
+
let worstIndex = -1;
|
|
49
|
+
for (let k = i + 1; k < j; k++) {
|
|
50
|
+
const p = points[k];
|
|
51
|
+
// Perpendicular distance to the chord, written out rather than via a
|
|
52
|
+
// cross-product helper: numpy's `cross` dropped 2-vector support and the
|
|
53
|
+
// Python original had to be rewritten this way, which is a reminder that
|
|
54
|
+
// the explicit form is the portable one.
|
|
55
|
+
const d = len === 0
|
|
56
|
+
? Math.hypot(p.x - a.x, p.y - a.y)
|
|
57
|
+
: Math.abs(dx * (p.y - a.y) - dy * (p.x - a.x)) / len;
|
|
58
|
+
if (d > worst) {
|
|
59
|
+
worst = d;
|
|
60
|
+
worstIndex = k;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (worst > epsilon && worstIndex >= 0) {
|
|
64
|
+
keep[worstIndex] = 1;
|
|
65
|
+
stack.push([i, worstIndex], [worstIndex, j]);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const out = [];
|
|
69
|
+
for (let i = 0; i < n; i++) {
|
|
70
|
+
if (keep[i])
|
|
71
|
+
out.push(points[i]);
|
|
72
|
+
}
|
|
73
|
+
return out;
|
|
74
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { type TraceParams, type TraceStage } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Which stage each parameter first affects.
|
|
4
|
+
*
|
|
5
|
+
* 🛑 A `Record<keyof TraceParams, TraceStage>` on purpose. Adding a parameter
|
|
6
|
+
* without classifying it is then a COMPILE error rather than a parameter that
|
|
7
|
+
* silently never invalidates anything — which would let a changed value resume
|
|
8
|
+
* past the stage it governs, i.e. exactly the defect this file exists to
|
|
9
|
+
* prevent. If `tsc` sends you here, the question to answer is "what is the
|
|
10
|
+
* earliest stage this value changes the output of".
|
|
11
|
+
*/
|
|
12
|
+
export declare const PARAM_STAGE: Record<keyof TraceParams, TraceStage>;
|
|
13
|
+
/** The pipeline order, straight from the union so it cannot drift from it. */
|
|
14
|
+
export declare const STAGE_ORDER: readonly TraceStage[];
|
|
15
|
+
export declare function stageIndex(stage: TraceStage): number;
|
|
16
|
+
/**
|
|
17
|
+
* The earliest stage whose parameters differ between two runs.
|
|
18
|
+
*
|
|
19
|
+
* `null` means nothing relevant changed, so the requested resume point stands.
|
|
20
|
+
*
|
|
21
|
+
* Compared with `!==` after a JSON round-trip is deliberately NOT what happens
|
|
22
|
+
* here — every `TraceParams` member is a number, boolean or short string
|
|
23
|
+
* union, so a direct comparison is exact. A nested object would need the
|
|
24
|
+
* key-order-independent treatment Root Cause #92 is about; there isn't one, and
|
|
25
|
+
* the `Record` above is what stops one being added unnoticed.
|
|
26
|
+
*/
|
|
27
|
+
export declare function earliestChangedStage(previous: TraceParams, next: TraceParams): TraceStage | null;
|
|
28
|
+
export interface ResumeDecision {
|
|
29
|
+
/** Where the new run actually starts. */
|
|
30
|
+
stage: TraceStage;
|
|
31
|
+
/** True when the clamp moved it earlier than asked. */
|
|
32
|
+
clamped: boolean;
|
|
33
|
+
requested: TraceStage;
|
|
34
|
+
/** The parameter stage that forced the clamp, when one did. */
|
|
35
|
+
forcedBy: TraceStage | null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* `resumeStage = max(requested, earliestChangedParamStage)` — where "max" means
|
|
39
|
+
* EARLIER in the pipeline, because a changed parameter invalidates its own
|
|
40
|
+
* stage and everything after it.
|
|
41
|
+
*/
|
|
42
|
+
export declare function resolveResumeStage(requested: TraceStage, previous: TraceParams, next: TraceParams): ResumeDecision;
|
|
43
|
+
/**
|
|
44
|
+
* The sentence the retry panel shows. Empty when nothing was clamped.
|
|
45
|
+
*
|
|
46
|
+
* Returns plain text rather than a translation key because this is the one
|
|
47
|
+
* place the two stage names have to appear together, and a key would hide the
|
|
48
|
+
* fact that the message is load-bearing rather than decorative.
|
|
49
|
+
*/
|
|
50
|
+
export declare function explainResume(decision: ResumeDecision): string;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: A retry is a NEW named run, but it may resume rather than restart,
|
|
3
|
+
* because the expensive stage is usually not the one that failed. Resuming
|
|
4
|
+
* is only safe if the parameters the earlier stages ran under have not
|
|
5
|
+
* changed.
|
|
6
|
+
* WHAT: The clamp, and the param-to-stage grouping it reads.
|
|
7
|
+
*
|
|
8
|
+
* 🛑 THE CLAMP IS WHAT MAKES RESUME HONEST.
|
|
9
|
+
*
|
|
10
|
+
* Without it, "resume from `parts` but with a different ridge threshold"
|
|
11
|
+
* produces a run whose stored artifacts were generated under DIFFERENT
|
|
12
|
+
* parameters than the run records — and nothing anywhere contradicts it. The
|
|
13
|
+
* parts look plausible, the run says `hysteresisLow 0.3`, and the two have
|
|
14
|
+
* nothing to do with each other. That is the same class of silent lie as a
|
|
15
|
+
* mirror field drifting from its source (Root Cause #42), which is why the
|
|
16
|
+
* grouping below is structural rather than a convention someone remembers.
|
|
17
|
+
*
|
|
18
|
+
* 🛑 The clamp is SHOWN, never applied silently. `explainResume` returns the
|
|
19
|
+
* sentence the retry panel displays — "you changed a ridge threshold, so this
|
|
20
|
+
* run restarts from ridge rather than resuming from parts". An adjustment the
|
|
21
|
+
* user did not ask for and cannot see is indistinguishable from the tool
|
|
22
|
+
* ignoring them.
|
|
23
|
+
*
|
|
24
|
+
* Pure: no codec, no node, no providers. Enforced by
|
|
25
|
+
* scripts/audit-sticker-trace-purity.mjs.
|
|
26
|
+
*
|
|
27
|
+
* EXPORTS: PARAM_STAGE, STAGE_ORDER, stageIndex, earliestChangedStage,
|
|
28
|
+
* resolveResumeStage, explainResume
|
|
29
|
+
*
|
|
30
|
+
* @tag domain:sticker-trace
|
|
31
|
+
* @tag layer:shared
|
|
32
|
+
* @tag pattern:none
|
|
33
|
+
* @tag access:isomorphic
|
|
34
|
+
* @tag consumers:sticker-trace/actions,functions/sticker-trace
|
|
35
|
+
* @tag sideEffects:none
|
|
36
|
+
*/
|
|
37
|
+
import { TRACE_STAGES } from "./types.js";
|
|
38
|
+
/**
|
|
39
|
+
* Which stage each parameter first affects.
|
|
40
|
+
*
|
|
41
|
+
* 🛑 A `Record<keyof TraceParams, TraceStage>` on purpose. Adding a parameter
|
|
42
|
+
* without classifying it is then a COMPILE error rather than a parameter that
|
|
43
|
+
* silently never invalidates anything — which would let a changed value resume
|
|
44
|
+
* past the stage it governs, i.e. exactly the defect this file exists to
|
|
45
|
+
* prevent. If `tsc` sends you here, the question to answer is "what is the
|
|
46
|
+
* earliest stage this value changes the output of".
|
|
47
|
+
*/
|
|
48
|
+
export const PARAM_STAGE = {
|
|
49
|
+
// decode
|
|
50
|
+
workingLongEdge: "decode",
|
|
51
|
+
scanType: "decode",
|
|
52
|
+
/*
|
|
53
|
+
* Both map to the FIRST stage, i.e. changing either forces a full restart.
|
|
54
|
+
*
|
|
55
|
+
* `tier` carries workingLongEdge and subPixelContours, so it reaches decode
|
|
56
|
+
* and geometry at once — there is no partial resume that honours a new tier.
|
|
57
|
+
* `dpi` is the px-per-mm scale, and every mm-denominated parameter after it
|
|
58
|
+
* (minPartAreaMm2, bridgeMm, smoothMm, simplifyMm, clusterGapMm) converts
|
|
59
|
+
* through it — so a changed dpi silently re-means all five. That is the
|
|
60
|
+
* subtle one: nothing about those values changed, but what they MEAN did.
|
|
61
|
+
*/
|
|
62
|
+
tier: "decode",
|
|
63
|
+
dpi: "decode",
|
|
64
|
+
// prefilter
|
|
65
|
+
prefilter: "prefilter",
|
|
66
|
+
prefilterRadius: "prefilter",
|
|
67
|
+
// ridge
|
|
68
|
+
ridgeHysteresisLow: "ridge",
|
|
69
|
+
ridgeHysteresisHigh: "ridge",
|
|
70
|
+
ridgeKernelScale: "ridge",
|
|
71
|
+
// quantise + fuse — the second detector channel and its union into the barrier
|
|
72
|
+
quantiseEnabled: "quantise",
|
|
73
|
+
quantiseColours: "quantise",
|
|
74
|
+
quantiseWeight: "fuse",
|
|
75
|
+
// flood
|
|
76
|
+
paperTolerance: "flood",
|
|
77
|
+
seedBandPx: "flood",
|
|
78
|
+
// segment
|
|
79
|
+
minPartAreaMm2: "segment",
|
|
80
|
+
maxParts: "segment",
|
|
81
|
+
bridgeMm: "segment",
|
|
82
|
+
mergeStrengthFactor: "segment",
|
|
83
|
+
// geometry
|
|
84
|
+
smoothMm: "geometry",
|
|
85
|
+
borderMm: "geometry",
|
|
86
|
+
bleedMm: "geometry",
|
|
87
|
+
simplifyMm: "geometry",
|
|
88
|
+
cleanMm: "geometry",
|
|
89
|
+
/*
|
|
90
|
+
* 🛑 `subPixelContours` is NOT here, and that is not an omission. It lives on
|
|
91
|
+
* the TIER config, not on TraceParams — so it cannot change without the tier
|
|
92
|
+
* changing, and a tier change is a new run rather than a resume. The
|
|
93
|
+
* `Record<keyof TraceParams, …>` above rejected it on the first compile,
|
|
94
|
+
* which is the whole reason the map is typed that way.
|
|
95
|
+
*/
|
|
96
|
+
// cluster
|
|
97
|
+
clusterGapMm: "cluster",
|
|
98
|
+
};
|
|
99
|
+
/** The pipeline order, straight from the union so it cannot drift from it. */
|
|
100
|
+
export const STAGE_ORDER = TRACE_STAGES;
|
|
101
|
+
export function stageIndex(stage) {
|
|
102
|
+
const i = STAGE_ORDER.indexOf(stage);
|
|
103
|
+
/*
|
|
104
|
+
* 🛑 Fails LOUD. An unknown stage reaching here means the union moved and
|
|
105
|
+
* this file did not; returning -1 or 0 would make the clamp silently resume
|
|
106
|
+
* from the beginning (merely wasteful) or from wherever was asked (actively
|
|
107
|
+
* wrong), and both read as working.
|
|
108
|
+
*/
|
|
109
|
+
if (i === -1)
|
|
110
|
+
throw new Error(`Unknown trace stage: ${stage}`);
|
|
111
|
+
return i;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* The earliest stage whose parameters differ between two runs.
|
|
115
|
+
*
|
|
116
|
+
* `null` means nothing relevant changed, so the requested resume point stands.
|
|
117
|
+
*
|
|
118
|
+
* Compared with `!==` after a JSON round-trip is deliberately NOT what happens
|
|
119
|
+
* here — every `TraceParams` member is a number, boolean or short string
|
|
120
|
+
* union, so a direct comparison is exact. A nested object would need the
|
|
121
|
+
* key-order-independent treatment Root Cause #92 is about; there isn't one, and
|
|
122
|
+
* the `Record` above is what stops one being added unnoticed.
|
|
123
|
+
*/
|
|
124
|
+
export function earliestChangedStage(previous, next) {
|
|
125
|
+
let earliest = null;
|
|
126
|
+
for (const key of Object.keys(PARAM_STAGE)) {
|
|
127
|
+
if (previous[key] === next[key])
|
|
128
|
+
continue;
|
|
129
|
+
const stage = PARAM_STAGE[key];
|
|
130
|
+
if (earliest === null || stageIndex(stage) < stageIndex(earliest)) {
|
|
131
|
+
earliest = stage;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return earliest;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* `resumeStage = max(requested, earliestChangedParamStage)` — where "max" means
|
|
138
|
+
* EARLIER in the pipeline, because a changed parameter invalidates its own
|
|
139
|
+
* stage and everything after it.
|
|
140
|
+
*/
|
|
141
|
+
export function resolveResumeStage(requested, previous, next) {
|
|
142
|
+
const changed = earliestChangedStage(previous, next);
|
|
143
|
+
if (changed === null || stageIndex(changed) >= stageIndex(requested)) {
|
|
144
|
+
return { stage: requested, clamped: false, requested, forcedBy: changed };
|
|
145
|
+
}
|
|
146
|
+
return { stage: changed, clamped: true, requested, forcedBy: changed };
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* The sentence the retry panel shows. Empty when nothing was clamped.
|
|
150
|
+
*
|
|
151
|
+
* Returns plain text rather than a translation key because this is the one
|
|
152
|
+
* place the two stage names have to appear together, and a key would hide the
|
|
153
|
+
* fact that the message is load-bearing rather than decorative.
|
|
154
|
+
*/
|
|
155
|
+
export function explainResume(decision) {
|
|
156
|
+
if (!decision.clamped)
|
|
157
|
+
return "";
|
|
158
|
+
return (`You changed a ${decision.forcedBy} parameter, so this run restarts from ` +
|
|
159
|
+
`${decision.stage} rather than resuming from ${decision.requested}.`);
|
|
160
|
+
}
|