@mohasinac/appkit 4.53.0 → 4.53.2

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 (520) hide show
  1. package/dist/.build-stamp.json +3 -3
  2. package/dist/_internal/client/scaffolds/AppShell.js +1 -1
  3. package/dist/_internal/client/theme/ThemeProvider.js +15 -1
  4. package/dist/_internal/server/features/auctions/og.d.ts +3 -1
  5. package/dist/_internal/server/features/auctions/og.js +3 -1
  6. package/dist/_internal/server/features/bundles/actions.js +1 -1
  7. package/dist/_internal/server/features/business-documents/download.d.ts +41 -0
  8. package/dist/_internal/server/features/business-documents/download.js +91 -0
  9. package/dist/_internal/server/features/categories/adapters.d.ts +1 -1
  10. package/dist/_internal/server/features/categories/adapters.js +10 -0
  11. package/dist/_internal/server/features/categories/price-guidance-resolve.d.ts +66 -0
  12. package/dist/_internal/server/features/categories/price-guidance-resolve.js +138 -0
  13. package/dist/_internal/server/features/checkout/actions.d.ts +14 -0
  14. package/dist/_internal/server/features/checkout/actions.js +106 -12
  15. package/dist/_internal/server/features/checkout/bundle-expansion.js +17 -0
  16. package/dist/_internal/server/features/checkout/data.d.ts +22 -0
  17. package/dist/_internal/server/features/checkout/group-rule-revalidation.d.ts +34 -0
  18. package/dist/_internal/server/features/checkout/group-rule-revalidation.js +124 -0
  19. package/dist/_internal/server/features/checkout/supplier-identity.d.ts +55 -0
  20. package/dist/_internal/server/features/checkout/supplier-identity.js +81 -0
  21. package/dist/_internal/server/features/classified/metadata.js +1 -1
  22. package/dist/_internal/server/features/classified/og.d.ts +3 -1
  23. package/dist/_internal/server/features/classified/og.js +3 -1
  24. package/dist/_internal/server/features/digital-code/metadata.js +1 -1
  25. package/dist/_internal/server/features/digital-code/og.d.ts +3 -1
  26. package/dist/_internal/server/features/digital-code/og.js +3 -1
  27. package/dist/_internal/server/features/digital-code/pool.d.ts +19 -4
  28. package/dist/_internal/server/features/digital-code/pool.js +19 -4
  29. package/dist/_internal/server/features/live/metadata.js +1 -1
  30. package/dist/_internal/server/features/live/og.d.ts +3 -1
  31. package/dist/_internal/server/features/live/og.js +3 -1
  32. package/dist/_internal/server/features/messages/actions.js +1 -1
  33. package/dist/_internal/server/features/parts/og.js +1 -1
  34. package/dist/_internal/server/features/pre-orders/og.d.ts +3 -1
  35. package/dist/_internal/server/features/pre-orders/og.js +3 -1
  36. package/dist/_internal/server/features/price-index/market.d.ts +57 -0
  37. package/dist/_internal/server/features/price-index/market.js +120 -0
  38. package/dist/_internal/server/features/price-index/search.d.ts +18 -0
  39. package/dist/_internal/server/features/price-index/search.js +47 -7
  40. package/dist/_internal/server/features/prize-draws/og.d.ts +3 -1
  41. package/dist/_internal/server/features/prize-draws/og.js +3 -1
  42. package/dist/_internal/server/features/products/group-members.d.ts +26 -0
  43. package/dist/_internal/server/features/products/group-members.js +7 -1
  44. package/dist/_internal/server/features/products/list-public.d.ts +12 -0
  45. package/dist/_internal/server/features/products/list-public.js +10 -1
  46. package/dist/_internal/server/features/products/listing-tab-counts.d.ts +25 -1
  47. package/dist/_internal/server/features/products/listing-tab-counts.js +128 -10
  48. package/dist/_internal/server/features/products/og.d.ts +3 -1
  49. package/dist/_internal/server/features/products/og.js +3 -1
  50. package/dist/_internal/server/features/search/scoped-sources.d.ts +26 -0
  51. package/dist/_internal/server/features/search/scoped-sources.js +252 -0
  52. package/dist/_internal/server/features/search/search-everything.d.ts +57 -0
  53. package/dist/_internal/server/features/search/search-everything.js +70 -20
  54. package/dist/_internal/server/features/seo/sitemap.js +6 -0
  55. package/dist/_internal/server/features/shared/listing-adapters.js +4 -2
  56. package/dist/_internal/server/features/sticker-trace/adapters.d.ts +11 -0
  57. package/dist/_internal/server/features/sticker-trace/adapters.js +1 -0
  58. package/dist/_internal/server/features/sticker-trace/promote-to-listings.d.ts +26 -0
  59. package/dist/_internal/server/features/sticker-trace/promote-to-listings.js +264 -0
  60. package/dist/_internal/server/features/sticker-trace/sheet-actions.d.ts +3 -1
  61. package/dist/_internal/server/features/sticker-trace/sheet-actions.js +32 -0
  62. package/dist/_internal/server/features/sticker-trace/storage.d.ts +20 -1
  63. package/dist/_internal/server/features/sticker-trace/storage.js +20 -1
  64. package/dist/_internal/server/features/stores/adapters.d.ts +1 -1
  65. package/dist/_internal/server/features/stores/adapters.js +16 -0
  66. package/dist/_internal/server/features/stores/index.d.ts +1 -0
  67. package/dist/_internal/server/features/stores/index.js +1 -0
  68. package/dist/_internal/server/features/stores/tabs.d.ts +30 -0
  69. package/dist/_internal/server/features/stores/tabs.js +124 -0
  70. package/dist/_internal/shared/checkout/rules/_defaults.js +0 -2
  71. package/dist/_internal/shared/checkout/rules/_limits.d.ts +14 -1
  72. package/dist/_internal/shared/checkout/rules/_limits.js +14 -1
  73. package/dist/_internal/shared/checkout/rules/_registry.js +2 -0
  74. package/dist/_internal/shared/checkout/rules/auction.rule.js +9 -1
  75. package/dist/_internal/shared/checkout/rules/bundle.rule.js +13 -0
  76. package/dist/_internal/shared/checkout/rules/index.d.ts +2 -0
  77. package/dist/_internal/shared/checkout/rules/index.js +9 -0
  78. package/dist/_internal/shared/checkout/rules/offer.rule.js +0 -1
  79. package/dist/_internal/shared/checkout/rules/payment-gate.d.ts +26 -0
  80. package/dist/_internal/shared/checkout/rules/payment-gate.js +133 -0
  81. package/dist/_internal/shared/checkout/rules/prize-draw.rule.js +29 -8
  82. package/dist/_internal/shared/checkout/rules/spares.rule.d.ts +16 -0
  83. package/dist/_internal/shared/checkout/rules/spares.rule.js +5 -0
  84. package/dist/_internal/shared/checkout/rules/types.d.ts +26 -2
  85. package/dist/_internal/shared/config/schema.d.ts +122 -0
  86. package/dist/_internal/shared/features/cart/schema.js +3 -2
  87. package/dist/_internal/shared/features/products/group-rules.d.ts +75 -0
  88. package/dist/_internal/shared/features/products/group-rules.js +142 -0
  89. package/dist/_internal/shared/listing-types/_registry.d.ts +24 -0
  90. package/dist/_internal/shared/listing-types/_registry.js +39 -1
  91. package/dist/_internal/shared/listing-types/art/config.d.ts +1 -0
  92. package/dist/_internal/shared/listing-types/art/config.js +2 -0
  93. package/dist/_internal/shared/listing-types/auction/config.d.ts +1 -0
  94. package/dist/_internal/shared/listing-types/auction/config.js +2 -0
  95. package/dist/_internal/shared/listing-types/availability.js +48 -0
  96. package/dist/_internal/shared/listing-types/capabilities.js +19 -0
  97. package/dist/_internal/shared/listing-types/classified/config.d.ts +1 -0
  98. package/dist/_internal/shared/listing-types/classified/config.js +2 -0
  99. package/dist/_internal/shared/listing-types/digital-code/config.d.ts +1 -0
  100. package/dist/_internal/shared/listing-types/digital-code/config.js +2 -0
  101. package/dist/_internal/shared/listing-types/feature-flags.js +1 -0
  102. package/dist/_internal/shared/listing-types/live/config.d.ts +1 -0
  103. package/dist/_internal/shared/listing-types/live/config.js +2 -0
  104. package/dist/_internal/shared/listing-types/pre-order/config.d.ts +1 -0
  105. package/dist/_internal/shared/listing-types/pre-order/config.js +2 -0
  106. package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +1 -0
  107. package/dist/_internal/shared/listing-types/prize-draw/config.js +2 -0
  108. package/dist/_internal/shared/listing-types/spares/config.d.ts +74 -0
  109. package/dist/_internal/shared/listing-types/spares/config.js +60 -0
  110. package/dist/_internal/shared/listing-types/spares/ctas.d.ts +1 -0
  111. package/dist/_internal/shared/listing-types/spares/ctas.js +4 -0
  112. package/dist/_internal/shared/listing-types/spares/og.js +1 -0
  113. package/dist/_internal/shared/listing-types/spares/schema.d.ts +2 -0
  114. package/dist/_internal/shared/listing-types/spares/schema.js +3 -0
  115. package/dist/_internal/shared/listing-types/spares/seed-factory.d.ts +1 -0
  116. package/dist/_internal/shared/listing-types/spares/seed-factory.js +1 -0
  117. package/dist/_internal/shared/listing-types/standard/config.d.ts +1 -0
  118. package/dist/_internal/shared/listing-types/standard/config.js +2 -0
  119. package/dist/_internal/shared/listing-types/stickers/config.d.ts +1 -0
  120. package/dist/_internal/shared/listing-types/stickers/config.js +2 -0
  121. package/dist/_internal/shared/search/match.d.ts +11 -0
  122. package/dist/_internal/shared/search/match.js +30 -3
  123. package/dist/_internal/shared/search/to-groups.d.ts +52 -0
  124. package/dist/_internal/shared/search/to-groups.js +141 -0
  125. package/dist/client.d.ts +8 -2
  126. package/dist/client.js +4 -1
  127. package/dist/constants/api-endpoints.d.ts +46 -15
  128. package/dist/constants/api-endpoints.js +35 -5
  129. package/dist/constants/cache-invalidation.js +3 -1
  130. package/dist/constants/field-names.d.ts +6 -0
  131. package/dist/constants/field-names.js +6 -0
  132. package/dist/features/about/components/PolicyPageView.d.ts +22 -2
  133. package/dist/features/about/components/PolicyPageView.js +14 -2
  134. package/dist/features/about/components/PublicProfileView.js +2 -1
  135. package/dist/features/about/components/ShippingPolicyView.js +42 -2
  136. package/dist/features/account/components/NotificationBell.js +1 -1
  137. package/dist/features/account/hooks/useProfileStats.js +5 -1
  138. package/dist/features/addresses/repository/addresses.repository.d.ts +16 -0
  139. package/dist/features/addresses/repository/addresses.repository.js +21 -0
  140. package/dist/features/admin/actions/admin-actions.js +16 -1
  141. package/dist/features/admin/components/AdminCategoryEditorView.js +19 -2
  142. package/dist/features/admin/components/AdminNavigationView.js +1 -1
  143. package/dist/features/admin/components/AdminPageHeader.js +1 -1
  144. package/dist/features/admin/components/AdminProductEditorView.js +17 -2
  145. package/dist/features/admin/components/AdminSidebar.js +1 -1
  146. package/dist/features/admin/components/AdminSiteSettingsView.js +39 -8
  147. package/dist/features/admin/components/AdminSparesView.d.ts +12 -0
  148. package/dist/features/admin/components/AdminSparesView.js +30 -0
  149. package/dist/features/admin/components/AdminUsersView.js +9 -7
  150. package/dist/features/admin/components/index.d.ts +2 -0
  151. package/dist/features/admin/components/index.js +1 -0
  152. package/dist/features/admin/components/sections/adminSectionsTypes.js +7 -0
  153. package/dist/features/admin/constants/filter-tabs.d.ts +3 -0
  154. package/dist/features/admin/constants/filter-tabs.js +1 -0
  155. package/dist/features/admin/schemas/firestore.d.ts +26 -2
  156. package/dist/features/auctions/components/AuctionDetailPageView.js +12 -18
  157. package/dist/features/auth/repository/user.repository.d.ts +13 -0
  158. package/dist/features/auth/repository/user.repository.js +28 -0
  159. package/dist/features/auth/schemas/firestore.d.ts +2 -0
  160. package/dist/features/auth/schemas/firestore.js +2 -0
  161. package/dist/features/business-documents/repository/business-documents.repository.d.ts +58 -0
  162. package/dist/features/business-documents/repository/business-documents.repository.js +54 -0
  163. package/dist/features/business-documents/schemas/firestore.d.ts +105 -0
  164. package/dist/features/business-documents/schemas/firestore.js +75 -0
  165. package/dist/features/cart/actions/cart-actions.js +83 -6
  166. package/dist/features/cart/repository/cart.repository.js +32 -4
  167. package/dist/features/cart/schemas/firestore.d.ts +20 -0
  168. package/dist/features/cart/schemas/index.d.ts +2 -2
  169. package/dist/features/catalogue/components/PublicCatalogueItemDetailView.js +1 -1
  170. package/dist/features/categories/api/[id]/price-guidance/route.d.ts +42 -0
  171. package/dist/features/categories/api/[id]/price-guidance/route.js +90 -0
  172. package/dist/features/categories/components/BrandDetailPageView.js +32 -8
  173. package/dist/features/categories/components/BrandDetailTabs.d.ts +7 -1
  174. package/dist/features/categories/components/BrandDetailTabs.js +28 -3
  175. package/dist/features/categories/components/BundleCollage.js +3 -2
  176. package/dist/features/categories/components/BundleItemsPicker.js +3 -4
  177. package/dist/features/categories/components/CategoriesIndexListing.js +23 -8
  178. package/dist/features/categories/components/CategoryDetailPageView.js +157 -20
  179. package/dist/features/categories/components/CategoryDetailTabs.d.ts +7 -1
  180. package/dist/features/categories/components/CategoryDetailTabs.js +41 -7
  181. package/dist/features/categories/components/CategoryGrid.js +10 -1
  182. package/dist/features/categories/components/PriceGuidanceHint.d.ts +29 -0
  183. package/dist/features/categories/components/PriceGuidanceHint.js +61 -0
  184. package/dist/features/categories/components/SubcategoryCardRow.d.ts +27 -0
  185. package/dist/features/categories/components/SubcategoryCardRow.js +98 -0
  186. package/dist/features/categories/constants/category-tabs.d.ts +20 -25
  187. package/dist/features/categories/constants/category-tabs.js +22 -39
  188. package/dist/features/categories/repository/categories.repository.d.ts +12 -0
  189. package/dist/features/categories/repository/categories.repository.js +20 -0
  190. package/dist/features/categories/schemas/firestore.d.ts +22 -1
  191. package/dist/features/categories/schemas/firestore.js +10 -0
  192. package/dist/features/categories/schemas/index.d.ts +6 -0
  193. package/dist/features/categories/schemas/index.js +2 -0
  194. package/dist/features/categories/types/index.d.ts +8 -0
  195. package/dist/features/categories/utils/taxonomy-visual.d.ts +16 -3
  196. package/dist/features/categories/utils/taxonomy-visual.js +26 -10
  197. package/dist/features/classified/components/ClassifiedDetailPageView.js +14 -10
  198. package/dist/features/contact/components/ContactPageView.d.ts +33 -1
  199. package/dist/features/contact/components/ContactPageView.js +58 -28
  200. package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +14 -10
  201. package/dist/features/grouped/components/GroupedListingDetailView.js +9 -1
  202. package/dist/features/grouped/schemas/firestore.d.ts +5 -0
  203. package/dist/features/homepage/actions/homepage-section-actions.d.ts +3 -3
  204. package/dist/features/homepage/components/CollectionCardsSection.d.ts +28 -6
  205. package/dist/features/homepage/components/CollectionCardsSection.js +43 -8
  206. package/dist/features/homepage/components/HowItWorksSection.d.ts +23 -6
  207. package/dist/features/homepage/components/HowItWorksSection.js +4 -4
  208. package/dist/features/homepage/components/PromoGrid.d.ts +31 -2
  209. package/dist/features/homepage/components/PromoGrid.js +12 -3
  210. package/dist/features/homepage/components/TestimonialsCarousel.d.ts +34 -2
  211. package/dist/features/homepage/components/TestimonialsCarousel.js +1 -1
  212. package/dist/features/homepage/components/index.d.ts +0 -20
  213. package/dist/features/homepage/components/index.js +0 -11
  214. package/dist/features/homepage/index.d.ts +0 -2
  215. package/dist/features/homepage/index.js +0 -2
  216. package/dist/features/homepage/lib/section-renderer.d.ts +9 -0
  217. package/dist/features/homepage/lib/section-renderer.js +202 -58
  218. package/dist/features/homepage/repository/homepage-sections.repository.d.ts +35 -3
  219. package/dist/features/homepage/repository/homepage-sections.repository.js +58 -8
  220. package/dist/features/homepage/schemas/firestore.d.ts +106 -3
  221. package/dist/features/homepage/schemas/firestore.js +32 -2
  222. package/dist/features/homepage/schemas/index.d.ts +36 -7
  223. package/dist/features/homepage/schemas/index.js +39 -27
  224. package/dist/features/homepage/server.d.ts +0 -3
  225. package/dist/features/homepage/server.js +0 -3
  226. package/dist/features/homepage/types/index.d.ts +0 -47
  227. package/dist/features/homepage/types/index.js +49 -0
  228. package/dist/features/layout/AppLayoutShell.js +1 -1
  229. package/dist/features/layout/BottomNavItem.js +1 -1
  230. package/dist/features/layout/BottomSheet.js +1 -1
  231. package/dist/features/layout/TitleBarLayout.js +1 -1
  232. package/dist/features/live/components/LiveItemDetailPageView.js +14 -10
  233. package/dist/features/media/hooks/useMedia.js +17 -0
  234. package/dist/features/media/repository/media-assets.repository.d.ts +46 -0
  235. package/dist/features/media/repository/media-assets.repository.js +31 -0
  236. package/dist/features/media/trust-signals.d.ts +85 -0
  237. package/dist/features/media/trust-signals.js +126 -0
  238. package/dist/features/parts/components/PartDetailPageView.d.ts +14 -1
  239. package/dist/features/parts/components/PartDetailPageView.js +2 -2
  240. package/dist/features/parts/components/PartsIndexPageView.d.ts +11 -2
  241. package/dist/features/parts/components/PartsIndexPageView.js +2 -2
  242. package/dist/features/parts/components/PartsSearchBox.d.ts +9 -0
  243. package/dist/features/parts/components/PartsSearchBox.js +57 -0
  244. package/dist/features/parts/schemas/firestore.d.ts +149 -3
  245. package/dist/features/parts/schemas/firestore.js +184 -0
  246. package/dist/features/payments/repository/payout.repository.d.ts +15 -0
  247. package/dist/features/payments/repository/payout.repository.js +21 -0
  248. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +12 -18
  249. package/dist/features/pre-orders/components/PreOrdersIndexListing.js +1 -1
  250. package/dist/features/price-index/components/PriceIndexToolView.d.ts +24 -1
  251. package/dist/features/price-index/components/PriceIndexToolView.js +299 -17
  252. package/dist/features/price-index/lookup-target.d.ts +48 -0
  253. package/dist/features/price-index/lookup-target.js +107 -0
  254. package/dist/features/products/components/AvailabilityScopeHint.d.ts +22 -0
  255. package/dist/features/products/components/AvailabilityScopeHint.js +27 -0
  256. package/dist/features/products/components/CompareOverlay.d.ts +20 -2
  257. package/dist/features/products/components/CompareOverlay.js +23 -3
  258. package/dist/features/products/components/CustomSectionTabContent.d.ts +31 -0
  259. package/dist/features/products/components/CustomSectionTabContent.js +29 -3
  260. package/dist/features/products/components/GroupMemberPicker.d.ts +19 -1
  261. package/dist/features/products/components/GroupMemberPicker.js +46 -8
  262. package/dist/features/products/components/GroupSettingsPanel.d.ts +11 -1
  263. package/dist/features/products/components/GroupSettingsPanel.js +92 -3
  264. package/dist/features/products/components/PrizeDrawDetailPageView.js +1 -1
  265. package/dist/features/products/components/PrizeDrawEntryActions.d.ts +15 -1
  266. package/dist/features/products/components/PrizeDrawEntryActions.js +70 -8
  267. package/dist/features/products/components/ProductDetailPageView.js +81 -17
  268. package/dist/features/products/components/ProductForm.d.ts +13 -1
  269. package/dist/features/products/components/ProductForm.js +16 -2
  270. package/dist/features/products/components/ProductsIndexListing.d.ts +16 -1
  271. package/dist/features/products/components/ProductsIndexListing.js +3 -3
  272. package/dist/features/products/components/ShowGroupSection.js +15 -2
  273. package/dist/features/products/components/SparesListView.d.ts +7 -0
  274. package/dist/features/products/components/SparesListView.js +39 -0
  275. package/dist/features/products/components/SublistingCarouselSection.js +2 -1
  276. package/dist/features/products/constants/action-defs.d.ts +1 -0
  277. package/dist/features/products/constants/action-defs.js +1 -0
  278. package/dist/features/products/repository/products.repository.d.ts +99 -0
  279. package/dist/features/products/repository/products.repository.js +240 -18
  280. package/dist/features/products/schemas/firestore.d.ts +97 -4
  281. package/dist/features/products/schemas/firestore.js +104 -0
  282. package/dist/features/products/schemas/index.d.ts +10 -19
  283. package/dist/features/products/schemas/index.js +23 -6
  284. package/dist/features/products/types/index.d.ts +45 -1
  285. package/dist/features/products/utils/group-member-image.d.ts +46 -0
  286. package/dist/features/products/utils/group-member-image.js +4 -0
  287. package/dist/features/products/utils/listing-badge-variant.js +4 -0
  288. package/dist/features/reviews/components/ReviewsList.js +1 -1
  289. package/dist/features/scams/components/ScamProfileView.js +1 -1
  290. package/dist/features/search/components/EntityTypeahead.d.ts +44 -0
  291. package/dist/features/search/components/EntityTypeahead.js +92 -0
  292. package/dist/features/search/components/Search.d.ts +12 -1
  293. package/dist/features/search/components/Search.js +47 -3
  294. package/dist/features/search/components/SearchFacetRail.d.ts +11 -0
  295. package/dist/features/search/components/SearchFacetRail.js +92 -0
  296. package/dist/features/search/components/SearchResultsClient.d.ts +33 -0
  297. package/dist/features/search/components/SearchResultsClient.js +103 -0
  298. package/dist/features/search/components/SearchResultsPageView.d.ts +15 -1
  299. package/dist/features/search/components/SearchResultsPageView.js +2 -2
  300. package/dist/features/search/components/index.d.ts +0 -6
  301. package/dist/features/search/components/index.js +0 -3
  302. package/dist/features/search/hooks/useNavSuggestions.d.ts +13 -0
  303. package/dist/features/search/hooks/useScopedSearch.d.ts +34 -0
  304. package/dist/features/search/hooks/useScopedSearch.js +114 -0
  305. package/dist/features/search/hooks/useSiteSearch.d.ts +26 -0
  306. package/dist/features/search/hooks/useSiteSearch.js +149 -0
  307. package/dist/features/search/index.d.ts +0 -4
  308. package/dist/features/search/index.js +0 -4
  309. package/dist/features/search/manifest.d.ts +12 -0
  310. package/dist/features/search/manifest.js +17 -2
  311. package/dist/features/search/server.d.ts +0 -3
  312. package/dist/features/search/server.js +0 -3
  313. package/dist/features/seller/components/SellerListingTypeView.d.ts +1 -1
  314. package/dist/features/seller/components/SellerListingTypeView.js +20 -0
  315. package/dist/features/seller/components/SellerPayoutSettingsView.js +35 -14
  316. package/dist/features/seller/components/SellerProductShell.d.ts +1 -1
  317. package/dist/features/seller/components/SellerProductShell.js +2 -1
  318. package/dist/features/seller/components/SellerProductsView.js +3 -2
  319. package/dist/features/seller/components/SellerSidebar.js +1 -1
  320. package/dist/features/seller/components/SellerSparesView.d.ts +17 -0
  321. package/dist/features/seller/components/SellerSparesView.js +6 -0
  322. package/dist/features/seller/components/index.d.ts +2 -0
  323. package/dist/features/seller/components/index.js +1 -0
  324. package/dist/features/shell/CommandPalette.js +1 -1
  325. package/dist/features/sticker-trace/schemas/firestore.d.ts +19 -0
  326. package/dist/features/stores/components/StoreAuctionsListing.js +2 -1
  327. package/dist/features/stores/components/StoreDetailLayoutView.d.ts +1 -1
  328. package/dist/features/stores/components/StoreDetailLayoutView.js +7 -82
  329. package/dist/features/stores/components/StoreHeader.js +1 -2
  330. package/dist/features/stores/components/StoreSparesPageView.d.ts +27 -0
  331. package/dist/features/stores/components/StoreSparesPageView.js +48 -0
  332. package/dist/features/stores/schemas/firestore.d.ts +19 -0
  333. package/dist/features/tester/seed-data/authored/buying__spares-and-groups.d.ts +2 -0
  334. package/dist/features/tester/seed-data/authored/buying__spares-and-groups.js +96 -0
  335. package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.d.ts +2 -0
  336. package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.js +392 -45
  337. package/dist/features/tester/seed-data/authored/content-discovery__category-tabs-franchise-bundles.js +54 -32
  338. package/dist/features/tester/seed-data/authored/content-discovery__parts-database.js +3 -2
  339. package/dist/features/tester/seed-data/authored/content-discovery__price-index-and-compare.d.ts +2 -0
  340. package/dist/features/tester/seed-data/authored/content-discovery__price-index-and-compare.js +73 -0
  341. package/dist/features/tester/seed-data/authored/content-discovery__site-wide-index.d.ts +2 -0
  342. package/dist/features/tester/seed-data/authored/content-discovery__site-wide-index.js +340 -0
  343. package/dist/features/tester/seed-data/authored/index.js +16 -0
  344. package/dist/features/tester/seed-data/authored/search-and-nav__header-search.d.ts +1 -0
  345. package/dist/features/tester/seed-data/authored/search-and-nav__header-search.js +57 -0
  346. package/dist/features/tester/seed-data/authored/selling__spares-and-group-editing.d.ts +2 -0
  347. package/dist/features/tester/seed-data/authored/selling__spares-and-group-editing.js +77 -0
  348. package/dist/features/tester/seed-data/authored/tools__sticker-promote-to-listings.d.ts +2 -0
  349. package/dist/features/tester/seed-data/authored/tools__sticker-promote-to-listings.js +58 -0
  350. package/dist/features/tester/seed-data/authored/tools__sticker-tracer.js +5 -4
  351. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +384 -18
  352. package/dist/index.d.ts +17 -57
  353. package/dist/index.js +35 -96
  354. package/dist/next/routing/route-map.d.ts +42 -1
  355. package/dist/next/routing/route-map.js +45 -0
  356. package/dist/providers/db-firebase/base.repository.d.ts +22 -0
  357. package/dist/providers/db-firebase/base.repository.js +36 -0
  358. package/dist/schemas/registry.d.ts +15 -6
  359. package/dist/security/blind-index-tokens.d.ts +54 -0
  360. package/dist/security/blind-index-tokens.js +152 -0
  361. package/dist/security/index.d.ts +1 -1
  362. package/dist/security/index.js +1 -1
  363. package/dist/security/settings-encryption.d.ts +35 -0
  364. package/dist/security/settings-encryption.js +91 -0
  365. package/dist/seed/_helpers/brand-rows.js +38 -14
  366. package/dist/seed/_helpers/category-forest.js +73 -7
  367. package/dist/seed/_helpers/category-images-generated.d.ts +25 -6
  368. package/dist/seed/_helpers/category-images-generated.js +81 -6
  369. package/dist/seed/_helpers/category-models.d.ts +1 -1
  370. package/dist/seed/_helpers/category-models.js +7 -1
  371. package/dist/seed/_helpers/category-parts-glossary-map.js +8 -0
  372. package/dist/seed/_helpers/category-parts.d.ts +1 -1
  373. package/dist/seed/_helpers/category-parts.js +50 -2
  374. package/dist/seed/_helpers/character-features.d.ts +1 -1
  375. package/dist/seed/_helpers/character-features.js +2 -1
  376. package/dist/seed/_helpers/franchise-rows.js +10 -2
  377. package/dist/seed/_helpers/media.d.ts +47 -0
  378. package/dist/seed/_helpers/media.js +34 -0
  379. package/dist/seed/authenticity-knowledge-seed-data.d.ts +49 -5
  380. package/dist/seed/authenticity-knowledge-seed-data.js +10001 -549
  381. package/dist/seed/categories-seed-data.js +124 -20
  382. package/dist/seed/grouped-listings-seed-data.js +16 -0
  383. package/dist/seed/homepage-sections-seed-data.js +94 -5
  384. package/dist/seed/index.d.ts +2 -3
  385. package/dist/seed/index.js +2 -2
  386. package/dist/seed/manifest.js +3 -0
  387. package/dist/seed/media-assets-seed-data.d.ts +1 -1
  388. package/dist/seed/media-assets-seed-data.js +746 -196
  389. package/dist/seed/model-composition-seed-data.js +122 -6
  390. package/dist/seed/part-glossary-seed-data.d.ts +1 -1
  391. package/dist/seed/part-glossary-seed-data.js +37219 -463
  392. package/dist/seed/products-art-seed-data.js +7 -18
  393. package/dist/seed/products-auctions-seed-data.js +56 -47
  394. package/dist/seed/products-beyblade-x-seed-data.d.ts +2 -0
  395. package/dist/seed/products-beyblade-x-seed-data.js +476 -0
  396. package/dist/seed/products-catalogue-seed-data.d.ts +5 -5
  397. package/dist/seed/products-catalogue-seed-data.js +1500 -1240
  398. package/dist/seed/products-classifieds-seed-data.js +9 -27
  399. package/dist/seed/products-digital-codes-seed-data.js +9 -18
  400. package/dist/seed/products-live-items-seed-data.js +5 -13
  401. package/dist/seed/products-preorders-seed-data.js +67 -33
  402. package/dist/seed/products-prize-draws-seed-data.js +8 -17
  403. package/dist/seed/products-spares-seed-data.d.ts +2 -0
  404. package/dist/seed/products-spares-seed-data.js +368 -0
  405. package/dist/seed/products-standard-seed-data.js +39 -126
  406. package/dist/seed/products-stickers-seed-data.js +59 -15
  407. package/dist/seed/site-settings-seed-data.js +8 -0
  408. package/dist/seo/json-ld.d.ts +25 -0
  409. package/dist/seo/json-ld.js +28 -0
  410. package/dist/server-entry.d.ts +3 -1
  411. package/dist/server-entry.js +2 -2
  412. package/dist/server.d.ts +11 -9
  413. package/dist/server.js +35 -25
  414. package/dist/styles.css +202 -1
  415. package/dist/tailwind-input.css +31 -17
  416. package/dist/tailwind-utilities.css +1 -1
  417. package/dist/ui/components/Accordion.js +1 -1
  418. package/dist/ui/components/Breadcrumb.js +1 -1
  419. package/dist/ui/components/DetailPageGallery.js +0 -2
  420. package/dist/ui/components/DetailPageHero.js +0 -1
  421. package/dist/ui/components/DetailPageTabs.js +1 -1
  422. package/dist/ui/components/Divider.js +3 -3
  423. package/dist/ui/components/GatedPrice.js +5 -1
  424. package/dist/ui/components/HorizontalScroller.js +1 -1
  425. package/dist/ui/components/ListingLayout.js +3 -3
  426. package/dist/ui/components/MediaTabs.style.css +81 -0
  427. package/dist/ui/components/Pagination.js +1 -1
  428. package/dist/ui/components/PendingValue.d.ts +45 -0
  429. package/dist/ui/components/PendingValue.js +7 -0
  430. package/dist/ui/components/Radio.style.css +119 -0
  431. package/dist/ui/components/RatingDisplay.js +2 -2
  432. package/dist/ui/components/SettingsSection.js +0 -2
  433. package/dist/ui/components/SiteLogo.js +3 -0
  434. package/dist/ui/components/SiteMark.js +3 -0
  435. package/dist/ui/components/SortDropdown.js +1 -1
  436. package/dist/ui/components/SpecTable.d.ts +58 -0
  437. package/dist/ui/components/SpecTable.js +8 -0
  438. package/dist/ui/components/StarRating.js +1 -3
  439. package/dist/ui/components/SummaryCard.js +1 -1
  440. package/dist/ui/components/index.style.css +1 -0
  441. package/dist/ui/icons/icon-registry.d.ts +1 -0
  442. package/dist/ui/icons/icon-registry.js +9 -1
  443. package/dist/ui/index.d.ts +4 -0
  444. package/dist/ui/index.js +2 -0
  445. package/dist/utils/search-txt-query.d.ts +12 -0
  446. package/dist/utils/search-txt-query.js +12 -0
  447. package/package.json +1 -1
  448. package/scripts/dedupe-peer-deps.mjs +18 -0
  449. package/scripts/seed-cli.mjs +250 -35
  450. package/scripts/verify-css-build.mjs +118 -37
  451. package/dist/_internal/server/features/search/actions.d.ts +0 -7
  452. package/dist/_internal/server/features/search/actions.js +0 -21
  453. package/dist/_internal/server/features/search/data.d.ts +0 -15
  454. package/dist/_internal/server/features/search/data.js +0 -18
  455. package/dist/_internal/server/features/search/index.d.ts +0 -3
  456. package/dist/_internal/server/features/search/index.js +0 -2
  457. package/dist/features/homepage/api/[id]/route.d.ts +0 -23
  458. package/dist/features/homepage/api/[id]/route.js +0 -103
  459. package/dist/features/homepage/api/route.d.ts +0 -14
  460. package/dist/features/homepage/api/route.js +0 -140
  461. package/dist/features/homepage/api/sections/[id]/route.d.ts +0 -26
  462. package/dist/features/homepage/api/sections/[id]/route.js +0 -95
  463. package/dist/features/homepage/api/sections/route.d.ts +0 -13
  464. package/dist/features/homepage/api/sections/route.js +0 -82
  465. package/dist/features/homepage/components/AdvertisementBanner.d.ts +0 -14
  466. package/dist/features/homepage/components/AdvertisementBanner.js +0 -35
  467. package/dist/features/homepage/components/BeforeAfterCard.d.ts +0 -9
  468. package/dist/features/homepage/components/BeforeAfterCard.js +0 -73
  469. package/dist/features/homepage/components/FeaturedResultsSection.d.ts +0 -17
  470. package/dist/features/homepage/components/FeaturedResultsSection.js +0 -17
  471. package/dist/features/homepage/components/HeroBanner.d.ts +0 -7
  472. package/dist/features/homepage/components/HeroBanner.js +0 -43
  473. package/dist/features/homepage/components/HeroSection.d.ts +0 -7
  474. package/dist/features/homepage/components/HeroSection.js +0 -6
  475. package/dist/features/homepage/components/HomepageSkeleton.d.ts +0 -2
  476. package/dist/features/homepage/components/HomepageSkeleton.js +0 -21
  477. package/dist/features/homepage/components/HomepageView.d.ts +0 -25
  478. package/dist/features/homepage/components/HomepageView.js +0 -5
  479. package/dist/features/homepage/components/NewsletterBanner.d.ts +0 -23
  480. package/dist/features/homepage/components/NewsletterBanner.js +0 -37
  481. package/dist/features/homepage/components/SiteFeaturesSection.d.ts +0 -14
  482. package/dist/features/homepage/components/SiteFeaturesSection.js +0 -11
  483. package/dist/features/homepage/components/TrustBadges.d.ts +0 -6
  484. package/dist/features/homepage/components/TrustBadges.js +0 -46
  485. package/dist/features/homepage/components/TrustIndicatorsSection.d.ts +0 -12
  486. package/dist/features/homepage/components/TrustIndicatorsSection.js +0 -11
  487. package/dist/features/homepage/hooks/useHomepage.d.ts +0 -11
  488. package/dist/features/homepage/hooks/useHomepage.js +0 -17
  489. package/dist/features/homepage/hooks/useHomepageSections.d.ts +0 -2
  490. package/dist/features/homepage/hooks/useHomepageSections.js +0 -10
  491. package/dist/features/homepage/repository/homepage.repository.d.ts +0 -11
  492. package/dist/features/homepage/repository/homepage.repository.js +0 -25
  493. package/dist/features/search/actions/index.d.ts +0 -1
  494. package/dist/features/search/actions/index.js +0 -1
  495. package/dist/features/search/actions/search-actions.d.ts +0 -18
  496. package/dist/features/search/actions/search-actions.js +0 -43
  497. package/dist/features/search/api/route.d.ts +0 -22
  498. package/dist/features/search/api/route.js +0 -128
  499. package/dist/features/search/columns/index.d.ts +0 -17
  500. package/dist/features/search/columns/index.js +0 -49
  501. package/dist/features/search/components/SearchFiltersRow.d.ts +0 -22
  502. package/dist/features/search/components/SearchFiltersRow.js +0 -21
  503. package/dist/features/search/components/SearchResultsSection.d.ts +0 -53
  504. package/dist/features/search/components/SearchResultsSection.js +0 -35
  505. package/dist/features/search/components/SearchView.d.ts +0 -27
  506. package/dist/features/search/components/SearchView.js +0 -8
  507. package/dist/features/search/hooks/useSearch.d.ts +0 -21
  508. package/dist/features/search/hooks/useSearch.js +0 -33
  509. package/dist/features/search/repository/search.repository.d.ts +0 -14
  510. package/dist/features/search/repository/search.repository.js +0 -59
  511. package/dist/features/search/schemas/index.d.ts +0 -70
  512. package/dist/features/search/schemas/index.js +0 -36
  513. package/dist/features/search/types/index.d.ts +0 -48
  514. package/dist/features/stores/components/StoreScopedSearch.d.ts +0 -17
  515. package/dist/features/stores/components/StoreScopedSearch.js +0 -27
  516. package/dist/seed/defaults/homepage-sections.d.ts +0 -2
  517. package/dist/seed/defaults/homepage-sections.js +0 -60
  518. package/dist/seed/factories/homepage-section.factory.d.ts +0 -10
  519. package/dist/seed/factories/homepage-section.factory.js +0 -13
  520. /package/dist/{features/search/types/index.js → _internal/shared/listing-types/spares/og.d.ts} +0 -0
