@microblink/camera-manager 7.1.0 → 7.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/camera-manager.js +2147 -1361
- package/dist/camera-manager.js.map +1 -0
- package/package.json +1 -1
- package/types/index.rollup.d.ts +18 -1
- package/types/ui/CameraSelector.d.ts.map +1 -1
- package/types/ui/CameraUiStoreContext.d.ts +7 -0
- package/types/ui/CameraUiStoreContext.d.ts.map +1 -1
- package/types/ui/CaptureScreen.d.ts.map +1 -1
- package/types/ui/Header.d.ts.map +1 -1
- package/types/ui/createCameraManagerUi.d.ts +18 -1
- package/types/ui/createCameraManagerUi.d.ts.map +1 -1
package/dist/camera-manager.js
CHANGED
|
@@ -1,53 +1,76 @@
|
|
|
1
|
-
(function(){"use strict";(r=>{window.__mbCameraManagerCssCode=r})("._dialogPositioner_worsp_1{position:fixed;top:calc(var(--mb-size)*0rem);left:calc(var(--mb-size)*0rem);display:grid;height:100vh;width:100%;padding:calc(var(--mb-size)*2rem)}@supports (height:100dvh){._dialogPositioner_worsp_1{height:100dvh}}._dialogBackdrop_worsp_5{position:absolute;top:calc(var(--mb-size)*0rem);left:calc(var(--mb-size)*0rem);width:100%;height:100%;--un-bg-opacity:1;background-color:rgb(var(--color-black-rgb-value) / var(--un-bg-opacity));--un-bg-opacity:.5;--un-backdrop-blur:blur(4px);-webkit-backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia);backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia)}._dialogContent_worsp_9{position:relative;max-height:calc(100dvh - 4rem);max-width:28rem;display:flex;flex-direction:column;place-self:center;border-radius:.5rem;--un-bg-opacity:1;background-color:rgb(var(--color-white-rgb-value) / var(--un-bg-opacity));padding-left:min(8%,3rem);padding-right:min(8%,3rem);padding-top:min(8%,1.5rem);padding-bottom:min(8%,1.5rem);--un-text-opacity:1;color:rgb(15 15 15 / var(--un-text-opacity));--un-shadow:var(--un-shadow-inset) 0 10px 15px -3px var(--un-shadow-color, rgb(0 0 0 / .1)),var(--un-shadow-inset) 0 4px 6px -4px var(--un-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--un-ring-offset-shadow),var(--un-ring-shadow),var(--un-shadow)}._dialogContent_worsp_9._large_worsp_13{padding-left:min(8%,4rem);padding-right:min(8%,4rem);padding-top:min(8%,3rem);padding-bottom:min(8%,3rem)}._dialogContent_worsp_9._compact_worsp_16{padding:min(8%,1.5rem)}@media (min-width: 640px){._dialogContent_worsp_9{max-width:36rem}}@media (min-width: 1024px){._dialogContent_worsp_9{max-width:28rem}}._dialogTitle_worsp_30{text-align:center;font-size:calc(var(--mb-size)*1.5rem);line-height:calc(var(--mb-size)*2rem);font-weight:700}._contentOut_worsp_34{overflow-y:auto}._closeButton_worsp_38{position:absolute;top:.625rem;right:.625rem;width:calc(var(--mb-size)*2rem);height:calc(var(--mb-size)*2rem);display:flex;align-items:center;justify-content:center;border-radius:9999px;border-style:none;background-color:transparent;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;transition-duration:.1s}._closeButton_worsp_38:hover{--un-bg-opacity:1;background-color:rgb(var(--color-gray-100-rgb-value) / var(--un-bg-opacity))}._closeButton_worsp_38:active{--un-bg-opacity:1;background-color:rgb(var(--color-gray-200-rgb-value) / var(--un-bg-opacity))}._closeButtonInner_worsp_44{display:flex;--un-translate-y:-2px;transform:translate(var(--un-translate-x)) translateY(var(--un-translate-y)) translateZ(var(--un-translate-z)) rotate(var(--un-rotate)) rotateX(var(--un-rotate-x)) rotateY(var(--un-rotate-y)) rotate(var(--un-rotate-z)) skew(var(--un-skew-x)) skewY(var(--un-skew-y)) scaleX(var(--un-scale-x)) scaleY(var(--un-scale-y)) scaleZ(var(--un-scale-z));align-items:center;justify-content:center;font-size:calc(var(--mb-size)*1.875rem);line-height:calc(var(--mb-size)*2.25rem);--un-text-opacity:1;color:rgb(var(--color-black-rgb-value) / var(--un-text-opacity));font-weight:200;line-height:1}._primaryActionButton_worsp_49{height:2.5rem;-webkit-appearance:none;appearance:none;border-radius:calc(var(--mb-size)*2.5rem);border-style:none;--un-bg-opacity:1;background-color:rgb(var(--color-primary) / var(--un-bg-opacity));padding-left:calc(var(--mb-size)*1.25rem);padding-right:calc(var(--mb-size)*1.25rem);padding-top:calc(var(--mb-size)*.25rem);padding-bottom:calc(var(--mb-size)*.25rem);text-wrap:nowrap;font-size:calc(var(--mb-size)*.875rem);line-height:calc(var(--mb-size)*1.25rem);--un-text-opacity:1;color:rgb(var(--color-white-rgb-value) / var(--un-text-opacity));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;transition-duration:.1s}._primaryActionButton_worsp_49[disabled]{cursor:not-allowed;--un-bg-opacity:1;background-color:rgb(var(--color-gray-200-rgb-value) / var(--un-bg-opacity));--un-text-opacity:1;color:rgb(var(--color-gray-500-rgb-value) / var(--un-text-opacity));--un-ring-width:0px;--un-ring-offset-shadow:var(--un-ring-inset) 0 0 0 var(--un-ring-offset-width) var(--un-ring-offset-color);--un-ring-shadow:var(--un-ring-inset) 0 0 0 calc(var(--un-ring-width) + var(--un-ring-offset-width)) var(--un-ring-color);box-shadow:var(--un-ring-offset-shadow),var(--un-ring-shadow),var(--un-shadow)}._primaryActionButton_worsp_49[disabled]:hover{--un-bg-opacity:1;background-color:rgb(var(--color-gray-200-rgb-value) / var(--un-bg-opacity));--un-text-opacity:1;color:rgb(var(--color-gray-500-rgb-value) / var(--un-text-opacity))}._primaryActionButton_worsp_49:hover{--un-bg-opacity:1;background-color:rgb(var(--color-accent-700-rgb-value) / var(--un-bg-opacity))}._primaryActionButton_worsp_49:active{--un-bg-opacity:1;background-color:rgb(var(--color-accent-800-rgb-value) / var(--un-bg-opacity))}._primaryActionButton_worsp_49:focus{outline-width:2px;--un-outline-color-opacity:1;outline-color:rgb(var(--color-accent-400-rgb-value) / var(--un-outline-color-opacity));outline-offset:4px;outline-style:solid}._secondaryActionButton_worsp_53{height:2.5rem;-webkit-appearance:none;appearance:none;border-radius:calc(var(--mb-size)*2.5rem);border-style:none;background-color:transparent;padding-left:calc(var(--mb-size)*1.25rem);padding-right:calc(var(--mb-size)*1.25rem);padding-top:calc(var(--mb-size)*.25rem);padding-bottom:calc(var(--mb-size)*.25rem);text-wrap:nowrap;font-size:calc(var(--mb-size)*.875rem);line-height:calc(var(--mb-size)*1.25rem);--un-text-opacity:1;color:rgb(var(--color-primary) / var(--un-text-opacity));--un-ring-width:1px;--un-ring-offset-shadow:var(--un-ring-inset) 0 0 0 var(--un-ring-offset-width) var(--un-ring-offset-color);--un-ring-shadow:var(--un-ring-inset) 0 0 0 calc(var(--un-ring-width) + var(--un-ring-offset-width)) var(--un-ring-color);box-shadow:var(--un-ring-offset-shadow),var(--un-ring-shadow),var(--un-shadow);--un-ring-opacity:1;--un-ring-color:rgb(var(--color-primary) / var(--un-ring-opacity)) ;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;transition-duration:.1s}._secondaryActionButton_worsp_53[disabled]{cursor:not-allowed;--un-bg-opacity:1;background-color:rgb(var(--color-gray-200-rgb-value) / var(--un-bg-opacity));--un-text-opacity:1;color:rgb(var(--color-gray-500-rgb-value) / var(--un-text-opacity));--un-ring-width:0px;--un-ring-offset-shadow:var(--un-ring-inset) 0 0 0 var(--un-ring-offset-width) var(--un-ring-offset-color);--un-ring-shadow:var(--un-ring-inset) 0 0 0 calc(var(--un-ring-width) + var(--un-ring-offset-width)) var(--un-ring-color);box-shadow:var(--un-ring-offset-shadow),var(--un-ring-shadow),var(--un-shadow)}._secondaryActionButton_worsp_53[disabled]:hover{--un-bg-opacity:1;background-color:rgb(var(--color-gray-200-rgb-value) / var(--un-bg-opacity));--un-text-opacity:1;color:rgb(var(--color-gray-500-rgb-value) / var(--un-text-opacity))}._secondaryActionButton_worsp_53:hover{--un-bg-opacity:1;background-color:rgb(var(--color-accent-25-rgb-value) / var(--un-bg-opacity));--un-text-opacity:1;color:rgb(var(--color-accent-700-rgb-value) / var(--un-text-opacity));--un-ring-opacity:1;--un-ring-color:rgb(var(--color-accent-700-rgb-value) / var(--un-ring-opacity)) }._secondaryActionButton_worsp_53:active{--un-bg-opacity:1;background-color:rgb(var(--color-accent-50-rgb-value) / var(--un-bg-opacity));--un-text-opacity:1;color:rgb(var(--color-accent-800-rgb-value) / var(--un-text-opacity));--un-ring-opacity:1;--un-ring-color:rgb(var(--color-accent-800-rgb-value) / var(--un-ring-opacity)) }._secondaryActionButton_worsp_53:focus{outline-width:2px;--un-outline-color-opacity:1;outline-color:rgb(var(--color-accent-400-rgb-value) / var(--un-outline-color-opacity));outline-offset:4px;outline-style:solid}._actions_worsp_57{display:flex;gap:calc(var(--mb-size)*1rem)}._actions_worsp_57 ._primaryActionButton_worsp_49,._actions_worsp_57 ._secondaryActionButton_worsp_53{width:50%}._alertTitle_worsp_64{font-size:calc(var(--mb-size)*1.125rem);line-height:calc(var(--mb-size)*1.75rem);--un-text-opacity:1;color:rgb(var(--color-gray-700-rgb-value) / var(--un-text-opacity));font-weight:400}._alertText_worsp_68{margin-top:calc(var(--mb-size)*1rem);margin-bottom:calc(var(--mb-size)*2rem);padding-left:calc(var(--mb-size)*.5rem);padding-right:calc(var(--mb-size)*.5rem);text-align:center;text-wrap:pretty;--un-text-opacity:1;color:rgb(var(--color-gray-500-rgb-value) / var(--un-text-opacity));font-weight:300;line-height:1.5}*,:before,:after{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / .5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }::backdrop{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / .5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.left-0{left:calc(var(--mb-size)*0rem)}.right-0{right:calc(var(--mb-size)*0rem)}.right-4{right:calc(var(--mb-size)*1rem)}.top-\\[-1px\\]{top:-1px}.top-0{top:calc(var(--mb-size)*0rem)}.has-\\[\\[data-scope\\]\\]\\:z-2:has([data-scope]),.z-2{z-index:2}.z-1{z-index:1}.grid{display:grid}.auto-cols-auto{grid-auto-columns:auto}.grid-cols-\\[1fr_auto_1fr\\]{grid-template-columns:1fr auto 1fr}.block{display:block}.size-12{width:calc(var(--mb-size)*3rem);height:calc(var(--mb-size)*3rem)}.size-6{width:calc(var(--mb-size)*1.5rem);height:calc(var(--mb-size)*1.5rem)}.size-full{width:100%;height:100%}.h-\\[1px\\]{height:1px}.h-full{height:100%}.h-vh{height:100vh}.max-w-\\[100\\%\\]{max-width:100%}.min-h-\\[300px\\]{min-height:300px}.min-w-0{min-width:calc(var(--mb-size)*0rem)}.w-full{width:100%}.flex{display:flex}.shrink-0{flex-shrink:0}.flex-nowrap{flex-wrap:nowrap}.data-\\[state\\=open\\]\\:scale-y-\\[-1\\][data-state=open]{--un-scale-y:-1;transform:translate(var(--un-translate-x)) translateY(var(--un-translate-y)) translateZ(var(--un-translate-z)) rotate(var(--un-rotate)) rotateX(var(--un-rotate-x)) rotateY(var(--un-rotate-y)) rotate(var(--un-rotate-z)) skew(var(--un-skew-x)) skewY(var(--un-skew-y)) scaleX(var(--un-scale-x)) scaleY(var(--un-scale-y)) scaleZ(var(--un-scale-z))}.transform{transform:translate(var(--un-translate-x)) translateY(var(--un-translate-y)) translateZ(var(--un-translate-z)) rotate(var(--un-rotate)) rotateX(var(--un-rotate-x)) rotateY(var(--un-rotate-y)) rotate(var(--un-rotate-z)) skew(var(--un-skew-x)) skewY(var(--un-skew-y)) scaleX(var(--un-scale-x)) scaleY(var(--un-scale-y)) scaleZ(var(--un-scale-z))}.cursor-pointer{cursor:pointer}.disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.select-none{-webkit-user-select:none;user-select:none}.resize{resize:both}.appearance-none{-webkit-appearance:none;appearance:none}.place-items-center{place-items:center}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-self-start{justify-self:start}.justify-self-end{justify-self:end}.justify-self-center{justify-self:center}.gap-\\[1px\\]{gap:1px}.gap-2{gap:calc(var(--mb-size)*.5rem)}.gap-4{gap:calc(var(--mb-size)*1rem)}.overflow-hidden{overflow:hidden}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.rounded-4{border-radius:calc(var(--mb-size)*1rem)}.rounded-full{border-radius:9999px}.rounded-md{border-radius:.375rem}.border-none{border-style:none}.bg-dark-100\\/50{background-color:#3c3c3c80}.bg-dark-500{--un-bg-opacity:1;background-color:rgb(31 31 31 / var(--un-bg-opacity))}.bg-white{--un-bg-opacity:1;background-color:rgb(var(--color-white-rgb-value) / var(--un-bg-opacity))}.data-\\[highlighted\\]\\:bg-gray-500\\/50[data-highlighted]{background-color:rgb(var(--color-gray-500-rgb-value) / .5)}.bg-opacity-50{--un-bg-opacity:.5}.p-2{padding:calc(var(--mb-size)*.5rem)}.px-4{padding-left:calc(var(--mb-size)*1rem);padding-right:calc(var(--mb-size)*1rem)}.py-2{padding-top:calc(var(--mb-size)*.5rem);padding-bottom:calc(var(--mb-size)*.5rem)}.py-3{padding-top:calc(var(--mb-size)*.75rem);padding-bottom:calc(var(--mb-size)*.75rem)}.py-4{padding-top:calc(var(--mb-size)*1rem);padding-bottom:calc(var(--mb-size)*1rem)}.pl-4{padding-left:calc(var(--mb-size)*1rem)}.pr-12{padding-right:calc(var(--mb-size)*3rem)}.text-align-center{text-align:center}.text-base{font-size:calc(var(--mb-size)*1rem);line-height:calc(var(--mb-size)*1.5rem)}.text-sm{font-size:calc(var(--mb-size)*.875rem);line-height:calc(var(--mb-size)*1.25rem)}.color-white{--un-text-opacity:1;color:rgb(var(--color-white-rgb-value) / var(--un-text-opacity))}.font-500{font-weight:500}.disabled\\:opacity-50:disabled{opacity:.5}.shadow{--un-shadow:var(--un-shadow-inset) 0 1px 3px 0 var(--un-shadow-color, rgb(0 0 0 / .1)),var(--un-shadow-inset) 0 1px 2px -1px var(--un-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--un-ring-offset-shadow),var(--un-ring-shadow),var(--un-shadow)}.backdrop-blur{--un-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia);backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia)}.backdrop-blur-xl{--un-backdrop-blur:blur(24px);-webkit-backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia);backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia)}.drop-shadow-md{--un-drop-shadow:drop-shadow(0 4px 3px var(--un-drop-shadow-color, rgb(0 0 0 / .07))) drop-shadow(0 2px 2px var(--un-drop-shadow-color, rgb(0 0 0 / .06)));filter:var(--un-blur) var(--un-brightness) var(--un-contrast) var(--un-drop-shadow) var(--un-grayscale) var(--un-hue-rotate) var(--un-invert) var(--un-saturate) var(--un-sepia)}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-300{transition-duration:.3s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.lerp\\:px-3\\@xs\\,8\\@lg{padding-inline:clamp(calc(var(--mb-size)*.75rem),calc(var(--mb-size)*.75rem) + (100vw - 380px) * .031055900621118012,calc(var(--mb-size)*2rem))}@supports (height:100dvh){.supports-\\[\\(height\\:100dvh\\)\\]\\:h-dvh{height:100dvh}}")})();
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import { createContext as be, onCleanup as ie, useContext as pe, onMount as Q, createSignal as z, Show as E, Index as qe, createRoot as He, getOwner as ve, splitProps as We, createEffect as Ge } from "solid-js";
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
1
|
+
(function() {
|
|
2
|
+
"use strict";
|
|
3
|
+
((cssCode) => {
|
|
4
|
+
window.__mbCameraManagerCssCode = cssCode;
|
|
5
|
+
})("._dialogPositioner_worsp_1 {\n position:fixed;top:calc(var(--mb-size)*0rem);left:calc(var(--mb-size)*0rem);display:grid;height:100vh;width:100%;padding:calc(var(--mb-size)*2rem);\n}@supports (height:100dvh){._dialogPositioner_worsp_1{height:100dvh;}}\n\n._dialogBackdrop_worsp_5 {\n position:absolute;top:calc(var(--mb-size)*0rem);left:calc(var(--mb-size)*0rem);width:100%;height:100%;--un-bg-opacity:1;background-color:rgb(var(--color-black-rgb-value) / var(--un-bg-opacity)) /* rgb(var(--color-black-rgb-value) / <alpha-value>) */;--un-bg-opacity:0.5;--un-backdrop-blur:blur(4px);-webkit-backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia);backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia);\n}\n\n._dialogContent_worsp_9 {\n position:relative;max-height:calc(100dvh - 4rem);max-width:28rem;display:flex;flex-direction:column;place-self:center;border-radius:0.5rem;--un-bg-opacity:1;background-color:rgb(var(--color-white-rgb-value) / var(--un-bg-opacity)) /* rgb(var(--color-white-rgb-value) / <alpha-value>) */;padding-left:min(8%,3rem);padding-right:min(8%,3rem);padding-top:min(8%,1.5rem);padding-bottom:min(8%,1.5rem);--un-text-opacity:1;color:rgb(15 15 15 / var(--un-text-opacity)) /* #0f0f0f */;--un-shadow:var(--un-shadow-inset) 0 10px 15px -3px var(--un-shadow-color, rgb(0 0 0 / 0.1)),var(--un-shadow-inset) 0 4px 6px -4px var(--un-shadow-color, rgb(0 0 0 / 0.1));box-shadow:var(--un-ring-offset-shadow), var(--un-ring-shadow), var(--un-shadow);\n}\n._dialogContent_worsp_9._large_worsp_13 {\n padding-left:min(8%,4rem);padding-right:min(8%,4rem);padding-top:min(8%,3rem);padding-bottom:min(8%,3rem);\n}\n._dialogContent_worsp_9._compact_worsp_16 {\n padding:min(8%,1.5rem);\n}\n@media (min-width: 640px){\n ._dialogContent_worsp_9 {\n max-width:36rem;\n }\n}\n@media (min-width: 1024px){\n ._dialogContent_worsp_9 {\n max-width:28rem;\n }\n}\n\n._dialogTitle_worsp_30 {\n text-align:center;font-size:calc(var(--mb-size)*1.5rem);line-height:calc(var(--mb-size)*2rem);font-weight:700;\n}\n\n._contentOut_worsp_34 {\n overflow-y:auto;\n}\n\n._closeButton_worsp_38 {\n position:absolute;top:0.625rem;right:0.625rem;width:calc(var(--mb-size)*2rem);height:calc(var(--mb-size)*2rem);display:flex;align-items:center;justify-content:center;border-radius:9999px;border-style:none;background-color:transparent /* transparent */;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;transition-duration:100ms;\n}._closeButton_worsp_38:hover{--un-bg-opacity:1;background-color:rgb(var(--color-gray-100-rgb-value) / var(--un-bg-opacity)) /* rgb(var(--color-gray-100-rgb-value) / <alpha-value>) */;}._closeButton_worsp_38:active{--un-bg-opacity:1;background-color:rgb(var(--color-gray-200-rgb-value) / var(--un-bg-opacity)) /* rgb(var(--color-gray-200-rgb-value) / <alpha-value>) */;}\n\n._closeButtonInner_worsp_44 {\n display:flex;--un-translate-y:-2px;transform:translateX(var(--un-translate-x)) translateY(var(--un-translate-y)) translateZ(var(--un-translate-z)) rotate(var(--un-rotate)) rotateX(var(--un-rotate-x)) rotateY(var(--un-rotate-y)) rotateZ(var(--un-rotate-z)) skewX(var(--un-skew-x)) skewY(var(--un-skew-y)) scaleX(var(--un-scale-x)) scaleY(var(--un-scale-y)) scaleZ(var(--un-scale-z));align-items:center;justify-content:center;font-size:calc(var(--mb-size)*1.875rem);line-height:calc(var(--mb-size)*2.25rem);--un-text-opacity:1;color:rgb(var(--color-black-rgb-value) / var(--un-text-opacity)) /* rgb(var(--color-black-rgb-value) / <alpha-value>) */;font-weight:200;line-height:1;\n}\n\n._primaryActionButton_worsp_49 {\n height:2.5rem;-webkit-appearance:none;appearance:none;border-radius:calc(var(--mb-size)*2.5rem);border-style:none;--un-bg-opacity:1;background-color:rgb(var(--color-primary) / var(--un-bg-opacity)) /* rgb(var(--color-primary) / <alpha-value>) */;padding-left:calc(var(--mb-size)*1.25rem);padding-right:calc(var(--mb-size)*1.25rem);padding-top:calc(var(--mb-size)*0.25rem);padding-bottom:calc(var(--mb-size)*0.25rem);text-wrap:nowrap;font-size:calc(var(--mb-size)*0.875rem);line-height:calc(var(--mb-size)*1.25rem);--un-text-opacity:1;color:rgb(var(--color-white-rgb-value) / var(--un-text-opacity)) /* rgb(var(--color-white-rgb-value) / <alpha-value>) */;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;transition-duration:100ms;\n}._primaryActionButton_worsp_49[disabled]{cursor:not-allowed;--un-bg-opacity:1;background-color:rgb(var(--color-gray-200-rgb-value) / var(--un-bg-opacity)) /* rgb(var(--color-gray-200-rgb-value) / <alpha-value>) */;--un-text-opacity:1;color:rgb(var(--color-gray-500-rgb-value) / var(--un-text-opacity)) /* rgb(var(--color-gray-500-rgb-value) / <alpha-value>) */;--un-ring-width:0px;--un-ring-offset-shadow:var(--un-ring-inset) 0 0 0 var(--un-ring-offset-width) var(--un-ring-offset-color);--un-ring-shadow:var(--un-ring-inset) 0 0 0 calc(var(--un-ring-width) + var(--un-ring-offset-width)) var(--un-ring-color);box-shadow:var(--un-ring-offset-shadow), var(--un-ring-shadow), var(--un-shadow);}._primaryActionButton_worsp_49[disabled]:hover{--un-bg-opacity:1;background-color:rgb(var(--color-gray-200-rgb-value) / var(--un-bg-opacity)) /* rgb(var(--color-gray-200-rgb-value) / <alpha-value>) */;--un-text-opacity:1;color:rgb(var(--color-gray-500-rgb-value) / var(--un-text-opacity)) /* rgb(var(--color-gray-500-rgb-value) / <alpha-value>) */;}._primaryActionButton_worsp_49:hover{--un-bg-opacity:1;background-color:rgb(var(--color-accent-700-rgb-value) / var(--un-bg-opacity)) /* rgb(var(--color-accent-700-rgb-value) / <alpha-value>) */;}._primaryActionButton_worsp_49:active{--un-bg-opacity:1;background-color:rgb(var(--color-accent-800-rgb-value) / var(--un-bg-opacity)) /* rgb(var(--color-accent-800-rgb-value) / <alpha-value>) */;}._primaryActionButton_worsp_49:focus{outline-width:2px;--un-outline-color-opacity:1;outline-color:rgb(var(--color-accent-400-rgb-value) / var(--un-outline-color-opacity)) /* rgb(var(--color-accent-400-rgb-value) / <alpha-value>) */;outline-offset:4px;outline-style:solid;}\n\n._secondaryActionButton_worsp_53 {\n height:2.5rem;-webkit-appearance:none;appearance:none;border-radius:calc(var(--mb-size)*2.5rem);border-style:none;background-color:transparent /* transparent */;padding-left:calc(var(--mb-size)*1.25rem);padding-right:calc(var(--mb-size)*1.25rem);padding-top:calc(var(--mb-size)*0.25rem);padding-bottom:calc(var(--mb-size)*0.25rem);text-wrap:nowrap;font-size:calc(var(--mb-size)*0.875rem);line-height:calc(var(--mb-size)*1.25rem);--un-text-opacity:1;color:rgb(var(--color-primary) / var(--un-text-opacity)) /* rgb(var(--color-primary) / <alpha-value>) */;--un-ring-width:1px;--un-ring-offset-shadow:var(--un-ring-inset) 0 0 0 var(--un-ring-offset-width) var(--un-ring-offset-color);--un-ring-shadow:var(--un-ring-inset) 0 0 0 calc(var(--un-ring-width) + var(--un-ring-offset-width)) var(--un-ring-color);box-shadow:var(--un-ring-offset-shadow), var(--un-ring-shadow), var(--un-shadow);--un-ring-opacity:1;--un-ring-color:rgb(var(--color-primary) / var(--un-ring-opacity)) /* rgb(var(--color-primary) / <alpha-value>) */;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;transition-duration:100ms;\n}._secondaryActionButton_worsp_53[disabled]{cursor:not-allowed;--un-bg-opacity:1;background-color:rgb(var(--color-gray-200-rgb-value) / var(--un-bg-opacity)) /* rgb(var(--color-gray-200-rgb-value) / <alpha-value>) */;--un-text-opacity:1;color:rgb(var(--color-gray-500-rgb-value) / var(--un-text-opacity)) /* rgb(var(--color-gray-500-rgb-value) / <alpha-value>) */;--un-ring-width:0px;--un-ring-offset-shadow:var(--un-ring-inset) 0 0 0 var(--un-ring-offset-width) var(--un-ring-offset-color);--un-ring-shadow:var(--un-ring-inset) 0 0 0 calc(var(--un-ring-width) + var(--un-ring-offset-width)) var(--un-ring-color);box-shadow:var(--un-ring-offset-shadow), var(--un-ring-shadow), var(--un-shadow);}._secondaryActionButton_worsp_53[disabled]:hover{--un-bg-opacity:1;background-color:rgb(var(--color-gray-200-rgb-value) / var(--un-bg-opacity)) /* rgb(var(--color-gray-200-rgb-value) / <alpha-value>) */;--un-text-opacity:1;color:rgb(var(--color-gray-500-rgb-value) / var(--un-text-opacity)) /* rgb(var(--color-gray-500-rgb-value) / <alpha-value>) */;}._secondaryActionButton_worsp_53:hover{--un-bg-opacity:1;background-color:rgb(var(--color-accent-25-rgb-value) / var(--un-bg-opacity)) /* rgb(var(--color-accent-25-rgb-value) / <alpha-value>) */;--un-text-opacity:1;color:rgb(var(--color-accent-700-rgb-value) / var(--un-text-opacity)) /* rgb(var(--color-accent-700-rgb-value) / <alpha-value>) */;--un-ring-opacity:1;--un-ring-color:rgb(var(--color-accent-700-rgb-value) / var(--un-ring-opacity)) /* rgb(var(--color-accent-700-rgb-value) / <alpha-value>) */;}._secondaryActionButton_worsp_53:active{--un-bg-opacity:1;background-color:rgb(var(--color-accent-50-rgb-value) / var(--un-bg-opacity)) /* rgb(var(--color-accent-50-rgb-value) / <alpha-value>) */;--un-text-opacity:1;color:rgb(var(--color-accent-800-rgb-value) / var(--un-text-opacity)) /* rgb(var(--color-accent-800-rgb-value) / <alpha-value>) */;--un-ring-opacity:1;--un-ring-color:rgb(var(--color-accent-800-rgb-value) / var(--un-ring-opacity)) /* rgb(var(--color-accent-800-rgb-value) / <alpha-value>) */;}._secondaryActionButton_worsp_53:focus{outline-width:2px;--un-outline-color-opacity:1;outline-color:rgb(var(--color-accent-400-rgb-value) / var(--un-outline-color-opacity)) /* rgb(var(--color-accent-400-rgb-value) / <alpha-value>) */;outline-offset:4px;outline-style:solid;}\n\n._actions_worsp_57 {\n display:flex;gap:calc(var(--mb-size)*1rem);\n}\n._actions_worsp_57 ._primaryActionButton_worsp_49, ._actions_worsp_57 ._secondaryActionButton_worsp_53 {\n width:50%;\n}\n\n._alertTitle_worsp_64 {\n font-size:calc(var(--mb-size)*1.125rem);line-height:calc(var(--mb-size)*1.75rem);--un-text-opacity:1;color:rgb(var(--color-gray-700-rgb-value) / var(--un-text-opacity)) /* rgb(var(--color-gray-700-rgb-value) / <alpha-value>) */;font-weight:400;\n}\n\n._alertText_worsp_68 {\n margin-top:calc(var(--mb-size)*1rem);margin-bottom:calc(var(--mb-size)*2rem);padding-left:calc(var(--mb-size)*0.5rem);padding-right:calc(var(--mb-size)*0.5rem);text-align:center;text-wrap:pretty;--un-text-opacity:1;color:rgb(var(--color-gray-500-rgb-value) / var(--un-text-opacity)) /* rgb(var(--color-gray-500-rgb-value) / <alpha-value>) */;font-weight:300;line-height:1.5;\n} *,::before,::after{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / 0.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: ;}::backdrop{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / 0.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: ;}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0;}.pointer-events-none{pointer-events:none;}.absolute{position:absolute;}.fixed{position:fixed;}.relative{position:relative;}.left-0{left:calc(var(--mb-size)*0rem);}.right-0{right:calc(var(--mb-size)*0rem);}.right-4{right:calc(var(--mb-size)*1rem);}.top-\\[-1px\\]{top:-1px;}.top-0{top:calc(var(--mb-size)*0rem);}.z-1{z-index:1;}.has-\\[\\[data-scope\\]\\]\\:z-2:has([data-scope]),.z-2{z-index:2;}.grid{display:grid;}.auto-cols-auto{grid-auto-columns:auto;}.grid-cols-\\[1fr_auto_1fr\\]{grid-template-columns:1fr auto 1fr;}.block{display:block;}.size-12{width:calc(var(--mb-size)*3rem);height:calc(var(--mb-size)*3rem);}.size-6{width:calc(var(--mb-size)*1.5rem);height:calc(var(--mb-size)*1.5rem);}.size-full{width:100%;height:100%;}.h-\\[1px\\]{height:1px;}.h-full{height:100%;}.h-vh{height:100vh;}.max-w-\\[100\\%\\]{max-width:100%;}.min-h-\\[300px\\]{min-height:300px;}.min-w-0{min-width:calc(var(--mb-size)*0rem);}.w-full{width:100%;}.flex{display:flex;}.shrink-0{flex-shrink:0;}.flex-nowrap{flex-wrap:nowrap;}.data-\\[state\\=open\\]\\:scale-y-\\[-1\\][data-state=open]{--un-scale-y:-1;transform:translateX(var(--un-translate-x)) translateY(var(--un-translate-y)) translateZ(var(--un-translate-z)) rotate(var(--un-rotate)) rotateX(var(--un-rotate-x)) rotateY(var(--un-rotate-y)) rotateZ(var(--un-rotate-z)) skewX(var(--un-skew-x)) skewY(var(--un-skew-y)) scaleX(var(--un-scale-x)) scaleY(var(--un-scale-y)) scaleZ(var(--un-scale-z));}.transform{transform:translateX(var(--un-translate-x)) translateY(var(--un-translate-y)) translateZ(var(--un-translate-z)) rotate(var(--un-rotate)) rotateX(var(--un-rotate-x)) rotateY(var(--un-rotate-y)) rotateZ(var(--un-rotate-z)) skewX(var(--un-skew-x)) skewY(var(--un-skew-y)) scaleX(var(--un-scale-x)) scaleY(var(--un-scale-y)) scaleZ(var(--un-scale-z));}.cursor-pointer{cursor:pointer;}.disabled\\:cursor-not-allowed:disabled{cursor:not-allowed;}.select-none{-webkit-user-select:none;user-select:none;}.resize{resize:both;}.appearance-none{-webkit-appearance:none;appearance:none;}.place-items-center{place-items:center;}.items-center{align-items:center;}.justify-between{justify-content:space-between;}.justify-self-start{justify-self:start;}.justify-self-end{justify-self:end;}.justify-self-center{justify-self:center;}.gap-\\[1px\\]{gap:1px;}.gap-2{gap:calc(var(--mb-size)*0.5rem);}.gap-4{gap:calc(var(--mb-size)*1rem);}.overflow-hidden{overflow:hidden;}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}.whitespace-nowrap{white-space:nowrap;}.rounded-4{border-radius:calc(var(--mb-size)*1rem);}.rounded-full{border-radius:9999px;}.rounded-md{border-radius:0.375rem;}.border-none{border-style:none;}.bg-dark-100\\/50{background-color:rgb(60 60 60 / 0.5) /* #3c3c3c */;}.bg-dark-500{--un-bg-opacity:1;background-color:rgb(31 31 31 / var(--un-bg-opacity)) /* #1f1f1f */;}.data-\\[highlighted\\]\\:bg-gray-500\\/50[data-highlighted]{background-color:rgb(var(--color-gray-500-rgb-value) / 0.5) /* rgb(var(--color-gray-500-rgb-value) / <alpha-value>) */;}.bg-white{--un-bg-opacity:1;background-color:rgb(var(--color-white-rgb-value) / var(--un-bg-opacity)) /* rgb(var(--color-white-rgb-value) / <alpha-value>) */;}.bg-opacity-50{--un-bg-opacity:0.5;}.p-2{padding:calc(var(--mb-size)*0.5rem);}.px-4{padding-left:calc(var(--mb-size)*1rem);padding-right:calc(var(--mb-size)*1rem);}.py-2{padding-top:calc(var(--mb-size)*0.5rem);padding-bottom:calc(var(--mb-size)*0.5rem);}.py-3{padding-top:calc(var(--mb-size)*0.75rem);padding-bottom:calc(var(--mb-size)*0.75rem);}.py-4{padding-top:calc(var(--mb-size)*1rem);padding-bottom:calc(var(--mb-size)*1rem);}.pl-4{padding-left:calc(var(--mb-size)*1rem);}.pr-12{padding-right:calc(var(--mb-size)*3rem);}.text-align-center{text-align:center;}.text-base{font-size:calc(var(--mb-size)*1rem);line-height:calc(var(--mb-size)*1.5rem);}.text-sm{font-size:calc(var(--mb-size)*0.875rem);line-height:calc(var(--mb-size)*1.25rem);}.color-white{--un-text-opacity:1;color:rgb(var(--color-white-rgb-value) / var(--un-text-opacity)) /* rgb(var(--color-white-rgb-value) / <alpha-value>) */;}.font-500{font-weight:500;}.disabled\\:opacity-50:disabled{opacity:0.5;}.shadow{--un-shadow:var(--un-shadow-inset) 0 1px 3px 0 var(--un-shadow-color, rgb(0 0 0 / 0.1)),var(--un-shadow-inset) 0 1px 2px -1px var(--un-shadow-color, rgb(0 0 0 / 0.1));box-shadow:var(--un-ring-offset-shadow), var(--un-ring-shadow), var(--un-shadow);}.backdrop-blur{--un-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia);backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia);}.backdrop-blur-xl{--un-backdrop-blur:blur(24px);-webkit-backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia);backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia);}.drop-shadow-md{--un-drop-shadow:drop-shadow(0 4px 3px var(--un-drop-shadow-color, rgb(0 0 0 / 0.07))) drop-shadow(0 2px 2px var(--un-drop-shadow-color, rgb(0 0 0 / 0.06)));filter:var(--un-blur) var(--un-brightness) var(--un-contrast) var(--un-drop-shadow) var(--un-grayscale) var(--un-hue-rotate) var(--un-invert) var(--un-saturate) var(--un-sepia);}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;}.duration-300{transition-duration:300ms;}.ease-in-out{transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);}@keyframes __un_qm{0%{box-shadow:inset 4px 4px #ff1e90, inset -4px -4px #ff1e90}100%{box-shadow:inset 8px 8px #3399ff, inset -8px -8px #3399ff}} .\\?{animation:__un_qm 0.5s ease-in-out alternate infinite;}.lerp\\:px-3\\@xs\\,8\\@lg{padding-inline:clamp(calc(var(--mb-size)*0.75rem), calc(var(--mb-size)*0.75rem) + (100vw - 380px) * 0.031055900621118012, calc(var(--mb-size)*2rem));}@supports (height:100dvh){.supports-\\[\\(height\\:100dvh\\)\\]\\:h-dvh{height:100dvh;}}");
|
|
6
|
+
})();
|
|
7
|
+
import { subscribeWithSelector } from "zustand/middleware";
|
|
8
|
+
import { createStore } from "zustand/vanilla";
|
|
9
|
+
import { createComponent, use, template, spread, mergeProps, insert, memo, isServer, delegateEvents, effect, className, Portal, Dynamic, render } from "solid-js/web";
|
|
10
|
+
import { createContext, onCleanup, useContext, onMount, createSignal, Show, Index, createRoot, getOwner, splitProps, createEffect } from "solid-js";
|
|
11
|
+
import { createWithSignal } from "solid-zustand";
|
|
12
|
+
import { createStore as createStore$1 } from "solid-js/store";
|
|
13
|
+
import { EnvironmentProvider } from "@ark-ui/solid/environment";
|
|
14
|
+
import { Dialog } from "@ark-ui/solid/dialog";
|
|
15
|
+
import { Select, createListCollection } from "@ark-ui/solid/select";
|
|
16
|
+
import { Tooltip } from "@ark-ui/solid/tooltip";
|
|
17
|
+
if (typeof HTMLVideoElement !== "undefined" && !("requestVideoFrameCallback" in HTMLVideoElement.prototype) && "getVideoPlaybackQuality" in HTMLVideoElement.prototype) {
|
|
18
|
+
HTMLVideoElement.prototype._rvfcpolyfillmap = {};
|
|
19
|
+
HTMLVideoElement.prototype.requestVideoFrameCallback = function(callback) {
|
|
20
|
+
const handle = performance.now();
|
|
21
|
+
const quality = this.getVideoPlaybackQuality();
|
|
22
|
+
const baseline = this.mozPresentedFrames || this.mozPaintedFrames || quality.totalVideoFrames - quality.droppedVideoFrames;
|
|
23
|
+
const check = (old, now) => {
|
|
24
|
+
const newquality = this.getVideoPlaybackQuality();
|
|
25
|
+
const presentedFrames = this.mozPresentedFrames || this.mozPaintedFrames || newquality.totalVideoFrames - newquality.droppedVideoFrames;
|
|
26
|
+
if (presentedFrames > baseline) {
|
|
27
|
+
const processingDuration = this.mozFrameDelay || newquality.totalFrameDelay - quality.totalFrameDelay || 0;
|
|
28
|
+
const timediff = now - old;
|
|
29
|
+
callback(now, {
|
|
30
|
+
presentationTime: now + processingDuration * 1e3,
|
|
31
|
+
expectedDisplayTime: now + timediff,
|
|
32
|
+
width: this.videoWidth,
|
|
33
|
+
height: this.videoHeight,
|
|
34
|
+
mediaTime: Math.max(0, this.currentTime || 0) + timediff / 1e3,
|
|
35
|
+
presentedFrames,
|
|
36
|
+
processingDuration
|
|
37
|
+
});
|
|
38
|
+
delete this._rvfcpolyfillmap[handle];
|
|
39
|
+
} else {
|
|
40
|
+
this._rvfcpolyfillmap[handle] = requestAnimationFrame((newer) => check(now, newer));
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
this._rvfcpolyfillmap[handle] = requestAnimationFrame((newer) => check(handle, newer));
|
|
44
|
+
return handle;
|
|
28
45
|
};
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
46
|
+
HTMLVideoElement.prototype.cancelVideoFrameCallback = function(handle) {
|
|
47
|
+
cancelAnimationFrame(this._rvfcpolyfillmap[handle]);
|
|
48
|
+
delete this._rvfcpolyfillmap[handle];
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const initialState$1 = {
|
|
34
52
|
cameras: [],
|
|
35
53
|
facingFilter: void 0,
|
|
36
54
|
videoElement: void 0,
|
|
37
55
|
playbackState: "idle",
|
|
38
56
|
selectedCamera: void 0,
|
|
39
|
-
isSwappingCamera:
|
|
40
|
-
isQueryingCameras:
|
|
41
|
-
mirrorX:
|
|
57
|
+
isSwappingCamera: false,
|
|
58
|
+
isQueryingCameras: false,
|
|
59
|
+
mirrorX: false,
|
|
42
60
|
errorState: void 0
|
|
43
|
-
}
|
|
61
|
+
};
|
|
62
|
+
const cameraManagerStore = createStore()(
|
|
44
63
|
// this is important! Otherwise solid-zustand will start mutating the initial state
|
|
45
|
-
|
|
46
|
-
)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
64
|
+
subscribeWithSelector(() => structuredClone(initialState$1))
|
|
65
|
+
);
|
|
66
|
+
const resetCameraManagerStore = () => {
|
|
67
|
+
console.debug("Stopping all cameras and resetting the `cameraManagerStore`.");
|
|
68
|
+
cameraManagerStore.getState().cameras.forEach((camera) => {
|
|
69
|
+
camera.stopStream();
|
|
70
|
+
});
|
|
71
|
+
cameraManagerStore.setState(structuredClone(initialState$1));
|
|
72
|
+
};
|
|
73
|
+
const backCameraKeywords = [
|
|
51
74
|
// English
|
|
52
75
|
"back",
|
|
53
76
|
"rear",
|
|
@@ -118,7 +141,8 @@ const ye = {
|
|
|
118
141
|
"बैक",
|
|
119
142
|
// Latin American Spanish
|
|
120
143
|
"posterior"
|
|
121
|
-
]
|
|
144
|
+
];
|
|
145
|
+
const frontCameraKeywords = [
|
|
122
146
|
// English
|
|
123
147
|
"front",
|
|
124
148
|
// German
|
|
@@ -185,38 +209,66 @@ const ye = {
|
|
|
185
209
|
"फ्रंट",
|
|
186
210
|
// Latin American Spanish
|
|
187
211
|
"frontal"
|
|
188
|
-
]
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
212
|
+
];
|
|
213
|
+
const containsKeyword = (string, keywords) => {
|
|
214
|
+
return keywords.some((keyword) => string.toLowerCase().includes(keyword));
|
|
215
|
+
};
|
|
216
|
+
const isBackCameraName = (string) => containsKeyword(string, backCameraKeywords);
|
|
217
|
+
const isFrontCameraName = (string) => containsKeyword(string, frontCameraKeywords);
|
|
218
|
+
var _createClass = /* @__PURE__ */ function() {
|
|
219
|
+
function defineProperties(target, props) {
|
|
220
|
+
for (var i = 0; i < props.length; i++) {
|
|
221
|
+
var descriptor = props[i];
|
|
222
|
+
descriptor.enumerable = descriptor.enumerable || false;
|
|
223
|
+
descriptor.configurable = true;
|
|
224
|
+
if ("value" in descriptor) descriptor.writable = true;
|
|
225
|
+
Object.defineProperty(target, descriptor.key, descriptor);
|
|
194
226
|
}
|
|
195
227
|
}
|
|
196
|
-
return function(
|
|
197
|
-
|
|
228
|
+
return function(Constructor, protoProps, staticProps) {
|
|
229
|
+
if (protoProps) defineProperties(Constructor.prototype, protoProps);
|
|
230
|
+
if (staticProps) defineProperties(Constructor, staticProps);
|
|
231
|
+
return Constructor;
|
|
198
232
|
};
|
|
199
|
-
}()
|
|
200
|
-
|
|
201
|
-
|
|
233
|
+
}();
|
|
234
|
+
var _templateObject = _taggedTemplateLiteral(["", ""], ["", ""]);
|
|
235
|
+
function _taggedTemplateLiteral(strings, raw) {
|
|
236
|
+
return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } }));
|
|
202
237
|
}
|
|
203
|
-
function
|
|
204
|
-
if (!(
|
|
238
|
+
function _classCallCheck(instance, Constructor) {
|
|
239
|
+
if (!(instance instanceof Constructor)) {
|
|
205
240
|
throw new TypeError("Cannot call a class as a function");
|
|
241
|
+
}
|
|
206
242
|
}
|
|
207
|
-
var
|
|
208
|
-
function
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
243
|
+
var TemplateTag = function() {
|
|
244
|
+
function TemplateTag2() {
|
|
245
|
+
var _this = this;
|
|
246
|
+
for (var _len = arguments.length, transformers = Array(_len), _key = 0; _key < _len; _key++) {
|
|
247
|
+
transformers[_key] = arguments[_key];
|
|
248
|
+
}
|
|
249
|
+
_classCallCheck(this, TemplateTag2);
|
|
250
|
+
this.tag = function(strings) {
|
|
251
|
+
for (var _len2 = arguments.length, expressions = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|
252
|
+
expressions[_key2 - 1] = arguments[_key2];
|
|
253
|
+
}
|
|
254
|
+
if (typeof strings === "function") {
|
|
255
|
+
return _this.interimTag.bind(_this, strings);
|
|
256
|
+
}
|
|
257
|
+
if (typeof strings === "string") {
|
|
258
|
+
return _this.transformEndResult(strings);
|
|
259
|
+
}
|
|
260
|
+
strings = strings.map(_this.transformString.bind(_this));
|
|
261
|
+
return _this.transformEndResult(strings.reduce(_this.processSubstitutions.bind(_this, expressions)));
|
|
262
|
+
};
|
|
263
|
+
if (transformers.length > 0 && Array.isArray(transformers[0])) {
|
|
264
|
+
transformers = transformers[0];
|
|
265
|
+
}
|
|
266
|
+
this.transformers = transformers.map(function(transformer) {
|
|
267
|
+
return typeof transformer === "function" ? transformer() : transformer;
|
|
268
|
+
});
|
|
269
|
+
return this.tag;
|
|
270
|
+
}
|
|
271
|
+
_createClass(TemplateTag2, [{
|
|
220
272
|
key: "interimTag",
|
|
221
273
|
/**
|
|
222
274
|
* An intermediary template tag that receives a template tag and passes the result of calling the template with the received
|
|
@@ -226,10 +278,11 @@ var _ = function() {
|
|
|
226
278
|
* @param {...*} ...substitutions - `substitutions` is an array of all substitutions in the template
|
|
227
279
|
* @return {*} - the final processed value
|
|
228
280
|
*/
|
|
229
|
-
value: function(
|
|
230
|
-
for (var
|
|
231
|
-
|
|
232
|
-
|
|
281
|
+
value: function interimTag(previousTag, template2) {
|
|
282
|
+
for (var _len3 = arguments.length, substitutions = Array(_len3 > 2 ? _len3 - 2 : 0), _key3 = 2; _key3 < _len3; _key3++) {
|
|
283
|
+
substitutions[_key3 - 2] = arguments[_key3];
|
|
284
|
+
}
|
|
285
|
+
return this.tag(_templateObject, previousTag.apply(void 0, [template2].concat(substitutions)));
|
|
233
286
|
}
|
|
234
287
|
/**
|
|
235
288
|
* Performs bulk processing on the tagged template, transforming each substitution and then
|
|
@@ -241,9 +294,9 @@ var _ = function() {
|
|
|
241
294
|
*/
|
|
242
295
|
}, {
|
|
243
296
|
key: "processSubstitutions",
|
|
244
|
-
value: function(
|
|
245
|
-
var
|
|
246
|
-
return "".concat(
|
|
297
|
+
value: function processSubstitutions(substitutions, resultSoFar, remainingPart) {
|
|
298
|
+
var substitution = this.transformSubstitution(substitutions.shift(), resultSoFar);
|
|
299
|
+
return "".concat(resultSoFar, substitution, remainingPart);
|
|
247
300
|
}
|
|
248
301
|
/**
|
|
249
302
|
* Iterate through each transformer, applying the transformer's `onString` method to the template
|
|
@@ -253,11 +306,11 @@ var _ = function() {
|
|
|
253
306
|
*/
|
|
254
307
|
}, {
|
|
255
308
|
key: "transformString",
|
|
256
|
-
value: function(
|
|
257
|
-
var
|
|
258
|
-
return
|
|
309
|
+
value: function transformString(str) {
|
|
310
|
+
var cb = function cb2(res, transform) {
|
|
311
|
+
return transform.onString ? transform.onString(res) : res;
|
|
259
312
|
};
|
|
260
|
-
return this.transformers.reduce(
|
|
313
|
+
return this.transformers.reduce(cb, str);
|
|
261
314
|
}
|
|
262
315
|
/**
|
|
263
316
|
* When a substitution is encountered, iterates through each transformer and applies the transformer's
|
|
@@ -268,11 +321,11 @@ var _ = function() {
|
|
|
268
321
|
*/
|
|
269
322
|
}, {
|
|
270
323
|
key: "transformSubstitution",
|
|
271
|
-
value: function(
|
|
272
|
-
var
|
|
273
|
-
return
|
|
324
|
+
value: function transformSubstitution(substitution, resultSoFar) {
|
|
325
|
+
var cb = function cb2(res, transform) {
|
|
326
|
+
return transform.onSubstitution ? transform.onSubstitution(res, resultSoFar) : res;
|
|
274
327
|
};
|
|
275
|
-
return this.transformers.reduce(
|
|
328
|
+
return this.transformers.reduce(cb, substitution);
|
|
276
329
|
}
|
|
277
330
|
/**
|
|
278
331
|
* Iterates through each transformer, applying the transformer's `onEndResult` method to the
|
|
@@ -282,120 +335,161 @@ var _ = function() {
|
|
|
282
335
|
*/
|
|
283
336
|
}, {
|
|
284
337
|
key: "transformEndResult",
|
|
285
|
-
value: function(
|
|
286
|
-
var
|
|
287
|
-
return
|
|
338
|
+
value: function transformEndResult(endResult) {
|
|
339
|
+
var cb = function cb2(res, transform) {
|
|
340
|
+
return transform.onEndResult ? transform.onEndResult(res) : res;
|
|
288
341
|
};
|
|
289
|
-
return this.transformers.reduce(
|
|
342
|
+
return this.transformers.reduce(cb, endResult);
|
|
290
343
|
}
|
|
291
|
-
}])
|
|
292
|
-
|
|
293
|
-
|
|
344
|
+
}]);
|
|
345
|
+
return TemplateTag2;
|
|
346
|
+
}();
|
|
347
|
+
var trimResultTransformer = function trimResultTransformer2() {
|
|
348
|
+
var side = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : "";
|
|
294
349
|
return {
|
|
295
|
-
onEndResult: function(
|
|
296
|
-
if (
|
|
297
|
-
return
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
if (
|
|
301
|
-
return
|
|
302
|
-
|
|
350
|
+
onEndResult: function onEndResult(endResult) {
|
|
351
|
+
if (side === "") {
|
|
352
|
+
return endResult.trim();
|
|
353
|
+
}
|
|
354
|
+
side = side.toLowerCase();
|
|
355
|
+
if (side === "start" || side === "left") {
|
|
356
|
+
return endResult.replace(/^\s*/, "");
|
|
357
|
+
}
|
|
358
|
+
if (side === "end" || side === "right") {
|
|
359
|
+
return endResult.replace(/\s*$/, "");
|
|
360
|
+
}
|
|
361
|
+
throw new Error("Side not supported: " + side);
|
|
303
362
|
}
|
|
304
363
|
};
|
|
305
364
|
};
|
|
306
|
-
function
|
|
307
|
-
if (Array.isArray(
|
|
308
|
-
for (var
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
365
|
+
function _toConsumableArray(arr) {
|
|
366
|
+
if (Array.isArray(arr)) {
|
|
367
|
+
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
|
|
368
|
+
arr2[i] = arr[i];
|
|
369
|
+
}
|
|
370
|
+
return arr2;
|
|
371
|
+
} else {
|
|
372
|
+
return Array.from(arr);
|
|
373
|
+
}
|
|
313
374
|
}
|
|
314
|
-
var
|
|
315
|
-
var
|
|
375
|
+
var stripIndentTransformer = function stripIndentTransformer2() {
|
|
376
|
+
var type = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : "initial";
|
|
316
377
|
return {
|
|
317
|
-
onEndResult: function(
|
|
318
|
-
if (
|
|
319
|
-
var
|
|
320
|
-
|
|
378
|
+
onEndResult: function onEndResult(endResult) {
|
|
379
|
+
if (type === "initial") {
|
|
380
|
+
var match = endResult.match(/^[^\S\n]*(?=\S)/gm);
|
|
381
|
+
var indent = match && Math.min.apply(Math, _toConsumableArray(match.map(function(el) {
|
|
382
|
+
return el.length;
|
|
321
383
|
})));
|
|
322
|
-
if (
|
|
323
|
-
var
|
|
324
|
-
return
|
|
384
|
+
if (indent) {
|
|
385
|
+
var regexp = new RegExp("^.{" + indent + "}", "gm");
|
|
386
|
+
return endResult.replace(regexp, "");
|
|
325
387
|
}
|
|
326
|
-
return
|
|
388
|
+
return endResult;
|
|
327
389
|
}
|
|
328
|
-
if (
|
|
329
|
-
return
|
|
330
|
-
|
|
390
|
+
if (type === "all") {
|
|
391
|
+
return endResult.replace(/^[^\S\n]+/gm, "");
|
|
392
|
+
}
|
|
393
|
+
throw new Error("Unknown type: " + type);
|
|
331
394
|
}
|
|
332
395
|
};
|
|
333
|
-
}
|
|
396
|
+
};
|
|
397
|
+
var replaceResultTransformer = function replaceResultTransformer2(replaceWhat, replaceWith) {
|
|
334
398
|
return {
|
|
335
|
-
onEndResult: function(
|
|
336
|
-
if (
|
|
399
|
+
onEndResult: function onEndResult(endResult) {
|
|
400
|
+
if (replaceWhat == null || replaceWith == null) {
|
|
337
401
|
throw new Error("replaceResultTransformer requires at least 2 arguments.");
|
|
338
|
-
|
|
402
|
+
}
|
|
403
|
+
return endResult.replace(replaceWhat, replaceWith);
|
|
339
404
|
}
|
|
340
405
|
};
|
|
341
|
-
}
|
|
406
|
+
};
|
|
407
|
+
var replaceSubstitutionTransformer = function replaceSubstitutionTransformer2(replaceWhat, replaceWith) {
|
|
342
408
|
return {
|
|
343
|
-
onSubstitution: function(
|
|
344
|
-
if (
|
|
409
|
+
onSubstitution: function onSubstitution(substitution, resultSoFar) {
|
|
410
|
+
if (replaceWhat == null || replaceWith == null) {
|
|
345
411
|
throw new Error("replaceSubstitutionTransformer requires at least 2 arguments.");
|
|
346
|
-
|
|
412
|
+
}
|
|
413
|
+
if (substitution == null) {
|
|
414
|
+
return substitution;
|
|
415
|
+
} else {
|
|
416
|
+
return substitution.toString().replace(replaceWhat, replaceWith);
|
|
417
|
+
}
|
|
347
418
|
}
|
|
348
419
|
};
|
|
349
|
-
}
|
|
420
|
+
};
|
|
421
|
+
var defaults = {
|
|
350
422
|
separator: "",
|
|
351
423
|
conjunction: "",
|
|
352
|
-
serial:
|
|
353
|
-
}
|
|
354
|
-
|
|
424
|
+
serial: false
|
|
425
|
+
};
|
|
426
|
+
var inlineArrayTransformer = function inlineArrayTransformer2() {
|
|
427
|
+
var opts = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : defaults;
|
|
355
428
|
return {
|
|
356
|
-
onSubstitution: function(
|
|
357
|
-
if (Array.isArray(
|
|
358
|
-
var
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
429
|
+
onSubstitution: function onSubstitution(substitution, resultSoFar) {
|
|
430
|
+
if (Array.isArray(substitution)) {
|
|
431
|
+
var arrayLength = substitution.length;
|
|
432
|
+
var separator = opts.separator;
|
|
433
|
+
var conjunction = opts.conjunction;
|
|
434
|
+
var serial = opts.serial;
|
|
435
|
+
var indent = resultSoFar.match(/(\n?[^\S\n]+)$/);
|
|
436
|
+
if (indent) {
|
|
437
|
+
substitution = substitution.join(separator + indent[1]);
|
|
438
|
+
} else {
|
|
439
|
+
substitution = substitution.join(separator + " ");
|
|
440
|
+
}
|
|
441
|
+
if (conjunction && arrayLength > 1) {
|
|
442
|
+
var separatorIndex = substitution.lastIndexOf(separator);
|
|
443
|
+
substitution = substitution.slice(0, separatorIndex) + (serial ? separator : "") + " " + conjunction + substitution.slice(separatorIndex + 1);
|
|
362
444
|
}
|
|
363
445
|
}
|
|
364
|
-
return
|
|
446
|
+
return substitution;
|
|
365
447
|
}
|
|
366
448
|
};
|
|
367
|
-
}
|
|
449
|
+
};
|
|
450
|
+
var splitStringTransformer = function splitStringTransformer2(splitBy) {
|
|
368
451
|
return {
|
|
369
|
-
onSubstitution: function(
|
|
370
|
-
|
|
452
|
+
onSubstitution: function onSubstitution(substitution, resultSoFar) {
|
|
453
|
+
{
|
|
454
|
+
if (typeof substitution === "string" && substitution.includes(splitBy)) {
|
|
455
|
+
substitution = substitution.split(splitBy);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
return substitution;
|
|
371
459
|
}
|
|
372
460
|
};
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
|
|
461
|
+
};
|
|
462
|
+
var isValidValue = function isValidValue2(x) {
|
|
463
|
+
return x != null && !Number.isNaN(x) && typeof x !== "boolean";
|
|
464
|
+
};
|
|
465
|
+
var removeNonPrintingValuesTransformer = function removeNonPrintingValuesTransformer2() {
|
|
376
466
|
return {
|
|
377
|
-
onSubstitution: function(
|
|
378
|
-
|
|
467
|
+
onSubstitution: function onSubstitution(substitution) {
|
|
468
|
+
if (Array.isArray(substitution)) {
|
|
469
|
+
return substitution.filter(isValidValue);
|
|
470
|
+
}
|
|
471
|
+
if (isValidValue(substitution)) {
|
|
472
|
+
return substitution;
|
|
473
|
+
}
|
|
474
|
+
return "";
|
|
379
475
|
}
|
|
380
476
|
};
|
|
381
477
|
};
|
|
382
|
-
new
|
|
383
|
-
new
|
|
384
|
-
new
|
|
385
|
-
new
|
|
386
|
-
|
|
387
|
-
new
|
|
388
|
-
|
|
389
|
-
new
|
|
390
|
-
new
|
|
391
|
-
new
|
|
392
|
-
new
|
|
393
|
-
new
|
|
394
|
-
new
|
|
395
|
-
new
|
|
396
|
-
|
|
397
|
-
var _e = new _(L("all"), T);
|
|
398
|
-
const st = [
|
|
478
|
+
new TemplateTag(inlineArrayTransformer({ separator: "," }), stripIndentTransformer, trimResultTransformer);
|
|
479
|
+
new TemplateTag(inlineArrayTransformer({ separator: ",", conjunction: "and" }), stripIndentTransformer, trimResultTransformer);
|
|
480
|
+
new TemplateTag(inlineArrayTransformer({ separator: ",", conjunction: "or" }), stripIndentTransformer, trimResultTransformer);
|
|
481
|
+
new TemplateTag(splitStringTransformer("\n"), removeNonPrintingValuesTransformer, inlineArrayTransformer, stripIndentTransformer, trimResultTransformer);
|
|
482
|
+
new TemplateTag(splitStringTransformer("\n"), inlineArrayTransformer, stripIndentTransformer, trimResultTransformer, replaceSubstitutionTransformer(/&/g, "&"), replaceSubstitutionTransformer(/</g, "<"), replaceSubstitutionTransformer(/>/g, ">"), replaceSubstitutionTransformer(/"/g, """), replaceSubstitutionTransformer(/'/g, "'"), replaceSubstitutionTransformer(/`/g, "`"));
|
|
483
|
+
new TemplateTag(replaceResultTransformer(/(?:\n(?:\s*))+/g, " "), trimResultTransformer);
|
|
484
|
+
new TemplateTag(replaceResultTransformer(/(?:\n\s*)/g, ""), trimResultTransformer);
|
|
485
|
+
new TemplateTag(inlineArrayTransformer({ separator: "," }), replaceResultTransformer(/(?:\s+)/g, " "), trimResultTransformer);
|
|
486
|
+
new TemplateTag(inlineArrayTransformer({ separator: ",", conjunction: "or" }), replaceResultTransformer(/(?:\s+)/g, " "), trimResultTransformer);
|
|
487
|
+
new TemplateTag(inlineArrayTransformer({ separator: ",", conjunction: "and" }), replaceResultTransformer(/(?:\s+)/g, " "), trimResultTransformer);
|
|
488
|
+
new TemplateTag(inlineArrayTransformer, stripIndentTransformer, trimResultTransformer);
|
|
489
|
+
new TemplateTag(inlineArrayTransformer, replaceResultTransformer(/(?:\s+)/g, " "), trimResultTransformer);
|
|
490
|
+
new TemplateTag(stripIndentTransformer, trimResultTransformer);
|
|
491
|
+
var stripIndents = new TemplateTag(stripIndentTransformer("all"), trimResultTransformer);
|
|
492
|
+
const backDualWideCameraLocalizations = [
|
|
399
493
|
"Cameră dublă cu obiectiv superangular spate",
|
|
400
494
|
"מצלמה כפולה רחבה אחורית",
|
|
401
495
|
"Артқы қос кең бұрышты камера",
|
|
@@ -433,145 +527,213 @@ const st = [
|
|
|
433
527
|
"Cámara trasera dual con gran angular",
|
|
434
528
|
"背面デュアル広角カメラ",
|
|
435
529
|
"Stražnja dvostruka široka kamera"
|
|
436
|
-
]
|
|
437
|
-
|
|
530
|
+
];
|
|
531
|
+
const asError = (thrown) => {
|
|
532
|
+
if (thrown instanceof Error) return thrown;
|
|
438
533
|
try {
|
|
439
|
-
return new Error(JSON.stringify(
|
|
534
|
+
return new Error(JSON.stringify(thrown));
|
|
440
535
|
} catch {
|
|
441
|
-
return new Error(String(
|
|
536
|
+
return new Error(String(thrown));
|
|
442
537
|
}
|
|
443
538
|
};
|
|
444
|
-
class
|
|
539
|
+
class CameraError extends Error {
|
|
445
540
|
code;
|
|
446
|
-
constructor(
|
|
447
|
-
super(
|
|
541
|
+
constructor(message, code, cause) {
|
|
542
|
+
super(message);
|
|
543
|
+
this.code = code;
|
|
544
|
+
this.cause = cause;
|
|
448
545
|
}
|
|
449
546
|
}
|
|
450
|
-
const
|
|
547
|
+
const askForCameraPermission = async () => {
|
|
451
548
|
try {
|
|
452
|
-
const
|
|
453
|
-
video:
|
|
549
|
+
const mediaStream = await navigator.mediaDevices.getUserMedia({
|
|
550
|
+
video: true
|
|
454
551
|
});
|
|
455
|
-
|
|
456
|
-
} catch (
|
|
457
|
-
|
|
552
|
+
closeStreamTracks(mediaStream);
|
|
553
|
+
} catch (error) {
|
|
554
|
+
console.log(error);
|
|
555
|
+
const newError = new CameraError(
|
|
458
556
|
"Camera permission not given",
|
|
459
557
|
"PERMISSION_DENIED",
|
|
460
|
-
|
|
558
|
+
asError(error)
|
|
461
559
|
);
|
|
560
|
+
throw newError;
|
|
462
561
|
}
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
|
|
562
|
+
};
|
|
563
|
+
const obtainVideoInputDevices = async () => {
|
|
564
|
+
if (!isSecureContext) {
|
|
565
|
+
throw new Error(stripIndents`
|
|
466
566
|
Cameras can only be used in a secure context:
|
|
467
567
|
https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts
|
|
468
568
|
`);
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
const
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
569
|
+
}
|
|
570
|
+
await askForCameraPermission();
|
|
571
|
+
const allDevices = await navigator.mediaDevices.enumerateDevices();
|
|
572
|
+
const cameraDevices = allDevices.filter((device) => {
|
|
573
|
+
return device.kind === "videoinput";
|
|
574
|
+
});
|
|
575
|
+
return cameraDevices;
|
|
576
|
+
};
|
|
577
|
+
const closeStreamTracks = (stream) => {
|
|
578
|
+
const tracks = stream.getTracks();
|
|
579
|
+
for (const track of tracks) {
|
|
580
|
+
track.stop();
|
|
581
|
+
}
|
|
582
|
+
};
|
|
583
|
+
const createConstraints = (resolution, facing, id) => {
|
|
584
|
+
const constraints = {
|
|
585
|
+
video: {
|
|
586
|
+
deviceId: id ? { exact: id } : void 0,
|
|
587
|
+
frameRate: 30,
|
|
588
|
+
aspectRatio: {
|
|
589
|
+
exact: videoResolutions[resolution].width / videoResolutions[resolution].height
|
|
590
|
+
},
|
|
591
|
+
width: {
|
|
592
|
+
ideal: videoResolutions[resolution].width
|
|
593
|
+
},
|
|
594
|
+
height: {
|
|
595
|
+
ideal: videoResolutions[resolution].height
|
|
596
|
+
},
|
|
597
|
+
facingMode: facing
|
|
486
598
|
},
|
|
487
|
-
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
}
|
|
491
|
-
|
|
599
|
+
audio: false
|
|
600
|
+
};
|
|
601
|
+
return constraints;
|
|
602
|
+
};
|
|
603
|
+
const findIdealCamera = async (cameras, resolution = "4k", requestedFacing = "back") => {
|
|
604
|
+
if (cameras.length === 0) {
|
|
492
605
|
throw new Error("No cameras found");
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
606
|
+
}
|
|
607
|
+
if (requestedFacing === "back") {
|
|
608
|
+
const dualWideCamera = cameras.find(
|
|
609
|
+
(camera) => backDualWideCameraLocalizations.includes(camera.name)
|
|
496
610
|
);
|
|
497
|
-
if (
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
611
|
+
if (dualWideCamera) {
|
|
612
|
+
await dualWideCamera.startStream(resolution);
|
|
613
|
+
return dualWideCamera;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
const cameraPool = cameras.filter((camera) => {
|
|
617
|
+
if (requestedFacing === "back" || requestedFacing === void 0) {
|
|
618
|
+
return isBackCameraName(camera.name);
|
|
619
|
+
} else {
|
|
620
|
+
return isFrontCameraName(camera.name);
|
|
621
|
+
}
|
|
622
|
+
});
|
|
623
|
+
if (cameraPool.length === 1 && cameraPool[0].facingMode === requestedFacing) {
|
|
624
|
+
await cameraPool[0].startStream(resolution);
|
|
625
|
+
return cameraPool[0];
|
|
626
|
+
}
|
|
627
|
+
if (cameraPool.length > 0 && requestedFacing === "front") {
|
|
628
|
+
const lastCamera = cameraPool[cameraPool.length - 1];
|
|
629
|
+
await lastCamera.startStream(resolution);
|
|
630
|
+
return lastCamera;
|
|
631
|
+
}
|
|
632
|
+
if (cameraPool.length === 0) {
|
|
633
|
+
console.debug("No camera found with requested facing, using all cameras");
|
|
634
|
+
cameraPool.push(...cameras);
|
|
635
|
+
}
|
|
636
|
+
const cameraScores = /* @__PURE__ */ new Map();
|
|
637
|
+
cameras.forEach((camera) => cameraScores.set(camera, 0));
|
|
638
|
+
for (let i = cameraPool.length - 1; i >= 0; i--) {
|
|
639
|
+
const camera = cameraPool[i];
|
|
640
|
+
await camera.startStream(resolution);
|
|
641
|
+
if (!camera.facingMode) {
|
|
642
|
+
console.debug("No facing mode, returning last camera");
|
|
643
|
+
return camera;
|
|
644
|
+
}
|
|
645
|
+
if (camera.facingMode && camera.facingMode !== requestedFacing) {
|
|
646
|
+
console.debug("Mismatched facing mode, moving on to the next camera");
|
|
647
|
+
camera.stopStream();
|
|
516
648
|
continue;
|
|
517
649
|
}
|
|
518
|
-
if (
|
|
519
|
-
|
|
520
|
-
|
|
650
|
+
if (camera.torchSupported && camera.singleShotSupported) {
|
|
651
|
+
console.debug("Camera supports torch and single shot, returning");
|
|
652
|
+
return camera;
|
|
653
|
+
}
|
|
654
|
+
if (camera.torchSupported) {
|
|
655
|
+
cameraScores.set(camera, cameraScores.get(camera) + 1);
|
|
656
|
+
}
|
|
657
|
+
if (camera.singleShotSupported) {
|
|
658
|
+
cameraScores.set(camera, cameraScores.get(camera) + 1);
|
|
659
|
+
}
|
|
660
|
+
if (i === 0) {
|
|
521
661
|
console.debug("Last camera in the pool, picking the best one");
|
|
522
|
-
let
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
662
|
+
let maxKey;
|
|
663
|
+
let maxValue = -Infinity;
|
|
664
|
+
cameraScores.forEach((score, camera2) => {
|
|
665
|
+
if (score > maxValue) {
|
|
666
|
+
maxValue = score;
|
|
667
|
+
maxKey = camera2;
|
|
668
|
+
}
|
|
669
|
+
});
|
|
670
|
+
return maxKey;
|
|
526
671
|
}
|
|
527
|
-
|
|
672
|
+
camera.stopStream();
|
|
528
673
|
}
|
|
529
674
|
throw new Error("No camera found, should not happen");
|
|
530
675
|
};
|
|
531
|
-
function
|
|
532
|
-
const
|
|
533
|
-
for (const
|
|
534
|
-
const
|
|
535
|
-
|
|
676
|
+
function createCameras(cameras) {
|
|
677
|
+
const camerasWithStream = [];
|
|
678
|
+
for (const device of cameras) {
|
|
679
|
+
const camera = new Camera(device);
|
|
680
|
+
if (camera !== null) {
|
|
681
|
+
camerasWithStream.push(camera);
|
|
682
|
+
}
|
|
536
683
|
}
|
|
537
|
-
return
|
|
684
|
+
return camerasWithStream;
|
|
538
685
|
}
|
|
539
|
-
const
|
|
686
|
+
const videoResolutions = {
|
|
540
687
|
"720p": { width: 1280, height: 720 },
|
|
541
688
|
"1080p": { width: 1920, height: 1080 },
|
|
542
689
|
"4k": { width: 3840, height: 2160 }
|
|
543
690
|
};
|
|
544
|
-
function
|
|
545
|
-
return Math.max(
|
|
691
|
+
function returnLongerSide(resolution) {
|
|
692
|
+
return Math.max(resolution.width, resolution.height);
|
|
546
693
|
}
|
|
547
|
-
function
|
|
548
|
-
const
|
|
549
|
-
width: Math.max(
|
|
550
|
-
height: Math.min(
|
|
694
|
+
function getNormalizedResolution(resolution) {
|
|
695
|
+
const normalized = {
|
|
696
|
+
width: Math.max(resolution.width, resolution.height),
|
|
697
|
+
height: Math.min(resolution.width, resolution.height)
|
|
551
698
|
};
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
699
|
+
const epsilon = 1e-4;
|
|
700
|
+
if (Math.abs(normalized.width / normalized.height - 16 / 9) > epsilon) {
|
|
701
|
+
console.warn(
|
|
702
|
+
`Resolution ${JSON.stringify(
|
|
703
|
+
resolution
|
|
704
|
+
)} is not 16:9, may cause issues with some video players.`
|
|
705
|
+
);
|
|
706
|
+
}
|
|
707
|
+
return normalized;
|
|
557
708
|
}
|
|
558
|
-
function
|
|
559
|
-
const
|
|
560
|
-
|
|
709
|
+
function matchClosestResolution(resolution) {
|
|
710
|
+
const actualWidth = returnLongerSide(resolution);
|
|
711
|
+
if (actualWidth > 1920) {
|
|
712
|
+
return "4k";
|
|
713
|
+
} else if (actualWidth > 1280) {
|
|
714
|
+
return "1080p";
|
|
715
|
+
} else {
|
|
716
|
+
return "720p";
|
|
717
|
+
}
|
|
561
718
|
}
|
|
562
|
-
function
|
|
563
|
-
const
|
|
564
|
-
|
|
719
|
+
function findResolutionKey(videoTrackResolution) {
|
|
720
|
+
const normalizedResolution = getNormalizedResolution(videoTrackResolution);
|
|
721
|
+
const resolutionMatch = Object.entries(videoResolutions).find(
|
|
722
|
+
([key, value]) => {
|
|
723
|
+
return value.width === normalizedResolution.width && value.height === normalizedResolution.height;
|
|
724
|
+
}
|
|
565
725
|
);
|
|
566
|
-
if (!
|
|
567
|
-
const
|
|
568
|
-
|
|
569
|
-
`No exact resolution match found for ${JSON.stringify(
|
|
570
|
-
)
|
|
726
|
+
if (!resolutionMatch) {
|
|
727
|
+
const closestMatch = matchClosestResolution(videoTrackResolution);
|
|
728
|
+
console.warn(
|
|
729
|
+
`No exact resolution match found for ${JSON.stringify(videoTrackResolution)}, categorizing as ${closestMatch}`
|
|
730
|
+
);
|
|
731
|
+
return closestMatch;
|
|
571
732
|
}
|
|
572
|
-
|
|
733
|
+
const resolutionKey = resolutionMatch[0];
|
|
734
|
+
return resolutionKey;
|
|
573
735
|
}
|
|
574
|
-
class
|
|
736
|
+
class Camera {
|
|
575
737
|
deviceInfo;
|
|
576
738
|
/**
|
|
577
739
|
* Stream capabilities as reported by the stream.
|
|
@@ -585,9 +747,9 @@ class Me {
|
|
|
585
747
|
activeStream;
|
|
586
748
|
name;
|
|
587
749
|
facingMode;
|
|
588
|
-
torchSupported =
|
|
589
|
-
torchEnabled =
|
|
590
|
-
singleShotSupported =
|
|
750
|
+
torchSupported = false;
|
|
751
|
+
torchEnabled = false;
|
|
752
|
+
singleShotSupported = false;
|
|
591
753
|
maxSupportedResolution;
|
|
592
754
|
/**
|
|
593
755
|
* Reference to the original instance before it was proxied.
|
|
@@ -604,100 +766,158 @@ class Me {
|
|
|
604
766
|
*
|
|
605
767
|
* @deprecated Not used. Reconsider using once Firefox and Chrome align on this.
|
|
606
768
|
*/
|
|
607
|
-
#
|
|
608
|
-
constructor(
|
|
609
|
-
if (
|
|
769
|
+
#deviceCapabilities;
|
|
770
|
+
constructor(deviceInfo) {
|
|
771
|
+
if (deviceInfo.kind !== "videoinput") {
|
|
610
772
|
throw new Error("Device is not a video input device");
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
773
|
+
}
|
|
774
|
+
this.deviceInfo = deviceInfo;
|
|
775
|
+
this.name = deviceInfo.label;
|
|
776
|
+
if (isFrontCameraName(deviceInfo.label)) {
|
|
777
|
+
this.facingMode = "front";
|
|
778
|
+
}
|
|
779
|
+
if (isBackCameraName(deviceInfo.label)) {
|
|
780
|
+
this.facingMode = "back";
|
|
781
|
+
}
|
|
782
|
+
const originalRef = this;
|
|
783
|
+
const proxy = new Proxy(this, {
|
|
784
|
+
set(target, property, value, receiver) {
|
|
785
|
+
const oldValue = Reflect.get(target, property, receiver);
|
|
786
|
+
const change = {
|
|
787
|
+
property,
|
|
788
|
+
oldValue,
|
|
789
|
+
value
|
|
618
790
|
};
|
|
619
|
-
|
|
791
|
+
originalRef.notify(change);
|
|
792
|
+
return Reflect.set(target, property, value, receiver);
|
|
620
793
|
}
|
|
621
794
|
});
|
|
622
|
-
|
|
623
|
-
this.notifyStateChange?.(
|
|
624
|
-
}
|
|
795
|
+
this.notify = (reason) => {
|
|
796
|
+
this.notifyStateChange?.(proxy, reason);
|
|
797
|
+
};
|
|
798
|
+
return proxy;
|
|
625
799
|
}
|
|
626
|
-
async startStream(
|
|
627
|
-
if (this.activeStream)
|
|
800
|
+
async startStream(resolution) {
|
|
801
|
+
if (this.activeStream) {
|
|
628
802
|
return this.activeStream;
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
803
|
+
}
|
|
804
|
+
if (this.maxSupportedResolution) {
|
|
805
|
+
resolution = this.maxSupportedResolution;
|
|
806
|
+
}
|
|
807
|
+
const stream = await this.acquireStreamWithFallback(resolution);
|
|
808
|
+
this.populateCapabilities(stream);
|
|
809
|
+
this.activeStream = stream;
|
|
810
|
+
const videoTrack = stream.getVideoTracks()[0];
|
|
811
|
+
videoTrack.onended = (e) => {
|
|
812
|
+
this.stopStream();
|
|
813
|
+
this.notify({
|
|
814
|
+
event: e,
|
|
636
815
|
payload: "TRACK_END"
|
|
637
816
|
});
|
|
638
|
-
}
|
|
817
|
+
};
|
|
818
|
+
return stream;
|
|
639
819
|
}
|
|
640
820
|
/**
|
|
641
821
|
* Acquires a camera stream with the specified resolution.
|
|
642
822
|
* If acquisition fails, it tries a lower resolution as fallback.
|
|
643
823
|
*/
|
|
644
|
-
async acquireStreamWithFallback(
|
|
824
|
+
async acquireStreamWithFallback(resolution) {
|
|
645
825
|
try {
|
|
646
|
-
const
|
|
647
|
-
|
|
826
|
+
const constraints = createConstraints(
|
|
827
|
+
resolution,
|
|
648
828
|
this.facingMode,
|
|
649
829
|
this.deviceInfo.deviceId
|
|
650
830
|
);
|
|
651
|
-
return await navigator.mediaDevices.getUserMedia(
|
|
652
|
-
} catch (
|
|
831
|
+
return await navigator.mediaDevices.getUserMedia(constraints);
|
|
832
|
+
} catch (error) {
|
|
653
833
|
console.warn(
|
|
654
|
-
`Can't get camera stream for ${this.name} at ${
|
|
655
|
-
|
|
834
|
+
`Can't get camera stream for ${this.name} at ${resolution}`,
|
|
835
|
+
error
|
|
656
836
|
);
|
|
657
|
-
let
|
|
658
|
-
if (
|
|
837
|
+
let currentResolutionIndex = Object.keys(videoResolutions).indexOf(resolution);
|
|
838
|
+
if (currentResolutionIndex === 0) {
|
|
659
839
|
throw new Error("Failed to get camera stream");
|
|
660
|
-
|
|
661
|
-
|
|
840
|
+
}
|
|
841
|
+
const fallbackResolution = Object.keys(videoResolutions)[currentResolutionIndex - 1];
|
|
842
|
+
return await this.acquireStreamWithFallback(fallbackResolution);
|
|
662
843
|
}
|
|
663
844
|
}
|
|
664
845
|
/**
|
|
665
846
|
* Populates the camera instance with capabilities from the stream.
|
|
666
847
|
*/
|
|
667
|
-
populateCapabilities(
|
|
668
|
-
this.streamCapabilities =
|
|
669
|
-
const
|
|
670
|
-
|
|
848
|
+
populateCapabilities(stream) {
|
|
849
|
+
this.streamCapabilities = stream.getVideoTracks()[0].getCapabilities();
|
|
850
|
+
const videoTrack = stream.getVideoTracks()[0];
|
|
851
|
+
const trackSettings = videoTrack.getSettings();
|
|
852
|
+
if (!trackSettings.width || !trackSettings.height) {
|
|
671
853
|
throw new Error(
|
|
672
854
|
"Video track resolution not available. Should not happen."
|
|
673
855
|
);
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
856
|
+
}
|
|
857
|
+
const videoTrackResolution = {
|
|
858
|
+
width: trackSettings.width,
|
|
859
|
+
height: trackSettings.height
|
|
860
|
+
};
|
|
861
|
+
const resolutionKey = findResolutionKey(videoTrackResolution);
|
|
862
|
+
if (!this.maxSupportedResolution && resolutionKey) {
|
|
863
|
+
this.maxSupportedResolution = resolutionKey;
|
|
864
|
+
}
|
|
865
|
+
if ("torch" in this.streamCapabilities) {
|
|
866
|
+
this.torchSupported = true;
|
|
867
|
+
}
|
|
868
|
+
if ("focusMode" in this.streamCapabilities && this.streamCapabilities.focusMode?.includes("single-shot")) {
|
|
869
|
+
this.singleShotSupported = true;
|
|
870
|
+
}
|
|
871
|
+
if (this.facingMode === "front" && this.streamCapabilities.facingMode?.includes("environment")) {
|
|
872
|
+
this.facingMode = "back";
|
|
873
|
+
console.warn("Front camera selected, but facingMode is environment");
|
|
874
|
+
}
|
|
875
|
+
if (this.facingMode === "back" && this.streamCapabilities.facingMode?.includes("user")) {
|
|
876
|
+
this.facingMode = "front";
|
|
877
|
+
console.warn("Back camera selected, but facingMode is user");
|
|
878
|
+
}
|
|
879
|
+
if (!this.facingMode) {
|
|
880
|
+
if (this.streamCapabilities.facingMode?.includes("environment")) {
|
|
881
|
+
this.facingMode = "back";
|
|
882
|
+
}
|
|
883
|
+
if (this.streamCapabilities.facingMode?.includes("user")) {
|
|
884
|
+
this.facingMode = "front";
|
|
885
|
+
}
|
|
886
|
+
}
|
|
679
887
|
}
|
|
680
888
|
async toggleTorch() {
|
|
681
|
-
const
|
|
682
|
-
if (!
|
|
889
|
+
const videoTrack = this.getVideoTrack();
|
|
890
|
+
if (!videoTrack) {
|
|
683
891
|
throw new Error("No active stream on Camera instance.");
|
|
684
|
-
|
|
892
|
+
}
|
|
893
|
+
if (!this.torchSupported) {
|
|
685
894
|
throw new Error("Torch not supported on this device.");
|
|
895
|
+
}
|
|
686
896
|
try {
|
|
687
|
-
await
|
|
897
|
+
await videoTrack.applyConstraints({
|
|
688
898
|
advanced: [
|
|
689
899
|
{
|
|
690
900
|
torch: !this.torchEnabled
|
|
691
901
|
}
|
|
692
902
|
]
|
|
693
|
-
})
|
|
694
|
-
|
|
695
|
-
|
|
903
|
+
});
|
|
904
|
+
this.torchEnabled = !this.torchEnabled;
|
|
905
|
+
} catch (error) {
|
|
906
|
+
console.error("Failed to toggle torch", error);
|
|
907
|
+
this.torchEnabled = false;
|
|
908
|
+
this.torchSupported = false;
|
|
909
|
+
throw new Error("Failed to toggle torch", { cause: error });
|
|
696
910
|
}
|
|
697
911
|
return this.torchEnabled;
|
|
698
912
|
}
|
|
699
913
|
stopStream() {
|
|
700
|
-
|
|
914
|
+
if (this.activeStream) {
|
|
915
|
+
console.debug(`Stopping active stream on ${this.name}`);
|
|
916
|
+
closeStreamTracks(this.activeStream);
|
|
917
|
+
this.activeStream = void 0;
|
|
918
|
+
this.streamCapabilities = void 0;
|
|
919
|
+
this.torchEnabled = false;
|
|
920
|
+
}
|
|
701
921
|
}
|
|
702
922
|
getVideoTrack() {
|
|
703
923
|
if (!this.activeStream) {
|
|
@@ -707,149 +927,241 @@ class Me {
|
|
|
707
927
|
return this.activeStream.getVideoTracks()[0];
|
|
708
928
|
}
|
|
709
929
|
}
|
|
710
|
-
const
|
|
711
|
-
function
|
|
712
|
-
return typeof window.ShadyDOM
|
|
930
|
+
const ORIGINAL_ATTACH_SHADOW = Element.prototype.attachShadow;
|
|
931
|
+
function isShady() {
|
|
932
|
+
return typeof window.ShadyDOM !== "undefined" && typeof ShadowRoot !== "undefined";
|
|
713
933
|
}
|
|
714
|
-
function
|
|
715
|
-
return typeof ShadowRoot
|
|
934
|
+
function supportsShadowRoots() {
|
|
935
|
+
return typeof ShadowRoot !== "undefined";
|
|
716
936
|
}
|
|
717
|
-
function
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
937
|
+
function patchElementPrototypeAttachShadow(callback) {
|
|
938
|
+
if (ORIGINAL_ATTACH_SHADOW == null || isShady())
|
|
939
|
+
return;
|
|
940
|
+
Element.prototype.attachShadow = function(shadowRootInitDict) {
|
|
941
|
+
const shadowRoot = ORIGINAL_ATTACH_SHADOW.call(this, shadowRootInitDict);
|
|
942
|
+
callback(shadowRoot);
|
|
943
|
+
return shadowRoot;
|
|
944
|
+
};
|
|
722
945
|
}
|
|
723
|
-
function
|
|
724
|
-
const
|
|
725
|
-
let
|
|
726
|
-
const
|
|
727
|
-
for (const
|
|
728
|
-
|
|
729
|
-
|
|
946
|
+
function createPausableQueue(job, ...queueItems) {
|
|
947
|
+
const queue = new Set(queueItems);
|
|
948
|
+
let running = false;
|
|
949
|
+
const flush = () => {
|
|
950
|
+
for (const queuedNode of queue) {
|
|
951
|
+
job(queuedNode);
|
|
952
|
+
}
|
|
953
|
+
queue.clear();
|
|
730
954
|
};
|
|
731
955
|
return {
|
|
732
956
|
isRunning() {
|
|
733
|
-
return
|
|
957
|
+
return running;
|
|
734
958
|
},
|
|
735
|
-
schedule(
|
|
736
|
-
|
|
959
|
+
schedule(node) {
|
|
960
|
+
queue.add(node);
|
|
961
|
+
if (running) {
|
|
962
|
+
flush();
|
|
963
|
+
}
|
|
737
964
|
},
|
|
738
965
|
stop() {
|
|
739
|
-
|
|
966
|
+
running = false;
|
|
740
967
|
},
|
|
741
968
|
run() {
|
|
742
|
-
|
|
969
|
+
if (running)
|
|
970
|
+
return;
|
|
971
|
+
running = true;
|
|
972
|
+
flush();
|
|
743
973
|
}
|
|
744
974
|
};
|
|
745
975
|
}
|
|
746
|
-
const
|
|
747
|
-
childList:
|
|
748
|
-
subtree:
|
|
749
|
-
}, St = (r) => {
|
|
750
|
-
typeof queueMicrotask < "u" ? queueMicrotask(r) : typeof Promise < "u" ? Promise.resolve().then(() => r()) : setTimeout(() => r(), 0);
|
|
976
|
+
const MUTATION_OBSERVER_INIT = {
|
|
977
|
+
childList: true,
|
|
978
|
+
subtree: true
|
|
751
979
|
};
|
|
752
|
-
|
|
753
|
-
if (typeof
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
980
|
+
const nextMicrotask = (func) => {
|
|
981
|
+
if (typeof queueMicrotask !== "undefined")
|
|
982
|
+
queueMicrotask(func);
|
|
983
|
+
else if (typeof Promise !== "undefined")
|
|
984
|
+
Promise.resolve().then(() => func());
|
|
985
|
+
else
|
|
986
|
+
setTimeout(() => func(), 0);
|
|
987
|
+
};
|
|
988
|
+
function nodeListToArray(nodeList) {
|
|
989
|
+
if (typeof Symbol !== "undefined" && nodeList[Symbol.iterator] != null) {
|
|
990
|
+
return [...nodeList];
|
|
991
|
+
} else {
|
|
992
|
+
const arr = [];
|
|
993
|
+
for (let i = 0; i < nodeList.length; i++) {
|
|
994
|
+
arr[i] = nodeList[i];
|
|
995
|
+
}
|
|
996
|
+
return arr;
|
|
760
997
|
}
|
|
761
998
|
}
|
|
762
|
-
function
|
|
763
|
-
|
|
999
|
+
function queryRoot(root, query) {
|
|
1000
|
+
if (isShady()) {
|
|
1001
|
+
return new Set(nodeListToArray(window.ShadyDOM.nativeMethods.querySelectorAll.call(document.documentElement, query)));
|
|
1002
|
+
}
|
|
1003
|
+
return new Set(!("querySelectorAll" in root) ? [] : nodeListToArray(root.querySelectorAll(query)));
|
|
764
1004
|
}
|
|
765
|
-
function
|
|
766
|
-
return /* @__PURE__ */ new Set([...
|
|
1005
|
+
function mergeNodes(a, b) {
|
|
1006
|
+
return /* @__PURE__ */ new Set([...a == null ? [] : a, ...b == null ? [] : b]);
|
|
767
1007
|
}
|
|
768
|
-
function
|
|
769
|
-
return "activeElement" in
|
|
1008
|
+
function isDocumentOrShadowRoot(root) {
|
|
1009
|
+
return "activeElement" in root;
|
|
770
1010
|
}
|
|
771
|
-
function
|
|
772
|
-
if (
|
|
1011
|
+
function observeMissingRoots(root = document.documentElement) {
|
|
1012
|
+
if (isDocumentOrShadowRoot(root)) {
|
|
1013
|
+
observeRoot(root);
|
|
1014
|
+
}
|
|
1015
|
+
if (isShady() && root instanceof ShadowRoot)
|
|
773
1016
|
return;
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
1017
|
+
if (!supportsShadowRoots())
|
|
1018
|
+
return;
|
|
1019
|
+
const childNodes = root.childNodes;
|
|
1020
|
+
const shadowRoot = "shadowRoot" in root && root.shadowRoot != null ? [root.shadowRoot] : [];
|
|
1021
|
+
for (const node of [...childNodes, ...shadowRoot]) {
|
|
1022
|
+
observeMissingRoots(node);
|
|
1023
|
+
}
|
|
777
1024
|
}
|
|
778
|
-
function
|
|
779
|
-
|
|
1025
|
+
function isConnected(node) {
|
|
1026
|
+
if ("isConnected" in Node.prototype)
|
|
1027
|
+
return node.isConnected;
|
|
1028
|
+
return node.ownerDocument == null || !(node.ownerDocument.compareDocumentPosition(node) & node.DOCUMENT_POSITION_DISCONNECTED);
|
|
780
1029
|
}
|
|
781
|
-
const
|
|
782
|
-
function
|
|
783
|
-
const
|
|
784
|
-
|
|
785
|
-
const
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
1030
|
+
const CONNECTION_OBSERVER_INTERNALS_MAP = /* @__PURE__ */ new Map();
|
|
1031
|
+
function initializeConnectionObserver(observer, callback) {
|
|
1032
|
+
const queue = /* @__PURE__ */ new Set();
|
|
1033
|
+
const observedTargets = /* @__PURE__ */ new Set();
|
|
1034
|
+
const rootToQuerySelectorToMatchedNodesMap = /* @__PURE__ */ new Map();
|
|
1035
|
+
const nodeToLastConnectionValueMap = /* @__PURE__ */ new WeakMap();
|
|
1036
|
+
let scheduled = false;
|
|
1037
|
+
let flushing = false;
|
|
1038
|
+
let hasFoundMissingRoots = false;
|
|
1039
|
+
const flush = () => {
|
|
1040
|
+
flushing = true;
|
|
1041
|
+
const arr = [...queue];
|
|
1042
|
+
if (arr.length > 0) {
|
|
1043
|
+
callback(arr, observer);
|
|
1044
|
+
}
|
|
1045
|
+
queue.clear();
|
|
1046
|
+
scheduled = false;
|
|
1047
|
+
flushing = false;
|
|
1048
|
+
};
|
|
1049
|
+
const scheduleFlush = () => {
|
|
1050
|
+
if (!scheduled) {
|
|
1051
|
+
scheduled = true;
|
|
1052
|
+
nextMicrotask(flush);
|
|
1053
|
+
}
|
|
1054
|
+
};
|
|
1055
|
+
const addToQueue = (entry) => {
|
|
1056
|
+
queue.add(entry);
|
|
1057
|
+
if (!flushing) {
|
|
1058
|
+
scheduleFlush();
|
|
1059
|
+
}
|
|
1060
|
+
};
|
|
1061
|
+
const clearQueue = () => {
|
|
1062
|
+
const items = [...queue];
|
|
1063
|
+
queue.clear();
|
|
1064
|
+
return items;
|
|
1065
|
+
};
|
|
1066
|
+
const clearObservedTargets = () => {
|
|
1067
|
+
observedTargets.clear();
|
|
1068
|
+
};
|
|
1069
|
+
const queryRootAndHandleMutationChanges = (root, query) => {
|
|
1070
|
+
let oldQuerySelectorMap = rootToQuerySelectorToMatchedNodesMap.get(root);
|
|
1071
|
+
const currentNodes = queryRoot(root, query);
|
|
1072
|
+
const oldNodes = oldQuerySelectorMap == null ? void 0 : oldQuerySelectorMap.get(query);
|
|
1073
|
+
const mergedNodes = mergeNodes(currentNodes, oldNodes);
|
|
1074
|
+
handleMutationChange(mergedNodes);
|
|
1075
|
+
if (oldQuerySelectorMap == null) {
|
|
1076
|
+
oldQuerySelectorMap = /* @__PURE__ */ new Map();
|
|
1077
|
+
rootToQuerySelectorToMatchedNodesMap.set(root, oldQuerySelectorMap);
|
|
1078
|
+
}
|
|
1079
|
+
oldQuerySelectorMap.set(query, currentNodes);
|
|
1080
|
+
};
|
|
1081
|
+
const handleMutationChange = (targetNodes) => {
|
|
1082
|
+
for (const targetNode of targetNodes) {
|
|
1083
|
+
const lastValue = nodeToLastConnectionValueMap.get(targetNode);
|
|
1084
|
+
const isTargetNodeConnected = isConnected(targetNode);
|
|
1085
|
+
if (lastValue !== isTargetNodeConnected) {
|
|
1086
|
+
nodeToLastConnectionValueMap.set(targetNode, isTargetNodeConnected);
|
|
1087
|
+
addToQueue({
|
|
1088
|
+
connected: isTargetNodeConnected,
|
|
1089
|
+
target: targetNode
|
|
1090
|
+
});
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
};
|
|
1094
|
+
const addObservedTarget = (target) => {
|
|
1095
|
+
rootObserverQueue.run();
|
|
1096
|
+
if (!hasFoundMissingRoots) {
|
|
1097
|
+
hasFoundMissingRoots = true;
|
|
1098
|
+
observeMissingRoots();
|
|
1099
|
+
}
|
|
1100
|
+
observedTargets.add(target);
|
|
1101
|
+
if (typeof target !== "string") {
|
|
1102
|
+
handleMutationChange([target]);
|
|
1103
|
+
} else {
|
|
1104
|
+
for (const root of OBSERVED_ROOTS) {
|
|
1105
|
+
queryRootAndHandleMutationChanges(root, target);
|
|
1106
|
+
}
|
|
809
1107
|
}
|
|
810
|
-
}, b = {
|
|
811
|
-
observedTargets: a,
|
|
812
|
-
queryRootAndHandleMutationChanges: p,
|
|
813
|
-
handleMutationChange: C,
|
|
814
|
-
addObservedTarget: (v) => {
|
|
815
|
-
if (ae.run(), c || (c = !0, Re()), a.add(v), typeof v != "string")
|
|
816
|
-
C([v]);
|
|
817
|
-
else
|
|
818
|
-
for (const x of re)
|
|
819
|
-
p(x, v);
|
|
820
|
-
},
|
|
821
|
-
clearObservedTargets: h,
|
|
822
|
-
clearQueue: u
|
|
823
1108
|
};
|
|
824
|
-
|
|
1109
|
+
const internals = {
|
|
1110
|
+
observedTargets,
|
|
1111
|
+
queryRootAndHandleMutationChanges,
|
|
1112
|
+
handleMutationChange,
|
|
1113
|
+
addObservedTarget,
|
|
1114
|
+
clearObservedTargets,
|
|
1115
|
+
clearQueue
|
|
1116
|
+
};
|
|
1117
|
+
CONNECTION_OBSERVER_INTERNALS_MAP.set(observer, internals);
|
|
825
1118
|
}
|
|
826
|
-
const
|
|
827
|
-
for (const
|
|
828
|
-
if (
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
1119
|
+
const mutationCallback = (mutations) => {
|
|
1120
|
+
for (const mutation of mutations) {
|
|
1121
|
+
if (mutation.type !== "childList")
|
|
1122
|
+
continue;
|
|
1123
|
+
for (const observer of CONNECTION_OBSERVER_INTERNALS_MAP.values()) {
|
|
1124
|
+
for (const target of observer.observedTargets) {
|
|
1125
|
+
if (typeof target === "string") {
|
|
1126
|
+
observer.queryRootAndHandleMutationChanges(mutation.target, target);
|
|
1127
|
+
} else {
|
|
1128
|
+
observer.handleMutationChange([target]);
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
};
|
|
1134
|
+
const OBSERVED_ROOTS = /* @__PURE__ */ new Set();
|
|
1135
|
+
const observeRoot = /* @__PURE__ */ (() => {
|
|
1136
|
+
let instance;
|
|
1137
|
+
return function(root) {
|
|
1138
|
+
if (OBSERVED_ROOTS.has(root))
|
|
1139
|
+
return;
|
|
1140
|
+
OBSERVED_ROOTS.add(root);
|
|
1141
|
+
if (instance == null) {
|
|
1142
|
+
instance = new MutationObserver(mutationCallback);
|
|
1143
|
+
}
|
|
1144
|
+
instance.observe(root, MUTATION_OBSERVER_INIT);
|
|
836
1145
|
};
|
|
837
|
-
})()
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
if (
|
|
845
|
-
throw new
|
|
846
|
-
|
|
1146
|
+
})();
|
|
1147
|
+
const rootObserverQueue = createPausableQueue(observeRoot, document.documentElement);
|
|
1148
|
+
class ConnectionObserver {
|
|
1149
|
+
constructor(callback) {
|
|
1150
|
+
if (new.target === void 0) {
|
|
1151
|
+
throw new TypeError(`Constructor ${ConnectionObserver.name} requires 'new'`);
|
|
1152
|
+
}
|
|
1153
|
+
if (callback === void 0) {
|
|
1154
|
+
throw new ReferenceError(`Failed to construct '${ConnectionObserver.name}': 1 argument required, but only 0 present.`);
|
|
1155
|
+
} else if (typeof callback !== "function") {
|
|
1156
|
+
throw new TypeError(`Failed to construct '${ConnectionObserver.name}': The callback provided as parameter 1 is not a function.`);
|
|
1157
|
+
}
|
|
1158
|
+
initializeConnectionObserver(this, callback);
|
|
847
1159
|
}
|
|
848
1160
|
/**
|
|
849
1161
|
* The Symbol.@@toStringTag value
|
|
850
1162
|
*/
|
|
851
1163
|
get [Symbol.toStringTag]() {
|
|
852
|
-
return
|
|
1164
|
+
return `ConnectionObserver`;
|
|
853
1165
|
}
|
|
854
1166
|
/**
|
|
855
1167
|
* Observe the given node or query selector for connections/disconnections.
|
|
@@ -857,121 +1169,148 @@ class N {
|
|
|
857
1169
|
* as for example "img[data-some-attr]", for each new MutationRecord, the query selector
|
|
858
1170
|
* will be executed and the matched nodes will be observed for connections/disconnections
|
|
859
1171
|
*/
|
|
860
|
-
observe(
|
|
861
|
-
if (
|
|
862
|
-
throw new ReferenceError(`Failed to execute '${this.observe.name}' on '${
|
|
863
|
-
if (typeof
|
|
864
|
-
throw new TypeError(`Failed to execute '${this.observe.name}' on '${
|
|
865
|
-
|
|
866
|
-
|
|
1172
|
+
observe(target) {
|
|
1173
|
+
if (target === void 0) {
|
|
1174
|
+
throw new ReferenceError(`Failed to execute '${this.observe.name}' on '${ConnectionObserver.name}': 1 argument required, but only 0 present.`);
|
|
1175
|
+
} else if (typeof target !== "string" && !(target instanceof Node)) {
|
|
1176
|
+
throw new TypeError(`Failed to execute '${this.observe.name}' on '${ConnectionObserver.name}': parameter 1 is not of type 'Node' or a DOMString.`);
|
|
1177
|
+
}
|
|
1178
|
+
const internals = CONNECTION_OBSERVER_INTERNALS_MAP.get(this);
|
|
1179
|
+
if (internals == null)
|
|
1180
|
+
return;
|
|
1181
|
+
internals.addObservedTarget(target);
|
|
867
1182
|
}
|
|
868
1183
|
/**
|
|
869
1184
|
* Takes the records immediately (instead of waiting for the next flush)
|
|
870
1185
|
*/
|
|
871
1186
|
takeRecords() {
|
|
872
|
-
const
|
|
873
|
-
|
|
1187
|
+
const internals = CONNECTION_OBSERVER_INTERNALS_MAP.get(this);
|
|
1188
|
+
if (internals == null)
|
|
1189
|
+
return [];
|
|
1190
|
+
return internals.clearQueue();
|
|
874
1191
|
}
|
|
875
1192
|
/**
|
|
876
1193
|
* Disconnects the ConnectionObserver such that none of its callbacks will be invoked any longer
|
|
877
1194
|
*/
|
|
878
1195
|
disconnect() {
|
|
879
|
-
const
|
|
880
|
-
|
|
1196
|
+
const internals = CONNECTION_OBSERVER_INTERNALS_MAP.get(this);
|
|
1197
|
+
if (internals == null)
|
|
1198
|
+
return;
|
|
1199
|
+
internals.clearObservedTargets();
|
|
881
1200
|
}
|
|
882
1201
|
}
|
|
883
|
-
|
|
884
|
-
function
|
|
885
|
-
|
|
886
|
-
|
|
1202
|
+
patchElementPrototypeAttachShadow(rootObserverQueue.schedule.bind(rootObserverQueue));
|
|
1203
|
+
function radEventListener(element, ...args) {
|
|
1204
|
+
element.addEventListener(...args);
|
|
1205
|
+
return () => {
|
|
1206
|
+
element.removeEventListener(...args);
|
|
887
1207
|
};
|
|
888
1208
|
}
|
|
889
|
-
function
|
|
890
|
-
let
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
1209
|
+
function rad(element, gen) {
|
|
1210
|
+
let cleanup;
|
|
1211
|
+
gen((listener, options) => {
|
|
1212
|
+
element.addEventListener(listener, options);
|
|
1213
|
+
cleanup = () => element.removeEventListener(listener, options);
|
|
1214
|
+
});
|
|
1215
|
+
if (!cleanup) {
|
|
894
1216
|
throw new Error("you forgot to add event listener");
|
|
895
|
-
|
|
1217
|
+
}
|
|
1218
|
+
return cleanup;
|
|
896
1219
|
}
|
|
897
|
-
function
|
|
898
|
-
const
|
|
899
|
-
if ("detached" in
|
|
900
|
-
|
|
1220
|
+
function isBufferDetached(buffer) {
|
|
1221
|
+
const actualBuffer = getBuffer(buffer);
|
|
1222
|
+
if ("detached" in actualBuffer) {
|
|
1223
|
+
const detached = actualBuffer.detached;
|
|
1224
|
+
return detached;
|
|
1225
|
+
}
|
|
901
1226
|
try {
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
1227
|
+
new Uint8Array(actualBuffer);
|
|
1228
|
+
return false;
|
|
1229
|
+
} catch (e) {
|
|
1230
|
+
return true;
|
|
905
1231
|
}
|
|
906
1232
|
}
|
|
907
|
-
class
|
|
908
|
-
#
|
|
909
|
-
#
|
|
910
|
-
#
|
|
911
|
-
#
|
|
912
|
-
#
|
|
913
|
-
#
|
|
914
|
-
#
|
|
915
|
-
#
|
|
916
|
-
#
|
|
917
|
-
#
|
|
918
|
-
constructor(
|
|
919
|
-
const { canvasRenderingMode
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
1233
|
+
class VideoFrameProcessor {
|
|
1234
|
+
#canvas;
|
|
1235
|
+
#context2d = null;
|
|
1236
|
+
#contextWebGl2 = null;
|
|
1237
|
+
#webGl2Texture = null;
|
|
1238
|
+
#webGl2Framebuffer = null;
|
|
1239
|
+
#buffer = null;
|
|
1240
|
+
#cachedWidth = 0;
|
|
1241
|
+
#cachedHeight = 0;
|
|
1242
|
+
#canvasRenderingMode;
|
|
1243
|
+
#requiredPackAlignment = 4;
|
|
1244
|
+
constructor(options = {}) {
|
|
1245
|
+
const { canvasRenderingMode = "webgl2", fallbackWebGlTo2d = true } = options;
|
|
1246
|
+
this.#canvasRenderingMode = canvasRenderingMode;
|
|
1247
|
+
this.#canvas = document.createElement("canvas");
|
|
1248
|
+
if (canvasRenderingMode === "2d") {
|
|
1249
|
+
this.#initialize2dContext();
|
|
1250
|
+
} else if (canvasRenderingMode === "webgl2") {
|
|
923
1251
|
try {
|
|
924
|
-
this.#
|
|
925
|
-
} catch (
|
|
926
|
-
if (
|
|
1252
|
+
this.#initializeWebGl2Context();
|
|
1253
|
+
} catch (error) {
|
|
1254
|
+
if (fallbackWebGlTo2d) {
|
|
927
1255
|
console.warn(
|
|
928
1256
|
"Failed to create WebGL2 context, falling back to 2D canvas"
|
|
929
|
-
)
|
|
930
|
-
|
|
931
|
-
|
|
1257
|
+
);
|
|
1258
|
+
this.#canvasRenderingMode = "2d";
|
|
1259
|
+
this.#initialize2dContext();
|
|
1260
|
+
} else {
|
|
1261
|
+
throw error;
|
|
1262
|
+
}
|
|
932
1263
|
}
|
|
933
|
-
else
|
|
1264
|
+
} else {
|
|
934
1265
|
throw new Error(
|
|
935
|
-
`Unsupported rendering context: ${
|
|
1266
|
+
`Unsupported rendering context: ${canvasRenderingMode}`
|
|
936
1267
|
);
|
|
1268
|
+
}
|
|
937
1269
|
}
|
|
938
1270
|
/**
|
|
939
1271
|
* Initializes the 2D canvas context
|
|
940
1272
|
*/
|
|
941
|
-
#
|
|
942
|
-
const
|
|
943
|
-
alpha:
|
|
944
|
-
willReadFrequently:
|
|
1273
|
+
#initialize2dContext() {
|
|
1274
|
+
const ctx = this.#canvas.getContext("2d", {
|
|
1275
|
+
alpha: false,
|
|
1276
|
+
willReadFrequently: true
|
|
945
1277
|
});
|
|
946
|
-
if (!
|
|
947
|
-
this.#
|
|
1278
|
+
if (!ctx) throw new Error("CanvasRenderingContext2D is missing!");
|
|
1279
|
+
this.#context2d = ctx;
|
|
948
1280
|
}
|
|
949
1281
|
/**
|
|
950
1282
|
* Initializes the WebGL2 context and resources
|
|
951
1283
|
*/
|
|
952
|
-
#
|
|
953
|
-
const
|
|
954
|
-
alpha:
|
|
955
|
-
depth:
|
|
956
|
-
stencil:
|
|
957
|
-
antialias:
|
|
958
|
-
premultipliedAlpha:
|
|
959
|
-
preserveDrawingBuffer:
|
|
960
|
-
desynchronized:
|
|
1284
|
+
#initializeWebGl2Context() {
|
|
1285
|
+
const ctx = this.#canvas.getContext("webgl2", {
|
|
1286
|
+
alpha: false,
|
|
1287
|
+
depth: false,
|
|
1288
|
+
stencil: false,
|
|
1289
|
+
antialias: false,
|
|
1290
|
+
premultipliedAlpha: false,
|
|
1291
|
+
preserveDrawingBuffer: false,
|
|
1292
|
+
desynchronized: false,
|
|
961
1293
|
powerPreference: "high-performance"
|
|
962
1294
|
});
|
|
963
|
-
if (!
|
|
964
|
-
this.#
|
|
965
|
-
const
|
|
966
|
-
if (!
|
|
967
|
-
this.#
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
1295
|
+
if (!ctx) throw new Error("WebGL2RenderingContext is missing!");
|
|
1296
|
+
this.#contextWebGl2 = ctx;
|
|
1297
|
+
const texture = ctx.createTexture();
|
|
1298
|
+
if (!texture) throw new Error("Failed to create WebGL texture");
|
|
1299
|
+
this.#webGl2Texture = texture;
|
|
1300
|
+
ctx.bindTexture(ctx.TEXTURE_2D, texture);
|
|
1301
|
+
ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_S, ctx.CLAMP_TO_EDGE);
|
|
1302
|
+
ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_T, ctx.CLAMP_TO_EDGE);
|
|
1303
|
+
ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.NEAREST);
|
|
1304
|
+
ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.NEAREST);
|
|
1305
|
+
const framebuffer = ctx.createFramebuffer();
|
|
1306
|
+
if (!framebuffer) throw new Error("Failed to create framebuffer");
|
|
1307
|
+
this.#webGl2Framebuffer = framebuffer;
|
|
1308
|
+
ctx.bindFramebuffer(ctx.FRAMEBUFFER, framebuffer);
|
|
1309
|
+
ctx.framebufferTexture2D(
|
|
1310
|
+
ctx.FRAMEBUFFER,
|
|
1311
|
+
ctx.COLOR_ATTACHMENT0,
|
|
1312
|
+
ctx.TEXTURE_2D,
|
|
1313
|
+
texture,
|
|
975
1314
|
0
|
|
976
1315
|
);
|
|
977
1316
|
}
|
|
@@ -980,31 +1319,34 @@ class At {
|
|
|
980
1319
|
* This should only be called with ArrayBuffers that were originally from this processor
|
|
981
1320
|
* Typically used after transferring the buffer to/from a worker
|
|
982
1321
|
*/
|
|
983
|
-
reattachArrayBuffer(
|
|
984
|
-
const
|
|
985
|
-
if (
|
|
1322
|
+
reattachArrayBuffer(arrayBuffer) {
|
|
1323
|
+
const actualBuffer = getBuffer(arrayBuffer);
|
|
1324
|
+
if (isBufferDetached(actualBuffer)) {
|
|
986
1325
|
throw new Error("Can't use a detached array buffer!");
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
1326
|
+
}
|
|
1327
|
+
const requiredSize = this.#cachedWidth * this.#cachedHeight * 4;
|
|
1328
|
+
if (actualBuffer.byteLength === requiredSize) {
|
|
1329
|
+
this.#buffer = new Uint8ClampedArray(actualBuffer);
|
|
1330
|
+
} else {
|
|
991
1331
|
throw new Error(
|
|
992
|
-
`ArrayBuffer size mismatch: expected ${
|
|
1332
|
+
`ArrayBuffer size mismatch: expected ${requiredSize}, got ${actualBuffer.byteLength}`
|
|
993
1333
|
);
|
|
1334
|
+
}
|
|
994
1335
|
}
|
|
995
1336
|
/**
|
|
996
1337
|
* Used to check if the processor owns the buffer
|
|
997
1338
|
*/
|
|
998
1339
|
isBufferDetached() {
|
|
999
|
-
if (!this.#
|
|
1340
|
+
if (!this.#buffer) {
|
|
1000
1341
|
throw new Error("Buffer is missing!");
|
|
1001
|
-
|
|
1342
|
+
}
|
|
1343
|
+
return isBufferDetached(this.#buffer.buffer);
|
|
1002
1344
|
}
|
|
1003
1345
|
/**
|
|
1004
1346
|
* Extracts image data from a source element
|
|
1005
1347
|
*/
|
|
1006
|
-
getImageData(
|
|
1007
|
-
return this.#
|
|
1348
|
+
getImageData(source, area) {
|
|
1349
|
+
return this.#canvasRenderingMode === "2d" ? this.#getImageData2d(source, area) : this.#getImageDataWebGl2(source, area);
|
|
1008
1350
|
}
|
|
1009
1351
|
/**
|
|
1010
1352
|
* Used to get the current ImageData object with the current buffer. Useful
|
|
@@ -1013,126 +1355,178 @@ class At {
|
|
|
1013
1355
|
* @returns ImageData object with the current buffer
|
|
1014
1356
|
*/
|
|
1015
1357
|
getCurrentImageData() {
|
|
1016
|
-
if (!this.#
|
|
1358
|
+
if (!this.#buffer) {
|
|
1017
1359
|
throw new Error("Buffer is missing!");
|
|
1018
|
-
|
|
1360
|
+
}
|
|
1361
|
+
return new ImageData(this.#buffer, this.#cachedWidth, this.#cachedHeight);
|
|
1019
1362
|
}
|
|
1020
1363
|
/**
|
|
1021
1364
|
* Extract image data using 2D canvas
|
|
1022
1365
|
*/
|
|
1023
|
-
#
|
|
1024
|
-
if (!this.#
|
|
1366
|
+
#getImageData2d(source, area) {
|
|
1367
|
+
if (!this.#context2d)
|
|
1025
1368
|
throw new Error("CanvasRenderingContext2D is missing!");
|
|
1026
|
-
const
|
|
1027
|
-
|
|
1369
|
+
const fullWidth = "videoWidth" in source ? source.videoWidth : source.width;
|
|
1370
|
+
const fullHeight = "videoHeight" in source ? source.videoHeight : source.height;
|
|
1371
|
+
const x = area?.x ?? 0;
|
|
1372
|
+
const y = area?.y ?? 0;
|
|
1373
|
+
const w = area?.width ?? fullWidth;
|
|
1374
|
+
const h = area?.height ?? fullHeight;
|
|
1375
|
+
this.#updateCanvasSize(w, h);
|
|
1376
|
+
this.#context2d.drawImage(source, x, y, w, h);
|
|
1377
|
+
return this.#context2d.getImageData(0, 0, w, h);
|
|
1028
1378
|
}
|
|
1029
1379
|
/**
|
|
1030
1380
|
* Extract image data using WebGL2
|
|
1031
1381
|
*/
|
|
1032
|
-
#
|
|
1033
|
-
if (!this.#
|
|
1382
|
+
#getImageDataWebGl2(source, area) {
|
|
1383
|
+
if (!this.#contextWebGl2 || !this.#webGl2Texture || !this.#webGl2Framebuffer) {
|
|
1034
1384
|
throw new Error("WebGL2 context or resources are missing!");
|
|
1035
|
-
|
|
1036
|
-
|
|
1385
|
+
}
|
|
1386
|
+
const fullWidth = "videoWidth" in source ? source.videoWidth : source.width;
|
|
1387
|
+
const fullHeight = "videoHeight" in source ? source.videoHeight : source.height;
|
|
1388
|
+
const x = area?.x ?? 0;
|
|
1389
|
+
const y = area?.y ?? 0;
|
|
1390
|
+
const w = area?.width ?? fullWidth;
|
|
1391
|
+
const h = area?.height ?? fullHeight;
|
|
1392
|
+
const requiredSize = w * h * 4;
|
|
1393
|
+
this.#updateCanvasSize(w, h);
|
|
1394
|
+
if (this.isBufferDetached()) {
|
|
1037
1395
|
throw new Error("Buffer is detached!");
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1396
|
+
}
|
|
1397
|
+
if (!this.#buffer || this.#buffer.length !== requiredSize) {
|
|
1398
|
+
this.#buffer = new Uint8ClampedArray(requiredSize);
|
|
1399
|
+
}
|
|
1400
|
+
const gl = this.#contextWebGl2;
|
|
1401
|
+
gl.bindTexture(gl.TEXTURE_2D, this.#webGl2Texture);
|
|
1402
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
|
|
1403
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, this.#webGl2Framebuffer);
|
|
1041
1404
|
try {
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1405
|
+
gl.pixelStorei(gl.PACK_ALIGNMENT, this.#requiredPackAlignment);
|
|
1406
|
+
gl.readPixels(x, y, w, h, gl.RGBA, gl.UNSIGNED_BYTE, this.#buffer);
|
|
1407
|
+
} catch (error) {
|
|
1408
|
+
if (this.#requiredPackAlignment !== 1) {
|
|
1409
|
+
this.#requiredPackAlignment = 1;
|
|
1410
|
+
gl.pixelStorei(gl.PACK_ALIGNMENT, 1);
|
|
1411
|
+
const newBuffer = new Uint8ClampedArray(requiredSize);
|
|
1412
|
+
gl.readPixels(0, 0, w, h, gl.RGBA, gl.UNSIGNED_BYTE, newBuffer);
|
|
1413
|
+
this.#buffer = newBuffer;
|
|
1414
|
+
return new ImageData(newBuffer, w, h);
|
|
1048
1415
|
}
|
|
1049
|
-
throw
|
|
1416
|
+
throw error;
|
|
1050
1417
|
}
|
|
1051
|
-
return new ImageData(this.#
|
|
1418
|
+
return new ImageData(this.#buffer, w, h);
|
|
1052
1419
|
}
|
|
1053
1420
|
/**
|
|
1054
1421
|
* Update canvas dimensions if needed
|
|
1055
1422
|
*
|
|
1056
1423
|
* This canvas is the orientation-aware
|
|
1057
1424
|
*/
|
|
1058
|
-
#
|
|
1059
|
-
if (this.#
|
|
1060
|
-
this.#
|
|
1061
|
-
|
|
1062
|
-
this.#
|
|
1425
|
+
#updateCanvasSize(width, height) {
|
|
1426
|
+
if (this.#cachedWidth !== width || this.#cachedHeight !== height) {
|
|
1427
|
+
this.#canvas.width = width;
|
|
1428
|
+
this.#canvas.height = height;
|
|
1429
|
+
this.#cachedWidth = width;
|
|
1430
|
+
this.#cachedHeight = height;
|
|
1431
|
+
const requiredSize = width * height * 4;
|
|
1432
|
+
this.#buffer = new Uint8ClampedArray(requiredSize);
|
|
1063
1433
|
}
|
|
1064
1434
|
}
|
|
1065
1435
|
/**
|
|
1066
1436
|
* Clean up resources
|
|
1067
1437
|
*/
|
|
1068
1438
|
dispose() {
|
|
1069
|
-
|
|
1439
|
+
if (this.#contextWebGl2) {
|
|
1440
|
+
if (this.#webGl2Texture) {
|
|
1441
|
+
this.#contextWebGl2.deleteTexture(this.#webGl2Texture);
|
|
1442
|
+
this.#webGl2Texture = null;
|
|
1443
|
+
}
|
|
1444
|
+
if (this.#webGl2Framebuffer) {
|
|
1445
|
+
this.#contextWebGl2.deleteFramebuffer(this.#webGl2Framebuffer);
|
|
1446
|
+
this.#webGl2Framebuffer = null;
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
this.#context2d = null;
|
|
1450
|
+
this.#contextWebGl2 = null;
|
|
1451
|
+
this.#buffer = null;
|
|
1070
1452
|
}
|
|
1071
1453
|
}
|
|
1072
|
-
const
|
|
1073
|
-
|
|
1454
|
+
const getBuffer = (buffer) => {
|
|
1455
|
+
if (ArrayBuffer.isView(buffer)) {
|
|
1456
|
+
return buffer.buffer;
|
|
1457
|
+
} else {
|
|
1458
|
+
return buffer;
|
|
1459
|
+
}
|
|
1460
|
+
};
|
|
1461
|
+
const defaultCameraManagerOptions = {
|
|
1462
|
+
mirrorFrontCameras: true
|
|
1074
1463
|
};
|
|
1075
|
-
class
|
|
1076
|
-
#
|
|
1077
|
-
#
|
|
1078
|
-
#
|
|
1079
|
-
#
|
|
1080
|
-
#
|
|
1081
|
-
#
|
|
1082
|
-
#
|
|
1464
|
+
class CameraManager {
|
|
1465
|
+
#resumeRequest;
|
|
1466
|
+
#resolution = "4k";
|
|
1467
|
+
#extractionArea;
|
|
1468
|
+
#videoFrameRequestId;
|
|
1469
|
+
#videoFrameProcessor;
|
|
1470
|
+
#mirrorFrontCameras;
|
|
1471
|
+
#eventListenerCleanup;
|
|
1083
1472
|
/**
|
|
1084
1473
|
* If true, the user has initiated an abort. This will prevent the
|
|
1085
1474
|
* CameraManager from throwing errors when the user interrupts the process.
|
|
1086
1475
|
*/
|
|
1087
|
-
#
|
|
1476
|
+
#userInitiatedAbort = false;
|
|
1088
1477
|
get userInitiatedAbort() {
|
|
1089
|
-
return this.#
|
|
1478
|
+
return this.#userInitiatedAbort;
|
|
1090
1479
|
}
|
|
1091
|
-
set userInitiatedAbort(
|
|
1092
|
-
this.#
|
|
1480
|
+
set userInitiatedAbort(value) {
|
|
1481
|
+
this.#userInitiatedAbort = value;
|
|
1093
1482
|
}
|
|
1094
1483
|
/**
|
|
1095
1484
|
* Sets the area of the video frame that will be extracted.
|
|
1096
1485
|
* @param extractionArea The area of the video frame that will be extracted.
|
|
1097
1486
|
*/
|
|
1098
|
-
setExtractionArea(
|
|
1099
|
-
this.#
|
|
1487
|
+
setExtractionArea(extractionArea) {
|
|
1488
|
+
this.#extractionArea = extractionArea;
|
|
1100
1489
|
}
|
|
1101
1490
|
/**
|
|
1102
1491
|
* Callbacks that will be triggered on each frame when the playback state is
|
|
1103
1492
|
* "capturing".
|
|
1104
1493
|
*/
|
|
1105
|
-
#
|
|
1106
|
-
constructor(
|
|
1107
|
-
const { mirrorFrontCameras
|
|
1108
|
-
|
|
1109
|
-
...
|
|
1494
|
+
#frameCaptureCallbacks = /* @__PURE__ */ new Set();
|
|
1495
|
+
constructor(options = {}, videoFrameProcessorOptions) {
|
|
1496
|
+
const { mirrorFrontCameras } = {
|
|
1497
|
+
...defaultCameraManagerOptions,
|
|
1498
|
+
...options
|
|
1110
1499
|
};
|
|
1111
|
-
this.#
|
|
1112
|
-
|
|
1113
|
-
)
|
|
1500
|
+
this.#videoFrameProcessor = new VideoFrameProcessor(
|
|
1501
|
+
videoFrameProcessorOptions
|
|
1502
|
+
);
|
|
1503
|
+
this.#mirrorFrontCameras = mirrorFrontCameras;
|
|
1114
1504
|
}
|
|
1115
1505
|
/**
|
|
1116
1506
|
* Sets the resolution of the camera stream
|
|
1117
1507
|
*/
|
|
1118
|
-
setResolution = async (
|
|
1119
|
-
this.#
|
|
1120
|
-
const
|
|
1121
|
-
|
|
1508
|
+
setResolution = async (resolution) => {
|
|
1509
|
+
this.#resolution = resolution;
|
|
1510
|
+
const playbackState = this.getState().playbackState;
|
|
1511
|
+
if (playbackState !== "idle") {
|
|
1512
|
+
this.#resumeRequest = playbackState;
|
|
1513
|
+
this.stopStream();
|
|
1514
|
+
await this.startCameraStream();
|
|
1515
|
+
}
|
|
1122
1516
|
};
|
|
1123
1517
|
get resolution() {
|
|
1124
|
-
return this.#
|
|
1518
|
+
return this.#resolution;
|
|
1125
1519
|
}
|
|
1126
1520
|
/**
|
|
1127
1521
|
* True if there is a video playing or capturing
|
|
1128
1522
|
* TODO: see if we can simplify this, by observing the video playback state
|
|
1129
1523
|
*/
|
|
1130
1524
|
get isActive() {
|
|
1131
|
-
return
|
|
1525
|
+
return cameraManagerStore.getState().playbackState !== "idle";
|
|
1132
1526
|
}
|
|
1133
|
-
setFacingFilter(
|
|
1134
|
-
|
|
1135
|
-
facingFilter
|
|
1527
|
+
setFacingFilter(facingFilter) {
|
|
1528
|
+
cameraManagerStore.setState({
|
|
1529
|
+
facingFilter
|
|
1136
1530
|
});
|
|
1137
1531
|
}
|
|
1138
1532
|
/**
|
|
@@ -1140,28 +1534,37 @@ class Qr {
|
|
|
1140
1534
|
* If no facing mode is set, all cameras are returned.
|
|
1141
1535
|
*/
|
|
1142
1536
|
async getCameraDevices() {
|
|
1143
|
-
let
|
|
1144
|
-
const
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1537
|
+
let allCameras = cameraManagerStore.getState().cameras;
|
|
1538
|
+
const facingFilter = cameraManagerStore.getState().facingFilter;
|
|
1539
|
+
if (!allCameras.length) {
|
|
1540
|
+
await this.refreshCameraDevices();
|
|
1541
|
+
}
|
|
1542
|
+
allCameras = cameraManagerStore.getState().cameras;
|
|
1543
|
+
if (!facingFilter) {
|
|
1544
|
+
return allCameras;
|
|
1545
|
+
}
|
|
1546
|
+
const filteredCameras = allCameras.filter(
|
|
1547
|
+
(camera) => facingFilter.includes(camera.facingMode)
|
|
1548
|
+
);
|
|
1549
|
+
return filteredCameras;
|
|
1148
1550
|
}
|
|
1149
1551
|
/**
|
|
1150
1552
|
* Single-time setup for a video element
|
|
1151
1553
|
*/
|
|
1152
|
-
#
|
|
1153
|
-
if (!(
|
|
1554
|
+
#initVideoElement(videoElement) {
|
|
1555
|
+
if (!(videoElement instanceof HTMLVideoElement)) {
|
|
1154
1556
|
throw new Error(
|
|
1155
|
-
`Expected an HTMLVideoElement, got ${typeof
|
|
1557
|
+
`Expected an HTMLVideoElement, got ${typeof videoElement}`,
|
|
1156
1558
|
{
|
|
1157
|
-
cause:
|
|
1559
|
+
cause: videoElement
|
|
1158
1560
|
}
|
|
1159
1561
|
);
|
|
1160
|
-
|
|
1161
|
-
|
|
1562
|
+
}
|
|
1563
|
+
cameraManagerStore.setState({
|
|
1564
|
+
videoElement
|
|
1162
1565
|
});
|
|
1163
|
-
const
|
|
1164
|
-
[
|
|
1566
|
+
const videoEventCleanup = rad(videoElement, (add) => {
|
|
1567
|
+
const events = [
|
|
1165
1568
|
"abort"
|
|
1166
1569
|
// "error",
|
|
1167
1570
|
// "canplay",
|
|
@@ -1180,49 +1583,62 @@ class Qr {
|
|
|
1180
1583
|
// "timeupdate",
|
|
1181
1584
|
// "ratechange",
|
|
1182
1585
|
// "durationchange",
|
|
1183
|
-
]
|
|
1184
|
-
|
|
1185
|
-
|
|
1586
|
+
];
|
|
1587
|
+
events.forEach((event) => {
|
|
1588
|
+
add(event, () => {
|
|
1589
|
+
console.debug(`Video event: ${event}`);
|
|
1186
1590
|
});
|
|
1187
1591
|
});
|
|
1188
1592
|
});
|
|
1189
|
-
new
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1593
|
+
const connectionObserver = new ConnectionObserver((entries) => {
|
|
1594
|
+
if (!entries[0].connected) {
|
|
1595
|
+
this.releaseVideoElement();
|
|
1596
|
+
}
|
|
1597
|
+
});
|
|
1598
|
+
connectionObserver.observe(videoElement);
|
|
1599
|
+
videoElement.setAttribute("playsInline", "");
|
|
1600
|
+
videoElement.setAttribute("muted", "");
|
|
1601
|
+
videoElement.controls = false;
|
|
1602
|
+
let previousPlaybackState = "idle";
|
|
1603
|
+
const cleanupVisibilityListener = radEventListener(
|
|
1194
1604
|
document,
|
|
1195
1605
|
"visibilitychange",
|
|
1196
1606
|
async () => {
|
|
1197
|
-
|
|
1198
|
-
|
|
1607
|
+
const isHidden = document.hidden;
|
|
1608
|
+
if (isHidden) {
|
|
1609
|
+
previousPlaybackState = cameraManagerStore.getState().playbackState;
|
|
1610
|
+
this.stopStream();
|
|
1199
1611
|
return;
|
|
1200
1612
|
}
|
|
1201
|
-
switch (
|
|
1613
|
+
switch (previousPlaybackState) {
|
|
1202
1614
|
case "playback":
|
|
1203
|
-
await this.startCameraStream()
|
|
1615
|
+
await this.startCameraStream();
|
|
1616
|
+
await this.startPlayback();
|
|
1204
1617
|
break;
|
|
1205
1618
|
case "capturing":
|
|
1206
|
-
await this.startCameraStream()
|
|
1619
|
+
await this.startCameraStream();
|
|
1620
|
+
await this.startFrameCapture();
|
|
1207
1621
|
break;
|
|
1208
1622
|
}
|
|
1209
1623
|
}
|
|
1210
1624
|
);
|
|
1211
|
-
this.#
|
|
1212
|
-
|
|
1625
|
+
this.#eventListenerCleanup = () => {
|
|
1626
|
+
cleanupVisibilityListener();
|
|
1627
|
+
videoEventCleanup();
|
|
1213
1628
|
};
|
|
1214
1629
|
}
|
|
1215
1630
|
/**
|
|
1216
1631
|
* Initializes the CameraManager with a video element.
|
|
1217
1632
|
*/
|
|
1218
|
-
initVideoElement(
|
|
1633
|
+
initVideoElement(videoElement) {
|
|
1219
1634
|
try {
|
|
1220
|
-
this.#
|
|
1221
|
-
} catch (
|
|
1222
|
-
if (this.userInitiatedAbort)
|
|
1635
|
+
this.#initVideoElement(videoElement);
|
|
1636
|
+
} catch (error) {
|
|
1637
|
+
if (this.userInitiatedAbort) {
|
|
1223
1638
|
this.reset();
|
|
1224
|
-
else
|
|
1225
|
-
throw
|
|
1639
|
+
} else {
|
|
1640
|
+
throw error;
|
|
1641
|
+
}
|
|
1226
1642
|
}
|
|
1227
1643
|
}
|
|
1228
1644
|
/**
|
|
@@ -1232,74 +1648,108 @@ class Qr {
|
|
|
1232
1648
|
* @param frameCaptureCallback
|
|
1233
1649
|
* @returns a cleanup function to remove the callback
|
|
1234
1650
|
*/
|
|
1235
|
-
addFrameCaptureCallback(
|
|
1236
|
-
|
|
1651
|
+
addFrameCaptureCallback(frameCaptureCallback) {
|
|
1652
|
+
this.#frameCaptureCallbacks.add(frameCaptureCallback);
|
|
1653
|
+
return () => this.#frameCaptureCallbacks.delete(frameCaptureCallback);
|
|
1237
1654
|
}
|
|
1238
1655
|
releaseVideoElement() {
|
|
1239
|
-
this.#
|
|
1656
|
+
this.#eventListenerCleanup?.();
|
|
1657
|
+
cameraManagerStore.setState({
|
|
1240
1658
|
videoElement: void 0
|
|
1241
|
-
})
|
|
1659
|
+
});
|
|
1660
|
+
this.stopStream();
|
|
1242
1661
|
}
|
|
1243
1662
|
/**
|
|
1244
1663
|
* Select a camera device from available ones.
|
|
1245
1664
|
*
|
|
1246
1665
|
* TODO: might become a private method in the future as an implementation detail of `startStream`
|
|
1247
1666
|
*/
|
|
1248
|
-
async selectCamera(
|
|
1249
|
-
const
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1667
|
+
async selectCamera(camera) {
|
|
1668
|
+
const playbackState = cameraManagerStore.getState().playbackState;
|
|
1669
|
+
if (playbackState !== "idle") {
|
|
1670
|
+
this.#resumeRequest = playbackState;
|
|
1671
|
+
}
|
|
1672
|
+
const state = cameraManagerStore.getState();
|
|
1673
|
+
if (state.selectedCamera === camera) {
|
|
1253
1674
|
console.debug("Already selected");
|
|
1254
1675
|
return;
|
|
1255
1676
|
}
|
|
1256
|
-
if (
|
|
1677
|
+
if (state.isSwappingCamera) {
|
|
1257
1678
|
console.debug("Already swapping");
|
|
1258
1679
|
return;
|
|
1259
1680
|
}
|
|
1260
|
-
|
|
1261
|
-
isSwappingCamera:
|
|
1262
|
-
})
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1681
|
+
cameraManagerStore.setState({
|
|
1682
|
+
isSwappingCamera: true
|
|
1683
|
+
});
|
|
1684
|
+
if (state.selectedCamera?.activeStream) {
|
|
1685
|
+
console.debug("Stopping previous stream");
|
|
1686
|
+
state.selectedCamera.stopStream();
|
|
1687
|
+
}
|
|
1688
|
+
if (state.videoElement) {
|
|
1689
|
+
state.videoElement.srcObject = null;
|
|
1690
|
+
}
|
|
1691
|
+
cameraManagerStore.setState({
|
|
1692
|
+
selectedCamera: camera,
|
|
1693
|
+
isSwappingCamera: false
|
|
1694
|
+
});
|
|
1695
|
+
if (this.#resumeRequest === "playback") {
|
|
1696
|
+
console.debug("Starting new stream");
|
|
1697
|
+
await this.startPlayback();
|
|
1698
|
+
}
|
|
1699
|
+
if (this.#resumeRequest === "capturing") {
|
|
1700
|
+
console.debug("Resuming frame capture");
|
|
1701
|
+
await this.startFrameCapture();
|
|
1702
|
+
}
|
|
1703
|
+
this.#resumeRequest = void 0;
|
|
1266
1704
|
}
|
|
1267
1705
|
/**
|
|
1268
1706
|
* Refreshes available devices on the system and updates the state.
|
|
1269
1707
|
*/
|
|
1270
1708
|
async refreshCameraDevices() {
|
|
1271
|
-
if (
|
|
1709
|
+
if (cameraManagerStore.getState().isQueryingCameras || cameraManagerStore.getState().isSwappingCamera) {
|
|
1272
1710
|
console.debug("Already querying cameras");
|
|
1273
1711
|
return;
|
|
1274
1712
|
}
|
|
1275
|
-
|
|
1276
|
-
isQueryingCameras:
|
|
1713
|
+
cameraManagerStore.setState({
|
|
1714
|
+
isQueryingCameras: true
|
|
1277
1715
|
});
|
|
1278
|
-
const
|
|
1279
|
-
|
|
1280
|
-
errorState:
|
|
1281
|
-
isQueryingCameras:
|
|
1282
|
-
})
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1716
|
+
const availableCameras = await obtainVideoInputDevices().catch((err) => {
|
|
1717
|
+
cameraManagerStore.setState({
|
|
1718
|
+
errorState: asError(err),
|
|
1719
|
+
isQueryingCameras: false
|
|
1720
|
+
});
|
|
1721
|
+
throw err;
|
|
1722
|
+
});
|
|
1723
|
+
const cameras = createCameras(availableCameras);
|
|
1724
|
+
cameras.forEach((camera) => {
|
|
1725
|
+
if (camera.notifyStateChange) {
|
|
1726
|
+
return;
|
|
1727
|
+
}
|
|
1728
|
+
camera.notifyStateChange = (camInstance, reason) => {
|
|
1286
1729
|
window.queueMicrotask(() => {
|
|
1287
|
-
|
|
1288
|
-
cameras: [...
|
|
1730
|
+
cameraManagerStore.setState({
|
|
1731
|
+
cameras: [...cameraManagerStore.getState().cameras]
|
|
1289
1732
|
});
|
|
1290
|
-
const
|
|
1291
|
-
if (!
|
|
1733
|
+
const selectedCamera = cameraManagerStore.getState().selectedCamera;
|
|
1734
|
+
if (!selectedCamera) {
|
|
1292
1735
|
return;
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
}
|
|
1736
|
+
}
|
|
1737
|
+
let streamError;
|
|
1738
|
+
if (typeof reason === "object" && reason !== null && "payload" in reason && reason.payload === "TRACK_END") {
|
|
1739
|
+
streamError = new Error("Camera stream ended unexpectedly");
|
|
1740
|
+
}
|
|
1741
|
+
if (camInstance === selectedCamera) {
|
|
1742
|
+
cameraManagerStore.setState({
|
|
1743
|
+
selectedCamera,
|
|
1744
|
+
errorState: streamError
|
|
1745
|
+
});
|
|
1746
|
+
}
|
|
1298
1747
|
});
|
|
1299
|
-
}
|
|
1300
|
-
})
|
|
1301
|
-
|
|
1302
|
-
|
|
1748
|
+
};
|
|
1749
|
+
});
|
|
1750
|
+
cameraManagerStore.setState({
|
|
1751
|
+
cameras,
|
|
1752
|
+
isQueryingCameras: false
|
|
1303
1753
|
});
|
|
1304
1754
|
}
|
|
1305
1755
|
/**
|
|
@@ -1308,140 +1758,181 @@ class Qr {
|
|
|
1308
1758
|
* @returns resolves when playback starts
|
|
1309
1759
|
*/
|
|
1310
1760
|
async startPlayback() {
|
|
1311
|
-
const
|
|
1312
|
-
if (
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1761
|
+
const state = cameraManagerStore.getState();
|
|
1762
|
+
if (this.isActive && !this.#resumeRequest) {
|
|
1763
|
+
return;
|
|
1764
|
+
}
|
|
1765
|
+
if (!state.videoElement) {
|
|
1766
|
+
console.warn("Starting playback - no video element present.");
|
|
1767
|
+
return;
|
|
1768
|
+
}
|
|
1769
|
+
if (!state.selectedCamera) {
|
|
1770
|
+
console.warn("Select a camera first.");
|
|
1771
|
+
return;
|
|
1772
|
+
}
|
|
1773
|
+
if (!state.selectedCamera.activeStream) {
|
|
1774
|
+
const stream = await state.selectedCamera.startStream(this.resolution);
|
|
1775
|
+
state.videoElement.srcObject = stream;
|
|
1776
|
+
}
|
|
1777
|
+
try {
|
|
1778
|
+
this.#applyMirrorIfNeeded();
|
|
1779
|
+
await state.videoElement.play();
|
|
1780
|
+
cameraManagerStore.setState({
|
|
1781
|
+
playbackState: "playback"
|
|
1782
|
+
});
|
|
1783
|
+
} catch (error) {
|
|
1784
|
+
console.error("Failed to start playback", error);
|
|
1785
|
+
cameraManagerStore.setState({
|
|
1786
|
+
errorState: asError(error)
|
|
1787
|
+
});
|
|
1788
|
+
throw error;
|
|
1334
1789
|
}
|
|
1335
1790
|
}
|
|
1336
1791
|
/**
|
|
1337
1792
|
* Starts playback and frame capturing.
|
|
1338
1793
|
*/
|
|
1339
|
-
async #
|
|
1340
|
-
const
|
|
1341
|
-
if (
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1794
|
+
async #startFrameCapture() {
|
|
1795
|
+
const state = cameraManagerStore.getState();
|
|
1796
|
+
if (this.userInitiatedAbort) {
|
|
1797
|
+
return;
|
|
1798
|
+
}
|
|
1799
|
+
if (state.playbackState === "capturing" && this.#resumeRequest !== "capturing") {
|
|
1800
|
+
return;
|
|
1801
|
+
}
|
|
1802
|
+
if (!state.videoElement) {
|
|
1803
|
+
console.warn(
|
|
1804
|
+
"Missing video element. Setup a video element first using `initVideoElement`"
|
|
1805
|
+
);
|
|
1806
|
+
return;
|
|
1807
|
+
}
|
|
1808
|
+
if (!state.selectedCamera) {
|
|
1809
|
+
console.warn(
|
|
1810
|
+
"No active camera! Select a camera first, or use `startCameraStream`"
|
|
1811
|
+
);
|
|
1812
|
+
return;
|
|
1357
1813
|
}
|
|
1814
|
+
await this.startPlayback();
|
|
1815
|
+
cameraManagerStore.setState({
|
|
1816
|
+
playbackState: "capturing"
|
|
1817
|
+
});
|
|
1818
|
+
this.#queueFrame();
|
|
1819
|
+
this.#resumeRequest = void 0;
|
|
1358
1820
|
}
|
|
1359
1821
|
/**
|
|
1360
1822
|
* Starts capturing frames from the video element.
|
|
1361
1823
|
*/
|
|
1362
1824
|
startFrameCapture = async () => {
|
|
1363
1825
|
try {
|
|
1364
|
-
await this.#
|
|
1365
|
-
} catch (
|
|
1366
|
-
if (this.userInitiatedAbort)
|
|
1826
|
+
await this.#startFrameCapture();
|
|
1827
|
+
} catch (error) {
|
|
1828
|
+
if (this.userInitiatedAbort) {
|
|
1367
1829
|
this.reset();
|
|
1368
|
-
else
|
|
1369
|
-
throw
|
|
1830
|
+
} else {
|
|
1831
|
+
throw error;
|
|
1832
|
+
}
|
|
1370
1833
|
}
|
|
1371
1834
|
};
|
|
1372
|
-
async #
|
|
1373
|
-
autoplay
|
|
1374
|
-
preferredCamera
|
|
1375
|
-
preferredFacing
|
|
1835
|
+
async #startCameraStream({
|
|
1836
|
+
autoplay = true,
|
|
1837
|
+
preferredCamera,
|
|
1838
|
+
preferredFacing
|
|
1376
1839
|
} = {}) {
|
|
1377
|
-
const
|
|
1378
|
-
if (!
|
|
1840
|
+
const videoElement = cameraManagerStore.getState().videoElement;
|
|
1841
|
+
if (!videoElement) {
|
|
1379
1842
|
console.warn("Can't start stream without a video element");
|
|
1380
1843
|
return;
|
|
1381
1844
|
}
|
|
1382
|
-
if (this.isActive && !this.#
|
|
1845
|
+
if (this.isActive && !this.#resumeRequest) {
|
|
1383
1846
|
console.warn("Already streaming");
|
|
1384
1847
|
return;
|
|
1385
1848
|
}
|
|
1386
|
-
if (
|
|
1849
|
+
if (preferredCamera instanceof Camera) {
|
|
1850
|
+
await this.selectCamera(preferredCamera);
|
|
1851
|
+
}
|
|
1852
|
+
if (!cameraManagerStore.getState().selectedCamera) {
|
|
1387
1853
|
try {
|
|
1388
|
-
const
|
|
1389
|
-
let
|
|
1390
|
-
if (!
|
|
1391
|
-
|
|
1392
|
-
|
|
1854
|
+
const cameras = await this.getCameraDevices();
|
|
1855
|
+
let selectedCamera2;
|
|
1856
|
+
if (!cameras.length) {
|
|
1857
|
+
console.log("Camera list is empty");
|
|
1858
|
+
throw new Error(
|
|
1859
|
+
`No cameras found matching the filter ${preferredFacing}`
|
|
1393
1860
|
);
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1861
|
+
}
|
|
1862
|
+
if (typeof preferredCamera === "function") {
|
|
1863
|
+
selectedCamera2 = preferredCamera(cameras);
|
|
1864
|
+
if (!selectedCamera2) {
|
|
1865
|
+
console.warn(
|
|
1866
|
+
`No camera found matching the preferred camera function, falling back to facing mode`
|
|
1867
|
+
);
|
|
1868
|
+
}
|
|
1869
|
+
}
|
|
1870
|
+
if (!selectedCamera2) {
|
|
1871
|
+
selectedCamera2 = await findIdealCamera(
|
|
1872
|
+
cameras,
|
|
1873
|
+
this.resolution,
|
|
1874
|
+
preferredFacing
|
|
1875
|
+
);
|
|
1876
|
+
}
|
|
1877
|
+
if (!selectedCamera2) {
|
|
1401
1878
|
throw new Error(
|
|
1402
|
-
`No cameras found matching the filter ${
|
|
1879
|
+
`No cameras found matching the filter ${preferredFacing}`
|
|
1403
1880
|
);
|
|
1404
|
-
|
|
1405
|
-
|
|
1881
|
+
}
|
|
1882
|
+
await this.selectCamera(selectedCamera2);
|
|
1883
|
+
if (this.#hasPermissionError()) {
|
|
1884
|
+
cameraManagerStore.setState({
|
|
1885
|
+
errorState: void 0
|
|
1886
|
+
});
|
|
1887
|
+
}
|
|
1888
|
+
} catch (error) {
|
|
1889
|
+
cameraManagerStore.setState({
|
|
1890
|
+
errorState: asError(error)
|
|
1406
1891
|
});
|
|
1407
|
-
|
|
1408
|
-
throw d.setState({
|
|
1409
|
-
errorState: X(l)
|
|
1410
|
-
}), l;
|
|
1892
|
+
throw error;
|
|
1411
1893
|
}
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1894
|
+
}
|
|
1895
|
+
const selectedCamera = cameraManagerStore.getState().selectedCamera;
|
|
1896
|
+
if (!selectedCamera) {
|
|
1897
|
+
console.warn("No selected camera!");
|
|
1898
|
+
throw new Error("No selected camera");
|
|
1899
|
+
}
|
|
1900
|
+
const stream = await selectedCamera.startStream(this.#resolution);
|
|
1901
|
+
if (!videoElement.isConnected) {
|
|
1417
1902
|
throw new Error("Video element needs to be in the document!");
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1903
|
+
}
|
|
1904
|
+
videoElement.srcObject = stream;
|
|
1905
|
+
cameraManagerStore.setState({
|
|
1906
|
+
videoElement
|
|
1907
|
+
});
|
|
1908
|
+
if (autoplay) {
|
|
1909
|
+
await this.startPlayback();
|
|
1910
|
+
}
|
|
1421
1911
|
}
|
|
1422
1912
|
/**
|
|
1423
1913
|
* Starts a best-effort camera stream. Will pick a camera automatically if
|
|
1424
1914
|
* none is selected.
|
|
1425
1915
|
*/
|
|
1426
|
-
async startCameraStream(
|
|
1916
|
+
async startCameraStream(params = {}) {
|
|
1427
1917
|
try {
|
|
1428
|
-
await this.#
|
|
1429
|
-
} catch (
|
|
1430
|
-
if (this.userInitiatedAbort)
|
|
1918
|
+
await this.#startCameraStream(params);
|
|
1919
|
+
} catch (error) {
|
|
1920
|
+
if (this.userInitiatedAbort) {
|
|
1431
1921
|
this.reset();
|
|
1432
|
-
else
|
|
1433
|
-
throw
|
|
1922
|
+
} else {
|
|
1923
|
+
throw error;
|
|
1924
|
+
}
|
|
1434
1925
|
}
|
|
1435
1926
|
}
|
|
1436
|
-
#
|
|
1437
|
-
const
|
|
1438
|
-
return
|
|
1927
|
+
#hasPermissionError = () => {
|
|
1928
|
+
const errorState = cameraManagerStore.getState().errorState;
|
|
1929
|
+
return errorState instanceof CameraError && errorState.code === "PERMISSION_DENIED";
|
|
1439
1930
|
};
|
|
1440
1931
|
/**
|
|
1441
1932
|
* Pauses capturing frames without pausing playback.
|
|
1442
1933
|
*/
|
|
1443
1934
|
stopFrameCapture() {
|
|
1444
|
-
|
|
1935
|
+
cameraManagerStore.setState({
|
|
1445
1936
|
playbackState: "playback"
|
|
1446
1937
|
});
|
|
1447
1938
|
}
|
|
@@ -1450,92 +1941,128 @@ class Qr {
|
|
|
1450
1941
|
*/
|
|
1451
1942
|
stopStream() {
|
|
1452
1943
|
console.debug("stopStream called");
|
|
1453
|
-
const
|
|
1454
|
-
this.pausePlayback()
|
|
1944
|
+
const state = cameraManagerStore.getState();
|
|
1945
|
+
this.pausePlayback();
|
|
1946
|
+
state.selectedCamera?.stopStream();
|
|
1947
|
+
if (state.videoElement) {
|
|
1948
|
+
state.videoElement.srcObject = null;
|
|
1949
|
+
}
|
|
1455
1950
|
}
|
|
1456
1951
|
/**
|
|
1457
1952
|
* Pauses the video playback. This will also stop the capturing process.
|
|
1458
1953
|
*/
|
|
1459
1954
|
pausePlayback() {
|
|
1460
1955
|
console.debug("pausePlayback called");
|
|
1461
|
-
const
|
|
1462
|
-
|
|
1956
|
+
const video = cameraManagerStore.getState().videoElement;
|
|
1957
|
+
cameraManagerStore.setState({
|
|
1463
1958
|
playbackState: "idle"
|
|
1464
|
-
})
|
|
1959
|
+
});
|
|
1960
|
+
if (!video) {
|
|
1961
|
+
return;
|
|
1962
|
+
}
|
|
1963
|
+
if (this.#videoFrameRequestId) {
|
|
1964
|
+
video.cancelVideoFrameCallback(this.#videoFrameRequestId);
|
|
1965
|
+
}
|
|
1966
|
+
video.pause();
|
|
1465
1967
|
}
|
|
1466
1968
|
/**
|
|
1467
1969
|
* The main recognition loop. Do not call this method directly, use #queueFrame instead.
|
|
1468
1970
|
*/
|
|
1469
|
-
async #
|
|
1470
|
-
const
|
|
1471
|
-
if (this.#
|
|
1971
|
+
async #loop() {
|
|
1972
|
+
const state = cameraManagerStore.getState();
|
|
1973
|
+
if (this.#videoFrameRequestId === void 0) {
|
|
1472
1974
|
console.error("Missing request ID");
|
|
1473
1975
|
return;
|
|
1474
1976
|
}
|
|
1475
|
-
if (!
|
|
1977
|
+
if (!state.videoElement) {
|
|
1476
1978
|
console.warn("Missing video element, should not happen");
|
|
1477
1979
|
return;
|
|
1478
1980
|
}
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1981
|
+
const isSameOrientation = state.videoElement.videoHeight >= state.videoElement.videoWidth === this.#extractionArea.height >= this.#extractionArea.width;
|
|
1982
|
+
if (!isSameOrientation) {
|
|
1983
|
+
return this.#queueFrame();
|
|
1984
|
+
}
|
|
1985
|
+
if (this.#frameCaptureCallbacks.size !== 0) {
|
|
1986
|
+
const capturedFrame = this.#videoFrameProcessor.getImageData(
|
|
1987
|
+
state.videoElement,
|
|
1988
|
+
this.#extractionArea
|
|
1485
1989
|
);
|
|
1486
|
-
for (const
|
|
1487
|
-
const
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1990
|
+
for (const callback of this.#frameCaptureCallbacks) {
|
|
1991
|
+
const workingFrame = isBufferDetached(capturedFrame.data) ? this.#videoFrameProcessor.getCurrentImageData() : capturedFrame;
|
|
1992
|
+
const returnedBuffer = await callback(workingFrame);
|
|
1993
|
+
if (!returnedBuffer) {
|
|
1994
|
+
continue;
|
|
1995
|
+
}
|
|
1996
|
+
if (!(returnedBuffer instanceof ArrayBuffer)) {
|
|
1997
|
+
throw new Error(
|
|
1998
|
+
stripIndents`
|
|
1492
1999
|
Frame capture callback did not return an ArrayBuffer.
|
|
1493
2000
|
Make sure to return the underlying buffer, not the view.
|
|
1494
2001
|
`
|
|
1495
|
-
|
|
1496
|
-
this.#n.reattachArrayBuffer(i);
|
|
2002
|
+
);
|
|
1497
2003
|
}
|
|
2004
|
+
this.#videoFrameProcessor.reattachArrayBuffer(returnedBuffer);
|
|
1498
2005
|
}
|
|
1499
2006
|
}
|
|
1500
|
-
this.#
|
|
2007
|
+
this.#queueFrame();
|
|
1501
2008
|
}
|
|
1502
2009
|
/**
|
|
1503
2010
|
* Queues the next frame to be processed
|
|
1504
2011
|
*/
|
|
1505
|
-
#
|
|
1506
|
-
const
|
|
1507
|
-
if (
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
2012
|
+
#queueFrame() {
|
|
2013
|
+
const state = cameraManagerStore.getState();
|
|
2014
|
+
if (state.playbackState !== "capturing") {
|
|
2015
|
+
return;
|
|
2016
|
+
}
|
|
2017
|
+
if (!state.videoElement) {
|
|
2018
|
+
console.warn("Missing video element, should not happen");
|
|
2019
|
+
return;
|
|
2020
|
+
}
|
|
2021
|
+
if (this.#videoFrameRequestId) {
|
|
2022
|
+
state.videoElement.cancelVideoFrameCallback(this.#videoFrameRequestId);
|
|
1515
2023
|
}
|
|
2024
|
+
this.#videoFrameRequestId = state.videoElement.requestVideoFrameCallback(
|
|
2025
|
+
() => void this.#loop()
|
|
2026
|
+
);
|
|
1516
2027
|
}
|
|
1517
2028
|
/**
|
|
1518
2029
|
* Applies a mirror effect to the video if the camera is front-facing.
|
|
1519
2030
|
* Assumes that desktop devices don't return a facing mode and that they are front-facing.
|
|
1520
2031
|
*/
|
|
1521
|
-
#
|
|
1522
|
-
const
|
|
1523
|
-
if (!
|
|
2032
|
+
#applyMirrorIfNeeded() {
|
|
2033
|
+
const camera = cameraManagerStore.getState().selectedCamera;
|
|
2034
|
+
if (!camera) {
|
|
1524
2035
|
console.warn("No camera selected");
|
|
1525
2036
|
return;
|
|
1526
2037
|
}
|
|
1527
|
-
|
|
2038
|
+
if (!this.#mirrorFrontCameras) {
|
|
2039
|
+
return;
|
|
2040
|
+
}
|
|
2041
|
+
if (camera.facingMode !== "back") {
|
|
2042
|
+
this.setCameraMirrorX(true);
|
|
2043
|
+
} else {
|
|
2044
|
+
this.setCameraMirrorX(false);
|
|
2045
|
+
}
|
|
1528
2046
|
}
|
|
1529
2047
|
/**
|
|
1530
2048
|
* If true, the video and captured frames will be mirrored horizontally.
|
|
1531
2049
|
*/
|
|
1532
|
-
setCameraMirrorX(
|
|
1533
|
-
const
|
|
1534
|
-
|
|
2050
|
+
setCameraMirrorX(mirrorX) {
|
|
2051
|
+
const currentState = cameraManagerStore.getState();
|
|
2052
|
+
const videoElement = currentState.videoElement;
|
|
2053
|
+
if (!videoElement) {
|
|
1535
2054
|
console.warn("Mirror video - no video element present.");
|
|
1536
2055
|
return;
|
|
1537
2056
|
}
|
|
1538
|
-
|
|
2057
|
+
if (currentState.mirrorX === mirrorX) {
|
|
2058
|
+
return;
|
|
2059
|
+
}
|
|
2060
|
+
if (mirrorX) {
|
|
2061
|
+
videoElement.style.scale = "-1 1";
|
|
2062
|
+
} else {
|
|
2063
|
+
videoElement.style.removeProperty("scale");
|
|
2064
|
+
}
|
|
2065
|
+
cameraManagerStore.setState({ mirrorX });
|
|
1539
2066
|
}
|
|
1540
2067
|
// The "typeof" is necessary to avoid a circular dependency when resolving types
|
|
1541
2068
|
/**
|
|
@@ -1543,54 +2070,64 @@ class Qr {
|
|
|
1543
2070
|
* Implemented using Zustand. For usage information, see
|
|
1544
2071
|
* {@link https://github.com/pmndrs/zustand#using-subscribe-with-selector}
|
|
1545
2072
|
*/
|
|
1546
|
-
subscribe =
|
|
2073
|
+
subscribe = cameraManagerStore.subscribe;
|
|
1547
2074
|
/**
|
|
1548
2075
|
* Gets the current internal state of the CameraManager.
|
|
1549
2076
|
*/
|
|
1550
|
-
getState =
|
|
2077
|
+
getState = cameraManagerStore.getState;
|
|
1551
2078
|
/**
|
|
1552
2079
|
* Resets the CameraManager and stop all streams
|
|
1553
2080
|
*/
|
|
1554
2081
|
reset() {
|
|
1555
|
-
console.debug("Resetting camera manager")
|
|
2082
|
+
console.debug("Resetting camera manager");
|
|
2083
|
+
this.#frameCaptureCallbacks.clear();
|
|
2084
|
+
this.stopStream();
|
|
2085
|
+
resetCameraManagerStore();
|
|
1556
2086
|
}
|
|
1557
2087
|
}
|
|
1558
|
-
const
|
|
1559
|
-
function
|
|
1560
|
-
return
|
|
2088
|
+
const CameraUiStoreContext = createContext();
|
|
2089
|
+
function createCameraManagerSolidStore() {
|
|
2090
|
+
return createWithSignal(cameraManagerStore);
|
|
1561
2091
|
}
|
|
1562
|
-
const
|
|
1563
|
-
const
|
|
1564
|
-
cameraManagerSolidStore:
|
|
2092
|
+
const CameraUiStoreProvider = (props) => {
|
|
2093
|
+
const contextValue = {
|
|
2094
|
+
cameraManagerSolidStore: createCameraManagerSolidStore(),
|
|
1565
2095
|
// eslint-disable-next-line solid/reactivity
|
|
1566
|
-
cameraManager:
|
|
2096
|
+
cameraManager: props.cameraManager,
|
|
1567
2097
|
// eslint-disable-next-line solid/reactivity
|
|
1568
2098
|
dismountCameraUi: () => {
|
|
1569
|
-
|
|
2099
|
+
props.cameraManager.userInitiatedAbort = true;
|
|
2100
|
+
props.dismountCameraUi();
|
|
1570
2101
|
},
|
|
1571
2102
|
// eslint-disable-next-line solid/reactivity
|
|
1572
|
-
addOnDismountCallback:
|
|
2103
|
+
addOnDismountCallback: props.addOnDismountCallback,
|
|
1573
2104
|
// eslint-disable-next-line solid/reactivity
|
|
1574
|
-
mountTarget:
|
|
2105
|
+
mountTarget: props.mountTarget,
|
|
1575
2106
|
// eslint-disable-next-line solid/reactivity
|
|
1576
|
-
showMirrorCameraButton:
|
|
2107
|
+
showMirrorCameraButton: props.showMirrorCameraButton,
|
|
2108
|
+
// eslint-disable-next-line solid/reactivity
|
|
2109
|
+
showTorchButton: props.showTorchButton,
|
|
2110
|
+
// eslint-disable-next-line solid/reactivity
|
|
2111
|
+
showCloseButton: props.showCloseButton
|
|
1577
2112
|
};
|
|
1578
|
-
|
|
2113
|
+
onCleanup(() => {
|
|
1579
2114
|
console.debug("CameraUiStoreProvider cleanup");
|
|
1580
|
-
})
|
|
1581
|
-
|
|
2115
|
+
});
|
|
2116
|
+
return createComponent(CameraUiStoreContext.Provider, {
|
|
2117
|
+
value: contextValue,
|
|
1582
2118
|
get children() {
|
|
1583
|
-
return
|
|
2119
|
+
return props.children;
|
|
1584
2120
|
}
|
|
1585
2121
|
});
|
|
1586
2122
|
};
|
|
1587
|
-
function
|
|
1588
|
-
const
|
|
1589
|
-
if (!
|
|
2123
|
+
function useCameraUiStore() {
|
|
2124
|
+
const ctx = useContext(CameraUiStoreContext);
|
|
2125
|
+
if (!ctx) {
|
|
1590
2126
|
throw new Error("StoreContext.Provider not in scope");
|
|
1591
|
-
|
|
2127
|
+
}
|
|
2128
|
+
return ctx;
|
|
1592
2129
|
}
|
|
1593
|
-
const
|
|
2130
|
+
const enLocaleStrings = {
|
|
1594
2131
|
selected_camera: "Selected camera",
|
|
1595
2132
|
loading_cameras: "Loading cameras...",
|
|
1596
2133
|
select_a_camera: "Select a camera",
|
|
@@ -1603,229 +2140,277 @@ const It = {
|
|
|
1603
2140
|
camera_error_details: "Please allow camera access in your browser and try again.",
|
|
1604
2141
|
camera_error_cancel_btn: "Cancel",
|
|
1605
2142
|
camera_error_primary_btn: "Retry"
|
|
1606
|
-
}
|
|
1607
|
-
|
|
2143
|
+
};
|
|
2144
|
+
const LocalizationContext = createContext();
|
|
2145
|
+
const LocalizationProvider = (props) => {
|
|
2146
|
+
const [localizationStore, updateLocalizationStore] = createStore$1(
|
|
1608
2147
|
// we structure clone to avoid proxying to the original object
|
|
1609
2148
|
structuredClone({
|
|
1610
|
-
...
|
|
2149
|
+
...enLocaleStrings,
|
|
1611
2150
|
// we don't care on init
|
|
1612
2151
|
// eslint-disable-next-line solid/reactivity
|
|
1613
|
-
...
|
|
2152
|
+
...props.userStrings
|
|
1614
2153
|
})
|
|
1615
2154
|
);
|
|
1616
|
-
|
|
1617
|
-
|
|
2155
|
+
onMount(() => {
|
|
2156
|
+
props.setLocalizationRef(updateLocalizationStore);
|
|
1618
2157
|
});
|
|
1619
|
-
const
|
|
1620
|
-
t:
|
|
1621
|
-
updateLocalization:
|
|
2158
|
+
const contextValue = {
|
|
2159
|
+
t: localizationStore,
|
|
2160
|
+
updateLocalization: updateLocalizationStore
|
|
1622
2161
|
};
|
|
1623
|
-
return
|
|
1624
|
-
value:
|
|
2162
|
+
return createComponent(LocalizationContext.Provider, {
|
|
2163
|
+
value: contextValue,
|
|
1625
2164
|
get children() {
|
|
1626
|
-
return
|
|
2165
|
+
return props.children;
|
|
1627
2166
|
}
|
|
1628
2167
|
});
|
|
1629
2168
|
};
|
|
1630
|
-
function
|
|
1631
|
-
const
|
|
1632
|
-
if (!
|
|
2169
|
+
function useLocalization() {
|
|
2170
|
+
const ctx = useContext(LocalizationContext);
|
|
2171
|
+
if (!ctx) {
|
|
1633
2172
|
throw new Error("LocalizationContext.Provider not in scope.");
|
|
1634
|
-
|
|
2173
|
+
}
|
|
2174
|
+
return ctx;
|
|
1635
2175
|
}
|
|
1636
|
-
var
|
|
1637
|
-
const
|
|
1638
|
-
const [
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
2176
|
+
var _tmpl$$c = /* @__PURE__ */ template(`<span>`);
|
|
2177
|
+
const SmartEnvironmentProvider = (props) => {
|
|
2178
|
+
const [rootNode, setRootNode] = createSignal();
|
|
2179
|
+
const [ref, setRef] = createSignal();
|
|
2180
|
+
onMount(() => {
|
|
2181
|
+
const spanRef = ref();
|
|
2182
|
+
if (!spanRef) {
|
|
2183
|
+
return;
|
|
2184
|
+
}
|
|
2185
|
+
setRootNode(spanRef.getRootNode());
|
|
2186
|
+
});
|
|
2187
|
+
return createComponent(Show, {
|
|
1643
2188
|
get when() {
|
|
1644
|
-
return
|
|
2189
|
+
return rootNode();
|
|
1645
2190
|
},
|
|
1646
2191
|
get fallback() {
|
|
1647
2192
|
return (() => {
|
|
1648
|
-
var
|
|
1649
|
-
|
|
2193
|
+
var _el$ = _tmpl$$c();
|
|
2194
|
+
use(setRef, _el$);
|
|
2195
|
+
return _el$;
|
|
1650
2196
|
})();
|
|
1651
2197
|
},
|
|
1652
|
-
children: (
|
|
1653
|
-
value: () =>
|
|
2198
|
+
children: (rootNode2) => createComponent(EnvironmentProvider, {
|
|
2199
|
+
value: () => rootNode2(),
|
|
1654
2200
|
get children() {
|
|
1655
|
-
return
|
|
2201
|
+
return props.children(rootNode2());
|
|
1656
2202
|
}
|
|
1657
2203
|
})
|
|
1658
2204
|
});
|
|
1659
2205
|
};
|
|
1660
|
-
var
|
|
1661
|
-
const
|
|
1662
|
-
var
|
|
1663
|
-
|
|
2206
|
+
var _tmpl$$b = /* @__PURE__ */ template(`<svg viewBox="0 0 24 24"width=1.2em height=1.2em><path fill=currentColor d="M6.4 19L5 17.6l5.6-5.6L5 6.4L6.4 5l5.6 5.6L17.6 5L19 6.4L13.4 12l5.6 5.6l-1.4 1.4l-5.6-5.6z">`);
|
|
2207
|
+
const CloseIcon = (props = {}) => (() => {
|
|
2208
|
+
var _el$ = _tmpl$$b();
|
|
2209
|
+
spread(_el$, props, true, true);
|
|
2210
|
+
return _el$;
|
|
1664
2211
|
})();
|
|
1665
|
-
var
|
|
1666
|
-
const
|
|
1667
|
-
var
|
|
1668
|
-
|
|
2212
|
+
var _tmpl$$a = /* @__PURE__ */ template(`<svg viewBox="0 0 24 24"width=1.2em height=1.2em><path fill=currentColor d="M7 2h10l-2 7h4l-2.925 4.225L7 4.15zm3 20v-8H7V9.85L1.375 4.225L2.8 2.8l18.4 18.4l-1.425 1.425L13.75 16.6z">`);
|
|
2213
|
+
const FlashOff = (props = {}) => (() => {
|
|
2214
|
+
var _el$ = _tmpl$$a();
|
|
2215
|
+
spread(_el$, props, true, true);
|
|
2216
|
+
return _el$;
|
|
1669
2217
|
})();
|
|
1670
|
-
var
|
|
1671
|
-
const
|
|
1672
|
-
var
|
|
1673
|
-
|
|
2218
|
+
var _tmpl$$9 = /* @__PURE__ */ template(`<svg viewBox="0 0 24 24"width=1.2em height=1.2em><path fill=currentColor d="M10 22v-8H7V2h10l-2 7h4z">`);
|
|
2219
|
+
const FlashOn = (props = {}) => (() => {
|
|
2220
|
+
var _el$ = _tmpl$$9();
|
|
2221
|
+
spread(_el$, props, true, true);
|
|
2222
|
+
return _el$;
|
|
1674
2223
|
})();
|
|
1675
|
-
var
|
|
1676
|
-
const
|
|
1677
|
-
var
|
|
1678
|
-
|
|
2224
|
+
var _tmpl$$8 = /* @__PURE__ */ template(`<svg viewBox="0 0 24 24"width=1.2em height=1.2em><path fill=currentColor d="M9 21H5q-.825 0-1.412-.587T3 19V5q0-.825.588-1.412T5 3h4v2H5v14h4zm2 2V1h2v22zm4-2v-2h2v2zm0-16V3h2v2zm4 16v-2h2q0 .825-.587 1.413T19 21m0-4v-2h2v2zm0-4v-2h2v2zm0-4V7h2v2zm0-4V3q.825 0 1.413.588T21 5z">`);
|
|
2225
|
+
const MirrorIcon = (props = {}) => (() => {
|
|
2226
|
+
var _el$ = _tmpl$$8();
|
|
2227
|
+
spread(_el$, props, true, true);
|
|
2228
|
+
return _el$;
|
|
1679
2229
|
})();
|
|
1680
|
-
function
|
|
1681
|
-
const
|
|
1682
|
-
|
|
1683
|
-
const
|
|
1684
|
-
let
|
|
1685
|
-
if (
|
|
1686
|
-
|
|
1687
|
-
const
|
|
1688
|
-
|
|
1689
|
-
} else
|
|
1690
|
-
|
|
1691
|
-
|
|
2230
|
+
function eventFixer(props) {
|
|
2231
|
+
const newObj = {};
|
|
2232
|
+
Object.entries(props).forEach(([key, value]) => {
|
|
2233
|
+
const lowerCaseKey = key.toLowerCase();
|
|
2234
|
+
let trimmedKey = lowerCaseKey;
|
|
2235
|
+
if (lowerCaseKey.startsWith("on")) {
|
|
2236
|
+
trimmedKey = lowerCaseKey.slice(2);
|
|
2237
|
+
const newKey = `on:${trimmedKey}`;
|
|
2238
|
+
newObj[newKey] = value;
|
|
2239
|
+
} else {
|
|
2240
|
+
newObj[trimmedKey] = value;
|
|
2241
|
+
}
|
|
2242
|
+
});
|
|
2243
|
+
return newObj;
|
|
1692
2244
|
}
|
|
1693
|
-
var
|
|
1694
|
-
const
|
|
1695
|
-
var
|
|
1696
|
-
|
|
2245
|
+
var _tmpl$$7 = /* @__PURE__ */ template(`<svg xmlns=http://www.w3.org/2000/svg fill=none viewBox="0 0 20 20"><g fill=#fff fill-rule=evenodd clip-rule=evenodd><path d="M6.322 2.988A1.67 1.67 0 0 1 7.5 2.5h5a1.667 1.667 0 0 1 1.667 1.667A.833.833 0 0 0 15 5h.833a2.5 2.5 0 0 1 2.5 2.5V15a2.5 2.5 0 0 1-2.5 2.5H4.167a2.5 2.5 0 0 1-2.5-2.5V7.5a2.5 2.5 0 0 1 2.5-2.5H5a.833.833 0 0 0 .833-.833c0-.442.176-.866.489-1.179M4.167 6.667a.833.833 0 0 0-.834.833V15a.833.833 0 0 0 .834.833h11.666a.834.834 0 0 0 .834-.833V7.5a.833.833 0 0 0-.834-.833H15a2.5 2.5 0 0 1-2.5-2.5h-5a2.5 2.5 0 0 1-2.5 2.5z"></path><path d="M10 9.167a1.667 1.667 0 1 0 0 3.333 1.667 1.667 0 0 0 0-3.333m-3.333 1.666a3.333 3.333 0 1 1 6.666 0 3.333 3.333 0 0 1-6.666 0">`);
|
|
2246
|
+
const IconCamera = (props = {}) => (() => {
|
|
2247
|
+
var _el$ = _tmpl$$7();
|
|
2248
|
+
spread(_el$, props, true, true);
|
|
2249
|
+
return _el$;
|
|
1697
2250
|
})();
|
|
1698
|
-
var
|
|
1699
|
-
const
|
|
1700
|
-
var
|
|
1701
|
-
|
|
2251
|
+
var _tmpl$$6 = /* @__PURE__ */ template(`<svg xmlns=http://www.w3.org/2000/svg fill=none viewBox="0 0 20 20"><path stroke=#fff stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M4.167 10.833 7.5 14.167l8.333-8.334">`);
|
|
2252
|
+
const IconCheck = (props = {}) => (() => {
|
|
2253
|
+
var _el$ = _tmpl$$6();
|
|
2254
|
+
spread(_el$, props, true, true);
|
|
2255
|
+
return _el$;
|
|
1702
2256
|
})();
|
|
1703
|
-
var
|
|
1704
|
-
const
|
|
1705
|
-
var
|
|
1706
|
-
|
|
2257
|
+
var _tmpl$$5 = /* @__PURE__ */ template(`<svg xmlns=http://www.w3.org/2000/svg fill=none viewBox="0 0 20 20"><path fill=#fff fill-rule=evenodd d="M4.41 6.91a.833.833 0 0 1 1.18 0L10 11.323l4.41-4.411a.833.833 0 1 1 1.18 1.178l-5 5a.833.833 0 0 1-1.18 0l-5-5a.833.833 0 0 1 0-1.178"clip-rule=evenodd>`);
|
|
2258
|
+
const IconChevronDown = (props = {}) => (() => {
|
|
2259
|
+
var _el$ = _tmpl$$5();
|
|
2260
|
+
spread(_el$, props, true, true);
|
|
2261
|
+
return _el$;
|
|
1707
2262
|
})();
|
|
1708
|
-
var
|
|
1709
|
-
const
|
|
2263
|
+
var _tmpl$$4 = /* @__PURE__ */ template(`<button>`), _tmpl$2$3 = /* @__PURE__ */ template(`<div class="h-[1px] absolute left-0 right-0 top-[-1px] bg-white pointer-events-none">`);
|
|
2264
|
+
const CameraSelector = () => {
|
|
2265
|
+
const {
|
|
2266
|
+
cameraManagerSolidStore,
|
|
2267
|
+
cameraManager
|
|
2268
|
+
} = useCameraUiStore();
|
|
1710
2269
|
const {
|
|
1711
|
-
cameraManagerSolidStore: r,
|
|
1712
|
-
cameraManager: e
|
|
1713
|
-
} = q(), {
|
|
1714
2270
|
t
|
|
1715
|
-
} =
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
2271
|
+
} = useLocalization();
|
|
2272
|
+
const cameras = cameraManagerSolidStore((x) => x.cameras);
|
|
2273
|
+
const selectedCamera = cameraManagerSolidStore((x) => x.selectedCamera);
|
|
2274
|
+
const isQueryingCameras = cameraManagerSolidStore((x) => x.isQueryingCameras);
|
|
2275
|
+
const facingFilter = cameraManagerSolidStore((x) => x.facingFilter);
|
|
2276
|
+
const [isSwapping, setIsSwapping] = createSignal(false);
|
|
2277
|
+
const isDisabled = () => isQueryingCameras() || isSwapping();
|
|
2278
|
+
const camerasWithFacingFilter = () => {
|
|
2279
|
+
const $facingFilter = facingFilter();
|
|
2280
|
+
if (!$facingFilter) {
|
|
2281
|
+
return cameras();
|
|
2282
|
+
}
|
|
2283
|
+
return cameras().filter((camera) => $facingFilter.includes(camera.facingMode));
|
|
2284
|
+
};
|
|
2285
|
+
const createCameraOptions = () => [...camerasWithFacingFilter().map((camera) => ({
|
|
2286
|
+
value: camera.deviceInfo.deviceId,
|
|
2287
|
+
label: camera.name
|
|
2288
|
+
}))];
|
|
2289
|
+
const cameraCollection = () => createListCollection({
|
|
2290
|
+
items: [...createCameraOptions()]
|
|
2291
|
+
});
|
|
2292
|
+
const selectedCameraInCollection = () => {
|
|
2293
|
+
const $selectedCamera = selectedCamera();
|
|
2294
|
+
if (!$selectedCamera) {
|
|
2295
|
+
return;
|
|
2296
|
+
}
|
|
2297
|
+
const foundCamera = cameraCollection().find($selectedCamera.deviceInfo.deviceId);
|
|
2298
|
+
if (!foundCamera) {
|
|
1726
2299
|
return;
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
2300
|
+
}
|
|
2301
|
+
return [foundCamera.value];
|
|
2302
|
+
};
|
|
2303
|
+
const isFakeCamera = (value) => {
|
|
2304
|
+
return fakeCameras.some((fakeCamera) => fakeCamera.value === value);
|
|
2305
|
+
};
|
|
2306
|
+
const selectCameraById = async (id) => {
|
|
2307
|
+
setIsSwapping(true);
|
|
2308
|
+
const camera = cameras().find((camera2) => camera2.deviceInfo.deviceId === id);
|
|
2309
|
+
if (!camera) {
|
|
1734
2310
|
console.warn("No camera");
|
|
1735
2311
|
return;
|
|
1736
2312
|
}
|
|
1737
|
-
await
|
|
2313
|
+
await cameraManager.selectCamera(camera);
|
|
2314
|
+
setIsSwapping(false);
|
|
1738
2315
|
};
|
|
1739
|
-
return
|
|
1740
|
-
children: () =>
|
|
2316
|
+
return createComponent(SmartEnvironmentProvider, {
|
|
2317
|
+
children: () => createComponent(Select.Root, {
|
|
2318
|
+
part: "camera-select-part",
|
|
1741
2319
|
get collection() {
|
|
1742
|
-
return
|
|
2320
|
+
return cameraCollection();
|
|
1743
2321
|
},
|
|
1744
2322
|
get value() {
|
|
1745
|
-
return
|
|
2323
|
+
return selectedCameraInCollection();
|
|
1746
2324
|
},
|
|
1747
2325
|
positioning: {
|
|
1748
2326
|
placement: "top"
|
|
1749
2327
|
},
|
|
1750
|
-
lazyMount:
|
|
2328
|
+
lazyMount: true,
|
|
1751
2329
|
get disabled() {
|
|
1752
|
-
return
|
|
2330
|
+
return isDisabled();
|
|
1753
2331
|
},
|
|
1754
|
-
onValueChange: (
|
|
1755
|
-
if (
|
|
2332
|
+
onValueChange: (details) => {
|
|
2333
|
+
if (isFakeCamera(details.value[0])) {
|
|
1756
2334
|
console.warn("Fake camera, skipping");
|
|
1757
2335
|
return;
|
|
1758
2336
|
}
|
|
1759
|
-
|
|
2337
|
+
void selectCameraById(details.value[0]);
|
|
1760
2338
|
},
|
|
1761
2339
|
get children() {
|
|
1762
|
-
return [
|
|
1763
|
-
class: "sr-only",
|
|
2340
|
+
return [createComponent(Select.Label, {
|
|
2341
|
+
"class": "sr-only",
|
|
1764
2342
|
get children() {
|
|
1765
2343
|
return t.selected_camera;
|
|
1766
2344
|
}
|
|
1767
|
-
}),
|
|
1768
|
-
asChild: (
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
2345
|
+
}), createComponent(Select.Trigger, {
|
|
2346
|
+
asChild: (selectProps) => {
|
|
2347
|
+
return (() => {
|
|
2348
|
+
var _el$ = _tmpl$$4();
|
|
2349
|
+
spread(_el$, mergeProps(() => eventFixer(selectProps()), {
|
|
2350
|
+
"class": `flex px-4 py-2 items-center gap-2 rounded-full bg-dark-100/50 backdrop-blur-xl
|
|
1772
2351
|
whitespace-nowrap text-base color-white font-500 cursor-pointer appearance-none
|
|
1773
2352
|
border-none disabled:opacity-50 disabled:cursor-not-allowed max-w-[100%]`
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
2353
|
+
}), false, true);
|
|
2354
|
+
insert(_el$, createComponent(IconCamera, {
|
|
2355
|
+
"class": "size-6 shrink-0",
|
|
2356
|
+
"aria-hidden": true
|
|
2357
|
+
}), null);
|
|
2358
|
+
insert(_el$, createComponent(Select.ValueText, {
|
|
2359
|
+
"class": "truncate",
|
|
2360
|
+
get placeholder() {
|
|
2361
|
+
return isQueryingCameras() ? t.loading_cameras : t.select_a_camera;
|
|
2362
|
+
}
|
|
2363
|
+
}), null);
|
|
2364
|
+
insert(_el$, createComponent(Select.Indicator, {
|
|
2365
|
+
"class": "shrink-0 data-[state=open]:scale-y-[-1]",
|
|
2366
|
+
get children() {
|
|
2367
|
+
return createComponent(IconChevronDown, {
|
|
2368
|
+
"class": "size-6 shrink-0"
|
|
2369
|
+
});
|
|
2370
|
+
}
|
|
2371
|
+
}), null);
|
|
2372
|
+
return _el$;
|
|
2373
|
+
})();
|
|
2374
|
+
}
|
|
2375
|
+
}), createComponent(Select.Positioner, {
|
|
1792
2376
|
get children() {
|
|
1793
|
-
return
|
|
2377
|
+
return createComponent(Select.Content, {
|
|
1794
2378
|
get children() {
|
|
1795
|
-
return
|
|
1796
|
-
class: "rounded-4 overflow-hidden text-base color-white",
|
|
2379
|
+
return createComponent(Select.ItemGroup, {
|
|
2380
|
+
"class": "rounded-4 overflow-hidden text-base color-white",
|
|
1797
2381
|
get children() {
|
|
1798
|
-
return
|
|
2382
|
+
return createComponent(Index, {
|
|
1799
2383
|
get each() {
|
|
1800
|
-
return
|
|
2384
|
+
return cameraCollection().items;
|
|
1801
2385
|
},
|
|
1802
|
-
children: (
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
bg-dark-100/50 backdrop-blur-xl data-[highlighted]:bg-gray-500/50
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
2386
|
+
children: (camera, index) => {
|
|
2387
|
+
return createComponent(Select.Item, {
|
|
2388
|
+
get item() {
|
|
2389
|
+
return camera();
|
|
2390
|
+
},
|
|
2391
|
+
"class": "flex py-3 pl-4 pr-12 cursor-pointer select-none relative gap-[1px]\n bg-dark-100/50 backdrop-blur-xl data-[highlighted]:bg-gray-500/50",
|
|
2392
|
+
get children() {
|
|
2393
|
+
return [createComponent(Select.ItemText, {
|
|
2394
|
+
"class": "truncate",
|
|
2395
|
+
get children() {
|
|
2396
|
+
return camera().label;
|
|
2397
|
+
}
|
|
2398
|
+
}), createComponent(Select.ItemIndicator, {
|
|
2399
|
+
"class": "absolute right-4",
|
|
2400
|
+
get children() {
|
|
2401
|
+
return createComponent(IconCheck, {
|
|
2402
|
+
"class": "size-6 shrink-0"
|
|
2403
|
+
});
|
|
2404
|
+
}
|
|
2405
|
+
}), createComponent(Show, {
|
|
2406
|
+
when: index !== 0,
|
|
2407
|
+
get children() {
|
|
2408
|
+
return _tmpl$2$3();
|
|
2409
|
+
}
|
|
2410
|
+
})];
|
|
2411
|
+
}
|
|
2412
|
+
});
|
|
2413
|
+
}
|
|
1829
2414
|
});
|
|
1830
2415
|
}
|
|
1831
2416
|
});
|
|
@@ -1836,7 +2421,8 @@ const Zt = () => {
|
|
|
1836
2421
|
}
|
|
1837
2422
|
})
|
|
1838
2423
|
});
|
|
1839
|
-
}
|
|
2424
|
+
};
|
|
2425
|
+
const fakeCameras = [{
|
|
1840
2426
|
value: "5",
|
|
1841
2427
|
label: "Back Camera 2"
|
|
1842
2428
|
}, {
|
|
@@ -1852,307 +2438,389 @@ const Zt = () => {
|
|
|
1852
2438
|
value: "4",
|
|
1853
2439
|
label: "Some random desktop camera"
|
|
1854
2440
|
}];
|
|
1855
|
-
var
|
|
1856
|
-
const
|
|
2441
|
+
var _tmpl$$3 = /* @__PURE__ */ template(`<span class=sr-only>`), _tmpl$2$2 = /* @__PURE__ */ template(`<div class=justify-self-end>`), _tmpl$3$2 = /* @__PURE__ */ template(`<div class="z-2 relative gap-2 grid justify-between items-center grid-cols-[1fr_auto_1fr] py-4 color-white lerp:px-3@xs,8@lg"><div class="justify-self-start flex flex-nowrap gap-4 auto-cols-auto"></div><div class="justify-self-center min-w-0 w-full">`), _tmpl$4$1 = /* @__PURE__ */ template(`<button>`);
|
|
2442
|
+
const Header = () => {
|
|
2443
|
+
const {
|
|
2444
|
+
dismountCameraUi,
|
|
2445
|
+
cameraManagerSolidStore,
|
|
2446
|
+
cameraManager,
|
|
2447
|
+
showMirrorCameraButton,
|
|
2448
|
+
showTorchButton,
|
|
2449
|
+
showCloseButton
|
|
2450
|
+
} = useCameraUiStore();
|
|
1857
2451
|
const {
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
2452
|
+
t
|
|
2453
|
+
} = useLocalization();
|
|
2454
|
+
const isMirrored = cameraManagerSolidStore((s) => s.mirrorX);
|
|
2455
|
+
const selectedCamera = cameraManagerSolidStore((s) => s.selectedCamera);
|
|
2456
|
+
const cameras = cameraManagerSolidStore((s) => s.cameras);
|
|
2457
|
+
const isActive = cameraManagerSolidStore((s) => s.playbackState !== "idle");
|
|
2458
|
+
const torchEnabled = cameraManagerSolidStore((s) => s.selectedCamera?.torchEnabled);
|
|
2459
|
+
const hasTorch = () => selectedCamera()?.torchSupported;
|
|
2460
|
+
const toggleTorch = () => {
|
|
2461
|
+
const camera = selectedCamera();
|
|
2462
|
+
if (!camera) {
|
|
2463
|
+
return;
|
|
2464
|
+
}
|
|
2465
|
+
void camera.toggleTorch();
|
|
1869
2466
|
};
|
|
1870
|
-
|
|
2467
|
+
const toggleMirrorX = () => {
|
|
2468
|
+
cameraManager.setCameraMirrorX(!cameraManagerSolidStore.getState().mirrorX);
|
|
2469
|
+
};
|
|
2470
|
+
return createComponent(SmartEnvironmentProvider, {
|
|
1871
2471
|
children: () => (() => {
|
|
1872
|
-
var
|
|
1873
|
-
|
|
2472
|
+
var _el$ = _tmpl$3$2(), _el$2 = _el$.firstChild, _el$5 = _el$2.nextSibling;
|
|
2473
|
+
insert(_el$2, createComponent(Show, {
|
|
1874
2474
|
get when() {
|
|
1875
|
-
return
|
|
2475
|
+
return showMirrorCameraButton && isActive();
|
|
1876
2476
|
},
|
|
1877
2477
|
get children() {
|
|
1878
|
-
return
|
|
2478
|
+
return createComponent(ToolbarButton, {
|
|
2479
|
+
part: "mirror-camera-button-part",
|
|
1879
2480
|
get tooltipLabel() {
|
|
1880
|
-
return
|
|
2481
|
+
return t.mirror_camera;
|
|
1881
2482
|
},
|
|
1882
|
-
onClick: () =>
|
|
2483
|
+
onClick: () => toggleMirrorX(),
|
|
1883
2484
|
get children() {
|
|
1884
2485
|
return [(() => {
|
|
1885
|
-
var
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
2486
|
+
var _el$3 = _tmpl$$3();
|
|
2487
|
+
insert(_el$3, () => t.mirror_camera);
|
|
2488
|
+
return _el$3;
|
|
2489
|
+
})(), createComponent(MirrorIcon, {
|
|
2490
|
+
"class": "size-6 shrink-0 transition-transform duration-300 ease-in-out",
|
|
1889
2491
|
get style() {
|
|
1890
2492
|
return {
|
|
1891
|
-
transform:
|
|
2493
|
+
transform: isMirrored() ? "scaleX(-1)" : "scaleX(1)"
|
|
1892
2494
|
};
|
|
1893
2495
|
}
|
|
1894
2496
|
})];
|
|
1895
2497
|
}
|
|
1896
2498
|
});
|
|
1897
2499
|
}
|
|
1898
|
-
}), null)
|
|
2500
|
+
}), null);
|
|
2501
|
+
insert(_el$2, createComponent(Show, {
|
|
1899
2502
|
get when() {
|
|
1900
|
-
return
|
|
2503
|
+
return memo(() => !!(showTorchButton && hasTorch()))() && isActive();
|
|
1901
2504
|
},
|
|
1902
2505
|
get children() {
|
|
1903
|
-
return
|
|
1904
|
-
|
|
2506
|
+
return createComponent(ToolbarButton, {
|
|
2507
|
+
part: "torch-button-part",
|
|
2508
|
+
onClick: () => toggleTorch(),
|
|
1905
2509
|
get tooltipLabel() {
|
|
1906
|
-
return
|
|
2510
|
+
return t.torch;
|
|
1907
2511
|
},
|
|
1908
2512
|
get children() {
|
|
1909
|
-
return [
|
|
2513
|
+
return [createComponent(Show, {
|
|
1910
2514
|
get when() {
|
|
1911
|
-
return !
|
|
2515
|
+
return !torchEnabled();
|
|
1912
2516
|
},
|
|
1913
2517
|
get children() {
|
|
1914
2518
|
return [(() => {
|
|
1915
|
-
var
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
2519
|
+
var _el$4 = _tmpl$$3();
|
|
2520
|
+
insert(_el$4, () => t.torch);
|
|
2521
|
+
return _el$4;
|
|
2522
|
+
})(), createComponent(FlashOn, {
|
|
2523
|
+
"class": "size-6 shrink-0"
|
|
1919
2524
|
})];
|
|
1920
2525
|
}
|
|
1921
|
-
}),
|
|
2526
|
+
}), createComponent(Show, {
|
|
1922
2527
|
get when() {
|
|
1923
|
-
return
|
|
2528
|
+
return torchEnabled();
|
|
1924
2529
|
},
|
|
1925
2530
|
get children() {
|
|
1926
|
-
return
|
|
1927
|
-
class: "size-6 shrink-0"
|
|
2531
|
+
return createComponent(FlashOff, {
|
|
2532
|
+
"class": "size-6 shrink-0"
|
|
1928
2533
|
});
|
|
1929
2534
|
}
|
|
1930
2535
|
})];
|
|
1931
2536
|
}
|
|
1932
2537
|
});
|
|
1933
2538
|
}
|
|
1934
|
-
}), null)
|
|
2539
|
+
}), null);
|
|
2540
|
+
insert(_el$5, createComponent(Show, {
|
|
1935
2541
|
get when() {
|
|
1936
|
-
return
|
|
2542
|
+
return cameras().length > 1;
|
|
1937
2543
|
},
|
|
1938
2544
|
get children() {
|
|
1939
|
-
return
|
|
2545
|
+
return createComponent(CameraSelector, {});
|
|
1940
2546
|
}
|
|
1941
|
-
}))
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
return n.close;
|
|
1945
|
-
},
|
|
2547
|
+
}));
|
|
2548
|
+
insert(_el$, createComponent(Show, {
|
|
2549
|
+
when: showCloseButton,
|
|
1946
2550
|
get children() {
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
2551
|
+
var _el$6 = _tmpl$2$2();
|
|
2552
|
+
insert(_el$6, createComponent(ToolbarButton, {
|
|
2553
|
+
part: "close-button-part",
|
|
2554
|
+
onClick: () => dismountCameraUi(),
|
|
2555
|
+
get tooltipLabel() {
|
|
2556
|
+
return t.close;
|
|
2557
|
+
},
|
|
2558
|
+
get children() {
|
|
2559
|
+
return [(() => {
|
|
2560
|
+
var _el$7 = _tmpl$$3();
|
|
2561
|
+
insert(_el$7, () => t.close);
|
|
2562
|
+
return _el$7;
|
|
2563
|
+
})(), createComponent(CloseIcon, {
|
|
2564
|
+
"class": "size-6 shrink-0"
|
|
2565
|
+
})];
|
|
2566
|
+
}
|
|
2567
|
+
}));
|
|
2568
|
+
return _el$6;
|
|
1953
2569
|
}
|
|
1954
|
-
})
|
|
2570
|
+
}), null);
|
|
2571
|
+
return _el$;
|
|
1955
2572
|
})()
|
|
1956
2573
|
});
|
|
1957
|
-
}
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
2574
|
+
};
|
|
2575
|
+
const ToolbarButton = (props) => {
|
|
2576
|
+
return createComponent(Tooltip.Root, {
|
|
2577
|
+
get children() {
|
|
2578
|
+
return [createComponent(Tooltip.Trigger, mergeProps(props, {
|
|
2579
|
+
asChild: (tooltipProps) => {
|
|
2580
|
+
return (() => {
|
|
2581
|
+
var _el$8 = _tmpl$4$1();
|
|
2582
|
+
spread(_el$8, mergeProps(() => eventFixer(tooltipProps()), {
|
|
2583
|
+
"class": `rounded-full bg-dark-500 bg-opacity-50 backdrop-blur grid place-items-center
|
|
1964
2584
|
size-12 appearance-none border-none cursor-pointer`
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
2585
|
+
}), false, true);
|
|
2586
|
+
insert(_el$8, () => props.children);
|
|
2587
|
+
return _el$8;
|
|
2588
|
+
})();
|
|
2589
|
+
}
|
|
2590
|
+
})), createComponent(Tooltip.Positioner, {
|
|
2591
|
+
get children() {
|
|
2592
|
+
return createComponent(Tooltip.Content, {
|
|
2593
|
+
"class": `bg-dark-500 bg-opacity-50 backdrop-blur color-white text-align-center p-2
|
|
1971
2594
|
rounded-md text-sm drop-shadow-md`,
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
})
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
2595
|
+
get children() {
|
|
2596
|
+
return props.tooltipLabel;
|
|
2597
|
+
}
|
|
2598
|
+
});
|
|
2599
|
+
}
|
|
2600
|
+
})];
|
|
2601
|
+
}
|
|
2602
|
+
});
|
|
2603
|
+
};
|
|
2604
|
+
const renderWithOwner = (code, element, owner) => {
|
|
2605
|
+
return createRoot((dispose) => {
|
|
2606
|
+
insert(element, code(), element.firstChild ? null : void 0);
|
|
2607
|
+
return () => {
|
|
2608
|
+
dispose();
|
|
2609
|
+
element.textContent = "";
|
|
2610
|
+
};
|
|
2611
|
+
}, owner);
|
|
2612
|
+
};
|
|
2613
|
+
var _tmpl$$2 = /* @__PURE__ */ template(`<div>`);
|
|
2614
|
+
const SolidShadowRoot = (props) => {
|
|
2615
|
+
const owner = getOwner();
|
|
2616
|
+
const [local, others] = splitProps(props, ["children", "disableShadowRoot", "getRef"]);
|
|
1985
2617
|
return (() => {
|
|
1986
|
-
var
|
|
1987
|
-
|
|
1988
|
-
if (
|
|
2618
|
+
var _el$ = _tmpl$$2();
|
|
2619
|
+
use((ref) => {
|
|
2620
|
+
if (local.disableShadowRoot) {
|
|
1989
2621
|
return;
|
|
1990
|
-
|
|
2622
|
+
}
|
|
2623
|
+
const shadowRoot = ref.attachShadow({
|
|
1991
2624
|
mode: "open"
|
|
1992
2625
|
});
|
|
1993
|
-
|
|
1994
|
-
},
|
|
2626
|
+
renderWithOwner(() => memo(() => local.children), shadowRoot, owner);
|
|
2627
|
+
}, _el$);
|
|
2628
|
+
spread(_el$, others, false, true);
|
|
2629
|
+
insert(_el$, createComponent(Show, {
|
|
1995
2630
|
get when() {
|
|
1996
|
-
return
|
|
2631
|
+
return local.disableShadowRoot;
|
|
1997
2632
|
},
|
|
1998
2633
|
get children() {
|
|
1999
|
-
return
|
|
2634
|
+
return local.children;
|
|
2000
2635
|
}
|
|
2001
|
-
}))
|
|
2636
|
+
}));
|
|
2637
|
+
return _el$;
|
|
2002
2638
|
})();
|
|
2003
|
-
}
|
|
2639
|
+
};
|
|
2640
|
+
const normalize = '/* Document\n * ========================================================================== */\n\n/**\n * 1. Correct the line height in all browsers.\n * 2. Prevent adjustments of font size after orientation changes in iOS.\n */\n\n:where(html) {\n line-height: 1.15; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n text-size-adjust: 100%; /* 2 */\n}\n\n/* Sections\n * ========================================================================== */\n\n/**\n * Correct the font size and margin on `h1` elements within `section` and\n * `article` contexts in Chrome, Edge, Firefox, and Safari.\n */\n\n:where(h1) {\n font-size: 2em;\n margin-block-end: 0.67em;\n margin-block-start: 0.67em;\n}\n\n/* Grouping content\n * ========================================================================== */\n\n/**\n * Remove the margin on nested lists in Chrome, Edge, and Safari.\n */\n\n:where(dl, ol, ul) :where(dl, ol, ul) {\n margin-block-end: 0;\n margin-block-start: 0;\n}\n\n/**\n * 1. Add the correct box sizing in Firefox.\n * 2. Correct the inheritance of border color in Firefox.\n */\n\n:where(hr) {\n box-sizing: content-box; /* 1 */\n color: inherit; /* 2 */\n height: 0; /* 1 */\n}\n\n/* Text-level semantics\n * ========================================================================== */\n\n/**\n * Add the correct text decoration in Safari.\n */\n\n:where(abbr[title]) {\n text-decoration: underline;\n text-decoration: underline dotted;\n}\n\n/**\n * Add the correct font weight in Chrome, Edge, and Safari.\n */\n\n:where(b, strong) {\n font-weight: bolder;\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\n:where(code, kbd, pre, samp) {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/**\n * Add the correct font size in all browsers.\n */\n\n:where(small) {\n font-size: 80%;\n}\n\n/* Tabular data\n * ========================================================================== */\n\n/**\n * 1. Correct table border color in Chrome, Edge, and Safari.\n * 2. Remove text indentation from table contents in Chrome, Edge, and Safari.\n */\n\n:where(table) {\n border-color: currentColor; /* 1 */\n text-indent: 0; /* 2 */\n}\n\n/* Forms\n * ========================================================================== */\n\n/**\n * Remove the margin on controls in Safari.\n */\n\n:where(button, input, select) {\n margin: 0;\n}\n\n/**\n * Remove the inheritance of text transform in Firefox.\n */\n\n:where(button) {\n text-transform: none;\n}\n\n/**\n * Correct the inability to style buttons in iOS and Safari.\n */\n\n:where(button, input:is([type="button" i], [type="reset" i], [type="submit" i])) {\n -webkit-appearance: button;\n}\n\n/**\n * Add the correct vertical alignment in Chrome, Edge, and Firefox.\n */\n\n:where(progress) {\n vertical-align: baseline;\n}\n\n/**\n * Remove the inheritance of text transform in Firefox.\n */\n\n:where(select) {\n text-transform: none;\n}\n\n/**\n * Remove the margin in Firefox and Safari.\n */\n\n:where(textarea) {\n margin: 0;\n}\n\n/**\n * 1. Correct the odd appearance in Chrome, Edge, and Safari.\n * 2. Correct the outline style in Safari.\n */\n\n:where(input[type="search" i]) {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/**\n * Correct the cursor style of increment and decrement buttons in Safari.\n */\n\n::-webkit-inner-spin-button,\n::-webkit-outer-spin-button {\n height: auto;\n}\n\n/**\n * Correct the text style of placeholders in Chrome, Edge, and Safari.\n */\n\n::-webkit-input-placeholder {\n color: inherit;\n opacity: 0.54;\n}\n\n/**\n * Remove the inner padding in Chrome, Edge, and Safari on macOS.\n */\n\n::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/**\n * 1. Correct the inability to style upload buttons in iOS and Safari.\n * 2. Change font properties to `inherit` in Safari.\n */\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/**\n * Remove the inner border and padding of focus outlines in Firefox.\n */\n\n:where(button, input:is([type="button" i], [type="color" i], [type="reset" i], [type="submit" i]))::-moz-focus-inner {\n border-style: none;\n padding: 0;\n}\n\n/**\n * Restore the focus outline styles unset by the previous rule in Firefox.\n */\n\n:where(button, input:is([type="button" i], [type="color" i], [type="reset" i], [type="submit" i]))::-moz-focusring {\n outline: 1px dotted ButtonText;\n}\n\n/**\n * Remove the additional :invalid styles in Firefox.\n */\n\n:where(:-moz-ui-invalid) {\n box-shadow: none;\n}\n\n/* Interactive\n * ========================================================================== */\n\n/*\n * Add the correct styles in Safari.\n */\n\n:where(dialog) {\n background-color: white;\n border: solid;\n color: black;\n height: -moz-fit-content;\n height: fit-content;\n left: 0;\n margin: auto;\n padding: 1em;\n position: absolute;\n right: 0;\n width: -moz-fit-content;\n width: fit-content;\n}\n\n:where(dialog:not([open])) {\n display: none;\n}\n\n/*\n * Add the correct display in all browsers.\n */\n\n:where(summary) {\n display: list-item;\n}\n';
|
|
2641
|
+
const rootStyles = ":host {\n font-family: var(--mb-ui-font);\n line-height: 1.15;\n isolation: isolate;\n box-sizing: border-box;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n}\n\np,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n overflow-wrap: break-word;\n}\n\ncode {\n font-family: var(--mb-monospace-font-stack);\n}\n\npre {\n font-family: var(--mb-monospace-font-stack);\n}\n\nsvg path {\n pointer-events: none;\n}\n\nimg,\npicture,\nvideo,\ncanvas,\nsvg {\n display: block;\n max-width: 100%;\n}\n\nimg {\n pointer-events: none;\n user-select: none;\n}\n\n:where(input, button, textarea, select) {\n font: inherit;\n}\n\n:where(button, select) {\n cursor: pointer;\n color: inherit;\n font: inherit;\n}\n\n:where(p, h1, h2, h3, h4, h5, h6) {\n overflow-wrap: break-word;\n}";
|
|
2642
|
+
const variables = ':host {\n --mb-system-font-stack:\n -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu",\n "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;\n --mb-monospace-font-stack:\n Menlo, Consolas, "Ubuntu Mono", "Roboto Mono", "DejaVu Sans Mono", monospace;\n --mb-ui-font: var(--mb-system-font-stack);\n --mb-size: 1;\n /***************************************/\n /* MB COLORS */\n /***************************************/\n --color-accent-25-rgb-value: 242 247 255; /* #F2F7FF */\n --color-accent-50-rgb-value: 231 240 255; /* #E7F0FF */\n --color-accent-100-rgb-value: 220 234 255; /* #DCEAFF */\n --color-accent-200-rgb-value: 198 221 255; /* #C6DDFF */\n --color-accent-300-rgb-value: 158 197 255; /* #9EC5FF */\n --color-accent-400-rgb-value: 111 169 255; /* #6FA9FF */\n --color-accent-500-rgb-value: 58 137 253; /* #3A89FD */\n --color-accent-600-rgb-value: 0 98 242; /* #0062F2 */\n --color-accent-700-rgb-value: 0 80 197; /* #0050C5 */\n --color-accent-800-rgb-value: 0 64 157; /* #00409D */\n --color-accent-900-rgb-value: 0 54 133; /* #003685 */\n --color-error-25-rgb-value: 255 248 249; /* #FFF8F9 */\n --color-error-50-rgb-value: 255 241 242; /* #FFF1F2 */\n --color-error-100-rgb-value: 255 228 230; /* #FFE4E6 */\n --color-error-200-rgb-value: 254 205 211; /* #FECDD3 */\n --color-error-300-rgb-value: 253 164 175; /* #FDA4AF */\n --color-error-400-rgb-value: 251 113 133; /* #FB7185 */\n --color-error-500-rgb-value: 244 63 94; /* #F43F5E */\n --color-error-600-rgb-value: 225 29 72; /* #E11D48 */\n --color-error-700-rgb-value: 190 18 60; /* #BE123C */\n --color-error-800-rgb-value: 136 19 39; /* #881337 */\n --color-error-900-rgb-value: 89 13 40; /* #590D28 */\n --color-success-25-rgb-value: 245 254 250; /* #F5FEFA */\n --color-success-50-rgb-value: 236 253 245; /* #ECFDF5 */\n --color-success-100-rgb-value: 209 250 229; /* #D1FAE5 */\n --color-success-200-rgb-value: 167 243 208; /* #A7F3D0 */\n --color-success-300-rgb-value: 110 231 183; /* #6EE7B7 */\n --color-success-400-rgb-value: 52 211 153; /* #34D399 */\n --color-success-500-rgb-value: 16 185 144; /* #10B990 */\n --color-success-600-rgb-value: 22 163 138; /* #16A38A */\n --color-success-700-rgb-value: 39 121 106; /* #27796A */\n --color-success-800-rgb-value: 23 92 79; /* #175C4F */\n --color-success-900-rgb-value: 12 59 50; /* #0C3B32 */\n --color-warning-25-rgb-value: 255 253 243; /* #FFFDF3 */\n --color-warning-50-rgb-value: 254 252 232; /* #FEFCE8 */\n --color-warning-100-rgb-value: 254 249 195; /* #FEF9C3 */\n --color-warning-200-rgb-value: 254 240 138; /* #FEF08A */\n --color-warning-300-rgb-value: 253 229 99; /* #FDE563 */\n --color-warning-400-rgb-value: 252 218 59; /* #FCDA3B */\n --color-warning-500-rgb-value: 250 204 21; /* #FACC15 */\n --color-warning-600-rgb-value: 234 179 8; /* #EAB308 */\n --color-warning-700-rgb-value: 190 142 48; /* #BE8E30 */\n --color-warning-800-rgb-value: 132 83 28; /* #84531C */\n --color-warning-900-rgb-value: 80 29 10; /* #501D0A */\n --color-deep-blue-25-rgb-value: 249 252 255; /* #F9FCFF */\n --color-deep-blue-50-rgb-value: 243 249 254; /* #F3F9FE */\n --color-deep-blue-100-rgb-value: 231 242 251; /* #E7F2FB */\n --color-deep-blue-200-rgb-value: 201 218 241; /* #C9DAF1 */\n --color-deep-blue-300-rgb-value: 162 185 216; /* #A2B9D8 */\n --color-deep-blue-400-rgb-value: 93 128 182; /* #5D80B6 */\n --color-deep-blue-500-rgb-value: 60 100 161; /* #3C64A1 */\n --color-deep-blue-600-rgb-value: 28 68 129; /* #1C4481 */\n --color-deep-blue-700-rgb-value: 24 53 97; /* #183561 */\n --color-deep-blue-800-rgb-value: 20 38 65; /* #142641 */\n --color-deep-blue-900-rgb-value: 6 23 49; /* #061731 */\n --color-light-blue-25-rgb-value: 248 251 253; /* #F8FBFD */\n --color-light-blue-50-rgb-value: 240 247 251; /* #F0F7FB */\n --color-light-blue-100-rgb-value: 228 238 244; /* #E4EEF4 */\n --color-light-blue-200-rgb-value: 215 229 238; /* #D7E5EE */\n --color-light-blue-300-rgb-value: 190 218 237; /* #BEDAED */\n --color-light-blue-400-rgb-value: 159 202 232; /* #9FCAE8 */\n --color-light-blue-500-rgb-value: 135 180 211; /* #87B4D3 */\n --color-light-blue-600-rgb-value: 104 157 193; /* #689DC1 */\n --color-light-blue-700-rgb-value: 78 129 164; /* #4E81A4 */\n --color-light-blue-800-rgb-value: 67 109 138; /* #436D8A */\n --color-light-blue-900-rgb-value: 55 84 104; /* #375468 */\n --color-gray-50-rgb-value: 249 250 251; /* #FAFAFA */\n --color-gray-100-rgb-value: 243 244 246; /* #F5F5F5 */\n --color-gray-200-rgb-value: 229 231 235; /* #F0F0F0 */\n --color-gray-300-rgb-value: 209 213 219; /* #D9D9D9 */\n --color-gray-400-rgb-value: 156 163 175; /* #BFBFBF */\n --color-gray-500-rgb-value: 107 114 128; /* #8C8C8C */\n --color-gray-600-rgb-value: 75 85 99; /* #595959 */\n --color-gray-700-rgb-value: 55 65 81; /* #434343 */\n --color-gray-800-rgb-value: 31 41 55; /* #262626 */\n --color-blue-gray-50-rgb-value: 74 74 74; /* #F9FAFB */\n --color-blue-gray-100-rgb-value: 60 60 60; /* #F3F4F6 */\n --color-blue-gray-200-rgb-value: 50 50 50; /* #E5E7EB */\n --color-blue-gray-300-rgb-value: 45 45 45; /* #D1D5DB */\n --color-blue-gray-400-rgb-value: 34 34 34; /* #9CA3AF */\n --color-blue-gray-500-rgb-value: 31 31 31; /* #6B7280 */\n --color-blue-gray-600-rgb-value: 28 28 30; /* #4B5563 */\n --color-blue-gray-700-rgb-value: 27 27 27; /* #374151 */\n --color-blue-gray-800-rgb-value: 24 24 24; /* #1F2937 */\n --color-blue-gray-900-rgb-value: 15 15 15; /* #111827 */\n --color-black-rgb-value: 0 0 0; /* #000000 */\n --color-white-rgb-value: 255 255 255; /* #FFFFFF */\n --color-primary: var(--color-accent-600-rgb-value);\n --color-error: var(--color-error-500-rgb-value);\n --color-success: var(--color-success-500-rgb-value);\n --color-warning: var(--color-warning-500-rgb-value);\n --color-deep-blue: var(--color-deep-blue-800-rgb-value);\n --color-light-blue: var(--color-light-blue-200-rgb-value);\n accent-color: var(--color-primary);\n caret-color: red;\n}';
|
|
2643
|
+
const initialState = {
|
|
2004
2644
|
feedbackLayer: null,
|
|
2005
2645
|
overlayLayer: null,
|
|
2006
2646
|
owner: null
|
|
2007
|
-
}, U = me()(
|
|
2008
|
-
// this is important! Otherwise, solid-zustand will start mutating the initial state
|
|
2009
|
-
he(() => structuredClone(ur))
|
|
2010
|
-
), oe = we(U), de = () => {
|
|
2011
2647
|
};
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2648
|
+
const cameraUiRefStore = createStore()(
|
|
2649
|
+
// this is important! Otherwise, solid-zustand will start mutating the initial state
|
|
2650
|
+
subscribeWithSelector(() => structuredClone(initialState))
|
|
2651
|
+
);
|
|
2652
|
+
const cameraUiRefSignalStore = createWithSignal(cameraUiRefStore);
|
|
2653
|
+
const noop = () => void 0;
|
|
2654
|
+
function makeResizeObserver(callback, options) {
|
|
2655
|
+
if (isServer) {
|
|
2656
|
+
return { observe: noop, unobserve: noop };
|
|
2657
|
+
}
|
|
2658
|
+
const observer = new ResizeObserver(callback);
|
|
2659
|
+
onCleanup(observer.disconnect.bind(observer));
|
|
2660
|
+
return {
|
|
2661
|
+
observe: (ref) => observer.observe(ref, options),
|
|
2662
|
+
unobserve: observer.unobserve.bind(observer)
|
|
2019
2663
|
};
|
|
2020
2664
|
}
|
|
2021
|
-
const
|
|
2022
|
-
const
|
|
2023
|
-
let
|
|
2024
|
-
if (
|
|
2025
|
-
const
|
|
2026
|
-
|
|
2665
|
+
const determineFitMode = (Cw, Ch, Vw, Vh) => {
|
|
2666
|
+
const scaleCover = Math.max(Cw / Vw, Ch / Vh);
|
|
2667
|
+
let croppedFraction = 0;
|
|
2668
|
+
if (Cw / Vw > Ch / Vh) {
|
|
2669
|
+
const visible = scaleCover * Vh;
|
|
2670
|
+
croppedFraction = 1 - Ch / visible;
|
|
2671
|
+
} else {
|
|
2672
|
+
const visible = scaleCover * Vw;
|
|
2673
|
+
croppedFraction = 1 - Cw / visible;
|
|
2674
|
+
}
|
|
2675
|
+
if (croppedFraction < 0.1) {
|
|
2676
|
+
return "cover";
|
|
2027
2677
|
} else {
|
|
2028
|
-
|
|
2029
|
-
o = 1 - r / i;
|
|
2678
|
+
return "contain";
|
|
2030
2679
|
}
|
|
2031
|
-
return o < 0.1 ? "cover" : "contain";
|
|
2032
2680
|
};
|
|
2033
|
-
function
|
|
2034
|
-
const
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2681
|
+
function getVisibleVideoArea(containerWidth, containerHeight, videoWidth, videoHeight) {
|
|
2682
|
+
const scaleX = containerWidth / videoWidth;
|
|
2683
|
+
const scaleY = containerHeight / videoHeight;
|
|
2684
|
+
const s = Math.max(scaleX, scaleY);
|
|
2685
|
+
if (scaleX >= scaleY) {
|
|
2686
|
+
const visibleNaturalHeight = Math.round(containerHeight / s);
|
|
2687
|
+
const y = Math.round((videoHeight - visibleNaturalHeight) / 2);
|
|
2688
|
+
return { x: 0, y, width: videoWidth, height: visibleNaturalHeight };
|
|
2038
2689
|
} else {
|
|
2039
|
-
const
|
|
2040
|
-
|
|
2690
|
+
const visibleNaturalWidth = Math.round(containerWidth / s);
|
|
2691
|
+
const x = Math.round((videoWidth - visibleNaturalWidth) / 2);
|
|
2692
|
+
return { x, y: 0, width: visibleNaturalWidth, height: videoHeight };
|
|
2041
2693
|
}
|
|
2042
2694
|
}
|
|
2043
|
-
const
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2695
|
+
const dialogPositioner = "_dialogPositioner_worsp_1";
|
|
2696
|
+
const dialogBackdrop = "_dialogBackdrop_worsp_5";
|
|
2697
|
+
const dialogContent = "_dialogContent_worsp_9";
|
|
2698
|
+
const large = "_large_worsp_13";
|
|
2699
|
+
const compact = "_compact_worsp_16";
|
|
2700
|
+
const dialogTitle = "_dialogTitle_worsp_30";
|
|
2701
|
+
const contentOut = "_contentOut_worsp_34";
|
|
2702
|
+
const closeButton = "_closeButton_worsp_38";
|
|
2703
|
+
const closeButtonInner = "_closeButtonInner_worsp_44";
|
|
2704
|
+
const primaryActionButton = "_primaryActionButton_worsp_49";
|
|
2705
|
+
const secondaryActionButton = "_secondaryActionButton_worsp_53";
|
|
2706
|
+
const actions = "_actions_worsp_57";
|
|
2707
|
+
const alertTitle = "_alertTitle_worsp_64";
|
|
2708
|
+
const alertText = "_alertText_worsp_68";
|
|
2709
|
+
const styles = {
|
|
2710
|
+
dialogPositioner,
|
|
2711
|
+
dialogBackdrop,
|
|
2712
|
+
dialogContent,
|
|
2713
|
+
large,
|
|
2714
|
+
compact,
|
|
2715
|
+
dialogTitle,
|
|
2716
|
+
contentOut,
|
|
2717
|
+
closeButton,
|
|
2718
|
+
closeButtonInner,
|
|
2719
|
+
primaryActionButton,
|
|
2720
|
+
secondaryActionButton,
|
|
2721
|
+
actions,
|
|
2722
|
+
alertTitle,
|
|
2723
|
+
alertText
|
|
2058
2724
|
};
|
|
2059
|
-
var
|
|
2060
|
-
const
|
|
2061
|
-
const
|
|
2062
|
-
switch (
|
|
2725
|
+
var _tmpl$$1 = /* @__PURE__ */ template(`<span>×`), _tmpl$2$1 = /* @__PURE__ */ template(`<div>`), _tmpl$3$1 = /* @__PURE__ */ template(`<p>`), _tmpl$4 = /* @__PURE__ */ template(`<span>`), _tmpl$5 = /* @__PURE__ */ template(`<div><button></button><button>`);
|
|
2726
|
+
const Modal = (props) => {
|
|
2727
|
+
const getPaddingClass = () => {
|
|
2728
|
+
switch (props.modalStyle) {
|
|
2063
2729
|
case "compact":
|
|
2064
|
-
return
|
|
2730
|
+
return styles.compact;
|
|
2065
2731
|
case "large":
|
|
2066
|
-
return
|
|
2732
|
+
return styles.compact;
|
|
2067
2733
|
case "default":
|
|
2068
2734
|
default:
|
|
2069
|
-
return;
|
|
2735
|
+
return void 0;
|
|
2070
2736
|
}
|
|
2071
2737
|
};
|
|
2072
|
-
return
|
|
2073
|
-
children: () =>
|
|
2074
|
-
onFocusOutside: (
|
|
2075
|
-
onInteractOutside: (
|
|
2076
|
-
restoreFocus:
|
|
2077
|
-
unmountOnExit:
|
|
2078
|
-
lazyMount:
|
|
2079
|
-
},
|
|
2738
|
+
return createComponent(SmartEnvironmentProvider, {
|
|
2739
|
+
children: () => createComponent(Dialog.Root, mergeProps({
|
|
2740
|
+
onFocusOutside: (e) => e.preventDefault(),
|
|
2741
|
+
onInteractOutside: (e) => e.preventDefault(),
|
|
2742
|
+
restoreFocus: true,
|
|
2743
|
+
unmountOnExit: true,
|
|
2744
|
+
lazyMount: true
|
|
2745
|
+
}, props, {
|
|
2080
2746
|
get children() {
|
|
2081
|
-
return
|
|
2747
|
+
return createComponent(Show, {
|
|
2082
2748
|
get when() {
|
|
2083
|
-
return
|
|
2749
|
+
return props.open;
|
|
2084
2750
|
},
|
|
2085
2751
|
get children() {
|
|
2086
|
-
return
|
|
2752
|
+
return createComponent(Portal, {
|
|
2087
2753
|
get mount() {
|
|
2088
|
-
return
|
|
2754
|
+
return props.mountTarget;
|
|
2089
2755
|
},
|
|
2090
2756
|
get children() {
|
|
2091
|
-
return
|
|
2092
|
-
get class() {
|
|
2093
|
-
return
|
|
2757
|
+
return createComponent(Dialog.Positioner, {
|
|
2758
|
+
get ["class"]() {
|
|
2759
|
+
return styles.dialogPositioner;
|
|
2094
2760
|
},
|
|
2095
2761
|
get children() {
|
|
2096
|
-
return [
|
|
2097
|
-
get class() {
|
|
2098
|
-
return
|
|
2762
|
+
return [createComponent(Dialog.Backdrop, {
|
|
2763
|
+
get ["class"]() {
|
|
2764
|
+
return styles.dialogBackdrop;
|
|
2099
2765
|
}
|
|
2100
|
-
}),
|
|
2101
|
-
get class() {
|
|
2102
|
-
return `${
|
|
2766
|
+
}), createComponent(Dialog.Content, {
|
|
2767
|
+
get ["class"]() {
|
|
2768
|
+
return `${styles.dialogContent} ${getPaddingClass()}`;
|
|
2103
2769
|
},
|
|
2104
2770
|
get children() {
|
|
2105
|
-
return [
|
|
2771
|
+
return [createComponent(Show, {
|
|
2106
2772
|
get when() {
|
|
2107
|
-
return
|
|
2773
|
+
return props.showCloseButton;
|
|
2108
2774
|
},
|
|
2109
2775
|
get children() {
|
|
2110
|
-
return
|
|
2111
|
-
get class() {
|
|
2112
|
-
return
|
|
2776
|
+
return createComponent(Dialog.CloseTrigger, {
|
|
2777
|
+
get ["class"]() {
|
|
2778
|
+
return styles.closeButton;
|
|
2113
2779
|
},
|
|
2114
2780
|
get onClick() {
|
|
2115
|
-
return
|
|
2781
|
+
return props.onCloseClicked;
|
|
2116
2782
|
},
|
|
2117
2783
|
get children() {
|
|
2118
|
-
var
|
|
2119
|
-
|
|
2784
|
+
var _el$ = _tmpl$$1();
|
|
2785
|
+
effect(() => className(_el$, styles.closeButtonInner));
|
|
2786
|
+
return _el$;
|
|
2120
2787
|
}
|
|
2121
2788
|
});
|
|
2122
2789
|
}
|
|
2123
|
-
}),
|
|
2790
|
+
}), createComponent(Show, {
|
|
2124
2791
|
get when() {
|
|
2125
|
-
return
|
|
2792
|
+
return props.headerImage;
|
|
2126
2793
|
},
|
|
2127
2794
|
get children() {
|
|
2128
|
-
return
|
|
2795
|
+
return props.headerImage;
|
|
2129
2796
|
}
|
|
2130
|
-
}),
|
|
2797
|
+
}), createComponent(Show, {
|
|
2131
2798
|
get when() {
|
|
2132
|
-
return
|
|
2799
|
+
return props.header;
|
|
2133
2800
|
},
|
|
2134
|
-
children: (
|
|
2135
|
-
get class() {
|
|
2136
|
-
return
|
|
2801
|
+
children: (header) => createComponent(Dialog.Title, {
|
|
2802
|
+
get ["class"]() {
|
|
2803
|
+
return styles.dialogTitle;
|
|
2137
2804
|
},
|
|
2138
2805
|
get children() {
|
|
2139
|
-
return
|
|
2806
|
+
return header();
|
|
2140
2807
|
}
|
|
2141
2808
|
})
|
|
2142
|
-
}),
|
|
2143
|
-
get class() {
|
|
2144
|
-
return
|
|
2809
|
+
}), createComponent(Dialog.Description, {
|
|
2810
|
+
get ["class"]() {
|
|
2811
|
+
return styles.contentOut;
|
|
2145
2812
|
},
|
|
2146
2813
|
get children() {
|
|
2147
|
-
return
|
|
2814
|
+
return props.children;
|
|
2148
2815
|
}
|
|
2149
|
-
}),
|
|
2816
|
+
}), createComponent(Show, {
|
|
2150
2817
|
get when() {
|
|
2151
|
-
return
|
|
2818
|
+
return props.actions;
|
|
2152
2819
|
},
|
|
2153
2820
|
get children() {
|
|
2154
|
-
var
|
|
2155
|
-
|
|
2821
|
+
var _el$2 = _tmpl$2$1();
|
|
2822
|
+
insert(_el$2, () => props.actions);
|
|
2823
|
+
return _el$2;
|
|
2156
2824
|
}
|
|
2157
2825
|
})];
|
|
2158
2826
|
}
|
|
@@ -2166,205 +2834,275 @@ const Dr = (r) => {
|
|
|
2166
2834
|
}
|
|
2167
2835
|
}))
|
|
2168
2836
|
});
|
|
2169
|
-
}
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2837
|
+
};
|
|
2838
|
+
const AlertModal = ({
|
|
2839
|
+
mountTarget,
|
|
2840
|
+
header,
|
|
2841
|
+
text,
|
|
2842
|
+
open,
|
|
2843
|
+
onPrimaryClick,
|
|
2844
|
+
onSecondaryClick,
|
|
2845
|
+
primaryButtonText = "Retry",
|
|
2846
|
+
secondaryButtonText = "Cancel"
|
|
2178
2847
|
}) => {
|
|
2179
|
-
let
|
|
2180
|
-
return
|
|
2181
|
-
mountTarget
|
|
2848
|
+
let primaryButtonEl;
|
|
2849
|
+
return createComponent(Modal, {
|
|
2850
|
+
mountTarget,
|
|
2182
2851
|
get header() {
|
|
2183
2852
|
return (() => {
|
|
2184
|
-
var
|
|
2185
|
-
|
|
2853
|
+
var _el$4 = _tmpl$4();
|
|
2854
|
+
insert(_el$4, header);
|
|
2855
|
+
effect(() => className(_el$4, styles.alertTitle));
|
|
2856
|
+
return _el$4;
|
|
2186
2857
|
})();
|
|
2187
2858
|
},
|
|
2188
|
-
initialFocusEl: () =>
|
|
2189
|
-
open
|
|
2859
|
+
initialFocusEl: () => primaryButtonEl,
|
|
2860
|
+
open,
|
|
2190
2861
|
get actions() {
|
|
2191
2862
|
return (() => {
|
|
2192
|
-
var
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2863
|
+
var _el$5 = _tmpl$5(), _el$6 = _el$5.firstChild, _el$7 = _el$6.nextSibling;
|
|
2864
|
+
_el$6.$$click = () => onSecondaryClick();
|
|
2865
|
+
insert(_el$6, secondaryButtonText);
|
|
2866
|
+
_el$7.$$click = () => onPrimaryClick();
|
|
2867
|
+
var _ref$ = primaryButtonEl;
|
|
2868
|
+
typeof _ref$ === "function" ? use(_ref$, _el$7) : primaryButtonEl = _el$7;
|
|
2869
|
+
insert(_el$7, primaryButtonText);
|
|
2870
|
+
effect((_p$) => {
|
|
2871
|
+
var _v$ = styles.actions, _v$2 = styles.secondaryActionButton, _v$3 = styles.primaryActionButton;
|
|
2872
|
+
_v$ !== _p$.e && className(_el$5, _p$.e = _v$);
|
|
2873
|
+
_v$2 !== _p$.t && className(_el$6, _p$.t = _v$2);
|
|
2874
|
+
_v$3 !== _p$.a && className(_el$7, _p$.a = _v$3);
|
|
2875
|
+
return _p$;
|
|
2198
2876
|
}, {
|
|
2199
2877
|
e: void 0,
|
|
2200
2878
|
t: void 0,
|
|
2201
2879
|
a: void 0
|
|
2202
|
-
})
|
|
2880
|
+
});
|
|
2881
|
+
return _el$5;
|
|
2203
2882
|
})();
|
|
2204
2883
|
},
|
|
2205
2884
|
modalStyle: "compact",
|
|
2206
2885
|
get children() {
|
|
2207
|
-
var
|
|
2208
|
-
|
|
2886
|
+
var _el$3 = _tmpl$3$1();
|
|
2887
|
+
insert(_el$3, text);
|
|
2888
|
+
effect(() => className(_el$3, styles.alertText));
|
|
2889
|
+
return _el$3;
|
|
2209
2890
|
}
|
|
2210
2891
|
});
|
|
2211
2892
|
};
|
|
2212
|
-
|
|
2213
|
-
const
|
|
2893
|
+
delegateEvents(["click"]);
|
|
2894
|
+
const CameraErrorModal = () => {
|
|
2214
2895
|
const {
|
|
2215
|
-
t
|
|
2216
|
-
} =
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2896
|
+
t
|
|
2897
|
+
} = useLocalization();
|
|
2898
|
+
const {
|
|
2899
|
+
cameraManagerSolidStore,
|
|
2900
|
+
cameraManager,
|
|
2901
|
+
dismountCameraUi
|
|
2902
|
+
} = useCameraUiStore();
|
|
2903
|
+
const errorState = cameraManagerSolidStore((x) => x.errorState);
|
|
2904
|
+
const overlayLayer = cameraUiRefSignalStore((x) => x.overlayLayer);
|
|
2905
|
+
return createComponent(Show, {
|
|
2222
2906
|
get when() {
|
|
2223
|
-
return
|
|
2907
|
+
return errorState();
|
|
2224
2908
|
},
|
|
2225
2909
|
get children() {
|
|
2226
|
-
return
|
|
2910
|
+
return createComponent(AlertModal, {
|
|
2227
2911
|
get mountTarget() {
|
|
2228
|
-
return
|
|
2912
|
+
return overlayLayer();
|
|
2229
2913
|
},
|
|
2230
2914
|
get header() {
|
|
2231
|
-
return
|
|
2915
|
+
return t.camera_error_title;
|
|
2232
2916
|
},
|
|
2233
|
-
open:
|
|
2234
|
-
onPrimaryClick: () => void
|
|
2235
|
-
onSecondaryClick: () =>
|
|
2917
|
+
open: true,
|
|
2918
|
+
onPrimaryClick: () => void cameraManager.startCameraStream(),
|
|
2919
|
+
onSecondaryClick: () => dismountCameraUi(),
|
|
2236
2920
|
get primaryButtonText() {
|
|
2237
|
-
return
|
|
2921
|
+
return t.camera_error_primary_btn;
|
|
2238
2922
|
},
|
|
2239
2923
|
get secondaryButtonText() {
|
|
2240
|
-
return
|
|
2924
|
+
return t.camera_error_cancel_btn;
|
|
2241
2925
|
},
|
|
2242
2926
|
get text() {
|
|
2243
|
-
return
|
|
2927
|
+
return t.camera_error_details;
|
|
2244
2928
|
}
|
|
2245
2929
|
});
|
|
2246
2930
|
}
|
|
2247
2931
|
});
|
|
2248
2932
|
};
|
|
2249
|
-
var
|
|
2250
|
-
const
|
|
2933
|
+
var _tmpl$ = /* @__PURE__ */ template(`<style>`), _tmpl$2 = /* @__PURE__ */ template(`<style id=camera-manager-style>`), _tmpl$3 = /* @__PURE__ */ template(`<div class="bg-dark-500 color-white size-full relative min-h-[300px]"part=capture-screen-part><video part=video-element-part class="block absolute top-0 left-0 size-full"></video><div class="absolute top-0 left-0 w-full h-full z-1"id=feedback-layer></div><div class="absolute top-0 left-0 w-full h-full has-[[data-scope]]:z-2"id=overlay-layer>`);
|
|
2934
|
+
const CAPTURE_SCREEN_SHADOW_ROOT_HOST_ID = "capture-screen-host";
|
|
2935
|
+
const CaptureScreen = () => {
|
|
2251
2936
|
const {
|
|
2252
|
-
cameraManager
|
|
2253
|
-
mountTarget
|
|
2254
|
-
} =
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2937
|
+
cameraManager,
|
|
2938
|
+
mountTarget
|
|
2939
|
+
} = useCameraUiStore();
|
|
2940
|
+
const [videoRef, setVideoRef] = createSignal();
|
|
2941
|
+
const [feedbackRef, setFeedbackRef] = createSignal();
|
|
2942
|
+
const [overlayLayerRef, setOverlayLayerRef] = createSignal();
|
|
2943
|
+
const isPortalled = () => mountTarget.parentNode === document.body;
|
|
2944
|
+
const [fitMode, setFitMode] = createSignal("contain");
|
|
2945
|
+
function adjustVideoFit() {
|
|
2946
|
+
const video = videoRef();
|
|
2947
|
+
if (!video) {
|
|
2258
2948
|
return;
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2949
|
+
}
|
|
2950
|
+
const Cw = video.clientWidth;
|
|
2951
|
+
const Ch = video.clientHeight;
|
|
2952
|
+
const Vw = video.videoWidth;
|
|
2953
|
+
const Vh = video.videoHeight;
|
|
2954
|
+
const newFitMode = determineFitMode(Cw, Ch, Vw, Vh);
|
|
2955
|
+
setFitMode(newFitMode);
|
|
2956
|
+
if (newFitMode === "cover") {
|
|
2957
|
+
const visibleArea = getVisibleVideoArea(Cw, Ch, Vw, Vh);
|
|
2958
|
+
cameraManager.setExtractionArea(visibleArea);
|
|
2959
|
+
} else {
|
|
2960
|
+
cameraManager.setExtractionArea({
|
|
2265
2961
|
x: 0,
|
|
2266
2962
|
y: 0,
|
|
2267
|
-
width:
|
|
2268
|
-
height:
|
|
2963
|
+
width: Vw,
|
|
2964
|
+
height: Vh
|
|
2269
2965
|
});
|
|
2966
|
+
}
|
|
2270
2967
|
}
|
|
2271
|
-
|
|
2272
|
-
const
|
|
2273
|
-
if (!
|
|
2968
|
+
onMount(() => {
|
|
2969
|
+
const video = videoRef();
|
|
2970
|
+
if (!video) {
|
|
2274
2971
|
return;
|
|
2972
|
+
}
|
|
2275
2973
|
const {
|
|
2276
|
-
observe
|
|
2277
|
-
unobserve
|
|
2278
|
-
} =
|
|
2279
|
-
|
|
2280
|
-
|
|
2974
|
+
observe,
|
|
2975
|
+
unobserve
|
|
2976
|
+
} = makeResizeObserver(adjustVideoFit);
|
|
2977
|
+
observe(video);
|
|
2978
|
+
video.addEventListener("loadedmetadata", adjustVideoFit);
|
|
2979
|
+
onCleanup(() => {
|
|
2980
|
+
unobserve(video);
|
|
2981
|
+
video.removeEventListener("loadedmetadata", adjustVideoFit);
|
|
2281
2982
|
});
|
|
2282
|
-
})
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2983
|
+
});
|
|
2984
|
+
onMount(() => {
|
|
2985
|
+
const owner = getOwner();
|
|
2986
|
+
if (!owner) {
|
|
2987
|
+
return;
|
|
2988
|
+
}
|
|
2989
|
+
cameraUiRefSignalStore.setState({
|
|
2990
|
+
owner
|
|
2991
|
+
});
|
|
2992
|
+
});
|
|
2993
|
+
createEffect(() => {
|
|
2994
|
+
const $videoRef = videoRef();
|
|
2995
|
+
const $feedbackRef = feedbackRef();
|
|
2996
|
+
const $overlayLayerRef = overlayLayerRef();
|
|
2997
|
+
if (!$videoRef || !$feedbackRef || !$overlayLayerRef) {
|
|
2998
|
+
return;
|
|
2999
|
+
}
|
|
3000
|
+
cameraUiRefSignalStore.setState({
|
|
3001
|
+
feedbackLayer: $feedbackRef,
|
|
3002
|
+
overlayLayer: $overlayLayerRef
|
|
2286
3003
|
});
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
feedbackLayer: h,
|
|
2291
|
-
overlayLayer: p
|
|
2292
|
-
}), r.initVideoElement(u));
|
|
2293
|
-
}), s(ir, {
|
|
3004
|
+
cameraManager.initVideoElement($videoRef);
|
|
3005
|
+
});
|
|
3006
|
+
return createComponent(SolidShadowRoot, {
|
|
2294
3007
|
get id() {
|
|
2295
|
-
return
|
|
3008
|
+
return !isPortalled() ? CAPTURE_SCREEN_SHADOW_ROOT_HOST_ID : void 0;
|
|
2296
3009
|
},
|
|
2297
3010
|
get disableShadowRoot() {
|
|
2298
|
-
return
|
|
3011
|
+
return isPortalled();
|
|
2299
3012
|
},
|
|
2300
3013
|
get style() {
|
|
2301
|
-
return
|
|
3014
|
+
return isPortalled() ? {
|
|
2302
3015
|
height: "100%"
|
|
2303
3016
|
} : void 0;
|
|
2304
3017
|
},
|
|
2305
3018
|
get children() {
|
|
2306
3019
|
return [(() => {
|
|
2307
|
-
var
|
|
2308
|
-
|
|
3020
|
+
var _el$ = _tmpl$();
|
|
3021
|
+
insert(_el$, variables);
|
|
3022
|
+
return _el$;
|
|
2309
3023
|
})(), (() => {
|
|
2310
|
-
var
|
|
2311
|
-
|
|
3024
|
+
var _el$2 = _tmpl$();
|
|
3025
|
+
insert(_el$2, normalize);
|
|
3026
|
+
return _el$2;
|
|
2312
3027
|
})(), (() => {
|
|
2313
|
-
var
|
|
2314
|
-
|
|
3028
|
+
var _el$3 = _tmpl$();
|
|
3029
|
+
insert(_el$3, rootStyles);
|
|
3030
|
+
return _el$3;
|
|
2315
3031
|
})(), (() => {
|
|
2316
|
-
var
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
3032
|
+
var _el$4 = _tmpl$2();
|
|
3033
|
+
use((ref) => {
|
|
3034
|
+
if (window.__mbCameraManagerCssCode) {
|
|
3035
|
+
ref.innerHTML = window.__mbCameraManagerCssCode;
|
|
3036
|
+
}
|
|
3037
|
+
}, _el$4);
|
|
3038
|
+
return _el$4;
|
|
2320
3039
|
})(), (() => {
|
|
2321
|
-
var
|
|
2322
|
-
|
|
3040
|
+
var _el$5 = _tmpl$3(), _el$6 = _el$5.firstChild, _el$7 = _el$6.nextSibling, _el$8 = _el$7.nextSibling;
|
|
3041
|
+
insert(_el$5, createComponent(Header, {}), _el$6);
|
|
3042
|
+
use(setVideoRef, _el$6);
|
|
3043
|
+
use(setFeedbackRef, _el$7);
|
|
3044
|
+
use(setOverlayLayerRef, _el$8);
|
|
3045
|
+
insert(_el$5, createComponent(CameraErrorModal, {}), null);
|
|
3046
|
+
effect((_$p) => (_$p = fitMode()) != null ? _el$6.style.setProperty("object-fit", _$p) : _el$6.style.removeProperty("object-fit"));
|
|
3047
|
+
return _el$5;
|
|
2323
3048
|
})()];
|
|
2324
3049
|
}
|
|
2325
3050
|
});
|
|
2326
|
-
}
|
|
3051
|
+
};
|
|
3052
|
+
const CaptureScreenPortalled = () => {
|
|
2327
3053
|
const {
|
|
2328
|
-
t
|
|
2329
|
-
} =
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
3054
|
+
t
|
|
3055
|
+
} = useLocalization();
|
|
3056
|
+
const [isOpen, setIsOpen] = createSignal(true);
|
|
3057
|
+
const {
|
|
3058
|
+
addOnDismountCallback
|
|
3059
|
+
} = useCameraUiStore();
|
|
3060
|
+
addOnDismountCallback(() => {
|
|
3061
|
+
setIsOpen(false);
|
|
3062
|
+
});
|
|
3063
|
+
return createComponent(Portal, {
|
|
3064
|
+
useShadow: true,
|
|
2336
3065
|
get mount() {
|
|
2337
|
-
return document.getElementById(
|
|
3066
|
+
return document.getElementById(MOUNT_POINT_ID);
|
|
3067
|
+
},
|
|
3068
|
+
ref: (ref) => {
|
|
3069
|
+
ref.id = CAPTURE_SCREEN_SHADOW_ROOT_HOST_ID;
|
|
3070
|
+
ref.style.zIndex = "1000";
|
|
3071
|
+
ref.style.position = "fixed";
|
|
3072
|
+
ref.id = "mb-camera-host";
|
|
3073
|
+
return ref;
|
|
2338
3074
|
},
|
|
2339
|
-
ref: (n) => (n.id = ze, n.style.zIndex = "1000", n.style.position = "fixed", n.id = "mb-camera-host", n),
|
|
2340
3075
|
get children() {
|
|
2341
|
-
return
|
|
2342
|
-
children: (
|
|
3076
|
+
return createComponent(SmartEnvironmentProvider, {
|
|
3077
|
+
children: (rootNode) => createComponent(Dialog.Root, {
|
|
2343
3078
|
get open() {
|
|
2344
|
-
return
|
|
3079
|
+
return isOpen();
|
|
2345
3080
|
},
|
|
2346
|
-
lazyMount:
|
|
2347
|
-
unmountOnExit:
|
|
3081
|
+
lazyMount: true,
|
|
3082
|
+
unmountOnExit: true,
|
|
2348
3083
|
initialFocusEl: () => {
|
|
2349
|
-
const
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
3084
|
+
const dummyNode = document.createElement("div");
|
|
3085
|
+
dummyNode.tabIndex = -1;
|
|
3086
|
+
rootNode.appendChild(dummyNode);
|
|
3087
|
+
setTimeout(() => {
|
|
3088
|
+
dummyNode.remove();
|
|
3089
|
+
}, 0);
|
|
3090
|
+
return dummyNode;
|
|
2353
3091
|
},
|
|
2354
3092
|
get children() {
|
|
2355
|
-
return
|
|
3093
|
+
return createComponent(Dialog.Positioner, {
|
|
2356
3094
|
get children() {
|
|
2357
|
-
return
|
|
3095
|
+
return createComponent(Dialog.Content, {
|
|
2358
3096
|
"aria-labelledby": "dialog-title",
|
|
2359
|
-
class: "h-vh supports-[(height:100dvh)]:h-dvh top-0 left-0 w-full fixed",
|
|
3097
|
+
"class": "h-vh supports-[(height:100dvh)]:h-dvh top-0 left-0 w-full fixed",
|
|
2360
3098
|
get children() {
|
|
2361
|
-
return [
|
|
2362
|
-
class: "sr-only",
|
|
3099
|
+
return [createComponent(Dialog.Title, {
|
|
3100
|
+
"class": "sr-only",
|
|
2363
3101
|
id: "dialog-title",
|
|
2364
3102
|
get children() {
|
|
2365
|
-
return
|
|
3103
|
+
return t.scan_document;
|
|
2366
3104
|
}
|
|
2367
|
-
}),
|
|
3105
|
+
}), createComponent(CaptureScreen, {})];
|
|
2368
3106
|
}
|
|
2369
3107
|
});
|
|
2370
3108
|
}
|
|
@@ -2374,65 +3112,89 @@ const ze = "capture-screen-host", Le = () => {
|
|
|
2374
3112
|
});
|
|
2375
3113
|
}
|
|
2376
3114
|
});
|
|
2377
|
-
}
|
|
3115
|
+
};
|
|
3116
|
+
const RootComponent = () => {
|
|
2378
3117
|
const {
|
|
2379
|
-
mountTarget
|
|
2380
|
-
} =
|
|
2381
|
-
return
|
|
3118
|
+
mountTarget
|
|
3119
|
+
} = useCameraUiStore();
|
|
3120
|
+
return createComponent(Dynamic, {
|
|
2382
3121
|
get component() {
|
|
2383
|
-
return
|
|
3122
|
+
return mountTarget.parentNode === document.body ? CaptureScreenPortalled : CaptureScreen;
|
|
2384
3123
|
}
|
|
2385
3124
|
});
|
|
2386
|
-
}
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
3125
|
+
};
|
|
3126
|
+
const MOUNT_POINT_ID = "camera-manager-mount-point";
|
|
3127
|
+
function createCameraManagerUi(cameraManager, target, {
|
|
3128
|
+
localizationStrings,
|
|
3129
|
+
showMirrorCameraButton = false,
|
|
3130
|
+
showTorchButton = true,
|
|
3131
|
+
showCloseButton = true
|
|
2390
3132
|
} = {}) {
|
|
2391
|
-
let
|
|
2392
|
-
const
|
|
2393
|
-
let
|
|
2394
|
-
const
|
|
2395
|
-
|
|
2396
|
-
}, c = () => {
|
|
2397
|
-
r.reset();
|
|
3133
|
+
let mountTarget;
|
|
3134
|
+
const dismountCallbacks = /* @__PURE__ */ new Set();
|
|
3135
|
+
let updateLocalizationRef;
|
|
3136
|
+
const setLocalizationRef = (setter) => {
|
|
3137
|
+
updateLocalizationRef = setter;
|
|
2398
3138
|
};
|
|
2399
|
-
|
|
2400
|
-
|
|
3139
|
+
const cleanupCameraManager = () => {
|
|
3140
|
+
cameraManager.reset();
|
|
3141
|
+
};
|
|
3142
|
+
let dismountRef;
|
|
3143
|
+
const dismountCameraManagerUi = () => {
|
|
2401
3144
|
try {
|
|
2402
3145
|
console.debug("🧱 Dismounting camera manager UI");
|
|
2403
|
-
for (const
|
|
2404
|
-
|
|
2405
|
-
|
|
3146
|
+
for (const callback of dismountCallbacks) {
|
|
3147
|
+
callback();
|
|
3148
|
+
}
|
|
3149
|
+
dismountCallbacks.clear();
|
|
3150
|
+
cleanupCameraManager();
|
|
3151
|
+
requestAnimationFrame(() => {
|
|
2406
3152
|
requestAnimationFrame(() => {
|
|
2407
|
-
|
|
3153
|
+
if (dismountRef) {
|
|
3154
|
+
dismountRef();
|
|
3155
|
+
}
|
|
3156
|
+
mountTarget.remove();
|
|
3157
|
+
cleanupCameraManager();
|
|
2408
3158
|
});
|
|
2409
3159
|
});
|
|
2410
|
-
} catch (
|
|
2411
|
-
console.warn("Error while dismounting camera manager UI",
|
|
3160
|
+
} catch (e) {
|
|
3161
|
+
console.warn("Error while dismounting camera manager UI", e);
|
|
2412
3162
|
}
|
|
2413
|
-
}
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
3163
|
+
};
|
|
3164
|
+
const newMountTarget = document.createElement("div");
|
|
3165
|
+
newMountTarget.id = MOUNT_POINT_ID;
|
|
3166
|
+
mountTarget = newMountTarget;
|
|
3167
|
+
if (target) {
|
|
3168
|
+
target.appendChild(newMountTarget);
|
|
3169
|
+
} else {
|
|
3170
|
+
document.body.appendChild(newMountTarget);
|
|
3171
|
+
}
|
|
3172
|
+
const addOnDismountCallback = (fn) => {
|
|
3173
|
+
dismountCallbacks.add(fn);
|
|
3174
|
+
return () => {
|
|
3175
|
+
dismountCallbacks.delete(fn);
|
|
3176
|
+
};
|
|
3177
|
+
};
|
|
3178
|
+
dismountRef = render(() => createComponent(LocalizationProvider, {
|
|
3179
|
+
userStrings: localizationStrings,
|
|
3180
|
+
setLocalizationRef,
|
|
2421
3181
|
get children() {
|
|
2422
|
-
return
|
|
2423
|
-
addOnDismountCallback
|
|
2424
|
-
dismountCameraUi:
|
|
2425
|
-
cameraManager
|
|
2426
|
-
showMirrorCameraButton
|
|
2427
|
-
|
|
3182
|
+
return createComponent(CameraUiStoreProvider, {
|
|
3183
|
+
addOnDismountCallback,
|
|
3184
|
+
dismountCameraUi: dismountCameraManagerUi,
|
|
3185
|
+
cameraManager,
|
|
3186
|
+
showMirrorCameraButton,
|
|
3187
|
+
showTorchButton,
|
|
3188
|
+
showCloseButton,
|
|
3189
|
+
mountTarget,
|
|
2428
3190
|
get children() {
|
|
2429
|
-
return
|
|
3191
|
+
return createComponent(RootComponent, {});
|
|
2430
3192
|
}
|
|
2431
3193
|
});
|
|
2432
3194
|
}
|
|
2433
|
-
}),
|
|
2434
|
-
const
|
|
2435
|
-
updateLocalization:
|
|
3195
|
+
}), mountTarget);
|
|
3196
|
+
const exposedComponentApi = {
|
|
3197
|
+
updateLocalization: updateLocalizationRef,
|
|
2436
3198
|
/**
|
|
2437
3199
|
* Adds a callback to be called when the component is unmounted.
|
|
2438
3200
|
* Returns a cleanup function that removes the callback when called.
|
|
@@ -2440,64 +3202,88 @@ function Yr(r, e, {
|
|
|
2440
3202
|
* @param fn - The callback function to be called when the component is unmounted
|
|
2441
3203
|
* @returns A cleanup function that removes the callback when called
|
|
2442
3204
|
*/
|
|
2443
|
-
addOnDismountCallback
|
|
2444
|
-
cameraManager
|
|
3205
|
+
addOnDismountCallback,
|
|
3206
|
+
cameraManager,
|
|
2445
3207
|
// we know these are defined because `createCameraManagerUi` resolves when they are defined
|
|
2446
3208
|
// TODO: maybe don't use getters but make sure they are defined
|
|
2447
3209
|
get feedbackLayerNode() {
|
|
2448
|
-
return
|
|
3210
|
+
return cameraUiRefStore.getState().feedbackLayer;
|
|
2449
3211
|
},
|
|
2450
3212
|
get overlayLayerNode() {
|
|
2451
|
-
return
|
|
3213
|
+
return cameraUiRefStore.getState().overlayLayer;
|
|
2452
3214
|
},
|
|
2453
3215
|
get owner() {
|
|
2454
|
-
return
|
|
3216
|
+
return cameraUiRefStore.getState().owner;
|
|
2455
3217
|
},
|
|
2456
|
-
dismount:
|
|
3218
|
+
dismount: dismountCameraManagerUi
|
|
2457
3219
|
};
|
|
2458
|
-
return new Promise((
|
|
2459
|
-
let
|
|
2460
|
-
|
|
2461
|
-
|
|
3220
|
+
return new Promise((resolve) => {
|
|
3221
|
+
let videoExists = false;
|
|
3222
|
+
let feedbackExists = false;
|
|
3223
|
+
let overlayExists = false;
|
|
3224
|
+
let unsubscribeFeedbackLayer = () => {
|
|
3225
|
+
};
|
|
3226
|
+
let unsubscribeOverlayLayer = () => {
|
|
3227
|
+
};
|
|
3228
|
+
let unsubscribeVideo = () => {
|
|
2462
3229
|
};
|
|
2463
|
-
const
|
|
2464
|
-
|
|
3230
|
+
const checkReady = () => {
|
|
3231
|
+
if (videoExists && feedbackExists && overlayExists) {
|
|
3232
|
+
unsubscribeFeedbackLayer();
|
|
3233
|
+
unsubscribeOverlayLayer();
|
|
3234
|
+
unsubscribeVideo();
|
|
3235
|
+
resolve(exposedComponentApi);
|
|
3236
|
+
}
|
|
2465
3237
|
};
|
|
2466
|
-
|
|
2467
|
-
|
|
3238
|
+
unsubscribeFeedbackLayer = cameraUiRefStore.subscribe((x) => x.feedbackLayer, (feedbackLayer) => {
|
|
3239
|
+
if (feedbackLayer) {
|
|
3240
|
+
feedbackExists = true;
|
|
3241
|
+
}
|
|
3242
|
+
checkReady();
|
|
2468
3243
|
}, {
|
|
2469
|
-
fireImmediately:
|
|
2470
|
-
})
|
|
2471
|
-
|
|
3244
|
+
fireImmediately: true
|
|
3245
|
+
});
|
|
3246
|
+
unsubscribeOverlayLayer = cameraUiRefStore.subscribe((x) => x.overlayLayer, (overlayLayer) => {
|
|
3247
|
+
if (overlayLayer) {
|
|
3248
|
+
overlayExists = true;
|
|
3249
|
+
}
|
|
3250
|
+
checkReady();
|
|
2472
3251
|
}, {
|
|
2473
|
-
fireImmediately:
|
|
2474
|
-
})
|
|
2475
|
-
|
|
3252
|
+
fireImmediately: true
|
|
3253
|
+
});
|
|
3254
|
+
unsubscribeVideo = cameraManager.subscribe((state) => state.videoElement, (videoElement) => {
|
|
3255
|
+
if (videoElement) {
|
|
3256
|
+
videoExists = true;
|
|
3257
|
+
checkReady();
|
|
3258
|
+
}
|
|
2476
3259
|
}, {
|
|
2477
|
-
fireImmediately:
|
|
3260
|
+
fireImmediately: true
|
|
2478
3261
|
});
|
|
2479
3262
|
});
|
|
2480
3263
|
}
|
|
2481
|
-
const
|
|
2482
|
-
globalThis.__CAMERA_MANAGER__ ||=
|
|
2483
|
-
globalThis.__CAMERA_MANAGER__ !==
|
|
2484
|
-
|
|
2485
|
-
|
|
3264
|
+
const testSymbol = Symbol();
|
|
3265
|
+
globalThis.__CAMERA_MANAGER__ ||= testSymbol;
|
|
3266
|
+
if (globalThis.__CAMERA_MANAGER__ !== testSymbol) {
|
|
3267
|
+
console.warn(
|
|
3268
|
+
"Detected multiple instances of @microblink/camera-manager. This can lead to unexpected behavior."
|
|
3269
|
+
);
|
|
3270
|
+
}
|
|
2486
3271
|
export {
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
3272
|
+
Camera,
|
|
3273
|
+
CameraManager,
|
|
3274
|
+
MOUNT_POINT_ID,
|
|
3275
|
+
VideoFrameProcessor,
|
|
3276
|
+
cameraManagerStore,
|
|
3277
|
+
cameraUiRefStore,
|
|
3278
|
+
createCameraManagerUi,
|
|
3279
|
+
defaultCameraManagerOptions,
|
|
3280
|
+
findResolutionKey,
|
|
3281
|
+
getBuffer,
|
|
3282
|
+
getNormalizedResolution,
|
|
3283
|
+
isBufferDetached,
|
|
3284
|
+
matchClosestResolution,
|
|
3285
|
+
resetCameraManagerStore,
|
|
3286
|
+
returnLongerSide,
|
|
3287
|
+
videoResolutions
|
|
2503
3288
|
};
|
|
3289
|
+
//# sourceMappingURL=camera-manager.js.map
|