@krizaka/ui 3.3.0 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (352) hide show
  1. package/dist/activity-feed.d.ts +199 -0
  2. package/dist/activity-feed.js +155 -0
  3. package/dist/activity-feed.js.map +1 -0
  4. package/dist/argument-card.js +3 -3
  5. package/dist/chunk-7Z4KHPFC.js +42 -0
  6. package/dist/chunk-7Z4KHPFC.js.map +1 -0
  7. package/dist/data-table.js +98 -131
  8. package/dist/data-table.js.map +1 -1
  9. package/dist/description-list.d.ts +105 -0
  10. package/dist/description-list.js +49 -0
  11. package/dist/description-list.js.map +1 -0
  12. package/dist/index.js +13 -66
  13. package/dist/index.js.map +1 -1
  14. package/dist/kanban.d.ts +132 -0
  15. package/dist/kanban.js +187 -0
  16. package/dist/kanban.js.map +1 -0
  17. package/dist/list.d.ts +153 -0
  18. package/dist/list.js +130 -0
  19. package/dist/list.js.map +1 -0
  20. package/dist/map.d.ts +463 -0
  21. package/dist/map.js +952 -0
  22. package/dist/map.js.map +1 -0
  23. package/dist/motion.css +12 -1
  24. package/dist/native/map.d.ts +200 -0
  25. package/dist/native/map.js +673 -0
  26. package/dist/native/map.js.map +1 -0
  27. package/dist/native/media-picker.d.ts +58 -0
  28. package/dist/native/media-picker.js +63 -0
  29. package/dist/native/media-picker.js.map +1 -0
  30. package/dist/native.d.ts +568 -6
  31. package/dist/native.js +1989 -868
  32. package/dist/native.js.map +1 -1
  33. package/dist/page-hero.js +3 -3
  34. package/dist/stat.d.ts +31 -2
  35. package/dist/stat.js +21 -4
  36. package/dist/stat.js.map +1 -1
  37. package/dist/tree-view.d.ts +111 -0
  38. package/dist/tree-view.js +154 -0
  39. package/dist/tree-view.js.map +1 -0
  40. package/package.json +147 -10
  41. package/registry/achievement.json +1 -1
  42. package/registry/action-bar.json +1 -1
  43. package/registry/action-sheet.json +121 -0
  44. package/registry/activity-feed.json +468 -0
  45. package/registry/alert.json +1 -1
  46. package/registry/app-shell.json +1 -1
  47. package/registry/argument-card.json +1 -1
  48. package/registry/audio-player.json +1 -1
  49. package/registry/auth-layout.json +1 -1
  50. package/registry/avatar.json +58 -3
  51. package/registry/badge.json +1 -1
  52. package/registry/button.json +1 -1
  53. package/registry/card-grid.json +1 -1
  54. package/registry/card.json +1 -1
  55. package/registry/catalogue-page.json +1 -1
  56. package/registry/changelog-page.json +1 -1
  57. package/registry/checkbox.json +1 -1
  58. package/registry/chip-link.json +1 -1
  59. package/registry/chip.json +1 -1
  60. package/registry/choice-grid.json +1 -1
  61. package/registry/code-block.json +1 -1
  62. package/registry/combobox.json +1 -1
  63. package/registry/command.json +1 -1
  64. package/registry/component-page.json +1 -1
  65. package/registry/confirm-button.json +1 -1
  66. package/registry/contact-page.json +1 -1
  67. package/registry/continue-prompt.json +1 -1
  68. package/registry/countdown.json +1 -1
  69. package/registry/cta-panel.json +1 -1
  70. package/registry/dashboard-layout.json +1 -1
  71. package/registry/data-table.json +1 -1
  72. package/registry/date-picker.json +2 -2
  73. package/registry/decision-list.json +1 -1
  74. package/registry/description-list.json +232 -0
  75. package/registry/detail-layout.json +1 -1
  76. package/registry/dialog.json +1 -1
  77. package/registry/docs-article-page.json +1 -1
  78. package/registry/docs-hub-page.json +1 -1
  79. package/registry/docs-layout.json +1 -1
  80. package/registry/dropdown-menu.json +1 -1
  81. package/registry/empty-state.json +1 -1
  82. package/registry/error-page.json +1 -1
  83. package/registry/examples/action-sheet/native/video-actions.d.ts +4 -0
  84. package/registry/examples/action-sheet/native/video-actions.dark.png +0 -0
  85. package/registry/examples/action-sheet/native/video-actions.js +30 -0
  86. package/registry/examples/action-sheet/native/video-actions.light.png +0 -0
  87. package/registry/examples/action-sheet/native/video-actions.tsx +24 -0
  88. package/registry/examples/activity-feed/job-activity.d.ts +4 -0
  89. package/registry/examples/activity-feed/job-activity.js +21 -0
  90. package/registry/examples/activity-feed/job-activity.tsx +17 -0
  91. package/registry/examples/activity-feed/live.d.ts +4 -0
  92. package/registry/examples/activity-feed/live.js +23 -0
  93. package/registry/examples/activity-feed/live.tsx +24 -0
  94. package/registry/examples/activity-feed/native/notifications.d.ts +4 -0
  95. package/registry/examples/activity-feed/native/notifications.dark.png +0 -0
  96. package/registry/examples/activity-feed/native/notifications.js +18 -0
  97. package/registry/examples/activity-feed/native/notifications.light.png +0 -0
  98. package/registry/examples/activity-feed/native/notifications.tsx +18 -0
  99. package/registry/examples/activity-feed/timeline.d.ts +4 -0
  100. package/registry/examples/activity-feed/timeline.js +25 -0
  101. package/registry/examples/activity-feed/timeline.tsx +19 -0
  102. package/registry/examples/avatar/native/presence.d.ts +4 -0
  103. package/registry/examples/avatar/native/presence.dark.png +0 -0
  104. package/registry/examples/avatar/native/presence.js +18 -0
  105. package/registry/examples/avatar/native/presence.light.png +0 -0
  106. package/registry/examples/avatar/native/presence.tsx +15 -0
  107. package/registry/examples/description-list/job-details.d.ts +4 -0
  108. package/registry/examples/description-list/job-details.js +23 -0
  109. package/registry/examples/description-list/job-details.tsx +17 -0
  110. package/registry/examples/description-list/key-value-grid.d.ts +4 -0
  111. package/registry/examples/description-list/key-value-grid.js +22 -0
  112. package/registry/examples/description-list/key-value-grid.tsx +16 -0
  113. package/registry/examples/description-list/native/job-details.d.ts +4 -0
  114. package/registry/examples/description-list/native/job-details.dark.png +0 -0
  115. package/registry/examples/description-list/native/job-details.js +33 -0
  116. package/registry/examples/description-list/native/job-details.light.png +0 -0
  117. package/registry/examples/description-list/native/job-details.tsx +24 -0
  118. package/registry/examples/description-list/receipt.d.ts +4 -0
  119. package/registry/examples/description-list/receipt.js +23 -0
  120. package/registry/examples/description-list/receipt.tsx +17 -0
  121. package/registry/examples/fab/native/extended.d.ts +4 -0
  122. package/registry/examples/fab/native/extended.dark.png +0 -0
  123. package/registry/examples/fab/native/extended.js +18 -0
  124. package/registry/examples/fab/native/extended.light.png +0 -0
  125. package/registry/examples/fab/native/extended.tsx +23 -0
  126. package/registry/examples/header/native/large-title.d.ts +4 -0
  127. package/registry/examples/header/native/large-title.dark.png +0 -0
  128. package/registry/examples/header/native/large-title.js +23 -0
  129. package/registry/examples/header/native/large-title.light.png +0 -0
  130. package/registry/examples/header/native/large-title.tsx +31 -0
  131. package/registry/examples/image-viewer/native/gallery.d.ts +4 -0
  132. package/registry/examples/image-viewer/native/gallery.dark.png +0 -0
  133. package/registry/examples/image-viewer/native/gallery.js +22 -0
  134. package/registry/examples/image-viewer/native/gallery.light.png +0 -0
  135. package/registry/examples/image-viewer/native/gallery.tsx +21 -0
  136. package/registry/examples/kanban/moderation.d.ts +4 -0
  137. package/registry/examples/kanban/moderation.js +35 -0
  138. package/registry/examples/kanban/moderation.tsx +37 -0
  139. package/registry/examples/list/jobs.d.ts +4 -0
  140. package/registry/examples/list/jobs.js +35 -0
  141. package/registry/examples/list/jobs.tsx +33 -0
  142. package/registry/examples/list/selectable.d.ts +4 -0
  143. package/registry/examples/list/selectable.js +33 -0
  144. package/registry/examples/list/selectable.tsx +30 -0
  145. package/registry/examples/list/virtualized.d.ts +4 -0
  146. package/registry/examples/list/virtualized.js +22 -0
  147. package/registry/examples/list/virtualized.tsx +17 -0
  148. package/registry/examples/loader/native/block.d.ts +4 -0
  149. package/registry/examples/loader/native/block.dark.png +0 -0
  150. package/registry/examples/loader/native/block.js +12 -0
  151. package/registry/examples/loader/native/block.light.png +0 -0
  152. package/registry/examples/loader/native/block.tsx +11 -0
  153. package/registry/examples/loader/native/job-wait.d.ts +4 -0
  154. package/registry/examples/loader/native/job-wait.dark.png +0 -0
  155. package/registry/examples/loader/native/job-wait.js +17 -0
  156. package/registry/examples/loader/native/job-wait.light.png +0 -0
  157. package/registry/examples/loader/native/job-wait.tsx +14 -0
  158. package/registry/examples/map/cluster.d.ts +4 -0
  159. package/registry/examples/map/cluster.js +16 -0
  160. package/registry/examples/map/cluster.tsx +18 -0
  161. package/registry/examples/map/location-picker.d.ts +4 -0
  162. package/registry/examples/map/location-picker.js +24 -0
  163. package/registry/examples/map/location-picker.tsx +22 -0
  164. package/registry/examples/map/native/location-picker.d.ts +4 -0
  165. package/registry/examples/map/native/location-picker.dark.png +0 -0
  166. package/registry/examples/map/native/location-picker.js +14 -0
  167. package/registry/examples/map/native/location-picker.light.png +0 -0
  168. package/registry/examples/map/native/location-picker.tsx +13 -0
  169. package/registry/examples/map/native/places.d.ts +4 -0
  170. package/registry/examples/map/native/places.dark.png +0 -0
  171. package/registry/examples/map/native/places.js +25 -0
  172. package/registry/examples/map/native/places.light.png +0 -0
  173. package/registry/examples/map/native/places.tsx +27 -0
  174. package/registry/examples/map/places.d.ts +4 -0
  175. package/registry/examples/map/places.js +28 -0
  176. package/registry/examples/map/places.tsx +28 -0
  177. package/registry/examples/map/static.d.ts +4 -0
  178. package/registry/examples/map/static.js +22 -0
  179. package/registry/examples/map/static.tsx +18 -0
  180. package/registry/examples/media-picker/native/story.d.ts +4 -0
  181. package/registry/examples/media-picker/native/story.dark.png +0 -0
  182. package/registry/examples/media-picker/native/story.js +30 -0
  183. package/registry/examples/media-picker/native/story.light.png +0 -0
  184. package/registry/examples/media-picker/native/story.tsx +26 -0
  185. package/registry/examples/meter/native/credits.d.ts +4 -0
  186. package/registry/examples/meter/native/credits.dark.png +0 -0
  187. package/registry/examples/meter/native/credits.js +15 -0
  188. package/registry/examples/meter/native/credits.light.png +0 -0
  189. package/registry/examples/meter/native/credits.tsx +12 -0
  190. package/registry/examples/meter/native/split-ring.d.ts +4 -0
  191. package/registry/examples/meter/native/split-ring.dark.png +0 -0
  192. package/registry/examples/meter/native/split-ring.js +24 -0
  193. package/registry/examples/meter/native/split-ring.light.png +0 -0
  194. package/registry/examples/meter/native/split-ring.tsx +19 -0
  195. package/registry/examples/number-ticker/native/balance.d.ts +4 -0
  196. package/registry/examples/number-ticker/native/balance.dark.png +0 -0
  197. package/registry/examples/number-ticker/native/balance.js +18 -0
  198. package/registry/examples/number-ticker/native/balance.light.png +0 -0
  199. package/registry/examples/number-ticker/native/balance.tsx +17 -0
  200. package/registry/examples/onboarding/native/first-launch.d.ts +4 -0
  201. package/registry/examples/onboarding/native/first-launch.dark.png +0 -0
  202. package/registry/examples/onboarding/native/first-launch.js +23 -0
  203. package/registry/examples/onboarding/native/first-launch.light.png +0 -0
  204. package/registry/examples/onboarding/native/first-launch.tsx +19 -0
  205. package/registry/examples/otp-input/native/invalid.d.ts +4 -0
  206. package/registry/examples/otp-input/native/invalid.dark.png +0 -0
  207. package/registry/examples/otp-input/native/invalid.js +15 -0
  208. package/registry/examples/otp-input/native/invalid.light.png +0 -0
  209. package/registry/examples/otp-input/native/invalid.tsx +14 -0
  210. package/registry/examples/otp-input/native/verify.d.ts +4 -0
  211. package/registry/examples/otp-input/native/verify.dark.png +0 -0
  212. package/registry/examples/otp-input/native/verify.js +17 -0
  213. package/registry/examples/otp-input/native/verify.light.png +0 -0
  214. package/registry/examples/otp-input/native/verify.tsx +14 -0
  215. package/registry/examples/permission-prompt/native/blocked.d.ts +4 -0
  216. package/registry/examples/permission-prompt/native/blocked.dark.png +0 -0
  217. package/registry/examples/permission-prompt/native/blocked.js +25 -0
  218. package/registry/examples/permission-prompt/native/blocked.light.png +0 -0
  219. package/registry/examples/permission-prompt/native/blocked.tsx +21 -0
  220. package/registry/examples/permission-prompt/native/camera.d.ts +4 -0
  221. package/registry/examples/permission-prompt/native/camera.dark.png +0 -0
  222. package/registry/examples/permission-prompt/native/camera.js +25 -0
  223. package/registry/examples/permission-prompt/native/camera.light.png +0 -0
  224. package/registry/examples/permission-prompt/native/camera.tsx +21 -0
  225. package/registry/examples/pull-to-refresh/native/feed.d.ts +4 -0
  226. package/registry/examples/pull-to-refresh/native/feed.dark.png +0 -0
  227. package/registry/examples/pull-to-refresh/native/feed.js +14 -0
  228. package/registry/examples/pull-to-refresh/native/feed.light.png +0 -0
  229. package/registry/examples/pull-to-refresh/native/feed.tsx +19 -0
  230. package/registry/examples/search-field/native/cancel.d.ts +4 -0
  231. package/registry/examples/search-field/native/cancel.dark.png +0 -0
  232. package/registry/examples/search-field/native/cancel.js +14 -0
  233. package/registry/examples/search-field/native/cancel.light.png +0 -0
  234. package/registry/examples/search-field/native/cancel.tsx +13 -0
  235. package/registry/examples/stat/grid.d.ts +4 -0
  236. package/registry/examples/stat/grid.js +17 -0
  237. package/registry/examples/stat/grid.tsx +14 -0
  238. package/registry/examples/stepper/native/run.d.ts +4 -0
  239. package/registry/examples/stepper/native/run.dark.png +0 -0
  240. package/registry/examples/stepper/native/run.js +24 -0
  241. package/registry/examples/stepper/native/run.light.png +0 -0
  242. package/registry/examples/stepper/native/run.tsx +20 -0
  243. package/registry/examples/swipeable-row/native/conversation.d.ts +4 -0
  244. package/registry/examples/swipeable-row/native/conversation.dark.png +0 -0
  245. package/registry/examples/swipeable-row/native/conversation.js +30 -0
  246. package/registry/examples/swipeable-row/native/conversation.light.png +0 -0
  247. package/registry/examples/swipeable-row/native/conversation.tsx +27 -0
  248. package/registry/examples/tab-bar/native/main-sections.d.ts +4 -0
  249. package/registry/examples/tab-bar/native/main-sections.dark.png +0 -0
  250. package/registry/examples/tab-bar/native/main-sections.js +29 -0
  251. package/registry/examples/tab-bar/native/main-sections.light.png +0 -0
  252. package/registry/examples/tab-bar/native/main-sections.tsx +30 -0
  253. package/registry/examples/tabs/native/sections.d.ts +4 -0
  254. package/registry/examples/tabs/native/sections.dark.png +0 -0
  255. package/registry/examples/tabs/native/sections.js +23 -0
  256. package/registry/examples/tabs/native/sections.light.png +0 -0
  257. package/registry/examples/tabs/native/sections.tsx +19 -0
  258. package/registry/examples/tabs/native/segmented.d.ts +4 -0
  259. package/registry/examples/tabs/native/segmented.dark.png +0 -0
  260. package/registry/examples/tabs/native/segmented.js +22 -0
  261. package/registry/examples/tabs/native/segmented.light.png +0 -0
  262. package/registry/examples/tabs/native/segmented.tsx +18 -0
  263. package/registry/examples/toast/native/snackbar.d.ts +4 -0
  264. package/registry/examples/toast/native/snackbar.dark.png +0 -0
  265. package/registry/examples/toast/native/snackbar.js +23 -0
  266. package/registry/examples/toast/native/snackbar.light.png +0 -0
  267. package/registry/examples/toast/native/snackbar.tsx +21 -0
  268. package/registry/examples/tree-view/docs.d.ts +4 -0
  269. package/registry/examples/tree-view/docs.js +24 -0
  270. package/registry/examples/tree-view/docs.tsx +22 -0
  271. package/registry/examples/tree-view/lazy.d.ts +4 -0
  272. package/registry/examples/tree-view/lazy.js +21 -0
  273. package/registry/examples/tree-view/lazy.tsx +19 -0
  274. package/registry/fab.json +122 -0
  275. package/registry/field.json +1 -1
  276. package/registry/file-upload.json +2 -2
  277. package/registry/filter-bar.json +1 -1
  278. package/registry/form.json +2 -2
  279. package/registry/gallery-page.json +1 -1
  280. package/registry/glow-card.json +1 -1
  281. package/registry/goal-gauge.json +1 -1
  282. package/registry/header.json +137 -0
  283. package/registry/how-it-works-page.json +1 -1
  284. package/registry/image-cropper.json +1 -1
  285. package/registry/image-viewer.json +107 -0
  286. package/registry/index.json +299 -25
  287. package/registry/iso.json +1 -1
  288. package/registry/kanban.json +253 -0
  289. package/registry/kbd.json +1 -1
  290. package/registry/landing-page.json +1 -1
  291. package/registry/landscape.json +1 -1
  292. package/registry/legal-page.json +1 -1
  293. package/registry/link-card.json +1 -1
  294. package/registry/list.json +367 -30
  295. package/registry/loader.json +157 -4
  296. package/registry/longform-page.json +1 -1
  297. package/registry/map.json +1368 -0
  298. package/registry/marketing-layout.json +1 -1
  299. package/registry/marquee.json +1 -1
  300. package/registry/mascot-quote.json +1 -1
  301. package/registry/mascot-state.json +1 -1
  302. package/registry/mascots.json +1 -1
  303. package/registry/media-capture.json +1 -1
  304. package/registry/media-picker.json +129 -0
  305. package/registry/meter.json +136 -4
  306. package/registry/nav-bar.json +1 -1
  307. package/registry/number-ticker.json +96 -4
  308. package/registry/onboarding.json +95 -0
  309. package/registry/otp-input.json +150 -0
  310. package/registry/page-header.json +1 -1
  311. package/registry/page-hero.json +1 -1
  312. package/registry/page.json +1 -1
  313. package/registry/pagination.json +1 -1
  314. package/registry/permission-prompt.json +172 -0
  315. package/registry/pointer-light.json +1 -1
  316. package/registry/popover.json +1 -1
  317. package/registry/pricing-page.json +1 -1
  318. package/registry/product-page.json +1 -1
  319. package/registry/profile-card.json +1 -1
  320. package/registry/progress.json +2 -2
  321. package/registry/promise-card.json +1 -1
  322. package/registry/pull-to-refresh.json +74 -0
  323. package/registry/radio-group.json +1 -1
  324. package/registry/scroll-stage.json +1 -1
  325. package/registry/search-field.json +30 -3
  326. package/registry/section-backdrop.json +1 -1
  327. package/registry/separator.json +1 -1
  328. package/registry/settings-layout.json +1 -1
  329. package/registry/skeleton.json +1 -1
  330. package/registry/slider.json +1 -1
  331. package/registry/slot.json +1 -1
  332. package/registry/spinner.json +1 -1
  333. package/registry/split-view.json +1 -1
  334. package/registry/stage-banner.json +1 -1
  335. package/registry/stat.json +68 -5
  336. package/registry/status-page.json +1 -1
  337. package/registry/stepper.json +75 -4
  338. package/registry/swipeable-row.json +124 -0
  339. package/registry/switch.json +1 -1
  340. package/registry/tab-bar.json +115 -0
  341. package/registry/tabs.json +94 -4
  342. package/registry/tag-input.json +1 -1
  343. package/registry/terminal-replay.json +1 -1
  344. package/registry/theme.json +8 -1
  345. package/registry/toast.json +17 -3
  346. package/registry/toc.json +1 -1
  347. package/registry/tooltip.json +1 -1
  348. package/registry/tree-view.json +291 -0
  349. package/registry/video-player.json +1 -1
  350. package/registry/video-trimmer.json +1 -1
  351. package/registry/virtual.json +1 -1
  352. package/skills/map/SKILL.md +35 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/native/map.tsx","../../src/map/assets.ts","../../src/map/geo.ts","../../../tokens/dist/native.js","../../src/map/style.ts"],"sourcesContent":["/// <reference types=\"geojson\" />\n// React Native: the maps of `@krizaka/ui/map` on MapLibre Native (`@maplibre/maplibre-react-native`, an optional peer\n// installed only by the apps that show a map) — the same style generated from the tokens, the same Protomaps tiles on the\n// Krizaka CDN (MapLibre Native reads `pmtiles://` as it is), no API key. `Map`, `Marker`, `Cluster`, `UserPosition`,\n// `RadiusCircle`, `LocationPicker`; details of a place in a `Sheet` (`@krizaka/ui/native`).\nimport { type BrandId, Txt, useTheme } from \"@krizaka/ui/native\";\nimport {\n Camera,\n type CameraRef,\n GeoJSONSource,\n Layer,\n LocationManager,\n Map as MapView,\n Marker as MapMarker,\n} from \"@maplibre/maplibre-react-native\";\nimport * as React from \"react\";\nimport { Animated, Pressable, type StyleProp, StyleSheet, Text, View, type ViewStyle } from \"react-native\";\nimport Svg, { Circle, Path } from \"react-native-svg\";\n\nimport { MAP_ATTRIBUTION } from \"../map/assets\";\nimport { circlePolygon, distanceMeters, formatDistance, type LngLat } from \"../map/geo\";\nimport { mapPalette, type MapRegion,mapStyle } from \"../map/style\";\n\ntype Ctx = { palette: ReturnType<typeof mapPalette>; reduce: boolean; places: { add: (id: string, text: string) => void; remove: (id: string) => void } };\nconst MapContext = React.createContext<Ctx | null>(null);\nconst useMapContext = () => {\n const ctx = React.useContext(MapContext);\n if (!ctx) throw new Error(\"inside a <Map> only\");\n return ctx;\n};\n\nexport type MapProps = {\n /** The map's accessible name (\"Pick-up points near you\"), passed translated; the places follow it. */\n label: string;\n /** Where the map looks: longitude, latitude. */\n center: LngLat;\n /** The zoom (0 the world, 12 a city, 16 a street). Default 12. */\n zoom?: number;\n /** The product whose accent the map carries. Default `krizaka`. */\n brand?: BrandId;\n /** The language of the labels (`fr`, `en`). Default `en`. */\n lang?: string;\n /** The detailed region (PMTiles) drawn from zoom 6.5. Default: our Montréal–Québec extract (to zoom 14). */\n region?: MapRegion | null;\n /** The world's low zooms (PMTiles). Default: our world extract (to zoom 6). */\n world?: MapRegion | null;\n /** Moves with the hand (default). */\n interactive?: boolean;\n /** Called when the camera rests: its centre and zoom. */\n onMoveEnd?: (view: { center: LngLat; zoom: number }) => void;\n /** Called with the position pressed on the map (not on a marker). */\n onPress?: (position: LngLat) => void;\n /** Markers, circles, clusters, the person's position. */\n children?: React.ReactNode;\n /** Styles merged last (its height). */\n style?: StyleProp<ViewStyle>;\n};\n\n/** A map: MapLibre Native over our Protomaps tiles, styled from the tokens in the app's scheme; its places in its name. */\nexport function Map({ label, center, zoom = 12, brand, lang, region, world, interactive = true, onMoveEnd, onPress, children, style }: MapProps) {\n const { scheme, theme, radius, motion } = useTheme();\n const reduce = motion.duration.base === 0;\n const camera = React.useRef<CameraRef>(null);\n const [places, setPlaces] = React.useState<Record<string, string>>({});\n const registry = React.useMemo(\n () => ({\n add: (id: string, text: string) => setPlaces((p) => (p[id] === text ? p : { ...p, [id]: text })),\n remove: (id: string) =>\n setPlaces((p) => {\n const { [id]: _gone, ...rest } = p;\n return rest;\n }),\n }),\n [],\n );\n const styleJson = React.useMemo(() => mapStyle({ scheme, brand, lang, ...(region !== undefined ? { region } : {}), ...(world !== undefined ? { world } : {}) }), [scheme, brand, lang, region, world]);\n const palette = React.useMemo(() => mapPalette(scheme, brand), [scheme, brand]);\n const listed = Object.values(places);\n const ctx = React.useMemo(() => ({ palette, reduce, places: registry }), [palette, reduce, registry]);\n return (\n <MapContext.Provider value={ctx}>\n <View style={[styles.root, { borderRadius: radius.xl, borderColor: theme.borderDefault, backgroundColor: theme.surface2 }, style]}>\n <MapView\n style={StyleSheet.absoluteFill}\n mapStyle={styleJson as never}\n aria-label={listed.length ? `${label}: ${listed.join(\", \")}` : label}\n dragPan={interactive}\n touchZoom={interactive}\n doubleTapZoom={interactive}\n touchRotate={false}\n touchPitch={false}\n attribution={false}\n logo={false}\n compass={false}\n onRegionDidChange={(e) => onMoveEnd?.({ center: e.nativeEvent.center as unknown as LngLat, zoom: e.nativeEvent.zoom })}\n onPress={(e) => {\n const coords = (e.nativeEvent as unknown as { lngLat?: LngLat }).lngLat;\n if (coords) onPress?.(coords);\n }}\n >\n <Camera ref={camera} center={[...center] as [number, number]} zoom={zoom} duration={reduce ? 0 : 600} easing={reduce ? undefined : \"ease\"} />\n {children}\n </MapView>\n <View style={[styles.attribution, { backgroundColor: theme.surface1, borderRadius: radius.sm }]}>\n <Text style={[styles.attributionText, { color: theme.textSecondary }]}>\n {MAP_ATTRIBUTION.protomaps} · {MAP_ATTRIBUTION.osm}\n </Text>\n </View>\n </View>\n </MapContext.Provider>\n );\n}\n\nfunction usePlace(label: string) {\n const { places } = useMapContext();\n const id = React.useId();\n React.useEffect(() => {\n places.add(id, label);\n return () => places.remove(id);\n }, [id, label, places]);\n return id;\n}\n\nexport type MarkerProps = {\n /** Where it stands. */\n position: LngLat;\n /** Its words: the place's name (read in the map's name and as the button's name). */\n label: string;\n /** Pressing it: details in a `Sheet`. */\n onPress?: () => void;\n /** The chosen one: larger, its label above it. */\n selected?: boolean;\n /** What it draws instead of the accent dot. */\n children?: React.ReactNode;\n};\n\n/** A place: an accent dot (or your view) that is a button when it does something. */\nexport function Marker({ position, label, onPress, selected, children }: MarkerProps) {\n const { palette } = useMapContext();\n const { theme, radius, haptic } = useTheme();\n const id = usePlace(label);\n return (\n <MapMarker id={id} lngLat={[...position] as [number, number]} anchor=\"center\" selected={selected}>\n <Pressable\n role={onPress ? \"button\" : undefined}\n aria-label={label}\n disabled={!onPress}\n hitSlop={12}\n onPress={() => {\n haptic(\"selection\");\n onPress?.();\n }}\n style={styles.markerSlot}\n >\n {selected ? (\n <View style={[styles.markerLabel, { backgroundColor: theme.surface1, borderColor: theme.borderDefault, borderRadius: radius.md }]}>\n <Txt variant=\"label\">{label}</Txt>\n </View>\n ) : null}\n {children ?? <View style={[styles.dot, { backgroundColor: palette.accent, borderColor: palette.onAccent, transform: [{ scale: selected ? 1.3 : 1 }] }]} />}\n </Pressable>\n </MapMarker>\n );\n}\n\nexport type UserPositionProps = {\n /** Where the person is. */\n position: LngLat;\n /** Its words (\"You are here\"). */\n label: string;\n /** The accuracy in metres: a soft disc. */\n accuracy?: number;\n};\n\n/** The person's position: a dot that pulses (still when the system reduces motion). */\nexport function UserPosition({ position, label, accuracy }: UserPositionProps) {\n const { palette, reduce } = useMapContext();\n const id = usePlace(label);\n const [pulse] = React.useState(() => new Animated.Value(0));\n React.useEffect(() => {\n if (reduce) return;\n const loop = Animated.loop(Animated.timing(pulse, { toValue: 1, duration: 2000, useNativeDriver: true }));\n loop.start();\n return () => loop.stop();\n }, [pulse, reduce]);\n return (\n <>\n {accuracy ? <RadiusCircle center={position} radius={accuracy} tone=\"soft\" /> : null}\n <MapMarker id={id} lngLat={[...position] as [number, number]} anchor=\"center\">\n <View role=\"img\" aria-label={label} accessible style={styles.userSlot}>\n <Animated.View style={[styles.userHalo, { backgroundColor: palette.accent, opacity: pulse.interpolate({ inputRange: [0, 1], outputRange: [0.4, 0] }), transform: [{ scale: pulse.interpolate({ inputRange: [0, 1], outputRange: [1, 3] }) }] }]} />\n <View style={[styles.user, { backgroundColor: palette.accent, borderColor: palette.halo }]} />\n </View>\n </MapMarker>\n </>\n );\n}\n\nexport type RadiusCircleProps = {\n /** Its centre. */\n center: LngLat;\n /** Its radius in metres. */\n radius: number;\n /** `accent` (a zone) or `soft` (an accuracy). */\n tone?: \"accent\" | \"soft\";\n};\n\n/** A circle on the ground: a delivery zone, a search radius. */\nexport function RadiusCircle({ center, radius, tone = \"accent\" }: RadiusCircleProps) {\n const { palette } = useMapContext();\n const id = `kz-circle-${React.useId().replace(/[^a-zA-Z0-9]/g, \"\")}`;\n const data = React.useMemo(() => circlePolygon(center, radius), [center, radius]);\n return (\n <GeoJSONSource id={id} data={data}>\n <Layer type=\"fill\" id={`${id}-fill`} paint={{ \"fill-color\": palette.accent, \"fill-opacity\": tone === \"soft\" ? 0.1 : 0.14 }} />\n <Layer type=\"line\" id={`${id}-line`} paint={{ \"line-color\": palette.accent, \"line-width\": tone === \"soft\" ? 1 : 2, \"line-opacity\": tone === \"soft\" ? 0.4 : 0.9 }} />\n </GeoJSONSource>\n );\n}\n\nexport type ClusterPoint = { id: string; position: LngLat; label: string };\n\nexport type ClusterProps = {\n /** The points: many of them. */\n points: readonly ClusterPoint[];\n /** Pressing a single point (details in a `Sheet`). */\n onPointPress?: (point: ClusterPoint) => void;\n /** The radius, in points, within which points group. Default 48. */\n radius?: number;\n};\n\n/** Many points grouped while they are close: a disc with the count; each point is part of the map's name. */\nexport function Cluster({ points, onPointPress, radius = 48 }: ClusterProps) {\n const { palette, places } = useMapContext();\n const id = `kz-cluster-${React.useId().replace(/[^a-zA-Z0-9]/g, \"\")}`;\n React.useEffect(() => {\n for (const p of points) places.add(`${id}-${p.id}`, p.label);\n return () => points.forEach((p) => places.remove(`${id}-${p.id}`));\n }, [points, places, id]);\n const data = React.useMemo<GeoJSON.FeatureCollection>(\n () => ({ type: \"FeatureCollection\", features: points.map((p) => ({ type: \"Feature\", properties: { id: p.id, label: p.label }, geometry: { type: \"Point\", coordinates: [...p.position] } })) }),\n [points],\n );\n return (\n <GeoJSONSource\n id={id}\n data={data}\n cluster\n clusterRadius={radius}\n clusterMaxZoom={15}\n onPress={(e: unknown) => {\n const feature = (e as { nativeEvent?: { features?: GeoJSON.Feature[] } }).nativeEvent?.features?.[0];\n const pid = feature?.properties?.id;\n const point = points.find((p) => p.id === pid);\n if (point) onPointPress?.(point);\n }}\n >\n <Layer type=\"circle\" id={`${id}-groups`} filter={[\"has\", \"point_count\"]} paint={{ \"circle-color\": palette.accent, \"circle-radius\": [\"step\", [\"get\", \"point_count\"], 16, 10, 20, 50, 26], \"circle-stroke-width\": 3, \"circle-stroke-color\": palette.halo }} />\n <Layer type=\"symbol\" id={`${id}-count`} filter={[\"has\", \"point_count\"]} layout={{ \"text-field\": [\"get\", \"point_count_abbreviated\"], \"text-font\": [\"Noto Sans Medium\"], \"text-size\": 13 }} paint={{ \"text-color\": palette.onAccent }} />\n <Layer type=\"circle\" id={`${id}-points`} filter={[\"!\", [\"has\", \"point_count\"]]} paint={{ \"circle-color\": palette.accent, \"circle-radius\": 7, \"circle-stroke-width\": 2.5, \"circle-stroke-color\": palette.halo }} />\n </GeoJSONSource>\n );\n}\n\nexport type LocationPickerLabels = {\n /** \"Near me\". */\n nearMe: string;\n /** \"Finding you…\". */\n locating: string;\n /** \"Location is off for this app. Move the map instead.\" */\n denied: string;\n /** \"We could not find you. Move the map instead.\" */\n unavailable: string;\n /** \"You are here\". */\n you: string;\n /** The distance chip (\"1.2 km from you\"). */\n distance: (distance: string) => string;\n};\n\nconst pickerLabels: LocationPickerLabels = {\n nearMe: \"Near me\",\n locating: \"Finding you…\",\n denied: \"Location is off for this app. Move the map instead.\",\n unavailable: \"We could not find you. Move the map instead.\",\n you: \"You are here\",\n distance: (d) => `${d} from you`,\n};\n\nexport type LocationPickerProps = Pick<MapProps, \"brand\" | \"lang\" | \"region\" | \"world\" | \"style\"> & {\n /** The picker's accessible name (\"Meeting point\"). */\n label: string;\n /** The chosen position (the centre of the map). */\n value: LngLat;\n /** Called when the map rests on a new position. */\n onValueChange: (value: LngLat) => void;\n /** The BCP 47 locale of the distance. */\n locale: string;\n /** The zoom. Default 14. */\n zoom?: number;\n /** A radius in metres around the chosen position. */\n radius?: number;\n /** Where the person is, when already known. */\n origin?: LngLat | null;\n /** The words, passed translated. */\n labels?: Partial<LocationPickerLabels>;\n};\n\n/** A position picked by moving the map under a pin; its distance from the person; \"near me\" asks for the location only when pressed. */\nexport function LocationPicker({ label, value, onValueChange, locale, zoom = 14, radius: zone, origin: originProp = null, labels: given, style, ...map }: LocationPickerProps) {\n const labels = { ...pickerLabels, ...given };\n const { theme, radius, haptic } = useTheme();\n const [origin, setOrigin] = React.useState<LngLat | null>(originProp);\n const [camera, setCamera] = React.useState<LngLat>(value);\n const [status, setStatus] = React.useState<\"idle\" | \"locating\" | \"denied\" | \"unavailable\">(\"idle\");\n const nearMe = async () => {\n setStatus(\"locating\");\n try {\n if (!(await LocationManager.requestPermissions())) return setStatus(\"denied\");\n const p = await LocationManager.getCurrentPosition();\n if (!p) return setStatus(\"unavailable\");\n const here: LngLat = [p.coords.longitude, p.coords.latitude];\n haptic(\"success\");\n setOrigin(here);\n setCamera(here);\n onValueChange(here);\n setStatus(\"idle\");\n } catch {\n setStatus(\"unavailable\");\n }\n };\n const message = status === \"locating\" ? labels.locating : status === \"denied\" ? labels.denied : status === \"unavailable\" ? labels.unavailable : null;\n return (\n <View role=\"group\" aria-label={label} style={[styles.picker, style]}>\n <View style={styles.pickerFrame}>\n <Map {...map} label={label} center={camera} zoom={zoom} onMoveEnd={(v) => onValueChange(v.center)} style={StyleSheet.absoluteFill}>\n {zone ? <RadiusCircle center={value} radius={zone} /> : null}\n {origin ? <UserPosition position={origin} label={labels.you} /> : null}\n </Map>\n <View pointerEvents=\"none\" style={styles.pin}>\n <Svg width={30} height={40} viewBox=\"0 0 24 32\" aria-hidden>\n <Path d=\"M12 0C5.4 0 0 5.2 0 11.7 0 20.4 12 32 12 32s12-11.6 12-20.3C24 5.2 18.6 0 12 0Z\" fill={theme.accent} />\n <Circle cx={12} cy={11.5} r={4.5} fill={theme.onAccent} />\n </Svg>\n </View>\n <View style={styles.bar} pointerEvents=\"box-none\">\n {origin ? (\n <View style={[styles.chip, { backgroundColor: theme.surface1, borderColor: theme.borderDefault, borderRadius: radius.full }]}>\n <Txt variant=\"label\" aria-live=\"polite\">\n {labels.distance(formatDistance(distanceMeters(origin, value), locale))}\n </Txt>\n </View>\n ) : (\n <View />\n )}\n <Pressable role=\"button\" aria-label={labels.nearMe} disabled={status === \"locating\"} onPress={() => void nearMe()} style={[styles.near, { backgroundColor: theme.surface1, borderColor: theme.borderDefault, borderRadius: radius.full }]}>\n <Txt variant=\"label\">{status === \"locating\" ? labels.locating : labels.nearMe}</Txt>\n </Pressable>\n </View>\n </View>\n {message && status !== \"locating\" ? (\n <Txt variant=\"caption\" tone=\"danger\" role=\"alert\">\n {message}\n </Txt>\n ) : null}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n root: { height: 280, overflow: \"hidden\", borderWidth: StyleSheet.hairlineWidth, alignSelf: \"stretch\" },\n attribution: { position: \"absolute\", right: 6, bottom: 6, paddingHorizontal: 6, paddingVertical: 2, opacity: 0.9 },\n attributionText: { fontSize: 10 },\n markerSlot: { alignItems: \"center\", justifyContent: \"center\", minWidth: 44, minHeight: 44 },\n markerLabel: { position: \"absolute\", bottom: 40, paddingHorizontal: 8, paddingVertical: 4, borderWidth: StyleSheet.hairlineWidth },\n dot: { width: 18, height: 18, borderRadius: 9, borderWidth: 2.5 },\n userSlot: { width: 44, height: 44, alignItems: \"center\", justifyContent: \"center\" },\n userHalo: { position: \"absolute\", width: 16, height: 16, borderRadius: 8 },\n user: { width: 16, height: 16, borderRadius: 8, borderWidth: 3 },\n picker: { gap: 6, alignSelf: \"stretch\" },\n pickerFrame: { height: 320 },\n pin: { position: \"absolute\", left: \"50%\", top: \"50%\", marginLeft: -15, marginTop: -40 },\n bar: { position: \"absolute\", left: 12, right: 12, bottom: 28, flexDirection: \"row\", justifyContent: \"space-between\", alignItems: \"center\", gap: 8 },\n chip: { paddingHorizontal: 12, paddingVertical: 6, borderWidth: StyleSheet.hairlineWidth },\n near: { minHeight: 44, paddingHorizontal: 16, justifyContent: \"center\", borderWidth: StyleSheet.hairlineWidth },\n});\n\nexport { MAP_ATTRIBUTION, MAP_GLYPHS, MAP_TILES } from \"../map/assets\";\nexport { circlePolygon, distanceMeters, formatDistance, type LngLat } from \"../map/geo\";\nexport { mapPalette, type MapRegion, mapStyle } from \"../map/style\";\n","// Where the basemap lives: Protomaps PMTiles extracts on the Krizaka CDN (Bunny), uploaded by tools/map-assets.mjs.\n// No API key, no metered service: one file per region, read by HTTP range requests. A new extract is a new file (its\n// build date in the name) and a new default here.\n\nconst CDN = \"https://krizaka-assets.b-cdn.net/maps/v1\";\n\n/** The basemap extracts: OpenStreetMap data built by Protomaps (ODbL). `world` up to zoom 6, `quebec` (Montréal–Québec) up to 14. */\nexport const MAP_TILES = {\n world: `${CDN}/tiles/world-20261012.pmtiles`,\n quebec: `${CDN}/tiles/quebec-20261012.pmtiles`,\n} as const;\n\n/** The glyphs of the labels (Noto Sans, SIL OFL): `{fontstack}` and `{range}` filled by MapLibre. */\nexport const MAP_GLYPHS = `${CDN}/fonts/{fontstack}/{range}.pbf`;\n\n/** The words every map shows, as the licences ask: OpenStreetMap's contributors (ODbL) and Protomaps. */\nexport const MAP_ATTRIBUTION = { osm: \"© OpenStreetMap contributors\", osmUrl: \"https://www.openstreetmap.org/copyright\", protomaps: \"Protomaps\", protomapsUrl: \"https://protomaps.com\" } as const;\n\nlet base: string | null = null;\n\n/**\n * Where the maps read the tiles and the glyphs, when not from the CDN itself: a same-origin path that proxies it\n * (`https://www.krizaka.com/maps/v1`, a rewrite of the site) — no cross-origin request at all. Absolute URL, no trailing slash.\n */\nexport function setMapAssetsBase(url: string | null) {\n base = url ? url.replace(/\\/+$/, \"\") : null;\n}\n\n/** The tiles and glyphs the maps read now: the CDN's, or under the base set by `setMapAssetsBase`. */\nexport function mapAssets() {\n const at = (u: string) => (base ? u.replace(CDN, base) : u);\n return { tiles: { world: at(MAP_TILES.world), quebec: at(MAP_TILES.quebec) }, glyphs: at(MAP_GLYPHS) };\n}\n","/// <reference types=\"geojson\" />\n\n// Plain geometry for the maps, web and native (no DOM, no React): distances, circles, the Web Mercator projection.\n\n/** A position: longitude, latitude (GeoJSON's order, MapLibre's `LngLat`). */\nexport type LngLat = readonly [lng: number, lat: number];\n\nconst R = 6_371_008.8;\nconst rad = (d: number) => (d * Math.PI) / 180;\n\n/** The great-circle distance between two positions, in metres (haversine). */\nexport function distanceMeters(a: LngLat, b: LngLat): number {\n const dLat = rad(b[1] - a[1]);\n const dLng = rad(b[0] - a[0]);\n const h = Math.sin(dLat / 2) ** 2 + Math.cos(rad(a[1])) * Math.cos(rad(b[1])) * Math.sin(dLng / 2) ** 2;\n return 2 * R * Math.asin(Math.min(1, Math.sqrt(h)));\n}\n\n/** A circle of `radius` metres around `center` as a GeoJSON polygon (`steps` points): a delivery zone, a search radius. */\nexport function circlePolygon(center: LngLat, radius: number, steps = 64): GeoJSON.Feature<GeoJSON.Polygon> {\n const [lng, lat] = center;\n const d = radius / R;\n const ring: [number, number][] = [];\n for (let i = 0; i <= steps; i++) {\n const brg = (2 * Math.PI * i) / steps;\n const lat2 = Math.asin(Math.sin(rad(lat)) * Math.cos(d) + Math.cos(rad(lat)) * Math.sin(d) * Math.cos(brg));\n const lng2 = rad(lng) + Math.atan2(Math.sin(brg) * Math.sin(d) * Math.cos(rad(lat)), Math.cos(d) - Math.sin(rad(lat)) * Math.sin(lat2));\n ring.push([(lng2 * 180) / Math.PI, (lat2 * 180) / Math.PI]);\n }\n return { type: \"Feature\", properties: {}, geometry: { type: \"Polygon\", coordinates: [ring] } };\n}\n\n/** The Web Mercator pixel of a position at a zoom (256-px tiles): what a static map draws without an engine. */\nexport function project([lng, lat]: LngLat, zoom: number): [number, number] {\n const scale = 256 * 2 ** zoom;\n const s = Math.sin(rad(Math.max(-85.0511, Math.min(85.0511, lat))));\n return [((lng + 180) / 360) * scale, (0.5 - Math.log((1 + s) / (1 - s)) / (4 * Math.PI)) * scale];\n}\n\n/** A distance written the locale's way: metres under 1 km, kilometres (one decimal under 10) above. */\nexport function formatDistance(meters: number, locale: string): string {\n if (meters < 1000) return new Intl.NumberFormat(locale, { style: \"unit\", unit: \"meter\", maximumFractionDigits: 0 }).format(Math.round(meters / 10) * 10);\n return new Intl.NumberFormat(locale, { style: \"unit\", unit: \"kilometer\", maximumFractionDigits: meters < 10_000 ? 1 : 0 }).format(meters / 1000);\n}\n","// @krizaka/tokens — GÉNÉRÉ depuis src/tokens/*.tokens.json par scripts/build.mjs : ne pas éditer.\n\n/** Colour roles per theme, resolved for React Native (`#rrggbb`, `rgba()` when translucent). */\nexport const themes = /* @__PURE__ */ Object.freeze({ dark: /* @__PURE__ */ Object.freeze({\n \"surface0\": \"#0c0c0e\",\n \"surface1\": \"#161618\",\n \"surface2\": \"#1f1f23\",\n \"surface3\": \"#2a2a2d\",\n \"media\": \"#1b1b1d\",\n \"borderSubtle\": \"rgba(255,255,255,0.06)\",\n \"borderDefault\": \"rgba(255,255,255,0.1)\",\n \"borderStrong\": \"rgba(255,255,255,0.16)\",\n \"textPrimary\": \"#f5f5f5\",\n \"textSecondary\": \"#a0a0a7\",\n \"textMuted\": \"#73737d\",\n \"textOnMedia\": \"#ffffff\",\n \"accent\": \"#196df5\",\n \"accentHover\": \"#0e5bd8\",\n \"accentSoft\": \"rgba(25,109,245,0.1)\",\n \"accentText\": \"#629cf8\",\n \"accent2\": \"#196df5\",\n \"onAccent\": \"#ffffff\",\n \"ring\": \"#196df5\",\n \"brandGradientFrom\": \"#0e1525\",\n \"brandGradientVia\": \"#0e0f16\",\n \"brandGradientTo\": \"#0c0c0e\",\n \"success\": \"#10b77f\",\n \"successText\": \"#36d399\",\n \"successSoft\": \"rgba(16,183,127,0.14)\",\n \"warning\": \"#f59f0a\",\n \"warningText\": \"#f6a823\",\n \"warningSoft\": \"rgba(245,159,10,0.14)\",\n \"danger\": \"#ef4343\",\n \"dangerText\": \"#f87272\",\n \"dangerSoft\": \"rgba(239,67,67,0.14)\",\n \"info\": \"#196df5\",\n \"infoText\": \"#629cf8\",\n \"scrim\": \"rgba(0,0,0,0.6)\",\n \"scrimStrong\": \"rgba(0,0,0,0.8)\",\n \"overlay\": \"rgba(0,0,0,0.7)\",\n \"surfaceSheen\": \"rgba(255,255,255,0.045)\",\n \"fillShade\": \"rgba(0,0,0,0.12)\",\n \"edgeLight\": \"rgba(255,255,255,0.07)\",\n \"edgeOnFill\": \"rgba(255,255,255,0.22)\",\n \"edgeWell\": \"rgba(4,4,7,0.5)\",\n \"glassBg\": \"rgba(29,29,32,0.88)\",\n \"glassBorder\": \"rgba(255,255,255,0.1)\"\n}), light: /* @__PURE__ */ Object.freeze({\n \"surface0\": \"#fafafa\",\n \"surface1\": \"#ffffff\",\n \"surface2\": \"#f1f1f3\",\n \"surface3\": \"#e4e4e7\",\n \"media\": \"#e9e9ec\",\n \"borderSubtle\": \"rgba(0,0,0,0.06)\",\n \"borderDefault\": \"rgba(0,0,0,0.1)\",\n \"borderStrong\": \"rgba(0,0,0,0.16)\",\n \"textPrimary\": \"#18181b\",\n \"textSecondary\": \"#64646d\",\n \"textMuted\": \"#808089\",\n \"textOnMedia\": \"#ffffff\",\n \"accent\": \"#0a64f5\",\n \"accentHover\": \"#0d55c9\",\n \"accentSoft\": \"rgba(10,100,245,0.08)\",\n \"accentText\": \"#0954ce\",\n \"accent2\": \"#0a64f5\",\n \"onAccent\": \"#ffffff\",\n \"ring\": \"#0a64f5\",\n \"brandGradientFrom\": \"#dcebfe\",\n \"brandGradientVia\": \"#f3f6fc\",\n \"brandGradientTo\": \"#fafafa\",\n \"success\": \"#10b77f\",\n \"successText\": \"#0a714e\",\n \"successSoft\": \"rgba(16,183,127,0.1)\",\n \"warning\": \"#f59f0a\",\n \"warningText\": \"#955104\",\n \"warningSoft\": \"rgba(245,159,10,0.12)\",\n \"danger\": \"#ef4343\",\n \"dangerText\": \"#af1d1d\",\n \"dangerSoft\": \"rgba(239,67,67,0.1)\",\n \"info\": \"#0a64f5\",\n \"infoText\": \"#0954ce\",\n \"scrim\": \"rgba(0,0,0,0.6)\",\n \"scrimStrong\": \"rgba(0,0,0,0.8)\",\n \"overlay\": \"rgba(0,0,0,0.7)\",\n \"surfaceSheen\": \"rgba(255,255,255,0.7)\",\n \"fillShade\": \"rgba(0,0,0,0.12)\",\n \"edgeLight\": \"rgba(255,255,255,0.9)\",\n \"edgeOnFill\": \"rgba(255,255,255,0.22)\",\n \"edgeWell\": \"rgba(48,52,80,0.08)\",\n \"glassBg\": \"rgba(255,255,255,0.88)\",\n \"glassBorder\": \"rgba(0,0,0,0.08)\"\n}) });\n\n/** Corner radii, in dp. */\nexport const radius = /* @__PURE__ */ Object.freeze({\n \"xs\": 6,\n \"sm\": 8,\n \"md\": 12,\n \"lg\": 16,\n \"xl\": 20,\n \"2xl\": 28,\n \"full\": 9999\n});\n\n/** Font families: the first family of each web stack (React Native takes a single name). */\nexport const typography = /* @__PURE__ */ Object.freeze({\n \"sans\": \"Inter\",\n \"text\": \"Inter\",\n \"display\": \"Plus Jakarta Sans\",\n \"mono\": \"JetBrains Mono\"\n});\n\n/**\n * Motion: the cubic-bezier control points (`Easing.bezier(...motion.ease)`), the short spring of what answers the hand\n * (`motion.spring`) and the micro-interaction durations in ms (`motion.duration.fast`) — 0 when the system reduces motion.\n */\nexport const motion = /* @__PURE__ */ Object.freeze({ ease: /* @__PURE__ */ Object.freeze([0.16,1,0.3,1]), spring: /* @__PURE__ */ Object.freeze([0.34,1.36,0.64,1]), duration: /* @__PURE__ */ Object.freeze({\"instant\":90,\"fast\":150,\"base\":200}) });\n\n/**\n * The type scale in dp: fontSize, lineHeight and letterSpacing absolute (React Native has no em), fontWeight as a string,\n * and the role whose family sets it — with @krizaka/fonts: `{ ...typeScale.bodyMd, fontFamily: fontFamily(role, weight) }`.\n */\nexport const typeScale = /* @__PURE__ */ Object.freeze({\n \"display2xl\": {\n \"role\": \"display\",\n \"fontSize\": 72,\n \"lineHeight\": 73,\n \"fontWeight\": \"800\",\n \"letterSpacing\": -2.52\n },\n \"displayXl\": {\n \"role\": \"display\",\n \"fontSize\": 56,\n \"lineHeight\": 59,\n \"fontWeight\": \"800\",\n \"letterSpacing\": -1.68\n },\n \"displayLg\": {\n \"role\": \"display\",\n \"fontSize\": 44,\n \"lineHeight\": 48,\n \"fontWeight\": \"700\",\n \"letterSpacing\": -1.1\n },\n \"displayMd\": {\n \"role\": \"display\",\n \"fontSize\": 34,\n \"lineHeight\": 39,\n \"fontWeight\": \"700\",\n \"letterSpacing\": -0.68\n },\n \"displaySm\": {\n \"role\": \"display\",\n \"fontSize\": 26,\n \"lineHeight\": 31,\n \"fontWeight\": \"700\",\n \"letterSpacing\": -0.39\n },\n \"titleLg\": {\n \"role\": \"display\",\n \"fontSize\": 20,\n \"lineHeight\": 27,\n \"fontWeight\": \"700\",\n \"letterSpacing\": -0.2\n },\n \"titleMd\": {\n \"role\": \"text\",\n \"fontSize\": 17,\n \"lineHeight\": 24,\n \"fontWeight\": \"600\",\n \"letterSpacing\": -0.2\n },\n \"bodyLg\": {\n \"role\": \"text\",\n \"fontSize\": 18,\n \"lineHeight\": 29,\n \"fontWeight\": \"400\",\n \"letterSpacing\": -0.25\n },\n \"bodyMd\": {\n \"role\": \"text\",\n \"fontSize\": 16,\n \"lineHeight\": 26,\n \"fontWeight\": \"400\",\n \"letterSpacing\": -0.18\n },\n \"bodySm\": {\n \"role\": \"text\",\n \"fontSize\": 14,\n \"lineHeight\": 21,\n \"fontWeight\": \"400\",\n \"letterSpacing\": -0.08\n },\n \"caption\": {\n \"role\": \"text\",\n \"fontSize\": 12,\n \"lineHeight\": 17,\n \"fontWeight\": \"500\",\n \"letterSpacing\": 0\n },\n \"overline\": {\n \"role\": \"mono\",\n \"fontSize\": 11,\n \"lineHeight\": 14,\n \"fontWeight\": \"600\",\n \"letterSpacing\": 1.32\n },\n \"monoMd\": {\n \"role\": \"mono\",\n \"fontSize\": 14,\n \"lineHeight\": 22,\n \"fontWeight\": \"400\",\n \"letterSpacing\": 0\n },\n \"monoSm\": {\n \"role\": \"mono\",\n \"fontSize\": 12,\n \"lineHeight\": 18,\n \"fontWeight\": \"400\",\n \"letterSpacing\": 0\n }\n});\n\n/**\n * The shadows per theme as React Native `boxShadow` strings (RN ≥ 0.76): `raised` (a button, a card), `floating`\n * (a menu, a popover), `overlay` (a sheet, a toast) — ink-tinted, several layers, as on the web.\n */\nexport const shadows = /* @__PURE__ */ Object.freeze({ dark: /* @__PURE__ */ Object.freeze({\n \"sm\": \"0 1px 3px 0 rgba(0,0,0,0.12), 0 1px 2px 0 rgba(0,0,0,0.06)\",\n \"md\": \"0 4px 12px 0 rgba(0,0,0,0.15), 0 2px 4px 0 rgba(0,0,0,0.08)\",\n \"lg\": \"0 8px 24px 0 rgba(0,0,0,0.18), 0 4px 8px 0 rgba(0,0,0,0.08)\",\n \"raised\": \"0 1px 2px 0 rgba(4,4,7,0.45), 0 2px 6px -2px rgba(4,4,7,0.3)\",\n \"floating\": \"0 2px 4px 0 rgba(4,4,7,0.35), 0 12px 24px -6px rgba(4,4,7,0.45), 0 24px 48px -12px rgba(4,4,7,0.35)\",\n \"overlay\": \"0 4px 8px 0 rgba(4,4,7,0.4), 0 24px 48px -12px rgba(4,4,7,0.5), 0 48px 96px -24px rgba(4,4,7,0.45)\"\n}), light: /* @__PURE__ */ Object.freeze({\n \"sm\": \"0 1px 3px 0 rgba(0,0,0,0.06), 0 1px 2px 0 rgba(0,0,0,0.04)\",\n \"md\": \"0 4px 12px 0 rgba(0,0,0,0.08), 0 2px 4px 0 rgba(0,0,0,0.04)\",\n \"lg\": \"0 8px 24px 0 rgba(0,0,0,0.1), 0 4px 8px 0 rgba(0,0,0,0.05)\",\n \"raised\": \"0 1px 2px 0 rgba(48,52,80,0.08), 0 2px 6px -2px rgba(48,52,80,0.08)\",\n \"floating\": \"0 2px 4px 0 rgba(48,52,80,0.06), 0 12px 24px -6px rgba(48,52,80,0.1), 0 24px 48px -12px rgba(48,52,80,0.1)\",\n \"overlay\": \"0 4px 8px 0 rgba(48,52,80,0.08), 0 24px 48px -12px rgba(48,52,80,0.14), 0 48px 96px -24px rgba(48,52,80,0.14)\"\n}) });\n\n/** The griffe (BRAND.md §6.1): the size of the 45° cut corner of a control, in dp. */\nexport const cut = /* @__PURE__ */ Object.freeze({\n \"size\": 10\n});\n\n/** The brand themes as ThemeProvider overrides (`overrides={brands.orazaka}`): the accent family per theme. */\nexport const brands = /* @__PURE__ */ Object.freeze({\n \"krizaka\": {\n \"dark\": {\n \"accent\": \"#196df5\",\n \"accentHover\": \"#0e5bd8\",\n \"accentSoft\": \"rgba(25,109,245,0.1)\",\n \"accentText\": \"#629cf8\",\n \"accent2\": \"#196df5\",\n \"onAccent\": \"#ffffff\",\n \"ring\": \"#196df5\",\n \"info\": \"#196df5\",\n \"infoText\": \"#629cf8\",\n \"brandGradientFrom\": \"#0e1525\",\n \"brandGradientVia\": \"#0e0f16\",\n \"brandGradientTo\": \"#0c0c0e\"\n },\n \"light\": {\n \"accent\": \"#0a64f5\",\n \"accentHover\": \"#0d55c9\",\n \"accentSoft\": \"rgba(10,100,245,0.08)\",\n \"accentText\": \"#0954ce\",\n \"accent2\": \"#0a64f5\",\n \"onAccent\": \"#ffffff\",\n \"ring\": \"#0a64f5\",\n \"info\": \"#0a64f5\",\n \"infoText\": \"#0954ce\",\n \"brandGradientFrom\": \"#dcebfe\",\n \"brandGradientVia\": \"#f3f6fc\",\n \"brandGradientTo\": \"#fafafa\"\n }\n },\n \"orazaka\": {\n \"dark\": {\n \"accent\": \"#f67e23\",\n \"accentHover\": \"#f79245\",\n \"accentSoft\": \"rgba(246,126,35,0.12)\",\n \"accentText\": \"#f78c3b\",\n \"accent2\": \"#f59e0b\",\n \"onAccent\": \"#0c0c0e\",\n \"ring\": \"#f67e23\",\n \"info\": \"#3b83f7\",\n \"infoText\": \"#629cf8\",\n \"brandGradientFrom\": \"#28170b\",\n \"brandGradientVia\": \"#17130c\",\n \"brandGradientTo\": \"#0c0c0e\"\n },\n \"light\": {\n \"accent\": \"#b45309\",\n \"accentHover\": \"#964608\",\n \"accentSoft\": \"rgba(180,83,9,0.08)\",\n \"accentText\": \"#9b4808\",\n \"accent2\": \"#a45904\",\n \"onAccent\": \"#ffffff\",\n \"ring\": \"#b45309\",\n \"info\": \"#0a64f5\",\n \"infoText\": \"#0954ce\",\n \"brandGradientFrom\": \"#ffebd6\",\n \"brandGradientVia\": \"#fdf7ed\",\n \"brandGradientTo\": \"#fafafa\"\n }\n },\n \"orochia\": {\n \"dark\": {\n \"accent\": \"#7c3aed\",\n \"accentHover\": \"#6d28d9\",\n \"accentSoft\": \"rgba(139,92,246,0.12)\",\n \"accentText\": \"#a78bfa\",\n \"accent2\": \"#db2777\",\n \"onAccent\": \"#ffffff\",\n \"ring\": \"#a78bfa\",\n \"info\": \"#7c3aed\",\n \"infoText\": \"#a78bfa\",\n \"brandGradientFrom\": \"#1a0e2a\",\n \"brandGradientVia\": \"#1c0d17\",\n \"brandGradientTo\": \"#0c0c0e\"\n },\n \"light\": {\n \"accent\": \"#7c3aed\",\n \"accentHover\": \"#6d28d9\",\n \"accentSoft\": \"rgba(124,58,237,0.08)\",\n \"accentText\": \"#6d28d9\",\n \"accent2\": \"#db2777\",\n \"onAccent\": \"#ffffff\",\n \"ring\": \"#7c3aed\",\n \"info\": \"#7c3aed\",\n \"infoText\": \"#6d28d9\",\n \"brandGradientFrom\": \"#efe7fe\",\n \"brandGradientVia\": \"#fdedf5\",\n \"brandGradientTo\": \"#fafafa\"\n }\n },\n \"yazakia\": {\n \"dark\": {\n \"accent\": \"#24dbc9\",\n \"accentHover\": \"#47e1d2\",\n \"accentSoft\": \"rgba(36,219,201,0.12)\",\n \"accentText\": \"#3ee0cf\",\n \"accent2\": \"#22c378\",\n \"onAccent\": \"#0c0c0e\",\n \"ring\": \"#24dbc9\",\n \"info\": \"#3b83f7\",\n \"infoText\": \"#629cf8\",\n \"brandGradientFrom\": \"#0a241e\",\n \"brandGradientVia\": \"#0c1818\",\n \"brandGradientTo\": \"#0c0c0e\"\n },\n \"light\": {\n \"accent\": \"#097169\",\n \"accentHover\": \"#085e57\",\n \"accentSoft\": \"rgba(9,113,105,0.08)\",\n \"accentText\": \"#096d64\",\n \"accent2\": \"#107546\",\n \"onAccent\": \"#ffffff\",\n \"ring\": \"#097169\",\n \"info\": \"#0a64f5\",\n \"infoText\": \"#0954ce\",\n \"brandGradientFrom\": \"#e1faf1\",\n \"brandGradientVia\": \"#e9fbfa\",\n \"brandGradientTo\": \"#fafafa\"\n }\n },\n \"yororis\": {\n \"dark\": {\n \"accent\": \"#98b587\",\n \"accentHover\": \"#adc69f\",\n \"accentSoft\": \"rgba(152,181,135,0.12)\",\n \"accentText\": \"#a7c497\",\n \"accent2\": \"#c3a579\",\n \"onAccent\": \"#0c0c0e\",\n \"ring\": \"#98b587\",\n \"info\": \"#3b83f7\",\n \"infoText\": \"#629cf8\",\n \"brandGradientFrom\": \"#1c1812\",\n \"brandGradientVia\": \"#11140f\",\n \"brandGradientTo\": \"#0c0c0e\"\n },\n \"light\": {\n \"accent\": \"#456237\",\n \"accentHover\": \"#39532d\",\n \"accentSoft\": \"rgba(69,98,55,0.08)\",\n \"accentText\": \"#415b33\",\n \"accent2\": \"#745834\",\n \"onAccent\": \"#ffffff\",\n \"ring\": \"#456237\",\n \"info\": \"#0a64f5\",\n \"infoText\": \"#0954ce\",\n \"brandGradientFrom\": \"#f5efe5\",\n \"brandGradientVia\": \"#f1f6ee\",\n \"brandGradientTo\": \"#fafafa\"\n }\n }\n});\n/** The marks' emblem gradients: [offset, #rrggbb] stops, the same in both themes. */\nexport const marks = /* @__PURE__ */ Object.freeze({\n \"krizaka\": [\n [\n \"0%\",\n \"#196df5\"\n ],\n [\n \"100%\",\n \"#629cf8\"\n ]\n ],\n \"orazaka\": [\n [\n \"0%\",\n \"#b45309\"\n ],\n [\n \"100%\",\n \"#dc6509\"\n ]\n ],\n \"orochia\": [\n [\n \"0%\",\n \"#7c3aed\"\n ],\n [\n \"55%\",\n \"#d946ef\"\n ],\n [\n \"100%\",\n \"#f472b6\"\n ]\n ],\n \"yazakia\": [\n [\n \"0%\",\n \"#079d61\"\n ],\n [\n \"100%\",\n \"#089b96\"\n ]\n ],\n \"yororis\": [\n [\n \"0%\",\n \"#a4773d\"\n ],\n [\n \"100%\",\n \"#5d894d\"\n ]\n ]\n});\n","// The Krizaka map style, generated from the tokens (no hand-written colour): Protomaps' basemap layers\n// (@protomaps/basemaps) painted with a flavour drawn from `@krizaka/tokens` — the surfaces for the land, the accent\n// softened for the water, the text roles for the labels — in dark or light, the product's accent where a brand asks.\n// Platform-neutral: the web `Map` and the native `Map` both read it.\nimport { brands, themes } from \"@krizaka/tokens/native\";\nimport { type Flavor, layers, namedFlavor } from \"@protomaps/basemaps\";\n\nimport { MAP_ATTRIBUTION, mapAssets } from \"./assets\";\n\n/** A product of the family: its accent paints the map. */\nexport type MapBrand = keyof typeof brands;\n\n/** A colour mixed into another (`#rrggbb` only): `t` = 0 gives `a`, 1 gives `b`. */\nexport function mix(a: string, b: string, t: number): string {\n const p = (h: string) => [1, 3, 5].map((i) => parseInt(h.slice(i, i + 2), 16));\n const [x, y] = [p(a), p(b)];\n return `#${x.map((v, i) => Math.round(v + (y[i]! - v) * t).toString(16).padStart(2, \"0\")).join(\"\")}`;\n}\n\n/** The colours of the map in a scheme (and a brand): what the style, the markers and the static map share. */\nexport function mapPalette(scheme: \"dark\" | \"light\", brand: MapBrand = \"krizaka\") {\n const t = { ...themes[scheme], ...(brands as Record<string, Partial<Record<\"dark\" | \"light\", Partial<typeof themes.dark>>>>)[brand]?.[scheme] };\n const dark = scheme === \"dark\";\n const land = dark ? t.surface1 : t.surface0;\n return {\n land,\n background: dark ? t.surface0 : t.surface2,\n water: mix(land, t.accent, dark ? 0.18 : 0.14),\n park: mix(land, t.success, dark ? 0.1 : 0.12),\n road: dark ? mix(land, t.textPrimary, 0.12) : \"#ffffff\",\n roadMajor: dark ? mix(land, t.textPrimary, 0.2) : mix(land, t.textPrimary, 0.06),\n casing: mix(land, t.textPrimary, dark ? 0.05 : 0.12),\n building: mix(land, t.textPrimary, dark ? 0.06 : 0.07),\n boundary: mix(land, t.textPrimary, 0.3),\n label: t.textSecondary,\n labelStrong: t.textPrimary,\n halo: land,\n accent: t.accent,\n onAccent: t.onAccent,\n };\n}\n\n/** The basemap flavour of a palette: every role of Protomaps' layers filled from the tokens. */\nexport function mapFlavor(scheme: \"dark\" | \"light\", brand?: MapBrand): Flavor {\n const c = mapPalette(scheme, brand);\n const base = namedFlavor(scheme);\n return {\n ...base,\n background: c.background,\n earth: c.land,\n park_a: c.park,\n park_b: c.park,\n wood_a: c.park,\n wood_b: c.park,\n scrub_a: c.park,\n scrub_b: c.park,\n glacier: c.land,\n sand: c.land,\n beach: c.land,\n zoo: c.park,\n hospital: c.land,\n industrial: c.land,\n school: c.land,\n military: c.land,\n aerodrome: c.land,\n pedestrian: c.land,\n runway: c.building,\n water: c.water,\n buildings: c.building,\n pier: c.building,\n boundaries: c.boundary,\n railway: c.casing,\n other: c.road,\n minor_service: c.road,\n minor_a: c.road,\n minor_b: c.road,\n link: c.road,\n major: c.roadMajor,\n highway: c.roadMajor,\n bridges_other: c.road,\n bridges_minor: c.road,\n bridges_link: c.road,\n bridges_major: c.roadMajor,\n bridges_highway: c.roadMajor,\n tunnel_other: c.road,\n tunnel_minor: c.road,\n tunnel_link: c.road,\n tunnel_major: c.roadMajor,\n tunnel_highway: c.roadMajor,\n minor_service_casing: c.casing,\n minor_casing: c.casing,\n link_casing: c.casing,\n major_casing_late: c.casing,\n major_casing_early: c.casing,\n highway_casing_late: c.casing,\n highway_casing_early: c.casing,\n bridges_other_casing: c.casing,\n bridges_minor_casing: c.casing,\n bridges_link_casing: c.casing,\n bridges_major_casing: c.casing,\n bridges_highway_casing: c.casing,\n tunnel_other_casing: c.casing,\n tunnel_minor_casing: c.casing,\n tunnel_link_casing: c.casing,\n tunnel_major_casing: c.casing,\n tunnel_highway_casing: c.casing,\n roads_label_minor: c.label,\n roads_label_minor_halo: c.halo,\n roads_label_major: c.label,\n roads_label_major_halo: c.halo,\n ocean_label: c.label,\n subplace_label: c.label,\n subplace_label_halo: c.halo,\n city_label: c.labelStrong,\n city_label_halo: c.halo,\n state_label: c.label,\n state_label_halo: c.halo,\n country_label: c.label,\n address_label: c.label,\n address_label_halo: c.halo,\n regular: \"Noto Sans Regular\",\n bold: \"Noto Sans Medium\",\n italic: \"Noto Sans Italic\",\n // No point-of-interest icons (no sprite to host): the app's own markers carry the places that matter.\n pois: undefined,\n landcover: undefined,\n };\n}\n\n/** A region of the basemap: its PMTiles file and the zoom up to which it has tiles. */\nexport type MapRegion = { url: string; maxzoom: number };\n\nexport type MapStyleOptions = {\n /** `dark` or `light`: the scheme of the page or the app. */\n scheme: \"dark\" | \"light\";\n /** The product whose accent the map carries (its markers, its water's tint). Default `krizaka`. */\n brand?: MapBrand;\n /** The language of the labels (`fr`, `en`): the place names in it where OpenStreetMap has them. Default `en`. */\n lang?: string;\n /** The low zooms of the whole world. Default: our world extract (zoom 0–6). */\n world?: MapRegion | null;\n /** The detailed region drawn from zoom 7. Default: Montréal–Québec (up to 14, overzoomed beyond). */\n region?: MapRegion | null;\n /** The glyphs' URL template. Default: our Noto Sans on the CDN. */\n glyphs?: string;\n};\n\n/** The zoom where the detailed region takes over from the world. */\nexport const REGION_FROM_ZOOM = 6.5;\n\n/**\n * The MapLibre style of a Krizaka map (a `StyleSpecification`): the world's low zooms, then the detailed region,\n * painted from the tokens. The `pmtiles://` sources need the PMTiles protocol (the web `Map` registers it; MapLibre\n * Native reads it as it is).\n */\nexport function mapStyle({ scheme, brand, lang = \"en\", world = { url: mapAssets().tiles.world, maxzoom: 6 }, region = { url: mapAssets().tiles.quebec, maxzoom: 14 }, glyphs = mapAssets().glyphs }: MapStyleOptions) {\n const flavor = mapFlavor(scheme, brand);\n const attribution = `<a href=\"${MAP_ATTRIBUTION.protomapsUrl}\">${MAP_ATTRIBUTION.protomaps}</a> · <a href=\"${MAP_ATTRIBUTION.osmUrl}\">${MAP_ATTRIBUTION.osm}</a>`;\n const sources: Record<string, unknown> = {};\n const all: { id: string; minzoom?: number; maxzoom?: number; [k: string]: unknown }[] = [];\n if (world) {\n sources.world = { type: \"vector\", url: `pmtiles://${world.url}`, attribution };\n for (const l of layers(\"world\", flavor, { lang }) as typeof all) {\n if (l.id === \"background\") all.push(l);\n else all.push({ ...l, id: `world-${l.id}`, maxzoom: region ? Math.min(l.maxzoom ?? 24, REGION_FROM_ZOOM) : l.maxzoom });\n }\n }\n if (region) {\n sources.region = { type: \"vector\", url: `pmtiles://${region.url}`, attribution };\n for (const l of layers(\"region\", flavor, { lang }) as typeof all) {\n if (l.id === \"background\") {\n if (!world) all.push(l);\n continue;\n }\n all.push({ ...l, id: `region-${l.id}`, minzoom: world ? Math.max(l.minzoom ?? 0, REGION_FROM_ZOOM) : l.minzoom });\n }\n }\n // No sprite is hosted: a layer that needs an icon (points of interest) is left out — the app's markers carry the places.\n const drawn = all.filter((l) => !(l.layout as Record<string, unknown> | undefined)?.[\"icon-image\"]);\n return { version: 8 as const, glyphs, sources, layers: drawn.map((l) => (l.maxzoom === undefined ? withoutKey(l, \"maxzoom\") : l)) };\n}\n\nconst withoutKey = <T extends Record<string, unknown>>(o: T, key: string) => Object.fromEntries(Object.entries(o).filter(([k]) => k !== key)) as T;\n"],"mappings":"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","names":["base"]}