@@ -71,6 +71,97 @@ export function decryptSecret(encrypted) {
71
71
  export function isSecretEncrypted(value) {
72
72
  return encEnvelopeKind(value) === "settings";
73
73
  }
74
+ /*
75
+ * ---------------------------------------------------------------------------
76
+ * Binary envelope — for FILE BYTES, not strings.
77
+ * ---------------------------------------------------------------------------
78
+ *
79
+ * Same algorithm, same key, same `enc:v1:` marker as the string form above, but
80
+ * a BINARY layout rather than a dot-joined base64 triple:
81
+ *
82
+ * "enc:v1:" (7 ASCII bytes) || iv (12) || authTag (16) || ciphertext
83
+ *
84
+ * 🛑 Why not reuse `encryptSecret` with a base64 string. Two reasons, and the
85
+ * first one is a hard ceiling rather than a preference:
86
+ *
87
+ * 1. Base64 inflates by 4/3, so the 680 KB Udyam certificate becomes ~907 KB
88
+ * of string before the envelope is added. A Firestore document is capped
89
+ * at 1 MiB, so that approach is one slightly-larger PDF away from an
90
+ * unrecoverable write failure — and it fails at UPLOAD time, after the
91
+ * user has handed over the document.
92
+ * 2. The bytes belong in Storage regardless, and Storage takes a Buffer. Round
93
+ * -tripping them through base64 to satisfy a string API costs 33% of the
94
+ * object size and every byte of it is paid again on download.
95
+ *
96
+ * So: metadata in Firestore, ciphertext in Storage. These two functions are the
97
+ * seam between them.
98
+ */
99
+ /** ASCII `enc:v1:` — the same marker the string envelope uses, as raw bytes. */
100
+ const BINARY_PREFIX = Buffer.from(PREFIX, "ascii");
101
+ const TAG_BYTES = 16;
102
+ /**
103
+ * AES-256-GCM a file's bytes under `SETTINGS_ENCRYPTION_KEY`.
104
+ *
105
+ * Throws when the key is unset — deliberately, and identically to
106
+ * `encryptSecret`. A document store that silently writes plaintext when
107
+ * misconfigured is worse than one that refuses, because nothing downstream can
108
+ * tell the two apart afterwards.
109
+ */
110
+ export function encryptBuffer(plaintext) {
111
+ const key = getMasterKey();
112
+ const { randomBytes, createCipheriv } = nodeCrypto();
113
+ const iv = randomBytes(IV_BYTES);
114
+ const cipher = createCipheriv(ALGORITHM, key, iv);
115
+ const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);
116
+ return Buffer.concat([BINARY_PREFIX, iv, cipher.getAuthTag(), ciphertext]);
117
+ }
118
+ /**
119
+ * Reverse `encryptBuffer`.
120
+ *
121
+ * 🛑 Unlike `decryptSecret`, a buffer with no `enc:v1:` prefix is REJECTED
122
+ * rather than passed through. That asymmetry is intentional. `decryptSecret`
123
+ * tolerates plaintext because the settings collection genuinely holds
124
+ * unencrypted placeholders that predate encryption, so passing them through is
125
+ * the migration path. Here there is no such legacy: every object this reads was
126
+ * written by `encryptBuffer`, so an unprefixed buffer means the wrong object,
127
+ * a truncated download, or an upload that bypassed encryption — and returning
128
+ * it verbatim would serve one of those to an admin as though it were fine.
129
+ *
130
+ * GCM authentication also means `final()` throws on any tampering or on the
131
+ * wrong key, so a corrupted object fails loudly instead of yielding garbage.
132
+ */
133
+ export function decryptBuffer(encrypted) {
134
+ if (!isBufferEncrypted(encrypted)) {
135
+ // Interpolates PREFIX rather than writing "enc:v1:" a second time —
136
+ // audit-pii-crypto's ENC_PREFIX_REDECLARED rule exists because two
137
+ // independent copies of that literal are how two incompatible formats
138
+ // came to look identical to every "is this encrypted" check.
139
+ throw new Error(`Buffer is not settings-encrypted — expected a '${PREFIX}' binary envelope`);
140
+ }
141
+ const ivStart = BINARY_PREFIX.length;
142
+ const tagStart = ivStart + IV_BYTES;
143
+ const dataStart = tagStart + TAG_BYTES;
144
+ const { createDecipheriv } = nodeCrypto();
145
+ const decipher = createDecipheriv(ALGORITHM, getMasterKey(), encrypted.subarray(ivStart, tagStart));
146
+ decipher.setAuthTag(encrypted.subarray(tagStart, dataStart));
147
+ return Buffer.concat([
148
+ decipher.update(encrypted.subarray(dataStart)),
149
+ decipher.final(),
150
+ ]);
151
+ }
152
+ /**
153
+ * True when `buf` carries the binary envelope AND is long enough to hold a
154
+ * complete one.
155
+ *
156
+ * The length check is not pedantry: without it a 7-byte buffer containing only
157
+ * the prefix passes, and `decryptBuffer` then hands `createDecipheriv` a
158
+ * zero-length IV, which throws `Invalid initialization vector` — an error that
159
+ * describes the crypto call rather than the truncated download that caused it.
160
+ */
161
+ export function isBufferEncrypted(buf) {
162
+ return (buf.length > BINARY_PREFIX.length + IV_BYTES + TAG_BYTES &&
163
+ buf.subarray(0, BINARY_PREFIX.length).equals(BINARY_PREFIX));
164
+ }
74
165
  export function maskSecret(value) {
75
166
  if (!value || value.length < 12) {
76
167
  return "****";
@@ -34,23 +34,33 @@
34
34
  * never attributes a product code to Tomy alone). Every row below is one
35
35
  * B6 can put at least one real product behind.
36
36
  *
37
- * ## 🛑 Why these are seedPhoto tiles and not 28 committed logo SVGs
37
+ * ## 🛑 Real logos, decided 2026-10-20 — and what the earlier caution was right about
38
38
  *
39
- * The plan recommended committing `public/images/brands/<slug>.svg` to avoid
40
- * `seedExtMedia`, which persists an `/api/media/ext?url=…` into Firestore and
41
- * costs a lambda plus a third-party fetch plus a full sharp encode PER IMAGE
42
- * PER RENDER — Root Cause #104, the thing that took Fast Origin Transfer to
43
- * 52.52 GB against a 10 GB cap.
39
+ * This block used to argue for neutral `seedPhoto` tiles over real logos, on
40
+ * the grounds that 26 of these are marques we do not own and "shipping drawn
41
+ * approximations of their logos is trademark reproduction for commercial
42
+ * use… a licensed-asset task, not a seed task."
44
43
  *
45
- * That reasoning is right and the conclusion has moved, because `seedPhoto`
46
- * now resolves to one of six STATIC LOCAL SVG tiles served `immutable` from
47
- * `/images/`. It already has the property the recommendation was reaching for:
48
- * no proxy, no third-party fetch, no per-render cost.
44
+ * That call was reversed deliberately, not forgotten. Real wordmarks are now
45
+ * used to IDENTIFY the line a listing belongs to, which is nominative use, and
46
+ * the help pages carry an explicit fair-use and non-affiliation notice naming
47
+ * every marque. Provenance for each file is recorded per-image in
48
+ * `docs/research/taxonomy-images-2026-10/image-provenance.json`, so
49
+ * attribution is possible and a takedown is mechanical.
49
50
  *
50
- * And it avoids a question committing the files would raise — 26 of these are
51
- * marques we do not own, so shipping drawn approximations of their logos is
52
- * trademark reproduction for commercial use. A neutral tile is honest about
53
- * being a placeholder. Real logos are a licensed-asset task, not a seed task.
51
+ * 🛑 Two things the old reasoning got right and this did NOT change:
52
+ *
53
+ * 1. **Never `seedExtMedia`.** A persisted `/api/media/ext?url=…` costs a
54
+ * lambda plus a third-party fetch plus a sharp encode PER RENDER — Root
55
+ * Cause #104, which took Fast Origin Transfer to 52.52 GB against a
56
+ * 10 GB cap. These are fetched ONCE, stored in our own bucket, and
57
+ * referenced as `/media/<slug>`.
58
+ * 2. **No drawn approximations.** Nothing here is an imitation of a logo we
59
+ * traced; each is the actual wordmark, cited.
60
+ *
61
+ * Only three brands resolve an image today (Beyblade, Hasbro, Sonokong). The
62
+ * other 25 have no verified source yet and show no cover rather than a guessed
63
+ * one — see `knownGaps` in the manifest.
54
64
  *
55
65
  * @tag domain:categories
56
66
  * @tag layer:seed
@@ -96,6 +106,20 @@ export function brandRow(input, order, stamps) {
96
106
  * forest's DFS numbering, and giving them a position inside it would
97
107
  * corrupt the ranges `onCategoryWrite` shifts on insert.
98
108
  */
109
+ /*
110
+ * A placeholder tile, which a real logo now OVERRIDES rather than being
111
+ * blocked by — `withGeneratedCoverImage` treats a `/images/seed-tiles/`
112
+ * path as a default to improve on, not as a hand-authored decision
113
+ * (`isSeedPlaceholderImage`).
114
+ *
115
+ * 🛑 So keep it. Three brands resolve a real wordmark today (Beyblade,
116
+ * Hasbro, Sonokong) and override this; the other 25 have no verified
117
+ * source and fall back to the tile. Removing the line would give those 25
118
+ * an EMPTY grey box, because a brand row carries no `color` and no `icon`
119
+ * either — strictly worse than a neutral tile.
120
+ *
121
+ * `icon` stays unset — see trap 2. An emoji here would outrank the logo.
122
+ */
99
123
  display: {
100
124
  coverImage: seedPhoto(`brand-logo-${input.slug}-20260101`, 800, 800),
101
125
  showInMenu: false,
@@ -52,6 +52,24 @@ import { MODEL_LEAVES } from "./category-models.js";
52
52
  import { PART_LEAVES } from "./category-parts.js";
53
53
  import { BEY_TEMPLATES, COLLECTIBLE_TEMPLATES, PART_TEMPLATES, SEALED_TEMPLATES, accessoryDefaults, beyDefaults, diecastDefaults, figureDefaults, launcherDefaults, livingDefaults, marketBand, partDefaults, stadiumDefaults, tcgDefaults, ROOT_TAX_DEFAULTS, ROOT_AUTHENTICITY_DEFAULT, } from "./category-content.js";
54
54
  import { seedPhoto } from "./media.js";
55
+ /**
56
+ * A synthetic placeholder tile, for a node with no real cover of its own.
57
+ *
58
+ * 🛑 This is a FALLBACK, not a decision — and that took a fix to become true.
59
+ * `withGeneratedCoverImage` used to skip any row with a non-empty
60
+ * `display.coverImage`, so a `cover(...)` here BLOCKED the generated map
61
+ * outright: a wordmark could be fetched, uploaded and mapped and the card
62
+ * would still show a grey tile, with nothing reporting why.
63
+ *
64
+ * It now ranks the three sources honestly — a real authored path beats a
65
+ * generated image beats a placeholder tile (`isSeedPlaceholderImage`) — so
66
+ * every node can keep a tile in source and simply be overridden when an image
67
+ * exists. Four roots are overridden today (the Beyblade generations); the rest
68
+ * render the tile, which is the right thing to show when there is nothing
69
+ * better and much better than the empty box they would get from no value.
70
+ *
71
+ * So adding artwork to a node is now a manifest entry ALONE — no edit here.
72
+ */
55
73
  const cover = (slug) => seedPhoto(`category-image-${slug}-20260101`, 1200, 600);
56
74
  /**
57
75
  * A tier-3 line that owns named-model leaves.
@@ -62,13 +80,28 @@ const cover = (slug) => seedPhoto(`category-image-${slug}-20260101`, 1200, 600);
62
80
  * empty line, never a crash — but a line that is MEANT to have models and
63
81
  * silently has none is the failure this cannot see, which is why the seed
64
82
  * asserts `MODEL_LEAF_COUNT` against what it actually spread.
83
+ *
84
+ * `opts.hasbroName` carries the regional-naming divergence for the waves that
85
+ * have one. Last and optional, so all 21 existing call sites are unchanged.
86
+ *
87
+ * 🛑 There is no `hasbroCoverImage` here on purpose. The name is an editorial
88
+ * FACT and belongs in source; the image is a resolved asset and belongs in the
89
+ * generated map, exactly like `display.coverImage` — see
90
+ * `GENERATED_CATEGORY_HASBRO_IMAGES` and `withGeneratedHasbroCover` in
91
+ * `categories-seed-data.ts`. Hard-coding a `/media/…` string here would put
92
+ * the one field that changes on every re-upload into the one file that should
93
+ * not have to be edited for it.
65
94
  */
66
- function line(id, name, description, defaults, templates) {
95
+ function line(id, name, description, defaults, templates, opts) {
67
96
  return {
68
97
  id,
69
98
  name,
70
99
  description,
71
- extra: { productDefaults: defaults, descriptionTemplates: templates },
100
+ extra: {
101
+ productDefaults: defaults,
102
+ descriptionTemplates: templates,
103
+ ...(opts?.hasbroName ? { hasbroName: opts.hasbroName } : {}),
104
+ },
72
105
  children: MODEL_LEAVES[id] ?? [],
73
106
  };
74
107
  }
@@ -234,12 +267,32 @@ const BEYBLADE_BURST = {
234
267
  },
235
268
  children: [
236
269
  branch("category-burst-tops", "Burst Tops", "Complete Burst-system Beyblades across every wave.", [
270
+ /*
271
+ * 🛑 `hasbroName` is set on exactly the five waves where a Hasbro season
272
+ * title demonstrably differs, each confirmed by BOTH logos existing in
273
+ * the wiki corpus (a Japanese-market logo and an English-market one for
274
+ * the same wave):
275
+ *
276
+ * God <-> Evolution Beyblade_Burst_{God,Evolution}_Logo
277
+ * Cho-Z <-> Turbo {Chouzetsu,Turbo_English}_Logo
278
+ * GT <-> Rise {GT_Japanese,Rise_English}_Logo
279
+ * Superking <-> Surge {Superking_Japanese,Surge_English}_Logo
280
+ * Dynamite B <-> QuadDrive {Dynamite_Battle_Japanese,QuadDrive_English}_Logo
281
+ *
282
+ * `burst-classic` is unset because season 1 shipped as "Beyblade Burst"
283
+ * in both markets — there is no divergence to show. `burst-bu` is unset
284
+ * because the corpus will not support one: it describes Burst Ultimate
285
+ * as a Takara-Tomy toyline concluding the series, and while Hasbro's
286
+ * QuadStrike is contemporaneous, no source we hold states they are the
287
+ * same line renamed. A guessed pairing on a page a buyer reads as fact
288
+ * is worse than a blank.
289
+ */
237
290
  line("category-burst-classic", "Burst Classic", "The original 2015–2017 single- and dual-layer waves, before any metal entered the Layer.", beyDefaults("category-burst-classic", "Beyblade Burst", "Burst System"), BEY_TEMPLATES),
238
- line("category-burst-god", "Burst God", "The God Layer wave, which added spring-loaded Layers and the first real burst-resistance tuning.", beyDefaults("category-burst-god", "Beyblade Burst God", "God Layer System"), BEY_TEMPLATES),
239
- line("category-burst-cho-z", "Cho-Z", "The metal-layer wave — heavier Layers and roughly double the burst resistance of what came before.", beyDefaults("category-burst-cho-z", "Beyblade Burst Cho-Z", "Cho-Z Layer System"), BEY_TEMPLATES),
240
- line("category-burst-gt", "GT", "The Gatinko wave, with a swappable chip inside the Layer for a third tuning axis.", beyDefaults("category-burst-gt", "Beyblade Burst GT", "Gatinko Layer System"), BEY_TEMPLATES),
241
- line("category-burst-superking", "Superking", "The Sparking / Superking wave and its five-sided ratchet, which changed launch dynamics entirely.", beyDefaults("category-burst-superking", "Beyblade Burst Superking", "Sparking Layer System"), BEY_TEMPLATES),
242
- line("category-burst-db", "Dynamite Battle", "The DB wave — Armour Tips and the heaviest Layers Burst had shipped to that point.", beyDefaults("category-burst-db", "Beyblade Burst Dynamite Battle", "Dynamite Battle Layer System"), BEY_TEMPLATES),
291
+ line("category-burst-god", "Burst God", "The God Layer wave, which added spring-loaded Layers and the first real burst-resistance tuning.", beyDefaults("category-burst-god", "Beyblade Burst God", "God Layer System"), BEY_TEMPLATES, { hasbroName: "Beyblade Burst Evolution" }),
292
+ line("category-burst-cho-z", "Cho-Z", "The metal-layer wave — heavier Layers and roughly double the burst resistance of what came before.", beyDefaults("category-burst-cho-z", "Beyblade Burst Cho-Z", "Cho-Z Layer System"), BEY_TEMPLATES, { hasbroName: "Beyblade Burst Turbo" }),
293
+ line("category-burst-gt", "GT", "The Gatinko wave, with a swappable chip inside the Layer for a third tuning axis.", beyDefaults("category-burst-gt", "Beyblade Burst GT", "Gatinko Layer System"), BEY_TEMPLATES, { hasbroName: "Beyblade Burst Rise" }),
294
+ line("category-burst-superking", "Superking", "The Sparking / Superking wave and its five-sided ratchet, which changed launch dynamics entirely.", beyDefaults("category-burst-superking", "Beyblade Burst Superking", "Sparking Layer System"), BEY_TEMPLATES, { hasbroName: "Beyblade Burst Surge" }),
295
+ line("category-burst-db", "Dynamite Battle", "The DB wave — Armour Tips and the heaviest Layers Burst had shipped to that point.", beyDefaults("category-burst-db", "Beyblade Burst Dynamite Battle", "Dynamite Battle Layer System"), BEY_TEMPLATES, { hasbroName: "Beyblade Burst QuadDrive" }),
243
296
  line("category-burst-bu", "Burst Ultimate", "The final Burst wave, closing the line in 2023 before Beyblade X replaced it.", beyDefaults("category-burst-bu", "Beyblade Burst Ultimate", "Burst Ultimate Layer System"), BEY_TEMPLATES),
244
297
  ]),
245
298
  branch("category-burst-parts", "Burst Parts", "Layers, Discs, Drivers and the chips and armour that bolt onto them.", [
@@ -302,6 +355,19 @@ const BEYBLADE_X = {
302
355
  node("category-x-xtreme-stadiums", "Xtreme Stadiums", "X-format stadiums with the Xtreme Line rail — the feature the whole generation is designed around.", stadiumDefaults("category-x-xtreme-stadiums", "Beyblade X"), SEALED_TEMPLATES),
303
356
  node("category-x-standard-stadiums", "Standard X Stadiums", "Plain round X dishes without the rail, for casual play and practice.", stadiumDefaults("category-x-standard-stadiums", "Beyblade X"), SEALED_TEMPLATES),
304
357
  ]),
358
+ /*
359
+ * Added 2026-10-19 for the real CX-20 "Customize Set C" pre-order fixture.
360
+ * A Customize Set is its own retail concept, distinct from both a complete
361
+ * top (`category-x-tops`) and a single loose part (`category-x-parts`):
362
+ * it bundles one complete top with several loose Blades/Ratchets/Bits, so
363
+ * neither existing leaf is the right home. `partDefaults` is still the
364
+ * closer fit of the two existing helpers — the commercial character is
365
+ * "components for a custom build," which is what its FAQ templates
366
+ * (fit/compatibility, not authenticity) already speak to — and it carries
367
+ * `taxCodeId: TAX_TOY` (HSN 9503 0020, 5%), the same rate every other
368
+ * Beyblade/part/launcher/stadium in this catalogue already uses.
369
+ */
370
+ node("category-x-customize-sets", "Customize Sets", "CX-line Customize Sets — a complete top plus extra Blades, Ratchets and Bits for building several distinct combinations from one box.", partDefaults("category-x-customize-sets", "Customize Set"), PART_TEMPLATES),
305
371
  ],
306
372
  };
307
373
  /**
@@ -7,9 +7,11 @@
7
7
  * a third-party URL (Root Cause #104 — that adds an upstream fetch to every
8
8
  * single render).
9
9
  *
10
- * Covers BOTH complete-model leaves and PART leaves — they share one id space
11
- * (`category-*`), so one map serves the category cover and, through
12
- * `gen-catalogue-listings.mjs`, that leaf's product listing image too.
10
+ * Covers model leaves, PART leaves and taxonomy BRANCH rows (generation roots
11
+ * and waves, retail lines, brand rows, franchise rows) — they share one id
12
+ * space (`category-*` / `brand-*` / `franchise-*`), so one map serves the
13
+ * category cover and, through `gen-catalogue-listings.mjs`, a leaf's product
14
+ * listing image too.
13
15
  *
14
16
  * A hand-authored `display.coverImage` always wins over this map; a row absent
15
17
  * from it keeps no image rather than being given a placeholder. See
@@ -31,8 +33,25 @@
31
33
  * versioning and soft-delete are both OFF, so a deleted object leaves no
32
34
  * recoverable copy and no residual billing.
33
35
  *
34
- * Source and licensing for every file:
35
- * `docs/research/bey-corpus-2026-10/image-provenance.json`.
36
+ * Source and licensing for every file — TWO manifests, because the leaves and
37
+ * the branches were fetched by different scripts from different sources:
38
+ * `docs/research/bey-corpus-2026-10/image-provenance.json` (model/part leaves)
39
+ * `docs/research/taxonomy-images-2026-10/image-provenance.json` (branch wordmarks)
36
40
  */
37
41
  export declare const GENERATED_CATEGORY_IMAGES: Readonly<Record<string, string>>;
38
- export declare const GENERATED_CATEGORY_IMAGE_COUNT = 504;
42
+ export declare const GENERATED_CATEGORY_IMAGE_COUNT = 554;
43
+ /**
44
+ * The REGIONAL-VARIANT logo, keyed on the same category id.
45
+ *
46
+ * 🛑 A separate map rather than more entries in the one above, because this is
47
+ * a SECOND image for the SAME category — `category-burst-god` has both a
48
+ * Takara-Tomy "God" wordmark and a Hasbro "Evolution" one. Merging them would
49
+ * mean one silently overwriting the other, and the loser would be whichever
50
+ * the directory listing happened to reach second.
51
+ *
52
+ * Applied by `withGeneratedHasbroCover` to `hasbroCoverImage`, and rendered
53
+ * beside the "Also known as" name. Only populated for a category that also
54
+ * carries `hasbroName` — an image with no name to label it has nothing to say.
55
+ */
56
+ export declare const GENERATED_CATEGORY_HASBRO_IMAGES: Readonly<Record<string, string>>;
57
+ export declare const GENERATED_CATEGORY_HASBRO_IMAGE_COUNT = 5;
@@ -7,9 +7,11 @@
7
7
  * a third-party URL (Root Cause #104 — that adds an upstream fetch to every
8
8
  * single render).
9
9
  *
10
- * Covers BOTH complete-model leaves and PART leaves — they share one id space
11
- * (`category-*`), so one map serves the category cover and, through
12
- * `gen-catalogue-listings.mjs`, that leaf's product listing image too.
10
+ * Covers model leaves, PART leaves and taxonomy BRANCH rows (generation roots
11
+ * and waves, retail lines, brand rows, franchise rows) — they share one id
12
+ * space (`category-*` / `brand-*` / `franchise-*`), so one map serves the
13
+ * category cover and, through `gen-catalogue-listings.mjs`, a leaf's product
14
+ * listing image too.
13
15
  *
14
16
  * A hand-authored `display.coverImage` always wins over this map; a row absent
15
17
  * from it keeps no image rather than being given a placeholder. See
@@ -31,8 +33,10 @@
31
33
  * versioning and soft-delete are both OFF, so a deleted object leaves no
32
34
  * recoverable copy and no residual billing.
33
35
  *
34
- * Source and licensing for every file:
35
- * `docs/research/bey-corpus-2026-10/image-provenance.json`.
36
+ * Source and licensing for every file — TWO manifests, because the leaves and
37
+ * the branches were fetched by different scripts from different sources:
38
+ * `docs/research/bey-corpus-2026-10/image-provenance.json` (model/part leaves)
39
+ * `docs/research/taxonomy-images-2026-10/image-provenance.json` (branch wordmarks)
36
40
  */
37
41
  export const GENERATED_CATEGORY_IMAGES = {
38
42
  "category-ace-dragon-sting-charge-zan": "/media/category-ace-dragon-sting-charge-zan-image",
@@ -165,6 +169,7 @@ export const GENERATED_CATEGORY_IMAGES = {
165
169
  "category-obelisk-odin-triple-xtreme": "/media/category-obelisk-odin-triple-xtreme-image",
166
170
  "category-phantom-fox-ms": "/media/category-phantom-fox-ms-image",
167
171
  "category-phantom-orion-b-d": "/media/category-phantom-orion-b-d-image",
172
+ "category-phoenixforce-whm-65mt": "/media/category-phoenixforce-whm-65mt-image",
168
173
  "category-poison-serpent-sw145sd": "/media/category-poison-serpent-sw145sd-image",
169
174
  "category-prominence-phoenix-tapered-metal-universe-10": "/media/category-prominence-phoenix-tapered-metal-universe-10-image",
170
175
  "category-proto-nemesis-ad145d": "/media/category-proto-nemesis-ad145d-image",
@@ -539,5 +544,75 @@ export const GENERATED_CATEGORY_IMAGES = {
539
544
  "category-ten-heavy": "/media/category-ten-heavy-image",
540
545
  "category-ten-wide": "/media/category-ten-wide-image",
541
546
  "category-wing-attacker": "/media/category-wing-attacker-image",
547
+ "brand-bandai": "/media/brand-bandai-image",
548
+ "brand-banpresto": "/media/brand-banpresto-image",
549
+ "brand-beyblade": "/media/brand-beyblade-image",
550
+ "brand-bushiroad": "/media/brand-bushiroad-image",
551
+ "brand-funskool": "/media/brand-funskool-image",
552
+ "brand-furyu": "/media/brand-furyu-image",
553
+ "brand-good-smile-company": "/media/brand-good-smile-company-image",
554
+ "brand-hasbro": "/media/brand-hasbro-image",
555
+ "brand-hot-wheels": "/media/brand-hot-wheels-image",
556
+ "brand-konami": "/media/brand-konami-image",
557
+ "brand-mattel": "/media/brand-mattel-image",
558
+ "brand-mcfarlane-toys": "/media/brand-mcfarlane-toys-image",
559
+ "brand-mezco": "/media/brand-mezco-image",
560
+ "brand-newboy": "/media/brand-newboy-image",
561
+ "brand-pokemon-company": "/media/brand-pokemon-company-image",
562
+ "brand-sonokong": "/media/brand-sonokong-image",
563
+ "brand-taito": "/media/brand-taito-image",
564
+ "brand-takara-tomy": "/media/brand-takara-tomy-image",
565
+ "brand-takara": "/media/brand-takara-image",
566
+ "brand-tamashii-nations": "/media/brand-tamashii-nations-image",
567
+ "brand-toy-biz": "/media/brand-toy-biz-image",
568
+ "brand-wizards-of-the-coast": "/media/brand-wizards-of-the-coast-image",
569
+ "category-beyblade-burst": "/media/category-beyblade-burst-image",
570
+ "category-beyblade-metal": "/media/category-beyblade-metal-image",
571
+ "category-beyblade-original": "/media/category-beyblade-original-image",
572
+ "category-beyblade-x": "/media/category-beyblade-x-image",
573
+ "category-burst-cho-z": "/media/category-burst-cho-z-image",
574
+ "category-burst-classic": "/media/category-burst-classic-image",
575
+ "category-burst-db": "/media/category-burst-db-image",
576
+ "category-burst-god": "/media/category-burst-god-image",
577
+ "category-burst-gt": "/media/category-burst-gt-image",
578
+ "category-burst-superking": "/media/category-burst-superking-image",
579
+ "category-metal-fury-4d": "/media/category-metal-fury-4d-image",
580
+ "category-metal-fusion": "/media/category-metal-fusion-image",
581
+ "category-metal-masters": "/media/category-metal-masters-image",
582
+ "category-metal-shogun-steel": "/media/category-metal-shogun-steel-image",
583
+ "category-original-engine-gear": "/media/category-original-engine-gear-image",
584
+ "category-original-magnacore": "/media/category-original-magnacore-image",
585
+ "category-x-basic": "/media/category-x-basic-image",
586
+ "category-x-custom-cx": "/media/category-x-custom-cx-image",
587
+ "category-x-unique-ux": "/media/category-x-unique-ux-image",
588
+ "franchise-beyblade": "/media/franchise-beyblade-image",
589
+ "franchise-bleach": "/media/franchise-bleach-image",
590
+ "franchise-dc-comics": "/media/franchise-dc-comics-image",
591
+ "franchise-dragon-ball": "/media/franchise-dragon-ball-image",
592
+ "franchise-marvel": "/media/franchise-marvel-image",
593
+ "franchise-naruto": "/media/franchise-naruto-image",
594
+ "franchise-one-piece": "/media/franchise-one-piece-image",
595
+ "franchise-one-punch-man": "/media/franchise-one-punch-man-image",
542
596
  };
543
- export const GENERATED_CATEGORY_IMAGE_COUNT = 504;
597
+ export const GENERATED_CATEGORY_IMAGE_COUNT = 554;
598
+ /**
599
+ * The REGIONAL-VARIANT logo, keyed on the same category id.
600
+ *
601
+ * 🛑 A separate map rather than more entries in the one above, because this is
602
+ * a SECOND image for the SAME category — `category-burst-god` has both a
603
+ * Takara-Tomy "God" wordmark and a Hasbro "Evolution" one. Merging them would
604
+ * mean one silently overwriting the other, and the loser would be whichever
605
+ * the directory listing happened to reach second.
606
+ *
607
+ * Applied by `withGeneratedHasbroCover` to `hasbroCoverImage`, and rendered
608
+ * beside the "Also known as" name. Only populated for a category that also
609
+ * carries `hasbroName` — an image with no name to label it has nothing to say.
610
+ */
611
+ export const GENERATED_CATEGORY_HASBRO_IMAGES = {
612
+ "category-burst-cho-z": "/media/category-burst-cho-z-hasbro-image",
613
+ "category-burst-db": "/media/category-burst-db-hasbro-image",
614
+ "category-burst-god": "/media/category-burst-god-hasbro-image",
615
+ "category-burst-gt": "/media/category-burst-gt-hasbro-image",
616
+ "category-burst-superking": "/media/category-burst-superking-hasbro-image",
617
+ };
618
+ export const GENERATED_CATEGORY_HASBRO_IMAGE_COUNT = 5;
@@ -2,4 +2,4 @@ import type { CategoryTreeNode } from "./category-tree";
2
2
  /** Named-model leaves, keyed by the tier-3 line they belong to. */
3
3
  export declare const MODEL_LEAVES: Record<string, CategoryTreeNode[]>;
4
4
  /** Total named-model leaves — asserted by the seed so a silent drop is loud. */
5
- export declare const MODEL_LEAF_COUNT = 220;
5
+ export declare const MODEL_LEAF_COUNT = 221;
@@ -1330,6 +1330,12 @@ export const MODEL_LEAVES = {
1330
1330
  },
1331
1331
  ],
1332
1332
  "category-x-custom-cx": [
1333
+ {
1334
+ id: "category-phoenixforce-whm-65mt",
1335
+ name: "PhoenixForce WHM-65MT",
1336
+ description: "PhoenixForce WHM-65MT — a Balance-type, right-spin Custom Line (CX) release, product code CX-20, released by TT Customize Set. Release note: Released only as part of the CX-20 Customize Set C. Complete tops, loose parts, sticker sheets and pre-owned examples of this model are listed here.",
1337
+ extra: { aliases: ["CX-20", "PhoenixForce Weight Heavy M-65 Metal Taper", "Phoenix Force (manga, English)"], productDefaults: { defaultFeatures: ["feature-blader-burn-fujiwara", "feature-type-balance", "feature-right-spin"] } },
1338
+ },
1333
1339
  {
1334
1340
  id: "category-valkyrievolt-s4-70v",
1335
1341
  name: "ValkyrieVolt S4-70V",
@@ -1385,4 +1391,4 @@ export const MODEL_LEAVES = {
1385
1391
  ],
1386
1392
  };
1387
1393
  /** Total named-model leaves — asserted by the seed so a silent drop is loud. */
1388
- export const MODEL_LEAF_COUNT = 220;
1394
+ export const MODEL_LEAF_COUNT = 221;
@@ -15,6 +15,7 @@ export const PART_CATEGORY_TO_GLOSSARY_ID = {
15
15
  "category-00-00turn": "disc--00-00turn",
16
16
  "category-00-part-of-chassis": "disc--00-part-of-chassis",
17
17
  "category-1-60": "ratchet--1-60",
18
+ "category-1-70": "ratchet--1-70",
18
19
  "category-10": "disc--10",
19
20
  "category-100": "spin-track--100",
20
21
  "category-105": "spin-track--105",
@@ -58,6 +59,7 @@ export const PART_CATEGORY_TO_GLOSSARY_ID = {
58
59
  "category-6mobile-ring": "disc--6mobile-ring",
59
60
  "category-6vortex": "disc--6vortex",
60
61
  "category-8": "disc--8",
62
+ "category-8-80": "ratchet--8-80",
61
63
  "category-88": "spin-track--88",
62
64
  "category-8flow": "disc--8flow",
63
65
  "category-9": "ratchet--9",
@@ -416,6 +418,7 @@ export const PART_CATEGORY_TO_GLOSSARY_ID = {
416
418
  "category-hexa": "bit--hexa",
417
419
  "category-hf": "performance-tip--hf",
418
420
  "category-hf-s-hole-flat-sharp": "performance-tip--hf-s-hole-flat-sharp",
421
+ "category-high-needle": "bit--high-needle",
419
422
  "category-hit-release": "blade-base--hit-release",
420
423
  "category-hit-release-base": "blade-base--hit-release-base",
421
424
  "category-hit-release-draciel": "blade-base--hit-release-draciel",
@@ -442,6 +445,7 @@ export const PART_CATEGORY_TO_GLOSSARY_ID = {
442
445
  "category-karma": "disc--karma",
443
446
  "category-kerbecs-clear-wheel": "energy-ring--kerbecs-clear-wheel",
444
447
  "category-ketos-clear-wheel": "energy-ring--ketos-clear-wheel",
448
+ "category-kick": "bit--kick",
445
449
  "category-kick-3": "driver--kick-3",
446
450
  "category-killerken": "chrome-wheel--killerken",
447
451
  "category-king-kerbeus-k2": "layer--king-kerbeus-k2",
@@ -471,6 +475,8 @@ export const PART_CATEGORY_TO_GLOSSARY_ID = {
471
475
  "category-loop": "driver--loop",
472
476
  "category-lost-l-inor-l2": "layer--lost-l-inor-l2",
473
477
  "category-low": "performance-tip--low",
478
+ "category-low-orb": "bit--low-orb",
479
+ "category-low-rush": "bit--low-rush",
474
480
  "category-lw105": "spin-track--lw105",
475
481
  "category-lw160": "spin-track--lw160",
476
482
  "category-m145-gimmick-track": "spin-track--m145-gimmick-track",
@@ -628,6 +634,7 @@ export const PART_CATEGORY_TO_GLOSSARY_ID = {
628
634
  "category-sg-sharp": "blade-base--sg-sharp",
629
635
  "category-sg-sharp-base": "blade-base--sg-sharp-base",
630
636
  "category-sharkedge": "blade--sharkedge",
637
+ "category-sharkscale": "blade--sharkscale",
631
638
  "category-sharp-core": "running-core--sharp-core",
632
639
  "category-shield-hammer": "attack-ring--shield-hammer",
633
640
  "category-shooter-change-core": "running-core--shooter-change-core",
@@ -698,6 +705,7 @@ export const PART_CATEGORY_TO_GLOSSARY_ID = {
698
705
  "category-turtle-survivor": "attack-ring--turtle-survivor",
699
706
  "category-tyrannobeat": "blade--tyrannobeat",
700
707
  "category-ultimate-attacker": "attack-ring--ultimate-attacker",
708
+ "category-under-flat": "bit--under-flat",
701
709
  "category-unicornsting": "blade--unicornsting",
702
710
  "category-unite": "driver--unite",
703
711
  "category-unite-dash": "driver--unite-dash",
@@ -6,4 +6,4 @@ export declare const PART_LEAVES: Record<string, CategoryTreeNode[]>;
6
6
  * SAME string by construction, so this map exists only to let a reader see that
7
7
  * stated rather than inferred.
8
8
  */
9
- export declare const PART_LEAF_COUNT = 752;
9
+ export declare const PART_LEAF_COUNT = 760;
@@ -21,7 +21,7 @@
21
21
  * 🛑 The prose is ours, composed from facts (name, classification, printed
22
22
  * code, weight, model count). No corpus sentence is reproduced.
23
23
  *
24
- * 752 parts -> 752 leaves across 20 part-type nodes.
24
+ * 760 parts -> 760 leaves across 20 part-type nodes.
25
25
  * 129 needed a classification-qualified slug because the bare name
26
26
  * collides across classifications; the rest keep the short URL.
27
27
  *
@@ -4280,12 +4280,36 @@ export const PART_LEAVES = {
4280
4280
  description: "Hexa — a bit (used by 1 model). Loose examples, spares and pre-owned bits of this part are listed here.",
4281
4281
  extra: { aliases: ["Hexa", "hexa"] },
4282
4282
  },
4283
+ {
4284
+ id: "category-high-needle",
4285
+ name: "High Needle",
4286
+ description: "High Needle — a bit. Loose examples, spares and pre-owned bits of this part are listed here.",
4287
+ extra: { aliases: ["High Needle", "high-needle"] },
4288
+ },
4289
+ {
4290
+ id: "category-kick",
4291
+ name: "Kick",
4292
+ description: "Kick — a bit. Loose examples, spares and pre-owned bits of this part are listed here.",
4293
+ extra: { aliases: ["Kick", "kick"] },
4294
+ },
4283
4295
  {
4284
4296
  id: "category-bit-lf",
4285
4297
  name: "LF",
4286
4298
  description: "LF — a bit (used by 2 models). Loose examples, spares and pre-owned bits of this part are listed here.",
4287
4299
  extra: { aliases: ["LF", "lf"] },
4288
4300
  },
4301
+ {
4302
+ id: "category-low-orb",
4303
+ name: "Low Orb",
4304
+ description: "Low Orb — a bit. Loose examples, spares and pre-owned bits of this part are listed here.",
4305
+ extra: { aliases: ["Low Orb", "low-orb"] },
4306
+ },
4307
+ {
4308
+ id: "category-low-rush",
4309
+ name: "Low Rush",
4310
+ description: "Low Rush — a bit. Loose examples, spares and pre-owned bits of this part are listed here.",
4311
+ extra: { aliases: ["Low Rush", "low-rush"] },
4312
+ },
4289
4313
  {
4290
4314
  id: "category-n",
4291
4315
  name: "N",
@@ -4346,6 +4370,12 @@ export const PART_LEAVES = {
4346
4370
  description: "Trans Point — a bit (used by 1 model). Loose examples, spares and pre-owned bits of this part are listed here.",
4347
4371
  extra: { aliases: ["Trans Point", "trans point"] },
4348
4372
  },
4373
+ {
4374
+ id: "category-under-flat",
4375
+ name: "Under Flat",
4376
+ description: "Under Flat — a bit. Loose examples, spares and pre-owned bits of this part are listed here.",
4377
+ extra: { aliases: ["Under Flat", "under-flat"] },
4378
+ },
4349
4379
  {
4350
4380
  id: "category-vortex",
4351
4381
  name: "Vortex",
@@ -4456,6 +4486,12 @@ export const PART_LEAVES = {
4456
4486
  description: "SharkEdge — a blade (used by 2 models). Loose examples, spares and pre-owned blades of this part are listed here.",
4457
4487
  extra: { aliases: ["SharkEdge", "sharkedge"] },
4458
4488
  },
4489
+ {
4490
+ id: "category-sharkscale",
4491
+ name: "SharkScale",
4492
+ description: "SharkScale — a blade. Loose examples, spares and pre-owned blades of this part are listed here.",
4493
+ extra: { aliases: ["SharkScale", "sharkscale"] },
4494
+ },
4459
4495
  {
4460
4496
  id: "category-silverwolf",
4461
4497
  name: "SilverWolf",
@@ -4512,6 +4548,12 @@ export const PART_LEAVES = {
4512
4548
  description: "1-60 — a ratchet (used by 1 model). Loose examples, spares and pre-owned ratchets of this part are listed here.",
4513
4549
  extra: { aliases: ["1-60"] },
4514
4550
  },
4551
+ {
4552
+ id: "category-1-70",
4553
+ name: "1-70",
4554
+ description: "1-70 — a ratchet. Loose examples, spares and pre-owned ratchets of this part are listed here.",
4555
+ extra: { aliases: ["1-70"] },
4556
+ },
4515
4557
  {
4516
4558
  id: "category-2",
4517
4559
  name: "2",
@@ -4572,6 +4614,12 @@ export const PART_LEAVES = {
4572
4614
  description: "5-80 — a ratchet (used by 1 model). Loose examples, spares and pre-owned ratchets of this part are listed here.",
4573
4615
  extra: { aliases: ["5-80"] },
4574
4616
  },
4617
+ {
4618
+ id: "category-8-80",
4619
+ name: "8-80",
4620
+ description: "8-80 — a ratchet. Loose examples, spares and pre-owned ratchets of this part are listed here.",
4621
+ extra: { aliases: ["8-80"] },
4622
+ },
4575
4623
  {
4576
4624
  id: "category-9",
4577
4625
  name: "9",
@@ -4591,4 +4639,4 @@ export const PART_LEAVES = {
4591
4639
  * SAME string by construction, so this map exists only to let a reader see that
4592
4640
  * stated rather than inferred.
4593
4641
  */
4594
- export const PART_LEAF_COUNT = 752;
4642
+ export const PART_LEAF_COUNT = 760;