tempest-react-sdk 0.77.0 → 0.79.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 (1623) hide show
  1. package/README.md +6 -6
  2. package/bin/lib/alias/collect.mjs +20 -3
  3. package/bin/lib/alias/index.mjs +12 -1
  4. package/bin/lib/alias/index.test.mjs +24 -0
  5. package/bin/lib/css/analyze.test.mjs +21 -1
  6. package/bin/lib/css/collect.mjs +14 -0
  7. package/bin/lib/css/extract.mjs +63 -5
  8. package/bin/lib/css/extract.test.mjs +110 -1
  9. package/bin/lib/css/fix.e2e.test.mjs +50 -0
  10. package/bin/lib/css/index.mjs +6 -1
  11. package/bin/lib/fs/contain.mjs +50 -0
  12. package/bin/lib/icons/generate.mjs +28 -3
  13. package/bin/lib/icons/generate.test.mjs +57 -1
  14. package/bin/lib/openapi/escape.mjs +20 -6
  15. package/bin/lib/openapi/generate.encode.test.mjs +120 -0
  16. package/bin/lib/openapi/generate.hostile.test.mjs +38 -9
  17. package/bin/lib/openapi/generate.mjs +203 -64
  18. package/bin/lib/openapi/generate.pagination.test.mjs +3 -2
  19. package/bin/lib/openapi/generate.test.mjs +270 -3
  20. package/bin/lib/openapi/schema-to-zod.mjs +5 -3
  21. package/bin/tempest-gen.test.mjs +188 -0
  22. package/bin/tempest.mjs +120 -44
  23. package/dist/access/Can.cjs.map +1 -1
  24. package/dist/access/Can.js.map +1 -1
  25. package/dist/access/access-control-context.cjs.map +1 -1
  26. package/dist/access/access-control-context.js.map +1 -1
  27. package/dist/access/create-role-access-control.cjs.map +1 -1
  28. package/dist/access/create-role-access-control.js.map +1 -1
  29. package/dist/access/permissions-from-token.cjs.map +1 -1
  30. package/dist/access/permissions-from-token.js.map +1 -1
  31. package/dist/access/use-can.cjs.map +1 -1
  32. package/dist/access/use-can.js.map +1 -1
  33. package/dist/app/AppProviders.cjs.map +1 -1
  34. package/dist/app/AppProviders.js.map +1 -1
  35. package/dist/audio/audio-bus.cjs.map +1 -1
  36. package/dist/audio/audio-bus.js.map +1 -1
  37. package/dist/audio/audio-output.cjs.map +1 -1
  38. package/dist/audio/audio-output.js.map +1 -1
  39. package/dist/audio/audio-player.cjs.map +1 -1
  40. package/dist/audio/audio-player.js.map +1 -1
  41. package/dist/audio/audio-recorder.cjs.map +1 -1
  42. package/dist/audio/audio-recorder.js.map +1 -1
  43. package/dist/audio/duration.cjs.map +1 -1
  44. package/dist/audio/duration.js.map +1 -1
  45. package/dist/audio/level-meter.cjs.map +1 -1
  46. package/dist/audio/level-meter.js.map +1 -1
  47. package/dist/audio/media-access.cjs.map +1 -1
  48. package/dist/audio/media-access.js.map +1 -1
  49. package/dist/audio/noise-floor.cjs.map +1 -1
  50. package/dist/audio/noise-floor.js.map +1 -1
  51. package/dist/audio/sfx-pool.cjs.map +1 -1
  52. package/dist/audio/sfx-pool.js.map +1 -1
  53. package/dist/audio/use-audio-bus.cjs.map +1 -1
  54. package/dist/audio/use-audio-bus.js.map +1 -1
  55. package/dist/audio/use-audio-recorder.cjs.map +1 -1
  56. package/dist/audio/use-audio-recorder.js.map +1 -1
  57. package/dist/audio/use-audio.cjs.map +1 -1
  58. package/dist/audio/use-audio.js.map +1 -1
  59. package/dist/audio/use-microphone.cjs +1 -1
  60. package/dist/audio/use-microphone.cjs.map +1 -1
  61. package/dist/audio/use-microphone.js +1 -5
  62. package/dist/audio/use-microphone.js.map +1 -1
  63. package/dist/audio/use-sfx-pool.cjs.map +1 -1
  64. package/dist/audio/use-sfx-pool.js.map +1 -1
  65. package/dist/audio/voice-activity.cjs.map +1 -1
  66. package/dist/audio/voice-activity.js.map +1 -1
  67. package/dist/audio/voice-chain-stages.cjs.map +1 -1
  68. package/dist/audio/voice-chain-stages.js.map +1 -1
  69. package/dist/audio/voice-chain.cjs.map +1 -1
  70. package/dist/audio/voice-chain.js.map +1 -1
  71. package/dist/audio/wav.cjs.map +1 -1
  72. package/dist/audio/wav.js.map +1 -1
  73. package/dist/auth/AuthGuard.cjs.map +1 -1
  74. package/dist/auth/AuthGuard.js.map +1 -1
  75. package/dist/auth/create-auth-store.cjs.map +1 -1
  76. package/dist/auth/create-auth-store.js.map +1 -1
  77. package/dist/auth/create-tempest-auth.cjs +1 -1
  78. package/dist/auth/create-tempest-auth.cjs.map +1 -1
  79. package/dist/auth/create-tempest-auth.js +185 -114
  80. package/dist/auth/create-tempest-auth.js.map +1 -1
  81. package/dist/auth/jwt.cjs.map +1 -1
  82. package/dist/auth/jwt.js.map +1 -1
  83. package/dist/auth/lazy-with-retry.cjs.map +1 -1
  84. package/dist/auth/lazy-with-retry.js.map +1 -1
  85. package/dist/auth/passkey.cjs.map +1 -1
  86. package/dist/auth/passkey.js.map +1 -1
  87. package/dist/auth/refresh-queue.cjs.map +1 -1
  88. package/dist/auth/refresh-queue.js.map +1 -1
  89. package/dist/auth/use-passkey.cjs +1 -1
  90. package/dist/auth/use-passkey.cjs.map +1 -1
  91. package/dist/auth/use-passkey.js +1 -1
  92. package/dist/auth/use-passkey.js.map +1 -1
  93. package/dist/br/BrazilMap.cjs.map +1 -1
  94. package/dist/br/BrazilMap.js.map +1 -1
  95. package/dist/br/BrazilMap.module.cjs.map +1 -1
  96. package/dist/br/BrazilMap.module.js.map +1 -1
  97. package/dist/br/BrazilStateCitySelect.cjs.map +1 -1
  98. package/dist/br/BrazilStateCitySelect.js.map +1 -1
  99. package/dist/br/BrazilStateMap.cjs.map +1 -1
  100. package/dist/br/BrazilStateMap.js.map +1 -1
  101. package/dist/br/MapLegend.cjs.map +1 -1
  102. package/dist/br/MapLegend.js.map +1 -1
  103. package/dist/br/MapLegend.module.cjs.map +1 -1
  104. package/dist/br/MapLegend.module.js.map +1 -1
  105. package/dist/br/MapMarkers.cjs.map +1 -1
  106. package/dist/br/MapMarkers.js.map +1 -1
  107. package/dist/br/MapTooltip.cjs.map +1 -1
  108. package/dist/br/MapTooltip.js.map +1 -1
  109. package/dist/br/MunicipalitySearch.cjs +1 -1
  110. package/dist/br/MunicipalitySearch.cjs.map +1 -1
  111. package/dist/br/MunicipalitySearch.js +2 -5
  112. package/dist/br/MunicipalitySearch.js.map +1 -1
  113. package/dist/br/MunicipalitySearch.module.cjs.map +1 -1
  114. package/dist/br/MunicipalitySearch.module.js.map +1 -1
  115. package/dist/br/PixQRCode.cjs.map +1 -1
  116. package/dist/br/PixQRCode.js.map +1 -1
  117. package/dist/br/PixQRCode.module.cjs.map +1 -1
  118. package/dist/br/PixQRCode.module.js.map +1 -1
  119. package/dist/br/boleto.cjs.map +1 -1
  120. package/dist/br/boleto.js.map +1 -1
  121. package/dist/br/br-geo.cjs.map +1 -1
  122. package/dist/br/br-geo.js.map +1 -1
  123. package/dist/br/data/br-centroids.cjs.map +1 -1
  124. package/dist/br/data/br-centroids.js.map +1 -1
  125. package/dist/br/data/br-locations.cjs.map +1 -1
  126. package/dist/br/data/br-locations.js.map +1 -1
  127. package/dist/br/data/br-uf-geo.cjs.map +1 -1
  128. package/dist/br/data/br-uf-geo.js.map +1 -1
  129. package/dist/br/data/mun/AC.cjs.map +1 -1
  130. package/dist/br/data/mun/AC.js.map +1 -1
  131. package/dist/br/data/mun/AL.cjs.map +1 -1
  132. package/dist/br/data/mun/AL.js.map +1 -1
  133. package/dist/br/data/mun/AM.cjs.map +1 -1
  134. package/dist/br/data/mun/AM.js.map +1 -1
  135. package/dist/br/data/mun/AP.cjs.map +1 -1
  136. package/dist/br/data/mun/AP.js.map +1 -1
  137. package/dist/br/data/mun/BA.cjs.map +1 -1
  138. package/dist/br/data/mun/BA.js.map +1 -1
  139. package/dist/br/data/mun/CE.cjs.map +1 -1
  140. package/dist/br/data/mun/CE.js.map +1 -1
  141. package/dist/br/data/mun/DF.cjs.map +1 -1
  142. package/dist/br/data/mun/DF.js.map +1 -1
  143. package/dist/br/data/mun/ES.cjs.map +1 -1
  144. package/dist/br/data/mun/ES.js.map +1 -1
  145. package/dist/br/data/mun/GO.cjs.map +1 -1
  146. package/dist/br/data/mun/GO.js.map +1 -1
  147. package/dist/br/data/mun/MA.cjs.map +1 -1
  148. package/dist/br/data/mun/MA.js.map +1 -1
  149. package/dist/br/data/mun/MG.cjs.map +1 -1
  150. package/dist/br/data/mun/MG.js.map +1 -1
  151. package/dist/br/data/mun/MS.cjs.map +1 -1
  152. package/dist/br/data/mun/MS.js.map +1 -1
  153. package/dist/br/data/mun/MT.cjs.map +1 -1
  154. package/dist/br/data/mun/MT.js.map +1 -1
  155. package/dist/br/data/mun/PA.cjs.map +1 -1
  156. package/dist/br/data/mun/PA.js.map +1 -1
  157. package/dist/br/data/mun/PB.cjs.map +1 -1
  158. package/dist/br/data/mun/PB.js.map +1 -1
  159. package/dist/br/data/mun/PE.cjs.map +1 -1
  160. package/dist/br/data/mun/PE.js.map +1 -1
  161. package/dist/br/data/mun/PI.cjs.map +1 -1
  162. package/dist/br/data/mun/PI.js.map +1 -1
  163. package/dist/br/data/mun/PR.cjs.map +1 -1
  164. package/dist/br/data/mun/PR.js.map +1 -1
  165. package/dist/br/data/mun/RJ.cjs.map +1 -1
  166. package/dist/br/data/mun/RJ.js.map +1 -1
  167. package/dist/br/data/mun/RN.cjs.map +1 -1
  168. package/dist/br/data/mun/RN.js.map +1 -1
  169. package/dist/br/data/mun/RO.cjs.map +1 -1
  170. package/dist/br/data/mun/RO.js.map +1 -1
  171. package/dist/br/data/mun/RR.cjs.map +1 -1
  172. package/dist/br/data/mun/RR.js.map +1 -1
  173. package/dist/br/data/mun/RS.cjs.map +1 -1
  174. package/dist/br/data/mun/RS.js.map +1 -1
  175. package/dist/br/data/mun/SC.cjs.map +1 -1
  176. package/dist/br/data/mun/SC.js.map +1 -1
  177. package/dist/br/data/mun/SE.cjs.map +1 -1
  178. package/dist/br/data/mun/SE.js.map +1 -1
  179. package/dist/br/data/mun/SP.cjs.map +1 -1
  180. package/dist/br/data/mun/SP.js.map +1 -1
  181. package/dist/br/data/mun/TO.cjs.map +1 -1
  182. package/dist/br/data/mun/TO.js.map +1 -1
  183. package/dist/br/geocode.cjs.map +1 -1
  184. package/dist/br/geocode.js.map +1 -1
  185. package/dist/br/holidays.cjs.map +1 -1
  186. package/dist/br/holidays.js.map +1 -1
  187. package/dist/br/locations.cjs.map +1 -1
  188. package/dist/br/locations.js.map +1 -1
  189. package/dist/br/nfe.cjs.map +1 -1
  190. package/dist/br/nfe.js.map +1 -1
  191. package/dist/br/pix.cjs +1 -1
  192. package/dist/br/pix.cjs.map +1 -1
  193. package/dist/br/pix.js +108 -71
  194. package/dist/br/pix.js.map +1 -1
  195. package/dist/br/regions.cjs.map +1 -1
  196. package/dist/br/regions.js.map +1 -1
  197. package/dist/br/scales.cjs.map +1 -1
  198. package/dist/br/scales.js.map +1 -1
  199. package/dist/br/state-geo.cjs.map +1 -1
  200. package/dist/br/state-geo.js.map +1 -1
  201. package/dist/br/svg-utils.cjs.map +1 -1
  202. package/dist/br/svg-utils.js.map +1 -1
  203. package/dist/br/use-map-hover.cjs.map +1 -1
  204. package/dist/br/use-map-hover.js.map +1 -1
  205. package/dist/br/use-map-zoom.cjs.map +1 -1
  206. package/dist/br/use-map-zoom.js.map +1 -1
  207. package/dist/br/whatsapp.cjs.map +1 -1
  208. package/dist/br/whatsapp.js.map +1 -1
  209. package/dist/br.cjs.map +1 -1
  210. package/dist/br.d.ts +16 -5
  211. package/dist/br.js.map +1 -1
  212. package/dist/capture/barcode.cjs.map +1 -1
  213. package/dist/capture/barcode.js.map +1 -1
  214. package/dist/capture/media-recorder.cjs.map +1 -1
  215. package/dist/capture/media-recorder.js.map +1 -1
  216. package/dist/capture/use-barcode-scanner.cjs.map +1 -1
  217. package/dist/capture/use-barcode-scanner.js.map +1 -1
  218. package/dist/capture/use-screen-capture.cjs +1 -1
  219. package/dist/capture/use-screen-capture.cjs.map +1 -1
  220. package/dist/capture/use-screen-capture.js +1 -7
  221. package/dist/capture/use-screen-capture.js.map +1 -1
  222. package/dist/capture/use-speech-recognition.cjs +1 -1
  223. package/dist/capture/use-speech-recognition.cjs.map +1 -1
  224. package/dist/capture/use-speech-recognition.js +35 -36
  225. package/dist/capture/use-speech-recognition.js.map +1 -1
  226. package/dist/capture/use-torch.cjs.map +1 -1
  227. package/dist/capture/use-torch.js.map +1 -1
  228. package/dist/capture/use-video-recorder.cjs.map +1 -1
  229. package/dist/capture/use-video-recorder.js.map +1 -1
  230. package/dist/capture/video-recorder.cjs.map +1 -1
  231. package/dist/capture/video-recorder.js.map +1 -1
  232. package/dist/charts/AreaChart.cjs.map +1 -1
  233. package/dist/charts/AreaChart.js.map +1 -1
  234. package/dist/charts/BarChart.cjs.map +1 -1
  235. package/dist/charts/BarChart.js.map +1 -1
  236. package/dist/charts/LineChart.cjs.map +1 -1
  237. package/dist/charts/LineChart.js.map +1 -1
  238. package/dist/charts/PieChart.cjs.map +1 -1
  239. package/dist/charts/PieChart.js.map +1 -1
  240. package/dist/charts/RadarChart.cjs.map +1 -1
  241. package/dist/charts/RadarChart.js.map +1 -1
  242. package/dist/charts/palette.cjs.map +1 -1
  243. package/dist/charts/palette.js.map +1 -1
  244. package/dist/charts/scales.cjs.map +1 -1
  245. package/dist/charts/scales.js.map +1 -1
  246. package/dist/charts/types.cjs.map +1 -1
  247. package/dist/charts/types.js.map +1 -1
  248. package/dist/charts/use-chart-colors.cjs.map +1 -1
  249. package/dist/charts/use-chart-colors.js.map +1 -1
  250. package/dist/components/AIChat/AIChat.cjs +1 -1
  251. package/dist/components/AIChat/AIChat.cjs.map +1 -1
  252. package/dist/components/AIChat/AIChat.js +1 -5
  253. package/dist/components/AIChat/AIChat.js.map +1 -1
  254. package/dist/components/AIChat/AIChat.module.cjs.map +1 -1
  255. package/dist/components/AIChat/AIChat.module.js.map +1 -1
  256. package/dist/components/AIChat/AIChatComposer.cjs +1 -1
  257. package/dist/components/AIChat/AIChatComposer.cjs.map +1 -1
  258. package/dist/components/AIChat/AIChatComposer.js +1 -7
  259. package/dist/components/AIChat/AIChatComposer.js.map +1 -1
  260. package/dist/components/AIChat/AIChatTurn.cjs.map +1 -1
  261. package/dist/components/AIChat/AIChatTurn.js.map +1 -1
  262. package/dist/components/AIChat/ai-chat-turns.cjs.map +1 -1
  263. package/dist/components/AIChat/ai-chat-turns.js.map +1 -1
  264. package/dist/components/Accordion/Accordion.cjs.map +1 -1
  265. package/dist/components/Accordion/Accordion.js.map +1 -1
  266. package/dist/components/Accordion/Accordion.module.cjs.map +1 -1
  267. package/dist/components/Accordion/Accordion.module.js.map +1 -1
  268. package/dist/components/Alert/Alert.cjs.map +1 -1
  269. package/dist/components/Alert/Alert.js.map +1 -1
  270. package/dist/components/Alert/Alert.module.cjs.map +1 -1
  271. package/dist/components/Alert/Alert.module.js.map +1 -1
  272. package/dist/components/AppBar/AppBar.cjs.map +1 -1
  273. package/dist/components/AppBar/AppBar.js.map +1 -1
  274. package/dist/components/AppBar/AppBar.module.cjs.map +1 -1
  275. package/dist/components/AppBar/AppBar.module.js.map +1 -1
  276. package/dist/components/AppBar/use-sticky-body-warning.cjs +1 -1
  277. package/dist/components/AppBar/use-sticky-body-warning.cjs.map +1 -1
  278. package/dist/components/AppBar/use-sticky-body-warning.js +1 -1
  279. package/dist/components/AppBar/use-sticky-body-warning.js.map +1 -1
  280. package/dist/components/AppShell/AppShell.cjs.map +1 -1
  281. package/dist/components/AppShell/AppShell.js.map +1 -1
  282. package/dist/components/AppShell/AppShell.module.cjs.map +1 -1
  283. package/dist/components/AppShell/AppShell.module.js.map +1 -1
  284. package/dist/components/AspectRatio/AspectRatio.cjs.map +1 -1
  285. package/dist/components/AspectRatio/AspectRatio.js.map +1 -1
  286. package/dist/components/AspectRatio/AspectRatio.module.cjs.map +1 -1
  287. package/dist/components/AspectRatio/AspectRatio.module.js.map +1 -1
  288. package/dist/components/AudioPlayer/AudioPlayer.cjs +1 -1
  289. package/dist/components/AudioPlayer/AudioPlayer.cjs.map +1 -1
  290. package/dist/components/AudioPlayer/AudioPlayer.js +1 -7
  291. package/dist/components/AudioPlayer/AudioPlayer.js.map +1 -1
  292. package/dist/components/AudioPlayer/AudioPlayer.module.cjs.map +1 -1
  293. package/dist/components/AudioPlayer/AudioPlayer.module.js.map +1 -1
  294. package/dist/components/AudioRecorder/AudioRecorder.cjs +1 -1
  295. package/dist/components/AudioRecorder/AudioRecorder.cjs.map +1 -1
  296. package/dist/components/AudioRecorder/AudioRecorder.js +16 -21
  297. package/dist/components/AudioRecorder/AudioRecorder.js.map +1 -1
  298. package/dist/components/AudioRecorder/AudioRecorder.module.cjs.map +1 -1
  299. package/dist/components/AudioRecorder/AudioRecorder.module.js.map +1 -1
  300. package/dist/components/Avatar/Avatar.cjs.map +1 -1
  301. package/dist/components/Avatar/Avatar.js.map +1 -1
  302. package/dist/components/Avatar/Avatar.module.cjs.map +1 -1
  303. package/dist/components/Avatar/Avatar.module.js.map +1 -1
  304. package/dist/components/AvatarGroup/AvatarGroup.cjs.map +1 -1
  305. package/dist/components/AvatarGroup/AvatarGroup.js.map +1 -1
  306. package/dist/components/AvatarGroup/AvatarGroup.module.cjs.map +1 -1
  307. package/dist/components/AvatarGroup/AvatarGroup.module.js.map +1 -1
  308. package/dist/components/Badge/Badge.cjs.map +1 -1
  309. package/dist/components/Badge/Badge.js.map +1 -1
  310. package/dist/components/Badge/Badge.module.cjs.map +1 -1
  311. package/dist/components/Badge/Badge.module.js.map +1 -1
  312. package/dist/components/Banner/Banner.cjs.map +1 -1
  313. package/dist/components/Banner/Banner.js.map +1 -1
  314. package/dist/components/Banner/Banner.module.cjs.map +1 -1
  315. package/dist/components/Banner/Banner.module.js.map +1 -1
  316. package/dist/components/BarList/BarList.cjs.map +1 -1
  317. package/dist/components/BarList/BarList.js.map +1 -1
  318. package/dist/components/BarList/BarList.module.cjs.map +1 -1
  319. package/dist/components/BarList/BarList.module.js.map +1 -1
  320. package/dist/components/BarList/bar-list-model.cjs.map +1 -1
  321. package/dist/components/BarList/bar-list-model.js.map +1 -1
  322. package/dist/components/BarcodeScanner/BarcodeScanner.cjs.map +1 -1
  323. package/dist/components/BarcodeScanner/BarcodeScanner.js.map +1 -1
  324. package/dist/components/BarcodeScanner/BarcodeScanner.module.cjs.map +1 -1
  325. package/dist/components/BarcodeScanner/BarcodeScanner.module.js.map +1 -1
  326. package/dist/components/BottomNavigation/BottomNavigation.cjs.map +1 -1
  327. package/dist/components/BottomNavigation/BottomNavigation.js.map +1 -1
  328. package/dist/components/BottomNavigation/BottomNavigation.module.cjs.map +1 -1
  329. package/dist/components/BottomNavigation/BottomNavigation.module.js.map +1 -1
  330. package/dist/components/BottomSheet/BottomSheet.cjs.map +1 -1
  331. package/dist/components/BottomSheet/BottomSheet.js.map +1 -1
  332. package/dist/components/BottomSheet/BottomSheet.module.cjs.map +1 -1
  333. package/dist/components/BottomSheet/BottomSheet.module.js.map +1 -1
  334. package/dist/components/Breadcrumbs/Breadcrumbs.cjs.map +1 -1
  335. package/dist/components/Breadcrumbs/Breadcrumbs.js.map +1 -1
  336. package/dist/components/Breadcrumbs/Breadcrumbs.module.cjs.map +1 -1
  337. package/dist/components/Breadcrumbs/Breadcrumbs.module.js.map +1 -1
  338. package/dist/components/Button/Button.cjs.map +1 -1
  339. package/dist/components/Button/Button.js.map +1 -1
  340. package/dist/components/Button/Button.module.cjs.map +1 -1
  341. package/dist/components/Button/Button.module.js.map +1 -1
  342. package/dist/components/Button/ButtonContent.cjs.map +1 -1
  343. package/dist/components/Button/ButtonContent.js.map +1 -1
  344. package/dist/components/Button/ButtonSlot.cjs.map +1 -1
  345. package/dist/components/Button/ButtonSlot.js.map +1 -1
  346. package/dist/components/Button/button-class.cjs.map +1 -1
  347. package/dist/components/Button/button-class.js.map +1 -1
  348. package/dist/components/Button/link-rel.cjs.map +1 -1
  349. package/dist/components/Button/link-rel.js.map +1 -1
  350. package/dist/components/Button/slot.cjs.map +1 -1
  351. package/dist/components/Button/slot.js.map +1 -1
  352. package/dist/components/Calendar/Calendar.cjs.map +1 -1
  353. package/dist/components/Calendar/Calendar.js.map +1 -1
  354. package/dist/components/Calendar/Calendar.module.cjs.map +1 -1
  355. package/dist/components/Calendar/Calendar.module.js.map +1 -1
  356. package/dist/components/Card/Card.cjs.map +1 -1
  357. package/dist/components/Card/Card.js.map +1 -1
  358. package/dist/components/Card/Card.module.cjs.map +1 -1
  359. package/dist/components/Card/Card.module.js.map +1 -1
  360. package/dist/components/Carousel/Carousel.cjs.map +1 -1
  361. package/dist/components/Carousel/Carousel.js.map +1 -1
  362. package/dist/components/Carousel/Carousel.module.cjs.map +1 -1
  363. package/dist/components/Carousel/Carousel.module.js.map +1 -1
  364. package/dist/components/Center/Center.cjs.map +1 -1
  365. package/dist/components/Center/Center.js.map +1 -1
  366. package/dist/components/Center/Center.module.cjs.map +1 -1
  367. package/dist/components/Center/Center.module.js.map +1 -1
  368. package/dist/components/Chat/Chat.cjs.map +1 -1
  369. package/dist/components/Chat/Chat.js.map +1 -1
  370. package/dist/components/Chat/Chat.module.cjs.map +1 -1
  371. package/dist/components/Chat/Chat.module.js.map +1 -1
  372. package/dist/components/Chat/ChatActionsMenu.cjs.map +1 -1
  373. package/dist/components/Chat/ChatActionsMenu.js.map +1 -1
  374. package/dist/components/Chat/ChatAttachments.cjs.map +1 -1
  375. package/dist/components/Chat/ChatAttachments.js.map +1 -1
  376. package/dist/components/Chat/ChatBubble.cjs.map +1 -1
  377. package/dist/components/Chat/ChatBubble.js.map +1 -1
  378. package/dist/components/Chat/ChatComposer.cjs.map +1 -1
  379. package/dist/components/Chat/ChatComposer.js.map +1 -1
  380. package/dist/components/Chat/chat-groups.cjs +1 -1
  381. package/dist/components/Chat/chat-groups.cjs.map +1 -1
  382. package/dist/components/Chat/chat-groups.js +2 -6
  383. package/dist/components/Chat/chat-groups.js.map +1 -1
  384. package/dist/components/Chat/chat-receipt.cjs.map +1 -1
  385. package/dist/components/Chat/chat-receipt.js.map +1 -1
  386. package/dist/components/Checkbox/Checkbox.cjs.map +1 -1
  387. package/dist/components/Checkbox/Checkbox.js.map +1 -1
  388. package/dist/components/Checkbox/Checkbox.module.cjs.map +1 -1
  389. package/dist/components/Checkbox/Checkbox.module.js.map +1 -1
  390. package/dist/components/ChipInput/ChipInput.cjs +1 -1
  391. package/dist/components/ChipInput/ChipInput.cjs.map +1 -1
  392. package/dist/components/ChipInput/ChipInput.js +2 -12
  393. package/dist/components/ChipInput/ChipInput.js.map +1 -1
  394. package/dist/components/ChipInput/ChipInput.module.cjs.map +1 -1
  395. package/dist/components/ChipInput/ChipInput.module.js.map +1 -1
  396. package/dist/components/ClickOutside/ClickOutside.cjs.map +1 -1
  397. package/dist/components/ClickOutside/ClickOutside.js.map +1 -1
  398. package/dist/components/CodeBlock/CodeBlock.cjs +1 -1
  399. package/dist/components/CodeBlock/CodeBlock.cjs.map +1 -1
  400. package/dist/components/CodeBlock/CodeBlock.js +1 -1
  401. package/dist/components/CodeBlock/CodeBlock.js.map +1 -1
  402. package/dist/components/CodeBlock/CodeBlock.module.cjs.map +1 -1
  403. package/dist/components/CodeBlock/CodeBlock.module.js.map +1 -1
  404. package/dist/components/CodeBlock/tokenize.cjs +1 -1
  405. package/dist/components/CodeBlock/tokenize.cjs.map +1 -1
  406. package/dist/components/CodeBlock/tokenize.js +54 -25
  407. package/dist/components/CodeBlock/tokenize.js.map +1 -1
  408. package/dist/components/Collapsible/Collapsible.cjs.map +1 -1
  409. package/dist/components/Collapsible/Collapsible.js.map +1 -1
  410. package/dist/components/Collapsible/Collapsible.module.cjs.map +1 -1
  411. package/dist/components/Collapsible/Collapsible.module.js.map +1 -1
  412. package/dist/components/Combobox/Combobox.cjs.map +1 -1
  413. package/dist/components/Combobox/Combobox.js.map +1 -1
  414. package/dist/components/Combobox/Combobox.module.cjs.map +1 -1
  415. package/dist/components/Combobox/Combobox.module.js.map +1 -1
  416. package/dist/components/Combobox/use-listbox-dismiss.cjs.map +1 -1
  417. package/dist/components/Combobox/use-listbox-dismiss.js.map +1 -1
  418. package/dist/components/Command/Command.cjs +1 -1
  419. package/dist/components/Command/Command.cjs.map +1 -1
  420. package/dist/components/Command/Command.js +4 -11
  421. package/dist/components/Command/Command.js.map +1 -1
  422. package/dist/components/Command/Command.module.cjs.map +1 -1
  423. package/dist/components/Command/Command.module.js.map +1 -1
  424. package/dist/components/ConditionalWrapper/ConditionalWrapper.cjs.map +1 -1
  425. package/dist/components/ConditionalWrapper/ConditionalWrapper.js.map +1 -1
  426. package/dist/components/ConfirmDialog/ConfirmDialog.cjs.map +1 -1
  427. package/dist/components/ConfirmDialog/ConfirmDialog.js.map +1 -1
  428. package/dist/components/ContextMenu/ContextMenu.cjs +1 -1
  429. package/dist/components/ContextMenu/ContextMenu.cjs.map +1 -1
  430. package/dist/components/ContextMenu/ContextMenu.js +1 -1
  431. package/dist/components/ContextMenu/ContextMenu.js.map +1 -1
  432. package/dist/components/ContextMenu/ContextMenu.module.cjs.map +1 -1
  433. package/dist/components/ContextMenu/ContextMenu.module.js.map +1 -1
  434. package/dist/components/CopyButton/CopyButton.cjs.map +1 -1
  435. package/dist/components/CopyButton/CopyButton.js.map +1 -1
  436. package/dist/components/CopyButton/CopyButton.module.cjs.map +1 -1
  437. package/dist/components/CopyButton/CopyButton.module.js.map +1 -1
  438. package/dist/components/DataList/DataList.cjs.map +1 -1
  439. package/dist/components/DataList/DataList.js.map +1 -1
  440. package/dist/components/DataList/DataList.module.cjs.map +1 -1
  441. package/dist/components/DataList/DataList.module.js.map +1 -1
  442. package/dist/components/DataTable/DataTable.cjs +1 -1
  443. package/dist/components/DataTable/DataTable.cjs.map +1 -1
  444. package/dist/components/DataTable/DataTable.js +6 -14
  445. package/dist/components/DataTable/DataTable.js.map +1 -1
  446. package/dist/components/DataTable/DataTable.module.cjs.map +1 -1
  447. package/dist/components/DataTable/DataTable.module.js.map +1 -1
  448. package/dist/components/DataTable/EditableCell.cjs +1 -1
  449. package/dist/components/DataTable/EditableCell.cjs.map +1 -1
  450. package/dist/components/DataTable/EditableCell.js +1 -9
  451. package/dist/components/DataTable/EditableCell.js.map +1 -1
  452. package/dist/components/DataTable/LoadingRows.cjs.map +1 -1
  453. package/dist/components/DataTable/LoadingRows.js.map +1 -1
  454. package/dist/components/DataTable/edit-labels.cjs.map +1 -1
  455. package/dist/components/DataTable/edit-labels.js.map +1 -1
  456. package/dist/components/DataTable/use-dev-warnings.cjs.map +1 -1
  457. package/dist/components/DataTable/use-dev-warnings.js.map +1 -1
  458. package/dist/components/DatePicker/DatePicker.cjs.map +1 -1
  459. package/dist/components/DatePicker/DatePicker.js.map +1 -1
  460. package/dist/components/DateRangePicker/DateRangePicker.cjs.map +1 -1
  461. package/dist/components/DateRangePicker/DateRangePicker.js.map +1 -1
  462. package/dist/components/DateRangePicker/DateRangePicker.module.cjs.map +1 -1
  463. package/dist/components/DateRangePicker/DateRangePicker.module.js.map +1 -1
  464. package/dist/components/DescriptionList/DescriptionList.cjs.map +1 -1
  465. package/dist/components/DescriptionList/DescriptionList.js.map +1 -1
  466. package/dist/components/DescriptionList/DescriptionList.module.cjs.map +1 -1
  467. package/dist/components/DescriptionList/DescriptionList.module.js.map +1 -1
  468. package/dist/components/Divider/Divider.cjs.map +1 -1
  469. package/dist/components/Divider/Divider.js.map +1 -1
  470. package/dist/components/Divider/Divider.module.cjs.map +1 -1
  471. package/dist/components/Divider/Divider.module.js.map +1 -1
  472. package/dist/components/Drawer/Drawer.cjs.map +1 -1
  473. package/dist/components/Drawer/Drawer.js.map +1 -1
  474. package/dist/components/Drawer/Drawer.module.cjs.map +1 -1
  475. package/dist/components/Drawer/Drawer.module.js.map +1 -1
  476. package/dist/components/DropdownMenu/DropdownMenu.cjs +1 -1
  477. package/dist/components/DropdownMenu/DropdownMenu.cjs.map +1 -1
  478. package/dist/components/DropdownMenu/DropdownMenu.js +2 -14
  479. package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -1
  480. package/dist/components/DropdownMenu/DropdownMenu.module.cjs.map +1 -1
  481. package/dist/components/DropdownMenu/DropdownMenu.module.js.map +1 -1
  482. package/dist/components/Dropzone/Dropzone.cjs.map +1 -1
  483. package/dist/components/Dropzone/Dropzone.js.map +1 -1
  484. package/dist/components/Dropzone/Dropzone.module.cjs.map +1 -1
  485. package/dist/components/Dropzone/Dropzone.module.js.map +1 -1
  486. package/dist/components/EmptyState/EmptyState.cjs.map +1 -1
  487. package/dist/components/EmptyState/EmptyState.js.map +1 -1
  488. package/dist/components/EmptyState/EmptyState.module.cjs.map +1 -1
  489. package/dist/components/EmptyState/EmptyState.module.js.map +1 -1
  490. package/dist/components/ErrorState/ErrorState.cjs.map +1 -1
  491. package/dist/components/ErrorState/ErrorState.js.map +1 -1
  492. package/dist/components/ErrorState/ErrorState.module.cjs.map +1 -1
  493. package/dist/components/ErrorState/ErrorState.module.js.map +1 -1
  494. package/dist/components/ErrorText/ErrorText.cjs.map +1 -1
  495. package/dist/components/ErrorText/ErrorText.js.map +1 -1
  496. package/dist/components/ErrorText/ErrorText.module.cjs.map +1 -1
  497. package/dist/components/ErrorText/ErrorText.module.js.map +1 -1
  498. package/dist/components/FileUpload/FileUpload.cjs +1 -1
  499. package/dist/components/FileUpload/FileUpload.cjs.map +1 -1
  500. package/dist/components/FileUpload/FileUpload.js +7 -17
  501. package/dist/components/FileUpload/FileUpload.js.map +1 -1
  502. package/dist/components/FileUpload/FileUpload.module.cjs.map +1 -1
  503. package/dist/components/FileUpload/FileUpload.module.js.map +1 -1
  504. package/dist/components/FilterBar/FilterBar.cjs.map +1 -1
  505. package/dist/components/FilterBar/FilterBar.js.map +1 -1
  506. package/dist/components/FilterBar/FilterBar.module.cjs.map +1 -1
  507. package/dist/components/FilterBar/FilterBar.module.js.map +1 -1
  508. package/dist/components/FilterBar/filter-apply.cjs.map +1 -1
  509. package/dist/components/FilterBar/filter-apply.js.map +1 -1
  510. package/dist/components/FilterBar/filter-model.cjs.map +1 -1
  511. package/dist/components/FilterBar/filter-model.js.map +1 -1
  512. package/dist/components/FilterBar/filter-query.cjs +1 -1
  513. package/dist/components/FilterBar/filter-query.cjs.map +1 -1
  514. package/dist/components/FilterBar/filter-query.js +2 -5
  515. package/dist/components/FilterBar/filter-query.js.map +1 -1
  516. package/dist/components/FilterPanel/FilterPanel.cjs.map +1 -1
  517. package/dist/components/FilterPanel/FilterPanel.js.map +1 -1
  518. package/dist/components/FilterPanel/FilterPanel.module.cjs.map +1 -1
  519. package/dist/components/FilterPanel/FilterPanel.module.js.map +1 -1
  520. package/dist/components/FloatingActionButton/FloatingActionButton.cjs.map +1 -1
  521. package/dist/components/FloatingActionButton/FloatingActionButton.js.map +1 -1
  522. package/dist/components/FloatingActionButton/FloatingActionButton.module.cjs.map +1 -1
  523. package/dist/components/FloatingActionButton/FloatingActionButton.module.js.map +1 -1
  524. package/dist/components/For/For.cjs.map +1 -1
  525. package/dist/components/For/For.js.map +1 -1
  526. package/dist/components/Form/Form.cjs.map +1 -1
  527. package/dist/components/Form/Form.js.map +1 -1
  528. package/dist/components/Form/Form.module.cjs.map +1 -1
  529. package/dist/components/Form/Form.module.js.map +1 -1
  530. package/dist/components/HoverCard/HoverCard.cjs.map +1 -1
  531. package/dist/components/HoverCard/HoverCard.js.map +1 -1
  532. package/dist/components/HoverCard/HoverCard.module.cjs.map +1 -1
  533. package/dist/components/HoverCard/HoverCard.module.js.map +1 -1
  534. package/dist/components/Image/Image.cjs.map +1 -1
  535. package/dist/components/Image/Image.js.map +1 -1
  536. package/dist/components/Image/Image.module.cjs.map +1 -1
  537. package/dist/components/Image/Image.module.js.map +1 -1
  538. package/dist/components/ImageCropper/ImageCropper.cjs +1 -1
  539. package/dist/components/ImageCropper/ImageCropper.cjs.map +1 -1
  540. package/dist/components/ImageCropper/ImageCropper.js +4 -8
  541. package/dist/components/ImageCropper/ImageCropper.js.map +1 -1
  542. package/dist/components/ImageCropper/ImageCropper.module.cjs.map +1 -1
  543. package/dist/components/ImageCropper/ImageCropper.module.js.map +1 -1
  544. package/dist/components/ImageCropper/crop-geometry.cjs.map +1 -1
  545. package/dist/components/ImageCropper/crop-geometry.js.map +1 -1
  546. package/dist/components/Input/Input.cjs.map +1 -1
  547. package/dist/components/Input/Input.js.map +1 -1
  548. package/dist/components/Input/Input.module.cjs.map +1 -1
  549. package/dist/components/Input/Input.module.js.map +1 -1
  550. package/dist/components/InstallBanner/InstallBanner.cjs.map +1 -1
  551. package/dist/components/InstallBanner/InstallBanner.js.map +1 -1
  552. package/dist/components/InstallBanner/InstallBanner.module.cjs.map +1 -1
  553. package/dist/components/InstallBanner/InstallBanner.module.js.map +1 -1
  554. package/dist/components/InstallButton/InstallButton.cjs.map +1 -1
  555. package/dist/components/InstallButton/InstallButton.js.map +1 -1
  556. package/dist/components/InstallButton/InstallButton.module.cjs.map +1 -1
  557. package/dist/components/InstallButton/InstallButton.module.js.map +1 -1
  558. package/dist/components/InstallButton/install-hints.cjs.map +1 -1
  559. package/dist/components/InstallButton/install-hints.js.map +1 -1
  560. package/dist/components/Kanban/Kanban.cjs.map +1 -1
  561. package/dist/components/Kanban/Kanban.js.map +1 -1
  562. package/dist/components/Kanban/Kanban.module.cjs.map +1 -1
  563. package/dist/components/Kanban/Kanban.module.js.map +1 -1
  564. package/dist/components/Kbd/Kbd.cjs.map +1 -1
  565. package/dist/components/Kbd/Kbd.js.map +1 -1
  566. package/dist/components/Kbd/Kbd.module.cjs.map +1 -1
  567. package/dist/components/Kbd/Kbd.module.js.map +1 -1
  568. package/dist/components/Label/Label.cjs.map +1 -1
  569. package/dist/components/Label/Label.js.map +1 -1
  570. package/dist/components/Label/Label.module.cjs.map +1 -1
  571. package/dist/components/Label/Label.module.js.map +1 -1
  572. package/dist/components/Layout/Layout.cjs.map +1 -1
  573. package/dist/components/Layout/Layout.js.map +1 -1
  574. package/dist/components/Layout/Layout.module.cjs.map +1 -1
  575. package/dist/components/Layout/Layout.module.js.map +1 -1
  576. package/dist/components/Lightbox/Lightbox.cjs +1 -1
  577. package/dist/components/Lightbox/Lightbox.cjs.map +1 -1
  578. package/dist/components/Lightbox/Lightbox.js +1 -1
  579. package/dist/components/Lightbox/Lightbox.js.map +1 -1
  580. package/dist/components/Lightbox/Lightbox.module.cjs.map +1 -1
  581. package/dist/components/Lightbox/Lightbox.module.js.map +1 -1
  582. package/dist/components/ListTile/ListTile.cjs.map +1 -1
  583. package/dist/components/ListTile/ListTile.js.map +1 -1
  584. package/dist/components/ListTile/ListTile.module.cjs.map +1 -1
  585. package/dist/components/ListTile/ListTile.module.js.map +1 -1
  586. package/dist/components/Markdown/Markdown.cjs.map +1 -1
  587. package/dist/components/Markdown/Markdown.js.map +1 -1
  588. package/dist/components/Markdown/Markdown.module.cjs.map +1 -1
  589. package/dist/components/Markdown/Markdown.module.js.map +1 -1
  590. package/dist/components/Markdown/markdown-parse.cjs +6 -6
  591. package/dist/components/Markdown/markdown-parse.cjs.map +1 -1
  592. package/dist/components/Markdown/markdown-parse.js +94 -96
  593. package/dist/components/Markdown/markdown-parse.js.map +1 -1
  594. package/dist/components/Masonry/Masonry.cjs.map +1 -1
  595. package/dist/components/Masonry/Masonry.js.map +1 -1
  596. package/dist/components/Masonry/Masonry.module.cjs.map +1 -1
  597. package/dist/components/Masonry/Masonry.module.js.map +1 -1
  598. package/dist/components/Masonry/masonry-layout.cjs.map +1 -1
  599. package/dist/components/Masonry/masonry-layout.js.map +1 -1
  600. package/dist/components/Menubar/Menubar.cjs.map +1 -1
  601. package/dist/components/Menubar/Menubar.js.map +1 -1
  602. package/dist/components/Menubar/Menubar.module.cjs.map +1 -1
  603. package/dist/components/Menubar/Menubar.module.js.map +1 -1
  604. package/dist/components/Modal/Modal.cjs.map +1 -1
  605. package/dist/components/Modal/Modal.js.map +1 -1
  606. package/dist/components/Modal/Modal.module.cjs.map +1 -1
  607. package/dist/components/Modal/Modal.module.js.map +1 -1
  608. package/dist/components/ModalsManager/ModalsManager.cjs.map +1 -1
  609. package/dist/components/ModalsManager/ModalsManager.js.map +1 -1
  610. package/dist/components/ModalsManager/ModalsManager.module.cjs.map +1 -1
  611. package/dist/components/ModalsManager/ModalsManager.module.js.map +1 -1
  612. package/dist/components/Money/Money.cjs.map +1 -1
  613. package/dist/components/Money/Money.js.map +1 -1
  614. package/dist/components/MultiSelect/MultiSelect.cjs.map +1 -1
  615. package/dist/components/MultiSelect/MultiSelect.js.map +1 -1
  616. package/dist/components/MultiSelect/MultiSelect.module.cjs.map +1 -1
  617. package/dist/components/MultiSelect/MultiSelect.module.js.map +1 -1
  618. package/dist/components/NProgress/NProgress.cjs.map +1 -1
  619. package/dist/components/NProgress/NProgress.js.map +1 -1
  620. package/dist/components/NProgress/NProgress.module.cjs.map +1 -1
  621. package/dist/components/NProgress/NProgress.module.js.map +1 -1
  622. package/dist/components/Navbar/Navbar.cjs.map +1 -1
  623. package/dist/components/Navbar/Navbar.js.map +1 -1
  624. package/dist/components/Navbar/Navbar.module.cjs.map +1 -1
  625. package/dist/components/Navbar/Navbar.module.js.map +1 -1
  626. package/dist/components/NavigationMenu/NavigationMenu.cjs.map +1 -1
  627. package/dist/components/NavigationMenu/NavigationMenu.js.map +1 -1
  628. package/dist/components/NavigationMenu/NavigationMenu.module.cjs.map +1 -1
  629. package/dist/components/NavigationMenu/NavigationMenu.module.js.map +1 -1
  630. package/dist/components/NavigationRail/NavigationRail.cjs.map +1 -1
  631. package/dist/components/NavigationRail/NavigationRail.js.map +1 -1
  632. package/dist/components/NavigationRail/NavigationRail.module.cjs.map +1 -1
  633. package/dist/components/NavigationRail/NavigationRail.module.js.map +1 -1
  634. package/dist/components/NotificationCenter/NotificationCenter.cjs.map +1 -1
  635. package/dist/components/NotificationCenter/NotificationCenter.js.map +1 -1
  636. package/dist/components/NotificationCenter/NotificationCenter.module.cjs.map +1 -1
  637. package/dist/components/NotificationCenter/NotificationCenter.module.js.map +1 -1
  638. package/dist/components/NotificationCenter/use-notification-inbox.cjs.map +1 -1
  639. package/dist/components/NotificationCenter/use-notification-inbox.js.map +1 -1
  640. package/dist/components/OfflineIndicator/OfflineIndicator.cjs.map +1 -1
  641. package/dist/components/OfflineIndicator/OfflineIndicator.js.map +1 -1
  642. package/dist/components/OfflineIndicator/OfflineIndicator.module.cjs.map +1 -1
  643. package/dist/components/OfflineIndicator/OfflineIndicator.module.js.map +1 -1
  644. package/dist/components/Page/Page.cjs.map +1 -1
  645. package/dist/components/Page/Page.js.map +1 -1
  646. package/dist/components/Page/Page.module.cjs.map +1 -1
  647. package/dist/components/Page/Page.module.js.map +1 -1
  648. package/dist/components/Pagination/Pagination.cjs.map +1 -1
  649. package/dist/components/Pagination/Pagination.js.map +1 -1
  650. package/dist/components/Pagination/Pagination.module.cjs.map +1 -1
  651. package/dist/components/Pagination/Pagination.module.js.map +1 -1
  652. package/dist/components/PasswordInput/PasswordInput.cjs.map +1 -1
  653. package/dist/components/PasswordInput/PasswordInput.js.map +1 -1
  654. package/dist/components/PasswordInput/PasswordInput.module.cjs.map +1 -1
  655. package/dist/components/PasswordInput/PasswordInput.module.js.map +1 -1
  656. package/dist/components/PinInput/PinInput.cjs.map +1 -1
  657. package/dist/components/PinInput/PinInput.js.map +1 -1
  658. package/dist/components/PinInput/PinInput.module.cjs.map +1 -1
  659. package/dist/components/PinInput/PinInput.module.js.map +1 -1
  660. package/dist/components/Popover/Popover.cjs.map +1 -1
  661. package/dist/components/Popover/Popover.js.map +1 -1
  662. package/dist/components/Popover/Popover.module.cjs.map +1 -1
  663. package/dist/components/Popover/Popover.module.js.map +1 -1
  664. package/dist/components/Portal/Portal.cjs.map +1 -1
  665. package/dist/components/Portal/Portal.js.map +1 -1
  666. package/dist/components/Portal/anchor-position.cjs.map +1 -1
  667. package/dist/components/Portal/anchor-position.js.map +1 -1
  668. package/dist/components/Portal/escape-layer.cjs.map +1 -1
  669. package/dist/components/Portal/escape-layer.js.map +1 -1
  670. package/dist/components/Portal/portal-host.cjs.map +1 -1
  671. package/dist/components/Portal/portal-host.js.map +1 -1
  672. package/dist/components/Portal/tab-bridge.cjs +1 -1
  673. package/dist/components/Portal/tab-bridge.cjs.map +1 -1
  674. package/dist/components/Portal/tab-bridge.js +1 -5
  675. package/dist/components/Portal/tab-bridge.js.map +1 -1
  676. package/dist/components/Progress/Progress.cjs.map +1 -1
  677. package/dist/components/Progress/Progress.js.map +1 -1
  678. package/dist/components/Progress/Progress.module.cjs.map +1 -1
  679. package/dist/components/Progress/Progress.module.js.map +1 -1
  680. package/dist/components/QRCode/QRCode.cjs.map +1 -1
  681. package/dist/components/QRCode/QRCode.js.map +1 -1
  682. package/dist/components/QRCode/QRCode.module.cjs.map +1 -1
  683. package/dist/components/QRCode/QRCode.module.js.map +1 -1
  684. package/dist/components/QRCode/qr-encode.cjs +1 -1
  685. package/dist/components/QRCode/qr-encode.cjs.map +1 -1
  686. package/dist/components/QRCode/qr-encode.js +7 -13
  687. package/dist/components/QRCode/qr-encode.js.map +1 -1
  688. package/dist/components/QRCode/qr-tables.cjs.map +1 -1
  689. package/dist/components/QRCode/qr-tables.js.map +1 -1
  690. package/dist/components/Radio/Radio.cjs.map +1 -1
  691. package/dist/components/Radio/Radio.js.map +1 -1
  692. package/dist/components/Radio/Radio.module.cjs.map +1 -1
  693. package/dist/components/Radio/Radio.module.js.map +1 -1
  694. package/dist/components/RangeSlider/RangeSlider.cjs.map +1 -1
  695. package/dist/components/RangeSlider/RangeSlider.js.map +1 -1
  696. package/dist/components/RangeSlider/RangeSlider.module.cjs.map +1 -1
  697. package/dist/components/RangeSlider/RangeSlider.module.js.map +1 -1
  698. package/dist/components/RatingStars/RatingStars.cjs.map +1 -1
  699. package/dist/components/RatingStars/RatingStars.js.map +1 -1
  700. package/dist/components/RatingStars/RatingStars.module.cjs.map +1 -1
  701. package/dist/components/RatingStars/RatingStars.module.js.map +1 -1
  702. package/dist/components/RefreshIndicator/RefreshIndicator.cjs +1 -1
  703. package/dist/components/RefreshIndicator/RefreshIndicator.cjs.map +1 -1
  704. package/dist/components/RefreshIndicator/RefreshIndicator.js +10 -18
  705. package/dist/components/RefreshIndicator/RefreshIndicator.js.map +1 -1
  706. package/dist/components/RefreshIndicator/RefreshIndicator.module.cjs.map +1 -1
  707. package/dist/components/RefreshIndicator/RefreshIndicator.module.js.map +1 -1
  708. package/dist/components/RelativeTime/RelativeTime.cjs.map +1 -1
  709. package/dist/components/RelativeTime/RelativeTime.js.map +1 -1
  710. package/dist/components/Resizable/Resizable.cjs +1 -1
  711. package/dist/components/Resizable/Resizable.cjs.map +1 -1
  712. package/dist/components/Resizable/Resizable.js +1 -9
  713. package/dist/components/Resizable/Resizable.js.map +1 -1
  714. package/dist/components/Resizable/Resizable.module.cjs.map +1 -1
  715. package/dist/components/Resizable/Resizable.module.js.map +1 -1
  716. package/dist/components/Responsive/Responsive.cjs.map +1 -1
  717. package/dist/components/Responsive/Responsive.js.map +1 -1
  718. package/dist/components/Reveal/Reveal.cjs.map +1 -1
  719. package/dist/components/Reveal/Reveal.js.map +1 -1
  720. package/dist/components/Reveal/Reveal.module.cjs.map +1 -1
  721. package/dist/components/Reveal/Reveal.module.js.map +1 -1
  722. package/dist/components/Reveal/reveal-threshold.cjs.map +1 -1
  723. package/dist/components/Reveal/reveal-threshold.js.map +1 -1
  724. package/dist/components/SafeArea/SafeArea.cjs.map +1 -1
  725. package/dist/components/SafeArea/SafeArea.js.map +1 -1
  726. package/dist/components/SafeArea/SafeArea.module.cjs.map +1 -1
  727. package/dist/components/SafeArea/SafeArea.module.js.map +1 -1
  728. package/dist/components/Scheduler/Scheduler.cjs.map +1 -1
  729. package/dist/components/Scheduler/Scheduler.js.map +1 -1
  730. package/dist/components/Scheduler/Scheduler.module.cjs.map +1 -1
  731. package/dist/components/Scheduler/Scheduler.module.js.map +1 -1
  732. package/dist/components/Scheduler/scheduler-layout.cjs.map +1 -1
  733. package/dist/components/Scheduler/scheduler-layout.js.map +1 -1
  734. package/dist/components/ScrollArea/ScrollArea.cjs.map +1 -1
  735. package/dist/components/ScrollArea/ScrollArea.js.map +1 -1
  736. package/dist/components/ScrollArea/ScrollArea.module.cjs.map +1 -1
  737. package/dist/components/ScrollArea/ScrollArea.module.js.map +1 -1
  738. package/dist/components/SearchBar/SearchBar.cjs.map +1 -1
  739. package/dist/components/SearchBar/SearchBar.js.map +1 -1
  740. package/dist/components/SearchBar/SearchBar.module.cjs.map +1 -1
  741. package/dist/components/SearchBar/SearchBar.module.js.map +1 -1
  742. package/dist/components/SectionHeader/SectionHeader.cjs.map +1 -1
  743. package/dist/components/SectionHeader/SectionHeader.js.map +1 -1
  744. package/dist/components/SectionHeader/SectionHeader.module.cjs.map +1 -1
  745. package/dist/components/SectionHeader/SectionHeader.module.js.map +1 -1
  746. package/dist/components/SegmentedControl/SegmentedControl.cjs.map +1 -1
  747. package/dist/components/SegmentedControl/SegmentedControl.js.map +1 -1
  748. package/dist/components/SegmentedControl/SegmentedControl.module.cjs.map +1 -1
  749. package/dist/components/SegmentedControl/SegmentedControl.module.js.map +1 -1
  750. package/dist/components/Select/CaretIcon.cjs.map +1 -1
  751. package/dist/components/Select/CaretIcon.js.map +1 -1
  752. package/dist/components/Select/Select.cjs.map +1 -1
  753. package/dist/components/Select/Select.js.map +1 -1
  754. package/dist/components/Select/Select.module.cjs.map +1 -1
  755. package/dist/components/Select/Select.module.js.map +1 -1
  756. package/dist/components/Select/options.cjs.map +1 -1
  757. package/dist/components/Select/options.js.map +1 -1
  758. package/dist/components/Sidebar/Sidebar.cjs +1 -1
  759. package/dist/components/Sidebar/Sidebar.cjs.map +1 -1
  760. package/dist/components/Sidebar/Sidebar.js +13 -23
  761. package/dist/components/Sidebar/Sidebar.js.map +1 -1
  762. package/dist/components/Sidebar/Sidebar.module.cjs.map +1 -1
  763. package/dist/components/Sidebar/Sidebar.module.js.map +1 -1
  764. package/dist/components/Sidebar/SidebarEntry.cjs.map +1 -1
  765. package/dist/components/Sidebar/SidebarEntry.js.map +1 -1
  766. package/dist/components/Sidebar/active-nav-key.cjs.map +1 -1
  767. package/dist/components/Sidebar/active-nav-key.js.map +1 -1
  768. package/dist/components/SignaturePad/SignaturePad.cjs +1 -1
  769. package/dist/components/SignaturePad/SignaturePad.cjs.map +1 -1
  770. package/dist/components/SignaturePad/SignaturePad.js +1 -5
  771. package/dist/components/SignaturePad/SignaturePad.js.map +1 -1
  772. package/dist/components/SignaturePad/SignaturePad.module.cjs.map +1 -1
  773. package/dist/components/SignaturePad/SignaturePad.module.js.map +1 -1
  774. package/dist/components/Skeleton/Skeleton.cjs.map +1 -1
  775. package/dist/components/Skeleton/Skeleton.js.map +1 -1
  776. package/dist/components/Skeleton/Skeleton.module.cjs.map +1 -1
  777. package/dist/components/Skeleton/Skeleton.module.js.map +1 -1
  778. package/dist/components/Slider/Slider.cjs.map +1 -1
  779. package/dist/components/Slider/Slider.js.map +1 -1
  780. package/dist/components/Slider/Slider.module.cjs.map +1 -1
  781. package/dist/components/Slider/Slider.module.js.map +1 -1
  782. package/dist/components/Spacer/Spacer.cjs.map +1 -1
  783. package/dist/components/Spacer/Spacer.js.map +1 -1
  784. package/dist/components/Spacer/Spacer.module.cjs.map +1 -1
  785. package/dist/components/Spacer/Spacer.module.js.map +1 -1
  786. package/dist/components/Sparkline/Sparkline.cjs.map +1 -1
  787. package/dist/components/Sparkline/Sparkline.js.map +1 -1
  788. package/dist/components/Sparkline/Sparkline.module.cjs.map +1 -1
  789. package/dist/components/Sparkline/Sparkline.module.js.map +1 -1
  790. package/dist/components/Sparkline/sparkline-geometry.cjs.map +1 -1
  791. package/dist/components/Sparkline/sparkline-geometry.js.map +1 -1
  792. package/dist/components/Spinner/Spinner.cjs.map +1 -1
  793. package/dist/components/Spinner/Spinner.js.map +1 -1
  794. package/dist/components/Spinner/Spinner.module.cjs.map +1 -1
  795. package/dist/components/Spinner/Spinner.module.js.map +1 -1
  796. package/dist/components/Stat/Stat.cjs.map +1 -1
  797. package/dist/components/Stat/Stat.js.map +1 -1
  798. package/dist/components/Stat/Stat.module.cjs.map +1 -1
  799. package/dist/components/Stat/Stat.module.js.map +1 -1
  800. package/dist/components/Stepper/Stepper.cjs.map +1 -1
  801. package/dist/components/Stepper/Stepper.js.map +1 -1
  802. package/dist/components/Stepper/Stepper.module.cjs.map +1 -1
  803. package/dist/components/Stepper/Stepper.module.js.map +1 -1
  804. package/dist/components/StepperInput/StepperInput.cjs.map +1 -1
  805. package/dist/components/StepperInput/StepperInput.js.map +1 -1
  806. package/dist/components/StepperInput/StepperInput.module.cjs.map +1 -1
  807. package/dist/components/StepperInput/StepperInput.module.js.map +1 -1
  808. package/dist/components/Switch/Switch.cjs.map +1 -1
  809. package/dist/components/Switch/Switch.js.map +1 -1
  810. package/dist/components/Switch/Switch.module.cjs.map +1 -1
  811. package/dist/components/Switch/Switch.module.js.map +1 -1
  812. package/dist/components/SyncStatusBadge/SyncStatusBadge.cjs.map +1 -1
  813. package/dist/components/SyncStatusBadge/SyncStatusBadge.js.map +1 -1
  814. package/dist/components/SyncStatusBadge/SyncStatusBadge.module.cjs.map +1 -1
  815. package/dist/components/SyncStatusBadge/SyncStatusBadge.module.js.map +1 -1
  816. package/dist/components/Table/Table.cjs.map +1 -1
  817. package/dist/components/Table/Table.js.map +1 -1
  818. package/dist/components/Table/Table.module.cjs.map +1 -1
  819. package/dist/components/Table/Table.module.js.map +1 -1
  820. package/dist/components/Tabs/Tabs.cjs.map +1 -1
  821. package/dist/components/Tabs/Tabs.js.map +1 -1
  822. package/dist/components/Tabs/Tabs.module.cjs.map +1 -1
  823. package/dist/components/Tabs/Tabs.module.js.map +1 -1
  824. package/dist/components/Tag/Tag.cjs.map +1 -1
  825. package/dist/components/Tag/Tag.js.map +1 -1
  826. package/dist/components/Tag/Tag.module.cjs.map +1 -1
  827. package/dist/components/Tag/Tag.module.js.map +1 -1
  828. package/dist/components/Textarea/Textarea.cjs.map +1 -1
  829. package/dist/components/Textarea/Textarea.js.map +1 -1
  830. package/dist/components/Textarea/Textarea.module.cjs.map +1 -1
  831. package/dist/components/Textarea/Textarea.module.js.map +1 -1
  832. package/dist/components/TimePicker/TimePicker.cjs.map +1 -1
  833. package/dist/components/TimePicker/TimePicker.js.map +1 -1
  834. package/dist/components/TimePicker/TimePicker.module.cjs.map +1 -1
  835. package/dist/components/TimePicker/TimePicker.module.js.map +1 -1
  836. package/dist/components/Timeline/Timeline.cjs.map +1 -1
  837. package/dist/components/Timeline/Timeline.js.map +1 -1
  838. package/dist/components/Timeline/Timeline.module.cjs.map +1 -1
  839. package/dist/components/Timeline/Timeline.module.js.map +1 -1
  840. package/dist/components/Toast/Toast.module.cjs.map +1 -1
  841. package/dist/components/Toast/Toast.module.js.map +1 -1
  842. package/dist/components/Toast/ToastProvider.cjs.map +1 -1
  843. package/dist/components/Toast/ToastProvider.js.map +1 -1
  844. package/dist/components/Toggle/Toggle.cjs.map +1 -1
  845. package/dist/components/Toggle/Toggle.js.map +1 -1
  846. package/dist/components/Toggle/Toggle.module.cjs.map +1 -1
  847. package/dist/components/Toggle/Toggle.module.js.map +1 -1
  848. package/dist/components/ToggleGroup/ToggleGroup.cjs.map +1 -1
  849. package/dist/components/ToggleGroup/ToggleGroup.js.map +1 -1
  850. package/dist/components/ToggleGroup/ToggleGroup.module.cjs.map +1 -1
  851. package/dist/components/ToggleGroup/ToggleGroup.module.js.map +1 -1
  852. package/dist/components/Tooltip/Tooltip.cjs.map +1 -1
  853. package/dist/components/Tooltip/Tooltip.js.map +1 -1
  854. package/dist/components/Tooltip/Tooltip.module.cjs.map +1 -1
  855. package/dist/components/Tooltip/Tooltip.module.js.map +1 -1
  856. package/dist/components/Tour/Tour.cjs +1 -1
  857. package/dist/components/Tour/Tour.cjs.map +1 -1
  858. package/dist/components/Tour/Tour.js +1 -5
  859. package/dist/components/Tour/Tour.js.map +1 -1
  860. package/dist/components/Tour/Tour.module.cjs.map +1 -1
  861. package/dist/components/Tour/Tour.module.js.map +1 -1
  862. package/dist/components/Tour/tour-position.cjs.map +1 -1
  863. package/dist/components/Tour/tour-position.js.map +1 -1
  864. package/dist/components/Transfer/Transfer.cjs.map +1 -1
  865. package/dist/components/Transfer/Transfer.js.map +1 -1
  866. package/dist/components/Transfer/Transfer.module.cjs.map +1 -1
  867. package/dist/components/Transfer/Transfer.module.js.map +1 -1
  868. package/dist/components/Transfer/transfer-state.cjs.map +1 -1
  869. package/dist/components/Transfer/transfer-state.js.map +1 -1
  870. package/dist/components/TreeView/TreeView.cjs.map +1 -1
  871. package/dist/components/TreeView/TreeView.js.map +1 -1
  872. package/dist/components/TreeView/TreeView.module.cjs.map +1 -1
  873. package/dist/components/TreeView/TreeView.module.js.map +1 -1
  874. package/dist/components/TruncateText/TruncateText.cjs.map +1 -1
  875. package/dist/components/TruncateText/TruncateText.js.map +1 -1
  876. package/dist/components/TruncateText/TruncateText.module.cjs.map +1 -1
  877. package/dist/components/TruncateText/TruncateText.module.js.map +1 -1
  878. package/dist/components/UpdatePrompt/UpdatePrompt.cjs.map +1 -1
  879. package/dist/components/UpdatePrompt/UpdatePrompt.js.map +1 -1
  880. package/dist/components/UpdatePrompt/UpdatePrompt.module.cjs.map +1 -1
  881. package/dist/components/UpdatePrompt/UpdatePrompt.module.js.map +1 -1
  882. package/dist/components/VideoPlayer/VideoPlayer.cjs +1 -1
  883. package/dist/components/VideoPlayer/VideoPlayer.cjs.map +1 -1
  884. package/dist/components/VideoPlayer/VideoPlayer.js +1 -7
  885. package/dist/components/VideoPlayer/VideoPlayer.js.map +1 -1
  886. package/dist/components/VideoPlayer/VideoPlayer.module.cjs.map +1 -1
  887. package/dist/components/VideoPlayer/VideoPlayer.module.js.map +1 -1
  888. package/dist/components/VideoPlayer/playback-rates.cjs.map +1 -1
  889. package/dist/components/VideoPlayer/playback-rates.js.map +1 -1
  890. package/dist/components/VirtualList/VirtualList.cjs.map +1 -1
  891. package/dist/components/VirtualList/VirtualList.js.map +1 -1
  892. package/dist/components/VirtualList/VirtualList.module.cjs.map +1 -1
  893. package/dist/components/VirtualList/VirtualList.module.js.map +1 -1
  894. package/dist/components/VirtualTable/VirtualTable.cjs.map +1 -1
  895. package/dist/components/VirtualTable/VirtualTable.js.map +1 -1
  896. package/dist/components/VirtualTable/VirtualTable.module.cjs.map +1 -1
  897. package/dist/components/VirtualTable/VirtualTable.module.js.map +1 -1
  898. package/dist/components/VisuallyHidden/VisuallyHidden.cjs.map +1 -1
  899. package/dist/components/VisuallyHidden/VisuallyHidden.js.map +1 -1
  900. package/dist/components/VisuallyHidden/VisuallyHidden.module.cjs.map +1 -1
  901. package/dist/components/VisuallyHidden/VisuallyHidden.module.js.map +1 -1
  902. package/dist/components/Wizard/Wizard.cjs +1 -1
  903. package/dist/components/Wizard/Wizard.cjs.map +1 -1
  904. package/dist/components/Wizard/Wizard.js +4 -11
  905. package/dist/components/Wizard/Wizard.js.map +1 -1
  906. package/dist/components/Wizard/Wizard.module.cjs.map +1 -1
  907. package/dist/components/Wizard/Wizard.module.js.map +1 -1
  908. package/dist/data/create-data-provider.cjs.map +1 -1
  909. package/dist/data/create-data-provider.js.map +1 -1
  910. package/dist/data/data-provider-context.cjs.map +1 -1
  911. package/dist/data/data-provider-context.js.map +1 -1
  912. package/dist/data/use-resource.cjs.map +1 -1
  913. package/dist/data/use-resource.js.map +1 -1
  914. package/dist/editor/RichTextEditor.cjs.map +1 -1
  915. package/dist/editor/RichTextEditor.js.map +1 -1
  916. package/dist/editor/RichTextEditor.module.cjs.map +1 -1
  917. package/dist/editor/RichTextEditor.module.js.map +1 -1
  918. package/dist/editor.js +1 -2
  919. package/dist/error-boundary/ErrorBoundary.cjs.map +1 -1
  920. package/dist/error-boundary/ErrorBoundary.js.map +1 -1
  921. package/dist/error-boundary/use-error-handler.cjs.map +1 -1
  922. package/dist/error-boundary/use-error-handler.js.map +1 -1
  923. package/dist/feature-flags/FeatureFlagsProvider.cjs.map +1 -1
  924. package/dist/feature-flags/FeatureFlagsProvider.js.map +1 -1
  925. package/dist/feature-flags/growthbook-adapter.cjs.map +1 -1
  926. package/dist/feature-flags/growthbook-adapter.js.map +1 -1
  927. package/dist/feature-flags/in-memory-adapter.cjs.map +1 -1
  928. package/dist/feature-flags/in-memory-adapter.js.map +1 -1
  929. package/dist/feature-flags/launchdarkly-adapter.cjs.map +1 -1
  930. package/dist/feature-flags/launchdarkly-adapter.js.map +1 -1
  931. package/dist/forms/FormField.cjs.map +1 -1
  932. package/dist/forms/FormField.js.map +1 -1
  933. package/dist/forms/br-validators.cjs.map +1 -1
  934. package/dist/forms/br-validators.js.map +1 -1
  935. package/dist/forms/masked-inputs.cjs.map +1 -1
  936. package/dist/forms/masked-inputs.js.map +1 -1
  937. package/dist/forms/use-viacep.cjs.map +1 -1
  938. package/dist/forms/use-viacep.js.map +1 -1
  939. package/dist/forms/use-zod-form.cjs.map +1 -1
  940. package/dist/forms/use-zod-form.js.map +1 -1
  941. package/dist/forms/validate-form.cjs.map +1 -1
  942. package/dist/forms/validate-form.js.map +1 -1
  943. package/dist/forms/zod-resolver.cjs.map +1 -1
  944. package/dist/forms/zod-resolver.js.map +1 -1
  945. package/dist/geo/TrajectoryMap.cjs.map +1 -1
  946. package/dist/geo/TrajectoryMap.js.map +1 -1
  947. package/dist/geo/TrajectoryMap.module.cjs.map +1 -1
  948. package/dist/geo/TrajectoryMap.module.js.map +1 -1
  949. package/dist/geo/bounds.cjs.map +1 -1
  950. package/dist/geo/bounds.js.map +1 -1
  951. package/dist/geo/create-position-tracker.cjs +1 -1
  952. package/dist/geo/create-position-tracker.cjs.map +1 -1
  953. package/dist/geo/create-position-tracker.js +1 -7
  954. package/dist/geo/create-position-tracker.js.map +1 -1
  955. package/dist/geo/distance.cjs.map +1 -1
  956. package/dist/geo/distance.js.map +1 -1
  957. package/dist/geo/estimate.cjs.map +1 -1
  958. package/dist/geo/estimate.js.map +1 -1
  959. package/dist/geo/leaflet-map.cjs.map +1 -1
  960. package/dist/geo/leaflet-map.js.map +1 -1
  961. package/dist/geo/projection.cjs.map +1 -1
  962. package/dist/geo/projection.js.map +1 -1
  963. package/dist/geo/routing.cjs.map +1 -1
  964. package/dist/geo/routing.js.map +1 -1
  965. package/dist/geo/types.cjs.map +1 -1
  966. package/dist/geo/types.js.map +1 -1
  967. package/dist/geo/use-position-tracker.cjs.map +1 -1
  968. package/dist/geo/use-position-tracker.js.map +1 -1
  969. package/dist/hooks/pwa-env.cjs.map +1 -1
  970. package/dist/hooks/pwa-env.js.map +1 -1
  971. package/dist/hooks/tab-sequence.cjs.map +1 -1
  972. package/dist/hooks/tab-sequence.js.map +1 -1
  973. package/dist/hooks/use-announce.cjs +1 -1
  974. package/dist/hooks/use-announce.cjs.map +1 -1
  975. package/dist/hooks/use-announce.js +2 -2
  976. package/dist/hooks/use-announce.js.map +1 -1
  977. package/dist/hooks/use-async.cjs.map +1 -1
  978. package/dist/hooks/use-async.js.map +1 -1
  979. package/dist/hooks/use-before-install-prompt.cjs.map +1 -1
  980. package/dist/hooks/use-before-install-prompt.js.map +1 -1
  981. package/dist/hooks/use-breakpoint.cjs.map +1 -1
  982. package/dist/hooks/use-breakpoint.js.map +1 -1
  983. package/dist/hooks/use-click-outside.cjs.map +1 -1
  984. package/dist/hooks/use-click-outside.js.map +1 -1
  985. package/dist/hooks/use-client-filter.cjs.map +1 -1
  986. package/dist/hooks/use-client-filter.js.map +1 -1
  987. package/dist/hooks/use-clipboard.cjs.map +1 -1
  988. package/dist/hooks/use-clipboard.js.map +1 -1
  989. package/dist/hooks/use-countdown.cjs.map +1 -1
  990. package/dist/hooks/use-countdown.js.map +1 -1
  991. package/dist/hooks/use-counter.cjs.map +1 -1
  992. package/dist/hooks/use-counter.js.map +1 -1
  993. package/dist/hooks/use-debounce.cjs.map +1 -1
  994. package/dist/hooks/use-debounce.js.map +1 -1
  995. package/dist/hooks/use-deep-memo.cjs.map +1 -1
  996. package/dist/hooks/use-deep-memo.js.map +1 -1
  997. package/dist/hooks/use-disclosure.cjs.map +1 -1
  998. package/dist/hooks/use-disclosure.js.map +1 -1
  999. package/dist/hooks/use-document-title.cjs.map +1 -1
  1000. package/dist/hooks/use-document-title.js.map +1 -1
  1001. package/dist/hooks/use-document-visibility.cjs.map +1 -1
  1002. package/dist/hooks/use-document-visibility.js.map +1 -1
  1003. package/dist/hooks/use-draft-filters.cjs.map +1 -1
  1004. package/dist/hooks/use-draft-filters.js.map +1 -1
  1005. package/dist/hooks/use-event-listener.cjs.map +1 -1
  1006. package/dist/hooks/use-event-listener.js.map +1 -1
  1007. package/dist/hooks/use-favicon.cjs.map +1 -1
  1008. package/dist/hooks/use-favicon.js.map +1 -1
  1009. package/dist/hooks/use-focus-trap.cjs.map +1 -1
  1010. package/dist/hooks/use-focus-trap.js.map +1 -1
  1011. package/dist/hooks/use-fullscreen-element.cjs.map +1 -1
  1012. package/dist/hooks/use-fullscreen-element.js.map +1 -1
  1013. package/dist/hooks/use-fullscreen.cjs +1 -1
  1014. package/dist/hooks/use-fullscreen.cjs.map +1 -1
  1015. package/dist/hooks/use-fullscreen.js +7 -23
  1016. package/dist/hooks/use-fullscreen.js.map +1 -1
  1017. package/dist/hooks/use-geolocation.cjs.map +1 -1
  1018. package/dist/hooks/use-geolocation.js.map +1 -1
  1019. package/dist/hooks/use-hover.cjs.map +1 -1
  1020. package/dist/hooks/use-hover.js.map +1 -1
  1021. package/dist/hooks/use-idle.cjs.map +1 -1
  1022. package/dist/hooks/use-idle.js.map +1 -1
  1023. package/dist/hooks/use-install-prompt.cjs +1 -1
  1024. package/dist/hooks/use-install-prompt.cjs.map +1 -1
  1025. package/dist/hooks/use-install-prompt.js +1 -1
  1026. package/dist/hooks/use-install-prompt.js.map +1 -1
  1027. package/dist/hooks/use-intersection-observer.cjs.map +1 -1
  1028. package/dist/hooks/use-intersection-observer.js.map +1 -1
  1029. package/dist/hooks/use-interval.cjs.map +1 -1
  1030. package/dist/hooks/use-interval.js.map +1 -1
  1031. package/dist/hooks/use-is-first-render.cjs.map +1 -1
  1032. package/dist/hooks/use-is-first-render.js.map +1 -1
  1033. package/dist/hooks/use-keyboard-shortcut.cjs.map +1 -1
  1034. package/dist/hooks/use-keyboard-shortcut.js.map +1 -1
  1035. package/dist/hooks/use-latest-ref.cjs.map +1 -1
  1036. package/dist/hooks/use-latest-ref.js.map +1 -1
  1037. package/dist/hooks/use-list-state.cjs.map +1 -1
  1038. package/dist/hooks/use-list-state.js.map +1 -1
  1039. package/dist/hooks/use-local-storage.cjs +1 -1
  1040. package/dist/hooks/use-local-storage.cjs.map +1 -1
  1041. package/dist/hooks/use-local-storage.js +2 -5
  1042. package/dist/hooks/use-local-storage.js.map +1 -1
  1043. package/dist/hooks/use-long-press-handlers.cjs.map +1 -1
  1044. package/dist/hooks/use-long-press-handlers.js.map +1 -1
  1045. package/dist/hooks/use-long-press.cjs.map +1 -1
  1046. package/dist/hooks/use-long-press.js.map +1 -1
  1047. package/dist/hooks/use-map.cjs.map +1 -1
  1048. package/dist/hooks/use-map.js.map +1 -1
  1049. package/dist/hooks/use-media-devices.cjs.map +1 -1
  1050. package/dist/hooks/use-media-devices.js.map +1 -1
  1051. package/dist/hooks/use-media-permission.cjs +1 -1
  1052. package/dist/hooks/use-media-permission.cjs.map +1 -1
  1053. package/dist/hooks/use-media-permission.js +2 -5
  1054. package/dist/hooks/use-media-permission.js.map +1 -1
  1055. package/dist/hooks/use-media-query.cjs.map +1 -1
  1056. package/dist/hooks/use-media-query.js.map +1 -1
  1057. package/dist/hooks/use-object-url.cjs.map +1 -1
  1058. package/dist/hooks/use-object-url.js.map +1 -1
  1059. package/dist/hooks/use-online.cjs.map +1 -1
  1060. package/dist/hooks/use-online.js.map +1 -1
  1061. package/dist/hooks/use-pagination.cjs.map +1 -1
  1062. package/dist/hooks/use-pagination.js.map +1 -1
  1063. package/dist/hooks/use-previous.cjs.map +1 -1
  1064. package/dist/hooks/use-previous.js.map +1 -1
  1065. package/dist/hooks/use-push-to-talk.cjs.map +1 -1
  1066. package/dist/hooks/use-push-to-talk.js.map +1 -1
  1067. package/dist/hooks/use-queue.cjs.map +1 -1
  1068. package/dist/hooks/use-queue.js.map +1 -1
  1069. package/dist/hooks/use-resize-observer.cjs.map +1 -1
  1070. package/dist/hooks/use-resize-observer.js.map +1 -1
  1071. package/dist/hooks/use-scroll-lock.cjs.map +1 -1
  1072. package/dist/hooks/use-scroll-lock.js.map +1 -1
  1073. package/dist/hooks/use-scroll-overflow.cjs.map +1 -1
  1074. package/dist/hooks/use-scroll-overflow.js.map +1 -1
  1075. package/dist/hooks/use-service-worker-update.cjs.map +1 -1
  1076. package/dist/hooks/use-service-worker-update.js.map +1 -1
  1077. package/dist/hooks/use-set.cjs.map +1 -1
  1078. package/dist/hooks/use-set.js.map +1 -1
  1079. package/dist/hooks/use-sortable.cjs.map +1 -1
  1080. package/dist/hooks/use-sortable.js.map +1 -1
  1081. package/dist/hooks/use-stable-callback.cjs.map +1 -1
  1082. package/dist/hooks/use-stable-callback.js.map +1 -1
  1083. package/dist/hooks/use-storage-estimate.cjs.map +1 -1
  1084. package/dist/hooks/use-storage-estimate.js.map +1 -1
  1085. package/dist/hooks/use-throttle.cjs.map +1 -1
  1086. package/dist/hooks/use-throttle.js.map +1 -1
  1087. package/dist/hooks/use-timeout.cjs.map +1 -1
  1088. package/dist/hooks/use-timeout.js.map +1 -1
  1089. package/dist/hooks/use-toggle.cjs.map +1 -1
  1090. package/dist/hooks/use-toggle.js.map +1 -1
  1091. package/dist/hooks/use-typewriter.cjs.map +1 -1
  1092. package/dist/hooks/use-typewriter.js.map +1 -1
  1093. package/dist/hooks/use-window-size.cjs.map +1 -1
  1094. package/dist/hooks/use-window-size.js.map +1 -1
  1095. package/dist/http/api-client.cjs.map +1 -1
  1096. package/dist/http/api-client.js.map +1 -1
  1097. package/dist/http/build-url.cjs.map +1 -1
  1098. package/dist/http/build-url.js.map +1 -1
  1099. package/dist/http/credential-scope.cjs.map +1 -1
  1100. package/dist/http/credential-scope.js.map +1 -1
  1101. package/dist/http/csrf.cjs.map +1 -1
  1102. package/dist/http/csrf.js.map +1 -1
  1103. package/dist/http/decode-response.cjs.map +1 -1
  1104. package/dist/http/decode-response.js.map +1 -1
  1105. package/dist/http/describe-api-error.cjs.map +1 -1
  1106. package/dist/http/describe-api-error.js.map +1 -1
  1107. package/dist/http/errors.cjs.map +1 -1
  1108. package/dist/http/errors.js.map +1 -1
  1109. package/dist/http/idempotency.cjs.map +1 -1
  1110. package/dist/http/idempotency.js.map +1 -1
  1111. package/dist/http/parse-response.cjs.map +1 -1
  1112. package/dist/http/parse-response.js.map +1 -1
  1113. package/dist/http/resumable-upload.cjs +1 -1
  1114. package/dist/http/resumable-upload.cjs.map +1 -1
  1115. package/dist/http/resumable-upload.js +141 -105
  1116. package/dist/http/resumable-upload.js.map +1 -1
  1117. package/dist/http/retry.cjs +1 -1
  1118. package/dist/http/retry.cjs.map +1 -1
  1119. package/dist/http/retry.js +5 -6
  1120. package/dist/http/retry.js.map +1 -1
  1121. package/dist/http/timeout.cjs.map +1 -1
  1122. package/dist/http/timeout.js.map +1 -1
  1123. package/dist/http/upload-with-progress.cjs +1 -1
  1124. package/dist/http/upload-with-progress.cjs.map +1 -1
  1125. package/dist/http/upload-with-progress.js +2 -7
  1126. package/dist/http/upload-with-progress.js.map +1 -1
  1127. package/dist/http/use-describe-api-error.cjs.map +1 -1
  1128. package/dist/http/use-describe-api-error.js.map +1 -1
  1129. package/dist/http/use-poll.cjs +1 -1
  1130. package/dist/http/use-poll.cjs.map +1 -1
  1131. package/dist/http/use-poll.js +2 -5
  1132. package/dist/http/use-poll.js.map +1 -1
  1133. package/dist/i18n/I18nProvider.cjs.map +1 -1
  1134. package/dist/i18n/I18nProvider.js.map +1 -1
  1135. package/dist/i18n/create-i18n.cjs.map +1 -1
  1136. package/dist/i18n/create-i18n.js.map +1 -1
  1137. package/dist/icons/Icon.cjs.map +1 -1
  1138. package/dist/icons/Icon.js.map +1 -1
  1139. package/dist/icons/IconPicker.cjs.map +1 -1
  1140. package/dist/icons/IconPicker.js.map +1 -1
  1141. package/dist/icons/IconPicker.module.cjs.map +1 -1
  1142. package/dist/icons/IconPicker.module.js.map +1 -1
  1143. package/dist/icons/IconProvider.cjs.map +1 -1
  1144. package/dist/icons/IconProvider.js.map +1 -1
  1145. package/dist/icons/alias.cjs.map +1 -1
  1146. package/dist/icons/alias.js.map +1 -1
  1147. package/dist/icons/generated/aliases.cjs.map +1 -1
  1148. package/dist/icons/generated/aliases.js.map +1 -1
  1149. package/dist/icons/generated/icon-names.cjs.map +1 -1
  1150. package/dist/icons/generated/icon-names.js.map +1 -1
  1151. package/dist/icons/generated/loaders.cjs.map +1 -1
  1152. package/dist/icons/generated/loaders.js.map +1 -1
  1153. package/dist/icons/generated/shard-00.cjs.map +1 -1
  1154. package/dist/icons/generated/shard-00.js.map +1 -1
  1155. package/dist/icons/generated/shard-01.cjs.map +1 -1
  1156. package/dist/icons/generated/shard-01.js.map +1 -1
  1157. package/dist/icons/generated/shard-02.cjs.map +1 -1
  1158. package/dist/icons/generated/shard-02.js.map +1 -1
  1159. package/dist/icons/generated/shard-03.cjs.map +1 -1
  1160. package/dist/icons/generated/shard-03.js.map +1 -1
  1161. package/dist/icons/generated/shard-04.cjs.map +1 -1
  1162. package/dist/icons/generated/shard-04.js.map +1 -1
  1163. package/dist/icons/generated/shard-05.cjs.map +1 -1
  1164. package/dist/icons/generated/shard-05.js.map +1 -1
  1165. package/dist/icons/generated/shard-06.cjs.map +1 -1
  1166. package/dist/icons/generated/shard-06.js.map +1 -1
  1167. package/dist/icons/generated/shard-07.cjs.map +1 -1
  1168. package/dist/icons/generated/shard-07.js.map +1 -1
  1169. package/dist/icons/generated/shard-08.cjs.map +1 -1
  1170. package/dist/icons/generated/shard-08.js.map +1 -1
  1171. package/dist/icons/generated/shard-09.cjs.map +1 -1
  1172. package/dist/icons/generated/shard-09.js.map +1 -1
  1173. package/dist/icons/generated/shard-10.cjs.map +1 -1
  1174. package/dist/icons/generated/shard-10.js.map +1 -1
  1175. package/dist/icons/generated/shard-11.cjs.map +1 -1
  1176. package/dist/icons/generated/shard-11.js.map +1 -1
  1177. package/dist/icons/generated/shard-12.cjs.map +1 -1
  1178. package/dist/icons/generated/shard-12.js.map +1 -1
  1179. package/dist/icons/generated/shard-13.cjs.map +1 -1
  1180. package/dist/icons/generated/shard-13.js.map +1 -1
  1181. package/dist/icons/generated/shard-14.cjs.map +1 -1
  1182. package/dist/icons/generated/shard-14.js.map +1 -1
  1183. package/dist/icons/generated/shard-15.cjs.map +1 -1
  1184. package/dist/icons/generated/shard-15.js.map +1 -1
  1185. package/dist/icons/generated/shard-16.cjs.map +1 -1
  1186. package/dist/icons/generated/shard-16.js.map +1 -1
  1187. package/dist/icons/generated/shard-17.cjs.map +1 -1
  1188. package/dist/icons/generated/shard-17.js.map +1 -1
  1189. package/dist/icons/generated/shard-18.cjs.map +1 -1
  1190. package/dist/icons/generated/shard-18.js.map +1 -1
  1191. package/dist/icons/generated/shard-19.cjs.map +1 -1
  1192. package/dist/icons/generated/shard-19.js.map +1 -1
  1193. package/dist/icons/generated/shard-20.cjs.map +1 -1
  1194. package/dist/icons/generated/shard-20.js.map +1 -1
  1195. package/dist/icons/generated/shard-21.cjs.map +1 -1
  1196. package/dist/icons/generated/shard-21.js.map +1 -1
  1197. package/dist/icons/generated/shard-22.cjs.map +1 -1
  1198. package/dist/icons/generated/shard-22.js.map +1 -1
  1199. package/dist/icons/generated/shard-23.cjs.map +1 -1
  1200. package/dist/icons/generated/shard-23.js.map +1 -1
  1201. package/dist/icons/generated/shard-24.cjs.map +1 -1
  1202. package/dist/icons/generated/shard-24.js.map +1 -1
  1203. package/dist/icons/generated/shard-25.cjs.map +1 -1
  1204. package/dist/icons/generated/shard-25.js.map +1 -1
  1205. package/dist/icons/generated/shard-26.cjs.map +1 -1
  1206. package/dist/icons/generated/shard-26.js.map +1 -1
  1207. package/dist/icons/generated/shard-27.cjs.map +1 -1
  1208. package/dist/icons/generated/shard-27.js.map +1 -1
  1209. package/dist/icons/generated/shard-28.cjs.map +1 -1
  1210. package/dist/icons/generated/shard-28.js.map +1 -1
  1211. package/dist/icons/generated/shard-29.cjs.map +1 -1
  1212. package/dist/icons/generated/shard-29.js.map +1 -1
  1213. package/dist/icons/generated/shard-30.cjs.map +1 -1
  1214. package/dist/icons/generated/shard-30.js.map +1 -1
  1215. package/dist/icons/generated/shard-31.cjs.map +1 -1
  1216. package/dist/icons/generated/shard-31.js.map +1 -1
  1217. package/dist/icons/generated/shard-32.cjs.map +1 -1
  1218. package/dist/icons/generated/shard-32.js.map +1 -1
  1219. package/dist/icons/generated/shard-33.cjs.map +1 -1
  1220. package/dist/icons/generated/shard-33.js.map +1 -1
  1221. package/dist/icons/generated/shard-34.cjs.map +1 -1
  1222. package/dist/icons/generated/shard-34.js.map +1 -1
  1223. package/dist/icons/generated/shard-35.cjs.map +1 -1
  1224. package/dist/icons/generated/shard-35.js.map +1 -1
  1225. package/dist/icons/generated/shard-36.cjs.map +1 -1
  1226. package/dist/icons/generated/shard-36.js.map +1 -1
  1227. package/dist/icons/generated/shard-37.cjs.map +1 -1
  1228. package/dist/icons/generated/shard-37.js.map +1 -1
  1229. package/dist/icons/generated/shard-38.cjs.map +1 -1
  1230. package/dist/icons/generated/shard-38.js.map +1 -1
  1231. package/dist/icons/generated/shard-39.cjs.map +1 -1
  1232. package/dist/icons/generated/shard-39.js.map +1 -1
  1233. package/dist/icons/generated/shard-40.cjs.map +1 -1
  1234. package/dist/icons/generated/shard-40.js.map +1 -1
  1235. package/dist/icons/generated/shard-41.cjs.map +1 -1
  1236. package/dist/icons/generated/shard-41.js.map +1 -1
  1237. package/dist/icons/generated/shard-42.cjs.map +1 -1
  1238. package/dist/icons/generated/shard-42.js.map +1 -1
  1239. package/dist/icons/generated/shard-43.cjs.map +1 -1
  1240. package/dist/icons/generated/shard-43.js.map +1 -1
  1241. package/dist/icons/generated/shard-44.cjs.map +1 -1
  1242. package/dist/icons/generated/shard-44.js.map +1 -1
  1243. package/dist/icons/generated/shard-45.cjs.map +1 -1
  1244. package/dist/icons/generated/shard-45.js.map +1 -1
  1245. package/dist/icons/icon-context.cjs.map +1 -1
  1246. package/dist/icons/icon-context.js.map +1 -1
  1247. package/dist/icons/is-icon-name.cjs.map +1 -1
  1248. package/dist/icons/is-icon-name.js.map +1 -1
  1249. package/dist/icons/material-symbols.cjs.map +1 -1
  1250. package/dist/icons/material-symbols.js.map +1 -1
  1251. package/dist/icons/normalize-icon-name.cjs.map +1 -1
  1252. package/dist/icons/normalize-icon-name.js.map +1 -1
  1253. package/dist/icons/shard-cache.cjs +1 -1
  1254. package/dist/icons/shard-cache.cjs.map +1 -1
  1255. package/dist/icons/shard-cache.js +2 -5
  1256. package/dist/icons/shard-cache.js.map +1 -1
  1257. package/dist/icons/use-icon.cjs.map +1 -1
  1258. package/dist/icons/use-icon.js.map +1 -1
  1259. package/dist/icons/validate-icon-name.cjs.map +1 -1
  1260. package/dist/icons/validate-icon-name.js.map +1 -1
  1261. package/dist/icons-virtual.cjs.map +1 -1
  1262. package/dist/icons-virtual.js.map +1 -1
  1263. package/dist/imaging/canvas.cjs.map +1 -1
  1264. package/dist/imaging/canvas.js.map +1 -1
  1265. package/dist/imaging/compress.cjs.map +1 -1
  1266. package/dist/imaging/compress.js.map +1 -1
  1267. package/dist/imaging/decode.cjs.map +1 -1
  1268. package/dist/imaging/decode.js.map +1 -1
  1269. package/dist/imaging/encode.cjs.map +1 -1
  1270. package/dist/imaging/encode.js.map +1 -1
  1271. package/dist/imaging/exceptions.cjs.map +1 -1
  1272. package/dist/imaging/exceptions.js.map +1 -1
  1273. package/dist/imaging/frame.cjs.map +1 -1
  1274. package/dist/imaging/frame.js.map +1 -1
  1275. package/dist/imaging/thumbnails.cjs.map +1 -1
  1276. package/dist/imaging/thumbnails.js.map +1 -1
  1277. package/dist/imaging/transform.cjs.map +1 -1
  1278. package/dist/imaging/transform.js.map +1 -1
  1279. package/dist/imaging/use-image-processing.cjs.map +1 -1
  1280. package/dist/imaging/use-image-processing.js.map +1 -1
  1281. package/dist/logger/logger.cjs.map +1 -1
  1282. package/dist/logger/logger.js.map +1 -1
  1283. package/dist/neural.cjs.map +1 -1
  1284. package/dist/neural.js.map +1 -1
  1285. package/dist/oauth/GoogleSignIn.cjs +1 -1
  1286. package/dist/oauth/GoogleSignIn.cjs.map +1 -1
  1287. package/dist/oauth/GoogleSignIn.js +6 -9
  1288. package/dist/oauth/GoogleSignIn.js.map +1 -1
  1289. package/dist/oauth/callback.cjs.map +1 -1
  1290. package/dist/oauth/callback.js.map +1 -1
  1291. package/dist/oauth/use-oauth-callback.cjs.map +1 -1
  1292. package/dist/oauth/use-oauth-callback.js.map +1 -1
  1293. package/dist/offline/conflict.cjs.map +1 -1
  1294. package/dist/offline/conflict.js.map +1 -1
  1295. package/dist/offline/create-offline-database.cjs.map +1 -1
  1296. package/dist/offline/create-offline-database.js.map +1 -1
  1297. package/dist/offline/create-offline-store.cjs +1 -1
  1298. package/dist/offline/create-offline-store.cjs.map +1 -1
  1299. package/dist/offline/create-offline-store.js +1 -5
  1300. package/dist/offline/create-offline-store.js.map +1 -1
  1301. package/dist/offline/create-offline-sync.cjs +1 -1
  1302. package/dist/offline/create-offline-sync.cjs.map +1 -1
  1303. package/dist/offline/create-offline-sync.js +9 -14
  1304. package/dist/offline/create-offline-sync.js.map +1 -1
  1305. package/dist/offline/use-offline-sync.cjs.map +1 -1
  1306. package/dist/offline/use-offline-sync.js.map +1 -1
  1307. package/dist/perf/cache-size.cjs.map +1 -1
  1308. package/dist/perf/cache-size.js.map +1 -1
  1309. package/dist/perf/device.cjs.map +1 -1
  1310. package/dist/perf/device.js.map +1 -1
  1311. package/dist/perf/format.cjs.map +1 -1
  1312. package/dist/perf/format.js.map +1 -1
  1313. package/dist/perf/profiler.cjs.map +1 -1
  1314. package/dist/perf/profiler.js.map +1 -1
  1315. package/dist/push/use-push-subscription.cjs.map +1 -1
  1316. package/dist/push/use-push-subscription.js.map +1 -1
  1317. package/dist/push/utils.cjs.map +1 -1
  1318. package/dist/push/utils.js.map +1 -1
  1319. package/dist/push/web-push-client.cjs.map +1 -1
  1320. package/dist/push/web-push-client.js.map +1 -1
  1321. package/dist/query/QueryProvider.cjs.map +1 -1
  1322. package/dist/query/QueryProvider.js.map +1 -1
  1323. package/dist/query/constants.cjs.map +1 -1
  1324. package/dist/query/constants.js.map +1 -1
  1325. package/dist/query/create-query-keys.cjs.map +1 -1
  1326. package/dist/query/create-query-keys.js.map +1 -1
  1327. package/dist/query/foreign-client-warning.cjs.map +1 -1
  1328. package/dist/query/foreign-client-warning.js.map +1 -1
  1329. package/dist/query/offline-persistence.cjs +1 -1
  1330. package/dist/query/offline-persistence.cjs.map +1 -1
  1331. package/dist/query/offline-persistence.js +2 -10
  1332. package/dist/query/offline-persistence.js.map +1 -1
  1333. package/dist/query/optimistic.cjs.map +1 -1
  1334. package/dist/query/optimistic.js.map +1 -1
  1335. package/dist/query/pagination.cjs.map +1 -1
  1336. package/dist/query/pagination.js.map +1 -1
  1337. package/dist/query/retry-policy.cjs.map +1 -1
  1338. package/dist/query/retry-policy.js.map +1 -1
  1339. package/dist/query/use-cursor-query.cjs.map +1 -1
  1340. package/dist/query/use-cursor-query.js.map +1 -1
  1341. package/dist/query/use-offline-mutation.cjs.map +1 -1
  1342. package/dist/query/use-offline-mutation.js.map +1 -1
  1343. package/dist/query/use-paginated-query.cjs.map +1 -1
  1344. package/dist/query/use-paginated-query.js.map +1 -1
  1345. package/dist/router/AppRouter.cjs.map +1 -1
  1346. package/dist/router/AppRouter.js.map +1 -1
  1347. package/dist/router/RouteGuard.cjs.map +1 -1
  1348. package/dist/router/RouteGuard.js.map +1 -1
  1349. package/dist/router/index.js +2 -2
  1350. package/dist/share/share-or-download.cjs.map +1 -1
  1351. package/dist/share/share-or-download.js.map +1 -1
  1352. package/dist/share/share.cjs.map +1 -1
  1353. package/dist/share/share.js.map +1 -1
  1354. package/dist/sse/create-event-stream.cjs.map +1 -1
  1355. package/dist/sse/create-event-stream.js.map +1 -1
  1356. package/dist/sse/use-event-stream.cjs.map +1 -1
  1357. package/dist/sse/use-event-stream.js.map +1 -1
  1358. package/dist/store/create-selectors.cjs.map +1 -1
  1359. package/dist/store/create-selectors.js.map +1 -1
  1360. package/dist/store/create-store.cjs.map +1 -1
  1361. package/dist/store/create-store.js.map +1 -1
  1362. package/dist/sw/background-sync.cjs +1 -1
  1363. package/dist/sw/background-sync.cjs.map +1 -1
  1364. package/dist/sw/background-sync.js +32 -31
  1365. package/dist/sw/background-sync.js.map +1 -1
  1366. package/dist/sw/cache-inspect.cjs.map +1 -1
  1367. package/dist/sw/cache-inspect.js.map +1 -1
  1368. package/dist/sw/cache.cjs +1 -1
  1369. package/dist/sw/cache.cjs.map +1 -1
  1370. package/dist/sw/cache.js +2 -6
  1371. package/dist/sw/cache.js.map +1 -1
  1372. package/dist/sw/create-push-handler.cjs.map +1 -1
  1373. package/dist/sw/create-push-handler.js.map +1 -1
  1374. package/dist/sw/credential-headers.cjs.map +1 -1
  1375. package/dist/sw/credential-headers.js.map +1 -1
  1376. package/dist/sw/periodic-sync.cjs.map +1 -1
  1377. package/dist/sw/periodic-sync.js.map +1 -1
  1378. package/dist/sw/register-service-worker.cjs.map +1 -1
  1379. package/dist/sw/register-service-worker.js.map +1 -1
  1380. package/dist/sw/session-data.cjs.map +1 -1
  1381. package/dist/sw/session-data.js.map +1 -1
  1382. package/dist/sw.d.ts +46 -8
  1383. package/dist/tabular/assets.cjs.map +1 -1
  1384. package/dist/tabular/assets.js.map +1 -1
  1385. package/dist/tabular/cache.cjs.map +1 -1
  1386. package/dist/tabular/cache.js.map +1 -1
  1387. package/dist/tabular/compact.cjs.map +1 -1
  1388. package/dist/tabular/compact.js.map +1 -1
  1389. package/dist/tabular/exceptions.cjs.map +1 -1
  1390. package/dist/tabular/exceptions.js.map +1 -1
  1391. package/dist/tabular/manifest.cjs.map +1 -1
  1392. package/dist/tabular/manifest.js.map +1 -1
  1393. package/dist/tabular/predictor.cjs.map +1 -1
  1394. package/dist/tabular/predictor.js.map +1 -1
  1395. package/dist/tabular/use-tabular-predictor.cjs.map +1 -1
  1396. package/dist/tabular/use-tabular-predictor.js.map +1 -1
  1397. package/dist/telemetry/TelemetryProvider.cjs.map +1 -1
  1398. package/dist/telemetry/TelemetryProvider.js.map +1 -1
  1399. package/dist/telemetry/app-error-adapter.cjs.map +1 -1
  1400. package/dist/telemetry/app-error-adapter.js.map +1 -1
  1401. package/dist/telemetry/app-error-queue.cjs.map +1 -1
  1402. package/dist/telemetry/app-error-queue.js.map +1 -1
  1403. package/dist/telemetry/app-error-reporter.cjs +1 -1
  1404. package/dist/telemetry/app-error-reporter.cjs.map +1 -1
  1405. package/dist/telemetry/app-error-reporter.js +1 -1
  1406. package/dist/telemetry/app-error-reporter.js.map +1 -1
  1407. package/dist/telemetry/app-error-schema.cjs.map +1 -1
  1408. package/dist/telemetry/app-error-schema.js.map +1 -1
  1409. package/dist/telemetry/app-error-transport.cjs.map +1 -1
  1410. package/dist/telemetry/app-error-transport.js.map +1 -1
  1411. package/dist/telemetry/console-adapter.cjs.map +1 -1
  1412. package/dist/telemetry/console-adapter.js.map +1 -1
  1413. package/dist/telemetry/describe-app-error.cjs.map +1 -1
  1414. package/dist/telemetry/describe-app-error.js.map +1 -1
  1415. package/dist/telemetry/posthog-adapter.cjs +1 -1
  1416. package/dist/telemetry/posthog-adapter.cjs.map +1 -1
  1417. package/dist/telemetry/posthog-adapter.js +1 -5
  1418. package/dist/telemetry/posthog-adapter.js.map +1 -1
  1419. package/dist/telemetry/sentry-adapter.cjs.map +1 -1
  1420. package/dist/telemetry/sentry-adapter.js.map +1 -1
  1421. package/dist/tempest-react-sdk.cjs +1 -1
  1422. package/dist/tempest-react-sdk.d.ts +448 -15
  1423. package/dist/tempest-react-sdk.js +119 -119
  1424. package/dist/testing/create-mock-handlers.cjs.map +1 -1
  1425. package/dist/testing/create-mock-handlers.js.map +1 -1
  1426. package/dist/testing.js +1 -2
  1427. package/dist/theme/ThemeProvider.cjs.map +1 -1
  1428. package/dist/theme/ThemeProvider.js.map +1 -1
  1429. package/dist/theme/apply-theme.cjs.map +1 -1
  1430. package/dist/theme/apply-theme.js.map +1 -1
  1431. package/dist/theme/color.cjs.map +1 -1
  1432. package/dist/theme/color.js.map +1 -1
  1433. package/dist/theme/create-theme.cjs.map +1 -1
  1434. package/dist/theme/create-theme.js.map +1 -1
  1435. package/dist/theme/data-viz-ramps.cjs.map +1 -1
  1436. package/dist/theme/data-viz-ramps.js.map +1 -1
  1437. package/dist/theme/initial-theme.cjs.map +1 -1
  1438. package/dist/theme/initial-theme.js.map +1 -1
  1439. package/dist/theme/inverse-render.cjs.map +1 -1
  1440. package/dist/theme/inverse-render.js.map +1 -1
  1441. package/dist/theme/inverse-restore.cjs.map +1 -1
  1442. package/dist/theme/inverse-restore.js.map +1 -1
  1443. package/dist/theme/inverse-surface.cjs.map +1 -1
  1444. package/dist/theme/inverse-surface.js.map +1 -1
  1445. package/dist/theme/status-tokens.cjs.map +1 -1
  1446. package/dist/theme/status-tokens.js.map +1 -1
  1447. package/dist/theme/theme-presets.cjs.map +1 -1
  1448. package/dist/theme/theme-presets.js.map +1 -1
  1449. package/dist/utils/absent.cjs.map +1 -1
  1450. package/dist/utils/absent.js.map +1 -1
  1451. package/dist/utils/arrays.cjs.map +1 -1
  1452. package/dist/utils/arrays.js.map +1 -1
  1453. package/dist/utils/base64.cjs.map +1 -1
  1454. package/dist/utils/base64.js.map +1 -1
  1455. package/dist/utils/cn.cjs.map +1 -1
  1456. package/dist/utils/cn.js.map +1 -1
  1457. package/dist/utils/compare-values.cjs.map +1 -1
  1458. package/dist/utils/compare-values.js.map +1 -1
  1459. package/dist/utils/compressed-storage.cjs.map +1 -1
  1460. package/dist/utils/compressed-storage.js.map +1 -1
  1461. package/dist/utils/csv.cjs +3 -3
  1462. package/dist/utils/csv.cjs.map +1 -1
  1463. package/dist/utils/csv.js +11 -10
  1464. package/dist/utils/csv.js.map +1 -1
  1465. package/dist/utils/dev-mode.cjs.map +1 -1
  1466. package/dist/utils/dev-mode.js.map +1 -1
  1467. package/dist/utils/duplicate-instance.cjs.map +1 -1
  1468. package/dist/utils/duplicate-instance.js.map +1 -1
  1469. package/dist/utils/format.cjs.map +1 -1
  1470. package/dist/utils/format.js.map +1 -1
  1471. package/dist/utils/functions.cjs +1 -1
  1472. package/dist/utils/functions.cjs.map +1 -1
  1473. package/dist/utils/functions.js +1 -1
  1474. package/dist/utils/functions.js.map +1 -1
  1475. package/dist/utils/guards.cjs.map +1 -1
  1476. package/dist/utils/guards.js.map +1 -1
  1477. package/dist/utils/ids.cjs.map +1 -1
  1478. package/dist/utils/ids.js.map +1 -1
  1479. package/dist/utils/intl-cache.cjs.map +1 -1
  1480. package/dist/utils/intl-cache.js.map +1 -1
  1481. package/dist/utils/json-frame.cjs.map +1 -1
  1482. package/dist/utils/json-frame.js.map +1 -1
  1483. package/dist/utils/numbers.cjs.map +1 -1
  1484. package/dist/utils/numbers.js.map +1 -1
  1485. package/dist/utils/objects.cjs.map +1 -1
  1486. package/dist/utils/objects.js.map +1 -1
  1487. package/dist/{telemetry/app-error-owner.cjs → utils/owner-fingerprint.cjs} +2 -2
  1488. package/dist/utils/owner-fingerprint.cjs.map +1 -0
  1489. package/dist/{telemetry/app-error-owner.js → utils/owner-fingerprint.js} +3 -3
  1490. package/dist/utils/owner-fingerprint.js.map +1 -0
  1491. package/dist/utils/promises.cjs.map +1 -1
  1492. package/dist/utils/promises.js.map +1 -1
  1493. package/dist/utils/relative-time.cjs.map +1 -1
  1494. package/dist/utils/relative-time.js.map +1 -1
  1495. package/dist/utils/safe-url.cjs.map +1 -1
  1496. package/dist/utils/safe-url.js.map +1 -1
  1497. package/dist/utils/schema-like.cjs.map +1 -1
  1498. package/dist/utils/schema-like.js.map +1 -1
  1499. package/dist/utils/storage.cjs +1 -1
  1500. package/dist/utils/storage.cjs.map +1 -1
  1501. package/dist/utils/storage.js +2 -2
  1502. package/dist/utils/storage.js.map +1 -1
  1503. package/dist/utils/strings.cjs.map +1 -1
  1504. package/dist/utils/strings.js.map +1 -1
  1505. package/dist/utils/xlsx.cjs.map +1 -1
  1506. package/dist/utils/xlsx.js.map +1 -1
  1507. package/dist/vision/core/canvas.cjs.map +1 -1
  1508. package/dist/vision/core/canvas.js.map +1 -1
  1509. package/dist/vision/core/dtypes.cjs.map +1 -1
  1510. package/dist/vision/core/dtypes.js.map +1 -1
  1511. package/dist/vision/core/exceptions.cjs.map +1 -1
  1512. package/dist/vision/core/exceptions.js.map +1 -1
  1513. package/dist/vision/core/graph.cjs.map +1 -1
  1514. package/dist/vision/core/graph.js.map +1 -1
  1515. package/dist/vision/core/metadata.cjs +1 -1
  1516. package/dist/vision/core/metadata.cjs.map +1 -1
  1517. package/dist/vision/core/metadata.js +9 -26
  1518. package/dist/vision/core/metadata.js.map +1 -1
  1519. package/dist/vision/core/providers.cjs.map +1 -1
  1520. package/dist/vision/core/providers.js.map +1 -1
  1521. package/dist/vision/core/session.cjs.map +1 -1
  1522. package/dist/vision/core/session.js.map +1 -1
  1523. package/dist/vision/core/timing.cjs.map +1 -1
  1524. package/dist/vision/core/timing.js.map +1 -1
  1525. package/dist/vision/fusion.cjs.map +1 -1
  1526. package/dist/vision/fusion.js.map +1 -1
  1527. package/dist/vision/index.cjs.map +1 -1
  1528. package/dist/vision/index.js.map +1 -1
  1529. package/dist/vision/io/image.cjs.map +1 -1
  1530. package/dist/vision/io/image.js.map +1 -1
  1531. package/dist/vision/labels.cjs.map +1 -1
  1532. package/dist/vision/labels.js.map +1 -1
  1533. package/dist/vision/luminance.cjs.map +1 -1
  1534. package/dist/vision/luminance.js.map +1 -1
  1535. package/dist/vision/normalization.cjs.map +1 -1
  1536. package/dist/vision/normalization.js.map +1 -1
  1537. package/dist/vision/postprocess/classification.cjs.map +1 -1
  1538. package/dist/vision/postprocess/classification.js.map +1 -1
  1539. package/dist/vision/postprocess/detection.cjs.map +1 -1
  1540. package/dist/vision/postprocess/detection.js.map +1 -1
  1541. package/dist/vision/postprocess/segmentation.cjs.map +1 -1
  1542. package/dist/vision/postprocess/segmentation.js.map +1 -1
  1543. package/dist/vision/preprocess/image.cjs.map +1 -1
  1544. package/dist/vision/preprocess/image.js.map +1 -1
  1545. package/dist/vision/preprocess/pipeline.cjs.map +1 -1
  1546. package/dist/vision/preprocess/pipeline.js.map +1 -1
  1547. package/dist/vision/results.cjs.map +1 -1
  1548. package/dist/vision/results.js.map +1 -1
  1549. package/dist/vision/tasks/base.cjs.map +1 -1
  1550. package/dist/vision/tasks/base.js.map +1 -1
  1551. package/dist/vision/tasks/classifier.cjs.map +1 -1
  1552. package/dist/vision/tasks/classifier.js.map +1 -1
  1553. package/dist/vision/tasks/detectClassify.cjs.map +1 -1
  1554. package/dist/vision/tasks/detectClassify.js.map +1 -1
  1555. package/dist/vision/tasks/detector.cjs.map +1 -1
  1556. package/dist/vision/tasks/detector.js.map +1 -1
  1557. package/dist/vision/tasks/segmenter.cjs.map +1 -1
  1558. package/dist/vision/tasks/segmenter.js.map +1 -1
  1559. package/dist/vision/types.cjs.map +1 -1
  1560. package/dist/vision/types.js.map +1 -1
  1561. package/dist/vision/use-camera-stream.cjs +1 -1
  1562. package/dist/vision/use-camera-stream.cjs.map +1 -1
  1563. package/dist/vision/use-camera-stream.js +3 -9
  1564. package/dist/vision/use-camera-stream.js.map +1 -1
  1565. package/dist/vision/use-live-luminance.cjs +1 -1
  1566. package/dist/vision/use-live-luminance.cjs.map +1 -1
  1567. package/dist/vision/use-live-luminance.js +1 -5
  1568. package/dist/vision/use-live-luminance.js.map +1 -1
  1569. package/dist/vite/base-url.cjs.map +1 -1
  1570. package/dist/vite/base-url.js.map +1 -1
  1571. package/dist/vite/create-vite-config.cjs.map +1 -1
  1572. package/dist/vite/create-vite-config.js.map +1 -1
  1573. package/dist/vite/narrow-tokens.cjs.map +1 -1
  1574. package/dist/vite/narrow-tokens.js.map +1 -1
  1575. package/dist/vite/tempest-csp.cjs +2 -2
  1576. package/dist/vite/tempest-csp.cjs.map +1 -1
  1577. package/dist/vite/tempest-csp.js +69 -66
  1578. package/dist/vite/tempest-csp.js.map +1 -1
  1579. package/dist/vite/tempest-icons.cjs.map +1 -1
  1580. package/dist/vite/tempest-icons.js.map +1 -1
  1581. package/dist/vite/tempest-pwa-dev-sw.cjs +1 -1
  1582. package/dist/vite/tempest-pwa-dev-sw.cjs.map +1 -1
  1583. package/dist/vite/tempest-pwa-dev-sw.js +9 -16
  1584. package/dist/vite/tempest-pwa-dev-sw.js.map +1 -1
  1585. package/dist/vite/tempest-pwa-icons.cjs.map +1 -1
  1586. package/dist/vite/tempest-pwa-icons.js.map +1 -1
  1587. package/dist/vite/tempest-pwa-manifest.cjs.map +1 -1
  1588. package/dist/vite/tempest-pwa-manifest.js.map +1 -1
  1589. package/dist/vite/tempest-styles.cjs.map +1 -1
  1590. package/dist/vite/tempest-styles.js.map +1 -1
  1591. package/dist/vite/tempest-vitest.cjs.map +1 -1
  1592. package/dist/vite/tempest-vitest.js.map +1 -1
  1593. package/dist/vite.d.ts +5 -3
  1594. package/dist/webrtc/link-stats.cjs.map +1 -1
  1595. package/dist/webrtc/link-stats.js.map +1 -1
  1596. package/dist/webrtc/mesh-quality.cjs.map +1 -1
  1597. package/dist/webrtc/mesh-quality.js.map +1 -1
  1598. package/dist/webrtc/opus-sdp.cjs.map +1 -1
  1599. package/dist/webrtc/opus-sdp.js.map +1 -1
  1600. package/dist/webrtc/peer-link.cjs +1 -1
  1601. package/dist/webrtc/peer-link.cjs.map +1 -1
  1602. package/dist/webrtc/peer-link.js +2 -5
  1603. package/dist/webrtc/peer-link.js.map +1 -1
  1604. package/dist/webrtc/peer-mesh.cjs +1 -1
  1605. package/dist/webrtc/peer-mesh.cjs.map +1 -1
  1606. package/dist/webrtc/peer-mesh.js +8 -24
  1607. package/dist/webrtc/peer-mesh.js.map +1 -1
  1608. package/dist/webrtc/sender-bitrate.cjs.map +1 -1
  1609. package/dist/webrtc/sender-bitrate.js.map +1 -1
  1610. package/dist/webrtc/use-link-stats.cjs.map +1 -1
  1611. package/dist/webrtc/use-link-stats.js.map +1 -1
  1612. package/dist/ws/create-web-socket.cjs +1 -1
  1613. package/dist/ws/create-web-socket.cjs.map +1 -1
  1614. package/dist/ws/create-web-socket.js +4 -22
  1615. package/dist/ws/create-web-socket.js.map +1 -1
  1616. package/dist/ws/resilience.cjs.map +1 -1
  1617. package/dist/ws/resilience.js.map +1 -1
  1618. package/dist/ws/use-web-socket.cjs.map +1 -1
  1619. package/dist/ws/use-web-socket.js.map +1 -1
  1620. package/package.json +9 -6
  1621. package/template/package.json +1 -1
  1622. package/dist/telemetry/app-error-owner.cjs.map +0 -1
  1623. package/dist/telemetry/app-error-owner.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"whatsapp.js","names":[],"sources":["../../src/br/whatsapp.ts"],"sourcesContent":["/** Country calling code for Brazil, the digits `wa.me` needs in front of a national number. */\nconst BR_COUNTRY_CODE = \"55\";\n\nconst NATIONAL_LENGTHS = new Set([10, 11]);\nconst E164_MIN_WITH_COUNTRY_CODE = 12;\nconst E164_MAX = 15;\n\n/**\n * Normalise a phone number to the digits-only form `wa.me` accepts.\n *\n * A Brazilian number is stored almost everywhere **without** the country code —\n * ten digits for a landline, eleven for a mobile — and `wa.me` refuses anything\n * that is not fully qualified. Those two shapes get `55` in front; a number that\n * already carries a country code (12 to 15 digits, the E.164 range that no\n * Brazilian national number can reach) is returned untouched, so a foreign\n * client's number still works.\n *\n * Everything else returns an empty string rather than a best guess. Handing back\n * the digits as typed is what the naive version does, and it builds a `wa.me`\n * URL that opens WhatsApp on a number nobody owns — a typo becomes a dead chat\n * window instead of a disabled button.\n *\n * Trunk and carrier-selection prefixes (`0`, `021`, …) are **not** stripped: a\n * leading zero is ambiguous between the two, so a number carrying one reads as\n * invalid instead of being silently reinterpreted. Pass the plain number. The\n * leading zero is what rules it out even at a plausible length — no E.164\n * country code starts with `0`, so `011999998888` is a national number wearing a\n * trunk prefix, never an international one.\n *\n * @example\n * toWhatsAppNumber(\"(11) 99999-8888\"); // \"5511999998888\"\n * toWhatsAppNumber(\"+55 11 99999-8888\"); // \"5511999998888\"\n * toWhatsAppNumber(\"99999-8888\"); // \"\" — no area code, nothing to dial\n *\n * @param phone - Phone number in any shape: masked, spaced, `+`-prefixed.\n * @returns Digits ready for a `wa.me` link, or an empty string when the input\n * cannot be resolved to a dialable number.\n */\nexport function toWhatsAppNumber(phone: string): string {\n const digits = phone.replace(/\\D/g, \"\");\n if (NATIONAL_LENGTHS.has(digits.length)) return `${BR_COUNTRY_CODE}${digits}`;\n const withinE164 = digits.length >= E164_MIN_WITH_COUNTRY_CODE && digits.length <= E164_MAX;\n if (withinE164 && !digits.startsWith(\"0\")) return digits;\n return \"\";\n}\n\n/**\n * Build the `wa.me` deep link that opens a chat with an optional message\n * already typed.\n *\n * This is a **deep link, never a send**: the chat opens with the text ready and\n * the person presses send. That is the feature, not a limitation — it needs no\n * official Cloud API, no approved template and no business verification, and it\n * cannot let the UI claim a message was delivered when it was not.\n *\n * `api.whatsapp.com/send?phone=…` is deliberately not offered as an alternative\n * host: both resolve to the same chooser, and `wa.me` is the short form of it.\n *\n * @example\n * whatsAppUrl(\"(11) 99999-8888\", \"Seu horário é amanhã às 14h.\");\n * // \"https://wa.me/5511999998888?text=Seu%20hor%C3%A1rio%20%C3%A9%20amanh%C3%A3%20%C3%A0s%2014h.\"\n *\n * @param phone - Phone number in any shape; normalised by {@link toWhatsAppNumber}.\n * @param text - Message to pre-fill. Omitted or empty leaves the composer blank.\n * @returns The `https://wa.me/…` URL, or an empty string when the number cannot\n * be normalised.\n */\nexport function whatsAppUrl(phone: string, text?: string): string {\n const number = toWhatsAppNumber(phone);\n if (!number) return \"\";\n const url = `https://wa.me/${number}`;\n return text ? `${url}?text=${encodeURIComponent(text)}` : url;\n}\n\n/**\n * Open the WhatsApp chat in a new tab.\n *\n * @example\n * <Button onClick={() => openWhatsApp(client.phone, greeting)}>\n * Falar no WhatsApp\n * </Button>\n *\n * @param phone - Phone number in any shape; normalised by {@link toWhatsAppNumber}.\n * @param text - Message to pre-fill. Omitted or empty leaves the composer blank.\n * @returns `true` when a URL was built and the open was requested, `false` when\n * the number is unusable or there is no `window` (test runner, service worker,\n * build plugin). It reports the **request**, not the tab: opening with\n * `noopener` makes `window.open` return `null` even on success, so its result\n * cannot distinguish a blocked popup from an opened one.\n */\nexport function openWhatsApp(phone: string, text?: string): boolean {\n if (typeof window === \"undefined\") return false;\n const url = whatsAppUrl(phone, text);\n if (!url) return false;\n window.open(url, \"_blank\", \"noopener,noreferrer\");\n return true;\n}\n"],"mappings":";AACA,IAEM,oBAAmB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,GACnC,IAA6B,IAC7B,IAAW;AAiCjB,SAAgB,EAAiB,GAAuB;CACpD,IAAM,IAAS,EAAM,QAAQ,OAAO,EAAE;CAItC,OAHI,EAAiB,IAAI,EAAO,MAAM,IAAU,KAAqB,MAClD,EAAO,UAAU,KAA8B,EAAO,UAAU,KACjE,CAAC,EAAO,WAAW,GAAG,IAAU,IAC3C;AACX;AAuBA,SAAgB,EAAY,GAAe,GAAuB;CAC9D,IAAM,IAAS,EAAiB,CAAK;CACrC,IAAI,CAAC,GAAQ,OAAO;CACpB,IAAM,IAAM,iBAAiB;CAC7B,OAAO,IAAO,GAAG,EAAI,QAAQ,mBAAmB,CAAI,MAAM;AAC9D;AAkBA,SAAgB,EAAa,GAAe,GAAwB;CAChE,IAAI,OAAO,SAAW,KAAa,OAAO;CAC1C,IAAM,IAAM,EAAY,GAAO,CAAI;CAGnC,OAFK,KACL,OAAO,KAAK,GAAK,UAAU,qBAAqB,GACzC,MAFU;AAGrB"}
1
+ {"version":3,"file":"whatsapp.js","names":["NATIONAL_LENGTHS","E164_MIN_WITH_COUNTRY_CODE","E164_MAX","toWhatsAppNumber","digits","phone","whatsAppUrl","number","url","text","openWhatsApp"],"sources":["../../src/br/whatsapp.ts"],"sourcesContent":["/** Country calling code for Brazil, the digits `wa.me` needs in front of a national number. */\nconst BR_COUNTRY_CODE = \"55\";\n\nconst NATIONAL_LENGTHS = new Set([10, 11]);\nconst E164_MIN_WITH_COUNTRY_CODE = 12;\nconst E164_MAX = 15;\n\n/**\n * Normalise a phone number to the digits-only form `wa.me` accepts.\n *\n * A Brazilian number is stored almost everywhere **without** the country code —\n * ten digits for a landline, eleven for a mobile — and `wa.me` refuses anything\n * that is not fully qualified. Those two shapes get `55` in front; a number that\n * already carries a country code (12 to 15 digits, the E.164 range that no\n * Brazilian national number can reach) is returned untouched, so a foreign\n * client's number still works.\n *\n * Everything else returns an empty string rather than a best guess. Handing back\n * the digits as typed is what the naive version does, and it builds a `wa.me`\n * URL that opens WhatsApp on a number nobody owns — a typo becomes a dead chat\n * window instead of a disabled button.\n *\n * Trunk and carrier-selection prefixes (`0`, `021`, …) are **not** stripped: a\n * leading zero is ambiguous between the two, so a number carrying one reads as\n * invalid instead of being silently reinterpreted. Pass the plain number. The\n * leading zero is what rules it out even at a plausible length — no E.164\n * country code starts with `0`, so `011999998888` is a national number wearing a\n * trunk prefix, never an international one.\n *\n * @example\n * toWhatsAppNumber(\"(11) 99999-8888\"); // \"5511999998888\"\n * toWhatsAppNumber(\"+55 11 99999-8888\"); // \"5511999998888\"\n * toWhatsAppNumber(\"99999-8888\"); // \"\" — no area code, nothing to dial\n *\n * @param phone - Phone number in any shape: masked, spaced, `+`-prefixed.\n * @returns Digits ready for a `wa.me` link, or an empty string when the input\n * cannot be resolved to a dialable number.\n */\nexport function toWhatsAppNumber(phone: string): string {\n const digits = phone.replace(/\\D/g, \"\");\n if (NATIONAL_LENGTHS.has(digits.length)) return `${BR_COUNTRY_CODE}${digits}`;\n const withinE164 = digits.length >= E164_MIN_WITH_COUNTRY_CODE && digits.length <= E164_MAX;\n if (withinE164 && !digits.startsWith(\"0\")) return digits;\n return \"\";\n}\n\n/**\n * Build the `wa.me` deep link that opens a chat with an optional message\n * already typed.\n *\n * This is a **deep link, never a send**: the chat opens with the text ready and\n * the person presses send. That is the feature, not a limitation — it needs no\n * official Cloud API, no approved template and no business verification, and it\n * cannot let the UI claim a message was delivered when it was not.\n *\n * `api.whatsapp.com/send?phone=…` is deliberately not offered as an alternative\n * host: both resolve to the same chooser, and `wa.me` is the short form of it.\n *\n * @example\n * whatsAppUrl(\"(11) 99999-8888\", \"Seu horário é amanhã às 14h.\");\n * // \"https://wa.me/5511999998888?text=Seu%20hor%C3%A1rio%20%C3%A9%20amanh%C3%A3%20%C3%A0s%2014h.\"\n *\n * @param phone - Phone number in any shape; normalised by {@link toWhatsAppNumber}.\n * @param text - Message to pre-fill. Omitted or empty leaves the composer blank.\n * @returns The `https://wa.me/…` URL, or an empty string when the number cannot\n * be normalised.\n */\nexport function whatsAppUrl(phone: string, text?: string): string {\n const number = toWhatsAppNumber(phone);\n if (!number) return \"\";\n const url = `https://wa.me/${number}`;\n return text ? `${url}?text=${encodeURIComponent(text)}` : url;\n}\n\n/**\n * Open the WhatsApp chat in a new tab.\n *\n * @example\n * <Button onClick={() => openWhatsApp(client.phone, greeting)}>\n * Falar no WhatsApp\n * </Button>\n *\n * @param phone - Phone number in any shape; normalised by {@link toWhatsAppNumber}.\n * @param text - Message to pre-fill. Omitted or empty leaves the composer blank.\n * @returns `true` when a URL was built and the open was requested, `false` when\n * the number is unusable or there is no `window` (test runner, service worker,\n * build plugin). It reports the **request**, not the tab: opening with\n * `noopener` makes `window.open` return `null` even on success, so its result\n * cannot distinguish a blocked popup from an opened one.\n */\nexport function openWhatsApp(phone: string, text?: string): boolean {\n if (typeof window === \"undefined\") return false;\n const url = whatsAppUrl(phone, text);\n if (!url) return false;\n window.open(url, \"_blank\", \"noopener,noreferrer\");\n return true;\n}\n"],"mappings":";AACA,IAEMA,oBAAmB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,GACnCC,IAA6B,IAC7BC,IAAW;AAiCjB,SAAgBC,EAAiB,GAAuB;CACpD,IAAMC,IAASC,EAAM,QAAQ,OAAO,EAAE;CAItC,OAHIL,EAAiB,IAAII,EAAO,MAAM,IAAU,KAAqBA,MAClDA,EAAO,UAAUH,KAA8BG,EAAO,UAAUF,KACjE,CAACE,EAAO,WAAW,GAAG,IAAUA,IAC3C;AACX;AAuBA,SAAgBE,EAAY,GAAe,GAAuB;CAC9D,IAAMC,IAASJ,EAAiBE,CAAK;CACrC,IAAI,CAACE,GAAQ,OAAO;CACpB,IAAMC,IAAM,iBAAiBD;CAC7B,OAAOE,IAAO,GAAGD,EAAI,QAAQ,mBAAmBC,CAAI,MAAMD;AAC9D;AAkBA,SAAgBE,EAAa,GAAe,GAAwB;CAChE,IAAI,OAAO,SAAW,KAAa,OAAO;CAC1C,IAAMF,IAAMF,EAAYD,GAAOI,CAAI;CAGnC,OAFKD,KACL,OAAO,KAAKA,GAAK,UAAU,qBAAqB,GACzC,MAFU;AAGrB"}
package/dist/br.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"br.cjs","names":[],"sources":["../src/br/index.ts"],"sourcesContent":["// Brazilian locations data (states + cities) — mirrors the `utils/locations`\n// module of tempest-fastapi-sdk.\nexport {\n listStates,\n getState,\n citiesByUf,\n statesByRegion,\n isValidUf,\n normalizeUf,\n isValidCity,\n ufChoices,\n cityChoices,\n municipalitiesByUf,\n administrativeRegionsByUf,\n resolveMunicipality,\n datasetVintage,\n pendingGeometryIds,\n} from \"./locations\";\nexport type {\n UF,\n BrRegion,\n BrazilState,\n BrazilMunicipality,\n BrazilAdministrativeRegion,\n Choice,\n} from \"./locations\";\n\n// UF GeoJSON types (the geometry itself is lazy-loaded by BrazilMap).\nimport type { BrUfFeatureCollection } from \"./br-geo\";\nexport type { BrUfFeature, BrUfFeatureCollection, BrUfGeometry, Ring } from \"./br-geo\";\n\n/**\n * Lazily load the bundled simplified UF GeoJSON (~36 KB gzip). Kept out of the\n * synchronous barrel so a data-only import never pulls the geometry.\n */\nexport async function loadBrUfGeoJson(): Promise<BrUfFeatureCollection> {\n const mod = await import(\"./br-geo\");\n return mod.BR_UF_GEOJSON;\n}\n\n// Per-state municipality geometry (lazy, one chunk per UF).\nexport { loadStateMunicipalities } from \"./state-geo\";\nexport type { MunicipalityFeature, StateMunicipalities } from \"./state-geo\";\n\n// Offline geocoding (lazy centroid index).\nexport {\n nearestMunicipality,\n reverseGeocode,\n geocodeMunicipality,\n searchMunicipalities,\n municipalityCentroid,\n stateCentroid,\n} from \"./geocode\";\nexport type { MunicipalityCentroid, NearestMunicipality, ReverseGeocodeResult } from \"./geocode\";\n\n// Components\nexport { BrazilMap } from \"./BrazilMap\";\nexport type { BrazilMapProps, BrazilMapTooltipData } from \"./BrazilMap\";\nexport { BrazilStateMap } from \"./BrazilStateMap\";\nexport type {\n BrazilStateMapProps,\n BrazilStateMapTooltipData,\n Municipality,\n} from \"./BrazilStateMap\";\nexport { BrazilStateCitySelect } from \"./BrazilStateCitySelect\";\nexport type { BrazilStateCitySelectProps, BrazilStateCitySelection } from \"./BrazilStateCitySelect\";\nexport { MunicipalitySearch } from \"./MunicipalitySearch\";\nexport type { MunicipalitySearchProps } from \"./MunicipalitySearch\";\nexport type { GeoMarker } from \"@/geo/types\";\nexport type { MapMarkersProps } from \"./MapMarkers\";\nexport { MapLegend } from \"./MapLegend\";\nexport type { MapLegendProps, LegendItem } from \"./MapLegend\";\n\n// Pix — BR Code (EMV MPM) payload + the QR that carries it.\nexport {\n normalizePixKey,\n parsePixPayload,\n PixError,\n pixCrc16,\n pixKeyType,\n pixPayload,\n} from \"./pix\";\nexport type {\n NormalizedPixKey,\n ParsePixOptions,\n PixData,\n PixDynamicInput,\n PixField,\n PixInput,\n PixKeyType,\n PixStaticInput,\n} from \"./pix\";\nexport { PixQRCode } from \"./PixQRCode\";\nexport type { PixQRCodeLabels, PixQRCodeProps } from \"./PixQRCode\";\n\n// Boleto — 47/48-digit typed line, 44-digit barcode, FEBRABAN check digits.\nexport {\n boletoDueDate,\n BoletoError,\n boletoKind,\n codigoBarrasToLinhaDigitavel,\n fatorVencimento,\n formatLinhaDigitavel,\n linhaDigitavelToCodigoBarras,\n mod10Dac,\n mod11DacArrecadacao,\n mod11DacCobranca,\n parseCodigoBarras,\n parseLinhaDigitavel,\n validateBoleto,\n} from \"./boleto\";\nexport type {\n Boleto,\n BoletoArrecadacao,\n BoletoBanco,\n BoletoEpoch,\n BoletoKind,\n BoletoOptions,\n} from \"./boleto\";\n\n// NF-e / NFC-e / CT-e access key.\nexport {\n chaveNFeCheckDigit,\n ChaveNFeError,\n formatChaveNFe,\n parseChaveNFe,\n validateChaveNFe,\n} from \"./nfe\";\nexport type { ChaveNFe } from \"./nfe\";\n\n// WhatsApp deep link (chat opened with the message ready, never an API send).\nexport { openWhatsApp, toWhatsAppNumber, whatsAppUrl } from \"./whatsapp\";\n\n// National holidays + business-day arithmetic.\nexport {\n addBusinessDays,\n easterSunday,\n holidaysFor,\n isBusinessDay,\n isHoliday,\n nextBusinessDay,\n} from \"./holidays\";\nexport type { BusinessDayOptions, DateInput, Holiday, HolidayKind } from \"./holidays\";\n\n// Color scales + palettes for choropleths.\nexport {\n sequentialScale,\n quantizeScale,\n thresholdScale,\n SEQUENTIAL_BLUES,\n SEQUENTIAL_GREENS,\n SEQUENTIAL_VIRIDIS,\n DIVERGING_RDBU,\n} from \"./scales\";\nexport type { ColorScale } from \"./scales\";\nexport { REGION_COLORS, regionLegendItems } from \"./regions\";\n"],"mappings":"2kBAmCA,eAAsB,GAAkD,CAEpE,OAAO,MAAA,QAAA,QAAA,CAAA,CAAA,SAAA,QADW,iBAAA,CAAA,EAAA,CACP,aACf"}
1
+ {"version":3,"file":"br.cjs","names":["require_locations","require_state_geo","require_geocode","require_regions","require_BrazilMap","require_BrazilStateMap","require_BrazilStateCitySelect","require_MunicipalitySearch","require_scales","require_MapLegend","require_pix","require_PixQRCode","require_boleto","require_nfe","require_whatsapp","require_holidays","loadBrUfGeoJson"],"sources":["../src/br/index.ts"],"sourcesContent":["// Brazilian locations data (states + cities) — mirrors the `utils/locations`\n// module of tempest-fastapi-sdk.\nexport {\n listStates,\n getState,\n citiesByUf,\n statesByRegion,\n isValidUf,\n normalizeUf,\n isValidCity,\n ufChoices,\n cityChoices,\n municipalitiesByUf,\n administrativeRegionsByUf,\n resolveMunicipality,\n datasetVintage,\n pendingGeometryIds,\n} from \"./locations\";\nexport type {\n UF,\n BrRegion,\n BrazilState,\n BrazilMunicipality,\n BrazilAdministrativeRegion,\n Choice,\n} from \"./locations\";\n\n// UF GeoJSON types (the geometry itself is lazy-loaded by BrazilMap).\nimport type { BrUfFeatureCollection } from \"./br-geo\";\nexport type { BrUfFeature, BrUfFeatureCollection, BrUfGeometry, Ring } from \"./br-geo\";\n\n/**\n * Lazily load the bundled simplified UF GeoJSON (~36 KB gzip). Kept out of the\n * synchronous barrel so a data-only import never pulls the geometry.\n */\nexport async function loadBrUfGeoJson(): Promise<BrUfFeatureCollection> {\n const mod = await import(\"./br-geo\");\n return mod.BR_UF_GEOJSON;\n}\n\n// Per-state municipality geometry (lazy, one chunk per UF).\nexport { loadStateMunicipalities } from \"./state-geo\";\nexport type { MunicipalityFeature, StateMunicipalities } from \"./state-geo\";\n\n// Offline geocoding (lazy centroid index).\nexport {\n nearestMunicipality,\n reverseGeocode,\n geocodeMunicipality,\n searchMunicipalities,\n municipalityCentroid,\n stateCentroid,\n} from \"./geocode\";\nexport type { MunicipalityCentroid, NearestMunicipality, ReverseGeocodeResult } from \"./geocode\";\n\n// Components\nexport { BrazilMap } from \"./BrazilMap\";\nexport type { BrazilMapProps, BrazilMapTooltipData } from \"./BrazilMap\";\nexport { BrazilStateMap } from \"./BrazilStateMap\";\nexport type {\n BrazilStateMapProps,\n BrazilStateMapTooltipData,\n Municipality,\n} from \"./BrazilStateMap\";\nexport { BrazilStateCitySelect } from \"./BrazilStateCitySelect\";\nexport type { BrazilStateCitySelectProps, BrazilStateCitySelection } from \"./BrazilStateCitySelect\";\nexport { MunicipalitySearch } from \"./MunicipalitySearch\";\nexport type { MunicipalitySearchProps } from \"./MunicipalitySearch\";\nexport type { GeoMarker } from \"@/geo/types\";\nexport type { MapMarkersProps } from \"./MapMarkers\";\nexport { MapLegend } from \"./MapLegend\";\nexport type { MapLegendProps, LegendItem } from \"./MapLegend\";\n\n// Pix — BR Code (EMV MPM) payload + the QR that carries it.\nexport {\n normalizePixKey,\n parsePixPayload,\n PixError,\n pixCrc16,\n pixKeyType,\n pixPayload,\n} from \"./pix\";\nexport type {\n NormalizedPixKey,\n ParsePixOptions,\n PixData,\n PixDynamicInput,\n PixField,\n PixInput,\n PixKeyType,\n PixStaticInput,\n} from \"./pix\";\nexport { PixQRCode } from \"./PixQRCode\";\nexport type { PixQRCodeLabels, PixQRCodeProps } from \"./PixQRCode\";\n\n// Boleto — 47/48-digit typed line, 44-digit barcode, FEBRABAN check digits.\nexport {\n boletoDueDate,\n BoletoError,\n boletoKind,\n codigoBarrasToLinhaDigitavel,\n fatorVencimento,\n formatLinhaDigitavel,\n linhaDigitavelToCodigoBarras,\n mod10Dac,\n mod11DacArrecadacao,\n mod11DacCobranca,\n parseCodigoBarras,\n parseLinhaDigitavel,\n validateBoleto,\n} from \"./boleto\";\nexport type {\n Boleto,\n BoletoArrecadacao,\n BoletoBanco,\n BoletoEpoch,\n BoletoKind,\n BoletoOptions,\n} from \"./boleto\";\n\n// NF-e / NFC-e / CT-e access key.\nexport {\n chaveNFeCheckDigit,\n ChaveNFeError,\n formatChaveNFe,\n parseChaveNFe,\n validateChaveNFe,\n} from \"./nfe\";\nexport type { ChaveNFe } from \"./nfe\";\n\n// WhatsApp deep link (chat opened with the message ready, never an API send).\nexport { openWhatsApp, toWhatsAppNumber, whatsAppUrl } from \"./whatsapp\";\n\n// National holidays + business-day arithmetic.\nexport {\n addBusinessDays,\n easterSunday,\n holidaysFor,\n isBusinessDay,\n isHoliday,\n nextBusinessDay,\n} from \"./holidays\";\nexport type { BusinessDayOptions, DateInput, Holiday, HolidayKind } from \"./holidays\";\n\n// Color scales + palettes for choropleths.\nexport {\n sequentialScale,\n quantizeScale,\n thresholdScale,\n SEQUENTIAL_BLUES,\n SEQUENTIAL_GREENS,\n SEQUENTIAL_VIRIDIS,\n DIVERGING_RDBU,\n} from \"./scales\";\nexport type { ColorScale } from \"./scales\";\nexport { REGION_COLORS, regionLegendItems } from \"./regions\";\n"],"mappings":"A,2kBAmCA,eAAsBgB,GAAkD,CAEpE,OAAO,MAAA,QAAA,QAAA,CAAA,CAAA,SAAA,QADW,iBAAA,CAAA,EAAA,CACP,aACf,C"}
package/dist/br.d.ts CHANGED
@@ -1175,9 +1175,18 @@ export declare interface ParsePixOptions {
1175
1175
  * *not* tolerated is a broken frame — a length prefix that runs off the end, a
1176
1176
  * missing tag 63 — a checksum mismatch, which means the string was corrupted in
1177
1177
  * transit, or a payload with two readings: a tag repeated at the root or inside
1178
- * tags 26 and 62, a tag 26 with both a key and a URL, or a tag 54 outside the EMV
1179
- * amount format. A preview built from one reading while the wallet pays the
1180
- * other is the failure those rules exist for.
1178
+ * tags 26 and 62, a tag 63 anywhere but at the end, a tag 26 with both a key and
1179
+ * a URL, a tag 54 outside the EMV amount format, non-ASCII text in an `ans`
1180
+ * field (every root tag but 64 and 80–99, and so every subfield of tags 26 and
1181
+ * 62), or `String` text that a reader counting UTF-8 bytes or UTF-16 units
1182
+ * frames into other tags (#497). A preview built from one
1183
+ * reading while the wallet pays the other is the failure those rules exist for.
1184
+ *
1185
+ * Position is checked where EMV® QRCPS-MPM — the reference the BACEN manual
1186
+ * defers to — fixes it: tag 00 is the first object and tag 63 the last; every
1187
+ * other root tag may appear in any order. Before #475 an inner `6304` + CRC
1188
+ * followed by `5405…` and a second `6304` + CRC parsed as a priced payload,
1189
+ * while the same text cut at the first CRC was a valid payload with no amount.
1181
1190
  *
1182
1191
  * The CRC detects corruption, not authorship: whoever crafts a payload
1183
1192
  * recomputes it, so a valid CRC says nothing about who published the account.
@@ -1185,9 +1194,11 @@ export declare interface ParsePixOptions {
1185
1194
  * @param payload - The copia-e-cola string. Surrounding whitespace is ignored.
1186
1195
  * @param options - See {@link ParsePixOptions}.
1187
1196
  * @returns The decoded payload.
1188
- * @throws {PixError} On a malformed frame, a missing CRC tag, a repeated tag, a
1197
+ * @throws {PixError} On a malformed frame, a missing CRC tag, a tag 00 that is
1198
+ * not first or a tag 63 that is not last, a repeated tag, a
1189
1199
  * tag 26 that is not a Pix account or that carries both a key and a URL, an
1190
- * amount outside the EMV format, or — unless `requireCrc` is `false` — a CRC
1200
+ * amount outside the EMV format, non-ASCII text in an `ans` field, a payload
1201
+ * that another length unit reads differently, or — unless `requireCrc` is `false` — a CRC
1191
1202
  * mismatch.
1192
1203
  *
1193
1204
  * @example
package/dist/br.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"br.js","names":[],"sources":["../src/br/index.ts"],"sourcesContent":["// Brazilian locations data (states + cities) — mirrors the `utils/locations`\n// module of tempest-fastapi-sdk.\nexport {\n listStates,\n getState,\n citiesByUf,\n statesByRegion,\n isValidUf,\n normalizeUf,\n isValidCity,\n ufChoices,\n cityChoices,\n municipalitiesByUf,\n administrativeRegionsByUf,\n resolveMunicipality,\n datasetVintage,\n pendingGeometryIds,\n} from \"./locations\";\nexport type {\n UF,\n BrRegion,\n BrazilState,\n BrazilMunicipality,\n BrazilAdministrativeRegion,\n Choice,\n} from \"./locations\";\n\n// UF GeoJSON types (the geometry itself is lazy-loaded by BrazilMap).\nimport type { BrUfFeatureCollection } from \"./br-geo\";\nexport type { BrUfFeature, BrUfFeatureCollection, BrUfGeometry, Ring } from \"./br-geo\";\n\n/**\n * Lazily load the bundled simplified UF GeoJSON (~36 KB gzip). Kept out of the\n * synchronous barrel so a data-only import never pulls the geometry.\n */\nexport async function loadBrUfGeoJson(): Promise<BrUfFeatureCollection> {\n const mod = await import(\"./br-geo\");\n return mod.BR_UF_GEOJSON;\n}\n\n// Per-state municipality geometry (lazy, one chunk per UF).\nexport { loadStateMunicipalities } from \"./state-geo\";\nexport type { MunicipalityFeature, StateMunicipalities } from \"./state-geo\";\n\n// Offline geocoding (lazy centroid index).\nexport {\n nearestMunicipality,\n reverseGeocode,\n geocodeMunicipality,\n searchMunicipalities,\n municipalityCentroid,\n stateCentroid,\n} from \"./geocode\";\nexport type { MunicipalityCentroid, NearestMunicipality, ReverseGeocodeResult } from \"./geocode\";\n\n// Components\nexport { BrazilMap } from \"./BrazilMap\";\nexport type { BrazilMapProps, BrazilMapTooltipData } from \"./BrazilMap\";\nexport { BrazilStateMap } from \"./BrazilStateMap\";\nexport type {\n BrazilStateMapProps,\n BrazilStateMapTooltipData,\n Municipality,\n} from \"./BrazilStateMap\";\nexport { BrazilStateCitySelect } from \"./BrazilStateCitySelect\";\nexport type { BrazilStateCitySelectProps, BrazilStateCitySelection } from \"./BrazilStateCitySelect\";\nexport { MunicipalitySearch } from \"./MunicipalitySearch\";\nexport type { MunicipalitySearchProps } from \"./MunicipalitySearch\";\nexport type { GeoMarker } from \"@/geo/types\";\nexport type { MapMarkersProps } from \"./MapMarkers\";\nexport { MapLegend } from \"./MapLegend\";\nexport type { MapLegendProps, LegendItem } from \"./MapLegend\";\n\n// Pix — BR Code (EMV MPM) payload + the QR that carries it.\nexport {\n normalizePixKey,\n parsePixPayload,\n PixError,\n pixCrc16,\n pixKeyType,\n pixPayload,\n} from \"./pix\";\nexport type {\n NormalizedPixKey,\n ParsePixOptions,\n PixData,\n PixDynamicInput,\n PixField,\n PixInput,\n PixKeyType,\n PixStaticInput,\n} from \"./pix\";\nexport { PixQRCode } from \"./PixQRCode\";\nexport type { PixQRCodeLabels, PixQRCodeProps } from \"./PixQRCode\";\n\n// Boleto — 47/48-digit typed line, 44-digit barcode, FEBRABAN check digits.\nexport {\n boletoDueDate,\n BoletoError,\n boletoKind,\n codigoBarrasToLinhaDigitavel,\n fatorVencimento,\n formatLinhaDigitavel,\n linhaDigitavelToCodigoBarras,\n mod10Dac,\n mod11DacArrecadacao,\n mod11DacCobranca,\n parseCodigoBarras,\n parseLinhaDigitavel,\n validateBoleto,\n} from \"./boleto\";\nexport type {\n Boleto,\n BoletoArrecadacao,\n BoletoBanco,\n BoletoEpoch,\n BoletoKind,\n BoletoOptions,\n} from \"./boleto\";\n\n// NF-e / NFC-e / CT-e access key.\nexport {\n chaveNFeCheckDigit,\n ChaveNFeError,\n formatChaveNFe,\n parseChaveNFe,\n validateChaveNFe,\n} from \"./nfe\";\nexport type { ChaveNFe } from \"./nfe\";\n\n// WhatsApp deep link (chat opened with the message ready, never an API send).\nexport { openWhatsApp, toWhatsAppNumber, whatsAppUrl } from \"./whatsapp\";\n\n// National holidays + business-day arithmetic.\nexport {\n addBusinessDays,\n easterSunday,\n holidaysFor,\n isBusinessDay,\n isHoliday,\n nextBusinessDay,\n} from \"./holidays\";\nexport type { BusinessDayOptions, DateInput, Holiday, HolidayKind } from \"./holidays\";\n\n// Color scales + palettes for choropleths.\nexport {\n sequentialScale,\n quantizeScale,\n thresholdScale,\n SEQUENTIAL_BLUES,\n SEQUENTIAL_GREENS,\n SEQUENTIAL_VIRIDIS,\n DIVERGING_RDBU,\n} from \"./scales\";\nexport type { ColorScale } from \"./scales\";\nexport { REGION_COLORS, regionLegendItems } from \"./regions\";\n"],"mappings":";;;;;;;;;;;;;;;;;AAmCA,eAAsB,KAAkD;CAEpE,QAAO,MADW,OAAO,kBAAA,CACd;AACf"}
1
+ {"version":3,"file":"br.js","names":["loadBrUfGeoJson","BoletoError","BrazilMap","BrazilStateCitySelect","BrazilStateMap","ChaveNFeError","DIVERGING_RDBU","MapLegend","MunicipalitySearch","PixError","PixQRCode","REGION_COLORS","SEQUENTIAL_BLUES","SEQUENTIAL_GREENS","SEQUENTIAL_VIRIDIS","addBusinessDays","administrativeRegionsByUf","boletoDueDate","boletoKind","chaveNFeCheckDigit","citiesByUf","cityChoices","codigoBarrasToLinhaDigitavel","datasetVintage","easterSunday","fatorVencimento","formatChaveNFe","formatLinhaDigitavel","geocodeMunicipality","getState","holidaysFor","isBusinessDay","isHoliday","isValidCity","isValidUf","linhaDigitavelToCodigoBarras","listStates","loadStateMunicipalities","mod10Dac","mod11DacArrecadacao","mod11DacCobranca","municipalitiesByUf","municipalityCentroid","nearestMunicipality","nextBusinessDay","normalizePixKey","normalizeUf","openWhatsApp","parseChaveNFe","parseCodigoBarras","parseLinhaDigitavel","parsePixPayload","pendingGeometryIds","pixCrc16","pixKeyType","pixPayload","quantizeScale","regionLegendItems","resolveMunicipality","reverseGeocode","searchMunicipalities","sequentialScale","stateCentroid","statesByRegion","thresholdScale","toWhatsAppNumber","ufChoices","validateBoleto","validateChaveNFe","whatsAppUrl"],"sources":["../src/br/index.ts"],"sourcesContent":["// Brazilian locations data (states + cities) — mirrors the `utils/locations`\n// module of tempest-fastapi-sdk.\nexport {\n listStates,\n getState,\n citiesByUf,\n statesByRegion,\n isValidUf,\n normalizeUf,\n isValidCity,\n ufChoices,\n cityChoices,\n municipalitiesByUf,\n administrativeRegionsByUf,\n resolveMunicipality,\n datasetVintage,\n pendingGeometryIds,\n} from \"./locations\";\nexport type {\n UF,\n BrRegion,\n BrazilState,\n BrazilMunicipality,\n BrazilAdministrativeRegion,\n Choice,\n} from \"./locations\";\n\n// UF GeoJSON types (the geometry itself is lazy-loaded by BrazilMap).\nimport type { BrUfFeatureCollection } from \"./br-geo\";\nexport type { BrUfFeature, BrUfFeatureCollection, BrUfGeometry, Ring } from \"./br-geo\";\n\n/**\n * Lazily load the bundled simplified UF GeoJSON (~36 KB gzip). Kept out of the\n * synchronous barrel so a data-only import never pulls the geometry.\n */\nexport async function loadBrUfGeoJson(): Promise<BrUfFeatureCollection> {\n const mod = await import(\"./br-geo\");\n return mod.BR_UF_GEOJSON;\n}\n\n// Per-state municipality geometry (lazy, one chunk per UF).\nexport { loadStateMunicipalities } from \"./state-geo\";\nexport type { MunicipalityFeature, StateMunicipalities } from \"./state-geo\";\n\n// Offline geocoding (lazy centroid index).\nexport {\n nearestMunicipality,\n reverseGeocode,\n geocodeMunicipality,\n searchMunicipalities,\n municipalityCentroid,\n stateCentroid,\n} from \"./geocode\";\nexport type { MunicipalityCentroid, NearestMunicipality, ReverseGeocodeResult } from \"./geocode\";\n\n// Components\nexport { BrazilMap } from \"./BrazilMap\";\nexport type { BrazilMapProps, BrazilMapTooltipData } from \"./BrazilMap\";\nexport { BrazilStateMap } from \"./BrazilStateMap\";\nexport type {\n BrazilStateMapProps,\n BrazilStateMapTooltipData,\n Municipality,\n} from \"./BrazilStateMap\";\nexport { BrazilStateCitySelect } from \"./BrazilStateCitySelect\";\nexport type { BrazilStateCitySelectProps, BrazilStateCitySelection } from \"./BrazilStateCitySelect\";\nexport { MunicipalitySearch } from \"./MunicipalitySearch\";\nexport type { MunicipalitySearchProps } from \"./MunicipalitySearch\";\nexport type { GeoMarker } from \"@/geo/types\";\nexport type { MapMarkersProps } from \"./MapMarkers\";\nexport { MapLegend } from \"./MapLegend\";\nexport type { MapLegendProps, LegendItem } from \"./MapLegend\";\n\n// Pix — BR Code (EMV MPM) payload + the QR that carries it.\nexport {\n normalizePixKey,\n parsePixPayload,\n PixError,\n pixCrc16,\n pixKeyType,\n pixPayload,\n} from \"./pix\";\nexport type {\n NormalizedPixKey,\n ParsePixOptions,\n PixData,\n PixDynamicInput,\n PixField,\n PixInput,\n PixKeyType,\n PixStaticInput,\n} from \"./pix\";\nexport { PixQRCode } from \"./PixQRCode\";\nexport type { PixQRCodeLabels, PixQRCodeProps } from \"./PixQRCode\";\n\n// Boleto — 47/48-digit typed line, 44-digit barcode, FEBRABAN check digits.\nexport {\n boletoDueDate,\n BoletoError,\n boletoKind,\n codigoBarrasToLinhaDigitavel,\n fatorVencimento,\n formatLinhaDigitavel,\n linhaDigitavelToCodigoBarras,\n mod10Dac,\n mod11DacArrecadacao,\n mod11DacCobranca,\n parseCodigoBarras,\n parseLinhaDigitavel,\n validateBoleto,\n} from \"./boleto\";\nexport type {\n Boleto,\n BoletoArrecadacao,\n BoletoBanco,\n BoletoEpoch,\n BoletoKind,\n BoletoOptions,\n} from \"./boleto\";\n\n// NF-e / NFC-e / CT-e access key.\nexport {\n chaveNFeCheckDigit,\n ChaveNFeError,\n formatChaveNFe,\n parseChaveNFe,\n validateChaveNFe,\n} from \"./nfe\";\nexport type { ChaveNFe } from \"./nfe\";\n\n// WhatsApp deep link (chat opened with the message ready, never an API send).\nexport { openWhatsApp, toWhatsAppNumber, whatsAppUrl } from \"./whatsapp\";\n\n// National holidays + business-day arithmetic.\nexport {\n addBusinessDays,\n easterSunday,\n holidaysFor,\n isBusinessDay,\n isHoliday,\n nextBusinessDay,\n} from \"./holidays\";\nexport type { BusinessDayOptions, DateInput, Holiday, HolidayKind } from \"./holidays\";\n\n// Color scales + palettes for choropleths.\nexport {\n sequentialScale,\n quantizeScale,\n thresholdScale,\n SEQUENTIAL_BLUES,\n SEQUENTIAL_GREENS,\n SEQUENTIAL_VIRIDIS,\n DIVERGING_RDBU,\n} from \"./scales\";\nexport type { ColorScale } from \"./scales\";\nexport { REGION_COLORS, regionLegendItems } from \"./regions\";\n"],"mappings":";;;;;;;;;;;;;;;;;AAmCA,eAAsBA,KAAkD;CAEpE,QAAO,MADW,OAAO,kBAAA,CACd;AACf"}
@@ -1 +1 @@
1
- {"version":3,"file":"barcode.cjs","names":[],"sources":["../../src/capture/barcode.ts"],"sourcesContent":["/**\n * Symbologies the `BarcodeDetector` API names.\n *\n * Three of them carry the weight in Brazil: `ean_13` is the retail barcode on every\n * packaged product, `qr_code` is what a Pix \"copia e cola\" payload travels in, and\n * `code_128` is the label on a shipment. The rest are here because the spec has them\n * and asking for one costs nothing.\n */\nexport type BarcodeFormat =\n | \"aztec\"\n | \"codabar\"\n | \"code_128\"\n | \"code_39\"\n | \"code_93\"\n | \"data_matrix\"\n | \"ean_13\"\n | \"ean_8\"\n | \"itf\"\n | \"pdf417\"\n | \"qr_code\"\n | \"upc_a\"\n | \"upc_e\"\n | \"unknown\";\n\n/** Every symbology in the spec, used to validate what a detector reports back. */\nexport const ALL_BARCODE_FORMATS: readonly BarcodeFormat[] = [\n \"aztec\",\n \"codabar\",\n \"code_128\",\n \"code_39\",\n \"code_93\",\n \"data_matrix\",\n \"ean_13\",\n \"ean_8\",\n \"itf\",\n \"pdf417\",\n \"qr_code\",\n \"upc_a\",\n \"upc_e\",\n \"unknown\",\n];\n\n/**\n * What a scanner looks for when you do not say.\n *\n * Deliberately three formats, not all fourteen. Every extra symbology is more work\n * per frame, and on a mid-range phone the difference between three and fourteen is the\n * difference between a scanner that locks on instantly and one that feels broken.\n */\nexport const DEFAULT_BARCODE_FORMATS: readonly BarcodeFormat[] = [\"qr_code\", \"ean_13\", \"code_128\"];\n\n/** A corner of a detected symbol, in the source's pixel coordinates. */\nexport interface BarcodePoint {\n x: number;\n y: number;\n}\n\n/** One decoded symbol, normalised. */\nexport interface BarcodeScanResult {\n /** The decoded payload — a GTIN, a URL, a Pix BR Code. */\n rawValue: string;\n /** Which symbology it was read as. `\"unknown\"` when the engine does not say. */\n format: BarcodeFormat;\n /** Box in source pixels, or `null` when the engine reports none. */\n boundingBox: DOMRectReadOnly | null;\n /** Corners in source pixels, clockwise from top-left. Empty when unreported. */\n cornerPoints: readonly BarcodePoint[];\n}\n\n/**\n * The shape a detector resolves with, before normalisation.\n *\n * Every field is optional because a polyfill is allowed to report the value and no\n * geometry at all, and the native engines differ on `cornerPoints`.\n */\nexport interface DetectedBarcodeLike {\n rawValue?: string;\n format?: string;\n boundingBox?: DOMRectReadOnly;\n cornerPoints?: readonly BarcodePoint[];\n}\n\n/**\n * The slice of `BarcodeDetector` this SDK uses.\n *\n * Exported so a consumer can **inject a polyfill** where the native API is missing —\n * see {@link isBarcodeDetectionSupported} for why that matters — and so tests can hand\n * in a decoder without a camera. Anything with a `detect()` that resolves to objects\n * carrying a `rawValue` will do.\n */\nexport interface BarcodeDetectorLike {\n /**\n * Decode every symbol visible in the source.\n *\n * @param source - A `<video>`, a `<canvas>`, an `ImageBitmap`, a `Blob`…\n * @returns Every symbol found, or an empty array — finding nothing is not an error.\n */\n detect: (source: ImageBitmapSource) => Promise<readonly DetectedBarcodeLike[]>;\n}\n\n/** The constructor, as Chromium exposes it on the global scope. */\ninterface BarcodeDetectorConstructorLike {\n new (options?: { formats?: readonly string[] }): BarcodeDetectorLike;\n getSupportedFormats?: () => Promise<readonly string[]>;\n}\n\n/**\n * Read the constructor off the global scope, or `null` when the engine has none.\n *\n * Kept private: everything a consumer needs is covered by\n * {@link isBarcodeDetectionSupported}, {@link getSupportedBarcodeFormats} and\n * {@link createBarcodeDetector}.\n */\nfunction barcodeDetectorConstructor(): BarcodeDetectorConstructorLike | null {\n const candidate = (globalThis as { BarcodeDetector?: unknown }).BarcodeDetector;\n return typeof candidate === \"function\" ? (candidate as BarcodeDetectorConstructorLike) : null;\n}\n\n/**\n * Whether this browser can decode barcodes on its own.\n *\n * **Expect `false` on a lot of real devices, and design for it.** `BarcodeDetector` is\n * a Chromium-only API backed by a platform decoder, so it is there on Android and\n * ChromeOS, usually there on macOS, and **absent** on Chromium for Windows and Linux,\n * in Firefox, and in every browser on iOS (all of which are WebKit underneath,\n * including Chrome for iOS).\n *\n * This SDK ships **no** decoder of its own and no bundled fallback: a QR reader is\n * Reed–Solomon error correction plus perspective correction plus a finder-pattern\n * search, and the honest options are a WASM build every consumer of this SDK would pay\n * for, or nothing. So the escape hatch is injection instead — pass any\n * {@link BarcodeDetectorLike} (the `barcode-detector` polyfill, your own `zxing-wasm`\n * wrapper) as `detector` to `useBarcodeScanner`, and the SDK drives it exactly like\n * the native one.\n *\n * @returns `true` when `new BarcodeDetector()` will work.\n */\nexport function isBarcodeDetectionSupported(): boolean {\n return barcodeDetectorConstructor() !== null;\n}\n\n/**\n * Which symbologies this engine will actually decode.\n *\n * Worth asking rather than assuming: the format list belongs to the platform decoder,\n * not to the browser, so two Chromium builds on two operating systems answer\n * differently — and asking for a format the engine does not have makes the constructor\n * throw `NotSupportedError`, which reads like a bug in your code.\n *\n * @returns The supported formats, or an empty array when there is no detector.\n */\nexport async function getSupportedBarcodeFormats(): Promise<readonly BarcodeFormat[]> {\n const constructor = barcodeDetectorConstructor();\n if (!constructor || typeof constructor.getSupportedFormats !== \"function\") return [];\n try {\n const formats = await constructor.getSupportedFormats();\n return formats.filter((format): format is BarcodeFormat =>\n ALL_BARCODE_FORMATS.includes(format as BarcodeFormat),\n );\n } catch {\n return [];\n }\n}\n\n/**\n * Build a native detector for the given formats.\n *\n * @param formats - Symbologies to look for. Must be ones the engine supports.\n * @returns The detector, or `null` when the API is missing or refused the formats.\n */\nexport function createBarcodeDetector(\n formats: readonly BarcodeFormat[] = DEFAULT_BARCODE_FORMATS,\n): BarcodeDetectorLike | null {\n const constructor = barcodeDetectorConstructor();\n if (!constructor) return null;\n try {\n return new constructor({ formats: [...formats] });\n } catch {\n return null;\n }\n}\n\n/**\n * Turn one raw detection into a {@link BarcodeScanResult}.\n *\n * An unrecognised `format` string becomes `\"unknown\"` rather than being passed through\n * as a lie about the union, and missing geometry becomes `null`/`[]` rather than\n * `undefined`, so a consumer never has to branch on three kinds of absence.\n *\n * @param raw - What the detector resolved with.\n * @param known - The formats considered valid. Defaults to the whole spec list.\n * @returns The normalised result.\n */\nexport function normalizeBarcode(\n raw: DetectedBarcodeLike,\n known: readonly BarcodeFormat[] = ALL_BARCODE_FORMATS,\n): BarcodeScanResult {\n const format = raw.format as BarcodeFormat | undefined;\n return {\n rawValue: raw.rawValue ?? \"\",\n format: format !== undefined && known.includes(format) ? format : \"unknown\",\n boundingBox: raw.boundingBox ?? null,\n cornerPoints: raw.cornerPoints ?? [],\n };\n}\n"],"mappings":"AAyBA,IAAa,EAAgD,CACzD,QACA,UACA,WACA,UACA,UACA,cACA,SACA,QACA,MACA,SACA,UACA,QACA,QACA,SACJ,EASa,EAAoD,CAAC,UAAW,SAAU,UAAU,EAgEjG,SAAS,GAAoE,CACzE,IAAM,EAAa,WAA6C,gBAChE,OAAO,OAAO,GAAc,WAAc,EAA+C,IAC7F,CAqBA,SAAgB,GAAuC,CACnD,OAAO,EAA2B,IAAM,IAC5C,CAYA,eAAsB,GAAgE,CAClF,IAAM,EAAc,EAA2B,EAC/C,GAAI,CAAC,GAAe,OAAO,EAAY,qBAAwB,WAAY,MAAO,CAAC,EACnF,GAAI,CAEA,OAAO,MADe,EAAY,oBAAoB,EAAA,CACvC,OAAQ,GACnB,EAAoB,SAAS,CAAuB,CACxD,CACJ,MAAQ,CACJ,MAAO,CAAC,CACZ,CACJ,CAQA,SAAgB,EACZ,EAAoC,EACV,CAC1B,IAAM,EAAc,EAA2B,EAC/C,GAAI,CAAC,EAAa,OAAO,KACzB,GAAI,CACA,OAAO,IAAI,EAAY,CAAE,QAAS,CAAC,GAAG,CAAO,CAAE,CAAC,CACpD,MAAQ,CACJ,OAAO,IACX,CACJ,CAaA,SAAgB,EACZ,EACA,EAAkC,EACjB,CACjB,IAAM,EAAS,EAAI,OACnB,MAAO,CACH,SAAU,EAAI,UAAY,GAC1B,OAAQ,IAAW,IAAA,IAAa,EAAM,SAAS,CAAM,EAAI,EAAS,UAClE,YAAa,EAAI,aAAe,KAChC,aAAc,EAAI,cAAgB,CAAC,CACvC,CACJ"}
1
+ {"version":3,"file":"barcode.cjs","names":["ALL_BARCODE_FORMATS","DEFAULT_BARCODE_FORMATS","barcodeDetectorConstructor","candidate","isBarcodeDetectionSupported","getSupportedBarcodeFormats","constructor","format","createBarcodeDetector","formats","normalizeBarcode","raw","known"],"sources":["../../src/capture/barcode.ts"],"sourcesContent":["/**\n * Symbologies the `BarcodeDetector` API names.\n *\n * Three of them carry the weight in Brazil: `ean_13` is the retail barcode on every\n * packaged product, `qr_code` is what a Pix \"copia e cola\" payload travels in, and\n * `code_128` is the label on a shipment. The rest are here because the spec has them\n * and asking for one costs nothing.\n */\nexport type BarcodeFormat =\n | \"aztec\"\n | \"codabar\"\n | \"code_128\"\n | \"code_39\"\n | \"code_93\"\n | \"data_matrix\"\n | \"ean_13\"\n | \"ean_8\"\n | \"itf\"\n | \"pdf417\"\n | \"qr_code\"\n | \"upc_a\"\n | \"upc_e\"\n | \"unknown\";\n\n/** Every symbology in the spec, used to validate what a detector reports back. */\nexport const ALL_BARCODE_FORMATS: readonly BarcodeFormat[] = [\n \"aztec\",\n \"codabar\",\n \"code_128\",\n \"code_39\",\n \"code_93\",\n \"data_matrix\",\n \"ean_13\",\n \"ean_8\",\n \"itf\",\n \"pdf417\",\n \"qr_code\",\n \"upc_a\",\n \"upc_e\",\n \"unknown\",\n];\n\n/**\n * What a scanner looks for when you do not say.\n *\n * Deliberately three formats, not all fourteen. Every extra symbology is more work\n * per frame, and on a mid-range phone the difference between three and fourteen is the\n * difference between a scanner that locks on instantly and one that feels broken.\n */\nexport const DEFAULT_BARCODE_FORMATS: readonly BarcodeFormat[] = [\"qr_code\", \"ean_13\", \"code_128\"];\n\n/** A corner of a detected symbol, in the source's pixel coordinates. */\nexport interface BarcodePoint {\n x: number;\n y: number;\n}\n\n/** One decoded symbol, normalised. */\nexport interface BarcodeScanResult {\n /** The decoded payload — a GTIN, a URL, a Pix BR Code. */\n rawValue: string;\n /** Which symbology it was read as. `\"unknown\"` when the engine does not say. */\n format: BarcodeFormat;\n /** Box in source pixels, or `null` when the engine reports none. */\n boundingBox: DOMRectReadOnly | null;\n /** Corners in source pixels, clockwise from top-left. Empty when unreported. */\n cornerPoints: readonly BarcodePoint[];\n}\n\n/**\n * The shape a detector resolves with, before normalisation.\n *\n * Every field is optional because a polyfill is allowed to report the value and no\n * geometry at all, and the native engines differ on `cornerPoints`.\n */\nexport interface DetectedBarcodeLike {\n rawValue?: string;\n format?: string;\n boundingBox?: DOMRectReadOnly;\n cornerPoints?: readonly BarcodePoint[];\n}\n\n/**\n * The slice of `BarcodeDetector` this SDK uses.\n *\n * Exported so a consumer can **inject a polyfill** where the native API is missing —\n * see {@link isBarcodeDetectionSupported} for why that matters — and so tests can hand\n * in a decoder without a camera. Anything with a `detect()` that resolves to objects\n * carrying a `rawValue` will do.\n */\nexport interface BarcodeDetectorLike {\n /**\n * Decode every symbol visible in the source.\n *\n * @param source - A `<video>`, a `<canvas>`, an `ImageBitmap`, a `Blob`…\n * @returns Every symbol found, or an empty array — finding nothing is not an error.\n */\n detect: (source: ImageBitmapSource) => Promise<readonly DetectedBarcodeLike[]>;\n}\n\n/** The constructor, as Chromium exposes it on the global scope. */\ninterface BarcodeDetectorConstructorLike {\n new (options?: { formats?: readonly string[] }): BarcodeDetectorLike;\n getSupportedFormats?: () => Promise<readonly string[]>;\n}\n\n/**\n * Read the constructor off the global scope, or `null` when the engine has none.\n *\n * Kept private: everything a consumer needs is covered by\n * {@link isBarcodeDetectionSupported}, {@link getSupportedBarcodeFormats} and\n * {@link createBarcodeDetector}.\n */\nfunction barcodeDetectorConstructor(): BarcodeDetectorConstructorLike | null {\n const candidate = (globalThis as { BarcodeDetector?: unknown }).BarcodeDetector;\n return typeof candidate === \"function\" ? (candidate as BarcodeDetectorConstructorLike) : null;\n}\n\n/**\n * Whether this browser can decode barcodes on its own.\n *\n * **Expect `false` on a lot of real devices, and design for it.** `BarcodeDetector` is\n * a Chromium-only API backed by a platform decoder, so it is there on Android and\n * ChromeOS, usually there on macOS, and **absent** on Chromium for Windows and Linux,\n * in Firefox, and in every browser on iOS (all of which are WebKit underneath,\n * including Chrome for iOS).\n *\n * This SDK ships **no** decoder of its own and no bundled fallback: a QR reader is\n * Reed–Solomon error correction plus perspective correction plus a finder-pattern\n * search, and the honest options are a WASM build every consumer of this SDK would pay\n * for, or nothing. So the escape hatch is injection instead — pass any\n * {@link BarcodeDetectorLike} (the `barcode-detector` polyfill, your own `zxing-wasm`\n * wrapper) as `detector` to `useBarcodeScanner`, and the SDK drives it exactly like\n * the native one.\n *\n * @returns `true` when `new BarcodeDetector()` will work.\n */\nexport function isBarcodeDetectionSupported(): boolean {\n return barcodeDetectorConstructor() !== null;\n}\n\n/**\n * Which symbologies this engine will actually decode.\n *\n * Worth asking rather than assuming: the format list belongs to the platform decoder,\n * not to the browser, so two Chromium builds on two operating systems answer\n * differently — and asking for a format the engine does not have makes the constructor\n * throw `NotSupportedError`, which reads like a bug in your code.\n *\n * @returns The supported formats, or an empty array when there is no detector.\n */\nexport async function getSupportedBarcodeFormats(): Promise<readonly BarcodeFormat[]> {\n const constructor = barcodeDetectorConstructor();\n if (!constructor || typeof constructor.getSupportedFormats !== \"function\") return [];\n try {\n const formats = await constructor.getSupportedFormats();\n return formats.filter((format): format is BarcodeFormat =>\n ALL_BARCODE_FORMATS.includes(format as BarcodeFormat),\n );\n } catch {\n return [];\n }\n}\n\n/**\n * Build a native detector for the given formats.\n *\n * @param formats - Symbologies to look for. Must be ones the engine supports.\n * @returns The detector, or `null` when the API is missing or refused the formats.\n */\nexport function createBarcodeDetector(\n formats: readonly BarcodeFormat[] = DEFAULT_BARCODE_FORMATS,\n): BarcodeDetectorLike | null {\n const constructor = barcodeDetectorConstructor();\n if (!constructor) return null;\n try {\n return new constructor({ formats: [...formats] });\n } catch {\n return null;\n }\n}\n\n/**\n * Turn one raw detection into a {@link BarcodeScanResult}.\n *\n * An unrecognised `format` string becomes `\"unknown\"` rather than being passed through\n * as a lie about the union, and missing geometry becomes `null`/`[]` rather than\n * `undefined`, so a consumer never has to branch on three kinds of absence.\n *\n * @param raw - What the detector resolved with.\n * @param known - The formats considered valid. Defaults to the whole spec list.\n * @returns The normalised result.\n */\nexport function normalizeBarcode(\n raw: DetectedBarcodeLike,\n known: readonly BarcodeFormat[] = ALL_BARCODE_FORMATS,\n): BarcodeScanResult {\n const format = raw.format as BarcodeFormat | undefined;\n return {\n rawValue: raw.rawValue ?? \"\",\n format: format !== undefined && known.includes(format) ? format : \"unknown\",\n boundingBox: raw.boundingBox ?? null,\n cornerPoints: raw.cornerPoints ?? [],\n };\n}\n"],"mappings":"AAyBA,IAAaA,EAAgD,CACzD,QACA,UACA,WACA,UACA,UACA,cACA,SACA,QACA,MACA,SACA,UACA,QACA,QACA,SACJ,EASaC,EAAoD,CAAC,UAAW,SAAU,UAAU,EAgEjG,SAASC,GAAoE,CACzE,IAAMC,EAAa,WAA6C,gBAChE,OAAO,OAAOA,GAAc,WAAcA,EAA+C,IAC7F,CAqBA,SAAgBC,GAAuC,CACnD,OAAOF,EAA2B,IAAM,IAC5C,CAYA,eAAsBG,GAAgE,CAClF,IAAMC,EAAcJ,EAA2B,EAC/C,GAAI,CAACI,GAAe,OAAOA,EAAY,qBAAwB,WAAY,MAAO,CAAC,EACnF,GAAI,CAEA,OAAO,MADeA,EAAY,oBAAoB,EAAA,CACvC,OAAQ,GACnBN,EAAoB,SAASO,CAAuB,CACxD,CACJ,MAAQ,CACJ,MAAO,CAAC,CACZ,CACJ,CAQA,SAAgBC,EACZ,EAAoCP,EACV,CAC1B,IAAMK,EAAcJ,EAA2B,EAC/C,GAAI,CAACI,EAAa,OAAO,KACzB,GAAI,CACA,OAAO,IAAIA,EAAY,CAAE,QAAS,CAAC,GAAGG,CAAO,CAAE,CAAC,CACpD,MAAQ,CACJ,OAAO,IACX,CACJ,CAaA,SAAgBC,EACZ,EACA,EAAkCV,EACjB,CACjB,IAAMO,EAASI,EAAI,OACnB,MAAO,CACH,SAAUA,EAAI,UAAY,GAC1B,OAAQJ,IAAW,IAAA,IAAaK,EAAM,SAASL,CAAM,EAAIA,EAAS,UAClE,YAAaI,EAAI,aAAe,KAChC,aAAcA,EAAI,cAAgB,CAAC,CACvC,CACJ,C"}
@@ -1 +1 @@
1
- {"version":3,"file":"barcode.js","names":[],"sources":["../../src/capture/barcode.ts"],"sourcesContent":["/**\n * Symbologies the `BarcodeDetector` API names.\n *\n * Three of them carry the weight in Brazil: `ean_13` is the retail barcode on every\n * packaged product, `qr_code` is what a Pix \"copia e cola\" payload travels in, and\n * `code_128` is the label on a shipment. The rest are here because the spec has them\n * and asking for one costs nothing.\n */\nexport type BarcodeFormat =\n | \"aztec\"\n | \"codabar\"\n | \"code_128\"\n | \"code_39\"\n | \"code_93\"\n | \"data_matrix\"\n | \"ean_13\"\n | \"ean_8\"\n | \"itf\"\n | \"pdf417\"\n | \"qr_code\"\n | \"upc_a\"\n | \"upc_e\"\n | \"unknown\";\n\n/** Every symbology in the spec, used to validate what a detector reports back. */\nexport const ALL_BARCODE_FORMATS: readonly BarcodeFormat[] = [\n \"aztec\",\n \"codabar\",\n \"code_128\",\n \"code_39\",\n \"code_93\",\n \"data_matrix\",\n \"ean_13\",\n \"ean_8\",\n \"itf\",\n \"pdf417\",\n \"qr_code\",\n \"upc_a\",\n \"upc_e\",\n \"unknown\",\n];\n\n/**\n * What a scanner looks for when you do not say.\n *\n * Deliberately three formats, not all fourteen. Every extra symbology is more work\n * per frame, and on a mid-range phone the difference between three and fourteen is the\n * difference between a scanner that locks on instantly and one that feels broken.\n */\nexport const DEFAULT_BARCODE_FORMATS: readonly BarcodeFormat[] = [\"qr_code\", \"ean_13\", \"code_128\"];\n\n/** A corner of a detected symbol, in the source's pixel coordinates. */\nexport interface BarcodePoint {\n x: number;\n y: number;\n}\n\n/** One decoded symbol, normalised. */\nexport interface BarcodeScanResult {\n /** The decoded payload — a GTIN, a URL, a Pix BR Code. */\n rawValue: string;\n /** Which symbology it was read as. `\"unknown\"` when the engine does not say. */\n format: BarcodeFormat;\n /** Box in source pixels, or `null` when the engine reports none. */\n boundingBox: DOMRectReadOnly | null;\n /** Corners in source pixels, clockwise from top-left. Empty when unreported. */\n cornerPoints: readonly BarcodePoint[];\n}\n\n/**\n * The shape a detector resolves with, before normalisation.\n *\n * Every field is optional because a polyfill is allowed to report the value and no\n * geometry at all, and the native engines differ on `cornerPoints`.\n */\nexport interface DetectedBarcodeLike {\n rawValue?: string;\n format?: string;\n boundingBox?: DOMRectReadOnly;\n cornerPoints?: readonly BarcodePoint[];\n}\n\n/**\n * The slice of `BarcodeDetector` this SDK uses.\n *\n * Exported so a consumer can **inject a polyfill** where the native API is missing —\n * see {@link isBarcodeDetectionSupported} for why that matters — and so tests can hand\n * in a decoder without a camera. Anything with a `detect()` that resolves to objects\n * carrying a `rawValue` will do.\n */\nexport interface BarcodeDetectorLike {\n /**\n * Decode every symbol visible in the source.\n *\n * @param source - A `<video>`, a `<canvas>`, an `ImageBitmap`, a `Blob`…\n * @returns Every symbol found, or an empty array — finding nothing is not an error.\n */\n detect: (source: ImageBitmapSource) => Promise<readonly DetectedBarcodeLike[]>;\n}\n\n/** The constructor, as Chromium exposes it on the global scope. */\ninterface BarcodeDetectorConstructorLike {\n new (options?: { formats?: readonly string[] }): BarcodeDetectorLike;\n getSupportedFormats?: () => Promise<readonly string[]>;\n}\n\n/**\n * Read the constructor off the global scope, or `null` when the engine has none.\n *\n * Kept private: everything a consumer needs is covered by\n * {@link isBarcodeDetectionSupported}, {@link getSupportedBarcodeFormats} and\n * {@link createBarcodeDetector}.\n */\nfunction barcodeDetectorConstructor(): BarcodeDetectorConstructorLike | null {\n const candidate = (globalThis as { BarcodeDetector?: unknown }).BarcodeDetector;\n return typeof candidate === \"function\" ? (candidate as BarcodeDetectorConstructorLike) : null;\n}\n\n/**\n * Whether this browser can decode barcodes on its own.\n *\n * **Expect `false` on a lot of real devices, and design for it.** `BarcodeDetector` is\n * a Chromium-only API backed by a platform decoder, so it is there on Android and\n * ChromeOS, usually there on macOS, and **absent** on Chromium for Windows and Linux,\n * in Firefox, and in every browser on iOS (all of which are WebKit underneath,\n * including Chrome for iOS).\n *\n * This SDK ships **no** decoder of its own and no bundled fallback: a QR reader is\n * Reed–Solomon error correction plus perspective correction plus a finder-pattern\n * search, and the honest options are a WASM build every consumer of this SDK would pay\n * for, or nothing. So the escape hatch is injection instead — pass any\n * {@link BarcodeDetectorLike} (the `barcode-detector` polyfill, your own `zxing-wasm`\n * wrapper) as `detector` to `useBarcodeScanner`, and the SDK drives it exactly like\n * the native one.\n *\n * @returns `true` when `new BarcodeDetector()` will work.\n */\nexport function isBarcodeDetectionSupported(): boolean {\n return barcodeDetectorConstructor() !== null;\n}\n\n/**\n * Which symbologies this engine will actually decode.\n *\n * Worth asking rather than assuming: the format list belongs to the platform decoder,\n * not to the browser, so two Chromium builds on two operating systems answer\n * differently — and asking for a format the engine does not have makes the constructor\n * throw `NotSupportedError`, which reads like a bug in your code.\n *\n * @returns The supported formats, or an empty array when there is no detector.\n */\nexport async function getSupportedBarcodeFormats(): Promise<readonly BarcodeFormat[]> {\n const constructor = barcodeDetectorConstructor();\n if (!constructor || typeof constructor.getSupportedFormats !== \"function\") return [];\n try {\n const formats = await constructor.getSupportedFormats();\n return formats.filter((format): format is BarcodeFormat =>\n ALL_BARCODE_FORMATS.includes(format as BarcodeFormat),\n );\n } catch {\n return [];\n }\n}\n\n/**\n * Build a native detector for the given formats.\n *\n * @param formats - Symbologies to look for. Must be ones the engine supports.\n * @returns The detector, or `null` when the API is missing or refused the formats.\n */\nexport function createBarcodeDetector(\n formats: readonly BarcodeFormat[] = DEFAULT_BARCODE_FORMATS,\n): BarcodeDetectorLike | null {\n const constructor = barcodeDetectorConstructor();\n if (!constructor) return null;\n try {\n return new constructor({ formats: [...formats] });\n } catch {\n return null;\n }\n}\n\n/**\n * Turn one raw detection into a {@link BarcodeScanResult}.\n *\n * An unrecognised `format` string becomes `\"unknown\"` rather than being passed through\n * as a lie about the union, and missing geometry becomes `null`/`[]` rather than\n * `undefined`, so a consumer never has to branch on three kinds of absence.\n *\n * @param raw - What the detector resolved with.\n * @param known - The formats considered valid. Defaults to the whole spec list.\n * @returns The normalised result.\n */\nexport function normalizeBarcode(\n raw: DetectedBarcodeLike,\n known: readonly BarcodeFormat[] = ALL_BARCODE_FORMATS,\n): BarcodeScanResult {\n const format = raw.format as BarcodeFormat | undefined;\n return {\n rawValue: raw.rawValue ?? \"\",\n format: format !== undefined && known.includes(format) ? format : \"unknown\",\n boundingBox: raw.boundingBox ?? null,\n cornerPoints: raw.cornerPoints ?? [],\n };\n}\n"],"mappings":";AAyBA,IAAa,IAAgD;CACzD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACJ,GASa,IAAoD;CAAC;CAAW;CAAU;AAAU;AAgEjG,SAAS,IAAoE;CACzE,IAAM,IAAa,WAA6C;CAChE,OAAO,OAAO,KAAc,aAAc,IAA+C;AAC7F;AAqBA,SAAgB,IAAuC;CACnD,OAAO,EAA2B,MAAM;AAC5C;AAYA,eAAsB,IAAgE;CAClF,IAAM,IAAc,EAA2B;CAC/C,IAAI,CAAC,KAAe,OAAO,EAAY,uBAAwB,YAAY,OAAO,CAAC;CACnF,IAAI;EAEA,QAAO,MADe,EAAY,oBAAoB,EAAA,CACvC,QAAQ,MACnB,EAAoB,SAAS,CAAuB,CACxD;CACJ,QAAQ;EACJ,OAAO,CAAC;CACZ;AACJ;AAQA,SAAgB,EACZ,IAAoC,GACV;CAC1B,IAAM,IAAc,EAA2B;CAC/C,IAAI,CAAC,GAAa,OAAO;CACzB,IAAI;EACA,OAAO,IAAI,EAAY,EAAE,SAAS,CAAC,GAAG,CAAO,EAAE,CAAC;CACpD,QAAQ;EACJ,OAAO;CACX;AACJ;AAaA,SAAgB,EACZ,GACA,IAAkC,GACjB;CACjB,IAAM,IAAS,EAAI;CACnB,OAAO;EACH,UAAU,EAAI,YAAY;EAC1B,QAAQ,MAAW,KAAA,KAAa,EAAM,SAAS,CAAM,IAAI,IAAS;EAClE,aAAa,EAAI,eAAe;EAChC,cAAc,EAAI,gBAAgB,CAAC;CACvC;AACJ"}
1
+ {"version":3,"file":"barcode.js","names":["ALL_BARCODE_FORMATS","DEFAULT_BARCODE_FORMATS","barcodeDetectorConstructor","candidate","isBarcodeDetectionSupported","getSupportedBarcodeFormats","constructor","format","createBarcodeDetector","formats","normalizeBarcode","raw","known"],"sources":["../../src/capture/barcode.ts"],"sourcesContent":["/**\n * Symbologies the `BarcodeDetector` API names.\n *\n * Three of them carry the weight in Brazil: `ean_13` is the retail barcode on every\n * packaged product, `qr_code` is what a Pix \"copia e cola\" payload travels in, and\n * `code_128` is the label on a shipment. The rest are here because the spec has them\n * and asking for one costs nothing.\n */\nexport type BarcodeFormat =\n | \"aztec\"\n | \"codabar\"\n | \"code_128\"\n | \"code_39\"\n | \"code_93\"\n | \"data_matrix\"\n | \"ean_13\"\n | \"ean_8\"\n | \"itf\"\n | \"pdf417\"\n | \"qr_code\"\n | \"upc_a\"\n | \"upc_e\"\n | \"unknown\";\n\n/** Every symbology in the spec, used to validate what a detector reports back. */\nexport const ALL_BARCODE_FORMATS: readonly BarcodeFormat[] = [\n \"aztec\",\n \"codabar\",\n \"code_128\",\n \"code_39\",\n \"code_93\",\n \"data_matrix\",\n \"ean_13\",\n \"ean_8\",\n \"itf\",\n \"pdf417\",\n \"qr_code\",\n \"upc_a\",\n \"upc_e\",\n \"unknown\",\n];\n\n/**\n * What a scanner looks for when you do not say.\n *\n * Deliberately three formats, not all fourteen. Every extra symbology is more work\n * per frame, and on a mid-range phone the difference between three and fourteen is the\n * difference between a scanner that locks on instantly and one that feels broken.\n */\nexport const DEFAULT_BARCODE_FORMATS: readonly BarcodeFormat[] = [\"qr_code\", \"ean_13\", \"code_128\"];\n\n/** A corner of a detected symbol, in the source's pixel coordinates. */\nexport interface BarcodePoint {\n x: number;\n y: number;\n}\n\n/** One decoded symbol, normalised. */\nexport interface BarcodeScanResult {\n /** The decoded payload — a GTIN, a URL, a Pix BR Code. */\n rawValue: string;\n /** Which symbology it was read as. `\"unknown\"` when the engine does not say. */\n format: BarcodeFormat;\n /** Box in source pixels, or `null` when the engine reports none. */\n boundingBox: DOMRectReadOnly | null;\n /** Corners in source pixels, clockwise from top-left. Empty when unreported. */\n cornerPoints: readonly BarcodePoint[];\n}\n\n/**\n * The shape a detector resolves with, before normalisation.\n *\n * Every field is optional because a polyfill is allowed to report the value and no\n * geometry at all, and the native engines differ on `cornerPoints`.\n */\nexport interface DetectedBarcodeLike {\n rawValue?: string;\n format?: string;\n boundingBox?: DOMRectReadOnly;\n cornerPoints?: readonly BarcodePoint[];\n}\n\n/**\n * The slice of `BarcodeDetector` this SDK uses.\n *\n * Exported so a consumer can **inject a polyfill** where the native API is missing —\n * see {@link isBarcodeDetectionSupported} for why that matters — and so tests can hand\n * in a decoder without a camera. Anything with a `detect()` that resolves to objects\n * carrying a `rawValue` will do.\n */\nexport interface BarcodeDetectorLike {\n /**\n * Decode every symbol visible in the source.\n *\n * @param source - A `<video>`, a `<canvas>`, an `ImageBitmap`, a `Blob`…\n * @returns Every symbol found, or an empty array — finding nothing is not an error.\n */\n detect: (source: ImageBitmapSource) => Promise<readonly DetectedBarcodeLike[]>;\n}\n\n/** The constructor, as Chromium exposes it on the global scope. */\ninterface BarcodeDetectorConstructorLike {\n new (options?: { formats?: readonly string[] }): BarcodeDetectorLike;\n getSupportedFormats?: () => Promise<readonly string[]>;\n}\n\n/**\n * Read the constructor off the global scope, or `null` when the engine has none.\n *\n * Kept private: everything a consumer needs is covered by\n * {@link isBarcodeDetectionSupported}, {@link getSupportedBarcodeFormats} and\n * {@link createBarcodeDetector}.\n */\nfunction barcodeDetectorConstructor(): BarcodeDetectorConstructorLike | null {\n const candidate = (globalThis as { BarcodeDetector?: unknown }).BarcodeDetector;\n return typeof candidate === \"function\" ? (candidate as BarcodeDetectorConstructorLike) : null;\n}\n\n/**\n * Whether this browser can decode barcodes on its own.\n *\n * **Expect `false` on a lot of real devices, and design for it.** `BarcodeDetector` is\n * a Chromium-only API backed by a platform decoder, so it is there on Android and\n * ChromeOS, usually there on macOS, and **absent** on Chromium for Windows and Linux,\n * in Firefox, and in every browser on iOS (all of which are WebKit underneath,\n * including Chrome for iOS).\n *\n * This SDK ships **no** decoder of its own and no bundled fallback: a QR reader is\n * Reed–Solomon error correction plus perspective correction plus a finder-pattern\n * search, and the honest options are a WASM build every consumer of this SDK would pay\n * for, or nothing. So the escape hatch is injection instead — pass any\n * {@link BarcodeDetectorLike} (the `barcode-detector` polyfill, your own `zxing-wasm`\n * wrapper) as `detector` to `useBarcodeScanner`, and the SDK drives it exactly like\n * the native one.\n *\n * @returns `true` when `new BarcodeDetector()` will work.\n */\nexport function isBarcodeDetectionSupported(): boolean {\n return barcodeDetectorConstructor() !== null;\n}\n\n/**\n * Which symbologies this engine will actually decode.\n *\n * Worth asking rather than assuming: the format list belongs to the platform decoder,\n * not to the browser, so two Chromium builds on two operating systems answer\n * differently — and asking for a format the engine does not have makes the constructor\n * throw `NotSupportedError`, which reads like a bug in your code.\n *\n * @returns The supported formats, or an empty array when there is no detector.\n */\nexport async function getSupportedBarcodeFormats(): Promise<readonly BarcodeFormat[]> {\n const constructor = barcodeDetectorConstructor();\n if (!constructor || typeof constructor.getSupportedFormats !== \"function\") return [];\n try {\n const formats = await constructor.getSupportedFormats();\n return formats.filter((format): format is BarcodeFormat =>\n ALL_BARCODE_FORMATS.includes(format as BarcodeFormat),\n );\n } catch {\n return [];\n }\n}\n\n/**\n * Build a native detector for the given formats.\n *\n * @param formats - Symbologies to look for. Must be ones the engine supports.\n * @returns The detector, or `null` when the API is missing or refused the formats.\n */\nexport function createBarcodeDetector(\n formats: readonly BarcodeFormat[] = DEFAULT_BARCODE_FORMATS,\n): BarcodeDetectorLike | null {\n const constructor = barcodeDetectorConstructor();\n if (!constructor) return null;\n try {\n return new constructor({ formats: [...formats] });\n } catch {\n return null;\n }\n}\n\n/**\n * Turn one raw detection into a {@link BarcodeScanResult}.\n *\n * An unrecognised `format` string becomes `\"unknown\"` rather than being passed through\n * as a lie about the union, and missing geometry becomes `null`/`[]` rather than\n * `undefined`, so a consumer never has to branch on three kinds of absence.\n *\n * @param raw - What the detector resolved with.\n * @param known - The formats considered valid. Defaults to the whole spec list.\n * @returns The normalised result.\n */\nexport function normalizeBarcode(\n raw: DetectedBarcodeLike,\n known: readonly BarcodeFormat[] = ALL_BARCODE_FORMATS,\n): BarcodeScanResult {\n const format = raw.format as BarcodeFormat | undefined;\n return {\n rawValue: raw.rawValue ?? \"\",\n format: format !== undefined && known.includes(format) ? format : \"unknown\",\n boundingBox: raw.boundingBox ?? null,\n cornerPoints: raw.cornerPoints ?? [],\n };\n}\n"],"mappings":";AAyBA,IAAaA,IAAgD;CACzD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACJ,GASaC,IAAoD;CAAC;CAAW;CAAU;AAAU;AAgEjG,SAASC,IAAoE;CACzE,IAAMC,IAAa,WAA6C;CAChE,OAAO,OAAOA,KAAc,aAAcA,IAA+C;AAC7F;AAqBA,SAAgBC,IAAuC;CACnD,OAAOF,EAA2B,MAAM;AAC5C;AAYA,eAAsBG,IAAgE;CAClF,IAAMC,IAAcJ,EAA2B;CAC/C,IAAI,CAACI,KAAe,OAAOA,EAAY,uBAAwB,YAAY,OAAO,CAAC;CACnF,IAAI;EAEA,QAAO,MADeA,EAAY,oBAAoB,EAAA,CACvC,QAAQ,MACnBN,EAAoB,SAASO,CAAuB,CACxD;CACJ,QAAQ;EACJ,OAAO,CAAC;CACZ;AACJ;AAQA,SAAgBC,EACZ,IAAoCP,GACV;CAC1B,IAAMK,IAAcJ,EAA2B;CAC/C,IAAI,CAACI,GAAa,OAAO;CACzB,IAAI;EACA,OAAO,IAAIA,EAAY,EAAE,SAAS,CAAC,GAAGG,CAAO,EAAE,CAAC;CACpD,QAAQ;EACJ,OAAO;CACX;AACJ;AAaA,SAAgBC,EACZ,GACA,IAAkCV,GACjB;CACjB,IAAMO,IAASI,EAAI;CACnB,OAAO;EACH,UAAUA,EAAI,YAAY;EAC1B,QAAQJ,MAAW,KAAA,KAAaK,EAAM,SAASL,CAAM,IAAIA,IAAS;EAClE,aAAaI,EAAI,eAAe;EAChC,cAAcA,EAAI,gBAAgB,CAAC;CACvC;AACJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"media-recorder.cjs","names":[],"sources":["../../src/capture/media-recorder.ts"],"sourcesContent":["/**\n * @tempest-limits function-lines — the engine behind both the audio and the video\n * recorder: MIME negotiation, the state machine MediaRecorder does not give you, and\n * the clock kept by hand because a fresh WebM reports no duration. The clock has to\n * pause and resume with the state machine, so they are one closure.\n */\n/** Lifecycle of a recording. */\nexport type MediaRecorderStatus = \"idle\" | \"recording\" | \"paused\" | \"stopped\";\n\n/** What a track carries — used only to word the errors this engine throws. */\nexport type MediaRecordingKind = \"audio\" | \"video\";\n\n/** A finished recording, whatever it was made of. */\nexport interface MediaRecording {\n /** The bytes. Wrap with `useObjectUrl` to play it, or POST it as-is. */\n blob: Blob;\n /** What the browser actually produced — not necessarily what you asked for. */\n mimeType: string;\n /** Recorded length, excluding time spent paused. */\n durationMs: number;\n}\n\n/** Options for {@link createMediaRecorder}. */\nexport interface MediaRecordingOptions {\n /**\n * Container candidates, best first. Required: this engine has no opinion about\n * codecs — the audio and video wrappers own that list.\n */\n candidates: readonly string[];\n /** Wording for the thrown messages (\"cannot record any supported *video* container\"). */\n kind: MediaRecordingKind;\n /** Force a container, bypassing the negotiation. Throws when unsupported. */\n mimeType?: string;\n /** Target audio bitrate. */\n audioBitsPerSecond?: number;\n /** Target video bitrate. Ignored by the browser on an audio-only stream. */\n videoBitsPerSecond?: number;\n /**\n * Emit a chunk every N ms through `onChunk`, for streaming upload.\n *\n * Without it the whole recording is buffered in memory until `stop()`.\n */\n timesliceMs?: number;\n /** Receives each chunk when `timesliceMs` is set. Chunks are **not** independently playable. */\n onChunk?: (chunk: Blob) => void;\n /** Recorder-level failure (device unplugged mid-recording, encoder error). */\n onError?: (error: unknown) => void;\n}\n\n/** Imperative recorder over one `MediaStream`. */\nexport interface MediaRecorderHandle {\n /** Begin recording. No-op when already recording or paused. */\n start: () => void;\n /** Pause. The clock stops; `durationMs` freezes. */\n pause: () => void;\n /** Resume after `pause()`. */\n resume: () => void;\n /** Stop and resolve with the assembled recording. */\n stop: () => Promise<MediaRecording>;\n /** Stop and throw the bytes away. */\n cancel: () => void;\n status: () => MediaRecorderStatus;\n /** Recorded length so far, excluding paused time. */\n durationMs: () => number;\n /** The negotiated container. */\n mimeType: string;\n}\n\n/**\n * First container in `preferred` the browser can actually produce, or `null`.\n *\n * @param preferred - Candidates, best first.\n * @returns A supported MIME type, or `null` when none is.\n */\nexport function pickRecordingMimeType(preferred: readonly string[]): string | null {\n if (typeof MediaRecorder === \"undefined\") return null;\n // Older WebViews ship `MediaRecorder` without the static probe. Assume the first\n // candidate rather than refusing outright — the constructor will tell us.\n if (typeof MediaRecorder.isTypeSupported !== \"function\") return preferred[0] ?? null;\n return preferred.find((type) => MediaRecorder.isTypeSupported(type)) ?? null;\n}\n\n/**\n * Wrap a `MediaStream` in a recorder with a real state machine and an honest clock.\n *\n * This is the engine behind both `createAudioRecorder` and `createVideoRecorder`; the\n * only thing it does not decide is which containers to try, because that is the one\n * part that genuinely differs between the two.\n *\n * Two things `MediaRecorder` does not give you:\n *\n * - **A duration.** It reports none, and the `Blob` has no reliable one either —\n * WebM written by `MediaRecorder` carries no duration in its header, which is why\n * `<audio>`/`<video>` shows `Infinity` for a fresh recording. So the clock is kept\n * here, and it subtracts paused time: a recorder that counts wall-clock through a\n * pause reports a 30-second note as two minutes.\n * - **A promise from `stop()`.** The last chunk arrives *after* `stop()` returns, in\n * a `dataavailable` event that fires before `onstop`. Assembling the blob in\n * `onstop` is the only point where every chunk is in hand.\n *\n * The stream is **not** owned here: `stop()` leaves the device open so a retake does\n * not need a second permission round-trip. Release it with the owning hook's `stop()`.\n *\n * @param stream - A live stream, from `getUserMedia` or `getDisplayMedia`.\n * @param options - See {@link MediaRecordingOptions}.\n * @returns The imperative recorder.\n * @throws When `MediaRecorder` is unavailable, or an explicit `mimeType` is unsupported.\n */\nexport function createMediaRecorder(\n stream: MediaStream,\n options: MediaRecordingOptions,\n): MediaRecorderHandle {\n const {\n candidates,\n kind,\n mimeType: forced,\n audioBitsPerSecond,\n videoBitsPerSecond,\n timesliceMs,\n onChunk,\n onError,\n } = options;\n\n if (typeof MediaRecorder === \"undefined\") {\n throw new Error(\"MediaRecorder is not available in this environment.\");\n }\n const negotiated = forced ?? pickRecordingMimeType(candidates);\n if (negotiated === null) {\n throw new Error(`This browser cannot record any supported ${kind} container.`);\n }\n if (\n forced !== undefined &&\n typeof MediaRecorder.isTypeSupported === \"function\" &&\n !MediaRecorder.isTypeSupported(forced)\n ) {\n throw new Error(`This browser cannot record \"${forced}\".`);\n }\n\n const recorder = new MediaRecorder(stream, {\n mimeType: negotiated,\n ...(audioBitsPerSecond !== undefined ? { audioBitsPerSecond } : {}),\n ...(videoBitsPerSecond !== undefined ? { videoBitsPerSecond } : {}),\n });\n\n let chunks: Blob[] = [];\n let status: MediaRecorderStatus = \"idle\";\n let accumulatedMs = 0;\n let segmentStart = 0;\n let settle: ((recording: MediaRecording) => void) | null = null;\n let discard = false;\n\n const elapsed = (): number =>\n accumulatedMs + (status === \"recording\" ? Date.now() - segmentStart : 0);\n\n recorder.ondataavailable = (event: BlobEvent): void => {\n if (event.data.size === 0) return;\n if (discard) return;\n chunks.push(event.data);\n onChunk?.(event.data);\n };\n\n recorder.onerror = (event: Event): void => {\n onError?.((event as unknown as { error?: unknown }).error ?? event);\n };\n\n recorder.onstop = (): void => {\n const durationMs = elapsed();\n status = \"stopped\";\n const resolve = settle;\n settle = null;\n if (discard) {\n chunks = [];\n return;\n }\n // `recorder.mimeType` is the source of truth: a browser handed\n // `video/webm;codecs=vp9,opus` may report plain `video/webm` back.\n const type = recorder.mimeType || negotiated;\n resolve?.({ blob: new Blob(chunks, { type }), mimeType: type, durationMs });\n chunks = [];\n };\n\n return {\n mimeType: negotiated,\n status: () => status,\n durationMs: elapsed,\n\n start(): void {\n if (status === \"recording\" || status === \"paused\") return;\n chunks = [];\n accumulatedMs = 0;\n discard = false;\n segmentStart = Date.now();\n status = \"recording\";\n if (timesliceMs !== undefined) recorder.start(timesliceMs);\n else recorder.start();\n },\n\n pause(): void {\n if (status !== \"recording\") return;\n accumulatedMs += Date.now() - segmentStart;\n status = \"paused\";\n recorder.pause();\n },\n\n resume(): void {\n if (status !== \"paused\") return;\n segmentStart = Date.now();\n status = \"recording\";\n recorder.resume();\n },\n\n stop(): Promise<MediaRecording> {\n if (status === \"idle\" || status === \"stopped\") {\n return Promise.resolve({\n blob: new Blob([], { type: negotiated }),\n mimeType: negotiated,\n durationMs: 0,\n });\n }\n // Stopping while paused needs no clock fix-up: `pause()` already folded\n // the last segment into `accumulatedMs`, and `elapsed()` adds nothing\n // while the status is not `\"recording\"`.\n return new Promise<MediaRecording>((resolve) => {\n settle = resolve;\n recorder.stop();\n });\n },\n\n cancel(): void {\n if (status === \"idle\" || status === \"stopped\") return;\n discard = true;\n settle = null;\n recorder.stop();\n },\n };\n}\n"],"mappings":"AA0EA,SAAgB,EAAsB,EAA6C,CAK/E,OAJI,OAAO,cAAkB,IAAoB,KAG7C,OAAO,cAAc,iBAAoB,WACtC,EAAU,KAAM,GAAS,cAAc,gBAAgB,CAAI,CAAC,GAAK,KADR,EAAU,IAAM,IAEpF,CA4BA,SAAgB,EACZ,EACA,EACmB,CACnB,GAAM,CACF,aACA,OACA,SAAU,EACV,qBACA,qBACA,cACA,UACA,WACA,EAEJ,GAAI,OAAO,cAAkB,IACzB,MAAU,MAAM,qDAAqD,EAEzE,IAAM,EAAa,GAAU,EAAsB,CAAU,EAC7D,GAAI,IAAe,KACf,MAAU,MAAM,4CAA4C,EAAK,YAAY,EAEjF,GACI,IAAW,IAAA,IACX,OAAO,cAAc,iBAAoB,YACzC,CAAC,cAAc,gBAAgB,CAAM,EAErC,MAAU,MAAM,+BAA+B,EAAO,GAAG,EAG7D,IAAM,EAAW,IAAI,cAAc,EAAQ,CACvC,SAAU,EACV,GAAI,IAAuB,IAAA,GAAqC,CAAC,EAA1B,CAAE,oBAAmB,EAC5D,GAAI,IAAuB,IAAA,GAAqC,CAAC,EAA1B,CAAE,oBAAmB,CAChE,CAAC,EAEG,EAAiB,CAAC,EAClB,EAA8B,OAC9B,EAAgB,EAChB,EAAe,EACf,EAAuD,KACvD,EAAU,GAER,MACF,GAAiB,IAAW,YAAc,KAAK,IAAI,EAAI,EAAe,GA6B1E,MA3BA,GAAS,gBAAmB,GAA2B,CAC/C,EAAM,KAAK,OAAS,IACpB,IACJ,EAAO,KAAK,EAAM,IAAI,EACtB,IAAU,EAAM,IAAI,GACxB,EAEA,EAAS,QAAW,GAAuB,CACvC,IAAW,EAAyC,OAAS,CAAK,CACtE,EAEA,EAAS,WAAqB,CAC1B,IAAM,EAAa,EAAQ,EAC3B,EAAS,UACT,IAAM,EAAU,EAEhB,GADA,EAAS,KACL,EAAS,CACT,EAAS,CAAC,EACV,MACJ,CAGA,IAAM,EAAO,EAAS,UAAY,EAClC,IAAU,CAAE,KAAM,IAAI,KAAK,EAAQ,CAAE,MAAK,CAAC,EAAG,SAAU,EAAM,YAAW,CAAC,EAC1E,EAAS,CAAC,CACd,EAEO,CACH,SAAU,EACV,WAAc,EACd,WAAY,EAEZ,OAAc,CACN,IAAW,aAAe,IAAW,WACzC,EAAS,CAAC,EACV,EAAgB,EAChB,EAAU,GACV,EAAe,KAAK,IAAI,EACxB,EAAS,YACL,IAAgB,IAAA,GACf,EAAS,MAAM,EADW,EAAS,MAAM,CAAW,EAE7D,EAEA,OAAc,CACN,IAAW,cACf,GAAiB,KAAK,IAAI,EAAI,EAC9B,EAAS,SACT,EAAS,MAAM,EACnB,EAEA,QAAe,CACP,IAAW,WACf,EAAe,KAAK,IAAI,EACxB,EAAS,YACT,EAAS,OAAO,EACpB,EAEA,MAAgC,CAW5B,OAVI,IAAW,QAAU,IAAW,UACzB,QAAQ,QAAQ,CACnB,KAAM,IAAI,KAAK,CAAC,EAAG,CAAE,KAAM,CAAW,CAAC,EACvC,SAAU,EACV,WAAY,CAChB,CAAC,EAKE,IAAI,QAAyB,GAAY,CAC5C,EAAS,EACT,EAAS,KAAK,CAClB,CAAC,CACL,EAEA,QAAe,CACP,IAAW,QAAU,IAAW,YACpC,EAAU,GACV,EAAS,KACT,EAAS,KAAK,EAClB,CACJ,CACJ"}
1
+ {"version":3,"file":"media-recorder.cjs","names":["pickRecordingMimeType","preferred","type","createMediaRecorder","forced","options","negotiated","candidates","kind","recorder","stream","audioBitsPerSecond","videoBitsPerSecond","chunks","status","accumulatedMs","segmentStart","settle","discard","elapsed","event","onChunk","onError","durationMs","resolve","timesliceMs"],"sources":["../../src/capture/media-recorder.ts"],"sourcesContent":["/**\n * @tempest-limits function-lines — the engine behind both the audio and the video\n * recorder: MIME negotiation, the state machine MediaRecorder does not give you, and\n * the clock kept by hand because a fresh WebM reports no duration. The clock has to\n * pause and resume with the state machine, so they are one closure.\n */\n/** Lifecycle of a recording. */\nexport type MediaRecorderStatus = \"idle\" | \"recording\" | \"paused\" | \"stopped\";\n\n/** What a track carries — used only to word the errors this engine throws. */\nexport type MediaRecordingKind = \"audio\" | \"video\";\n\n/** A finished recording, whatever it was made of. */\nexport interface MediaRecording {\n /** The bytes. Wrap with `useObjectUrl` to play it, or POST it as-is. */\n blob: Blob;\n /** What the browser actually produced — not necessarily what you asked for. */\n mimeType: string;\n /** Recorded length, excluding time spent paused. */\n durationMs: number;\n}\n\n/** Options for {@link createMediaRecorder}. */\nexport interface MediaRecordingOptions {\n /**\n * Container candidates, best first. Required: this engine has no opinion about\n * codecs — the audio and video wrappers own that list.\n */\n candidates: readonly string[];\n /** Wording for the thrown messages (\"cannot record any supported *video* container\"). */\n kind: MediaRecordingKind;\n /** Force a container, bypassing the negotiation. Throws when unsupported. */\n mimeType?: string;\n /** Target audio bitrate. */\n audioBitsPerSecond?: number;\n /** Target video bitrate. Ignored by the browser on an audio-only stream. */\n videoBitsPerSecond?: number;\n /**\n * Emit a chunk every N ms through `onChunk`, for streaming upload.\n *\n * Without it the whole recording is buffered in memory until `stop()`.\n */\n timesliceMs?: number;\n /** Receives each chunk when `timesliceMs` is set. Chunks are **not** independently playable. */\n onChunk?: (chunk: Blob) => void;\n /** Recorder-level failure (device unplugged mid-recording, encoder error). */\n onError?: (error: unknown) => void;\n}\n\n/** Imperative recorder over one `MediaStream`. */\nexport interface MediaRecorderHandle {\n /** Begin recording. No-op when already recording or paused. */\n start: () => void;\n /** Pause. The clock stops; `durationMs` freezes. */\n pause: () => void;\n /** Resume after `pause()`. */\n resume: () => void;\n /** Stop and resolve with the assembled recording. */\n stop: () => Promise<MediaRecording>;\n /** Stop and throw the bytes away. */\n cancel: () => void;\n status: () => MediaRecorderStatus;\n /** Recorded length so far, excluding paused time. */\n durationMs: () => number;\n /** The negotiated container. */\n mimeType: string;\n}\n\n/**\n * First container in `preferred` the browser can actually produce, or `null`.\n *\n * @param preferred - Candidates, best first.\n * @returns A supported MIME type, or `null` when none is.\n */\nexport function pickRecordingMimeType(preferred: readonly string[]): string | null {\n if (typeof MediaRecorder === \"undefined\") return null;\n // Older WebViews ship `MediaRecorder` without the static probe. Assume the first\n // candidate rather than refusing outright — the constructor will tell us.\n if (typeof MediaRecorder.isTypeSupported !== \"function\") return preferred[0] ?? null;\n return preferred.find((type) => MediaRecorder.isTypeSupported(type)) ?? null;\n}\n\n/**\n * Wrap a `MediaStream` in a recorder with a real state machine and an honest clock.\n *\n * This is the engine behind both `createAudioRecorder` and `createVideoRecorder`; the\n * only thing it does not decide is which containers to try, because that is the one\n * part that genuinely differs between the two.\n *\n * Two things `MediaRecorder` does not give you:\n *\n * - **A duration.** It reports none, and the `Blob` has no reliable one either —\n * WebM written by `MediaRecorder` carries no duration in its header, which is why\n * `<audio>`/`<video>` shows `Infinity` for a fresh recording. So the clock is kept\n * here, and it subtracts paused time: a recorder that counts wall-clock through a\n * pause reports a 30-second note as two minutes.\n * - **A promise from `stop()`.** The last chunk arrives *after* `stop()` returns, in\n * a `dataavailable` event that fires before `onstop`. Assembling the blob in\n * `onstop` is the only point where every chunk is in hand.\n *\n * The stream is **not** owned here: `stop()` leaves the device open so a retake does\n * not need a second permission round-trip. Release it with the owning hook's `stop()`.\n *\n * @param stream - A live stream, from `getUserMedia` or `getDisplayMedia`.\n * @param options - See {@link MediaRecordingOptions}.\n * @returns The imperative recorder.\n * @throws When `MediaRecorder` is unavailable, or an explicit `mimeType` is unsupported.\n */\nexport function createMediaRecorder(\n stream: MediaStream,\n options: MediaRecordingOptions,\n): MediaRecorderHandle {\n const {\n candidates,\n kind,\n mimeType: forced,\n audioBitsPerSecond,\n videoBitsPerSecond,\n timesliceMs,\n onChunk,\n onError,\n } = options;\n\n if (typeof MediaRecorder === \"undefined\") {\n throw new Error(\"MediaRecorder is not available in this environment.\");\n }\n const negotiated = forced ?? pickRecordingMimeType(candidates);\n if (negotiated === null) {\n throw new Error(`This browser cannot record any supported ${kind} container.`);\n }\n if (\n forced !== undefined &&\n typeof MediaRecorder.isTypeSupported === \"function\" &&\n !MediaRecorder.isTypeSupported(forced)\n ) {\n throw new Error(`This browser cannot record \"${forced}\".`);\n }\n\n const recorder = new MediaRecorder(stream, {\n mimeType: negotiated,\n ...(audioBitsPerSecond !== undefined ? { audioBitsPerSecond } : {}),\n ...(videoBitsPerSecond !== undefined ? { videoBitsPerSecond } : {}),\n });\n\n let chunks: Blob[] = [];\n let status: MediaRecorderStatus = \"idle\";\n let accumulatedMs = 0;\n let segmentStart = 0;\n let settle: ((recording: MediaRecording) => void) | null = null;\n let discard = false;\n\n const elapsed = (): number =>\n accumulatedMs + (status === \"recording\" ? Date.now() - segmentStart : 0);\n\n recorder.ondataavailable = (event: BlobEvent): void => {\n if (event.data.size === 0) return;\n if (discard) return;\n chunks.push(event.data);\n onChunk?.(event.data);\n };\n\n recorder.onerror = (event: Event): void => {\n onError?.((event as unknown as { error?: unknown }).error ?? event);\n };\n\n recorder.onstop = (): void => {\n const durationMs = elapsed();\n status = \"stopped\";\n const resolve = settle;\n settle = null;\n if (discard) {\n chunks = [];\n return;\n }\n // `recorder.mimeType` is the source of truth: a browser handed\n // `video/webm;codecs=vp9,opus` may report plain `video/webm` back.\n const type = recorder.mimeType || negotiated;\n resolve?.({ blob: new Blob(chunks, { type }), mimeType: type, durationMs });\n chunks = [];\n };\n\n return {\n mimeType: negotiated,\n status: () => status,\n durationMs: elapsed,\n\n start(): void {\n if (status === \"recording\" || status === \"paused\") return;\n chunks = [];\n accumulatedMs = 0;\n discard = false;\n segmentStart = Date.now();\n status = \"recording\";\n if (timesliceMs !== undefined) recorder.start(timesliceMs);\n else recorder.start();\n },\n\n pause(): void {\n if (status !== \"recording\") return;\n accumulatedMs += Date.now() - segmentStart;\n status = \"paused\";\n recorder.pause();\n },\n\n resume(): void {\n if (status !== \"paused\") return;\n segmentStart = Date.now();\n status = \"recording\";\n recorder.resume();\n },\n\n stop(): Promise<MediaRecording> {\n if (status === \"idle\" || status === \"stopped\") {\n return Promise.resolve({\n blob: new Blob([], { type: negotiated }),\n mimeType: negotiated,\n durationMs: 0,\n });\n }\n // Stopping while paused needs no clock fix-up: `pause()` already folded\n // the last segment into `accumulatedMs`, and `elapsed()` adds nothing\n // while the status is not `\"recording\"`.\n return new Promise<MediaRecording>((resolve) => {\n settle = resolve;\n recorder.stop();\n });\n },\n\n cancel(): void {\n if (status === \"idle\" || status === \"stopped\") return;\n discard = true;\n settle = null;\n recorder.stop();\n },\n };\n}\n"],"mappings":"AA0EA,SAAgBA,EAAsB,EAA6C,CAK/E,OAJI,OAAO,cAAkB,IAAoB,KAG7C,OAAO,cAAc,iBAAoB,WACtCC,EAAU,KAAM,GAAS,cAAc,gBAAgBC,CAAI,CAAC,GAAK,KADRD,EAAU,IAAM,IAEpF,CA4BA,SAAgBE,EACZ,EACA,EACmB,CACnB,GAAM,CACF,aACA,OACA,SAAUC,EACV,qBACA,qBACA,cACA,UACA,WACAC,EAEJ,GAAI,OAAO,cAAkB,IACzB,MAAU,MAAM,qDAAqD,EAEzE,IAAMC,EAAaF,GAAUJ,EAAsBO,CAAU,EAC7D,GAAID,IAAe,KACf,MAAU,MAAM,4CAA4CE,EAAK,YAAY,EAEjF,GACIJ,IAAW,IAAA,IACX,OAAO,cAAc,iBAAoB,YACzC,CAAC,cAAc,gBAAgBA,CAAM,EAErC,MAAU,MAAM,+BAA+BA,EAAO,GAAG,EAG7D,IAAMK,EAAW,IAAI,cAAcC,EAAQ,CACvC,SAAUJ,EACV,GAAIK,IAAuB,IAAA,GAAqC,CAAC,EAA1B,CAAE,oBAAmB,EAC5D,GAAIC,IAAuB,IAAA,GAAqC,CAAC,EAA1B,CAAE,oBAAmB,CAChE,CAAC,EAEGC,EAAiB,CAAC,EAClBC,EAA8B,OAC9BC,EAAgB,EAChBC,EAAe,EACfC,EAAuD,KACvDC,EAAU,GAERC,MACFJ,GAAiBD,IAAW,YAAc,KAAK,IAAI,EAAIE,EAAe,GA6B1E,MA3BA,GAAS,gBAAmB,GAA2B,CAC/CI,EAAM,KAAK,OAAS,IACpBF,IACJL,EAAO,KAAKO,EAAM,IAAI,EACtBC,IAAUD,EAAM,IAAI,GACxB,EAEA,EAAS,QAAW,GAAuB,CACvCE,IAAWF,EAAyC,OAASA,CAAK,CACtE,EAEA,EAAS,WAAqB,CAC1B,IAAMG,EAAaJ,EAAQ,EAC3B,EAAS,UACT,IAAMK,EAAUP,EAEhB,GADA,EAAS,KACLC,EAAS,CACT,EAAS,CAAC,EACV,MACJ,CAGA,IAAMhB,EAAOO,EAAS,UAAYH,EAClCkB,IAAU,CAAE,KAAM,IAAI,KAAKX,EAAQ,CAAE,MAAK,CAAC,EAAG,SAAUX,EAAM,YAAW,CAAC,EAC1E,EAAS,CAAC,CACd,EAEO,CACH,SAAUI,EACV,WAAcQ,EACd,WAAYK,EAEZ,OAAc,CACNL,IAAW,aAAeA,IAAW,WACzC,EAAS,CAAC,EACV,EAAgB,EAChB,EAAU,GACV,EAAe,KAAK,IAAI,EACxB,EAAS,YACLW,IAAgB,IAAA,GACfhB,EAAS,MAAM,EADWA,EAAS,MAAMgB,CAAW,EAE7D,EAEA,OAAc,CACNX,IAAW,cACf,GAAiB,KAAK,IAAI,EAAIE,EAC9B,EAAS,SACTP,EAAS,MAAM,EACnB,EAEA,QAAe,CACPK,IAAW,WACf,EAAe,KAAK,IAAI,EACxB,EAAS,YACTL,EAAS,OAAO,EACpB,EAEA,MAAgC,CAW5B,OAVIK,IAAW,QAAUA,IAAW,UACzB,QAAQ,QAAQ,CACnB,KAAM,IAAI,KAAK,CAAC,EAAG,CAAE,KAAMR,CAAW,CAAC,EACvC,SAAUA,EACV,WAAY,CAChB,CAAC,EAKE,IAAI,QAAyB,GAAY,CAC5C,EAASkB,EACTf,EAAS,KAAK,CAClB,CAAC,CACL,EAEA,QAAe,CACPK,IAAW,QAAUA,IAAW,YACpC,EAAU,GACV,EAAS,KACTL,EAAS,KAAK,EAClB,CACJ,CACJ,C"}
@@ -1 +1 @@
1
- {"version":3,"file":"media-recorder.js","names":[],"sources":["../../src/capture/media-recorder.ts"],"sourcesContent":["/**\n * @tempest-limits function-lines — the engine behind both the audio and the video\n * recorder: MIME negotiation, the state machine MediaRecorder does not give you, and\n * the clock kept by hand because a fresh WebM reports no duration. The clock has to\n * pause and resume with the state machine, so they are one closure.\n */\n/** Lifecycle of a recording. */\nexport type MediaRecorderStatus = \"idle\" | \"recording\" | \"paused\" | \"stopped\";\n\n/** What a track carries — used only to word the errors this engine throws. */\nexport type MediaRecordingKind = \"audio\" | \"video\";\n\n/** A finished recording, whatever it was made of. */\nexport interface MediaRecording {\n /** The bytes. Wrap with `useObjectUrl` to play it, or POST it as-is. */\n blob: Blob;\n /** What the browser actually produced — not necessarily what you asked for. */\n mimeType: string;\n /** Recorded length, excluding time spent paused. */\n durationMs: number;\n}\n\n/** Options for {@link createMediaRecorder}. */\nexport interface MediaRecordingOptions {\n /**\n * Container candidates, best first. Required: this engine has no opinion about\n * codecs — the audio and video wrappers own that list.\n */\n candidates: readonly string[];\n /** Wording for the thrown messages (\"cannot record any supported *video* container\"). */\n kind: MediaRecordingKind;\n /** Force a container, bypassing the negotiation. Throws when unsupported. */\n mimeType?: string;\n /** Target audio bitrate. */\n audioBitsPerSecond?: number;\n /** Target video bitrate. Ignored by the browser on an audio-only stream. */\n videoBitsPerSecond?: number;\n /**\n * Emit a chunk every N ms through `onChunk`, for streaming upload.\n *\n * Without it the whole recording is buffered in memory until `stop()`.\n */\n timesliceMs?: number;\n /** Receives each chunk when `timesliceMs` is set. Chunks are **not** independently playable. */\n onChunk?: (chunk: Blob) => void;\n /** Recorder-level failure (device unplugged mid-recording, encoder error). */\n onError?: (error: unknown) => void;\n}\n\n/** Imperative recorder over one `MediaStream`. */\nexport interface MediaRecorderHandle {\n /** Begin recording. No-op when already recording or paused. */\n start: () => void;\n /** Pause. The clock stops; `durationMs` freezes. */\n pause: () => void;\n /** Resume after `pause()`. */\n resume: () => void;\n /** Stop and resolve with the assembled recording. */\n stop: () => Promise<MediaRecording>;\n /** Stop and throw the bytes away. */\n cancel: () => void;\n status: () => MediaRecorderStatus;\n /** Recorded length so far, excluding paused time. */\n durationMs: () => number;\n /** The negotiated container. */\n mimeType: string;\n}\n\n/**\n * First container in `preferred` the browser can actually produce, or `null`.\n *\n * @param preferred - Candidates, best first.\n * @returns A supported MIME type, or `null` when none is.\n */\nexport function pickRecordingMimeType(preferred: readonly string[]): string | null {\n if (typeof MediaRecorder === \"undefined\") return null;\n // Older WebViews ship `MediaRecorder` without the static probe. Assume the first\n // candidate rather than refusing outright — the constructor will tell us.\n if (typeof MediaRecorder.isTypeSupported !== \"function\") return preferred[0] ?? null;\n return preferred.find((type) => MediaRecorder.isTypeSupported(type)) ?? null;\n}\n\n/**\n * Wrap a `MediaStream` in a recorder with a real state machine and an honest clock.\n *\n * This is the engine behind both `createAudioRecorder` and `createVideoRecorder`; the\n * only thing it does not decide is which containers to try, because that is the one\n * part that genuinely differs between the two.\n *\n * Two things `MediaRecorder` does not give you:\n *\n * - **A duration.** It reports none, and the `Blob` has no reliable one either —\n * WebM written by `MediaRecorder` carries no duration in its header, which is why\n * `<audio>`/`<video>` shows `Infinity` for a fresh recording. So the clock is kept\n * here, and it subtracts paused time: a recorder that counts wall-clock through a\n * pause reports a 30-second note as two minutes.\n * - **A promise from `stop()`.** The last chunk arrives *after* `stop()` returns, in\n * a `dataavailable` event that fires before `onstop`. Assembling the blob in\n * `onstop` is the only point where every chunk is in hand.\n *\n * The stream is **not** owned here: `stop()` leaves the device open so a retake does\n * not need a second permission round-trip. Release it with the owning hook's `stop()`.\n *\n * @param stream - A live stream, from `getUserMedia` or `getDisplayMedia`.\n * @param options - See {@link MediaRecordingOptions}.\n * @returns The imperative recorder.\n * @throws When `MediaRecorder` is unavailable, or an explicit `mimeType` is unsupported.\n */\nexport function createMediaRecorder(\n stream: MediaStream,\n options: MediaRecordingOptions,\n): MediaRecorderHandle {\n const {\n candidates,\n kind,\n mimeType: forced,\n audioBitsPerSecond,\n videoBitsPerSecond,\n timesliceMs,\n onChunk,\n onError,\n } = options;\n\n if (typeof MediaRecorder === \"undefined\") {\n throw new Error(\"MediaRecorder is not available in this environment.\");\n }\n const negotiated = forced ?? pickRecordingMimeType(candidates);\n if (negotiated === null) {\n throw new Error(`This browser cannot record any supported ${kind} container.`);\n }\n if (\n forced !== undefined &&\n typeof MediaRecorder.isTypeSupported === \"function\" &&\n !MediaRecorder.isTypeSupported(forced)\n ) {\n throw new Error(`This browser cannot record \"${forced}\".`);\n }\n\n const recorder = new MediaRecorder(stream, {\n mimeType: negotiated,\n ...(audioBitsPerSecond !== undefined ? { audioBitsPerSecond } : {}),\n ...(videoBitsPerSecond !== undefined ? { videoBitsPerSecond } : {}),\n });\n\n let chunks: Blob[] = [];\n let status: MediaRecorderStatus = \"idle\";\n let accumulatedMs = 0;\n let segmentStart = 0;\n let settle: ((recording: MediaRecording) => void) | null = null;\n let discard = false;\n\n const elapsed = (): number =>\n accumulatedMs + (status === \"recording\" ? Date.now() - segmentStart : 0);\n\n recorder.ondataavailable = (event: BlobEvent): void => {\n if (event.data.size === 0) return;\n if (discard) return;\n chunks.push(event.data);\n onChunk?.(event.data);\n };\n\n recorder.onerror = (event: Event): void => {\n onError?.((event as unknown as { error?: unknown }).error ?? event);\n };\n\n recorder.onstop = (): void => {\n const durationMs = elapsed();\n status = \"stopped\";\n const resolve = settle;\n settle = null;\n if (discard) {\n chunks = [];\n return;\n }\n // `recorder.mimeType` is the source of truth: a browser handed\n // `video/webm;codecs=vp9,opus` may report plain `video/webm` back.\n const type = recorder.mimeType || negotiated;\n resolve?.({ blob: new Blob(chunks, { type }), mimeType: type, durationMs });\n chunks = [];\n };\n\n return {\n mimeType: negotiated,\n status: () => status,\n durationMs: elapsed,\n\n start(): void {\n if (status === \"recording\" || status === \"paused\") return;\n chunks = [];\n accumulatedMs = 0;\n discard = false;\n segmentStart = Date.now();\n status = \"recording\";\n if (timesliceMs !== undefined) recorder.start(timesliceMs);\n else recorder.start();\n },\n\n pause(): void {\n if (status !== \"recording\") return;\n accumulatedMs += Date.now() - segmentStart;\n status = \"paused\";\n recorder.pause();\n },\n\n resume(): void {\n if (status !== \"paused\") return;\n segmentStart = Date.now();\n status = \"recording\";\n recorder.resume();\n },\n\n stop(): Promise<MediaRecording> {\n if (status === \"idle\" || status === \"stopped\") {\n return Promise.resolve({\n blob: new Blob([], { type: negotiated }),\n mimeType: negotiated,\n durationMs: 0,\n });\n }\n // Stopping while paused needs no clock fix-up: `pause()` already folded\n // the last segment into `accumulatedMs`, and `elapsed()` adds nothing\n // while the status is not `\"recording\"`.\n return new Promise<MediaRecording>((resolve) => {\n settle = resolve;\n recorder.stop();\n });\n },\n\n cancel(): void {\n if (status === \"idle\" || status === \"stopped\") return;\n discard = true;\n settle = null;\n recorder.stop();\n },\n };\n}\n"],"mappings":";AA0EA,SAAgB,EAAsB,GAA6C;CAK/E,OAJI,OAAO,gBAAkB,MAAoB,OAG7C,OAAO,cAAc,mBAAoB,aACtC,EAAU,MAAM,MAAS,cAAc,gBAAgB,CAAI,CAAC,KAAK,OADR,EAAU,MAAM;AAEpF;AA4BA,SAAgB,EACZ,GACA,GACmB;CACnB,IAAM,EACF,eACA,SACA,UAAU,GACV,uBACA,uBACA,gBACA,YACA,eACA;CAEJ,IAAI,OAAO,gBAAkB,KACzB,MAAU,MAAM,qDAAqD;CAEzE,IAAM,IAAa,KAAU,EAAsB,CAAU;CAC7D,IAAI,MAAe,MACf,MAAU,MAAM,4CAA4C,EAAK,YAAY;CAEjF,IACI,MAAW,KAAA,KACX,OAAO,cAAc,mBAAoB,cACzC,CAAC,cAAc,gBAAgB,CAAM,GAErC,MAAU,MAAM,+BAA+B,EAAO,GAAG;CAG7D,IAAM,IAAW,IAAI,cAAc,GAAQ;EACvC,UAAU;EACV,GAAI,MAAuB,KAAA,IAAqC,CAAC,IAA1B,EAAE,sBAAmB;EAC5D,GAAI,MAAuB,KAAA,IAAqC,CAAC,IAA1B,EAAE,sBAAmB;CAChE,CAAC,GAEG,IAAiB,CAAC,GAClB,IAA8B,QAC9B,IAAgB,GAChB,IAAe,GACf,IAAuD,MACvD,IAAU,IAER,UACF,KAAiB,MAAW,cAAc,KAAK,IAAI,IAAI,IAAe;CA6B1E,OA3BA,EAAS,mBAAmB,MAA2B;EAC/C,EAAM,KAAK,SAAS,MACpB,MACJ,EAAO,KAAK,EAAM,IAAI,GACtB,IAAU,EAAM,IAAI;CACxB,GAEA,EAAS,WAAW,MAAuB;EACvC,IAAW,EAAyC,SAAS,CAAK;CACtE,GAEA,EAAS,eAAqB;EAC1B,IAAM,IAAa,EAAQ;EAC3B,IAAS;EACT,IAAM,IAAU;EAEhB,IADA,IAAS,MACL,GAAS;GACT,IAAS,CAAC;GACV;EACJ;EAGA,IAAM,IAAO,EAAS,YAAY;EAElC,AADA,IAAU;GAAE,MAAM,IAAI,KAAK,GAAQ,EAAE,QAAK,CAAC;GAAG,UAAU;GAAM;EAAW,CAAC,GAC1E,IAAS,CAAC;CACd,GAEO;EACH,UAAU;EACV,cAAc;EACd,YAAY;EAEZ,QAAc;GACN,MAAW,eAAe,MAAW,aACzC,IAAS,CAAC,GACV,IAAgB,GAChB,IAAU,IACV,IAAe,KAAK,IAAI,GACxB,IAAS,aACL,MAAgB,KAAA,IACf,EAAS,MAAM,IADW,EAAS,MAAM,CAAW;EAE7D;EAEA,QAAc;GACN,MAAW,gBACf,KAAiB,KAAK,IAAI,IAAI,GAC9B,IAAS,UACT,EAAS,MAAM;EACnB;EAEA,SAAe;GACP,MAAW,aACf,IAAe,KAAK,IAAI,GACxB,IAAS,aACT,EAAS,OAAO;EACpB;EAEA,OAAgC;GAW5B,OAVI,MAAW,UAAU,MAAW,YACzB,QAAQ,QAAQ;IACnB,MAAM,IAAI,KAAK,CAAC,GAAG,EAAE,MAAM,EAAW,CAAC;IACvC,UAAU;IACV,YAAY;GAChB,CAAC,IAKE,IAAI,SAAyB,MAAY;IAE5C,AADA,IAAS,GACT,EAAS,KAAK;GAClB,CAAC;EACL;EAEA,SAAe;GACP,MAAW,UAAU,MAAW,cACpC,IAAU,IACV,IAAS,MACT,EAAS,KAAK;EAClB;CACJ;AACJ"}
1
+ {"version":3,"file":"media-recorder.js","names":["pickRecordingMimeType","preferred","type","createMediaRecorder","forced","options","negotiated","candidates","kind","recorder","stream","audioBitsPerSecond","videoBitsPerSecond","chunks","status","accumulatedMs","segmentStart","settle","discard","elapsed","event","onChunk","durationMs","resolve","timesliceMs"],"sources":["../../src/capture/media-recorder.ts"],"sourcesContent":["/**\n * @tempest-limits function-lines — the engine behind both the audio and the video\n * recorder: MIME negotiation, the state machine MediaRecorder does not give you, and\n * the clock kept by hand because a fresh WebM reports no duration. The clock has to\n * pause and resume with the state machine, so they are one closure.\n */\n/** Lifecycle of a recording. */\nexport type MediaRecorderStatus = \"idle\" | \"recording\" | \"paused\" | \"stopped\";\n\n/** What a track carries — used only to word the errors this engine throws. */\nexport type MediaRecordingKind = \"audio\" | \"video\";\n\n/** A finished recording, whatever it was made of. */\nexport interface MediaRecording {\n /** The bytes. Wrap with `useObjectUrl` to play it, or POST it as-is. */\n blob: Blob;\n /** What the browser actually produced — not necessarily what you asked for. */\n mimeType: string;\n /** Recorded length, excluding time spent paused. */\n durationMs: number;\n}\n\n/** Options for {@link createMediaRecorder}. */\nexport interface MediaRecordingOptions {\n /**\n * Container candidates, best first. Required: this engine has no opinion about\n * codecs — the audio and video wrappers own that list.\n */\n candidates: readonly string[];\n /** Wording for the thrown messages (\"cannot record any supported *video* container\"). */\n kind: MediaRecordingKind;\n /** Force a container, bypassing the negotiation. Throws when unsupported. */\n mimeType?: string;\n /** Target audio bitrate. */\n audioBitsPerSecond?: number;\n /** Target video bitrate. Ignored by the browser on an audio-only stream. */\n videoBitsPerSecond?: number;\n /**\n * Emit a chunk every N ms through `onChunk`, for streaming upload.\n *\n * Without it the whole recording is buffered in memory until `stop()`.\n */\n timesliceMs?: number;\n /** Receives each chunk when `timesliceMs` is set. Chunks are **not** independently playable. */\n onChunk?: (chunk: Blob) => void;\n /** Recorder-level failure (device unplugged mid-recording, encoder error). */\n onError?: (error: unknown) => void;\n}\n\n/** Imperative recorder over one `MediaStream`. */\nexport interface MediaRecorderHandle {\n /** Begin recording. No-op when already recording or paused. */\n start: () => void;\n /** Pause. The clock stops; `durationMs` freezes. */\n pause: () => void;\n /** Resume after `pause()`. */\n resume: () => void;\n /** Stop and resolve with the assembled recording. */\n stop: () => Promise<MediaRecording>;\n /** Stop and throw the bytes away. */\n cancel: () => void;\n status: () => MediaRecorderStatus;\n /** Recorded length so far, excluding paused time. */\n durationMs: () => number;\n /** The negotiated container. */\n mimeType: string;\n}\n\n/**\n * First container in `preferred` the browser can actually produce, or `null`.\n *\n * @param preferred - Candidates, best first.\n * @returns A supported MIME type, or `null` when none is.\n */\nexport function pickRecordingMimeType(preferred: readonly string[]): string | null {\n if (typeof MediaRecorder === \"undefined\") return null;\n // Older WebViews ship `MediaRecorder` without the static probe. Assume the first\n // candidate rather than refusing outright — the constructor will tell us.\n if (typeof MediaRecorder.isTypeSupported !== \"function\") return preferred[0] ?? null;\n return preferred.find((type) => MediaRecorder.isTypeSupported(type)) ?? null;\n}\n\n/**\n * Wrap a `MediaStream` in a recorder with a real state machine and an honest clock.\n *\n * This is the engine behind both `createAudioRecorder` and `createVideoRecorder`; the\n * only thing it does not decide is which containers to try, because that is the one\n * part that genuinely differs between the two.\n *\n * Two things `MediaRecorder` does not give you:\n *\n * - **A duration.** It reports none, and the `Blob` has no reliable one either —\n * WebM written by `MediaRecorder` carries no duration in its header, which is why\n * `<audio>`/`<video>` shows `Infinity` for a fresh recording. So the clock is kept\n * here, and it subtracts paused time: a recorder that counts wall-clock through a\n * pause reports a 30-second note as two minutes.\n * - **A promise from `stop()`.** The last chunk arrives *after* `stop()` returns, in\n * a `dataavailable` event that fires before `onstop`. Assembling the blob in\n * `onstop` is the only point where every chunk is in hand.\n *\n * The stream is **not** owned here: `stop()` leaves the device open so a retake does\n * not need a second permission round-trip. Release it with the owning hook's `stop()`.\n *\n * @param stream - A live stream, from `getUserMedia` or `getDisplayMedia`.\n * @param options - See {@link MediaRecordingOptions}.\n * @returns The imperative recorder.\n * @throws When `MediaRecorder` is unavailable, or an explicit `mimeType` is unsupported.\n */\nexport function createMediaRecorder(\n stream: MediaStream,\n options: MediaRecordingOptions,\n): MediaRecorderHandle {\n const {\n candidates,\n kind,\n mimeType: forced,\n audioBitsPerSecond,\n videoBitsPerSecond,\n timesliceMs,\n onChunk,\n onError,\n } = options;\n\n if (typeof MediaRecorder === \"undefined\") {\n throw new Error(\"MediaRecorder is not available in this environment.\");\n }\n const negotiated = forced ?? pickRecordingMimeType(candidates);\n if (negotiated === null) {\n throw new Error(`This browser cannot record any supported ${kind} container.`);\n }\n if (\n forced !== undefined &&\n typeof MediaRecorder.isTypeSupported === \"function\" &&\n !MediaRecorder.isTypeSupported(forced)\n ) {\n throw new Error(`This browser cannot record \"${forced}\".`);\n }\n\n const recorder = new MediaRecorder(stream, {\n mimeType: negotiated,\n ...(audioBitsPerSecond !== undefined ? { audioBitsPerSecond } : {}),\n ...(videoBitsPerSecond !== undefined ? { videoBitsPerSecond } : {}),\n });\n\n let chunks: Blob[] = [];\n let status: MediaRecorderStatus = \"idle\";\n let accumulatedMs = 0;\n let segmentStart = 0;\n let settle: ((recording: MediaRecording) => void) | null = null;\n let discard = false;\n\n const elapsed = (): number =>\n accumulatedMs + (status === \"recording\" ? Date.now() - segmentStart : 0);\n\n recorder.ondataavailable = (event: BlobEvent): void => {\n if (event.data.size === 0) return;\n if (discard) return;\n chunks.push(event.data);\n onChunk?.(event.data);\n };\n\n recorder.onerror = (event: Event): void => {\n onError?.((event as unknown as { error?: unknown }).error ?? event);\n };\n\n recorder.onstop = (): void => {\n const durationMs = elapsed();\n status = \"stopped\";\n const resolve = settle;\n settle = null;\n if (discard) {\n chunks = [];\n return;\n }\n // `recorder.mimeType` is the source of truth: a browser handed\n // `video/webm;codecs=vp9,opus` may report plain `video/webm` back.\n const type = recorder.mimeType || negotiated;\n resolve?.({ blob: new Blob(chunks, { type }), mimeType: type, durationMs });\n chunks = [];\n };\n\n return {\n mimeType: negotiated,\n status: () => status,\n durationMs: elapsed,\n\n start(): void {\n if (status === \"recording\" || status === \"paused\") return;\n chunks = [];\n accumulatedMs = 0;\n discard = false;\n segmentStart = Date.now();\n status = \"recording\";\n if (timesliceMs !== undefined) recorder.start(timesliceMs);\n else recorder.start();\n },\n\n pause(): void {\n if (status !== \"recording\") return;\n accumulatedMs += Date.now() - segmentStart;\n status = \"paused\";\n recorder.pause();\n },\n\n resume(): void {\n if (status !== \"paused\") return;\n segmentStart = Date.now();\n status = \"recording\";\n recorder.resume();\n },\n\n stop(): Promise<MediaRecording> {\n if (status === \"idle\" || status === \"stopped\") {\n return Promise.resolve({\n blob: new Blob([], { type: negotiated }),\n mimeType: negotiated,\n durationMs: 0,\n });\n }\n // Stopping while paused needs no clock fix-up: `pause()` already folded\n // the last segment into `accumulatedMs`, and `elapsed()` adds nothing\n // while the status is not `\"recording\"`.\n return new Promise<MediaRecording>((resolve) => {\n settle = resolve;\n recorder.stop();\n });\n },\n\n cancel(): void {\n if (status === \"idle\" || status === \"stopped\") return;\n discard = true;\n settle = null;\n recorder.stop();\n },\n };\n}\n"],"mappings":";AA0EA,SAAgBA,EAAsB,GAA6C;CAK/E,OAJI,OAAO,gBAAkB,MAAoB,OAG7C,OAAO,cAAc,mBAAoB,aACtCC,EAAU,MAAM,MAAS,cAAc,gBAAgBC,CAAI,CAAC,KAAK,OADRD,EAAU,MAAM;AAEpF;AA4BA,SAAgBE,EACZ,GACA,GACmB;CACnB,IAAM,EACF,eACA,SACA,UAAUC,GACV,uBACA,uBACA,gBACA,YACA,eACAC;CAEJ,IAAI,OAAO,gBAAkB,KACzB,MAAU,MAAM,qDAAqD;CAEzE,IAAMC,IAAaF,KAAUJ,EAAsBO,CAAU;CAC7D,IAAID,MAAe,MACf,MAAU,MAAM,4CAA4CE,EAAK,YAAY;CAEjF,IACIJ,MAAW,KAAA,KACX,OAAO,cAAc,mBAAoB,cACzC,CAAC,cAAc,gBAAgBA,CAAM,GAErC,MAAU,MAAM,+BAA+BA,EAAO,GAAG;CAG7D,IAAMK,IAAW,IAAI,cAAcC,GAAQ;EACvC,UAAUJ;EACV,GAAIK,MAAuB,KAAA,IAAqC,CAAC,IAA1B,EAAE,sBAAmB;EAC5D,GAAIC,MAAuB,KAAA,IAAqC,CAAC,IAA1B,EAAE,sBAAmB;CAChE,CAAC,GAEGC,IAAiB,CAAC,GAClBC,IAA8B,QAC9BC,IAAgB,GAChBC,IAAe,GACfC,IAAuD,MACvDC,IAAU,IAERC,UACFJ,KAAiBD,MAAW,cAAc,KAAK,IAAI,IAAIE,IAAe;CA6B1E,OA3BA,EAAS,mBAAmB,MAA2B;EACnD,AAAII,EAAM,KAAK,SAAS,MACpBF,MACJL,EAAO,KAAKO,EAAM,IAAI,GACtBC,IAAUD,EAAM,IAAI;CACxB,GAEA,EAAS,WAAW,MAAuB;EACvC,IAAWA,EAAyC,SAASA,CAAK;CACtE,GAEA,EAAS,eAAqB;EAC1B,IAAME,IAAaH,EAAQ;EAC3B,IAAS;EACT,IAAMI,IAAUN;EAEhB,IADA,IAAS,MACLC,GAAS;GACT,IAAS,CAAC;GACV;EACJ;EAGA,IAAMhB,IAAOO,EAAS,YAAYH;EAElC,AADAiB,IAAU;GAAE,MAAM,IAAI,KAAKV,GAAQ,EAAE,QAAK,CAAC;GAAG,UAAUX;GAAM;EAAW,CAAC,GAC1E,IAAS,CAAC;CACd,GAEO;EACH,UAAUI;EACV,cAAcQ;EACd,YAAYK;EAEZ,QAAc;GACV,AAAIL,MAAW,eAAeA,MAAW,aACzC,IAAS,CAAC,GACV,IAAgB,GAChB,IAAU,IACV,IAAe,KAAK,IAAI,GACxB,IAAS,aACLU,MAAgB,KAAA,IACff,EAAS,MAAM,IADWA,EAAS,MAAMe,CAAW;EAE7D;EAEA,QAAc;GACV,AAAIV,MAAW,gBACf,KAAiB,KAAK,IAAI,IAAIE,GAC9B,IAAS,UACTP,EAAS,MAAM;EACnB;EAEA,SAAe;GACX,AAAIK,MAAW,aACf,IAAe,KAAK,IAAI,GACxB,IAAS,aACTL,EAAS,OAAO;EACpB;EAEA,OAAgC;GAW5B,OAVIK,MAAW,UAAUA,MAAW,YACzB,QAAQ,QAAQ;IACnB,MAAM,IAAI,KAAK,CAAC,GAAG,EAAE,MAAMR,EAAW,CAAC;IACvC,UAAUA;IACV,YAAY;GAChB,CAAC,IAKE,IAAI,SAAyB,MAAY;IAE5C,AADA,IAASiB,GACTd,EAAS,KAAK;GAClB,CAAC;EACL;EAEA,SAAe;GACX,AAAIK,MAAW,UAAUA,MAAW,cACpC,IAAU,IACV,IAAS,MACTL,EAAS,KAAK;EAClB;CACJ;AACJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-barcode-scanner.cjs","names":[],"sources":["../../src/capture/use-barcode-scanner.ts"],"sourcesContent":["/**\n * @tempest-limits hook-lines — the scan loop, the repeat suppression window and the\n * torch control share the same track and the same interval handle; splitting them\n * would leave a timer running against a track another hook stopped.\n */\nimport { useEffect, useRef, useState, type RefObject } from \"react\";\n\nimport { useStableCallback } from \"@/hooks/use-stable-callback\";\nimport {\n useCameraStream,\n type CameraStreamError,\n type CameraStreamStatus,\n} from \"@/vision/use-camera-stream\";\n\nimport {\n createBarcodeDetector,\n getSupportedBarcodeFormats,\n isBarcodeDetectionSupported,\n normalizeBarcode,\n DEFAULT_BARCODE_FORMATS,\n type BarcodeDetectorLike,\n type BarcodeFormat,\n type BarcodeScanResult,\n} from \"./barcode\";\nimport { useTorch, type UseTorchResult } from \"./use-torch\";\n\n/** Options for {@link useBarcodeScanner}. */\nexport interface UseBarcodeScannerOptions {\n /** Symbologies to look for. Defaults to {@link DEFAULT_BARCODE_FORMATS}. */\n formats?: readonly BarcodeFormat[];\n /** Called for every accepted read — that is, after repeat suppression. */\n onScan?: (result: BarcodeScanResult) => void;\n /**\n * How often a frame is examined, in ms. Default 200.\n *\n * Not `requestAnimationFrame`: decoding is 10–40 ms of main-thread work on a\n * phone, so running it per frame competes with the preview it is reading from and\n * makes the video stutter. Five looks per second is faster than a human can aim.\n */\n intervalMs?: number;\n /**\n * Ignore the **same** value again for this long, in ms. Default 2500.\n *\n * A symbol stays in frame for as long as the user holds the camera there, so a\n * scanner without this fires the same code five times a second — which, wired to\n * \"add item to cart\", is a bug the user pays for. A *different* value is never\n * suppressed.\n */\n repeatDelayMs?: number;\n /** Stop looking without releasing the camera — a confirmation sheet is open. */\n paused?: boolean;\n /**\n * A decoder to use instead of the native one.\n *\n * The way to support Safari and Firefox: hand in a polyfill and everything else\n * here works unchanged. See {@link isBarcodeDetectionSupported} for why the SDK\n * does not bundle one.\n */\n detector?: BarcodeDetectorLike;\n /** Camera constraints, forwarded to `useCameraStream`. Defaults to the rear camera. */\n constraints?: MediaStreamConstraints;\n /**\n * A frame the engine refused to decode.\n *\n * Not \"nothing found\" — that resolves to an empty list and is the normal case.\n * This is the engine itself failing, which the loop survives because it is\n * usually transient (a frame arriving between two resolutions).\n */\n onError?: (error: unknown) => void;\n}\n\n/** Value returned by {@link useBarcodeScanner}. */\nexport interface UseBarcodeScannerResult {\n /** Attach to a `<video ref={…} muted playsInline />`. */\n videoRef: RefObject<HTMLVideoElement | null>;\n /** Camera lifecycle. `\"ready\"` means the preview is running. */\n status: CameraStreamStatus;\n /** Classified camera error, or `null`. */\n error: CameraStreamError | null;\n /** `false` when there is no decoder — no native API and none injected. */\n supported: boolean;\n /**\n * Formats actually in use: the requested ones intersected with what the engine\n * reports. Empty while the probe is in flight, or when nothing matched.\n */\n formats: readonly BarcodeFormat[];\n /** Whether the detect loop is running right now. */\n scanning: boolean;\n /** The most recent accepted read, or `null`. */\n result: BarcodeScanResult | null;\n /** The LED torch of this camera, when it has one. */\n torch: UseTorchResult;\n /** Re-open the camera after an error (the user changed the permission). */\n retry: () => void;\n}\n\n/** A video is decodable once it has data for the current frame and a real size. */\nfunction frameIsReady(video: HTMLVideoElement): boolean {\n return video.readyState >= 2 && video.videoWidth > 0 && video.videoHeight > 0;\n}\n\n/**\n * Read barcodes and QR codes from the camera.\n *\n * The camera and its classified errors come from `useCameraStream`, so this hook is\n * only the decoding half: it drives a `BarcodeDetector` over the preview on an\n * interval, suppresses the same value repeating, and exposes the torch.\n *\n * **Mounting this opens the camera.** It inherits that from `useCameraStream`, which\n * acquires on mount — so mount it *after* the user asks to scan (a button that reveals\n * the scanner), never on a page that merely contains one. A permission prompt nobody\n * provoked is the most reliable way to earn a permanent block, after which\n * `getUserMedia` rejects without ever prompting again.\n *\n * `supported` deserves a branch in the UI, not an assertion: `BarcodeDetector` is\n * Chromium-only and missing on Windows/Linux desktop, Firefox and everything on iOS.\n * Inject a `detector` to cover those, or tell the user to type the code.\n *\n * @param options - See {@link UseBarcodeScannerOptions}.\n * @returns The camera plumbing plus the scan state.\n *\n * @example\n * const scanner = useBarcodeScanner({\n * formats: [\"ean_13\"],\n * onScan: ({ rawValue }) => addToCart(rawValue),\n * });\n * return <video ref={scanner.videoRef} muted playsInline />;\n */\nexport function useBarcodeScanner(options: UseBarcodeScannerOptions = {}): UseBarcodeScannerResult {\n const {\n formats: requested = DEFAULT_BARCODE_FORMATS,\n onScan,\n intervalMs = 200,\n repeatDelayMs = 2500,\n paused = false,\n detector: injected,\n constraints,\n onError,\n } = options;\n\n const [supported, setSupported] = useState(\n () => injected !== undefined || isBarcodeDetectionSupported(),\n );\n\n /**\n * No decoder, no camera.\n *\n * Opening the camera only to report \"this browser cannot decode barcodes\" spends a\n * permission prompt on nothing — and a refusal is permanent, so it also spends the\n * *next* feature that needs the camera.\n */\n const camera = useCameraStream({ constraints, enabled: supported });\n const torch = useTorch(camera.stream);\n\n const [formats, setFormats] = useState<readonly BarcodeFormat[]>(\n injected !== undefined ? requested : [],\n );\n const [scanning, setScanning] = useState(false);\n const [result, setResult] = useState<BarcodeScanResult | null>(null);\n\n const detectorRef = useRef<BarcodeDetectorLike | null>(null);\n const lastValue = useRef<string | null>(null);\n const lastAt = useRef(0);\n\n const emitScan = useStableCallback((scan: BarcodeScanResult) => onScan?.(scan));\n const emitError = useStableCallback((error: unknown) => onError?.(error));\n\n const requestedKey = requested.join(\",\");\n\n /**\n * Resolve which formats the engine will take, then build the detector.\n *\n * The intersection is not defensive coding: `new BarcodeDetector({ formats })`\n * throws `NotSupportedError` when any entry is unknown to the platform decoder, and\n * that list differs between two Chromium builds on two operating systems. Asking\n * for the intersection is the only way one call site works everywhere.\n */\n useEffect(() => {\n if (injected) {\n detectorRef.current = injected;\n setSupported(true);\n setFormats(requested);\n return;\n }\n if (!isBarcodeDetectionSupported()) {\n detectorRef.current = null;\n setSupported(false);\n setFormats([]);\n return;\n }\n let cancelled = false;\n void getSupportedBarcodeFormats().then((available) => {\n if (cancelled) return;\n const usable =\n available.length === 0\n ? requested\n : requested.filter((format) => available.includes(format));\n const detector = usable.length > 0 ? createBarcodeDetector(usable) : null;\n detectorRef.current = detector;\n setFormats(detector ? usable : []);\n setSupported(detector !== null);\n });\n return () => {\n cancelled = true;\n };\n // `requestedKey` stands in for the array identity, so a caller passing an\n // inline `formats={[\"ean_13\"]}` does not rebuild the detector every render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [injected, requestedKey]);\n\n /**\n * Look at a frame every `intervalMs`, and never overlap two looks.\n *\n * The loop re-arms itself *after* each `detect()` settles rather than running on a\n * fixed `setInterval`: decoding sometimes takes longer than the interval, and an\n * interval would then queue calls faster than the engine drains them until the tab\n * is unusable.\n */\n useEffect(() => {\n if (!supported || paused || camera.status !== \"ready\") {\n setScanning(false);\n return;\n }\n let stopped = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n setScanning(true);\n\n const accept = (scan: BarcodeScanResult): void => {\n const now = Date.now();\n const isRepeat =\n scan.rawValue === lastValue.current && now - lastAt.current < repeatDelayMs;\n if (isRepeat) return;\n lastValue.current = scan.rawValue;\n lastAt.current = now;\n setResult(scan);\n emitScan(scan);\n };\n\n const look = async (): Promise<void> => {\n const video = camera.videoRef.current;\n const detector = detectorRef.current;\n if (!video || !detector || !frameIsReady(video)) return;\n try {\n const found = await detector.detect(video);\n if (stopped) return;\n for (const raw of found) {\n const scan = normalizeBarcode(raw);\n if (scan.rawValue !== \"\") accept(scan);\n }\n } catch (error) {\n if (!stopped) emitError(error);\n }\n };\n\n const tick = (): void => {\n void look().finally(() => {\n if (!stopped) timer = setTimeout(tick, intervalMs);\n });\n };\n tick();\n\n return () => {\n stopped = true;\n if (timer !== undefined) clearTimeout(timer);\n setScanning(false);\n };\n }, [\n supported,\n paused,\n camera.status,\n camera.videoRef,\n intervalMs,\n repeatDelayMs,\n emitScan,\n emitError,\n ]);\n\n return {\n videoRef: camera.videoRef,\n status: camera.status,\n error: camera.error,\n supported,\n formats,\n scanning,\n result,\n torch,\n retry: camera.retry,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-barcode-scanner.cjs","names":["DEFAULT_BARCODE_FORMATS","useState","isBarcodeDetectionSupported","useCameraStream","useTorch","useRef","useStableCallback","getSupportedBarcodeFormats","createBarcodeDetector","normalizeBarcode","require_use_stable_callback","require_use_camera_stream","require_barcode","require_use_torch","react","frameIsReady","video","useBarcodeScanner","requested","injected","options","supported","setSupported","camera","torch","formats","setFormats","scanning","setScanning","result","setResult","detectorRef","lastValue","lastAt","emitScan","onScan","scan","emitError","onError","error","requestedKey","cancelled","usable","available","format","detector","paused","stopped","timer","accept","now","repeatDelayMs","look","found","raw","tick","intervalMs"],"sources":["../../src/capture/use-barcode-scanner.ts"],"sourcesContent":["/**\n * @tempest-limits hook-lines — the scan loop, the repeat suppression window and the\n * torch control share the same track and the same interval handle; splitting them\n * would leave a timer running against a track another hook stopped.\n */\nimport { useEffect, useRef, useState, type RefObject } from \"react\";\n\nimport { useStableCallback } from \"@/hooks/use-stable-callback\";\nimport {\n useCameraStream,\n type CameraStreamError,\n type CameraStreamStatus,\n} from \"@/vision/use-camera-stream\";\n\nimport {\n createBarcodeDetector,\n getSupportedBarcodeFormats,\n isBarcodeDetectionSupported,\n normalizeBarcode,\n DEFAULT_BARCODE_FORMATS,\n type BarcodeDetectorLike,\n type BarcodeFormat,\n type BarcodeScanResult,\n} from \"./barcode\";\nimport { useTorch, type UseTorchResult } from \"./use-torch\";\n\n/** Options for {@link useBarcodeScanner}. */\nexport interface UseBarcodeScannerOptions {\n /** Symbologies to look for. Defaults to {@link DEFAULT_BARCODE_FORMATS}. */\n formats?: readonly BarcodeFormat[];\n /** Called for every accepted read — that is, after repeat suppression. */\n onScan?: (result: BarcodeScanResult) => void;\n /**\n * How often a frame is examined, in ms. Default 200.\n *\n * Not `requestAnimationFrame`: decoding is 10–40 ms of main-thread work on a\n * phone, so running it per frame competes with the preview it is reading from and\n * makes the video stutter. Five looks per second is faster than a human can aim.\n */\n intervalMs?: number;\n /**\n * Ignore the **same** value again for this long, in ms. Default 2500.\n *\n * A symbol stays in frame for as long as the user holds the camera there, so a\n * scanner without this fires the same code five times a second — which, wired to\n * \"add item to cart\", is a bug the user pays for. A *different* value is never\n * suppressed.\n */\n repeatDelayMs?: number;\n /** Stop looking without releasing the camera — a confirmation sheet is open. */\n paused?: boolean;\n /**\n * A decoder to use instead of the native one.\n *\n * The way to support Safari and Firefox: hand in a polyfill and everything else\n * here works unchanged. See {@link isBarcodeDetectionSupported} for why the SDK\n * does not bundle one.\n */\n detector?: BarcodeDetectorLike;\n /** Camera constraints, forwarded to `useCameraStream`. Defaults to the rear camera. */\n constraints?: MediaStreamConstraints;\n /**\n * A frame the engine refused to decode.\n *\n * Not \"nothing found\" — that resolves to an empty list and is the normal case.\n * This is the engine itself failing, which the loop survives because it is\n * usually transient (a frame arriving between two resolutions).\n */\n onError?: (error: unknown) => void;\n}\n\n/** Value returned by {@link useBarcodeScanner}. */\nexport interface UseBarcodeScannerResult {\n /** Attach to a `<video ref={…} muted playsInline />`. */\n videoRef: RefObject<HTMLVideoElement | null>;\n /** Camera lifecycle. `\"ready\"` means the preview is running. */\n status: CameraStreamStatus;\n /** Classified camera error, or `null`. */\n error: CameraStreamError | null;\n /** `false` when there is no decoder — no native API and none injected. */\n supported: boolean;\n /**\n * Formats actually in use: the requested ones intersected with what the engine\n * reports. Empty while the probe is in flight, or when nothing matched.\n */\n formats: readonly BarcodeFormat[];\n /** Whether the detect loop is running right now. */\n scanning: boolean;\n /** The most recent accepted read, or `null`. */\n result: BarcodeScanResult | null;\n /** The LED torch of this camera, when it has one. */\n torch: UseTorchResult;\n /** Re-open the camera after an error (the user changed the permission). */\n retry: () => void;\n}\n\n/** A video is decodable once it has data for the current frame and a real size. */\nfunction frameIsReady(video: HTMLVideoElement): boolean {\n return video.readyState >= 2 && video.videoWidth > 0 && video.videoHeight > 0;\n}\n\n/**\n * Read barcodes and QR codes from the camera.\n *\n * The camera and its classified errors come from `useCameraStream`, so this hook is\n * only the decoding half: it drives a `BarcodeDetector` over the preview on an\n * interval, suppresses the same value repeating, and exposes the torch.\n *\n * **Mounting this opens the camera.** It inherits that from `useCameraStream`, which\n * acquires on mount — so mount it *after* the user asks to scan (a button that reveals\n * the scanner), never on a page that merely contains one. A permission prompt nobody\n * provoked is the most reliable way to earn a permanent block, after which\n * `getUserMedia` rejects without ever prompting again.\n *\n * `supported` deserves a branch in the UI, not an assertion: `BarcodeDetector` is\n * Chromium-only and missing on Windows/Linux desktop, Firefox and everything on iOS.\n * Inject a `detector` to cover those, or tell the user to type the code.\n *\n * @param options - See {@link UseBarcodeScannerOptions}.\n * @returns The camera plumbing plus the scan state.\n *\n * @example\n * const scanner = useBarcodeScanner({\n * formats: [\"ean_13\"],\n * onScan: ({ rawValue }) => addToCart(rawValue),\n * });\n * return <video ref={scanner.videoRef} muted playsInline />;\n */\nexport function useBarcodeScanner(options: UseBarcodeScannerOptions = {}): UseBarcodeScannerResult {\n const {\n formats: requested = DEFAULT_BARCODE_FORMATS,\n onScan,\n intervalMs = 200,\n repeatDelayMs = 2500,\n paused = false,\n detector: injected,\n constraints,\n onError,\n } = options;\n\n const [supported, setSupported] = useState(\n () => injected !== undefined || isBarcodeDetectionSupported(),\n );\n\n /**\n * No decoder, no camera.\n *\n * Opening the camera only to report \"this browser cannot decode barcodes\" spends a\n * permission prompt on nothing — and a refusal is permanent, so it also spends the\n * *next* feature that needs the camera.\n */\n const camera = useCameraStream({ constraints, enabled: supported });\n const torch = useTorch(camera.stream);\n\n const [formats, setFormats] = useState<readonly BarcodeFormat[]>(\n injected !== undefined ? requested : [],\n );\n const [scanning, setScanning] = useState(false);\n const [result, setResult] = useState<BarcodeScanResult | null>(null);\n\n const detectorRef = useRef<BarcodeDetectorLike | null>(null);\n const lastValue = useRef<string | null>(null);\n const lastAt = useRef(0);\n\n const emitScan = useStableCallback((scan: BarcodeScanResult) => onScan?.(scan));\n const emitError = useStableCallback((error: unknown) => onError?.(error));\n\n const requestedKey = requested.join(\",\");\n\n /**\n * Resolve which formats the engine will take, then build the detector.\n *\n * The intersection is not defensive coding: `new BarcodeDetector({ formats })`\n * throws `NotSupportedError` when any entry is unknown to the platform decoder, and\n * that list differs between two Chromium builds on two operating systems. Asking\n * for the intersection is the only way one call site works everywhere.\n */\n useEffect(() => {\n if (injected) {\n detectorRef.current = injected;\n setSupported(true);\n setFormats(requested);\n return;\n }\n if (!isBarcodeDetectionSupported()) {\n detectorRef.current = null;\n setSupported(false);\n setFormats([]);\n return;\n }\n let cancelled = false;\n void getSupportedBarcodeFormats().then((available) => {\n if (cancelled) return;\n const usable =\n available.length === 0\n ? requested\n : requested.filter((format) => available.includes(format));\n const detector = usable.length > 0 ? createBarcodeDetector(usable) : null;\n detectorRef.current = detector;\n setFormats(detector ? usable : []);\n setSupported(detector !== null);\n });\n return () => {\n cancelled = true;\n };\n // `requestedKey` stands in for the array identity, so a caller passing an\n // inline `formats={[\"ean_13\"]}` does not rebuild the detector every render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [injected, requestedKey]);\n\n /**\n * Look at a frame every `intervalMs`, and never overlap two looks.\n *\n * The loop re-arms itself *after* each `detect()` settles rather than running on a\n * fixed `setInterval`: decoding sometimes takes longer than the interval, and an\n * interval would then queue calls faster than the engine drains them until the tab\n * is unusable.\n */\n useEffect(() => {\n if (!supported || paused || camera.status !== \"ready\") {\n setScanning(false);\n return;\n }\n let stopped = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n setScanning(true);\n\n const accept = (scan: BarcodeScanResult): void => {\n const now = Date.now();\n const isRepeat =\n scan.rawValue === lastValue.current && now - lastAt.current < repeatDelayMs;\n if (isRepeat) return;\n lastValue.current = scan.rawValue;\n lastAt.current = now;\n setResult(scan);\n emitScan(scan);\n };\n\n const look = async (): Promise<void> => {\n const video = camera.videoRef.current;\n const detector = detectorRef.current;\n if (!video || !detector || !frameIsReady(video)) return;\n try {\n const found = await detector.detect(video);\n if (stopped) return;\n for (const raw of found) {\n const scan = normalizeBarcode(raw);\n if (scan.rawValue !== \"\") accept(scan);\n }\n } catch (error) {\n if (!stopped) emitError(error);\n }\n };\n\n const tick = (): void => {\n void look().finally(() => {\n if (!stopped) timer = setTimeout(tick, intervalMs);\n });\n };\n tick();\n\n return () => {\n stopped = true;\n if (timer !== undefined) clearTimeout(timer);\n setScanning(false);\n };\n }, [\n supported,\n paused,\n camera.status,\n camera.videoRef,\n intervalMs,\n repeatDelayMs,\n emitScan,\n emitError,\n ]);\n\n return {\n videoRef: camera.videoRef,\n status: camera.status,\n error: camera.error,\n supported,\n formats,\n scanning,\n result,\n torch,\n retry: camera.retry,\n };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-barcode-scanner.js","names":[],"sources":["../../src/capture/use-barcode-scanner.ts"],"sourcesContent":["/**\n * @tempest-limits hook-lines — the scan loop, the repeat suppression window and the\n * torch control share the same track and the same interval handle; splitting them\n * would leave a timer running against a track another hook stopped.\n */\nimport { useEffect, useRef, useState, type RefObject } from \"react\";\n\nimport { useStableCallback } from \"@/hooks/use-stable-callback\";\nimport {\n useCameraStream,\n type CameraStreamError,\n type CameraStreamStatus,\n} from \"@/vision/use-camera-stream\";\n\nimport {\n createBarcodeDetector,\n getSupportedBarcodeFormats,\n isBarcodeDetectionSupported,\n normalizeBarcode,\n DEFAULT_BARCODE_FORMATS,\n type BarcodeDetectorLike,\n type BarcodeFormat,\n type BarcodeScanResult,\n} from \"./barcode\";\nimport { useTorch, type UseTorchResult } from \"./use-torch\";\n\n/** Options for {@link useBarcodeScanner}. */\nexport interface UseBarcodeScannerOptions {\n /** Symbologies to look for. Defaults to {@link DEFAULT_BARCODE_FORMATS}. */\n formats?: readonly BarcodeFormat[];\n /** Called for every accepted read — that is, after repeat suppression. */\n onScan?: (result: BarcodeScanResult) => void;\n /**\n * How often a frame is examined, in ms. Default 200.\n *\n * Not `requestAnimationFrame`: decoding is 10–40 ms of main-thread work on a\n * phone, so running it per frame competes with the preview it is reading from and\n * makes the video stutter. Five looks per second is faster than a human can aim.\n */\n intervalMs?: number;\n /**\n * Ignore the **same** value again for this long, in ms. Default 2500.\n *\n * A symbol stays in frame for as long as the user holds the camera there, so a\n * scanner without this fires the same code five times a second — which, wired to\n * \"add item to cart\", is a bug the user pays for. A *different* value is never\n * suppressed.\n */\n repeatDelayMs?: number;\n /** Stop looking without releasing the camera — a confirmation sheet is open. */\n paused?: boolean;\n /**\n * A decoder to use instead of the native one.\n *\n * The way to support Safari and Firefox: hand in a polyfill and everything else\n * here works unchanged. See {@link isBarcodeDetectionSupported} for why the SDK\n * does not bundle one.\n */\n detector?: BarcodeDetectorLike;\n /** Camera constraints, forwarded to `useCameraStream`. Defaults to the rear camera. */\n constraints?: MediaStreamConstraints;\n /**\n * A frame the engine refused to decode.\n *\n * Not \"nothing found\" — that resolves to an empty list and is the normal case.\n * This is the engine itself failing, which the loop survives because it is\n * usually transient (a frame arriving between two resolutions).\n */\n onError?: (error: unknown) => void;\n}\n\n/** Value returned by {@link useBarcodeScanner}. */\nexport interface UseBarcodeScannerResult {\n /** Attach to a `<video ref={…} muted playsInline />`. */\n videoRef: RefObject<HTMLVideoElement | null>;\n /** Camera lifecycle. `\"ready\"` means the preview is running. */\n status: CameraStreamStatus;\n /** Classified camera error, or `null`. */\n error: CameraStreamError | null;\n /** `false` when there is no decoder — no native API and none injected. */\n supported: boolean;\n /**\n * Formats actually in use: the requested ones intersected with what the engine\n * reports. Empty while the probe is in flight, or when nothing matched.\n */\n formats: readonly BarcodeFormat[];\n /** Whether the detect loop is running right now. */\n scanning: boolean;\n /** The most recent accepted read, or `null`. */\n result: BarcodeScanResult | null;\n /** The LED torch of this camera, when it has one. */\n torch: UseTorchResult;\n /** Re-open the camera after an error (the user changed the permission). */\n retry: () => void;\n}\n\n/** A video is decodable once it has data for the current frame and a real size. */\nfunction frameIsReady(video: HTMLVideoElement): boolean {\n return video.readyState >= 2 && video.videoWidth > 0 && video.videoHeight > 0;\n}\n\n/**\n * Read barcodes and QR codes from the camera.\n *\n * The camera and its classified errors come from `useCameraStream`, so this hook is\n * only the decoding half: it drives a `BarcodeDetector` over the preview on an\n * interval, suppresses the same value repeating, and exposes the torch.\n *\n * **Mounting this opens the camera.** It inherits that from `useCameraStream`, which\n * acquires on mount — so mount it *after* the user asks to scan (a button that reveals\n * the scanner), never on a page that merely contains one. A permission prompt nobody\n * provoked is the most reliable way to earn a permanent block, after which\n * `getUserMedia` rejects without ever prompting again.\n *\n * `supported` deserves a branch in the UI, not an assertion: `BarcodeDetector` is\n * Chromium-only and missing on Windows/Linux desktop, Firefox and everything on iOS.\n * Inject a `detector` to cover those, or tell the user to type the code.\n *\n * @param options - See {@link UseBarcodeScannerOptions}.\n * @returns The camera plumbing plus the scan state.\n *\n * @example\n * const scanner = useBarcodeScanner({\n * formats: [\"ean_13\"],\n * onScan: ({ rawValue }) => addToCart(rawValue),\n * });\n * return <video ref={scanner.videoRef} muted playsInline />;\n */\nexport function useBarcodeScanner(options: UseBarcodeScannerOptions = {}): UseBarcodeScannerResult {\n const {\n formats: requested = DEFAULT_BARCODE_FORMATS,\n onScan,\n intervalMs = 200,\n repeatDelayMs = 2500,\n paused = false,\n detector: injected,\n constraints,\n onError,\n } = options;\n\n const [supported, setSupported] = useState(\n () => injected !== undefined || isBarcodeDetectionSupported(),\n );\n\n /**\n * No decoder, no camera.\n *\n * Opening the camera only to report \"this browser cannot decode barcodes\" spends a\n * permission prompt on nothing — and a refusal is permanent, so it also spends the\n * *next* feature that needs the camera.\n */\n const camera = useCameraStream({ constraints, enabled: supported });\n const torch = useTorch(camera.stream);\n\n const [formats, setFormats] = useState<readonly BarcodeFormat[]>(\n injected !== undefined ? requested : [],\n );\n const [scanning, setScanning] = useState(false);\n const [result, setResult] = useState<BarcodeScanResult | null>(null);\n\n const detectorRef = useRef<BarcodeDetectorLike | null>(null);\n const lastValue = useRef<string | null>(null);\n const lastAt = useRef(0);\n\n const emitScan = useStableCallback((scan: BarcodeScanResult) => onScan?.(scan));\n const emitError = useStableCallback((error: unknown) => onError?.(error));\n\n const requestedKey = requested.join(\",\");\n\n /**\n * Resolve which formats the engine will take, then build the detector.\n *\n * The intersection is not defensive coding: `new BarcodeDetector({ formats })`\n * throws `NotSupportedError` when any entry is unknown to the platform decoder, and\n * that list differs between two Chromium builds on two operating systems. Asking\n * for the intersection is the only way one call site works everywhere.\n */\n useEffect(() => {\n if (injected) {\n detectorRef.current = injected;\n setSupported(true);\n setFormats(requested);\n return;\n }\n if (!isBarcodeDetectionSupported()) {\n detectorRef.current = null;\n setSupported(false);\n setFormats([]);\n return;\n }\n let cancelled = false;\n void getSupportedBarcodeFormats().then((available) => {\n if (cancelled) return;\n const usable =\n available.length === 0\n ? requested\n : requested.filter((format) => available.includes(format));\n const detector = usable.length > 0 ? createBarcodeDetector(usable) : null;\n detectorRef.current = detector;\n setFormats(detector ? usable : []);\n setSupported(detector !== null);\n });\n return () => {\n cancelled = true;\n };\n // `requestedKey` stands in for the array identity, so a caller passing an\n // inline `formats={[\"ean_13\"]}` does not rebuild the detector every render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [injected, requestedKey]);\n\n /**\n * Look at a frame every `intervalMs`, and never overlap two looks.\n *\n * The loop re-arms itself *after* each `detect()` settles rather than running on a\n * fixed `setInterval`: decoding sometimes takes longer than the interval, and an\n * interval would then queue calls faster than the engine drains them until the tab\n * is unusable.\n */\n useEffect(() => {\n if (!supported || paused || camera.status !== \"ready\") {\n setScanning(false);\n return;\n }\n let stopped = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n setScanning(true);\n\n const accept = (scan: BarcodeScanResult): void => {\n const now = Date.now();\n const isRepeat =\n scan.rawValue === lastValue.current && now - lastAt.current < repeatDelayMs;\n if (isRepeat) return;\n lastValue.current = scan.rawValue;\n lastAt.current = now;\n setResult(scan);\n emitScan(scan);\n };\n\n const look = async (): Promise<void> => {\n const video = camera.videoRef.current;\n const detector = detectorRef.current;\n if (!video || !detector || !frameIsReady(video)) return;\n try {\n const found = await detector.detect(video);\n if (stopped) return;\n for (const raw of found) {\n const scan = normalizeBarcode(raw);\n if (scan.rawValue !== \"\") accept(scan);\n }\n } catch (error) {\n if (!stopped) emitError(error);\n }\n };\n\n const tick = (): void => {\n void look().finally(() => {\n if (!stopped) timer = setTimeout(tick, intervalMs);\n });\n };\n tick();\n\n return () => {\n stopped = true;\n if (timer !== undefined) clearTimeout(timer);\n setScanning(false);\n };\n }, [\n supported,\n paused,\n camera.status,\n camera.videoRef,\n intervalMs,\n repeatDelayMs,\n emitScan,\n emitError,\n ]);\n\n return {\n videoRef: camera.videoRef,\n status: camera.status,\n error: camera.error,\n supported,\n formats,\n scanning,\n result,\n torch,\n retry: camera.retry,\n };\n}\n"],"mappings":";;;;;;AAiGA,SAAS,EAAa,GAAkC;CACpD,OAAO,EAAM,cAAc,KAAK,EAAM,aAAa,KAAK,EAAM,cAAc;AAChF;AA6BA,SAAgB,EAAkB,IAAoC,CAAC,GAA4B;CAC/F,IAAM,EACF,SAAS,IAAY,GACrB,WACA,gBAAa,KACb,mBAAgB,MAChB,YAAS,IACT,UAAU,GACV,gBACA,eACA,GAEE,CAAC,GAAW,KAAgB,QACxB,MAAa,KAAA,KAAa,EAA4B,CAChE,GASM,IAAS,EAAgB;EAAE;EAAa,SAAS;CAAU,CAAC,GAC5D,IAAQ,EAAS,EAAO,MAAM,GAE9B,CAAC,GAAS,KAAc,EAC1B,MAAa,KAAA,IAAwB,CAAC,IAAb,CAC7B,GACM,CAAC,GAAU,KAAe,EAAS,EAAK,GACxC,CAAC,GAAQ,KAAa,EAAmC,IAAI,GAE7D,IAAc,EAAmC,IAAI,GACrD,IAAY,EAAsB,IAAI,GACtC,IAAS,EAAO,CAAC,GAEjB,IAAW,GAAmB,MAA4B,IAAS,CAAI,CAAC,GACxE,IAAY,GAAmB,MAAmB,IAAU,CAAK,CAAC,GAElE,IAAe,EAAU,KAAK,GAAG;CA8GvC,OApGA,QAAgB;EACZ,IAAI,GAAU;GAGV,AAFA,EAAY,UAAU,GACtB,EAAa,EAAI,GACjB,EAAW,CAAS;GACpB;EACJ;EACA,IAAI,CAAC,EAA4B,GAAG;GAGhC,AAFA,EAAY,UAAU,MACtB,EAAa,EAAK,GAClB,EAAW,CAAC,CAAC;GACb;EACJ;EACA,IAAI,IAAY;EAYhB,OAXA,EAAgC,CAAC,CAAC,MAAM,MAAc;GAClD,IAAI,GAAW;GACf,IAAM,IACF,EAAU,WAAW,IACf,IACA,EAAU,QAAQ,MAAW,EAAU,SAAS,CAAM,CAAC,GAC3D,IAAW,EAAO,SAAS,IAAI,EAAsB,CAAM,IAAI;GAGrE,AAFA,EAAY,UAAU,GACtB,EAAW,IAAW,IAAS,CAAC,CAAC,GACjC,EAAa,MAAa,IAAI;EAClC,CAAC,SACY;GACT,IAAY;EAChB;CAIJ,GAAG,CAAC,GAAU,CAAY,CAAC,GAU3B,QAAgB;EACZ,IAAI,CAAC,KAAa,KAAU,EAAO,WAAW,SAAS;GACnD,EAAY,EAAK;GACjB;EACJ;EACA,IAAI,IAAU,IACV;EACJ,EAAY,EAAI;EAEhB,IAAM,KAAU,MAAkC;GAC9C,IAAM,IAAM,KAAK,IAAI;GAEjB,EAAK,aAAa,EAAU,WAAW,IAAM,EAAO,UAAU,MAElE,EAAU,UAAU,EAAK,UACzB,EAAO,UAAU,GACjB,EAAU,CAAI,GACd,EAAS,CAAI;EACjB,GAEM,IAAO,YAA2B;GACpC,IAAM,IAAQ,EAAO,SAAS,SACxB,IAAW,EAAY;GACzB,IAAC,KAAU,KAAa,EAAa,CAAK,GAC9C,IAAI;IACA,IAAM,IAAQ,MAAM,EAAS,OAAO,CAAK;IACzC,IAAI,GAAS;IACb,KAAK,IAAM,KAAO,GAAO;KACrB,IAAM,IAAO,EAAiB,CAAG;KACjC,AAAI,EAAK,aAAa,MAAI,EAAO,CAAI;IACzC;GACJ,SAAS,GAAO;IACZ,AAAK,KAAS,EAAU,CAAK;GACjC;EACJ,GAEM,UAAmB;GACrB,EAAU,CAAC,CAAC,cAAc;IACtB,AAAK,MAAS,IAAQ,WAAW,GAAM,CAAU;GACrD,CAAC;EACL;EAGA,OAFA,EAAK,SAEQ;GAGT,AAFA,IAAU,IACN,MAAU,KAAA,KAAW,aAAa,CAAK,GAC3C,EAAY,EAAK;EACrB;CACJ,GAAG;EACC;EACA;EACA,EAAO;EACP,EAAO;EACP;EACA;EACA;EACA;CACJ,CAAC,GAEM;EACH,UAAU,EAAO;EACjB,QAAQ,EAAO;EACf,OAAO,EAAO;EACd;EACA;EACA;EACA;EACA;EACA,OAAO,EAAO;CAClB;AACJ"}
1
+ {"version":3,"file":"use-barcode-scanner.js","names":["frameIsReady","video","useBarcodeScanner","requested","DEFAULT_BARCODE_FORMATS","injected","options","supported","setSupported","useState","isBarcodeDetectionSupported","camera","useCameraStream","torch","useTorch","formats","setFormats","scanning","setScanning","result","setResult","detectorRef","useRef","lastValue","lastAt","emitScan","useStableCallback","onScan","scan","emitError","onError","error","requestedKey","useEffect","cancelled","getSupportedBarcodeFormats","usable","available","format","detector","createBarcodeDetector","paused","stopped","timer","accept","now","repeatDelayMs","look","found","raw","normalizeBarcode","tick","intervalMs"],"sources":["../../src/capture/use-barcode-scanner.ts"],"sourcesContent":["/**\n * @tempest-limits hook-lines — the scan loop, the repeat suppression window and the\n * torch control share the same track and the same interval handle; splitting them\n * would leave a timer running against a track another hook stopped.\n */\nimport { useEffect, useRef, useState, type RefObject } from \"react\";\n\nimport { useStableCallback } from \"@/hooks/use-stable-callback\";\nimport {\n useCameraStream,\n type CameraStreamError,\n type CameraStreamStatus,\n} from \"@/vision/use-camera-stream\";\n\nimport {\n createBarcodeDetector,\n getSupportedBarcodeFormats,\n isBarcodeDetectionSupported,\n normalizeBarcode,\n DEFAULT_BARCODE_FORMATS,\n type BarcodeDetectorLike,\n type BarcodeFormat,\n type BarcodeScanResult,\n} from \"./barcode\";\nimport { useTorch, type UseTorchResult } from \"./use-torch\";\n\n/** Options for {@link useBarcodeScanner}. */\nexport interface UseBarcodeScannerOptions {\n /** Symbologies to look for. Defaults to {@link DEFAULT_BARCODE_FORMATS}. */\n formats?: readonly BarcodeFormat[];\n /** Called for every accepted read — that is, after repeat suppression. */\n onScan?: (result: BarcodeScanResult) => void;\n /**\n * How often a frame is examined, in ms. Default 200.\n *\n * Not `requestAnimationFrame`: decoding is 10–40 ms of main-thread work on a\n * phone, so running it per frame competes with the preview it is reading from and\n * makes the video stutter. Five looks per second is faster than a human can aim.\n */\n intervalMs?: number;\n /**\n * Ignore the **same** value again for this long, in ms. Default 2500.\n *\n * A symbol stays in frame for as long as the user holds the camera there, so a\n * scanner without this fires the same code five times a second — which, wired to\n * \"add item to cart\", is a bug the user pays for. A *different* value is never\n * suppressed.\n */\n repeatDelayMs?: number;\n /** Stop looking without releasing the camera — a confirmation sheet is open. */\n paused?: boolean;\n /**\n * A decoder to use instead of the native one.\n *\n * The way to support Safari and Firefox: hand in a polyfill and everything else\n * here works unchanged. See {@link isBarcodeDetectionSupported} for why the SDK\n * does not bundle one.\n */\n detector?: BarcodeDetectorLike;\n /** Camera constraints, forwarded to `useCameraStream`. Defaults to the rear camera. */\n constraints?: MediaStreamConstraints;\n /**\n * A frame the engine refused to decode.\n *\n * Not \"nothing found\" — that resolves to an empty list and is the normal case.\n * This is the engine itself failing, which the loop survives because it is\n * usually transient (a frame arriving between two resolutions).\n */\n onError?: (error: unknown) => void;\n}\n\n/** Value returned by {@link useBarcodeScanner}. */\nexport interface UseBarcodeScannerResult {\n /** Attach to a `<video ref={…} muted playsInline />`. */\n videoRef: RefObject<HTMLVideoElement | null>;\n /** Camera lifecycle. `\"ready\"` means the preview is running. */\n status: CameraStreamStatus;\n /** Classified camera error, or `null`. */\n error: CameraStreamError | null;\n /** `false` when there is no decoder — no native API and none injected. */\n supported: boolean;\n /**\n * Formats actually in use: the requested ones intersected with what the engine\n * reports. Empty while the probe is in flight, or when nothing matched.\n */\n formats: readonly BarcodeFormat[];\n /** Whether the detect loop is running right now. */\n scanning: boolean;\n /** The most recent accepted read, or `null`. */\n result: BarcodeScanResult | null;\n /** The LED torch of this camera, when it has one. */\n torch: UseTorchResult;\n /** Re-open the camera after an error (the user changed the permission). */\n retry: () => void;\n}\n\n/** A video is decodable once it has data for the current frame and a real size. */\nfunction frameIsReady(video: HTMLVideoElement): boolean {\n return video.readyState >= 2 && video.videoWidth > 0 && video.videoHeight > 0;\n}\n\n/**\n * Read barcodes and QR codes from the camera.\n *\n * The camera and its classified errors come from `useCameraStream`, so this hook is\n * only the decoding half: it drives a `BarcodeDetector` over the preview on an\n * interval, suppresses the same value repeating, and exposes the torch.\n *\n * **Mounting this opens the camera.** It inherits that from `useCameraStream`, which\n * acquires on mount — so mount it *after* the user asks to scan (a button that reveals\n * the scanner), never on a page that merely contains one. A permission prompt nobody\n * provoked is the most reliable way to earn a permanent block, after which\n * `getUserMedia` rejects without ever prompting again.\n *\n * `supported` deserves a branch in the UI, not an assertion: `BarcodeDetector` is\n * Chromium-only and missing on Windows/Linux desktop, Firefox and everything on iOS.\n * Inject a `detector` to cover those, or tell the user to type the code.\n *\n * @param options - See {@link UseBarcodeScannerOptions}.\n * @returns The camera plumbing plus the scan state.\n *\n * @example\n * const scanner = useBarcodeScanner({\n * formats: [\"ean_13\"],\n * onScan: ({ rawValue }) => addToCart(rawValue),\n * });\n * return <video ref={scanner.videoRef} muted playsInline />;\n */\nexport function useBarcodeScanner(options: UseBarcodeScannerOptions = {}): UseBarcodeScannerResult {\n const {\n formats: requested = DEFAULT_BARCODE_FORMATS,\n onScan,\n intervalMs = 200,\n repeatDelayMs = 2500,\n paused = false,\n detector: injected,\n constraints,\n onError,\n } = options;\n\n const [supported, setSupported] = useState(\n () => injected !== undefined || isBarcodeDetectionSupported(),\n );\n\n /**\n * No decoder, no camera.\n *\n * Opening the camera only to report \"this browser cannot decode barcodes\" spends a\n * permission prompt on nothing — and a refusal is permanent, so it also spends the\n * *next* feature that needs the camera.\n */\n const camera = useCameraStream({ constraints, enabled: supported });\n const torch = useTorch(camera.stream);\n\n const [formats, setFormats] = useState<readonly BarcodeFormat[]>(\n injected !== undefined ? requested : [],\n );\n const [scanning, setScanning] = useState(false);\n const [result, setResult] = useState<BarcodeScanResult | null>(null);\n\n const detectorRef = useRef<BarcodeDetectorLike | null>(null);\n const lastValue = useRef<string | null>(null);\n const lastAt = useRef(0);\n\n const emitScan = useStableCallback((scan: BarcodeScanResult) => onScan?.(scan));\n const emitError = useStableCallback((error: unknown) => onError?.(error));\n\n const requestedKey = requested.join(\",\");\n\n /**\n * Resolve which formats the engine will take, then build the detector.\n *\n * The intersection is not defensive coding: `new BarcodeDetector({ formats })`\n * throws `NotSupportedError` when any entry is unknown to the platform decoder, and\n * that list differs between two Chromium builds on two operating systems. Asking\n * for the intersection is the only way one call site works everywhere.\n */\n useEffect(() => {\n if (injected) {\n detectorRef.current = injected;\n setSupported(true);\n setFormats(requested);\n return;\n }\n if (!isBarcodeDetectionSupported()) {\n detectorRef.current = null;\n setSupported(false);\n setFormats([]);\n return;\n }\n let cancelled = false;\n void getSupportedBarcodeFormats().then((available) => {\n if (cancelled) return;\n const usable =\n available.length === 0\n ? requested\n : requested.filter((format) => available.includes(format));\n const detector = usable.length > 0 ? createBarcodeDetector(usable) : null;\n detectorRef.current = detector;\n setFormats(detector ? usable : []);\n setSupported(detector !== null);\n });\n return () => {\n cancelled = true;\n };\n // `requestedKey` stands in for the array identity, so a caller passing an\n // inline `formats={[\"ean_13\"]}` does not rebuild the detector every render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [injected, requestedKey]);\n\n /**\n * Look at a frame every `intervalMs`, and never overlap two looks.\n *\n * The loop re-arms itself *after* each `detect()` settles rather than running on a\n * fixed `setInterval`: decoding sometimes takes longer than the interval, and an\n * interval would then queue calls faster than the engine drains them until the tab\n * is unusable.\n */\n useEffect(() => {\n if (!supported || paused || camera.status !== \"ready\") {\n setScanning(false);\n return;\n }\n let stopped = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n setScanning(true);\n\n const accept = (scan: BarcodeScanResult): void => {\n const now = Date.now();\n const isRepeat =\n scan.rawValue === lastValue.current && now - lastAt.current < repeatDelayMs;\n if (isRepeat) return;\n lastValue.current = scan.rawValue;\n lastAt.current = now;\n setResult(scan);\n emitScan(scan);\n };\n\n const look = async (): Promise<void> => {\n const video = camera.videoRef.current;\n const detector = detectorRef.current;\n if (!video || !detector || !frameIsReady(video)) return;\n try {\n const found = await detector.detect(video);\n if (stopped) return;\n for (const raw of found) {\n const scan = normalizeBarcode(raw);\n if (scan.rawValue !== \"\") accept(scan);\n }\n } catch (error) {\n if (!stopped) emitError(error);\n }\n };\n\n const tick = (): void => {\n void look().finally(() => {\n if (!stopped) timer = setTimeout(tick, intervalMs);\n });\n };\n tick();\n\n return () => {\n stopped = true;\n if (timer !== undefined) clearTimeout(timer);\n setScanning(false);\n };\n }, [\n supported,\n paused,\n camera.status,\n camera.videoRef,\n intervalMs,\n repeatDelayMs,\n emitScan,\n emitError,\n ]);\n\n return {\n videoRef: camera.videoRef,\n status: camera.status,\n error: camera.error,\n supported,\n formats,\n scanning,\n result,\n torch,\n retry: camera.retry,\n };\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- const e=require("../hooks/use-stable-callback.cjs"),t=require("../audio/media-access.cjs");let n=require("react");function r(){return typeof navigator<`u`&&navigator.mediaDevices!==void 0&&typeof navigator.mediaDevices.getDisplayMedia==`function`}function i(e){return e instanceof DOMException&&(e.name===`NotAllowedError`||e.name===`AbortError`)}function a(a={}){let{audio:o=!1,displaySurface:s,preferCurrentTab:c,selfBrowserSurface:l,surfaceSwitching:u,systemAudio:d,options:f,onEnded:p,onCancelled:m}=a,[h,g]=(0,n.useState)(`idle`),[_,v]=(0,n.useState)(null),[y,b]=(0,n.useState)(null),[x,S]=(0,n.useState)(null),[C,w]=(0,n.useState)(!1),[T]=(0,n.useState)(r),E=(0,n.useRef)(null),D=(0,n.useRef)(null),O=(0,n.useRef)(0),k=e.useStableCallback(()=>p?.()),A=e.useStableCallback(e=>m?.(e)),j=(0,n.useCallback)(()=>{D.current?.(),D.current=null,E.current?.getTracks().forEach(e=>e.stop()),E.current=null},[]),M=(0,n.useCallback)(()=>{v(null),S(null),w(!1)},[]),N=(0,n.useCallback)(()=>{O.current+=1,j(),M(),g(`idle`),b(null)},[j,M]),P=(0,n.useCallback)(()=>{if(E.current)return;let e=O.current+=1;if(g(`requesting`),b(null),!r()){b(t.missingCaptureApiError(`screen`)),g(`error`);return}let n=f??{video:s?{displaySurface:s}:{},audio:o,...c===void 0?{}:{preferCurrentTab:c},...l===void 0?{}:{selfBrowserSurface:l},...u===void 0?{}:{surfaceSwitching:u},...d===void 0?{}:{systemAudio:d}};navigator.mediaDevices.getDisplayMedia(n).then(t=>{if(e!==O.current){t.getTracks().forEach(e=>e.stop());return}E.current=t;let n=t.getVideoTracks()[0],r=()=>{e===O.current&&(j(),M(),g(`idle`),k())};n?.addEventListener(`ended`,r),D.current=()=>n?.removeEventListener(`ended`,r),v(t),S(n?.getSettings().displaySurface??null),w(t.getAudioTracks().length>0),g(`sharing`)}).catch(n=>{if(e===O.current){if(i(n)){g(`idle`),A(n);return}b(t.classifyMediaError(n,`screen`)),g(`error`)}})},[o,s,c,l,u,d,f,j,M,k,A]);return(0,n.useEffect)(()=>j,[j]),{status:h,stream:_,error:y,surface:x,hasAudio:C,supported:T,start:P,stop:N}}exports.isScreenCaptureSupported=r,exports.useScreenCapture=a;
1
+ const e=require("../hooks/use-stable-callback.cjs"),t=require("../audio/media-access.cjs");let n=require("react");function r(){return typeof navigator<`u`&&navigator.mediaDevices!==void 0&&typeof navigator.mediaDevices.getDisplayMedia==`function`}function i(e){return e instanceof DOMException&&(e.name===`NotAllowedError`||e.name===`AbortError`)}function a(a={}){let{audio:o=!1,displaySurface:s,preferCurrentTab:c,selfBrowserSurface:l,surfaceSwitching:u,systemAudio:d,options:f,onEnded:p,onCancelled:m}=a,[h,g]=(0,n.useState)(`idle`),[_,v]=(0,n.useState)(null),[y,b]=(0,n.useState)(null),[x,S]=(0,n.useState)(null),[C,w]=(0,n.useState)(!1),[T]=(0,n.useState)(r),E=(0,n.useRef)(null),D=(0,n.useRef)(null),O=(0,n.useRef)(0),k=e.useStableCallback(()=>p?.()),A=e.useStableCallback(e=>m?.(e)),j=(0,n.useCallback)(()=>{D.current?.(),D.current=null,E.current?.getTracks().forEach(e=>e.stop()),E.current=null},[]),M=(0,n.useCallback)(()=>{v(null),S(null),w(!1)},[]),N=(0,n.useCallback)(()=>{O.current+=1,j(),M(),g(`idle`),b(null)},[j,M]),P=(0,n.useCallback)(()=>{if(E.current)return;let e=O.current+=1;if(g(`requesting`),b(null),!r()){b(t.missingCaptureApiError(`screen`)),g(`error`);return}let n=f??{video:s?{displaySurface:s}:{},audio:o,...c===void 0?{}:{preferCurrentTab:c},...l===void 0?{}:{selfBrowserSurface:l},...u===void 0?{}:{surfaceSwitching:u},...d===void 0?{}:{systemAudio:d}};navigator.mediaDevices.getDisplayMedia(n).then(t=>{if(e!==O.current){t.getTracks().forEach(e=>e.stop());return}E.current=t;let n=t.getVideoTracks()[0],r=()=>{e===O.current&&(j(),M(),g(`idle`),k())};n?.addEventListener(`ended`,r),D.current=()=>n?.removeEventListener(`ended`,r),v(t),S(n?.getSettings().displaySurface??null),w(t.getAudioTracks().length>0),g(`sharing`)}).catch(n=>{e===O.current&&(i(n)?(g(`idle`),A(n)):(b(t.classifyMediaError(n,`screen`)),g(`error`)))})},[o,s,c,l,u,d,f,j,M,k,A]);return(0,n.useEffect)(()=>j,[j]),{status:h,stream:_,error:y,surface:x,hasAudio:C,supported:T,start:P,stop:N}}exports.isScreenCaptureSupported=r,exports.useScreenCapture=a;
2
2
  //# sourceMappingURL=use-screen-capture.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-screen-capture.cjs","names":[],"sources":["../../src/capture/use-screen-capture.ts"],"sourcesContent":["/**\n * @tempest-limits hook-lines — getDisplayMedia's cancellation is indistinguishable\n * from a policy block, so the hook holds the classification, the track's own `ended`\n * event (the user can stop sharing from the browser's bar) and the stop path in one\n * place — all three end the same session.\n */\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport {\n classifyMediaError,\n missingCaptureApiError,\n type MediaAccessError,\n} from \"@/audio/media-access\";\nimport { useStableCallback } from \"@/hooks/use-stable-callback\";\n\n/** Lifecycle of a screen share. */\nexport type ScreenCaptureStatus = \"idle\" | \"requesting\" | \"sharing\" | \"error\";\n\n/** Which surface to put first in the picker. */\nexport type DisplaySurfaceHint = \"monitor\" | \"window\" | \"browser\";\n\n/**\n * Hints `getDisplayMedia` takes that TypeScript's `DisplayMediaStreamOptions` does not\n * list yet.\n */\ntype DisplayMediaOptionsWithHints = DisplayMediaStreamOptions & {\n preferCurrentTab?: boolean;\n selfBrowserSurface?: \"include\" | \"exclude\";\n surfaceSwitching?: \"include\" | \"exclude\";\n systemAudio?: \"include\" | \"exclude\";\n};\n\n/** `displaySurface` is a constrainable property of a display track, but not in the DOM lib. */\ntype DisplayVideoConstraints = MediaTrackConstraints & { displaySurface?: DisplaySurfaceHint };\n\n/** Options for {@link useScreenCapture}. */\nexport interface UseScreenCaptureOptions {\n /**\n * Capture the tab's audio too. Default `false`.\n *\n * Chromium only offers this for a **tab** — sharing a window or a whole screen\n * yields no audio track no matter what you ask for, and Safari has no display\n * audio at all. Ask for it and check what you got.\n */\n audio?: boolean;\n /**\n * Which surface the picker should offer first — `\"browser\"` is a tab.\n *\n * A hint, never a guarantee: the user can always pick something else, and Firefox\n * ignores it. Read `surface` afterwards to learn what actually happened.\n */\n displaySurface?: DisplaySurfaceHint;\n /**\n * Put *this* tab at the top of the picker. Default `false`.\n *\n * The right setting for \"record what you are seeing right now\" in a support flow.\n * Chromium only.\n */\n preferCurrentTab?: boolean;\n /** Offer this tab in the list at all. `\"exclude\"` prevents the hall-of-mirrors capture. */\n selfBrowserSurface?: \"include\" | \"exclude\";\n /** Let the user switch to a different surface mid-share, without a new prompt. */\n surfaceSwitching?: \"include\" | \"exclude\";\n /** Include the system audio when a whole screen is shared. Chromium, Windows only. */\n systemAudio?: \"include\" | \"exclude\";\n /** Escape hatch: full options, replacing everything above. */\n options?: DisplayMediaStreamOptions;\n /**\n * The user stopped the share from the browser's own bar.\n *\n * The single most important callback here — see the note on\n * {@link useScreenCapture}.\n */\n onEnded?: () => void;\n /**\n * The user dismissed the picker. **Not an error.**\n *\n * Receives the rejection so an app that needs to tell a dismissal from an OS-level\n * block (macOS screen-recording permission) can look at the message. Most should\n * simply return the UI to its previous state.\n */\n onCancelled?: (reason: unknown) => void;\n}\n\n/** Value returned by {@link useScreenCapture}. */\nexport interface UseScreenCaptureResult {\n status: ScreenCaptureStatus;\n /** The live stream, or `null`. Feed it to {@link useVideoRecorder} or a `<video>`. */\n stream: MediaStream | null;\n /** Classified error, or `null`. A cancelled picker leaves this `null`. */\n error: MediaAccessError | null;\n /** What the user actually picked, when the browser reports it. */\n surface: string | null;\n /** Whether the stream carries an audio track — ask, do not assume. */\n hasAudio: boolean;\n /** `false` when `getDisplayMedia` is missing (every browser on iOS, insecure pages). */\n supported: boolean;\n /** Open the picker. Must be called from a user gesture. */\n start: () => void;\n /** Stop sharing from the app side. Fires nothing — you asked for it. */\n stop: () => void;\n}\n\n/** Whether `getDisplayMedia` is reachable at all. */\nexport function isScreenCaptureSupported(): boolean {\n return (\n typeof navigator !== \"undefined\" &&\n navigator.mediaDevices !== undefined &&\n typeof navigator.mediaDevices.getDisplayMedia === \"function\"\n );\n}\n\n/**\n * A rejection from `getDisplayMedia` that means \"the user said no thanks\".\n *\n * There is no distinct exception for a dismissed picker: closing it produces the same\n * `NotAllowedError` as a policy block, and some builds report `AbortError` instead. The\n * useful default is therefore to treat both as a cancellation, because a\n * display-capture prompt is **always** user-initiated — nothing can open it behind\n * their back — so the overwhelmingly likely cause is that they changed their mind, and\n * a red error toast for that punishes them for it. The rejection is handed to\n * `onCancelled` so the rarer causes stay diagnosable.\n */\nfunction isCancellation(err: unknown): boolean {\n return (\n err instanceof DOMException && (err.name === \"NotAllowedError\" || err.name === \"AbortError\")\n );\n}\n\n/**\n * Capture a screen, a window or a tab with `getDisplayMedia`.\n *\n * Three states decide whether this feels right, and two of them are easy to miss:\n *\n * - **The user dismissed the picker.** A rejection, but not a failure. It leaves\n * `error` at `null` and the status back at `\"idle\"`, and calls `onCancelled`.\n * - **The user stopped the share from the browser's own bar.** Nothing in your UI was\n * clicked and no promise rejects — the *only* signal is the video track's `ended`\n * event, so the hook listens for it and clears the stream. Without that listener, an\n * app shows \"gravando\" over a stream that is already dead.\n * - **The share is live.** `surface` says what was picked and `hasAudio` says whether\n * audio actually came along, which is not what you asked for but what you got.\n *\n * The stream is owned here: `stop()` and unmount both release every track. A recorder\n * built on it (`useVideoRecorder`) deliberately does not, so stopping a recording\n * leaves the share running for the next take.\n *\n * @param options - See {@link UseScreenCaptureOptions}.\n * @returns The stream, its status, a classified error and `start`/`stop`.\n *\n * @example\n * const screen = useScreenCapture({ preferCurrentTab: true, onEnded: () => save() });\n * const rec = useVideoRecorder(screen.stream);\n * <button onClick={screen.start}>Compartilhar tela</button>\n */\nexport function useScreenCapture(options: UseScreenCaptureOptions = {}): UseScreenCaptureResult {\n const {\n audio = false,\n displaySurface,\n preferCurrentTab,\n selfBrowserSurface,\n surfaceSwitching,\n systemAudio,\n options: raw,\n onEnded,\n onCancelled,\n } = options;\n\n const [status, setStatus] = useState<ScreenCaptureStatus>(\"idle\");\n const [stream, setStream] = useState<MediaStream | null>(null);\n const [error, setError] = useState<MediaAccessError | null>(null);\n const [surface, setSurface] = useState<string | null>(null);\n const [hasAudio, setHasAudio] = useState(false);\n const [supported] = useState(isScreenCaptureSupported);\n\n const streamRef = useRef<MediaStream | null>(null);\n const detach = useRef<(() => void) | null>(null);\n const generation = useRef(0);\n\n const emitEnded = useStableCallback(() => onEnded?.());\n const emitCancelled = useStableCallback((reason: unknown) => onCancelled?.(reason));\n\n const release = useCallback((): void => {\n detach.current?.();\n detach.current = null;\n streamRef.current?.getTracks().forEach((track) => track.stop());\n streamRef.current = null;\n }, []);\n\n const reset = useCallback((): void => {\n setStream(null);\n setSurface(null);\n setHasAudio(false);\n }, []);\n\n const stop = useCallback((): void => {\n generation.current += 1;\n release();\n reset();\n setStatus(\"idle\");\n setError(null);\n }, [release, reset]);\n\n const start = useCallback((): void => {\n if (streamRef.current) return;\n const run = (generation.current += 1);\n setStatus(\"requesting\");\n setError(null);\n\n if (!isScreenCaptureSupported()) {\n setError(missingCaptureApiError(\"screen\"));\n setStatus(\"error\");\n return;\n }\n\n const video: DisplayVideoConstraints = displaySurface ? { displaySurface } : {};\n const request: DisplayMediaOptionsWithHints = raw ?? {\n video,\n audio,\n ...(preferCurrentTab !== undefined ? { preferCurrentTab } : {}),\n ...(selfBrowserSurface !== undefined ? { selfBrowserSurface } : {}),\n ...(surfaceSwitching !== undefined ? { surfaceSwitching } : {}),\n ...(systemAudio !== undefined ? { systemAudio } : {}),\n };\n\n void navigator.mediaDevices\n .getDisplayMedia(request)\n .then((next) => {\n if (run !== generation.current) {\n next.getTracks().forEach((track) => track.stop());\n return;\n }\n streamRef.current = next;\n const track = next.getVideoTracks()[0];\n const ended = (): void => {\n if (run !== generation.current) return;\n release();\n reset();\n setStatus(\"idle\");\n emitEnded();\n };\n track?.addEventListener(\"ended\", ended);\n detach.current = () => track?.removeEventListener(\"ended\", ended);\n\n setStream(next);\n setSurface(track?.getSettings().displaySurface ?? null);\n setHasAudio(next.getAudioTracks().length > 0);\n setStatus(\"sharing\");\n })\n .catch((err: unknown) => {\n if (run !== generation.current) return;\n if (isCancellation(err)) {\n setStatus(\"idle\");\n emitCancelled(err);\n return;\n }\n setError(classifyMediaError(err, \"screen\"));\n setStatus(\"error\");\n });\n }, [\n audio,\n displaySurface,\n preferCurrentTab,\n selfBrowserSurface,\n surfaceSwitching,\n systemAudio,\n raw,\n release,\n reset,\n emitEnded,\n emitCancelled,\n ]);\n\n useEffect(() => release, [release]);\n\n return { status, stream, error, surface, hasAudio, supported, start, stop };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-screen-capture.cjs","names":["useState","useRef","useStableCallback","useCallback","missingCaptureApiError","classifyMediaError","require_use_stable_callback","require_media_access","react","isScreenCaptureSupported","isCancellation","err","useScreenCapture","raw","options","status","setStatus","stream","setStream","error","setError","surface","setSurface","hasAudio","setHasAudio","supported","streamRef","detach","generation","emitEnded","onEnded","emitCancelled","onCancelled","reason","release","track","reset","stop","start","run","request","displaySurface","preferCurrentTab","selfBrowserSurface","surfaceSwitching","systemAudio","next","ended","audio"],"sources":["../../src/capture/use-screen-capture.ts"],"sourcesContent":["/**\n * @tempest-limits hook-lines — getDisplayMedia's cancellation is indistinguishable\n * from a policy block, so the hook holds the classification, the track's own `ended`\n * event (the user can stop sharing from the browser's bar) and the stop path in one\n * place — all three end the same session.\n */\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport {\n classifyMediaError,\n missingCaptureApiError,\n type MediaAccessError,\n} from \"@/audio/media-access\";\nimport { useStableCallback } from \"@/hooks/use-stable-callback\";\n\n/** Lifecycle of a screen share. */\nexport type ScreenCaptureStatus = \"idle\" | \"requesting\" | \"sharing\" | \"error\";\n\n/** Which surface to put first in the picker. */\nexport type DisplaySurfaceHint = \"monitor\" | \"window\" | \"browser\";\n\n/**\n * Hints `getDisplayMedia` takes that TypeScript's `DisplayMediaStreamOptions` does not\n * list yet.\n */\ntype DisplayMediaOptionsWithHints = DisplayMediaStreamOptions & {\n preferCurrentTab?: boolean;\n selfBrowserSurface?: \"include\" | \"exclude\";\n surfaceSwitching?: \"include\" | \"exclude\";\n systemAudio?: \"include\" | \"exclude\";\n};\n\n/** `displaySurface` is a constrainable property of a display track, but not in the DOM lib. */\ntype DisplayVideoConstraints = MediaTrackConstraints & { displaySurface?: DisplaySurfaceHint };\n\n/** Options for {@link useScreenCapture}. */\nexport interface UseScreenCaptureOptions {\n /**\n * Capture the tab's audio too. Default `false`.\n *\n * Chromium only offers this for a **tab** — sharing a window or a whole screen\n * yields no audio track no matter what you ask for, and Safari has no display\n * audio at all. Ask for it and check what you got.\n */\n audio?: boolean;\n /**\n * Which surface the picker should offer first — `\"browser\"` is a tab.\n *\n * A hint, never a guarantee: the user can always pick something else, and Firefox\n * ignores it. Read `surface` afterwards to learn what actually happened.\n */\n displaySurface?: DisplaySurfaceHint;\n /**\n * Put *this* tab at the top of the picker. Default `false`.\n *\n * The right setting for \"record what you are seeing right now\" in a support flow.\n * Chromium only.\n */\n preferCurrentTab?: boolean;\n /** Offer this tab in the list at all. `\"exclude\"` prevents the hall-of-mirrors capture. */\n selfBrowserSurface?: \"include\" | \"exclude\";\n /** Let the user switch to a different surface mid-share, without a new prompt. */\n surfaceSwitching?: \"include\" | \"exclude\";\n /** Include the system audio when a whole screen is shared. Chromium, Windows only. */\n systemAudio?: \"include\" | \"exclude\";\n /** Escape hatch: full options, replacing everything above. */\n options?: DisplayMediaStreamOptions;\n /**\n * The user stopped the share from the browser's own bar.\n *\n * The single most important callback here — see the note on\n * {@link useScreenCapture}.\n */\n onEnded?: () => void;\n /**\n * The user dismissed the picker. **Not an error.**\n *\n * Receives the rejection so an app that needs to tell a dismissal from an OS-level\n * block (macOS screen-recording permission) can look at the message. Most should\n * simply return the UI to its previous state.\n */\n onCancelled?: (reason: unknown) => void;\n}\n\n/** Value returned by {@link useScreenCapture}. */\nexport interface UseScreenCaptureResult {\n status: ScreenCaptureStatus;\n /** The live stream, or `null`. Feed it to {@link useVideoRecorder} or a `<video>`. */\n stream: MediaStream | null;\n /** Classified error, or `null`. A cancelled picker leaves this `null`. */\n error: MediaAccessError | null;\n /** What the user actually picked, when the browser reports it. */\n surface: string | null;\n /** Whether the stream carries an audio track — ask, do not assume. */\n hasAudio: boolean;\n /** `false` when `getDisplayMedia` is missing (every browser on iOS, insecure pages). */\n supported: boolean;\n /** Open the picker. Must be called from a user gesture. */\n start: () => void;\n /** Stop sharing from the app side. Fires nothing — you asked for it. */\n stop: () => void;\n}\n\n/** Whether `getDisplayMedia` is reachable at all. */\nexport function isScreenCaptureSupported(): boolean {\n return (\n typeof navigator !== \"undefined\" &&\n navigator.mediaDevices !== undefined &&\n typeof navigator.mediaDevices.getDisplayMedia === \"function\"\n );\n}\n\n/**\n * A rejection from `getDisplayMedia` that means \"the user said no thanks\".\n *\n * There is no distinct exception for a dismissed picker: closing it produces the same\n * `NotAllowedError` as a policy block, and some builds report `AbortError` instead. The\n * useful default is therefore to treat both as a cancellation, because a\n * display-capture prompt is **always** user-initiated — nothing can open it behind\n * their back — so the overwhelmingly likely cause is that they changed their mind, and\n * a red error toast for that punishes them for it. The rejection is handed to\n * `onCancelled` so the rarer causes stay diagnosable.\n */\nfunction isCancellation(err: unknown): boolean {\n return (\n err instanceof DOMException && (err.name === \"NotAllowedError\" || err.name === \"AbortError\")\n );\n}\n\n/**\n * Capture a screen, a window or a tab with `getDisplayMedia`.\n *\n * Three states decide whether this feels right, and two of them are easy to miss:\n *\n * - **The user dismissed the picker.** A rejection, but not a failure. It leaves\n * `error` at `null` and the status back at `\"idle\"`, and calls `onCancelled`.\n * - **The user stopped the share from the browser's own bar.** Nothing in your UI was\n * clicked and no promise rejects — the *only* signal is the video track's `ended`\n * event, so the hook listens for it and clears the stream. Without that listener, an\n * app shows \"gravando\" over a stream that is already dead.\n * - **The share is live.** `surface` says what was picked and `hasAudio` says whether\n * audio actually came along, which is not what you asked for but what you got.\n *\n * The stream is owned here: `stop()` and unmount both release every track. A recorder\n * built on it (`useVideoRecorder`) deliberately does not, so stopping a recording\n * leaves the share running for the next take.\n *\n * @param options - See {@link UseScreenCaptureOptions}.\n * @returns The stream, its status, a classified error and `start`/`stop`.\n *\n * @example\n * const screen = useScreenCapture({ preferCurrentTab: true, onEnded: () => save() });\n * const rec = useVideoRecorder(screen.stream);\n * <button onClick={screen.start}>Compartilhar tela</button>\n */\nexport function useScreenCapture(options: UseScreenCaptureOptions = {}): UseScreenCaptureResult {\n const {\n audio = false,\n displaySurface,\n preferCurrentTab,\n selfBrowserSurface,\n surfaceSwitching,\n systemAudio,\n options: raw,\n onEnded,\n onCancelled,\n } = options;\n\n const [status, setStatus] = useState<ScreenCaptureStatus>(\"idle\");\n const [stream, setStream] = useState<MediaStream | null>(null);\n const [error, setError] = useState<MediaAccessError | null>(null);\n const [surface, setSurface] = useState<string | null>(null);\n const [hasAudio, setHasAudio] = useState(false);\n const [supported] = useState(isScreenCaptureSupported);\n\n const streamRef = useRef<MediaStream | null>(null);\n const detach = useRef<(() => void) | null>(null);\n const generation = useRef(0);\n\n const emitEnded = useStableCallback(() => onEnded?.());\n const emitCancelled = useStableCallback((reason: unknown) => onCancelled?.(reason));\n\n const release = useCallback((): void => {\n detach.current?.();\n detach.current = null;\n streamRef.current?.getTracks().forEach((track) => track.stop());\n streamRef.current = null;\n }, []);\n\n const reset = useCallback((): void => {\n setStream(null);\n setSurface(null);\n setHasAudio(false);\n }, []);\n\n const stop = useCallback((): void => {\n generation.current += 1;\n release();\n reset();\n setStatus(\"idle\");\n setError(null);\n }, [release, reset]);\n\n const start = useCallback((): void => {\n if (streamRef.current) return;\n const run = (generation.current += 1);\n setStatus(\"requesting\");\n setError(null);\n\n if (!isScreenCaptureSupported()) {\n setError(missingCaptureApiError(\"screen\"));\n setStatus(\"error\");\n return;\n }\n\n const video: DisplayVideoConstraints = displaySurface ? { displaySurface } : {};\n const request: DisplayMediaOptionsWithHints = raw ?? {\n video,\n audio,\n ...(preferCurrentTab !== undefined ? { preferCurrentTab } : {}),\n ...(selfBrowserSurface !== undefined ? { selfBrowserSurface } : {}),\n ...(surfaceSwitching !== undefined ? { surfaceSwitching } : {}),\n ...(systemAudio !== undefined ? { systemAudio } : {}),\n };\n\n void navigator.mediaDevices\n .getDisplayMedia(request)\n .then((next) => {\n if (run !== generation.current) {\n next.getTracks().forEach((track) => track.stop());\n return;\n }\n streamRef.current = next;\n const track = next.getVideoTracks()[0];\n const ended = (): void => {\n if (run !== generation.current) return;\n release();\n reset();\n setStatus(\"idle\");\n emitEnded();\n };\n track?.addEventListener(\"ended\", ended);\n detach.current = () => track?.removeEventListener(\"ended\", ended);\n\n setStream(next);\n setSurface(track?.getSettings().displaySurface ?? null);\n setHasAudio(next.getAudioTracks().length > 0);\n setStatus(\"sharing\");\n })\n .catch((err: unknown) => {\n if (run !== generation.current) return;\n if (isCancellation(err)) {\n setStatus(\"idle\");\n emitCancelled(err);\n return;\n }\n setError(classifyMediaError(err, \"screen\"));\n setStatus(\"error\");\n });\n }, [\n audio,\n displaySurface,\n preferCurrentTab,\n selfBrowserSurface,\n surfaceSwitching,\n systemAudio,\n raw,\n release,\n reset,\n emitEnded,\n emitCancelled,\n ]);\n\n useEffect(() => release, [release]);\n\n return { status, stream, error, surface, hasAudio, supported, start, stop };\n}\n"],"mappings":"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"}