@@ -0,0 +1,58 @@
1
+ import * as React from 'react';
2
+ import { StyleProp, ViewStyle } from 'react-native';
3
+
4
+ /** A picked photo or video, on the device. */
5
+ type PickedMedia = {
6
+ /** Its file on the device (upload it from here). */
7
+ uri: string;
8
+ /** `image` or `video`. */
9
+ kind: "image" | "video";
10
+ /** Its size in pixels. */
11
+ width: number;
12
+ height: number;
13
+ /** A video's length in milliseconds. */
14
+ duration?: number | null;
15
+ /** Its file name, when the system gives it. */
16
+ fileName?: string | null;
17
+ };
18
+ type MediaPickerLabels = {
19
+ /** The add tile (“Add a photo”). */
20
+ add: string;
21
+ /** The sheet's title (“Add from”). */
22
+ source: string;
23
+ /** From the library (“Photo library”). */
24
+ library: string;
25
+ /** From the camera (“Take a photo”). */
26
+ camera: string;
27
+ /** Cancel. */
28
+ cancel: string;
29
+ /** A tile's remove button: `(n) => "Remove photo " + n`. */
30
+ remove: (position: number) => string;
31
+ /** The count under the grid: `(n, max) => n + " of " + max`. */
32
+ count?: (n: number, max: number) => string;
33
+ };
34
+ type MediaPickerProps = {
35
+ /** The media picked (controlled). */
36
+ value: readonly PickedMedia[];
37
+ /** Called with the new list. */
38
+ onValueChange: (media: PickedMedia[]) => void;
39
+ /** What can be picked. Default `images`. */
40
+ accept?: "images" | "videos" | "all";
41
+ /** The most that can be picked. Default 1. */
42
+ max?: number;
43
+ /** Offer the camera beside the library. Default true. */
44
+ camera?: boolean;
45
+ /** The words, passed translated. */
46
+ labels: MediaPickerLabels;
47
+ /** Called when the camera is refused (show a `PermissionPrompt`). */
48
+ onPermissionDenied?: () => void;
49
+ /** Styles merged last. */
50
+ style?: StyleProp<ViewStyle>;
51
+ };
52
+ /**
53
+ * Photos and videos picked from the library or the camera, as a grid of square tiles: an add tile (the system's
54
+ * picker, or a sheet to choose library or camera), a remove button on each tile, a count against `max`.
55
+ */
56
+ declare function MediaPicker({ value, onValueChange, accept, max, camera, labels, onPermissionDenied, style }: MediaPickerProps): React.JSX.Element;
57
+
58
+ export { MediaPicker, type MediaPickerLabels, type MediaPickerProps, type PickedMedia };
@@ -0,0 +1,63 @@
1
+ // src/native/media-picker.tsx
2
+ import { ActionSheet, Txt, useTheme } from "@krizaka/ui/native";
3
+ import { launchCameraAsync, launchImageLibraryAsync, requestCameraPermissionsAsync } from "expo-image-picker";
4
+ import * as React from "react";
5
+ import { Image, Pressable, StyleSheet, View } from "react-native";
6
+ import Svg, { Path } from "react-native-svg";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ var typesOf = (accept) => accept === "videos" ? ["videos"] : accept === "all" ? ["images", "videos"] : ["images"];
9
+ function MediaPicker({ value, onValueChange, accept = "images", max = 1, camera = true, labels, onPermissionDenied, style }) {
10
+ const { theme, radius, haptic } = useTheme();
11
+ const [choosing, setChoosing] = React.useState(false);
12
+ const left = max - value.length;
13
+ const add = (picked) => {
14
+ if (picked.canceled || !picked.assets) return;
15
+ haptic("selection");
16
+ const media = picked.assets.map((a) => ({ uri: a.uri, kind: a.type === "video" ? "video" : "image", width: a.width, height: a.height, duration: a.duration, fileName: a.fileName }));
17
+ onValueChange([...value, ...media].slice(0, max));
18
+ };
19
+ const fromLibrary = async () => add(await launchImageLibraryAsync({ mediaTypes: typesOf(accept), allowsMultipleSelection: left > 1, selectionLimit: left, quality: 0.9 }));
20
+ const fromCamera = async () => {
21
+ const permission = await requestCameraPermissionsAsync();
22
+ if (!permission.granted) return onPermissionDenied?.();
23
+ add(await launchCameraAsync({ mediaTypes: typesOf(accept), quality: 0.9 }));
24
+ };
25
+ const tile = [styles.tile, { borderRadius: radius.md, backgroundColor: theme.surface2, borderColor: theme.borderDefault }];
26
+ return /* @__PURE__ */ jsxs(View, { style, children: [
27
+ /* @__PURE__ */ jsxs(View, { style: styles.grid, children: [
28
+ value.map((media, i) => /* @__PURE__ */ jsxs(View, { style: tile, children: [
29
+ /* @__PURE__ */ jsx(Image, { source: { uri: media.uri }, style: StyleSheet.absoluteFill, resizeMode: "cover", accessibilityIgnoresInvertColors: true }),
30
+ /* @__PURE__ */ jsx(Pressable, { role: "button", "aria-label": labels.remove(i + 1), hitSlop: 8, onPress: () => onValueChange(value.filter((_, j) => j !== i)), style: [styles.remove, { backgroundColor: theme.scrimStrong }], children: /* @__PURE__ */ jsx(Svg, { width: 14, height: 14, viewBox: "0 0 24 24", "aria-hidden": true, children: /* @__PURE__ */ jsx(Path, { d: "M18 6 6 18M6 6l12 12", stroke: theme.textOnMedia, strokeWidth: 3, strokeLinecap: "round" }) }) })
31
+ ] }, `${media.uri}-${i}`)),
32
+ left > 0 ? /* @__PURE__ */ jsxs(Pressable, { role: "button", "aria-label": labels.add, onPress: () => camera ? setChoosing(true) : void fromLibrary(), style: ({ pressed }) => [...tile, styles.add, { borderStyle: "dashed", opacity: pressed ? 0.7 : 1 }], children: [
33
+ /* @__PURE__ */ jsx(Svg, { width: 26, height: 26, viewBox: "0 0 24 24", "aria-hidden": true, children: /* @__PURE__ */ jsx(Path, { d: "M12 5v14M5 12h14", stroke: theme.accentText, strokeWidth: 2.4, strokeLinecap: "round" }) }),
34
+ /* @__PURE__ */ jsx(Txt, { variant: "caption", tone: "secondary", "aria-hidden": true, children: labels.add })
35
+ ] }) : null
36
+ ] }),
37
+ labels.count && max > 1 ? /* @__PURE__ */ jsx(Txt, { variant: "caption", tone: "secondary", style: styles.count, children: labels.count(value.length, max) }) : null,
38
+ camera ? /* @__PURE__ */ jsx(
39
+ ActionSheet,
40
+ {
41
+ open: choosing,
42
+ onOpenChange: setChoosing,
43
+ title: labels.source,
44
+ cancelLabel: labels.cancel,
45
+ actions: [
46
+ { label: labels.library, onPress: () => void fromLibrary() },
47
+ { label: labels.camera, onPress: () => void fromCamera() }
48
+ ]
49
+ }
50
+ ) : null
51
+ ] });
52
+ }
53
+ var styles = StyleSheet.create({
54
+ grid: { flexDirection: "row", flexWrap: "wrap", gap: 8 },
55
+ tile: { width: 96, height: 96, overflow: "hidden", borderWidth: StyleSheet.hairlineWidth },
56
+ add: { alignItems: "center", justifyContent: "center", gap: 4, borderWidth: 1.5 },
57
+ remove: { position: "absolute", top: 6, right: 6, width: 24, height: 24, borderRadius: 12, alignItems: "center", justifyContent: "center" },
58
+ count: { marginTop: 8 }
59
+ });
60
+ export {
61
+ MediaPicker
62
+ };
63
+ //# sourceMappingURL=media-picker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/native/media-picker.tsx"],"sourcesContent":["// @krizaka/ui/native/media-picker — its own entry, because it imports expo-image-picker: an optional peer, installed\n// only by the apps that pick photos or videos. The theme, the sheet and the buttons come from @krizaka/ui/native.\nimport { ActionSheet, Txt, useTheme } from \"@krizaka/ui/native\";\nimport { launchCameraAsync, launchImageLibraryAsync, requestCameraPermissionsAsync } from \"expo-image-picker\";\nimport * as React from \"react\";\nimport { Image, Pressable, type StyleProp, StyleSheet, View, type ViewStyle } from \"react-native\";\nimport Svg, { Path } from \"react-native-svg\";\n\n/** A picked photo or video, on the device. */\nexport type PickedMedia = {\n /** Its file on the device (upload it from here). */\n uri: string;\n /** `image` or `video`. */\n kind: \"image\" | \"video\";\n /** Its size in pixels. */\n width: number;\n height: number;\n /** A video's length in milliseconds. */\n duration?: number | null;\n /** Its file name, when the system gives it. */\n fileName?: string | null;\n};\n\nexport type MediaPickerLabels = {\n /** The add tile (“Add a photo”). */\n add: string;\n /** The sheet's title (“Add from”). */\n source: string;\n /** From the library (“Photo library”). */\n library: string;\n /** From the camera (“Take a photo”). */\n camera: string;\n /** Cancel. */\n cancel: string;\n /** A tile's remove button: `(n) => \"Remove photo \" + n`. */\n remove: (position: number) => string;\n /** The count under the grid: `(n, max) => n + \" of \" + max`. */\n count?: (n: number, max: number) => string;\n};\n\nexport type MediaPickerProps = {\n /** The media picked (controlled). */\n value: readonly PickedMedia[];\n /** Called with the new list. */\n onValueChange: (media: PickedMedia[]) => void;\n /** What can be picked. Default `images`. */\n accept?: \"images\" | \"videos\" | \"all\";\n /** The most that can be picked. Default 1. */\n max?: number;\n /** Offer the camera beside the library. Default true. */\n camera?: boolean;\n /** The words, passed translated. */\n labels: MediaPickerLabels;\n /** Called when the camera is refused (show a `PermissionPrompt`). */\n onPermissionDenied?: () => void;\n /** Styles merged last. */\n style?: StyleProp<ViewStyle>;\n};\n\nconst typesOf = (accept: MediaPickerProps[\"accept\"]) => (accept === \"videos\" ? [\"videos\"] : accept === \"all\" ? [\"images\", \"videos\"] : [\"images\"]);\n\n/**\n * Photos and videos picked from the library or the camera, as a grid of square tiles: an add tile (the system's\n * picker, or a sheet to choose library or camera), a remove button on each tile, a count against `max`.\n */\nexport function MediaPicker({ value, onValueChange, accept = \"images\", max = 1, camera = true, labels, onPermissionDenied, style }: MediaPickerProps) {\n const { theme, radius, haptic } = useTheme();\n const [choosing, setChoosing] = React.useState(false);\n const left = max - value.length;\n const add = (picked: { canceled: boolean; assets: readonly { uri: string; type?: string | null; width: number; height: number; duration?: number | null; fileName?: string | null }[] | null }) => {\n if (picked.canceled || !picked.assets) return;\n haptic(\"selection\");\n const media = picked.assets.map((a) => ({ uri: a.uri, kind: a.type === \"video\" ? (\"video\" as const) : (\"image\" as const), width: a.width, height: a.height, duration: a.duration, fileName: a.fileName }));\n onValueChange([...value, ...media].slice(0, max));\n };\n const fromLibrary = async () => add(await launchImageLibraryAsync({ mediaTypes: typesOf(accept) as never, allowsMultipleSelection: left > 1, selectionLimit: left, quality: 0.9 }));\n const fromCamera = async () => {\n const permission = await requestCameraPermissionsAsync();\n if (!permission.granted) return onPermissionDenied?.();\n add(await launchCameraAsync({ mediaTypes: typesOf(accept) as never, quality: 0.9 }));\n };\n const tile = [styles.tile, { borderRadius: radius.md, backgroundColor: theme.surface2, borderColor: theme.borderDefault }];\n return (\n <View style={style}>\n <View style={styles.grid}>\n {value.map((media, i) => (\n <View key={`${media.uri}-${i}`} style={tile}>\n <Image source={{ uri: media.uri }} style={StyleSheet.absoluteFill} resizeMode=\"cover\" accessibilityIgnoresInvertColors />\n <Pressable role=\"button\" aria-label={labels.remove(i + 1)} hitSlop={8} onPress={() => onValueChange(value.filter((_, j) => j !== i))} style={[styles.remove, { backgroundColor: theme.scrimStrong }]}>\n <Svg width={14} height={14} viewBox=\"0 0 24 24\" aria-hidden>\n <Path d=\"M18 6 6 18M6 6l12 12\" stroke={theme.textOnMedia} strokeWidth={3} strokeLinecap=\"round\" />\n </Svg>\n </Pressable>\n </View>\n ))}\n {left > 0 ? (\n <Pressable role=\"button\" aria-label={labels.add} onPress={() => (camera ? setChoosing(true) : void fromLibrary())} style={({ pressed }) => [...tile, styles.add, { borderStyle: \"dashed\", opacity: pressed ? 0.7 : 1 }]}>\n <Svg width={26} height={26} viewBox=\"0 0 24 24\" aria-hidden>\n <Path d=\"M12 5v14M5 12h14\" stroke={theme.accentText} strokeWidth={2.4} strokeLinecap=\"round\" />\n </Svg>\n <Txt variant=\"caption\" tone=\"secondary\" aria-hidden>\n {labels.add}\n </Txt>\n </Pressable>\n ) : null}\n </View>\n {labels.count && max > 1 ? (\n <Txt variant=\"caption\" tone=\"secondary\" style={styles.count}>\n {labels.count(value.length, max)}\n </Txt>\n ) : null}\n {camera ? (\n <ActionSheet\n open={choosing}\n onOpenChange={setChoosing}\n title={labels.source}\n cancelLabel={labels.cancel}\n actions={[\n { label: labels.library, onPress: () => void fromLibrary() },\n { label: labels.camera, onPress: () => void fromCamera() },\n ]}\n />\n ) : null}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n grid: { flexDirection: \"row\", flexWrap: \"wrap\", gap: 8 },\n tile: { width: 96, height: 96, overflow: \"hidden\", borderWidth: StyleSheet.hairlineWidth },\n add: { alignItems: \"center\", justifyContent: \"center\", gap: 4, borderWidth: 1.5 },\n remove: { position: \"absolute\", top: 6, right: 6, width: 24, height: 24, borderRadius: 12, alignItems: \"center\", justifyContent: \"center\" },\n count: { marginTop: 8 },\n});\n"],"mappings":"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","names":[]}