@seams/voiceid 0.56.0 → 0.56.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/esm/capture/prompt.js +5 -0
- package/dist/public/sdk/voiceid/{addVoiceId-BzirvbVh.js → addVoiceId-DVmRzRfq.js} +1 -1
- package/dist/public/sdk/voiceid/{deviceBridge-D8R6eVEE.js → deviceBridge-ClUeOYHs.js} +1 -1
- package/dist/public/sdk/voiceid/host.js +2 -2
- package/dist/public/sdk/voiceid/{operation-CObNRH_J.js → operation-CNp1Cd-f.js} +1 -1
- package/dist/public/sdk/voiceid/{phrase-CArJ-DH1.js → phrase-BhRrKm5W.js} +1 -1
- package/dist/public/sdk/voiceid/{phrase-BumWInpD.js → phrase-BtxLUoH-.js} +1 -1
- package/dist/public/sdk/voiceid/{prompt-BPtSdsWi.js → prompt-v-LTC3EA.js} +5 -0
- package/dist/public/sdk/voiceid/{unlock-CPiLZCsY.js → unlock-D5el17OL.js} +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ and the trusted host API. Existing voice enrollments keep their storage identity
|
|
|
10
10
|
Install matching Wallet and VoiceID versions, then import the descriptor:
|
|
11
11
|
|
|
12
12
|
```sh
|
|
13
|
-
pnpm add @seams/wallet@0.56.
|
|
13
|
+
pnpm add @seams/wallet@0.56.2 @seams/voiceid@0.56.2
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
```ts
|
|
@@ -36,6 +36,11 @@ const CSS = `
|
|
|
36
36
|
@starting-style {
|
|
37
37
|
.seams-voiceid-prompt { opacity: 0; transform: translateY(4px); }
|
|
38
38
|
}
|
|
39
|
+
/* Each line owns its row. The download overlays rows 3-5; an auto-placed line would move to new rows. */
|
|
40
|
+
.seams-voiceid-prompt > h2 { grid-area: 1 / 1; }
|
|
41
|
+
.seams-voiceid-prompt > .seams-voiceid-phrase { grid-area: 2 / 1; }
|
|
42
|
+
.seams-voiceid-prompt > .seams-voiceid-ribbon { grid-area: 3 / 1; }
|
|
43
|
+
.seams-voiceid-prompt > .seams-voiceid-status { grid-area: 4 / 1; }
|
|
39
44
|
.seams-voiceid-progress-slot { grid-row: 5; grid-column: 1; min-width: 0; align-self: center; }
|
|
40
45
|
.seams-voiceid-progress-slot:empty { visibility: hidden; }
|
|
41
46
|
.seams-voiceid-activation-surface[data-preparation="loading"] .seams-voiceid-record-slot { visibility: hidden; }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./prompt-
|
|
1
|
+
import"./prompt-v-LTC3EA.js";import{a as e,i as t,o as n,s as r,t as i}from"./deviceBridge-ClUeOYHs.js";import{WorkerDeferred as a,prepareVoiceOwner as o,toError as s}from"../voiceid-host.js";const c=`http://www.w3.org/2000/svg`;async function l(e,t,n,r,i){let a=new u(e,t,n,r,i);try{await a.result}finally{a.dispose()}}var u=class{completion=new a;result=this.completion.promise;document;element;enrollment;enrollmentValue;enrollmentSummary;startOver;status;actions;busy=!1;closed=!1;constructor(e,t,n,r,i){this.parent=e,this.confirmChange=t,this.scope=n,this.signal=r,this.model=i,this.document=e.ownerDocument,this.element=this.document.createElement(`div`),this.enrollment=this.document.createElement(`div`),this.enrollmentValue=this.document.createElement(`span`),this.enrollmentSummary=this.document.createElement(`span`),this.startOver=this.document.createElement(`p`),this.status=this.document.createElement(`p`),this.element.className=`seams-voiceid-prompt seams-voiceid-management`;let a=this.document.createElement(`div`);a.className=`seams-voiceid-management-header`;let o=this.document.createElement(`button`);o.type=`button`,o.className=`seams-voiceid-management-back`,o.setAttribute(`aria-label`,`Back`),o.append(d(this.document,`M15 6l-6 6 6 6`,20)),o.addEventListener(`click`,this.cancel);let s=this.document.createElement(`h2`);s.textContent=`Manage voice`,a.append(o,s);let c=this.document.createElement(`p`);c.className=`seams-voiceid-management-intro`,c.textContent=`Voice unlock on this device. Each change asks for your passkey.`,this.element.append(a,c,this.enrollmentRow()),this.actions={reset:this.resetAction(),improve:this.action(`improve`,`Improve recognition`,!0),import:this.action(`import`,`Use saved enrollment`,!1),replace:this.startOverAction()},this.status.setAttribute(`role`,`status`),this.element.append(this.status),this.enrollmentValue.textContent=`Checking…`,this.actions.import.button.hidden=!0,this.render(null,!1,!1),this.parent.replaceChildren(this.element),this.signal.addEventListener(`abort`,this.cancel,{once:!0}),this.refresh(),o.focus()}enrollmentRow(){this.enrollment.className=`seams-voiceid-management-enrollment`;let e=this.document.createElement(`span`);return e.textContent=`Enrollment`,this.enrollmentValue.className=`seams-voiceid-management-value`,this.enrollmentSummary.className=`seams-voiceid-management-summary`,this.enrollmentSummary.append(this.enrollmentValue),this.enrollment.append(e,this.enrollmentSummary),this.enrollment}resetAction(){let e=this.document.createElement(`button`);e.type=`button`,e.className=`seams-voiceid-management-reset`,e.textContent=`Reset`,e.setAttribute(`aria-label`,`Reset improvements`),e.addEventListener(`click`,this.begin.bind(this,`reset`));let t=this.document.createElement(`span`);return t.className=`seams-voiceid-management-enrollment-detail`,this.enrollmentSummary.append(t),this.enrollment.append(e),{button:e,title:e,detail:t,frame:this.enrollment}}startOverAction(){return this.startOver.className=`seams-voiceid-management-section`,this.startOver.textContent=`Start over`,this.element.append(this.startOver),this.action(`replace`,`Record voice again`,!1)}action(e,t,n){let r=this.document.createElement(`button`);r.type=`button`,r.className=`seams-voiceid-management-action`;let i=this.document.createElement(`span`),a=this.document.createElement(`span`);a.className=`seams-voiceid-management-action-heading`;let o=this.document.createElement(`span`);o.id=`seams-voiceid-management-${e}-title`,o.textContent=t,a.append(o);let s=[];if(n){let t=this.document.createElement(`span`);t.id=`seams-voiceid-management-${e}-chip`,t.className=`seams-voiceid-management-chip`,t.textContent=`Experimental`,a.append(t),s.push(t.id)}let c=this.document.createElement(`span`);return c.id=`seams-voiceid-management-${e}-detail`,c.className=`seams-voiceid-management-action-detail`,s.push(c.id),i.append(a,c),r.append(i,d(this.document,`M9 6l6 6-6 6`,16)),r.setAttribute(`aria-labelledby`,o.id),r.setAttribute(`aria-describedby`,s.join(` `)),r.disabled=!0,r.addEventListener(`click`,this.begin.bind(this,e)),this.element.append(r),{button:r,title:o,detail:c,frame:r}}async refresh(){try{let e=await r(this.scope),t=e?null:await n();if(this.closed)return;this.render(e,t!==null,!0)}catch(e){this.completion.reject(s(e))}}render(e,t,n){let r=e?.adaptation??null,{improve:i,reset:a,import:o,replace:s}=this.actions;n&&(this.enrollment.dataset.enrollment=r?.kind??`missing`,this.enrollmentValue.textContent=r===null?`Not on this device`:r.kind===`adapted`?`Improved`:`Original`,i.button.hidden=e===null,o.button.hidden=!t),a.button.hidden=r?.kind!==`adapted`,a.detail.textContent=r?.kind===`adapted`?`Saved on this device`:``,i.title.textContent=r?.kind===`adapted`?`Improve again`:`Improve recognition`,i.detail.textContent=r?.kind===`adapted`?`Replace the added samples. Your original enrollment stays.`:`Add three samples. They stay until you replace or reset them.`,o.detail.textContent=`Import the voice enrollment saved in this browser.`,s.detail.textContent=r?.kind===`adapted`?`Replace your enrollment and remove improvements.`:`Replace your enrollment with three new samples.`,this.startOver.hidden=i.button.hidden&&o.button.hidden;for(let e of Object.values(this.actions))delete e.frame.dataset.state,e.button.disabled=!n;this.status.textContent=``,delete this.status.dataset.placement}show(e,t,n){let r=this.actions[e];if(this.status.textContent=n,r.button.hidden){this.status.dataset.placement=`dialog`;return}r.frame.dataset.state=t,r.detail.textContent=n}begin(e){if(!(this.busy||this.closed)){this.busy=!0;for(let e of Object.values(this.actions))e.button.disabled=!0;this.show(e,`pending`,`Confirm with your passkey to continue.`),this.perform(e)}}async perform(n){try{let i=await o(this.scope,`enrolled`),a=await r(this.scope),s=await f(n,i,a?{kind:`present`,enrollment:a}:{kind:`missing`},this.signal),c=await this.confirmChange(s);switch(this.signal.throwIfAborted(),s.kind){case`improve`:await t(this.parent,{kind:`improve`,scope:this.scope,guard:s.guard,snapshot:s.snapshot,confirmation:c},this.signal,this.model);break;case`replace`:await t(this.parent,{kind:`replace`,scope:this.scope,guard:s.guard,snapshot:s.snapshot,confirmation:c},this.signal,this.model);break;case`reset`:await e({kind:`reset`,scope:this.scope,guard:s.guard,snapshot:s.snapshot,confirmation:c,signal:this.signal});break;case`import`:await e({kind:`import`,scope:this.scope,guard:s.guard,snapshot:s.snapshot,baseline:s.baseline,confirmation:c,signal:this.signal});break;default:return p(s)}this.closed||this.completion.resolve()}catch(e){if(this.closed)return;this.parent.replaceChildren(this.element),await this.refresh(),this.closed||this.show(n,`error`,e instanceof Error?e.message:`VoiceID could not be updated.`)}finally{this.busy=!1}}cancel=()=>{this.closed||(this.closed=!0,this.parent.dispatchEvent(new Event(`cancel`,{bubbles:!0})),this.completion.reject(Error(`VoiceID management was cancelled.`)))};dispose(){this.closed=!0,this.signal.removeEventListener(`abort`,this.cancel),this.element.remove()}};function d(e,t,n){let r=e.createElementNS(c,`svg`);r.setAttribute(`viewBox`,`0 0 24 24`),r.setAttribute(`width`,String(n)),r.setAttribute(`height`,String(n)),r.setAttribute(`aria-hidden`,`true`);let i=e.createElementNS(c,`path`);return i.setAttribute(`d`,t),i.setAttribute(`fill`,`none`),i.setAttribute(`stroke`,`currentColor`),i.setAttribute(`stroke-width`,`1.75`),i.setAttribute(`stroke-linecap`,`round`),i.setAttribute(`stroke-linejoin`,`round`),r.append(i),r}async function f(e,t,r,i){switch(e){case`replace`:return{kind:e,guard:t,snapshot:r,signal:i};case`import`:{if(r.kind!==`missing`)throw Error(`The previous enrollment is unavailable.`);let a=await n();if(!a)throw Error(`The previous enrollment is unavailable.`);return{kind:e,guard:t,snapshot:r,signal:i,baseline:a}}case`improve`:case`reset`:if(r.kind!==`present`)throw Error(`Record or import your original voice first.`);return{kind:e,guard:t,snapshot:r,signal:i};default:return p(e)}}function p(e){throw Error(`Unsupported VoiceID enrollment management action.`)}async function m(e,t,n,r){t.throwIfAborted();let i=await e.prepareActivation();return t.throwIfAborted(),i.kind===`enroll_existing`?{kind:`management`,action:h.bind(null,r,i,n)}:{kind:`recording`,action:g.bind(null,r,i,n),expiresAtMs:null}}async function h(e,t,n,r){return await l(n,t.confirmChange,t.scope,r,e),r.throwIfAborted(),{kind:`activated`,walletId:t.scope.walletId,walletAuthMethodId:t.scope.walletAuthMethodId}}function g(e,t,n,r,a,o){return t.activate(i.bind(null,e,{parent:n,onCapture:a,phrase:o}),r)}export{m as prepareActivationSurface};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,i as t,n,r,t as i}from"./phrase-CArJ-DH1.js";import{a,c as o,g as s,h as c,i as l,m as u,o as ee,s as d,t as f,u as p}from"./prompt-BPtSdsWi.js";import{WorkerDeferred as m,assertVoiceOwner as h,base64UrlEncode as g,createBrowserVoiceDevice as _,isFiniteNumber as v,openBrowserVoiceFactor as y,parseVoiceIdDeviceAssertion as te,parseVoiceIdOperationAssertion as b,prepareVoiceOwner as x,readBrowserVoiceDevice as S,requireRecord as C,resolveActivatingVoiceEnrollmentScope as w,resolveVoiceEnrollmentScope as T,toError as E,voiceEnrollmentStorage as D,voiceIdOperationStatementBytes as O,voiceIdWalletSessionChallengeBytes as k}from"../voiceid-host.js";const A=`e04dd7a6a1e23fc7b89e47682ea9d0a3946cf7bc59d07922c3db3efc52ae4269`,j=`redimnet-b1:${A}`,M=new u({path:`/sdk/voiceid/redimnet-b1.onnx`,sha256:A,bytes:8859593,label:`Speaker verification`});async function N(e){let t=await M.prepare(),n=new(await(import(`./ort.wasm.bundle.min-BH_0rOm8.js`))).Tensor(`float32`,e,[1,e.length]);try{let e=await t.run({samples:n});try{let t=e.embedding;if(!t||!(t.data instanceof Float32Array))throw Error(`VoiceID model returned an invalid embedding.`);return P(Array.from(t.data))}finally{for(let t of Object.values(e))t.dispose()}}finally{n.dispose()}}function P(e){if(e.length!==192)throw Error(`VoiceID template dimensions are invalid.`);let t=0;for(let n of e){if(!Number.isFinite(n))throw Error(`VoiceID template is invalid.`);t+=n*n}if(t<1e-12)throw Error(`VoiceID template contains no signal.`);let n=Math.sqrt(t),r=[];for(let t of e)r.push(t/n);return r}function F(e,t){if(e.length!==192||t.length!==192)throw Error(`VoiceID templates are incompatible.`);let n=0;for(let r=0;r<e.length;r+=1)n+=e[r]*t[r];return n}function I(e){return e.asset}function L(e,t){return e+t.size}var R=class{element=document.createElement(`section`);status=document.createElement(`p`);meter=document.createElement(`progress`);retryButton=document.createElement(`button`);retry=null;cancelled=new m;reveal;received=new Map;models;assets;total;constructor(e,t,n){this.parent=e,this.signal=t,this.models=[M,r(n),p],this.assets=[s,...this.models.map(I)],this.total=this.assets.reduce(L,0),this.element.className=`seams-voiceid-model-download`,this.status.setAttribute(`role`,`status`),this.status.setAttribute(`aria-live`,`polite`),this.meter.setAttribute(`aria-label`,`VoiceID download`),this.meter.style.width=`100%`,this.retryButton.type=`button`,this.retryButton.className=`seams-voiceid-primary`,this.retryButton.textContent=`Retry loading`,this.retryButton.hidden=!0,this.retryButton.addEventListener(`click`,this.retryLoading),this.element.append(this.status,this.meter,this.retryButton),this.status.textContent=`Loading saved VoiceID…`,this.reveal=setTimeout(e.append.bind(e,this.element),300),t.addEventListener(`abort`,this.abort,{once:!0})}settle=()=>{clearTimeout(this.reveal),this.signal.removeEventListener(`abort`,this.abort),this.retryButton.removeEventListener(`click`,this.retryLoading)};abort=()=>{let e=new DOMException(`VoiceID preparation was cancelled.`,`AbortError`);this.cancelled.reject(e),this.retry?.reject(e)};retryLoading=()=>{this.retry?.resolve(),this.retry=null};async prepare(){this.signal.throwIfAborted(),await Promise.race([this.prepareUntilReady(),this.cancelled.promise])}async prepareUntilReady(){for(;;){this.signal.throwIfAborted(),this.retryButton.hidden=!0,this.meter.hidden=!1;try{for(let e of this.assets)await e.download(this.update.bind(this,e)),this.signal.throwIfAborted();this.preparing();for(let e of this.models)await e.prepare(),this.signal.throwIfAborted();this.ready();return}catch(e){if(this.signal.throwIfAborted(),!(e instanceof c))throw e;clearTimeout(this.reveal),this.parent.append(this.element),this.element.dataset.state=`failed`,this.meter.hidden=!0,this.status.textContent=e.message,this.retry=new m,this.retryButton.hidden=!1,this.retryButton.focus(),await this.retry.promise}}}update=(e,t)=>{switch(t.kind){case`checking_cache`:return;case`downloading`:this.received.set(e,t.received),this.element.dataset.state=`downloading`;break;case`ready`:this.received.set(e,e.size);break;default:}if(this.element.dataset.state!==`downloading`)return;let n=0;for(let e of this.received.values())n+=e;this.meter.max=this.total,this.meter.value=n,this.status.textContent=`Downloading VoiceID: ${(n/1e6).toFixed(1)} of ${(this.total/1e6).toFixed(1)} MB · ${Math.floor(n/this.total*100)}%`};preparing(){this.element.dataset.state=`preparing`,this.meter.removeAttribute(`value`),this.status.textContent=`Preparing VoiceID…`}ready(){this.element.dataset.state=`ready`,this.meter.hidden=!0,this.status.textContent=`VoiceID is ready.`}};async function z(e,t,n){let r=new R(e,t,n);try{await r.prepare()}finally{r.settle()}}const B=.2,V=D({model:j,parseEnrollment:U});function H(e){if(!Array.isArray(e)||!e.every(v))throw Error(`VoiceID template is invalid.`);let t=P(e);for(let n=0;n<e.length;n+=1)if(Math.abs(e[n]-t[n])>1e-6)throw Error(`VoiceID template is not normalized.`);return e.slice()}function U(e,t){if(e===void 0)return null;let n=C(e,`VoiceID enrollment`),r=C(n.scope,`VoiceID enrollment scope`);if(n.kind!==`browser_voiceid_enrollment_v2`||r.walletId!==t.walletId||r.authorityId!==t.authorityId||r.walletAuthMethodId!==t.walletAuthMethodId||r.deviceKeyId!==t.deviceKeyId||typeof n.generation!=`string`||!n.generation||typeof n.revision!=`number`||!Number.isSafeInteger(n.revision)||n.revision<0)throw Error(`VoiceID enrollment identity is invalid.`);if(n.model!==j)return null;let i=H(n.baseline),a={kind:`baseline`};try{let e=C(n.adaptation,`VoiceID improvements`);if(e.kind===`adapted`&&Array.isArray(e.samples)&&e.samples.length===3){let t=e.samples.map(H);G(i,t),a={kind:`adapted`,samples:t}}}catch{a={kind:`baseline`}}return{kind:`browser_voiceid_enrollment_v2`,scope:t,model:j,generation:n.generation,revision:n.revision,baseline:i,adaptation:a}}function W(e,t){let n=Array(192).fill(0);for(let e of t)for(let r=0;r<n.length;r+=1)n[r]+=e[r]/t.length;let r=P(n);for(let t=0;t<n.length;t+=1)n[t]=(1-B)*e[t]+B*r[t];return P(n)}function G(e,t){if(t.length!==3)throw Error(`Record three samples before saving voice improvements.`);for(let n of t)if(F(e,n)<.45)throw Error(`This sample differs from your original voice. Try again or re-record your enrollment.`);if(F(e,W(e,t))<.98)throw Error(`These samples differ too much from your original voice. Re-record your enrollment instead.`)}function K(e){return V.read(e)}async function q(e,t){let n=await V.readTemplate(e,t),r=n.adaptation;return{template:r.kind===`adapted`?W(n.baseline,r.samples):[...n.baseline],baseline:[...n.baseline],kind:r.kind}}async function J(){let e=await V.readImportable();if(e===void 0)return null;let t=C(e,`Previous VoiceID enrollment`);return t.kind!==`browser_voiceid_enrollment_v1`||t.model!==j?null:H(t.template)}async function Y(e){let{scope:t,signal:n}=e;switch(e.kind){case`activate`:return V.commit({kind:`activate`,scope:t,signal:n,guard:e.guard,snapshot:e.snapshot,baseline:H(e.baseline)});case`import`:return V.commit({kind:`import`,scope:t,signal:n,guard:e.guard,snapshot:e.snapshot,confirmation:e.confirmation,baseline:H(e.baseline)});case`replace`:return V.commit({kind:`replace`,scope:t,signal:n,guard:e.guard,snapshot:e.snapshot,confirmation:e.confirmation,baseline:H(e.baseline)});case`improve`:return G(e.snapshot.enrollment.baseline,e.samples),V.commit({kind:`improve`,scope:t,signal:n,guard:e.guard,snapshot:e.snapshot,confirmation:e.confirmation,samples:e.samples});case`reset`:return V.commit({kind:`reset`,scope:t,signal:n,guard:e.guard,snapshot:e.snapshot,confirmation:e.confirmation});default:return X(e)}}function X(e){throw Error(`Unsupported VoiceID enrollment change.`)}async function Z(e,t,n,r){n.throwIfAborted();let i=new ne(e,t,n,r);try{await Promise.race([i.prepare(),i.result]),await i.result}finally{i.dispose()}}var ne=class{completion=new m;result=this.completion.promise;status;prompt;phrase=t(null);record;cancel;samples=[];phase=`loading`;get closed(){return this.phase===`closed`}controller=new AbortController;guardTimer;checkingGuard=!1;constructor(e,t,n,r){this.plan=t,this.signal=n,this.model=r,this.prompt=new f(e.ownerDocument,`Enroll your voice in this browser`,this.phrase),this.prompt.title.textContent=`Read aloud · 0 of 3 accepted`,this.status=this.prompt.status,this.record=this.prompt.record,this.cancel=this.prompt.cancel,this.record.textContent=`Record sample 1`,this.record.addEventListener(`click`,this.capture),this.cancel.setAttribute(`aria-label`,`Cancel enrollment`),this.cancel.addEventListener(`click`,this.cancelled),this.prompt.ready(t.kind===`improve`?`Read naturally. Your original enrollment stays unchanged.`:`Read the full phrase at your normal pace.`),this.record.disabled=!0,e.replaceChildren(this.prompt.element),n.addEventListener(`abort`,this.cancelled,{once:!0}),this.guardTimer=setInterval(this.checkGuard,250),n.aborted?this.cancelled():this.cancel.focus()}async prepare(){await z(this.prompt.progress,this.controller.signal,this.model),this.phase===`loading`&&(this.prompt.progress.replaceChildren(),this.phase=`ready`,this.record.disabled=!1,this.record.focus())}capture=()=>{this.collect()};async collect(){if(this.phase!==`ready`)return;let e=this.samples.length+1;try{d(),this.phase=`recording`,this.record.disabled=!0,this.status.textContent=`Opening microphone…`;let e=await a(this.controller.signal,this.prompt.capture);if(this.signal.aborted||this.closed){e.kind===`captured`&&e.samples.fill(0);return}if(e.kind===`insufficient_audio`){this.status.textContent=o(e.quality);return}if(this.plan.kind===`improve`&&e.quality.noise!==`normal`){e.samples.fill(0),this.status.textContent=`Use a quiet place to improve your voice enrollment.`;return}let t;try{if(await h(this.plan.scope,this.plan.guard),this.status.textContent=`Checking your voice…`,(await n(e.samples,this.phrase,this.model)).kind===`mismatch`)throw new i;t=await N(e.samples)}finally{e.samples.fill(0)}if(this.signal.aborted||this.closed){t.fill(0);return}if(this.plan.kind===`improve`&&F(this.plan.snapshot.enrollment.baseline,t)<.45)throw t.fill(0),Error(`Your voice did not match the original enrollment. To replace it, return to Manage voice and choose Record voice again.`);for(let e of this.samples)if(F(e,t)<.45)throw t.fill(0),Error(`This sample differs from the earlier samples. Use the same microphone and try again.`);if(this.samples.push(t),this.samples.length<3){this.prompt.accepted(),this.status.textContent=`Sample ${this.samples.length} accepted. Record the next sample.`,this.record.textContent=`Record sample ${this.samples.length+1}`;return}let r=Array(192).fill(0);for(let e of this.samples)for(let t=0;t<r.length;t+=1)r[t]+=e[t]/3;this.phase=`committing`,this.prompt.title.textContent=`3 of 3 accepted`,this.status.textContent=`Saving voice enrollment…`;let s=this.plan;switch(s.kind){case`activate`:await Y({kind:`activate`,scope:s.scope,guard:s.guard,snapshot:s.snapshot,baseline:P(r),signal:this.controller.signal});break;case`replace`:await Y({kind:`replace`,scope:s.scope,guard:s.guard,snapshot:s.snapshot,baseline:P(r),confirmation:s.confirmation,signal:this.controller.signal});break;case`improve`:await Y({kind:`improve`,scope:s.scope,guard:s.guard,snapshot:s.snapshot,samples:this.samples,confirmation:s.confirmation,signal:this.controller.signal});break;default:return re(s)}if(this.signal.aborted||this.closed)return;this.phase=`closed`,this.prompt.accepted(),this.status.textContent=`Voice enrollment saved.`,this.completion.resolve()}catch(e){if(!this.closed&&this.phase===`committing`){this.phase=`closed`,this.controller.abort(),this.completion.reject(E(e));return}!this.closed&&this.samples.length===3&&this.samples.pop()?.fill(0),this.closed||(this.status.textContent=e instanceof Error?e.message:`VoiceID enrollment failed.`)}finally{this.closed||(this.samples.length<e&&(this.record.textContent=`Retry sample ${e}`,this.status.textContent=`Sample ${e} was not accepted. ${this.status.textContent??``}`),this.phrase=t(this.phrase),this.prompt.setPhrase(this.phrase),this.prompt.title.textContent=`Read aloud · ${this.samples.length} of 3 accepted`,this.prompt.ready(this.status.textContent??``),this.phase=`ready`,this.record.disabled=!1)}}cancelled=()=>{this.closed||(this.phase=`closed`,this.completion.reject(Error(`VoiceID enrollment was cancelled.`)),this.controller.abort())};checkGuard=()=>{this.closed||this.checkingGuard||(this.checkingGuard=!0,this.validateGuard())};async validateGuard(){try{await h(this.plan.scope,this.plan.guard)}catch(e){this.closed||(this.phase=`closed`,this.controller.abort(),this.completion.reject(E(e)))}finally{this.checkingGuard=!1}}dispose(){this.phase=`closed`,this.controller.abort(),clearInterval(this.guardTimer),this.signal.removeEventListener(`abort`,this.cancelled),this.prompt.dispose(),this.record.removeEventListener(`click`,this.capture),this.cancel.removeEventListener(`click`,this.cancelled);for(let e of this.samples)e.fill(0)}};function re(e){throw Error(`Unsupported VoiceID enrollment capture.`)}async function Q(e,t,r,i,o){let s=await a(t,r);if(s.kind===`insufficient_audio`)return t.throwIfAborted(),s;try{t.throwIfAborted();let r=await n(s.samples,i,o),a=await N(s.samples),c;try{t.throwIfAborted();let n=await q(e,t);try{c=F(a,n.template)}finally{n.template.fill(0),n.baseline.fill(0)}}finally{a.fill(0)}return c<.45?{kind:`mismatch`,quality:s.quality}:r.kind===`matched`?{kind:`matched`}:{kind:`phrase_mismatch`}}finally{s.samples.fill(0)}}async function ie(e,t,n){d();let r=await _(n.walletId,n.walletAuthMethodId),i=await w(r);if(await K(i))await $({kind:`activation`,scope:i,owner:await x(i,`activating`)},n.signal,t.onCapture,t.phrase,e);else{let r=await x(i,`activating`);await Z(t.parent,{kind:`activate`,scope:i,guard:r,snapshot:{kind:`missing`}},n.signal,e)}n.signal.throwIfAborted();let a=await y(r);if(n.signal.aborted)throw a.fill(0),Error(`VoiceID activation was cancelled.`);return{kind:`activated`,publicKeyB64u:r.publicKeyB64u,deviceKeyId:r.deviceKeyId,factorSecret32:a}}async function ae(e,t,n){ee();let{challenge:r}=n;if(r.requestOrigin!==location.origin||r.expiresAtMs<=Date.now())throw Error(`VoiceID challenge is expired or belongs to another Wallet origin.`);let i=await S(r.walletId,r.walletAuthMethodId);if(!i||i.deviceKeyId!==r.deviceKeyId)throw Error(`VoiceID device key is unavailable in this browser.`);if(await $({kind:`active`,scope:await T(r.walletId,r.walletAuthMethodId)},n.signal,t.onCapture,t.phrase,e),n.signal.throwIfAborted(),r.expiresAtMs<=Date.now())throw Error(`VoiceID challenge expired. Start unlock again.`);let a=await crypto.subtle.sign(`Ed25519`,i.privateKey,k(r)),o=await y(i);if(n.signal.aborted||r.expiresAtMs<=Date.now())throw o.fill(0),Error(`VoiceID unlock expired or was cancelled.`);return{kind:`unlocked`,assertion:te({kind:`voiceid_device_assertion_v1`,challenge:r,signatureB64u:g(new Uint8Array(a))}),factorSecret32:o}}async function oe(e,t,n){d();let{statement:r}=n;if(r.requestOrigin!==location.origin||r.expiresAtMs<=Date.now())throw Error(`VoiceID check is expired or belongs to another Wallet origin.`);let i=await S(r.walletId,r.walletAuthMethodId);if(!i||i.deviceKeyId!==r.deviceKeyId)throw Error(`VoiceID device key is unavailable in this browser.`);if(await $({kind:`active`,scope:await T(r.walletId,r.walletAuthMethodId)},n.signal,t.onCapture,t.phrase,e),n.signal.throwIfAborted(),r.expiresAtMs<=Date.now())throw Error(`VoiceID check expired. Start again.`);let a=await crypto.subtle.sign(`Ed25519`,i.privateKey,O(r)),o=await y(i);if(n.signal.aborted||r.expiresAtMs<=Date.now())throw o.fill(0),Error(`VoiceID check expired or was cancelled.`);return{kind:`confirmed`,assertion:b({kind:`voiceid_operation_assertion_v1`,statement:r,signatureB64u:g(new Uint8Array(a))}),factorSecret32:o}}async function $(t,n,r,a,o){let s=await Q(t,n,r,a,o);switch(s.kind){case`matched`:return;case`insufficient_audio`:throw new l(s.quality);case`mismatch`:throw new e(s.quality);case`phrase_mismatch`:throw new i;default:return se(s)}}function se(e){throw Error(`Unexpected voice result: ${String(e)}`)}export{Y as a,z as c,Z as i,oe as n,J as o,ae as r,K as s,ie as t};
|
|
1
|
+
import{a as e,i as t,n,r,t as i}from"./phrase-BhRrKm5W.js";import{a,c as o,g as s,h as c,i as l,m as u,o as ee,s as d,t as f,u as p}from"./prompt-v-LTC3EA.js";import{WorkerDeferred as m,assertVoiceOwner as h,base64UrlEncode as g,createBrowserVoiceDevice as _,isFiniteNumber as v,openBrowserVoiceFactor as y,parseVoiceIdDeviceAssertion as te,parseVoiceIdOperationAssertion as b,prepareVoiceOwner as x,readBrowserVoiceDevice as S,requireRecord as C,resolveActivatingVoiceEnrollmentScope as w,resolveVoiceEnrollmentScope as T,toError as E,voiceEnrollmentStorage as D,voiceIdOperationStatementBytes as O,voiceIdWalletSessionChallengeBytes as k}from"../voiceid-host.js";const A=`e04dd7a6a1e23fc7b89e47682ea9d0a3946cf7bc59d07922c3db3efc52ae4269`,j=`redimnet-b1:${A}`,M=new u({path:`/sdk/voiceid/redimnet-b1.onnx`,sha256:A,bytes:8859593,label:`Speaker verification`});async function N(e){let t=await M.prepare(),n=new(await(import(`./ort.wasm.bundle.min-BH_0rOm8.js`))).Tensor(`float32`,e,[1,e.length]);try{let e=await t.run({samples:n});try{let t=e.embedding;if(!t||!(t.data instanceof Float32Array))throw Error(`VoiceID model returned an invalid embedding.`);return P(Array.from(t.data))}finally{for(let t of Object.values(e))t.dispose()}}finally{n.dispose()}}function P(e){if(e.length!==192)throw Error(`VoiceID template dimensions are invalid.`);let t=0;for(let n of e){if(!Number.isFinite(n))throw Error(`VoiceID template is invalid.`);t+=n*n}if(t<1e-12)throw Error(`VoiceID template contains no signal.`);let n=Math.sqrt(t),r=[];for(let t of e)r.push(t/n);return r}function F(e,t){if(e.length!==192||t.length!==192)throw Error(`VoiceID templates are incompatible.`);let n=0;for(let r=0;r<e.length;r+=1)n+=e[r]*t[r];return n}function I(e){return e.asset}function L(e,t){return e+t.size}var R=class{element=document.createElement(`section`);status=document.createElement(`p`);meter=document.createElement(`progress`);retryButton=document.createElement(`button`);retry=null;cancelled=new m;reveal;received=new Map;models;assets;total;constructor(e,t,n){this.parent=e,this.signal=t,this.models=[M,r(n),p],this.assets=[s,...this.models.map(I)],this.total=this.assets.reduce(L,0),this.element.className=`seams-voiceid-model-download`,this.status.setAttribute(`role`,`status`),this.status.setAttribute(`aria-live`,`polite`),this.meter.setAttribute(`aria-label`,`VoiceID download`),this.meter.style.width=`100%`,this.retryButton.type=`button`,this.retryButton.className=`seams-voiceid-primary`,this.retryButton.textContent=`Retry loading`,this.retryButton.hidden=!0,this.retryButton.addEventListener(`click`,this.retryLoading),this.element.append(this.status,this.meter,this.retryButton),this.status.textContent=`Loading saved VoiceID…`,this.reveal=setTimeout(e.append.bind(e,this.element),300),t.addEventListener(`abort`,this.abort,{once:!0})}settle=()=>{clearTimeout(this.reveal),this.signal.removeEventListener(`abort`,this.abort),this.retryButton.removeEventListener(`click`,this.retryLoading)};abort=()=>{let e=new DOMException(`VoiceID preparation was cancelled.`,`AbortError`);this.cancelled.reject(e),this.retry?.reject(e)};retryLoading=()=>{this.retry?.resolve(),this.retry=null};async prepare(){this.signal.throwIfAborted(),await Promise.race([this.prepareUntilReady(),this.cancelled.promise])}async prepareUntilReady(){for(;;){this.signal.throwIfAborted(),this.retryButton.hidden=!0,this.meter.hidden=!1;try{for(let e of this.assets)await e.download(this.update.bind(this,e)),this.signal.throwIfAborted();this.preparing();for(let e of this.models)await e.prepare(),this.signal.throwIfAborted();this.ready();return}catch(e){if(this.signal.throwIfAborted(),!(e instanceof c))throw e;clearTimeout(this.reveal),this.parent.append(this.element),this.element.dataset.state=`failed`,this.meter.hidden=!0,this.status.textContent=e.message,this.retry=new m,this.retryButton.hidden=!1,this.retryButton.focus(),await this.retry.promise}}}update=(e,t)=>{switch(t.kind){case`checking_cache`:return;case`downloading`:this.received.set(e,t.received),this.element.dataset.state=`downloading`;break;case`ready`:this.received.set(e,e.size);break;default:}if(this.element.dataset.state!==`downloading`)return;let n=0;for(let e of this.received.values())n+=e;this.meter.max=this.total,this.meter.value=n,this.status.textContent=`Downloading VoiceID: ${(n/1e6).toFixed(1)} of ${(this.total/1e6).toFixed(1)} MB · ${Math.floor(n/this.total*100)}%`};preparing(){this.element.dataset.state=`preparing`,this.meter.removeAttribute(`value`),this.status.textContent=`Preparing VoiceID…`}ready(){this.element.dataset.state=`ready`,this.meter.hidden=!0,this.status.textContent=`VoiceID is ready.`}};async function z(e,t,n){let r=new R(e,t,n);try{await r.prepare()}finally{r.settle()}}const B=.2,V=D({model:j,parseEnrollment:U});function H(e){if(!Array.isArray(e)||!e.every(v))throw Error(`VoiceID template is invalid.`);let t=P(e);for(let n=0;n<e.length;n+=1)if(Math.abs(e[n]-t[n])>1e-6)throw Error(`VoiceID template is not normalized.`);return e.slice()}function U(e,t){if(e===void 0)return null;let n=C(e,`VoiceID enrollment`),r=C(n.scope,`VoiceID enrollment scope`);if(n.kind!==`browser_voiceid_enrollment_v2`||r.walletId!==t.walletId||r.authorityId!==t.authorityId||r.walletAuthMethodId!==t.walletAuthMethodId||r.deviceKeyId!==t.deviceKeyId||typeof n.generation!=`string`||!n.generation||typeof n.revision!=`number`||!Number.isSafeInteger(n.revision)||n.revision<0)throw Error(`VoiceID enrollment identity is invalid.`);if(n.model!==j)return null;let i=H(n.baseline),a={kind:`baseline`};try{let e=C(n.adaptation,`VoiceID improvements`);if(e.kind===`adapted`&&Array.isArray(e.samples)&&e.samples.length===3){let t=e.samples.map(H);G(i,t),a={kind:`adapted`,samples:t}}}catch{a={kind:`baseline`}}return{kind:`browser_voiceid_enrollment_v2`,scope:t,model:j,generation:n.generation,revision:n.revision,baseline:i,adaptation:a}}function W(e,t){let n=Array(192).fill(0);for(let e of t)for(let r=0;r<n.length;r+=1)n[r]+=e[r]/t.length;let r=P(n);for(let t=0;t<n.length;t+=1)n[t]=(1-B)*e[t]+B*r[t];return P(n)}function G(e,t){if(t.length!==3)throw Error(`Record three samples before saving voice improvements.`);for(let n of t)if(F(e,n)<.45)throw Error(`This sample differs from your original voice. Try again or re-record your enrollment.`);if(F(e,W(e,t))<.98)throw Error(`These samples differ too much from your original voice. Re-record your enrollment instead.`)}function K(e){return V.read(e)}async function q(e,t){let n=await V.readTemplate(e,t),r=n.adaptation;return{template:r.kind===`adapted`?W(n.baseline,r.samples):[...n.baseline],baseline:[...n.baseline],kind:r.kind}}async function J(){let e=await V.readImportable();if(e===void 0)return null;let t=C(e,`Previous VoiceID enrollment`);return t.kind!==`browser_voiceid_enrollment_v1`||t.model!==j?null:H(t.template)}async function Y(e){let{scope:t,signal:n}=e;switch(e.kind){case`activate`:return V.commit({kind:`activate`,scope:t,signal:n,guard:e.guard,snapshot:e.snapshot,baseline:H(e.baseline)});case`import`:return V.commit({kind:`import`,scope:t,signal:n,guard:e.guard,snapshot:e.snapshot,confirmation:e.confirmation,baseline:H(e.baseline)});case`replace`:return V.commit({kind:`replace`,scope:t,signal:n,guard:e.guard,snapshot:e.snapshot,confirmation:e.confirmation,baseline:H(e.baseline)});case`improve`:return G(e.snapshot.enrollment.baseline,e.samples),V.commit({kind:`improve`,scope:t,signal:n,guard:e.guard,snapshot:e.snapshot,confirmation:e.confirmation,samples:e.samples});case`reset`:return V.commit({kind:`reset`,scope:t,signal:n,guard:e.guard,snapshot:e.snapshot,confirmation:e.confirmation});default:return X(e)}}function X(e){throw Error(`Unsupported VoiceID enrollment change.`)}async function Z(e,t,n,r){n.throwIfAborted();let i=new ne(e,t,n,r);try{await Promise.race([i.prepare(),i.result]),await i.result}finally{i.dispose()}}var ne=class{completion=new m;result=this.completion.promise;status;prompt;phrase=t(null);record;cancel;samples=[];phase=`loading`;get closed(){return this.phase===`closed`}controller=new AbortController;guardTimer;checkingGuard=!1;constructor(e,t,n,r){this.plan=t,this.signal=n,this.model=r,this.prompt=new f(e.ownerDocument,`Enroll your voice in this browser`,this.phrase),this.prompt.title.textContent=`Read aloud · 0 of 3 accepted`,this.status=this.prompt.status,this.record=this.prompt.record,this.cancel=this.prompt.cancel,this.record.textContent=`Record sample 1`,this.record.addEventListener(`click`,this.capture),this.cancel.setAttribute(`aria-label`,`Cancel enrollment`),this.cancel.addEventListener(`click`,this.cancelled),this.prompt.ready(t.kind===`improve`?`Read naturally. Your original enrollment stays unchanged.`:`Read the full phrase at your normal pace.`),this.record.disabled=!0,e.replaceChildren(this.prompt.element),n.addEventListener(`abort`,this.cancelled,{once:!0}),this.guardTimer=setInterval(this.checkGuard,250),n.aborted?this.cancelled():this.cancel.focus()}async prepare(){await z(this.prompt.progress,this.controller.signal,this.model),this.phase===`loading`&&(this.prompt.progress.replaceChildren(),this.phase=`ready`,this.record.disabled=!1,this.record.focus())}capture=()=>{this.collect()};async collect(){if(this.phase!==`ready`)return;let e=this.samples.length+1;try{d(),this.phase=`recording`,this.record.disabled=!0,this.status.textContent=`Opening microphone…`;let e=await a(this.controller.signal,this.prompt.capture);if(this.signal.aborted||this.closed){e.kind===`captured`&&e.samples.fill(0);return}if(e.kind===`insufficient_audio`){this.status.textContent=o(e.quality);return}if(this.plan.kind===`improve`&&e.quality.noise!==`normal`){e.samples.fill(0),this.status.textContent=`Use a quiet place to improve your voice enrollment.`;return}let t;try{if(await h(this.plan.scope,this.plan.guard),this.status.textContent=`Checking your voice…`,(await n(e.samples,this.phrase,this.model)).kind===`mismatch`)throw new i;t=await N(e.samples)}finally{e.samples.fill(0)}if(this.signal.aborted||this.closed){t.fill(0);return}if(this.plan.kind===`improve`&&F(this.plan.snapshot.enrollment.baseline,t)<.45)throw t.fill(0),Error(`Your voice did not match the original enrollment. To replace it, return to Manage voice and choose Record voice again.`);for(let e of this.samples)if(F(e,t)<.45)throw t.fill(0),Error(`This sample differs from the earlier samples. Use the same microphone and try again.`);if(this.samples.push(t),this.samples.length<3){this.prompt.accepted(),this.status.textContent=`Sample ${this.samples.length} accepted. Record the next sample.`,this.record.textContent=`Record sample ${this.samples.length+1}`;return}let r=Array(192).fill(0);for(let e of this.samples)for(let t=0;t<r.length;t+=1)r[t]+=e[t]/3;this.phase=`committing`,this.prompt.title.textContent=`3 of 3 accepted`,this.status.textContent=`Saving voice enrollment…`;let s=this.plan;switch(s.kind){case`activate`:await Y({kind:`activate`,scope:s.scope,guard:s.guard,snapshot:s.snapshot,baseline:P(r),signal:this.controller.signal});break;case`replace`:await Y({kind:`replace`,scope:s.scope,guard:s.guard,snapshot:s.snapshot,baseline:P(r),confirmation:s.confirmation,signal:this.controller.signal});break;case`improve`:await Y({kind:`improve`,scope:s.scope,guard:s.guard,snapshot:s.snapshot,samples:this.samples,confirmation:s.confirmation,signal:this.controller.signal});break;default:return re(s)}if(this.signal.aborted||this.closed)return;this.phase=`closed`,this.prompt.accepted(),this.status.textContent=`Voice enrollment saved.`,this.completion.resolve()}catch(e){if(!this.closed&&this.phase===`committing`){this.phase=`closed`,this.controller.abort(),this.completion.reject(E(e));return}!this.closed&&this.samples.length===3&&this.samples.pop()?.fill(0),this.closed||(this.status.textContent=e instanceof Error?e.message:`VoiceID enrollment failed.`)}finally{this.closed||(this.samples.length<e&&(this.record.textContent=`Retry sample ${e}`,this.status.textContent=`Sample ${e} was not accepted. ${this.status.textContent??``}`),this.phrase=t(this.phrase),this.prompt.setPhrase(this.phrase),this.prompt.title.textContent=`Read aloud · ${this.samples.length} of 3 accepted`,this.prompt.ready(this.status.textContent??``),this.phase=`ready`,this.record.disabled=!1)}}cancelled=()=>{this.closed||(this.phase=`closed`,this.completion.reject(Error(`VoiceID enrollment was cancelled.`)),this.controller.abort())};checkGuard=()=>{this.closed||this.checkingGuard||(this.checkingGuard=!0,this.validateGuard())};async validateGuard(){try{await h(this.plan.scope,this.plan.guard)}catch(e){this.closed||(this.phase=`closed`,this.controller.abort(),this.completion.reject(E(e)))}finally{this.checkingGuard=!1}}dispose(){this.phase=`closed`,this.controller.abort(),clearInterval(this.guardTimer),this.signal.removeEventListener(`abort`,this.cancelled),this.prompt.dispose(),this.record.removeEventListener(`click`,this.capture),this.cancel.removeEventListener(`click`,this.cancelled);for(let e of this.samples)e.fill(0)}};function re(e){throw Error(`Unsupported VoiceID enrollment capture.`)}async function Q(e,t,r,i,o){let s=await a(t,r);if(s.kind===`insufficient_audio`)return t.throwIfAborted(),s;try{t.throwIfAborted();let r=await n(s.samples,i,o),a=await N(s.samples),c;try{t.throwIfAborted();let n=await q(e,t);try{c=F(a,n.template)}finally{n.template.fill(0),n.baseline.fill(0)}}finally{a.fill(0)}return c<.45?{kind:`mismatch`,quality:s.quality}:r.kind===`matched`?{kind:`matched`}:{kind:`phrase_mismatch`}}finally{s.samples.fill(0)}}async function ie(e,t,n){d();let r=await _(n.walletId,n.walletAuthMethodId),i=await w(r);if(await K(i))await $({kind:`activation`,scope:i,owner:await x(i,`activating`)},n.signal,t.onCapture,t.phrase,e);else{let r=await x(i,`activating`);await Z(t.parent,{kind:`activate`,scope:i,guard:r,snapshot:{kind:`missing`}},n.signal,e)}n.signal.throwIfAborted();let a=await y(r);if(n.signal.aborted)throw a.fill(0),Error(`VoiceID activation was cancelled.`);return{kind:`activated`,publicKeyB64u:r.publicKeyB64u,deviceKeyId:r.deviceKeyId,factorSecret32:a}}async function ae(e,t,n){ee();let{challenge:r}=n;if(r.requestOrigin!==location.origin||r.expiresAtMs<=Date.now())throw Error(`VoiceID challenge is expired or belongs to another Wallet origin.`);let i=await S(r.walletId,r.walletAuthMethodId);if(!i||i.deviceKeyId!==r.deviceKeyId)throw Error(`VoiceID device key is unavailable in this browser.`);if(await $({kind:`active`,scope:await T(r.walletId,r.walletAuthMethodId)},n.signal,t.onCapture,t.phrase,e),n.signal.throwIfAborted(),r.expiresAtMs<=Date.now())throw Error(`VoiceID challenge expired. Start unlock again.`);let a=await crypto.subtle.sign(`Ed25519`,i.privateKey,k(r)),o=await y(i);if(n.signal.aborted||r.expiresAtMs<=Date.now())throw o.fill(0),Error(`VoiceID unlock expired or was cancelled.`);return{kind:`unlocked`,assertion:te({kind:`voiceid_device_assertion_v1`,challenge:r,signatureB64u:g(new Uint8Array(a))}),factorSecret32:o}}async function oe(e,t,n){d();let{statement:r}=n;if(r.requestOrigin!==location.origin||r.expiresAtMs<=Date.now())throw Error(`VoiceID check is expired or belongs to another Wallet origin.`);let i=await S(r.walletId,r.walletAuthMethodId);if(!i||i.deviceKeyId!==r.deviceKeyId)throw Error(`VoiceID device key is unavailable in this browser.`);if(await $({kind:`active`,scope:await T(r.walletId,r.walletAuthMethodId)},n.signal,t.onCapture,t.phrase,e),n.signal.throwIfAborted(),r.expiresAtMs<=Date.now())throw Error(`VoiceID check expired. Start again.`);let a=await crypto.subtle.sign(`Ed25519`,i.privateKey,O(r)),o=await y(i);if(n.signal.aborted||r.expiresAtMs<=Date.now())throw o.fill(0),Error(`VoiceID check expired or was cancelled.`);return{kind:`confirmed`,assertion:b({kind:`voiceid_operation_assertion_v1`,statement:r,signatureB64u:g(new Uint8Array(a))}),factorSecret32:o}}async function $(t,n,r,a,o){let s=await Q(t,n,r,a,o);switch(s.kind){case`matched`:return;case`insufficient_audio`:throw new l(s.quality);case`mismatch`:throw new e(s.quality);case`phrase_mismatch`:throw new i;default:return se(s)}}function se(e){throw Error(`Unexpected voice result: ${String(e)}`)}export{Y as a,z as c,Z as i,oe as n,J as o,ae as r,K as s,ie as t};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as e,i as t,t as n}from"./phrase-
|
|
1
|
+
import{a as e,i as t,t as n}from"./phrase-BhRrKm5W.js";import{i as r,l as i,n as a,r as o,t as s}from"./prompt-v-LTC3EA.js";import{SeamsWordmark as c,VOICE_ID_HOST_API_VERSION as l,WorkerDeferred as u,authMenuSuccessCopy as d,backIcon as f,createCspStylesheetManager as p,createWalletIframeSurfaceMeasurementReporter as m,getDefaultCspNonce as h,toError as g}from"../voiceid-host.js";const _=new WeakMap;var v=class{footer;constructor(e,t){this.prompt=t;let n=e.ownerDocument,r=_.get(n);r||(r=p({doc:n,baseCss:`
|
|
2
2
|
.seams-voiceid-activation-surface.seams-voiceid-unlock {
|
|
3
3
|
box-sizing: border-box;
|
|
4
4
|
overflow: hidden;
|
|
@@ -78,4 +78,4 @@ import{a as e,i as t,t as n}from"./phrase-CArJ-DH1.js";import{i as r,l as i,n as
|
|
|
78
78
|
color: var(--seams-colors-textPrimary, #eff2f3);
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
|
-
`,nonce:h}),_.set(n,r)),r.ensureBase(),e.classList.add(`seams-voiceid-unlock`);let i=n.createElement(`div`);i.className=`seams-voiceid-unlock-header`,t.cancel.className=`seams-voiceid-unlock-back`,t.cancel.setAttribute(`aria-label`,`Back`),t.cancel.replaceChildren(),a(f(),t.cancel),i.append(t.cancel),e.prepend(i),this.footer=n.createElement(`div`),this.footer.className=`seams-voiceid-unlock-footer`,a([o(`span`,null,`Secured by`),` `,o(c,{})],this.footer),e.append(this.footer)}succeed(){let e=this.prompt.cancel;return e.animate([{opacity:1},{opacity:0}],{duration:150,easing:`ease-in`,fill:`forwards`}),{top:e.getBoundingClientRect().top,bottom:this.footer.getBoundingClientRect().top}}dispose(){a(null,this.prompt.cancel),a(null,this.footer)}};const y={activation:`Activate VoiceID`,unlock:`Unlock with VoiceID`,export:`Export keys with VoiceID`};var b=class{result;completion=new u;controller=new AbortController;element;activateButton;cancelButton;status;prompt;unlockFrame;autoStartUnlock;unlockSuccess;unmountCapture;measurement;phrase=t(null);state={kind:`preparing`};settlement=`closed`;expiryTimer=null;constructor(e,t,n,r,i){this.unlockSuccess=r;let a=y[t],o=document.getElementById(`root`)??document.body;if(!o)throw Error(`Wallet activation surface has no mount root.`);this.element=document.createElement(`section`),this.element.className=`seams-wallet-ui seams-auth-method-activation-surface seams-voiceid-activation-surface`,this.element.setAttribute(`role`,`dialog`),this.element.setAttribute(`aria-modal`,`true`),this.element.setAttribute(`aria-label`,a);let c=t===`unlock`&&r===`skip`&&i!==void 0;this.prompt=new s(document,a,this.phrase,c?`segments`:`ring`),this.element.append(this.prompt.element),this.unlockFrame=t===`unlock`&&!c?new v(this.element,this.prompt):null,this.autoStartUnlock=t===`unlock`&&i!==void 0,c&&(this.element.classList.add(`seams-voiceid-in-card`),this.prompt.cancel.hidden=!0),this.status=this.prompt.status,this.status.textContent=`Loading VoiceID…`,this.prompt.title.textContent=`VoiceID`,this.element.dataset.preparation=`loading`,this.activateButton=this.prompt.record,this.activateButton.textContent=a,this.activateButton.disabled=!0,this.activateButton.hidden=this.autoStartUnlock,this.activateButton.addEventListener(`click`,this.begin),this.cancelButton=this.prompt.cancel,this.cancelButton.addEventListener(`click`,this.cancel),this.element.addEventListener(`cancel`,this.cancel),this.unmountCapture=i?i(this.element):null,i||o.appendChild(this.element),this.measurement=!i&&n.kind===`wallet_iframe`?m({kind:`request_surface`,element:this.element,requestId:n.requestId,postMeasurement:n.postMeasurement}):null,this.cancelButton.focus(),this.result=this.completion.promise,this.initialize(e)}dispose(){this.measurement?.disconnect(),this.expiryTimer!==null&&clearTimeout(this.expiryTimer),this.element.removeEventListener(`cancel`,this.cancel),this.activateButton.removeEventListener(`click`,this.begin),this.cancelButton.removeEventListener(`click`,this.cancel),this.unlockFrame?.dispose(),this.prompt.dispose(),this.unmountCapture?this.unmountCapture(this.settlement):this.element.remove()}async initialize(e){try{await new Promise(C),this.controller.signal.throwIfAborted();let t=await e(this.controller.signal,{parent:this.element,progress:this.prompt.progress});if(this.state.kind===`closed`)return;if(t.kind===`management`){this.element.setAttribute(`aria-label`,`Manage voice`),this.element.dataset.preparation=`ready`,this.state={kind:`capturing`};let e=await t.action(this.controller.signal);this.controller.signal.throwIfAborted(),this.state={kind:`closed`},this.completion.resolve(e);return}let n=t.expiresAtMs===null?null:t.expiresAtMs-Date.now();if(n!==null&&n<=0)throw Error(`VoiceID challenge expired. Start unlock again.`);this.state={kind:`ready`,capture:t},this.expiryTimer=n===null?null:setTimeout(this.expire,n);for(let e of this.element.querySelectorAll(`.seams-voiceid-model-download`))e.remove();this.element.dataset.preparation=`ready`,this.prompt.title.textContent=`Read aloud`,this.status.textContent=`Read naturally, then pause.`,this.activateButton.disabled=!1,this.autoStartUnlock?this.begin():this.activateButton.focus()}catch(e){if(this.state.kind===`closed`)return;this.state={kind:`closed`},this.completion.reject(g(e))}}begin=()=>{if(this.state.kind!==`ready`)return;let e=this.state.capture;this.state={kind:`capturing`},this.perform(e)};async perform(a){this.activateButton.disabled=!0,this.status.textContent=`Opening microphone…`;try{let e=await a.action(this.controller.signal,this.prompt.capture,this.phrase);if(this.state.kind===`closed`)return;this.unlockFrame&&this.unlockSuccess===`show`&&await this.showUnlocked(this.unlockFrame),this.settlement=`succeeded`,this.state={kind:`closed`},this.completion.resolve(e)}catch(o){if(this.state.kind===`closed`)return;if(o instanceof r||o instanceof n||o instanceof i||o instanceof e){if(a.expiresAtMs!==null&&Date.now()>=a.expiresAtMs){this.expire();return}let e=this.phrase;this.phrase=t(e),this.prompt.setPhrase(this.phrase),this.state={kind:`ready`,capture:a},this.activateButton.hidden=!1,this.activateButton.textContent=`Try again`,this.prompt.ready(o.message),this.activateButton.focus();return}this.state={kind:`closed`},this.completion.reject(g(o))}}async showUnlocked(e){this.state={kind:`succeeding`},this.settlement=`succeeded`,this.expiryTimer!==null&&clearTimeout(this.expiryTimer),this.expiryTimer=null,this.cancelButton.disabled=!0;let t=performance.now(),n=d(`authenticated`);await this.prompt.succeed(n.headline,n.message,e.succeed());let r=Math.max(0,1300-(performance.now()-t));await this.element.animate([{opacity:1},{opacity:1,offset:r/(r+240),easing:`ease-in`},{opacity:0}],{duration:r+240,fill:`forwards`}).finished}cancel=()=>{this.state.kind===`closed`||this.state.kind===`succeeding`||(this.state={kind:`closed`},this.controller.abort(),this.completion.reject(new x))};expire=()=>{this.state.kind===`closed`||this.state.kind===`succeeding`||(this.state={kind:`closed`},this.controller.abort(),this.completion.reject(Error(`VoiceID challenge expired. Start unlock again.`)))}},x=class extends Error{constructor(){super(`VoiceID capture was cancelled.`),this.name=`VoiceIdCaptureCancelledError`}};async function S(e){let t=new b(e.prepare,e.purpose,e.measurement,e.unlockSuccess??`show`,e.mountCapture);try{return await t.result}finally{t.dispose()}}function C(e){requestAnimationFrame(w.bind(null,e))}function w(e){setTimeout(e,0)}const T=9;if(l!==9)throw Error(`VoiceID requires a matching Wallet host API.`);function E(e){return{unlock:A.bind(null,e),activate:M.bind(null,e),confirmOperation:O.bind(null,e),recordPhrase:D}}async function D(e){let t=await import(`./phrase-
|
|
81
|
+
`,nonce:h}),_.set(n,r)),r.ensureBase(),e.classList.add(`seams-voiceid-unlock`);let i=n.createElement(`div`);i.className=`seams-voiceid-unlock-header`,t.cancel.className=`seams-voiceid-unlock-back`,t.cancel.setAttribute(`aria-label`,`Back`),t.cancel.replaceChildren(),a(f(),t.cancel),i.append(t.cancel),e.prepend(i),this.footer=n.createElement(`div`),this.footer.className=`seams-voiceid-unlock-footer`,a([o(`span`,null,`Secured by`),` `,o(c,{})],this.footer),e.append(this.footer)}succeed(){let e=this.prompt.cancel;return e.animate([{opacity:1},{opacity:0}],{duration:150,easing:`ease-in`,fill:`forwards`}),{top:e.getBoundingClientRect().top,bottom:this.footer.getBoundingClientRect().top}}dispose(){a(null,this.prompt.cancel),a(null,this.footer)}};const y={activation:`Activate VoiceID`,unlock:`Unlock with VoiceID`,export:`Export keys with VoiceID`};var b=class{result;completion=new u;controller=new AbortController;element;activateButton;cancelButton;status;prompt;unlockFrame;autoStartUnlock;unlockSuccess;unmountCapture;measurement;phrase=t(null);state={kind:`preparing`};settlement=`closed`;expiryTimer=null;constructor(e,t,n,r,i){this.unlockSuccess=r;let a=y[t],o=document.getElementById(`root`)??document.body;if(!o)throw Error(`Wallet activation surface has no mount root.`);this.element=document.createElement(`section`),this.element.className=`seams-wallet-ui seams-auth-method-activation-surface seams-voiceid-activation-surface`,this.element.setAttribute(`role`,`dialog`),this.element.setAttribute(`aria-modal`,`true`),this.element.setAttribute(`aria-label`,a);let c=t===`unlock`&&r===`skip`&&i!==void 0;this.prompt=new s(document,a,this.phrase,c?`segments`:`ring`),this.element.append(this.prompt.element),this.unlockFrame=t===`unlock`&&!c?new v(this.element,this.prompt):null,this.autoStartUnlock=t===`unlock`&&i!==void 0,c&&(this.element.classList.add(`seams-voiceid-in-card`),this.prompt.cancel.hidden=!0),this.status=this.prompt.status,this.status.textContent=`Loading VoiceID…`,this.prompt.title.textContent=`VoiceID`,this.element.dataset.preparation=`loading`,this.activateButton=this.prompt.record,this.activateButton.textContent=a,this.activateButton.disabled=!0,this.activateButton.hidden=this.autoStartUnlock,this.activateButton.addEventListener(`click`,this.begin),this.cancelButton=this.prompt.cancel,this.cancelButton.addEventListener(`click`,this.cancel),this.element.addEventListener(`cancel`,this.cancel),this.unmountCapture=i?i(this.element):null,i||o.appendChild(this.element),this.measurement=!i&&n.kind===`wallet_iframe`?m({kind:`request_surface`,element:this.element,requestId:n.requestId,postMeasurement:n.postMeasurement}):null,this.cancelButton.focus(),this.result=this.completion.promise,this.initialize(e)}dispose(){this.measurement?.disconnect(),this.expiryTimer!==null&&clearTimeout(this.expiryTimer),this.element.removeEventListener(`cancel`,this.cancel),this.activateButton.removeEventListener(`click`,this.begin),this.cancelButton.removeEventListener(`click`,this.cancel),this.unlockFrame?.dispose(),this.prompt.dispose(),this.unmountCapture?this.unmountCapture(this.settlement):this.element.remove()}async initialize(e){try{await new Promise(C),this.controller.signal.throwIfAborted();let t=await e(this.controller.signal,{parent:this.element,progress:this.prompt.progress});if(this.state.kind===`closed`)return;if(t.kind===`management`){this.element.setAttribute(`aria-label`,`Manage voice`),this.element.dataset.preparation=`ready`,this.state={kind:`capturing`};let e=await t.action(this.controller.signal);this.controller.signal.throwIfAborted(),this.state={kind:`closed`},this.completion.resolve(e);return}let n=t.expiresAtMs===null?null:t.expiresAtMs-Date.now();if(n!==null&&n<=0)throw Error(`VoiceID challenge expired. Start unlock again.`);this.state={kind:`ready`,capture:t},this.expiryTimer=n===null?null:setTimeout(this.expire,n);for(let e of this.element.querySelectorAll(`.seams-voiceid-model-download`))e.remove();this.element.dataset.preparation=`ready`,this.prompt.title.textContent=`Read aloud`,this.status.textContent=`Read naturally, then pause.`,this.activateButton.disabled=!1,this.autoStartUnlock?this.begin():this.activateButton.focus()}catch(e){if(this.state.kind===`closed`)return;this.state={kind:`closed`},this.completion.reject(g(e))}}begin=()=>{if(this.state.kind!==`ready`)return;let e=this.state.capture;this.state={kind:`capturing`},this.perform(e)};async perform(a){this.activateButton.disabled=!0,this.status.textContent=`Opening microphone…`;try{let e=await a.action(this.controller.signal,this.prompt.capture,this.phrase);if(this.state.kind===`closed`)return;this.unlockFrame&&this.unlockSuccess===`show`&&await this.showUnlocked(this.unlockFrame),this.settlement=`succeeded`,this.state={kind:`closed`},this.completion.resolve(e)}catch(o){if(this.state.kind===`closed`)return;if(o instanceof r||o instanceof n||o instanceof i||o instanceof e){if(a.expiresAtMs!==null&&Date.now()>=a.expiresAtMs){this.expire();return}let e=this.phrase;this.phrase=t(e),this.prompt.setPhrase(this.phrase),this.state={kind:`ready`,capture:a},this.activateButton.hidden=!1,this.activateButton.textContent=`Try again`,this.prompt.ready(o.message),this.activateButton.focus();return}this.state={kind:`closed`},this.completion.reject(g(o))}}async showUnlocked(e){this.state={kind:`succeeding`},this.settlement=`succeeded`,this.expiryTimer!==null&&clearTimeout(this.expiryTimer),this.expiryTimer=null,this.cancelButton.disabled=!0;let t=performance.now(),n=d(`authenticated`);await this.prompt.succeed(n.headline,n.message,e.succeed());let r=Math.max(0,1300-(performance.now()-t));await this.element.animate([{opacity:1},{opacity:1,offset:r/(r+240),easing:`ease-in`},{opacity:0}],{duration:r+240,fill:`forwards`}).finished}cancel=()=>{this.state.kind===`closed`||this.state.kind===`succeeding`||(this.state={kind:`closed`},this.controller.abort(),this.completion.reject(new x))};expire=()=>{this.state.kind===`closed`||this.state.kind===`succeeding`||(this.state={kind:`closed`},this.controller.abort(),this.completion.reject(Error(`VoiceID challenge expired. Start unlock again.`)))}},x=class extends Error{constructor(){super(`VoiceID capture was cancelled.`),this.name=`VoiceIdCaptureCancelledError`}};async function S(e){let t=new b(e.prepare,e.purpose,e.measurement,e.unlockSuccess??`show`,e.mountCapture);try{return await t.result}finally{t.dispose()}}function C(e){requestAnimationFrame(w.bind(null,e))}function w(e){setTimeout(e,0)}const T=9;if(l!==9)throw Error(`VoiceID requires a matching Wallet host API.`);function E(e){return{unlock:A.bind(null,e),activate:M.bind(null,e),confirmOperation:O.bind(null,e),recordPhrase:D}}async function D(e){let t=await import(`./phrase-BtxLUoH-.js`);return e.signal.throwIfAborted(),await t.recordPhrase(e)}function O(e,t){return S({purpose:`export`,measurement:t.surfaceMeasurementBinding,prepare:k.bind(null,e,t)})}async function k(e,t,n,r){let i=await import(`./operation-CNp1Cd-f.js`);return n.throwIfAborted(),i.prepareOperationSurface(t,n,r.progress,e)}function A(e,t){return S({purpose:`unlock`,unlockSuccess:t.purpose===`step_up`?`skip`:`show`,measurement:t.surfaceMeasurementBinding,mountCapture:t.mountCapture,prepare:j.bind(null,e,t)})}async function j(e,t,n,r){let i=await import(`./unlock-D5el17OL.js`);return n.throwIfAborted(),i.prepareUnlockSurface(t,n,r.progress,e)}async function M(e,t){try{return await S({purpose:`activation`,measurement:t.surfaceMeasurementBinding,prepare:N.bind(null,e,t)})}catch(e){if(e instanceof x)return{kind:`cancelled`};throw e}}async function N(e,t,n,r){let i=await import(`./addVoiceId-DVmRzRfq.js`);return n.throwIfAborted(),i.prepareActivationSurface(t,n,r.parent,e)}export{E as createVoiceIdHostPlugin,T as hostApiVersion};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./prompt-
|
|
1
|
+
import"./prompt-v-LTC3EA.js";import{c as e,n as t,s as n}from"./deviceBridge-ClUeOYHs.js";async function r(t,r,a,o){let s=await t.prepareOperation(r);if(!await n(s.scope))throw Error(`Open Manage voice to import or record your enrollment on this device.`);await e(a,r,o),r.throwIfAborted();let c=await s.challenge(r);return r.throwIfAborted(),{kind:`recording`,expiresAtMs:c.expiresAtMs,action:i.bind(null,o,c)}}function i(e,n,r,i,a){return n.complete(t.bind(null,e,{onCapture:i,phrase:a}),r)}export{r as prepareOperationSurface};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{d as e,f as t,m as n,p as r}from"./prompt-
|
|
1
|
+
import{d as e,f as t,m as n,p as r}from"./prompt-v-LTC3EA.js";var i=class extends Error{constructor(e){super(a(e)),this.name=`VoiceSpeakerMismatchError`}};function a(e){return e.microphoneSelection===`replacement`?`Your microphone changed to ${e.microphone}. Reconnect your usual microphone or try again.`:e.noise===`high`?`Your voice did not match. Background noise is high. Move closer and try again.`:`Your voice did not match. Read the next sentence naturally and try again.`}const o=`[PAD].[UNK].[CLS].[SEP].[MASK].'.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.##i.##s.##r.##o.##b.##n.##g.##m.##e.##d.##t.##a.##u.##p.##x.##c.##l.##z.##y.##v.##k.##h.##f.##q.##w.##j.th.the.##er.##nd.##in.##ed.##ou.##at.##en.and.##or.##es.to.of.##on.##is.##ing.##ar.##it.##as.##an.##ll.in.##re.wh.he.##om.be.ha.##le.##ot.##ow.##ic.##ut.it.##ld.that.sh.##ly.was.##gh.##id.##se.on.##ve.##et.##ent.you.##im.##st.##ce.##ith.for.##ir.##ion.as.##ay.his.##al.with.##ur.st.##ter.her.##ver.##ch.re.##ad.##ght.an.not.is.had.sa.at.##oo.##her.but.##ould.she.##ct.##ess.fr.se.##am.pr.we.him.so.##ill.##ain.su.##ight.me.##ere.##all.##ke.##il.de.my.they.all.##est.ch.##ich.ne.by.have.##ome.##pp.##ck.li.this.do.##ore.con.##us.which.##ri.##ul.up.said.from.##th.##ard.##ge.##ra.or.one.no.ex.were.there.##os.##pe.man.##ble.who.al.##ant.##ie.##ous.##ust.##ation.fe.##and.them.##ers.##lf.when.##ind.##ast.go.##ood.kn.##un.##our.##ist.##em.are.##out.would.##art.what.le.their.##ong.en.if.un.##if.com.##ound.ab.out.wor.##ol.will.int.br.##ak.mis.##ate.##op.##um.##ough.##la.##itt.ar.##ook.##ish.##one.##ap.been.##own.##ame.then.##ven`.split(`.`),s=new n({path:`/sdk/voiceid/aurora-int8.onnx`,sha256:`83ed6f3856458cd96d49a70d8c5175aeec18ba8c184e5367e089cd424eebefd6`,bytes:1342384,label:`Phrase recognition`}),c=new n({path:`/sdk/voiceid/citrinet-int8.onnx`,sha256:`875f58df0e2a593017ac9550c8fab68c4343cd1fbb2a042290450aa125441ed5`,bytes:10483704,label:`Phrase recognition`});function l(e){switch(e){case`aurora`:return s;case`citrinet`:return c;default:return f(e)}}let u=null;function d(t){return p(e,t)}function f(e){throw Error(`Unexpected VoiceID state: ${String(e)}`)}function p(e,t){let n=e.filter(m.bind(null,t)),r=n.filter(m.bind(null,u)),i=r.length>0?r:n;if(i.length===0)throw Error(`No fresh VoiceID challenge is available.`);let a=new Uint32Array(1);crypto.getRandomValues(a);let o=i[a[0]%i.length];return u=o,o}function m(e,t){return t!==e}const h=new Map([[`sea`,`see`],[`here`,`hear`],[`meat`,`meet`],[`whether`,`weather`],[`son`,`sun`],[`wood`,`would`],[`two`,`to`],[`too`,`to`],[`eye`,`i`],[`sail`,`sale`]]),g=new Set([`no`,`not`,`never`,`cannot`,`can't`,`don't`,`doesn't`,`isn't`,`aren't`,`wasn't`,`weren't`,`won't`,`wouldn't`,`shouldn't`,`without`]);function _(e){return e.toLowerCase().replace(/’/g,`'`).match(/[a-z0-9]+(?:'[a-z]+)?/g)??[]}function v(e){return e!==`a`&&e!==`an`&&e!==`the`}function y(e){return h.get(e)??e}function b(e){return e.filter(v).map(y).join(` `).replace(/\bto day\b/g,`today`)}function x(e){return g.has(e)}function S(e,t){let n=Array.from({length:t.length+1},C);for(let r=0;r<e.length;r+=1){let i=[r+1];for(let a=0;a<t.length;a+=1)i.push(Math.min(i[a]+1,n[a+1]+1,n[a]+(e[r]===t[a]?0:1)));n=i}return n[t.length]}function C(e,t){return t}function w(e){let t=_(e),n=b(t);if(!n)return{kind:`empty`};let i=r[0],a=1/0,o=1/0;for(let e of r){let t=b(_(e)),r=S(n,t)/Math.max(n.length,t.length);r<a?(o=a,a=r,i=e):o=Math.min(o,r)}let s=o-a;if(t.filter(x).join(` `)!==_(i).filter(x).join(` `))return{kind:`uncertain`,candidate:i,difference:a,margin:s,decodedText:e,reason:`negated`};let c=_(i).length;return a>.3||Math.abs(t.length-c)>2?{kind:`uncertain`,candidate:i,difference:a,margin:s,decodedText:e,reason:`different`}:s<.1?{kind:`uncertain`,candidate:i,difference:a,margin:s,decodedText:e,reason:`ambiguous`}:{kind:`recognized`,phrase:i,difference:a,margin:s,decodedText:e}}var T=class extends Error{constructor(){super(`The phrase was not clear. Try the new phrase at your normal pace.`),this.name=`VoicePhraseMismatchError`}};function E(e,t,n){let r=n===`aurora`?0:256,i=[],a=-1;for(let n=0;n<t;n+=1){let t=n*257,o=-1/0,s=r;for(let n=0;n<257;n+=1){let r=e[t+n];if(!Number.isFinite(r))throw Error(`Phrase model returned invalid scores.`);r>o&&(o=r,s=n)}s!==r&&s!==a&&i.push(s),a=s}if(i.length===0)return``;switch(n){case`aurora`:return i.map(k).join(``).replace(/▁/g,` `).trim().replace(/\s+/g,` `);case`citrinet`:return D(i);default:return f(n)}}function D(e){let t=``,n=!1;for(let r of e){let e=o[r];if(!e.startsWith(`[`)){if(e.startsWith(`##`))t+=e.slice(2);else if(e===`'`){t+=e,n=!0;continue}else t+=(n||t.length===0?``:` `)+e;n=!1}}return t.trim()}function O(e,t){let n=w(e);return n.kind===`recognized`&&n.phrase===t?{kind:`matched`,recognition:n}:{kind:`mismatch`,recognition:n}}function k(e){return t[e]}async function A(e,t,n){let r=await l(n).prepare(),i=new(await(import(`./ort.wasm.bundle.min-BH_0rOm8.js`))).Tensor(`float32`,e,[1,e.length]);try{let e=await r.run({samples:i});try{let r=e.logits;if(!r||!(r.data instanceof Float32Array)||r.dims.length!==3||r.dims[0]!==1||r.dims[2]!==257||r.data.length!==r.dims[1]*257)throw Error(`Phrase model returned an invalid result.`);return O(E(r.data,r.dims[1],n),t)}finally{for(let t of Object.values(e))t.dispose()}}finally{i.dispose()}}export{i as a,d as i,A as n,l as r,T as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,c as t,l as n,p as r,t as i}from"./prompt-
|
|
1
|
+
import{a as e,c as t,l as n,p as r,t as i}from"./prompt-v-LTC3EA.js";import{WorkerDeferred as a,createWalletIframeSurfaceMeasurementReporter as o,toError as s}from"../voiceid-host.js";const c=`Say this with your voice`;async function l(e){let t=new u(e.sentence,e.surfaceMeasurementBinding,e.signal);try{return await t.result}finally{t.dispose()}}var u=class{completion=new a;result=this.completion.promise;controller=new AbortController;element;prompt;measurement;recording=!1;settled=!1;constructor(e,t,n){this.outer=n;let a=document.getElementById(`root`)??document.body;this.element=document.createElement(`section`),this.element.className=`seams-wallet-ui seams-auth-method-activation-surface seams-voiceid-activation-surface`,this.element.setAttribute(`role`,`dialog`),this.element.setAttribute(`aria-modal`,`true`),this.element.setAttribute(`aria-label`,c),this.prompt=new i(document,c,r[0]),this.prompt.title.textContent=`Say this sentence`,this.prompt.phrase.textContent=/[.!?]$/.test(e)?e:`${e}.`,delete this.prompt.phrase.dataset.voiceidPhrase,this.prompt.status.textContent=`Read it naturally, then pause.`,this.prompt.record.textContent=`Record`,this.element.append(this.prompt.element),this.prompt.record.addEventListener(`click`,this.record),this.prompt.cancel.addEventListener(`click`,this.cancel),this.element.addEventListener(`cancel`,this.cancel),n.addEventListener(`abort`,this.cancel),a.appendChild(this.element),this.measurement=t.kind===`wallet_iframe`?o({kind:`request_surface`,element:this.element,requestId:t.requestId,postMeasurement:t.postMeasurement}):null,this.prompt.record.focus(),n.aborted&&this.cancel()}dispose(){this.controller.abort(),this.measurement?.disconnect(),this.outer.removeEventListener(`abort`,this.cancel),this.element.removeEventListener(`cancel`,this.cancel),this.prompt.record.removeEventListener(`click`,this.record),this.prompt.cancel.removeEventListener(`click`,this.cancel),this.prompt.dispose(),this.element.remove()}record=()=>{this.recording||this.settled||(this.recording=!0,this.prompt.record.disabled=!0,this.prompt.status.textContent=`Opening microphone…`,this.attempt())};async attempt(){try{let n=await e(this.controller.signal,this.prompt.capture),r=performance.now();if(this.settled){n.samples?.fill(0);return}if(n.kind===`insufficient_audio`){this.retry(t(n.quality));return}this.settle({kind:`recorded`,samples:n.samples,endOfSpeechAt:r})}catch(e){if(this.settled)return;if(e instanceof n){this.retry(e.message);return}this.settled=!0,this.completion.reject(s(e))}}retry(e){this.recording=!1,this.prompt.record.textContent=`Try again`,this.prompt.ready(e),this.prompt.record.focus()}settle(e){this.settled||(this.settled=!0,this.completion.resolve(e))}cancel=()=>{this.controller.abort(),this.settle({kind:`cancelled`})}};export{l as recordPhrase};
|
|
@@ -326,6 +326,11 @@ ${Ae.split(`{id}`).join(Le)}`:rn}),q(`div`,{...Fe,ref:cn,"data-voice-beam":Le,"d
|
|
|
326
326
|
@starting-style {
|
|
327
327
|
.seams-voiceid-prompt { opacity: 0; transform: translateY(4px); }
|
|
328
328
|
}
|
|
329
|
+
/* Each line owns its row. The download overlays rows 3-5; an auto-placed line would move to new rows. */
|
|
330
|
+
.seams-voiceid-prompt > h2 { grid-area: 1 / 1; }
|
|
331
|
+
.seams-voiceid-prompt > .seams-voiceid-phrase { grid-area: 2 / 1; }
|
|
332
|
+
.seams-voiceid-prompt > .seams-voiceid-ribbon { grid-area: 3 / 1; }
|
|
333
|
+
.seams-voiceid-prompt > .seams-voiceid-status { grid-area: 4 / 1; }
|
|
329
334
|
.seams-voiceid-progress-slot { grid-row: 5; grid-column: 1; min-width: 0; align-self: center; }
|
|
330
335
|
.seams-voiceid-progress-slot:empty { visibility: hidden; }
|
|
331
336
|
.seams-voiceid-activation-surface[data-preparation="loading"] .seams-voiceid-record-slot { visibility: hidden; }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{s as e}from"./prompt-
|
|
1
|
+
import{s as e}from"./prompt-v-LTC3EA.js";import{c as t,r as n,s as r}from"./deviceBridge-ClUeOYHs.js";async function i(e,n,i,o){let s=await e.prepareUnlock(n),c=s.scope;if(!await r(c))throw Error(`Unlock with a passkey, then open Manage voice to import or record your enrollment.`);await t(i,n,o),n.throwIfAborted();let l=await s.challenge(n),u={challenge:l,initiation:e.mountCapture?`hosted_menu`:`sdk_request`};return n.throwIfAborted(),{kind:`recording`,expiresAtMs:l.expiresAtMs,action:a.bind(null,o,u)}}async function a(t,r,i,a,s){switch(r.initiation){case`sdk_request`:e();break;case`hosted_menu`:break;default:return o(r.initiation)}return r.challenge.complete(n.bind(null,t,{onCapture:a,phrase:s}),i)}function o(e){throw Error(`Unexpected VoiceID initiation: ${String(e)}`)}export{i as prepareUnlockSurface};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seams/voiceid",
|
|
3
|
-
"version": "0.56.
|
|
3
|
+
"version": "0.56.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Optional browser VoiceID authentication for Seams Wallet",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"voice-glow": "0.2.1"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
|
-
"@seams/wallet": "0.56.
|
|
53
|
+
"@seams/wallet": "0.56.2",
|
|
54
54
|
"react": ">=19.0.0",
|
|
55
55
|
"react-dom": ">=19.0.0"
|
|
56
56
|
},
|