diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 9508e5d..cbc34b2 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -25,6 +25,11 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - - uses: Ortus-Solutions/commandbox-action@v1.0.2 - with: - cmd: run-script format:check + - name: Setup CommandBox CLI + uses: Ortus-Solutions/setup-commandbox@v2.0.1 + + - name: Install pinned formatter + run: box install commandbox-cfformat@0.21.0 + + - name: Check formatting + run: box run-script format:check diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6ec41c8..84d0ac4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -84,10 +84,22 @@ jobs: box package set dependencies.coldbox=${{ matrix.coldboxVersion }} box install + - name: Setup Node for the envelope receiver + uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Start local envelope receiver + run: | + mkdir -p test-harness/tests/results + node test-harness/support/receiver.mjs > test-harness/tests/results/receiver.log 2>&1 & + echo $! > test-harness/tests/results/receiver.pid + curl --fail --retry 10 --retry-connrefused --retry-delay 1 http://127.0.0.1:60320/state + - name: Start ${{ matrix.cfengine }} Server run: | box server start serverConfigFile="server-${{ matrix.cfengine }}.json" --noSaveSettings --debug - curl http://127.0.0.1:60299 + curl --fail-with-body http://127.0.0.1:60299/health.cfm - name: Run Tests run: | @@ -101,6 +113,16 @@ jobs: junit_files: test-harness/tests/results/**/*.xml check_name: "${{ matrix.cfengine }} ColdBox ${{ matrix.coldboxVersion }} Test Results" + - name: Stop local envelope receiver + if: always() + run: | + if [ -f test-harness/tests/results/receiver.pid ]; then + receiver_pid="$(cat test-harness/tests/results/receiver.pid)" + if kill -0 "$receiver_pid" 2>/dev/null; then + kill "$receiver_pid" + fi + fi + - name: Upload Test Results to Artifacts if: always() uses: actions/upload-artifact@v4 diff --git a/.gitignore b/.gitignore index df56d36..a02e184 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,15 @@ test-harness/.env # Local server configs (test artifacts) server-sentry-*.json test-harness/server-sentry-*.json + +/modules +/test-harness/coldbox +/test-harness/testbox +/test-harness/sentry +/browser/node_modules/ + +/test-harness/provider-feedback.html +/test-harness/tests/provider-proof.cfm +/test-harness/lucee-local-cache/ + +/test-harness/tests/provider-feedback-native.cfm diff --git a/ModuleConfig.cfc b/ModuleConfig.cfc index 8e32d48..34ebb00 100644 --- a/ModuleConfig.cfc +++ b/ModuleConfig.cfc @@ -97,6 +97,15 @@ component { } } + settings.append( + createObject( "component", "#moduleMapping#.models.telemetry.Observability" ).defaults(), + false + ); + interceptors = [ + { class : "#moduleMapping#.interceptors.QueueObservability" }, + { class : "#moduleMapping#.interceptors.Observability" }, + { class : "#moduleMapping#.interceptors.QueryObservability" } + ]; interceptorSettings = { customInterceptionPoints : [ "onSentryEventCapture" ] }; } @@ -105,9 +114,30 @@ component { */ function onLoad(){ // Incorporate defaults into settings + if ( settings.queryAdapter == "auto" || settings.queryAdapter == "boxlang" ) { + wirebox + .getInstance( "SentryService@sentry" ) + .getObservability() + .configureQueryInstrumentation( getApplicationMetadata().name ); + } + binder.mapDSL( "sentryCache", "#moduleMapping#.models.dsl.CacheDSL" ); + wirebox.registerDSL( "sentryCache", "#moduleMapping#.models.dsl.CacheDSL" ); settings.scrubFields.addAll( SCRUB_FIELDS ); settings.scrubHeaders.addAll( SCRUB_HEADERS ); + if ( settings.enableStructuredLogBoxAppender && settings.enableLogs ) { + logBox.registerAppender( + name = "sentry_structured", + class = "#moduleMapping#.models.StructuredLogAppender", + properties = { "messageMode" : settings.logMessageMode }, + levelMin = 0, + levelMax = 3 + ); + logBox + .getRootLogger() + .addAppender( logBox.getAppendersMap( "sentry_structured" )[ "sentry_structured" ] ); + } + // Load the LogBox Appenders if ( settings.enableLogBoxAppender ) { loadAppenders(); @@ -118,6 +148,9 @@ component { * Fired when the module is unregistered and unloaded */ function onUnload(){ + if ( wirebox.containsInstance( "SentryService@sentry" ) ) { + wirebox.getInstance( "SentryService@sentry" ).shutdown(); + } } /** diff --git a/box.json b/box.json index 42c8a29..4a0cd2c 100644 --- a/box.json +++ b/box.json @@ -1,55 +1,59 @@ { - "name":"Sentry", - "author":"Ortus Solutions ", - "version":"2.1.7", - "slug":"sentry", - "type":"modules", - "homepage":"https://github.com/coldbox-modules/sentry", - "documentation":"https://github.com/coldbox-modules/sentry", - "repository":{ - "type":"git", - "url":"https://github.com/coldbox-modules/sentry" + "name": "Sentry", + "author": "Ortus Solutions ", + "version": "3.0.0-alpha.1", + "slug": "sentry", + "type": "modules", + "homepage": "https://github.com/coldbox-modules/sentry", + "documentation": "https://github.com/coldbox-modules/sentry", + "repository": { + "type": "git", + "url": "https://github.com/coldbox-modules/sentry" }, - "bugs":"https://github.com/coldbox-modules/sentry/issues", - "shortDescription":"A module to log messages and send bug reports to Sentry", - "license":[ + "bugs": "https://github.com/coldbox-modules/sentry/issues", + "shortDescription": "A module to log messages and send bug reports to Sentry", + "license": [ { - "type":"Apache2", - "url":"http://www.apache.org/licenses/LICENSE-2.0.html" + "type": "Apache2", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" } ], - "contributors":[], - "dependencies":{ - "funclinenums":"^1.1.0" + "contributors": [], + "dependencies": { + "funclinenums": "^1.1.0" }, - "devDependencies":{}, - "installPaths":{ - "funclinenums":"modules/funclinenums/" + "devDependencies": {}, + "installPaths": { + "funclinenums": "modules/funclinenums/" }, - "ignore":[ + "ignore": [ "**/.*", "test-harness", - "*.md" + "*.md", + "browser/node_modules", + "browser/tests", + "browser/*config*", + "browser/build.mjs" ], - "scripts":{ - "build:module":"task run taskFile=build/Build.cfc :projectName=`package show slug` :version=`package show version`", - "build:docs":"task run taskFile=build/Build.cfc target=docs :projectName=`package show slug` :version=`package show version`", - "install:dependencies":"install --force && cd test-harness && install --force", - "release":"recipe build/release.boxr", - "format":"cfformat run helpers,models,interceptors,handlers,test-harness/tests/,ModuleConfig.cfc --overwrite", - "format:watch":"cfformat watch helpers,models,interceptors,handlers,test-harness/tests/,ModuleConfig.cfc ./.cfformat.json", - "format:check":"cfformat check helpers,models,interceptors,handlers,test-harness/tests/,ModuleConfig.cfc ./.cfformat.json", - "start:lucee":"server start serverConfigFile=server-lucee@5.json", - "start:2018":"server start serverConfigFile=server-adobe@2018.json", - "start:2021":"server start serverConfigFile=server-adobe@2021.json", - "stop:lucee":"server stop serverConfigFile=server-lucee@5.json", - "stop:2018":"server stop serverConfigFile=server-adobe@2018.json", - "stop:2021":"server stop serverConfigFile=server-adobe@2021.json", - "logs:lucee":"server log serverConfigFile=server-lucee@5.json --follow", - "logs:2018":"server log serverConfigFile=server-adobe@2018.json --follow", - "logs:2021":"server log serverConfigFile=server-adobe@2021.json --follow" + "scripts": { + "build:module": "task run taskFile=build/Build.cfc :projectName=`package show slug` :version=`package show version`", + "build:docs": "task run taskFile=build/Build.cfc target=docs :projectName=`package show slug` :version=`package show version`", + "install:dependencies": "install --force && cd test-harness && install --force", + "release": "recipe build/release.boxr", + "format": "cfformat run helpers,models,interceptors,handlers,test-harness/tests/,test-harness/Application.cfc,ModuleConfig.cfc --overwrite", + "format:watch": "cfformat watch helpers,models,interceptors,handlers,test-harness/tests/,test-harness/Application.cfc,ModuleConfig.cfc ./.cfformat.json", + "format:check": "cfformat check helpers,models,interceptors,handlers,test-harness/tests/,test-harness/Application.cfc,ModuleConfig.cfc ./.cfformat.json", + "start:lucee": "server start serverConfigFile=server-lucee@5.json", + "start:2018": "server start serverConfigFile=server-adobe@2018.json", + "start:2021": "server start serverConfigFile=server-adobe@2021.json", + "stop:lucee": "server stop serverConfigFile=server-lucee@5.json", + "stop:2018": "server stop serverConfigFile=server-adobe@2018.json", + "stop:2021": "server stop serverConfigFile=server-adobe@2021.json", + "logs:lucee": "server log serverConfigFile=server-lucee@5.json --follow", + "logs:2018": "server log serverConfigFile=server-adobe@2018.json --follow", + "logs:2021": "server log serverConfigFile=server-adobe@2021.json --follow" }, - "testbox":{ - "runner":"http://localhost:60299/tests/runner.cfm" + "testbox": { + "runner": "http://localhost:60299/tests/runner.cfm" } } diff --git a/browser/build.mjs b/browser/build.mjs new file mode 100644 index 0000000..6e4a576 --- /dev/null +++ b/browser/build.mjs @@ -0,0 +1,5 @@ +import { rmSync } from "node:fs"; +rmSync("dist", { recursive: true, force: true }); +import { build } from 'esbuild'; +await build({ entryPoints: ['src/index.ts'], bundle: true, format: 'esm', splitting: true, outdir: 'dist/esm', target: 'es2022', minify: true }); +await build({ entryPoints: ['src/script.ts'], bundle: true, format: 'iife', outfile: 'dist/sentry-box.js', target: 'es2022', minify: true }); diff --git a/browser/dist/esm/chunk-5LBAMSSV.js b/browser/dist/esm/chunk-5LBAMSSV.js new file mode 100644 index 0000000..7916a5b --- /dev/null +++ b/browser/dist/esm/chunk-5LBAMSSV.js @@ -0,0 +1,29 @@ +var At="10.74.0";var T=globalThis;function Ue(){return Ut(T),T}function Ut(e){let t=e.__SENTRY__=e.__SENTRY__||{};return t.version=t.version||At,t[At]=t[At]||{}}function gt(e,t,r=T){let n=r.__SENTRY__=r.__SENTRY__||{},i=n[At]=n[At]||{};return i[e]||(i[e]=t())}var _=typeof __SENTRY_DEBUG__>"u"||__SENTRY_DEBUG__;var Gi=["debug","info","warn","error","log","assert","trace"],sg="Sentry Logger ",vr={};function Oe(e){if(!("console"in T))return e();let t=T.console,r={},n=Object.keys(vr);n.forEach(i=>{let s=vr[i];r[i]=t[i],t[i]=s});try{return e()}finally{n.forEach(i=>{t[i]=r[i]})}}function ag(){Na().enabled=!0}function og(){Na().enabled=!1}function ol(){return Na().enabled}function cg(...e){ka("log",...e)}function lg(...e){ka("warn",...e)}function pg(...e){ka("error",...e)}function ka(e,...t){_&&ol()&&Oe(()=>{T.console[e](`${sg}[${e}]:`,...t)})}function Na(){return _?gt("loggerSettings",()=>({enabled:!1})):{enabled:!1}}var f={enable:ag,disable:og,isEnabled:ol,log:cg,warn:lg,error:pg};var cl=Object.prototype.toString;function we(e){switch(cl.call(e)){case"[object Error]":case"[object Exception]":case"[object DOMException]":case"[object WebAssembly.Exception]":return!0;default:return Er(e,Error)}}function Vr(e,t){return cl.call(e)===`[object ${t}]`}function jr(e){return Vr(e,"ErrorEvent")}function wn(e){return Vr(e,"DOMError")}function Wi(e){return Vr(e,"DOMException")}function Ce(e){return Vr(e,"String")}function er(e){return typeof e=="object"&&e!==null&&"__sentry_template_string__"in e&&"__sentry_template_values__"in e}function ze(e){return e===null||er(e)||typeof e!="object"&&typeof e!="function"}function Rt(e){return Vr(e,"Object")}function Ze(e){return typeof e=="object"&&e!==null}function tr(e){return typeof Event<"u"&&Er(e,Event)}function Yi(e){return Vr(e,"RegExp")}function ft(e){return!!(e?.then&&typeof e.then=="function")}function Er(e,t){try{return e instanceof t}catch{return!1}}function Cn(e){return typeof Request<"u"&&Er(e,Request)}function fe(e,t,r){if(!(t in e))return;let n=e[t];if(typeof n!="function")return;let i=r(n);typeof i=="function"&&Mn(i,n);try{e[t]=i}catch{_&&f.log(`Failed to replace method "${t}" in object`,e)}}function ne(e,t,r){try{Object.defineProperty(e,t,{value:r,writable:!0,configurable:!0})}catch{_&&f.log(`Failed to add non-enumerable property "${String(t)}" to object`,e)}}function Mn(e,t){try{let r=t.prototype||{};e.prototype=t.prototype=r,ne(e,"__sentry_original__",t)}catch{}}function rr(e){return e.__sentry_original__}function Ln(e){if(we(e))return{message:e.message,name:e.name,stack:e.stack,...ll(e)};if(tr(e)){let{type:t,target:r,currentTarget:n,detail:i}=e;return{type:t,target:r,currentTarget:n,...i?{detail:i}:{},...ll(e)}}return e}function ll(e){return Ze(e)?Object.fromEntries(Object.entries(e)):{}}function zi(e){let t=Object.keys(Ln(e));return t.sort(),t[0]?t.join(", "):"[object has no keys]"}var $r;function Tr(e){if($r!==void 0)return $r?$r(e):e();let t=Symbol.for("__SENTRY_SAFE_RANDOM_ID_WRAPPER__"),r=T;return t in r&&typeof r[t]=="function"?($r=r[t],$r(e)):($r=null,e())}function nt(){return Tr(()=>Math.random())}function it(){return Tr(()=>Date.now())}var ug=Symbol.for("sentry.skipNormalization"),dg=Symbol.for("sentry.overrideNormalizationDepth");function pl(e){return!!e[ug]}function ul(e){let t=e[dg];return typeof t=="number"?t:void 0}var dl=/\(error: (.*)\)/,ml=/captureMessage|captureException/;function Pn(...e){let t=e.sort((r,n)=>r[0]-n[0]).map(r=>r[1]);return(r,n=0,i=0)=>{let s=[],a=r.split(` +`);for(let c=n;c1024&&(o=o.slice(0,1024));let l=dl.test(o)?o.replace(dl,"$1"):o;if(!l.includes("Error: ")){for(let u of t){let p=u(l);if(p){s.push(p);break}}if(s.length>=50+i)break}}return Ca(s.slice(i))}}function ji(e){return Array.isArray(e)?Pn(...e):e}function Ca(e){if(!e.length)return[];let t=Array.from(e);return/sentryWrapped/.test(Vi(t).function||"")&&t.pop(),t.reverse(),ml.test(Vi(t).function||"")&&(t.pop(),ml.test(Vi(t).function||"")&&t.pop()),t.slice(0,50).map(r=>({...r,filename:r.filename||Vi(t).filename,function:r.function||"?"}))}function Vi(e){return e[e.length-1]||{}}var wa="";function Fe(e){try{return!e||typeof e!="function"?wa:e.name||wa}catch{return wa}}function Dn(e){let t=e.exception;if(t){let r=[];try{return t.values.forEach(n=>{n.stacktrace.frames&&r.push(...n.stacktrace.frames)}),r}catch{return}}}var Ma;function $i(e){Ma=e}function Me(e,t=100,r=1/0){try{return La("",e,t,r)}catch(n){return{ERROR:`**non-serializable** (${n})`}}}function Un(e,t=3,r=100*1024){let n=Me(e,t);return fg(n)>r?Un(e,t-1,r):n}function La(e,t,r=1/0,n=1/0,i=hg()){let[s,a]=i;if(t==null||["boolean","string"].includes(typeof t)||typeof t=="number"&&Number.isFinite(t))return t;let c=Pa(e,t);if(!c.startsWith("[object "))return c;if(pl(t))return t;let o=ul(t),l=o!==void 0?o:r;if(l===0)return c.replace("object ","");if(s(t))return"[Circular ~]";let u=t;if(u&&typeof u.toJSON=="function")try{let g=u.toJSON();return La("",g,l-1,n,i)}catch{}let p=Array.isArray(t)?[]:{},d=0,m=Ln(t);for(let g in m){if(!Object.prototype.hasOwnProperty.call(m,g))continue;if(d>=n){p[g]="[MaxProperties ~]";break}let h=m[g];p[g]=La(g,h,l-1,n,i),d++}return a(t),p}function Pa(e,t){try{if(Ma){let n=Ma(t);if(n)return n}return typeof global<"u"&&t===global?"[Global]":typeof t=="number"&&!Number.isFinite(t)?`[${t}]`:typeof t=="function"?`[Function: ${Fe(t)}]`:typeof t=="symbol"?`[${String(t)}]`:typeof t=="bigint"?`[BigInt: ${String(t)}]`:`[object ${mg(t)}]`}catch(r){return`**non-serializable** (${r})`}}function mg(e){let t=Object.getPrototypeOf(e);return t?.constructor?t.constructor.name:"null prototype"}function gg(e){return~-encodeURI(e).split(/%..|./).length}function fg(e){return gg(JSON.stringify(e))}function hg(){let e=new WeakSet;function t(n){return e.has(n)?!0:(e.add(n),!1)}function r(n){e.delete(n)}return[t,r]}function Ir(e,t=0){return typeof e!="string"||t===0||e.length<=t?e:`${e.slice(0,t)}...`}function Fn(e,t){if(!Array.isArray(e))return"";let r=[];for(let n=0;ne.randomUUID()).replace(/-/g,"")}catch{}return Da||(Da="10000000100040008000"+1e11),Da.replace(/[018]/g,t=>(t^(_g()&15)>>t/4).toString(16))}function gl(e){return e.exception?.values?.[0]}function ht(e){let{message:t,event_id:r}=e;if(t)return t;let n=gl(e);return n?n.type&&n.value?`${n.type}: ${n.value}`:n.type||n.value||r||"":r||""}function Ar(e,t,r){let n=e.exception=e.exception||{},i=n.values=n.values||[],s=i[0]=i[0]||{};s.value||(s.value=t||""),s.type||(s.type=r||"Error")}function st(e,t){let r=gl(e);if(!r)return;let n={type:"generic",handled:!0},i=r.mechanism;if(r.mechanism={...n,...i,...t},t&&"data"in t){let s={...i?.data,...t.data};r.mechanism.data=s}}function Bn(e){if(Ua(e))return!0;try{ne(e,"__sentry_captured__",!0)}catch{}return!1}function Ua(e){try{return e.__sentry_captured__}catch{}}var hl=1e3;function Ve(){return it()/hl}function yg(){let{performance:e}=T;if(!e?.now||!e.timeOrigin)return Ve;let t=e.timeOrigin;return()=>(t+Tr(()=>e.now()))/hl}var fl;function Q(){return(fl??(fl=yg()))()}var Fa=null;function Sg(){let{performance:e}=T;if(!e?.now)return;let t=3e5,r=Tr(()=>e.now()),n=it(),i=e.timeOrigin;if(typeof i=="number"&&Math.abs(i+r-n)vg(r)};return e&&Ft(r,e),r}function Ft(e,t={}){if(t.user&&(!e.ipAddress&&t.user.ip_address&&(e.ipAddress=t.user.ip_address),!e.did&&!t.did&&(e.did=t.user.id||t.user.email||t.user.username)),e.timestamp=t.timestamp||Q(),t.abnormal_mechanism&&(e.abnormal_mechanism=t.abnormal_mechanism),t.ignoreDuration&&(e.ignoreDuration=t.ignoreDuration),t.sid&&(e.sid=t.sid.length===32?t.sid:he()),t.init!==void 0&&(e.init=t.init),!e.did&&t.did&&(e.did=`${t.did}`),typeof t.started=="number"&&(e.started=t.started),e.ignoreDuration)e.duration=void 0;else if(typeof t.duration=="number")e.duration=t.duration;else{let r=e.timestamp-e.started;e.duration=r>=0?r:0}t.release&&(e.release=t.release),t.environment&&(e.environment=t.environment),!e.ipAddress&&t.ipAddress&&(e.ipAddress=t.ipAddress),!e.userAgent&&t.userAgent&&(e.userAgent=t.userAgent),typeof t.errors=="number"&&(e.errors=t.errors),t.status&&(e.status=t.status)}function _l(e,t){let r={};t?r={status:t}:e.status==="ok"&&(r={status:"exited"}),Ft(e,r)}function vg(e){return{sid:`${e.sid}`,init:e.init,started:new Date(e.started*1e3).toISOString(),timestamp:new Date(e.timestamp*1e3).toISOString(),status:e.status,errors:e.errors,did:typeof e.did=="number"||typeof e.did=="string"?`${e.did}`:void 0,duration:e.duration,abnormal_mechanism:e.abnormal_mechanism,attrs:{release:e.release,environment:e.environment,ip_address:e.ipAddress,user_agent:e.userAgent}}}function ir(e,t,r=2){if(!t||typeof t!="object"||r<=0)return t;if(e&&Object.keys(t).length===0)return e;let n={...e};for(let i in t)Object.prototype.hasOwnProperty.call(t,i)&&(n[i]=ir(n[i],t[i],r-1));return n}function je(){return he()}function Be(){return he().substring(16)}function Ki(e){try{let t=T.WeakRef;if(typeof t=="function")return new t(e)}catch{}return e}function Xi(e){if(e){if(typeof e=="object"&&"deref"in e&&typeof e.deref=="function")try{return e.deref()}catch{return}return e}}var Ba="_sentrySpan";function sr(e,t){t?ne(e,Ba,Ki(t)):delete e[Ba]}function Rr(e){return Xi(e[Ba])}var Eg=100,$e=class e{constructor(){this._notifyingListeners=!1,this._scopeListeners=[],this._eventProcessors=[],this._breadcrumbs=[],this._attachments=[],this._user={},this._tags={},this._attributes={},this._extra={},this._contexts={},this._sdkProcessingMetadata={},this._propagationContext={traceId:je(),sampleRand:nt()}}clone(){let t=new e;return t._breadcrumbs=[...this._breadcrumbs],t._tags={...this._tags},t._attributes={...this._attributes},t._extra={...this._extra},t._contexts={...this._contexts},this._contexts.flags&&(t._contexts.flags={values:[...this._contexts.flags.values]}),t._user=this._user,t._level=this._level,t._session=this._session,t._transactionName=this._transactionName,t._fingerprint=this._fingerprint,t._eventProcessors=[...this._eventProcessors],t._attachments=[...this._attachments],t._sdkProcessingMetadata={...this._sdkProcessingMetadata},t._propagationContext={...this._propagationContext},t._client=this._client,t._lastEventId=this._lastEventId,t._conversationId=this._conversationId,sr(t,Rr(this)),t}setClient(t){this._client=t}setLastEventId(t){this._lastEventId=t}getClient(){return this._client}lastEventId(){return this._lastEventId}addScopeListener(t){this._scopeListeners.push(t)}addEventProcessor(t){return this._eventProcessors.push(t),this}setUser(t){return this._user=t||{email:void 0,id:void 0,ip_address:void 0,username:void 0},this._session&&Ft(this._session,{user:t}),this._notifyScopeListeners(),this}getUser(){return this._user}setConversationId(t){return this._conversationId=t||void 0,this._notifyScopeListeners(),this}setTags(t){return this._tags={...this._tags,...t},this._notifyScopeListeners(),this}setTag(t,r){return this.setTags({[t]:r})}setAttributes(t){return this._attributes={...this._attributes,...t},this._notifyScopeListeners(),this}setAttribute(t,r){return this.setAttributes({[t]:r})}removeAttribute(t){return t in this._attributes&&(delete this._attributes[t],this._notifyScopeListeners()),this}setExtras(t){return this._extra={...this._extra,...t},this._notifyScopeListeners(),this}setExtra(t,r){return this._extra={...this._extra,[t]:r},this._notifyScopeListeners(),this}setFingerprint(t){return this._fingerprint=t,this._notifyScopeListeners(),this}setLevel(t){return this._level=t,this._notifyScopeListeners(),this}setTransactionName(t){return this._transactionName=t,this._notifyScopeListeners(),this}setContext(t,r){return r===null?delete this._contexts[t]:this._contexts[t]=r,this._notifyScopeListeners(),this}setSession(t){return t?this._session=t:delete this._session,this._notifyScopeListeners(),this}getSession(){return this._session}update(t){if(!t)return this;let r=typeof t=="function"?t(this):t,n=r instanceof e?r.getScopeData():Rt(r)?t:void 0,{tags:i,attributes:s,extra:a,user:c,contexts:o,level:l,fingerprint:u=[],propagationContext:p,conversationId:d}=n||{};return this._tags={...this._tags,...i},this._attributes={...this._attributes,...s},this._extra={...this._extra,...a},this._contexts={...this._contexts,...o},c&&Object.keys(c).length&&(this._user=c),l&&(this._level=l),u.length&&(this._fingerprint=u),p&&(this._propagationContext=p),d&&(this._conversationId=d),this}clear(){return this._breadcrumbs=[],this._tags={},this._attributes={},this._extra={},this._user={},this._contexts={},this._level=void 0,this._transactionName=void 0,this._fingerprint=void 0,this._session=void 0,this._conversationId=void 0,sr(this,void 0),this._attachments=[],this.setPropagationContext({traceId:je(),sampleRand:nt()}),this._notifyScopeListeners(),this}addBreadcrumb(t,r){let n=typeof r=="number"?r:Eg;if(n<=0)return this;let i={timestamp:Ve(),...t,message:t.message?Ir(t.message,2048):t.message};return this._breadcrumbs.push(i),this._breadcrumbs.length>n&&(this._breadcrumbs=this._breadcrumbs.slice(-n),this._client?.recordDroppedEvent("buffer_overflow","log_item")),this._notifyScopeListeners(),this}getLastBreadcrumb(){return this._breadcrumbs[this._breadcrumbs.length-1]}clearBreadcrumbs(){return this._breadcrumbs=[],this._notifyScopeListeners(),this}addAttachment(t){return this._attachments.push(t),this}clearAttachments(){return this._attachments=[],this}getScopeData(){return{breadcrumbs:this._breadcrumbs,attachments:this._attachments,contexts:this._contexts,tags:this._tags,attributes:this._attributes,extra:this._extra,user:this._user,level:this._level,fingerprint:this._fingerprint||[],eventProcessors:this._eventProcessors,propagationContext:this._propagationContext,sdkProcessingMetadata:this._sdkProcessingMetadata,transactionName:this._transactionName,span:Rr(this),conversationId:this._conversationId}}setSDKProcessingMetadata(t){return this._sdkProcessingMetadata=ir(this._sdkProcessingMetadata,t,2),this}setPropagationContext(t){return this._propagationContext=t,this}getPropagationContext(){return this._propagationContext}captureException(t,r){let n=r?.event_id||he();if(!this._client)return _&&f.warn("No client configured on scope - will not capture exception!"),n;let i=new Error("Sentry syntheticException");return this._client.captureException(t,{originalException:t,syntheticException:i,...r,event_id:n},this),n}captureMessage(t,r,n){let i=n?.event_id||he();if(!this._client)return _&&f.warn("No client configured on scope - will not capture message!"),i;let s=n?.syntheticException??new Error(t);return this._client.captureMessage(t,r,{originalException:t,syntheticException:s,...n,event_id:i},this),i}captureEvent(t,r){let n=t.event_id||r?.event_id||he();return this._client?(this._client.captureEvent(t,{...r,event_id:n},this),n):(_&&f.warn("No client configured on scope - will not capture event!"),n)}_notifyScopeListeners(){this._notifyingListeners||(this._notifyingListeners=!0,this._scopeListeners.forEach(t=>{t(this)}),this._notifyingListeners=!1)}};function yl(){return gt("defaultCurrentScope",()=>new $e)}function Sl(){return gt("defaultIsolationScope",()=>new $e)}var vl=e=>e instanceof Promise&&!e[El],El=Symbol("chained PromiseLike"),Tl=(e,t,r)=>{let n=e.then(i=>(t(i),i),i=>{throw r(i),i});return vl(n)&&vl(e)?n:Tg(e,n)},Tg=(e,t)=>{if(!t)return e;let r=!1;for(let n in e){if(n in t)continue;r=!0;let i=e[n];typeof i=="function"?Object.defineProperty(t,n,{value:(...s)=>i.apply(e,s),enumerable:!0,configurable:!0,writable:!0}):t[n]=i}return r&&Object.assign(t,{[El]:!0}),t};var qa=class{constructor(t,r){let n;t?n=t:n=new $e;let i;r?i=r:i=new $e,this._stack=[{scope:n}],this._isolationScope=i}withScope(t){let r=this._pushScope(),n;try{n=t(r)}catch(i){throw this._popScope(),i}return ft(n)?Tl(n,()=>this._popScope(),()=>this._popScope()):(this._popScope(),n)}getClient(){return this.getStackTop().client}getScope(){return this.getStackTop().scope}getIsolationScope(){return this._isolationScope}getStackTop(){return this._stack[this._stack.length-1]}_pushScope(){let t=this.getScope().clone();return this._stack.push({client:this.getClient(),scope:t}),t}_popScope(){return this._stack.length<=1?!1:!!this._stack.pop()}};function Kr(){let e=Ue(),t=Ut(e);return t.stack=t.stack||new qa(yl(),Sl())}function Ig(e){return Kr().withScope(e)}function Ag(e,t){let r=Kr();return r.withScope(()=>(r.getStackTop().scope=e,t(e)))}function Il(e){return Kr().withScope(()=>e(Kr().getIsolationScope()))}function Al(){return{withIsolationScope:Il,withScope:Ig,withSetScope:Ag,withSetIsolationScope:(e,t)=>Il(t),getCurrentScope:()=>Kr().getScope(),getIsolationScope:()=>Kr().getIsolationScope()}}function Ot(e){let t=Ut(e);return t.acs?t.acs:Al()}var Rl;function Ha(){return Rl?.()}function Ji(){return Rl!==void 0}function R(){let e=Ue();return Ot(e).getCurrentScope()}function me(){let e=Ue();return Ot(e).getIsolationScope()}function qn(){return gt("globalScope",()=>new $e)}function ar(...e){let t=Ue(),r=Ot(t);if(e.length===2){let[n,i]=e;return n?r.withSetScope(n,i):r.withScope(i)}return r.withScope(e[0])}function E(){return R().getClient()}function Qi(e){let t=Ha();if(t)return{trace_id:t.traceId,span_id:t.spanId};let r=e.getPropagationContext(),{traceId:n,parentSpanId:i,propagationSpanId:s}=r,a={trace_id:n,span_id:s||Be()};return i&&(a.parent_span_id=i),a}var Ga=[];function Rg(e){let t={};return e.forEach(r=>{let{name:n}=r,i=t[n];i&&!i.isDefaultInstance&&r.isDefaultInstance||(t[n]=r)}),Object.values(t)}function Wa(e){let t=e.defaultIntegrations||[],r=e.integrations;t.forEach(i=>{i.isDefaultInstance=!0});let n;if(Array.isArray(r))n=[...t,...r];else if(typeof r=="function"){let i=r(t);n=Array.isArray(i)?i:[i]}else n=t;return Rg(n)}function Ol(e,t){let r={};return t.forEach(n=>{n?.beforeSetup&&n.beforeSetup(e)}),t.forEach(n=>{n&&za(e,n,r)}),r}function Ya(e,t){for(let r of t)r?.afterAllSetup&&r.afterAllSetup(e)}function za(e,t,r){if(r[t.name]){_&&f.log(`Integration skipped because it was already installed: ${t.name}`);return}if(r[t.name]=t,!Ga.includes(t.name)&&typeof t.setupOnce=="function"&&(t.setupOnce(),Ga.push(t.name)),t.setup&&typeof t.setup=="function"&&t.setup(e),typeof t.preprocessEvent=="function"){let n=t.preprocessEvent.bind(t);e.on("preprocessEvent",(i,s)=>n(i,s,e))}if(typeof t.processEvent=="function"){let n=t.processEvent.bind(t),i=Object.assign((s,a)=>n(s,a,e),{id:t.name});e.addEventProcessor(i)}["processSpan","processSegmentSpan"].forEach(n=>{let i=t[n];typeof i=="function"&&e.on(n,s=>i.call(t,s,e))}),_&&f.log(`Integration installed: ${t.name}`)}function xl(e){let t=E();if(!t){_&&f.warn(`Cannot add integration "${e.name}" because no SDK Client is available.`);return}t.addIntegration(e)}var Hn={},kl={};function Le(e,t){return Hn[e]=Hn[e]||[],Hn[e].push(t),()=>{let r=Hn[e];if(r){let n=r.indexOf(t);n!==-1&&r.splice(n,1)}}}function Pe(e,t){if(!kl[e]){kl[e]=!0;try{t()}catch(r){_&&f.error(`Error while instrumenting ${e}`,r)}}}function ye(e,t){let r=e&&Hn[e];if(r)for(let n of r)try{n(t)}catch(i){_&&f.error(`Error while triggering instrumentation handler. +Type: ${e} +Name: ${Fe(n)} +Error:`,i)}}var Va=null;function Gn(e){let t="error";Le(t,e),Pe(t,Og)}function Og(){Va=T.onerror,T.onerror=function(e,t,r,n,i){return ye("error",{column:n,error:i,line:r,msg:e,url:t}),Va?Va.apply(this,arguments):!1},T.onerror.__SENTRY_INSTRUMENTED__=!0}var ja=null;function Wn(e){let t="unhandledrejection";Le(t,e),Pe(t,xg)}function xg(){ja=T.onunhandledrejection,T.onunhandledrejection=function(e){return ye("unhandledrejection",e),ja?ja.apply(this,arguments):!0},T.onunhandledrejection.__SENTRY_INSTRUMENTED__=!0}function kg(e){return typeof e=="object"&&e!=null&&!Array.isArray(e)&&Object.keys(e).includes("value")}function Ng(e,t){let{value:r,unit:n}=kg(e)?e:{value:e,unit:void 0},i=wg(r),s=n&&typeof n=="string"?{unit:n}:{};if(i)return{...i,...s};if(!t||t==="skip-undefined"&&r===void 0)return;let a="";try{a=JSON.stringify(r)??""}catch{}return{value:a,type:"string",...s}}function $a(e,t=!1){let r={};for(let[n,i]of Object.entries(e??{})){let s=Ng(i,t);s&&(r[n]=s)}return r}function wg(e){if(Array.isArray(e))return{value:e,type:"array"};let t=typeof e=="string"?"string":typeof e=="boolean"?"boolean":typeof e=="number"&&!Number.isNaN(e)?Number.isInteger(e)?"integer":"double":null;if(t)return{value:e,type:t}}var Se="sentry.source",Bt="sentry.sample_rate",Xr="sentry.previous_trace_sample_rate",de="sentry.op",j="sentry.origin",Zi="sentry.status.message",qt="sentry.idle_span_finish_reason",bt="sentry.measurement_unit",_t="sentry.measurement_value";var Jr="sentry.custom_span_name",Or="sentry.profile_id",De="sentry.exclusive_time";var es="sentry.link.type",ts="gen_ai.conversation.id";function Ka(e){if(e<400&&e>=100)return{code:1};if(e>=400&&e<500)switch(e){case 401:return{code:2,message:"unauthenticated"};case 403:return{code:2,message:"permission_denied"};case 404:return{code:2,message:"not_found"};case 409:return{code:2,message:"already_exists"};case 413:return{code:2,message:"failed_precondition"};case 429:return{code:2,message:"resource_exhausted"};case 499:return{code:2,message:"cancelled"};default:return{code:2,message:"invalid_argument"}}if(e>=500&&e<600)switch(e){case 501:return{code:2,message:"unimplemented"};case 503:return{code:2,message:"unavailable"};case 504:return{code:2,message:"deadline_exceeded"};default:return{code:2,message:"internal_error"}}return{code:2,message:"internal_error"}}function Qr(e,t){e.setAttribute("http.response.status_code",t);let r=Ka(t);r.message!=="unknown_error"&&e.setStatus(r)}var Nl="_sentryScope",wl="_sentryIsolationScope",Cg=Symbol.for("sentry.otelSourceInference"),Mg=Symbol.for("sentry.otelSourceExplicitlySet"),Lg=Symbol.for("sentry.tracerProviderSpan");function or(e,t,r){e&&(ne(e,wl,Ki(r)),ne(e,Nl,t))}function Ht(e){let t=e;return{scope:t[Nl],isolationScope:Xi(t[wl])}}function Xa(e){return e[Cg]===!0}function Cl(e){ne(e,Mg,!0)}function Ja(e){return e[Lg]===!0}var Yn="sentry-";var Pg=8192;function rs(e){let t=Dg(e);if(!t)return;let r=Object.entries(t).reduce((n,[i,s])=>{if(i.startsWith(Yn)){let a=i.slice(Yn.length);n[a]=s}return n},{});if(Object.keys(r).length>0)return r}function Qa(e){if(!e)return;let t=Object.entries(e).reduce((r,[n,i])=>(i&&(r[`${Yn}${n}`]=i),r),{});return Ug(t)}function Dg(e){if(!(!e||!Ce(e)&&!Array.isArray(e)))return Array.isArray(e)?e.reduce((t,r)=>{let n=Ml(r);return Object.entries(n).forEach(([i,s])=>{t[i]=s}),t},{}):Ml(e)}function Ml(e){return e.split(",").map(t=>{let r=t.indexOf("=");if(r===-1)return[];let n=t.slice(0,r),i=t.slice(r+1);return[n,i].map(s=>{try{return decodeURIComponent(s.trim())}catch{return}})}).reduce((t,[r,n])=>(r&&n&&(t[r]=n),t),{})}function Ug(e){if(Object.keys(e).length!==0)return Object.entries(e).reduce((t,[r,n],i)=>{let s=`${encodeURIComponent(r)}=${encodeURIComponent(n)}`,a=i===0?s:`${t},${s}`;return a.length>Pg?(_&&f.warn(`Not adding key: ${r} with val: ${n} to baggage header due to exceeding baggage size limits.`),t):a},"")}var Fg=/^o(\d+)\./,Bg=/^(?:(\w+):)\/\/(?:(\w+)(?::(\w+)?)?@)((?:\[[:.%\w]+\]|[\w.-]+))(?::(\d+))?\/(.+)/;function qg(e){return e==="http"||e==="https"}function yt(e,t=!1){let{host:r,path:n,pass:i,port:s,projectId:a,protocol:c,publicKey:o}=e;return`${c}://${o}${t&&i?`:${i}`:""}@${r}${s?`:${s}`:""}/${n&&`${n}/`}${a}`}function Hg(e){let t=Bg.exec(e);if(!t){Oe(()=>{console.error(`Invalid Sentry Dsn: ${e}`)});return}let[r,n,i="",s="",a="",c=""]=t.slice(1),o="",l=c,u=l.split("/");if(u.length>1&&(o=u.slice(0,-1).join("/"),l=u.pop()),l){let p=l.match(/^\d+/);p&&(l=p[0])}return Ll({host:s,pass:i,path:o,projectId:l,port:a,protocol:r,publicKey:n})}function Ll(e){return{protocol:e.protocol,publicKey:e.publicKey||"",pass:e.pass||"",host:e.host,port:e.port||"",path:e.path||"",projectId:e.projectId}}function Gg(e){if(!_)return!0;let{port:t,projectId:r,protocol:n}=e;return["protocol","publicKey","host","projectId"].find(a=>e[a]?!1:(f.error(`Invalid Sentry Dsn: ${a} missing`),!0))?!1:r.match(/^\d+$/)?qg(n)?t&&isNaN(parseInt(t,10))?(f.error(`Invalid Sentry Dsn: Invalid port ${t}`),!1):!0:(f.error(`Invalid Sentry Dsn: Invalid protocol ${n}`),!1):(f.error(`Invalid Sentry Dsn: Invalid projectId ${r}`),!1)}function Wg(e){return e.match(Fg)?.[1]}function Pl(e){let t=e.getOptions(),{host:r}=e.getDsn()||{},n;return t.orgId?n=String(t.orgId):r&&(n=Wg(r)),n}function Dl(e){let t=typeof e=="string"?Hg(e):Ll(e);if(!(!t||!Gg(t)))return t}function et(e){if(typeof e=="boolean")return Number(e);let t=typeof e=="string"?parseFloat(e):e;if(!(typeof t!="number"||isNaN(t)||t<0||t>1))return t}var ns=new RegExp("^[ \\t]*([0-9a-f]{32})?-?([0-9a-f]{16})?-?([01])?[ \\t]*$");function Ul(e){if(!e)return;let t=e.match(ns);if(!t)return;let r;return t[3]==="1"?r=!0:t[3]==="0"&&(r=!1),{traceId:t[1],parentSampled:r,parentSpanId:t[2]}}function Za(e,t){let r=Ul(e),n=rs(t);if(!r?.traceId)return{traceId:je(),sampleRand:nt()};let i=Yg(r,n);n&&(n.sample_rand=i.toString());let{traceId:s,parentSpanId:a,parentSampled:c}=r;return{traceId:s,parentSpanId:a,sampled:c,dsc:n||{},sampleRand:i}}function zn(e=je(),t=Be(),r){let n="";return r!==void 0&&(n=r?"-1":"-0"),`${e}-${t}${n}`}function Vn(e=je(),t=Be(),r){return`00-${e}-${t}-${r?"01":"00"}`}function Yg(e,t){let r=et(t?.sample_rand);if(r!==void 0)return r;let n=et(t?.sample_rate);return n&&e?.parentSampled!==void 0?e.parentSampled?nt()*n:n+nt()*(1-n):nt()}var is=0,$n=1,Fl=!1;function Hl(e){let{spanId:t,traceId:r}=e.spanContext(),{data:n,op:i,parent_span_id:s,status:a,origin:c,links:o}=O(e);return{parent_span_id:s,span_id:t,trace_id:r,data:n,op:i,status:a,origin:c,links:o}}function ss(e){let{spanId:t,traceId:r,isRemote:n}=e.spanContext(),i=n?t:O(e).parent_span_id,s=Ht(e).scope,a=n?s?.getPropagationContext().propagationSpanId||Be():t;return{parent_span_id:i,span_id:a,trace_id:r}}function Kn(e){let{traceId:t,spanId:r}=e.spanContext(),n=qe(e);return zn(t,r,n)}function Gl(e){let{traceId:t,spanId:r}=e.spanContext(),n=qe(e);return Vn(t,r,n)}function Xn(e){if(e&&e.length>0)return e.map(({context:{spanId:t,traceId:r,traceFlags:n,...i},attributes:s})=>({span_id:t,trace_id:r,sampled:n===$n,attributes:s,...i}))}function ro(e){if(e?.length)return e.map(({context:{spanId:t,traceId:r,traceFlags:n},attributes:i})=>({span_id:t,trace_id:r,sampled:n===$n,attributes:i}))}function Ke(e){return typeof e=="number"?Bl(e):Array.isArray(e)?e[0]+e[1]/1e9:e instanceof Date?Bl(e.getTime()):Q()}function Bl(e){return e>9999999999?e/1e3:e}function O(e){if(as(e))return e.getSpanJSON();let{spanId:t,traceId:r}=e.spanContext();if(zl(e)){let{attributes:n,startTime:i,name:s,endTime:a,status:c,links:o}=e;return{span_id:t,trace_id:r,data:n,description:s,parent_span_id:Wl(e),start_timestamp:Ke(i),timestamp:Ke(a)||void 0,status:Qn(c),op:n[de],origin:n[j],links:Xn(o)}}return{span_id:t,trace_id:r,start_timestamp:0,data:{}}}function Jn(e){if(as(e))return e.getStreamedSpanJSON();let{spanId:t,traceId:r}=e.spanContext();if(zl(e)){let{attributes:n,startTime:i,name:s,endTime:a,status:c,links:o}=e;return{name:s,span_id:t,trace_id:r,parent_span_id:Wl(e),start_timestamp:Ke(i),end_timestamp:Ke(a),is_segment:e===jn(e),status:os(c),attributes:no(n,c),links:ro(o)}}return{span_id:t,trace_id:r,start_timestamp:0,name:"",end_timestamp:0,status:"ok",is_segment:e===jn(e)}}function Wl(e){return"parentSpanId"in e?e.parentSpanId:"parentSpanContext"in e?e.parentSpanContext?.spanId:void 0}function Yl(e){return{...e,attributes:$a(e.attributes),links:e.links?.map(t=>({...t,attributes:$a(t.attributes)}))}}function zl(e){let t=e;return!!t.attributes&&!!t.startTime&&!!t.name&&!!t.endTime&&!!t.status}function as(e){return typeof e.getSpanJSON=="function"}function qe(e){let{traceFlags:t}=e.spanContext();return t===$n}function Qn(e){if(!(!e||e.code===0))return e.code===1?"ok":e.message||"internal_error"}function os(e){return!e||e.code===1||e.code===0||e.message==="cancelled"?"ok":"error"}function no(e,t){let r=os(t)==="error"?t?.message:void 0;return{...r&&{[Zi]:r},...e}}var xr="_sentryChildSpans",eo="_sentryRootSpan";function kr(e,t){let r=e[eo]||e;ne(t,eo,r),qe(e)&&(!e.isRecording()&&!r.isRecording()||(e[xr]?e[xr].add(t):ne(e,xr,new Set([t]))))}function Vl(e,t){e[xr]&&e[xr].delete(t)}function Gt(e){let t=new Set;function r(n){if(!t.has(n)&&qe(n)){t.add(n);let i=n[xr]?Array.from(n[xr]):[];for(let s of i)r(s)}}return r(e),Array.from(t)}var X=jn;function jn(e){return e[eo]||e}function te(){let e=Ue(),t=Ot(e);return t.getActiveSpan?t.getActiveSpan():Rr(R())}function Zn(){Fl||(Oe(()=>{console.warn("[Sentry] Returning null from `beforeSendSpan` is disallowed. To drop certain spans, configure the respective integrations directly or use `ignoreSpans`.")}),Fl=!0)}var jl=!1;function cs(){if(jl)return;function e(){let t=te(),r=t&&X(t);if(r){let n="internal_error";_&&f.log(`[Tracing] Root span: ${n} -> Global error occurred`),r.setStatus({code:2,message:n})}}jl=!0,Gn(e),Wn(e)}function _e(e){if(typeof __SENTRY_TRACING__=="boolean"&&!__SENTRY_TRACING__)return!1;let t=e||E()?.getOptions();return!!t&&(t.tracesSampleRate!=null||!!t.tracesSampler)}function $l(e){f.log(`Ignoring span ${e.op} - ${e.description} because it matches \`ignoreSpans\`.`)}function Wt(e,t){if(!t?.length)return!1;for(let r of t){if(Vg(r)){if(e.description&&nr(e.description,r))return _&&$l(e),!0;continue}let n=!!r.attributes&&Object.keys(r.attributes).length>0;if(!r.name&&!r.op&&!n)continue;let i=r.name?e.description&&nr(e.description,r.name):!0,s=r.op?e.op&&nr(e.op,r.op):!0,a=r.attributes?Object.entries(r.attributes).every(([c,o])=>zg(e.attributes?.[c],o)):!0;if(i&&s&&a)return _&&$l(e),!0}return!1}function zg(e,t){return typeof e=="string"&&(typeof t=="string"||t instanceof RegExp)?nr(e,t):Array.isArray(e)&&Array.isArray(t)?e.length===t.length&&e.every((r,n)=>r===t[n]):e===t}function Kl(e,t){let r=t.parent_span_id,n=t.span_id;if(r)for(let i of e)i.parent_span_id===n&&(i.parent_span_id=r)}function Vg(e){return typeof e=="string"||e instanceof RegExp}var Xl=Symbol.for("sentry.nonRecordingSpan"),Xe=class{constructor(t={}){this._traceId=t.traceId||je(),this._spanId=t.spanId||Be(),this.dropReason=t.dropReason,ne(this,Xl,!0)}spanContext(){return{spanId:this._spanId,traceId:this._traceId,traceFlags:is}}end(t){}setAttribute(t,r){return this}setAttributes(t){return this}setStatus(t){return this}updateName(t){return this}isRecording(){return!1}addEvent(t,r,n){return this}addLink(t){return this}addLinks(t){return this}recordException(t,r){}};function xt(e){return!!e&&e[Xl]===!0}var Zr="production";var Jl="_frozenDsc";function io(e,t){ne(e,Jl,t)}function ls(e,t){let r=t.getOptions(),{publicKey:n}=t.getDsn()||{},i={environment:r.environment||Zr,release:r.release,public_key:n,trace_id:e,org_id:Pl(t)};return t.emit("createDsc",i),i}function wr(e,t){let r=t.getPropagationContext();return r.dsc||ls(r.traceId,e)}function ke(e){let t=E();if(!t)return{};let r=X(e),n=O(r),i=n.data,s=r.spanContext().traceState,a=s?.get("sentry.sample_rate")??i[Bt]??i[Xr];function c(S){return(typeof a=="number"||typeof a=="string")&&(S.sample_rate=`${a}`),S}let o=r[Jl];if(o)return c(o);let l=xt(r),u=l&&r.dropReason==="ignored";if(l&&(!_e(t.getOptions())||u)){let S=Ht(r).scope;if(S){let b={...wr(t,S)};return u&&(b.sampled="false"),c(b)}}let p=s?.get("sentry.dsc"),d=p&&rs(p);if(d)return c(d);let m=ls(e.spanContext().traceId,t),g=i[Se]??i["sentry.segment.name.source"],h=n.description;return g!=="url"&&h&&(m.transaction=h),_e()&&(m.sampled=String(qe(r)),m.sample_rand=s?.get("sentry.sample_rand")??Ht(r).scope?.getPropagationContext().sampleRand.toString()),c(m),t.emit("createDsc",m,r),m}function ps(e){return!!e&&typeof e=="function"&&"_streamed"in e&&!!e._streamed}function He(e,t=[]){return[e,t]}function us(e,t){let[r,n]=e;return[r,[...n,t]]}function ei(e,t){let r=e[1];for(let n of r){let i=n[0].type;if(t(n,i))return!0}return!1}function ao(e,t){return ei(e,(r,n)=>t.includes(n))}function so(e){let t=Ut(T);return t.encodePolyfill?t.encodePolyfill(e):new TextEncoder().encode(e)}function oo(e){let[t,r]=e,n=JSON.stringify(t);function i(s){typeof n=="string"?n=typeof s=="string"?n+s:[so(n),s]:n.push(typeof s=="string"?so(s):s)}for(let s of r){let[a,c]=s;if(i(` +${JSON.stringify(a)} +`),typeof c=="string"||c instanceof Uint8Array)i(c);else{let o;try{o=JSON.stringify(c)}catch{o=JSON.stringify(Me(c))}i(o)}}return typeof n=="string"?n:jg(n)}function jg(e){let t=e.reduce((i,s)=>i+s.length,0),r=new Uint8Array(t),n=0;for(let i of e)r.set(i,n),n+=i.length;return r}function co(e){return[{type:"span"},e]}function lo(e){let t=typeof e.data=="string"?so(e.data):e.data;return[{type:"attachment",length:t.length,filename:e.filename,content_type:e.contentType,attachment_type:e.attachmentType},t]}var Ql={sessions:"session",event:"error",client_report:"internal",user_report:"default",profile_chunk:"profile",replay_event:"replay",replay_recording:"replay",check_in:"monitor",raw_security:"security",log:"log_item",trace_metric:"metric"};function $g(e){return e in Ql}function ds(e){return $g(e)?Ql[e]:e}function en(e){if(!e?.sdk)return;let{name:t,version:r}=e.sdk;return{name:t,version:r}}function ti(e,t,r,n){let i=e.sdkProcessingMetadata?.dynamicSamplingContext;return{event_id:e.event_id,sent_at:new Date(it()).toISOString(),...t&&{sdk:t},...!!r&&n&&{dsn:yt(n)},...i&&{trace:i}}}function Kg(e,t){if(!t)return e;let r=e.sdk||{};return e.sdk={...r,name:r.name||t.name,version:r.version||t.version,integrations:[...e.sdk?.integrations||[],...t.integrations||[]],packages:[...e.sdk?.packages||[],...t.packages||[]],settings:e.sdk?.settings||t.settings?{...e.sdk?.settings,...t.settings}:void 0},e}function Zl(e,t,r,n){let i=en(r),s={sent_at:new Date(it()).toISOString(),...i&&{sdk:i},...!!n&&t&&{dsn:yt(t)}},a="aggregates"in e?[{type:"sessions"},e]:[{type:"session"},e.toJSON()];return He(s,[a])}function ep(e,t,r,n){let i=en(r),s=e.type&&e.type!=="replay_event"?e.type:"event";Kg(e,r?.sdk);let a=ti(e,i,n,t);return delete e.sdkProcessingMetadata,He(a,[[{type:s},e]])}function tp(e,t){function r(m){return!!m.trace_id&&!!m.public_key}let n=ke(e[0]),i=t?.getDsn(),s=t?.getOptions().tunnel,a={sent_at:new Date(it()).toISOString(),...r(n)&&{trace:n},...!!s&&i&&{dsn:yt(i)}},{beforeSendSpan:c,ignoreSpans:o}=t?.getOptions()||{},l=o?.length?e.filter(m=>{let g=O(m);return!Wt({description:g.description,op:g.op,attributes:g.data},o)}):e,u=e.length-l.length;u&&t?.recordDroppedEvent("before_send","span",u);let p=c?m=>{let g=O(m),h=ps(c)?g:c(g);return h||(Zn(),g)}:O,d=[];for(let m of l){let g=p(m);g&&d.push(co(g))}return He(a,d)}function rp(e){if(!_)return;let{description:t="< unknown name >",op:r="< unknown op >",parent_span_id:n}=O(e),{spanId:i}=e.spanContext(),s=qe(e),a=X(e),c=a===e,o=`[Tracing] Starting ${s?"sampled":"unsampled"} ${c?"root ":""}span`,l=[`op: ${r}`,`name: ${t}`,`ID: ${i}`];if(n&&l.push(`parent ID: ${n}`),!c){let{op:u,description:p}=O(a);l.push(`root ID: ${a.spanContext().spanId}`),u&&l.push(`root op: ${u}`),p&&l.push(`root description: ${p}`)}f.log(`${o} + ${l.join(` + `)}`)}function np(e){if(!_)return;let{description:t="< unknown name >",op:r="< unknown op >"}=O(e),{spanId:n}=e.spanContext(),s=X(e)===e,a=`[Tracing] Finishing "${r}" ${s?"root ":""}span "${t}" with ID ${n}`;f.log(a)}function ri(e,t,r,n=te()){let i=n&&X(n);i&&(_&&f.log(`[Measurement] Setting measurement on root span: ${e} = ${t} ${r}`),i.addEvent(e,{[_t]:t,[bt]:r}))}function ms(e){if(!e||e.length===0)return;let t={};return e.forEach(r=>{let n=r.attributes||{},i=n[bt],s=n[_t];typeof i=="string"&&typeof s=="number"&&(t[r.name]={value:s,unit:i})}),t}function po(){return Ut(Ue()).segmentSpanCaptureStrategy}function Te(e){return e.getOptions().traceLifecycle==="stream"}var ip=1e3,cr=class{constructor(t={}){this._traceId=t.traceId||je(),this._spanId=t.spanId||Be(),this._startTime=t.startTimestamp||Q(),this._links=t.links,this._attributes={},this.setAttributes({[j]:"manual",[de]:t.op,...t.attributes}),this._name=t.name,t.parentSpanId&&(this._parentSpanId=t.parentSpanId),"sampled"in t&&(this._sampled=t.sampled),t.endTimestamp&&(this._endTime=t.endTimestamp),this._events=[],this._isStandaloneSpan=t.isStandalone,this._endTime&&this._onSpanEnded()}addLink(t){return this._frozen?this:(this._links?this._links.push(t):this._links=[t],this)}addLinks(t){return this._frozen?this:(this._links?this._links.push(...t):this._links=t,this)}recordException(t,r){}spanContext(){let{_spanId:t,_traceId:r,_sampled:n}=this;return{spanId:t,traceId:r,traceFlags:n?$n:is}}setAttribute(t,r){return this._frozen?this:(r===void 0?delete this._attributes[t]:this._attributes[t]=r,t===Se&&r!==void 0&&Xa(this)&&Cl(this),this)}setAttributes(t){return Object.keys(t).forEach(r=>this.setAttribute(r,t[r])),this}updateStartTime(t){this._frozen||(this._startTime=Ke(t))}setStatus(t){return this._frozen?this:(this._status=t,this)}updateName(t){return this._frozen?this:(this._name=t,Xa(this)||this.setAttribute(Se,"custom"),this)}end(t){if(this._endTime){this._frozen=Ja(this);return}this._endTime=Ke(t),np(this),this._onSpanEnded(),this._frozen=Ja(this)}getSpanJSON(){return{data:this._attributes,description:this._name,op:this._attributes[de],parent_span_id:this._parentSpanId,span_id:this._spanId,start_timestamp:this._startTime,status:Qn(this._status),timestamp:this._endTime,trace_id:this._traceId,origin:this._attributes[j],profile_id:this._attributes[Or],exclusive_time:this._attributes[De],measurements:ms(this._events),is_segment:this._isStandaloneSpan&&X(this)===this||void 0,segment_id:this._isStandaloneSpan?X(this).spanContext().spanId:void 0,links:Xn(this._links)}}getStreamedSpanJSON(){return{name:this._name??"",span_id:this._spanId,trace_id:this._traceId,parent_span_id:this._parentSpanId,start_timestamp:this._startTime,end_timestamp:this._endTime??this._startTime,is_segment:this._isStandaloneSpan||this===X(this),status:os(this._status),attributes:no(this._attributes,this._status),links:ro(this._links)}}isRecording(){return!this._endTime&&!!this._sampled}addEvent(t,r,n){if(this._frozen)return this;_&&f.log("[Tracing] Adding an event to span:",t);let i=sp(r)?r:n||Q(),s=sp(r)?{}:r||{},a={name:t,time:Ke(i),attributes:s};return this._events.push(a),this}isStandaloneSpan(){return!!this._isStandaloneSpan}_onSpanEnded(){let t=E();t&&(t.emit("spanEnd",this),this._isStandaloneSpan||t.emit("afterSpanEnd",this));let r=X(this),n=this._isStandaloneSpan||this===r;if(this._isStandaloneSpan){this._sampled?Jg(tp([this],t)):(_&&f.log("[Tracing] Discarding standalone span because its trace was not chosen to be sampled."),t&&t.recordDroppedEvent("sample_rate","span"));return}if(!n){let a=po();if(a){let c=Ht(this).scope||R();a.onChildSpanEnded(this,r,o=>this._convertSpanToTransaction(o),c)}return}if(t&&Te(t)){t.emit("afterSegmentSpanEnd",this);return}let i=Ht(this).scope||R(),s=po();if(s)s.onSegmentSpanEnded(a=>this._convertSpanToTransaction(a),i);else{let a=this._convertSpanToTransaction();a&&i.captureEvent(a)}}_convertSpanToTransaction(t={}){if(!ap(O(this)))return;this._name||(_&&f.warn("Transaction has no name, falling back to ``."),this._name="");let{scope:r,isolationScope:n}=Ht(this),i=r?.getScopeData().sdkProcessingMetadata?.normalizedRequest;if(this._sampled!==!0)return;t.onSpanCaptured?.(this);let s=[];for(let p of Gt(this)){if(p===this||Xg(p)||t.isSpanAlreadyCaptured?.(p))continue;let d=O(p);ap(d)&&(t.onSpanCaptured?.(p),s.push(d))}let a=this._attributes[Se];delete this._attributes[Jr];let c=!1;s.forEach(p=>{delete p.data[Jr],p.op?.startsWith("gen_ai.")&&(c=!0)});let o={contexts:{trace:Hl(this)},spans:s.length>ip?s.sort((p,d)=>p.start_timestamp-d.start_timestamp).slice(0,ip):s,start_timestamp:this._startTime,timestamp:this._endTime,transaction:this._name,type:"transaction",sdkProcessingMetadata:{capturedSpanScope:r,capturedSpanIsolationScope:n,dynamicSamplingContext:ke(this),hasGenAiSpans:c},request:i,...a&&{transaction_info:{source:a}}},l=ms(this._events);return l&&Object.keys(l).length&&(_&&f.log("[Measurements] Adding measurements to transaction event",JSON.stringify(l,void 0,2)),o.measurements=l),o}};function sp(e){return e&&typeof e=="number"||e instanceof Date||Array.isArray(e)}function ap(e){return!!e.start_timestamp&&!!e.timestamp&&!!e.span_id&&!!e.trace_id}function Xg(e){return e instanceof cr&&e.isStandaloneSpan()}function Jg(e){let t=E();if(!t)return;let r=e[1];if(!r||r.length===0){t.recordDroppedEvent("before_send","span");return}t.sendEnvelope(e)}function op(e,t,r){if(!_e(e))return[!1];let n,i;typeof e.tracesSampler=="function"?(i=e.tracesSampler({...t,inheritOrSampleWith:c=>typeof t.parentSampleRate=="number"?t.parentSampleRate:typeof t.parentSampled=="boolean"?Number(t.parentSampled):c}),n=!0):t.parentSampled!==void 0?i=t.parentSampled:typeof e.tracesSampleRate<"u"&&(i=e.tracesSampleRate,n=!0);let s=et(i);if(s===void 0)return _&&f.warn(`[Tracing] Discarding root span because of invalid sample rate. Sample rate must be a boolean or a number between 0 and 1. Got ${JSON.stringify(i)} of type ${JSON.stringify(typeof i)}.`),[!1];if(!s)return _&&f.log(`[Tracing] Discarding transaction because ${typeof e.tracesSampler=="function"?"tracesSampler returned 0 or false":"a negative sampling decision was inherited or tracesSampleRate is set to 0"}`),[!1,s,n];let a=rar(e.scope,s):n!==void 0?s=>tn(n,s):s=>s())(()=>{let s=R(),a=nf(s,n),c=E();return e.onlyIfParent&&!a?Zg(s,c):ef({parentSpan:a,spanArguments:t,forceTransaction:r,scope:s})})}function tn(e,t){let r=mo();return r.withActiveSpan?r.withActiveSpan(e,t):ar(n=>(sr(n,e||void 0),t(n)))}function ni(e=R()){let t=mo();return t.isTracingSuppressed?t.isTracingSuppressed(e):e.getScopeData().sdkProcessingMetadata[uo]===!0}function Zg(e,t){t?.recordDroppedEvent("no_parent_span","span");let r=new Xe({traceId:e.getPropagationContext().traceId});return or(r,e,me()),r}function ef({parentSpan:e,spanArguments:t,forceTransaction:r,scope:n}){let i=me();if(!_e()){let c=n.getPropagationContext(),o=e?e.spanContext().traceId:c.traceId,l=new Xe({traceId:o});return e&&!r&&kr(e,l),or(l,n,i),l}let s=E();if(sf(s,t)){ni(n)||s?.recordDroppedEvent("ignored","span");let c=new Xe({dropReason:"ignored",traceId:e?.spanContext().traceId??n.getPropagationContext().traceId});return e&&!r&&kr(e,c),or(c,n,i),c}let a;if(e&&!r)a=rf(e,n,t,i),kr(e,a);else if(e){let c=ke(e),{traceId:o,spanId:l}=e.spanContext(),u=qe(e);a=cp({traceId:o,parentSpanId:l,...t},n,i,u),io(a,c)}else{let{traceId:c,dsc:o,parentSpanId:l,sampled:u}=n.getPropagationContext();a=cp({traceId:c,parentSpanId:l,...t},n,i,u),o&&io(a,o)}return rp(a),a}function tf(e){let r={isStandalone:(e.experimental||{}).standalone,...e};if(e.startTime){let n={...r};return n.startTimestamp=Ke(e.startTime),delete n.startTime,n}return r}function mo(){let e=Ue();return Ot(e)}function cp(e,t,r,n){let i=E(),s=i?.getOptions()||{},{name:a=""}=e,c={spanAttributes:{...e.attributes},spanName:a,parentSampled:n};i?.emit("beforeSampling",c,{decision:!1});let o=c.parentSampled??n,l=c.spanAttributes,u=t.getPropagationContext(),p=ni(t),[d,m,g]=p?[!1]:op(s,{name:a,parentSampled:o,attributes:l,normalizedRequest:r.getScopeData().sdkProcessingMetadata.normalizedRequest,parentSampleRate:et(u.dsc?.sample_rate)},u.sampleRand),h=new cr({...e,attributes:{[Se]:"custom",[Bt]:m!==void 0&&g?m:void 0,...l},sampled:d});return!d&&i&&!p&&(_&&f.log("[Tracing] Discarding root span because its trace was not chosen to be sampled."),i.recordDroppedEvent("sample_rate",Te(i)?"span":"transaction")),or(h,t,r),i&&i.emit("spanStart",h),h}function rf(e,t,r,n){let{spanId:i,traceId:s}=e.spanContext(),a=ni(t),c=a?!1:qe(e),o=c?new cr({...r,parentSpanId:i,traceId:s,sampled:c}):new Xe({traceId:s});kr(e,o),or(o,t,n);let l=E();return l&&(Te(l)&&xt(o)&&(xt(e)&&e.dropReason?(o.dropReason=e.dropReason,l.recordDroppedEvent(e.dropReason,"span")):a||(o.dropReason="sample_rate",l.recordDroppedEvent("sample_rate","span"))),l.emit("spanStart",o),r.endTimestamp&&(l.emit("spanEnd",o),l.emit("afterSpanEnd",o))),o}function nf(e,t){if(t)return t;if(t===null)return;let r=Rr(e);if(!r)return;let n=E();return(n?n.getOptions():{}).parentSpanIsAlwaysRootSpan?X(r):r}function sf(e,t){let r=e?.getOptions().ignoreSpans;return!e||!Te(e)||!r?.length?!1:Wt({description:t.name||"",op:t.attributes?.[de]||t.op,attributes:t.attributes},r)}function rn(e){return xt(e)&&e.dropReason==="ignored"}var nn={idleTimeout:1e3,finalTimeout:3e4,childSpanTimeout:15e3},af="heartbeatFailed",of="idleTimeout",cf="finalTimeout",lf="externalFinish";function gs(e,t={}){let r=new Map,n=!1,i,s,a=lf,c=!t.disableAutoFinish,o=[],{idleTimeout:l=nn.idleTimeout,finalTimeout:u=nn.finalTimeout,childSpanTimeout:p=nn.childSpanTimeout,beforeSpanEnd:d,trimIdleSpanEndTimestamp:m=!0}=t,g=E(),h=R();if(!g||!_e()){let x=new Xe({traceId:h.getPropagationContext().traceId});return or(x,h,me()),x}let S=te(),b=pf(e);b.end=new Proxy(b.end,{apply(x,y,M){if(d&&d(b),xt(y))return;let[K,...ee]=M,re=K||Q(),ue=Ke(re),W=Gt(b).filter(oe=>oe!==b),L=O(b);if(!W.length||!m)return F(ue),Reflect.apply(x,y,[ue,...ee]);let A=g.getOptions().ignoreSpans,H=W?.reduce((oe,ce)=>{let ge=O(ce);return!ge.timestamp||A&&Wt({description:ge.description,op:ge.op,attributes:ge.data},A)?oe:oe?Math.max(oe,ge.timestamp):ge.timestamp},void 0),B=L.start_timestamp,ae=Math.min(B?B+u/1e3:1/0,Math.max(B||-1/0,Math.min(ue,H||1/0)));return F(ae),Reflect.apply(x,y,[ae,...ee])}});function C(){i&&(clearTimeout(i),i=void 0)}function q(){s&&(clearTimeout(s),s=void 0)}function U(x){C(),i=setTimeout(()=>{!n&&r.size===0&&c&&(a=of,b.end(x))},l)}function Y(x){q(),s=setTimeout(()=>{!n&&c&&(a=af,b.end(x))},p)}function D(x){C(),r.set(x,!0);let y=Q();Y(y+p/1e3)}function v(x){if(r.has(x)&&r.delete(x),r.size===0){let y=Q();U(y+l/1e3),q()}}function F(x){n=!0,r.clear(),o.forEach(W=>W()),sr(h,S);let y=O(b),{start_timestamp:M}=y;if(!M)return;y.data[qt]||b.setAttribute(qt,a);let ee=y.status;(!ee||ee==="unknown")&&b.setStatus({code:1}),f.log(`[Tracing] Idle span "${y.op}" finished`);let re=Gt(b).filter(W=>W!==b),ue=0;re.forEach(W=>{W.isRecording()&&(W.setStatus({code:2,message:"cancelled"}),W.end(x),_&&f.log("[Tracing] Cancelling span since span ended early",JSON.stringify(W,void 0,2)));let L=O(W),{timestamp:A=0,start_timestamp:H=0}=L,B=H<=x,ae=(u+l)/1e3,oe=A-H<=ae;if(_){let ce=JSON.stringify(W,void 0,2);B?oe||f.log("[Tracing] Discarding span since it finished after idle span final timeout",ce):f.log("[Tracing] Discarding span since it happened after idle span was finished",ce)}(!oe||!B)&&(Vl(b,W),ue++)}),ue>0&&b.setAttribute("sentry.idle_span_discarded_spans",ue)}return o.push(g.on("spanStart",x=>{if(n||x===b||O(x).timestamp||x instanceof cr&&x.isStandaloneSpan())return;Gt(b).includes(x)&&D(x.spanContext().spanId)})),o.push(g.on("spanEnd",x=>{n||v(x.spanContext().spanId)})),o.push(g.on("idleSpanEnableAutoFinish",x=>{x===b&&(c=!0,U(),r.size&&Y())})),t.disableAutoFinish||U(),setTimeout(()=>{n||(b.setStatus({code:2,message:"deadline_exceeded"}),a=cf,b.end())},u),b}function pf(e){let t=Ie(e);return sr(R(),t),_&&f.log("[Tracing] Started span is an idle span"),t}function go(e,t,r){let n,i,s,a=r?.maxWait?Math.max(r.maxWait,t):0,c=r?.setTimeoutImpl||setTimeout;function o(){return l(),n=e(),n}function l(){i!==void 0&&clearTimeout(i),s!==void 0&&clearTimeout(s),i=s=void 0}function u(){return i!==void 0||s!==void 0?o():n}function p(){return i&&clearTimeout(i),i=c(o,t),a&&s===void 0&&(s=c(o,a)),n}return p.cancel=l,p.flush=u,p}function pp(e,t){let{fingerprint:r,span:n,breadcrumbs:i,sdkProcessingMetadata:s}=t;uf(e,t),n&&gf(e,n),ff(e,r),df(e,i),mf(e,s)}function lp(e,t){let{extra:r,tags:n,attributes:i,user:s,contexts:a,level:c,sdkProcessingMetadata:o,breadcrumbs:l,fingerprint:u,eventProcessors:p,attachments:d,propagationContext:m,transactionName:g,span:h}=t;ii(e,"extra",r),ii(e,"tags",n),ii(e,"attributes",i),ii(e,"user",s),ii(e,"contexts",a),e.sdkProcessingMetadata=ir(e.sdkProcessingMetadata,o,2),c&&(e.level=c),g&&(e.transactionName=g),h&&(e.span=h),l.length&&(e.breadcrumbs=[...e.breadcrumbs,...l]),u.length&&(e.fingerprint=[...e.fingerprint,...u]),p.length&&(e.eventProcessors=[...e.eventProcessors,...p]),d.length&&(e.attachments=[...e.attachments,...d]),e.propagationContext={...e.propagationContext,...m}}function ii(e,t,r){e[t]=ir(e[t],r,1)}function fs(e,t){let r=qn().getScopeData();return e&&lp(r,e.getScopeData()),t&&lp(r,t.getScopeData()),r}function uf(e,t){let{extra:r,tags:n,user:i,contexts:s,level:a,transactionName:c}=t;Object.keys(r).length&&(e.extra={...r,...e.extra}),Object.keys(n).length&&(e.tags={...n,...e.tags}),Object.keys(i).length&&(e.user={...i,...e.user}),Object.keys(s).length&&(e.contexts={...s,...e.contexts}),a&&(e.level=a),c&&e.type!=="transaction"&&(e.transaction=c)}function df(e,t){let r=[...e.breadcrumbs||[],...t];e.breadcrumbs=r.length?r:void 0}function mf(e,t){e.sdkProcessingMetadata={...e.sdkProcessingMetadata,...t}}function gf(e,t){e.contexts={trace:ss(t),...e.contexts},e.sdkProcessingMetadata={dynamicSamplingContext:ke(t),...e.sdkProcessingMetadata};let r=X(t),n=O(r).description;n&&!e.transaction&&e.type==="transaction"&&(e.transaction=n)}function ff(e,t){e.fingerprint=e.fingerprint?Array.isArray(e.fingerprint)?e.fingerprint:[e.fingerprint]:[],t&&(e.fingerprint=e.fingerprint.concat(t)),e.fingerprint.length||delete e.fingerprint}var up="http.request.header";var hs="http.url";var dp="sentry.op";var fo="sentry.segment.name";var ho="sentry.transaction";var St="url.full",mp="url.path";var gp="user_agent.original";function Yt(e,t){let r=e.attributes??(e.attributes={});Object.entries(t).forEach(([n,i])=>{i!=null&&!(n in r)&&(r[n]=i)})}var bo=0,fp=1,hp=2;function kt(e){return new si(t=>{t(e)})}function ai(e){return new si((t,r)=>{r(e)})}var si=class e{constructor(t){this._state=bo,this._handlers=[],this._runExecutor(t)}then(t,r){return new e((n,i)=>{this._handlers.push([!1,s=>{if(!t)n(s);else try{n(t(s))}catch(a){i(a)}},s=>{if(!r)i(s);else try{n(r(s))}catch(a){i(a)}}]),this._executeHandlers()})}catch(t){return this.then(r=>r,t)}finally(t){return new e((r,n)=>{let i,s;return this.then(a=>{s=!1,i=a,t&&t()},a=>{s=!0,i=a,t&&t()}).then(()=>{if(s){n(i);return}r(i)})})}_executeHandlers(){if(this._state===bo)return;let t=this._handlers.slice();this._handlers=[],t.forEach(r=>{r[0]||(this._state===fp&&r[1](this._value),this._state===hp&&r[2](this._value),r[0]=!0)})}_runExecutor(t){let r=(s,a)=>{if(this._state===bo){if(ft(a)){a.then(n,i);return}this._state=s,this._value=a,this._executeHandlers()}},n=s=>{r(fp,s)},i=s=>{r(hp,s)};try{t(n,i)}catch(s){i(s)}}};function bp(e,t,r,n=0){try{let i=_o(t,r,e,n);return ft(i)?i:kt(i)}catch(i){return ai(i)}}function _o(e,t,r,n){let i=r[n];if(!e||!i)return e;let s=i({...e},t);return _&&s===null&&f.log(`Event processor "${i.id||"?"}" dropped event`),ft(s)?s.then(a=>_o(a,t,r,n+1)):_o(s,t,r,n+1)}var Cr,_p,yp,lr;function Sp(e){let t=T._sentryDebugIds,r=T._debugIds;if(!t&&!r)return{};let n=t?Object.keys(t):[],i=r?Object.keys(r):[];if(lr&&n.length===_p&&i.length===yp)return lr;_p=n.length,yp=i.length,lr={},Cr||(Cr={});let s=(a,c)=>{for(let o of a){let l=c[o],u=Cr?.[o];if(u&&lr&&l)lr[u[0]]=l,Cr&&(Cr[o]=[u[0],l]);else if(l){let p=e(o);for(let d=p.length-1;d>=0;d--){let g=p[d]?.filename;if(g&&lr&&Cr){lr[g]=l,Cr[o]=[g,l];break}}}}};return t&&s(n,t),r&&s(i,r),lr}function oi(e,t,r,n,i,s){let{normalizeDepth:a=3,normalizeMaxBreadth:c=1e3}=e,o={...t,event_id:t.event_id||r.event_id||he(),timestamp:t.timestamp||Ve()},l=r.integrations||e.integrations.map(b=>b.name);hf(o,e),yf(o,l),i&&i.emit("applyFrameMetadata",t),t.type===void 0&&bf(o,e.stackParser);let u=vf(n,r.captureContext);r.mechanism&&st(o,r.mechanism);let p=i?i.getEventProcessors():[],d=fs(s,u),m=[...r.attachments||[],...d.attachments];m.length&&(r.attachments=m),pp(o,d);let g=[...p,...d.eventProcessors];return(r.data&&r.data.__sentry__===!0?kt(o):bp(g,o,r)).then(b=>(b&&_f(b),typeof a=="number"&&a>0?Sf(b,a,c):b))}function hf(e,t){let{environment:r,release:n,dist:i,maxValueLength:s}=t;e.environment=e.environment||r||Zr,!e.release&&n&&(e.release=n),!e.dist&&i&&(e.dist=i);let a=e.request;a?.url&&s&&(a.url=Ir(a.url,s)),s&&e.exception?.values?.forEach(c=>{c.value&&(c.value=Ir(c.value,s))})}function bf(e,t){let r=Sp(t);e.exception?.values?.forEach(n=>{n.stacktrace?.frames?.forEach(i=>{i.filename&&(i.debug_id=r[i.filename])})})}function _f(e){let t={};if(e.exception?.values?.forEach(n=>{n.stacktrace?.frames?.forEach(i=>{i.debug_id&&(i.abs_path?t[i.abs_path]=i.debug_id:i.filename&&(t[i.filename]=i.debug_id),delete i.debug_id)})}),Object.keys(t).length===0)return;e.debug_meta=e.debug_meta||{},e.debug_meta.images=e.debug_meta.images||[];let r=e.debug_meta.images;Object.entries(t).forEach(([n,i])=>{r.push({type:"sourcemap",code_file:n,debug_id:i})})}function yf(e,t){t.length>0&&(e.sdk=e.sdk||{},e.sdk.integrations=[...e.sdk.integrations||[],...t])}function Sf(e,t,r){if(!e)return null;let n={...e,...e.breadcrumbs&&{breadcrumbs:e.breadcrumbs.map(i=>({...i,...i.data&&{data:Me(i.data,t,r)}}))},...e.user&&{user:Me(e.user,t,r)},...e.contexts&&{contexts:Me(e.contexts,t,r)},...e.extra&&{extra:Me(e.extra,t,r)}};return e.contexts?.trace&&n.contexts&&(n.contexts.trace=e.contexts.trace,e.contexts.trace.data&&(n.contexts.trace.data=Me(e.contexts.trace.data,t,r))),e.spans&&(n.spans=e.spans.map(i=>({...i,...i.data&&{data:Me(i.data,t,r)}}))),e.contexts?.flags&&n.contexts&&(n.contexts.flags=Me(e.contexts.flags,3,r)),n}function vf(e,t){if(!t)return e;let r=e?e.clone():new $e;return r.update(t),r}function vp(e){if(e)return Ef(e)?{captureContext:e}:If(e)?{captureContext:e}:e}function Ef(e){return e instanceof $e||typeof e=="function"}var Tf=["user","level","extra","contexts","tags","fingerprint","propagationContext"];function If(e){return Object.keys(e).some(t=>Tf.includes(t))}function Mr(e,t){return R().captureException(e,vp(t))}function sn(e,t){return R().captureEvent(e,t)}function ci(e,t){me().setContext(e,t)}function li(){let e=E();return e?.getOptions().enabled!==!1&&!!e?.getTransport()}function pi(e){me().addEventProcessor(e)}function an(e){let t=me(),{user:r}=fs(t,R()),{userAgent:n}=T.navigator||{},i=bl({user:r,...n&&{userAgent:n},...e}),s=t.getSession();return s?.status==="ok"&&Ft(s,{status:"exited"}),ui(),t.setSession(i),i}function ui(){let e=me(),r=R().getSession()||e.getSession();r&&_l(r),Ep(),e.setSession()}function Ep(){let e=me(),t=E(),r=e.getSession();r&&t&&t.captureSession(r)}function Lr(e=!1){if(e){ui();return}Ep()}function bs(e){return typeof e=="object"&&typeof e.unref=="function"&&e.unref(),e}var Af="7";function Rf(e){let t=e.protocol?`${e.protocol}:`:"",r=e.port?`:${e.port}`:"";return`${t}//${e.host}${r}${e.path?`/${e.path}`:""}/api/`}function Of(e){return`${Rf(e)}${e.projectId}/envelope/`}function xf(e,t){let r={sentry_version:Af};return e.publicKey&&(r.sentry_key=e.publicKey),t&&(r.sentry_client=`${t.name}/${t.version}`),new URLSearchParams(r).toString()}function Tp(e,t,r){return t||`${Of(e)}?${xf(e,r)}`}function yo(){return typeof __SENTRY_BROWSER_BUNDLE__<"u"&&!!__SENTRY_BROWSER_BUNDLE__}function So(){return"npm"}function Ip(){return!yo()&&Object.prototype.toString.call(typeof process<"u"?process:0)==="[object process]"}function at(){return typeof window<"u"&&(!Ip()||kf())}function kf(){return T.process?.type==="renderer"}function Nf(e,t){let r=t?"auto":"never";return[{type:"log",item_count:e.length,content_type:"application/vnd.sentry.items.log+json"},{version:2,...at()&&{ingest_settings:{infer_ip:r,infer_user_agent:r}},items:e}]}function Ap(e,t,r,n,i){let s={};return t?.sdk&&(s.sdk={name:t.sdk.name,version:t.sdk.version}),r&&n&&(s.dsn=yt(n)),He(s,[Nf(e,i)])}function Rp(e,t){let r=t??wf(e)??[];if(r.length===0)return;let n=e.getOptions(),i=Ap(r,n._metadata,n.tunnel,e.getDsn(),e.getDataCollectionOptions().userInfo);Op().set(e,[]),e.emit("flushLogs"),e.sendEnvelope(i)}function wf(e){return Op().get(e)}function Op(){return gt("clientToLogBufferMap",()=>new WeakMap)}function Cf(e,t){let r=t?"auto":"never";return[{type:"trace_metric",item_count:e.length,content_type:"application/vnd.sentry.items.trace-metric+json"},{version:2,...at()&&{ingest_settings:{infer_ip:r,infer_user_agent:r}},items:e}]}function xp(e,t,r,n,i){let s={};return t?.sdk&&(s.sdk={name:t.sdk.name,version:t.sdk.version}),r&&n&&(s.dsn=yt(n)),He(s,[Cf(e,i)])}function kp(e,t){let r=t??Mf(e)??[];if(r.length===0)return;let n=e.getOptions(),i=xp(r,n._metadata,n.tunnel,e.getDsn(),e.getDataCollectionOptions().userInfo);Np().set(e,[]),e.emit("flushMetrics"),e.sendEnvelope(i)}function Mf(e){return Np().get(e)}function Np(){return gt("clientToMetricBufferMap",()=>new WeakMap)}function wp(e){let t={trace_id:e.trace_id,span_id:e.span_id,parent_span_id:e.parent_span_id,name:e.description||"",start_timestamp:e.start_timestamp,end_timestamp:e.timestamp||e.start_timestamp,status:!e.status||e.status==="ok"||e.status==="cancelled"?"ok":"error",is_segment:!1,attributes:{...e.data},links:e.links};return Yl(t)}function Cp(e,t){if(e.type!=="transaction"||!e.spans?.length||!e.sdkProcessingMetadata?.hasGenAiSpans||t.getOptions().streamGenAiSpans===!1||Te(t))return;let r=[],n=[];for(let s of e.spans)s.op?.startsWith("gen_ai.")?r.push(wp(s)):n.push(s);if(r.length===0)return;e.spans=n;let i=t.getDataCollectionOptions().userInfo?"auto":"never";return[{type:"span",item_count:r.length,content_type:"application/vnd.sentry.items.span.v2+json"},{version:2,...at()&&{ingest_settings:{infer_ip:i,infer_user_agent:i}},items:r}]}var on=Symbol.for("SentryBufferFullError");function Pr(e=100){let t=new Set;function r(){return t.sizen(c),()=>n(c)),c}function s(a){if(!t.size)return kt(!0);let c=Promise.allSettled(Array.from(t)).then(()=>!0);if(!a)return c;let o=[c,new Promise(l=>bs(setTimeout(()=>l(!1),a)))];return Promise.race(o)}return{get $(){return Array.from(t)},add:i,drain:s}}var Mp=60*1e3;function Lp(e,t=it()){let r=parseInt(`${e}`,10);if(!isNaN(r))return r*1e3;let n=Date.parse(`${e}`);return isNaN(n)?Mp:n-t}function Pp(e,t){return e[t]||e.all||0}function di(e,t,r=it()){return Pp(e,t)>r}function mi(e,{statusCode:t,headers:r},n=it()){let i={...e},s=r?.["x-sentry-rate-limits"],a=r?.["retry-after"];if(s)for(let c of s.trim().split(",")){let[o,l,,,u]=c.split(":",5),p=parseInt(o,10),d=(isNaN(p)?60:p)*1e3;if(!l)i.all=n+d;else for(let m of l.split(";"))m==="metric_bucket"?(!u||u.split(";").includes("custom"))&&(i[m]=n+d):i[m]=n+d}else a?i.all=n+Lp(a,n):t===429&&(i.all=n+60*1e3);return i}var vo=64;function _s(e,t,r=Pr(e.bufferSize||vo)){let n={},i=a=>r.drain(a);function s(a){let c=[];if(ei(a,(p,d)=>{let m=ds(d);di(n,m)?e.recordDroppedEvent("ratelimit_backoff",m):c.push(p)}),c.length===0)return Promise.resolve({});let o=He(a[0],c),l=p=>{if(ao(o,["client_report"])){_&&f.warn(`Dropping client report. Will not send outcomes (reason: ${p}).`);return}ei(o,(d,m)=>{e.recordDroppedEvent(p,ds(m))})},u=()=>t({body:oo(o)}).then(p=>p.statusCode===413?(_&&f.error("Sentry responded with status code 413. Envelope was discarded due to exceeding size limits."),l("send_error"),p):(_&&p.statusCode!==void 0&&(p.statusCode<200||p.statusCode>=300)&&f.warn(`Sentry responded with status code ${p.statusCode} to sent event.`),n=mi(n,p),p),p=>{throw l("network_error"),_&&f.error("Encountered error running transport request:",p),p});return r.add(u).then(p=>p,p=>{if(p===on)return _&&f.error("Skipped sending event because buffer is full."),l("queue_overflow"),Promise.resolve({});throw p})}return{send:s,flush:i}}function Dp(e,t,r){let n=[{type:"client_report"},{timestamp:r||Ve(),discarded_events:e}];return He(t?{dsn:t}:{},[n])}function ys(e){let t=[];e.message&&t.push(e.message);try{let r=e.exception.values[e.exception.values.length-1];r?.value&&(t.push(r.value),r.type&&t.push(`${r.type}: ${r.value}`))}catch{}return t}function Up(e){let{trace_id:t,parent_span_id:r,span_id:n,status:i,origin:s,data:a,op:c}=e.contexts?.trace??{};return{data:a??{},description:e.transaction,op:c,parent_span_id:r,span_id:n??"",start_timestamp:e.start_timestamp??0,status:i,timestamp:e.timestamp,trace_id:t??"",origin:s,profile_id:a?.[Or],exclusive_time:a?.[De],measurements:e.measurements,is_segment:!0}}function Fp(e){return{type:"transaction",timestamp:e.timestamp,start_timestamp:e.start_timestamp,transaction:e.description,contexts:{trace:{trace_id:e.trace_id,span_id:e.span_id,parent_span_id:e.parent_span_id,op:e.op,status:e.status,origin:e.origin,data:{...e.data,...e.profile_id&&{[Or]:e.profile_id},...e.exclusive_time&&{[De]:e.exclusive_time}}}},measurements:e.measurements}}var gi=["forwarded","-ip","remote-","via","-user"];function Bp(e){return e===!0?{userInfo:!0,cookies:!0,httpHeaders:{request:!0,response:!0},httpBodies:["incomingRequest","outgoingRequest","incomingResponse","outgoingResponse"],urlQueryParams:!0,graphQL:{document:!0,variables:!0},genAI:{inputs:!0,outputs:!0},databaseQueryData:!0,stackFrameVariables:!0,frameContextLines:7}:{userInfo:!1,cookies:{deny:gi},httpHeaders:{request:{deny:gi},response:{deny:gi}},httpBodies:[],urlQueryParams:{deny:gi},graphQL:{document:!0,variables:!0},genAI:{inputs:!1,outputs:!1},databaseQueryData:!1,stackFrameVariables:!0,frameContextLines:7}}var Lf={userInfo:!0,cookies:!0,httpHeaders:{request:!0,response:!0},httpBodies:["incomingRequest","outgoingRequest","incomingResponse","outgoingResponse"],urlQueryParams:!0,graphQL:{document:!0,variables:!0},genAI:{inputs:!0,outputs:!0},databaseQueryData:!0,stackFrameVariables:!0,frameContextLines:5};function qp(e){let t=e.dataCollection!=null?Lf:Bp(e.sendDefaultPii),r=e.dataCollection??{};return{userInfo:r.userInfo??t.userInfo,cookies:r.cookies??t.cookies,httpHeaders:{request:r.httpHeaders?.request??t.httpHeaders.request,response:r.httpHeaders?.response??t.httpHeaders.response},httpBodies:r.httpBodies??t.httpBodies,urlQueryParams:r.urlQueryParams??r.queryParams??t.urlQueryParams,graphQL:{document:r.graphQL?.document??t.graphQL.document,variables:r.graphQL?.variables??t.graphQL.variables},genAI:{inputs:r.genAI?.inputs??t.genAI.inputs,outputs:r.genAI?.outputs??t.genAI.outputs},databaseQueryData:r.databaseQueryData??t.databaseQueryData,stackFrameVariables:r.stackFrameVariables??t.stackFrameVariables,frameContextLines:r.frameContextLines??t.frameContextLines}}var Hp="Not capturing exception because it's already been captured.",Gp="Discarded session because of missing or non-string release",$p=Symbol.for("SentryInternalError"),Kp=Symbol.for("SentryDoNotSendEventError"),Pf=5e3;function Ss(e){return{message:e,[$p]:!0}}function Eo(e){return{message:e,[Kp]:!0}}function Wp(e){return Ze(e)&&$p in e}function Yp(e){return Ze(e)&&Kp in e}function zp(e,t,r,n,i){let s=0,a,c=!1;e.on(r,()=>{s=0,clearTimeout(a),c=!1}),e.on(t,o=>{if(s+=n(o),s>=8e5)i(e);else if(!c){let l=e.getOptions()._flushInterval??Pf;l>0&&(c=!0,a=bs(setTimeout(()=>{i(e)},l)))}}),e.on("flush",()=>{i(e)})}var fi=class{constructor(t){if(this._options=t,this._integrations={},this._numProcessing=0,this._outcomes={},this._hooks={},this._eventProcessors=[],this._promiseBuffer=Pr(t.transportOptions?.bufferSize??vo),this._dataCollection=qp(t),t.dsn?this._dsn=Dl(t.dsn):_&&f.warn("No DSN provided, client will not send events."),this._dsn){let n=Tp(this._dsn,t.tunnel,t._metadata?t._metadata.sdk:void 0);this._transport=t.transport({tunnel:this._options.tunnel,recordDroppedEvent:this.recordDroppedEvent.bind(this),...t.transportOptions,url:n})}this._options.enableLogs=this._options.enableLogs??this._options._experiments?.enableLogs??!0,this._options.enableLogs&&zp(this,"afterCaptureLog","flushLogs",Bf,Rp),(this._options.enableMetrics??this._options._experiments?.enableMetrics??!0)&&zp(this,"afterCaptureMetric","flushMetrics",Ff,kp)}captureException(t,r,n){let i=he();if(Bn(t))return _&&f.log(Hp),i;let s={event_id:i,...r};return this._process(()=>this.eventFromException(t,s).then(a=>this._captureEvent(a,s,n)).then(a=>a),"error"),s.event_id}captureMessage(t,r,n,i){let s={event_id:he(),...n},a=er(t)?t:String(t),c=ze(t),o=c?this.eventFromMessage(a,r,s):this.eventFromException(t,s);return this._process(()=>o.then(l=>this._captureEvent(l,s,i)),c?"unknown":"error"),s.event_id}captureEvent(t,r,n){let i=he();if(r?.originalException&&Bn(r.originalException))return _&&f.log(Hp),i;let s={event_id:i,...r},a=t.sdkProcessingMetadata||{},c=a.capturedSpanScope,o=a.capturedSpanIsolationScope,l=Vp(t.type);return this._process(()=>this._captureEvent(t,s,c||n,o),l),s.event_id}captureSession(t){this.sendSession(t),Ft(t,{init:!1})}getDsn(){return this._dsn}getOptions(){return this._options}getDataCollectionOptions(){return this._dataCollection}getSdkMetadata(){return this._options._metadata}getTransport(){return this._transport}async flush(t){let r=this._transport;if(this.emit("flush"),!r)return!0;let n=await this._isClientDoneProcessing(t),i=await r.flush(t);return n&&i}async close(t){let r=await this.flush(t);return this.getOptions().enabled=!1,this.emit("close"),r}getEventProcessors(){return this._eventProcessors}addEventProcessor(t){this._eventProcessors.push(t)}init(){(this._isEnabled()||this._options.integrations.some(({name:t})=>t.startsWith("Spotlight")))&&this._setupIntegrations()}getIntegrationByName(t){return this._integrations[t]}getIntegrationNames(){return Object.keys(this._integrations)}addIntegration(t){let r=this._integrations[t.name];!r&&t.beforeSetup&&t.beforeSetup(this),za(this,t,this._integrations),r||Ya(this,[t])}sendEvent(t,r={}){this.emit("beforeSendEvent",t,r);let n=Cp(t,this),i=ep(t,this._dsn,this._options._metadata,this._options.tunnel);for(let s of r.attachments||[])i=us(i,lo(s));n&&(i=us(i,n)),this.sendEnvelope(i).then(s=>this.emit("afterSendEvent",t,s))}sendSession(t){let{release:r,environment:n=Zr}=this._options;if("aggregates"in t){let s=t.attrs||{};if(!s.release&&!r){_&&f.warn(Gp);return}s.release=s.release||r,s.environment=s.environment||n,t.attrs=s}else{if(!t.release&&!r){_&&f.warn(Gp);return}t.release=t.release||r,t.environment=t.environment||n}this.emit("beforeSendSession",t);let i=Zl(t,this._dsn,this._options._metadata,this._options.tunnel);this.sendEnvelope(i)}recordDroppedEvent(t,r,n=1){if(this._options.sendClientReports){let i=`${t}:${r}`;_&&f.log(`Recording outcome: "${i}"${n>1?` (${n} times)`:""}`),this._outcomes[i]=(this._outcomes[i]||0)+n}}on(t,r){let n=this._hooks[t]=this._hooks[t]||new Set,i=(...s)=>r(...s);return n.add(i),()=>{n.delete(i)}}emit(t,...r){let n=this._hooks[t];n&&n.forEach(i=>i(...r))}async sendEnvelope(t){if(this.emit("beforeEnvelope",t),this._isEnabled()&&this._transport)try{return await this._transport.send(t)}catch(r){return _&&f.error("Error while sending envelope:",r),{}}return _&&f.error("Transport disabled"),{}}registerCleanup(t){}dispose(){}_setupIntegrations(){let{integrations:t}=this._options;this._integrations=Ol(this,t),Ya(this,t)}_updateSessionFromEvent(t,r){let n=r.level==="fatal",i=!1,s=r.exception?.values;if(s){i=!0,n=!1;for(let o of s)if(o.mechanism?.handled===!1){n=!0;break}}let a=t.status==="ok";(a&&t.errors===0||a&&n)&&(Ft(t,{...n&&{status:"crashed"},errors:t.errors||Number(i||n)}),this.captureSession(t))}async _isClientDoneProcessing(t){let r=0;for(;!t||rsetTimeout(n,1)),!this._numProcessing)return!0;r++}return!1}_isEnabled(){return this.getOptions().enabled!==!1&&this._transport!==void 0}_prepareEvent(t,r,n,i){let s=this.getOptions(),a=this.getIntegrationNames();return!r.integrations&&a.length&&(r.integrations=a),this.emit("preprocessEvent",t,r),t.type||i.setLastEventId(t.event_id||r.event_id),oi(s,t,r,n,this,i).then(c=>{if(c===null)return c;this.emit("postprocessEvent",c,r),c.contexts={trace:{...c.contexts?.trace,...Qi(n)},...c.contexts};let o=wr(this,n);return c.sdkProcessingMetadata={dynamicSamplingContext:o,...c.sdkProcessingMetadata},c})}_captureEvent(t,r={},n=R(),i=me()){return _&&To(t)&&f.log(`Captured error event \`${ys(t)[0]||""}\``),this._processEvent(t,r,n,i).then(s=>s.event_id,s=>{_&&(Yp(s)?f.log(s.message):Wp(s)?f.warn(s.message):f.warn(s))})}_processEvent(t,r,n,i){let s=this.getOptions(),{sampleRate:a}=s,c=Xp(t),o=To(t),u=`before send for type \`${t.type||"error"}\``,p=typeof a>"u"?void 0:et(a),d=Vp(t.type);return this._prepareEvent(t,r,n,i).then(m=>{if(m===null)throw this.recordDroppedEvent("event_processor",d),Eo("An event processor returned `null`, will not send event.");if(r.data?.__sentry__===!0)return m;let h=Uf(this,s,m,r);return Df(h,u)}).then(m=>{if(m===null){if(this.recordDroppedEvent("before_send",d),c){let b=1+(t.spans||[]).length;this.recordDroppedEvent("before_send","span",b)}throw Eo(`${u} returned \`null\`, will not send event.`)}let g=n.getSession()||i.getSession();if(o&&g&&this._updateSessionFromEvent(g,m),o&&typeof p=="number"&&nt()>p)throw this.recordDroppedEvent("sample_rate","error"),Eo(`Discarding event because it's not included in the random sample (sampling rate = ${a})`);if(c){let S=m.sdkProcessingMetadata?.spanCountBeforeProcessing||0,b=m.spans?m.spans.length:0,C=S-b;C>0&&this.recordDroppedEvent("before_send","span",C)}let h=m.transaction_info;if(c&&h&&m.transaction!==t.transaction){let S="custom";m.transaction_info={...h,source:S}}return this.sendEvent(m,r),m}).then(null,m=>{throw Yp(m)||Wp(m)?m:(this.captureException(m,{mechanism:{handled:!1,type:"internal"},data:{__sentry__:!0},originalException:m}),Ss(`Event processing pipeline threw an error, original event will not be sent. Details have been sent as a new event. +Reason: ${m}`))})}_process(t,r){this._numProcessing++,this._promiseBuffer.add(t).then(n=>(this._numProcessing--,n),n=>(this._numProcessing--,n===on&&this.recordDroppedEvent("queue_overflow",r),n))}_clearOutcomes(){let t=this._outcomes;return this._outcomes={},Object.entries(t).map(([r,n])=>{let[i,s]=r.split(":");return{reason:i,category:s,quantity:n}})}_flushOutcomes(){_&&f.log("Flushing outcomes...");let t=this._clearOutcomes();if(t.length===0){_&&f.log("No outcomes to send");return}if(!this._dsn){_&&f.log("No dsn provided, will not send outcomes");return}_&&f.log("Sending outcomes:",t);let r=Dp(t,this._options.tunnel&&yt(this._dsn));this.sendEnvelope(r)}};function Vp(e){return e==="replay_event"?"replay":e||"error"}function Df(e,t){let r=`${t} must return \`null\` or a valid event.`;if(ft(e))return e.then(n=>{if(!Rt(n)&&n!==null)throw Ss(r);return n},n=>{throw Ss(`${t} rejected with ${n}`)});if(!Rt(e)&&e!==null)throw Ss(r);return e}function Uf(e,t,r,n){let{beforeSend:i,beforeSendTransaction:s,ignoreSpans:a}=t,c=!ps(t.beforeSendSpan)&&t.beforeSendSpan,o=r;if(To(o)&&i)return i(o,n);if(Xp(o)){if(c||a){let l=Up(o);if(a?.length&&Wt({description:l.description,op:l.op,attributes:l.data},a))return null;if(c){let u=c(l);u?o=ir(r,Fp(u)):Zn()}if(o.spans){let u=[],p=o.spans;for(let m of p){if(a?.length&&Wt({description:m.description,op:m.op,attributes:m.data},a)){Kl(p,m);continue}if(c){let g=c(m);g?u.push(g):(Zn(),u.push(m))}else u.push(m)}let d=o.spans.length-u.length;d&&e.recordDroppedEvent("before_send","span",d),o.spans=u}}if(s){if(o.spans){let l=o.spans.length;o.sdkProcessingMetadata={...r.sdkProcessingMetadata,spanCountBeforeProcessing:l}}return s(o,n)}}return o}function To(e){return e.type===void 0}function Xp(e){return e.type==="transaction"}function Ff(e){let t=0;return e.name&&(t+=e.name.length*2),t+=8,t+Jp(e.attributes)}function Bf(e){let t=0;return e.message&&(t+=e.message.length*2),t+Jp(e.attributes)}function Jp(e){if(!e)return 0;let t=0;return Object.values(e).forEach(r=>{Array.isArray(r)?t+=r.length*jp(r[0]):ze(r)?t+=jp(r):t+=100}),t}function jp(e){return typeof e=="string"?e.length*2:typeof e=="number"?8:typeof e=="boolean"?4:0}function Io(e,t){t.debug===!0&&(_?f.enable():Oe(()=>{console.warn("[Sentry] Cannot initialize SDK with `debug` option using a non-debug bundle.")})),R().update(t.initialScope);let n=new e(t);return Ao(n),n.init(),n}function Ao(e){R().setClient(e)}var qf="thismessage:/";function zt(e){return"isRelative"in e}function vt(e,t){let r=e.indexOf("://")<=0&&e.indexOf("//")!==0,n=t??(r?qf:void 0);try{if("canParse"in URL&&!URL.canParse(e,n))return;let i=new URL(e,n);return r?{isRelative:r,pathname:i.pathname,search:i.search,hash:i.hash}:i}catch{}}function cn(e){if(zt(e))return e.pathname;let t=new URL(e);return t.search="",t.hash="",["80","443"].includes(t.port)&&(t.port=""),t.password&&(t.password="%filtered%"),t.username&&(t.username="%filtered%"),t.toString()}function ot(e){if(!e)return{};let t=e.match(/^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/);if(!t)return{};let r=t[6]||"",n=t[8]||"";return{host:t[4],path:t[5],protocol:t[2],search:r,hash:n,relative:t[5]+r+n}}function vs(e){return e.split(/[?#]/,1)[0]}function Ne(e,t=!0){if(e.startsWith("data:")){let r=e.match(/^data:([^;,]+)/),n=r?r[1]:"text/plain",i=e.includes(";base64,"),s=e.indexOf(","),a="";if(t&&s!==-1){let c=e.slice(s+1);a=c.length>10?`${c.slice(0,10)}... [truncated]`:c}return`data:${n}${i?",base64":""}${a?`,${a}`:""}`}return e}function Ro(e,t){let r=t?.getDsn(),n=t?.getOptions().tunnel;return Gf(e,r)||Hf(e,n)}function Hf(e,t){return t?Qp(e)===Qp(t):!1}function Gf(e,t){let r=vt(e);return!r||zt(r)||!t?!1:Wf(r.hostname,t.host)&&/(^|&|\?)sentry_key=/.test(r.search)}function Wf(e,t){return e===t||t.length>0&&e.endsWith(`.${t}`)}function Qp(e){return e[e.length-1]==="/"?e.slice(0,-1):e}function Oo(e){"aggregates"in e?e.attrs?.ip_address===void 0&&(e.attrs={...e.attrs,ip_address:"{{auto}}"}):e.ipAddress===void 0&&(e.ipAddress="{{auto}}")}function xo(e,t,r=[t],n="npm"){let i=(e._metadata=e._metadata||{}).sdk=e._metadata.sdk||{};i.name||(i.name=`sentry.javascript.${t}`,i.packages=r.map(s=>({name:`${n}:@sentry/${s}`,version:At})),i.version=At)}function ln(e={}){let t=e.client||E();if(!li()||!t)return{};let r=Ue(),n=Ot(r);if(n.getTraceData)return n.getTraceData(e);let i=e.scope||R(),s=e.span||te(),a=xt(s)&&!_e(t.getOptions());if(!s&&Ji())return{};let c=s&&!a?Kn(s):Yf(i),o=s?ke(s):wr(t,i),l=Qa(o);if(!ns.test(c))return f.warn("Invalid sentry-trace data. Cannot generate trace data"),{};let p={"sentry-trace":c,baggage:l};return e.propagateTraceparent&&(p.traceparent=s&&!a?Gl(s):zf(i)),p}function Yf(e){let{traceId:t,sampled:r,propagationSpanId:n}=e.getPropagationContext();return zn(t,n,r)}function zf(e){let{traceId:t,sampled:r,propagationSpanId:n}=e.getPropagationContext();return Vn(t,n,r)}var Vf=100;function tt(e,t){let r=E(),n=me();if(!r)return;let{beforeBreadcrumb:i=null,maxBreadcrumbs:s=Vf}=r.getOptions();if(s<=0)return;let c={timestamp:Ve(),...e},o=i?Oe(()=>i(c,t)):c;o!==null&&(r.emit&&r.emit("beforeAddBreadcrumb",o,t),n.addBreadcrumb(o,s))}var jf="FunctionToString",Zp=new WeakMap,$f=(()=>({name:jf,setupOnce(){let e=Function.prototype.toString;try{Function.prototype.toString=function(...t){let r=rr(this),n;try{Zp.has(E())&&r!==void 0&&(n=r)}catch{}return e.apply(n??this,t)}}catch{}},setup(e){Zp.set(e,!0)}})),Es=$f;var Kf=[/^Script error\.?$/,/^Javascript error: Script error\.? on line 0$/,/^ResizeObserver loop completed with undelivered notifications.$/,/^Cannot redefine property: googletag$/,/^Can't find variable: gmo$/,/^undefined is not an object \(evaluating 'a\.[A-Z]'\)$/,/can't redefine non-configurable property "solana"/,/vv\(\)\.getRestrictions is not a function/,/Can't find variable: _AutofillCallbackHandler/,/Object Not Found Matching Id:\d+, MethodName:simulateEvent/,/Java exception was raised during method invocation$/,/Java object is gone$/],Xf="EventFilters",ko=(e={})=>{let t;return{name:Xf,setup(r){let n=r.getOptions();t=eu(e,n)},processEvent(r,n,i){if(!t){let s=i.getOptions();t=eu(e,s)}return Jf(r,t)?null:r}}},Is=((e={})=>({...ko(e),name:"InboundFilters"}));function eu(e={},t={}){return{allowUrls:[...e.allowUrls||[],...t.allowUrls||[]],denyUrls:[...e.denyUrls||[],...t.denyUrls||[]],ignoreErrors:[...e.ignoreErrors||[],...t.ignoreErrors||[],...e.disableErrorDefaults?[]:Kf],ignoreTransactions:[...e.ignoreTransactions||[],...t.ignoreTransactions||[]]}}function Jf(e,t){if(e.type){if(e.type==="transaction"&&Zf(e,t.ignoreTransactions))return _&&f.warn(`Event dropped due to being matched by \`ignoreTransactions\` option. +Event: ${ht(e)}`),!0}else{if(Qf(e,t.ignoreErrors))return _&&f.warn(`Event dropped due to being matched by \`ignoreErrors\` option. +Event: ${ht(e)}`),!0;if(nh(e))return _&&f.warn(`Event dropped due to not having an error message, error type or stacktrace. +Event: ${ht(e)}`),!0;if(eh(e,t.denyUrls))return _&&f.warn(`Event dropped due to being matched by \`denyUrls\` option. +Event: ${ht(e)}. +Url: ${Ts(e)}`),!0;if(!th(e,t.allowUrls))return _&&f.warn(`Event dropped due to not being matched by \`allowUrls\` option. +Event: ${ht(e)}. +Url: ${Ts(e)}`),!0}return!1}function Qf(e,t){return t?.length?ys(e).some(r=>xe(r,t)):!1}function Zf(e,t){if(!t?.length)return!1;let r=e.transaction;return r?xe(r,t):!1}function eh(e,t){if(!t?.length)return!1;let r=Ts(e);return r?xe(r,t):!1}function th(e,t){if(!t?.length)return!0;let r=Ts(e);return r?xe(r,t):!0}function rh(e=[]){for(let t=e.length-1;t>=0;t--){let r=e[t];if(r&&r.filename!==""&&r.filename!=="[native code]")return r.filename||null}return null}function Ts(e){try{let r=[...e.exception?.values??[]].reverse().find(n=>n.mechanism?.parent_id===void 0&&n.stacktrace?.frames?.length)?.stacktrace?.frames;return r?rh(r):null}catch{return _&&f.error(`Cannot extract url for event ${ht(e)}`),null}}function nh(e){return e.exception?.values?.length?!e.message&&!e.exception.values.some(t=>t.stacktrace||t.type&&t.type!=="Error"||t.value):!1}function wo(e,t,r,n,i,s){if(!i.exception?.values||!s||!we(s.originalException))return;let a=i.exception.values.length>0?i.exception.values[i.exception.values.length-1]:void 0;a&&(i.exception.values=No(e,t,n,s.originalException,r,i.exception.values,a,0))}function No(e,t,r,n,i,s,a,c){if(s.length>=r+1)return s;let o=[...s];if(we(n[i])){tu(a,c,n);let l=e(t,n[i]),u=o.length;ru(l,i,u,c),o=No(e,t,r,n[i],i,[l,...o],l,u)}return nu(n)&&n.errors.forEach((l,u)=>{if(we(l)){tu(a,c,n);let p=e(t,l),d=o.length;ru(p,`errors[${u}]`,d,c),o=No(e,t,r,l,i,[p,...o],p,d)}}),o}function nu(e){return Array.isArray(e.errors)}function tu(e,t,r){e.mechanism={handled:!0,type:"auto.core.linked_errors",...nu(r)&&{is_exception_group:!0},...e.mechanism,exception_id:t}}function ru(e,t,r,n){e.mechanism={handled:!0,...e.mechanism,type:"chained",source:t,exception_id:r,parent_id:n}}function ih(e){return we(e)&&"__sentry_fetch_url_host__"in e&&typeof e.__sentry_fetch_url_host__=="string"}function As(e){return ih(e)?`${e.message} (${e.__sentry_fetch_url_host__})`:e.message}var iu=new Set([]);function Co(e){let t="console",r=Le(t,e);return Pe(t,sh),r}var su=new Set;function sh(){"console"in T&&Gi.forEach(function(e){su.has(e)||!(e in T.console)||(su.add(e),fe(T.console,e,function(t){return vr[e]=t,function(...r){let n=r[0],i=vr[e],s=iu.size&&typeof n=="string"&&xe(n,iu);s||ye("console",{args:r,level:e}),(!s||_&&f.isEnabled())&&i?.apply(T.console,r)}}))})}function pn(e){return e==="warn"?"warning":["fatal","error","warning","log","info","debug"].includes(e)?e:"log"}var ah="Dedupe",oh=(()=>{let e;return{name:ah,processEvent(t){if(t.type)return t;try{if(ch(t,e))return _&&f.warn("Event dropped due to being a duplicate of previously captured event."),null}catch{}return e=t}}}),Rs=oh;function ch(e,t){return t?!!(lh(e,t)||ph(e,t)):!1}function lh(e,t){let r=e.message,n=t.message;return!(!r&&!n||r&&!n||!r&&n||r!==n||!cu(e,t)||!ou(e,t))}function ph(e,t){let r=au(t),n=au(e);return!(!r||!n||r.type!==n.type||r.value!==n.value||!cu(e,t)||!ou(e,t))}function ou(e,t){let r=Dn(e),n=Dn(t);if(!r&&!n)return!0;if(r&&!n||!r&&n||(r=r,n=n,n.length!==r.length))return!1;for(let i=0;i({name:uh,setup(e){e.on("spanStart",t=>{let r=R().getScopeData(),n=me().getScopeData(),i=r.conversationId||n.conversationId;if(i){let{op:s,data:a,description:c}=O(t);if(!s?.startsWith("gen_ai.")&&!a["ai.operationId"]&&!c?.startsWith("ai."))return;t.setAttribute(ts,i)}})}})),Mo=dh;function Lo(e,t,r,n,i){if(!e.fetchData)return;let{method:s,url:a}=e.fetchData,c=_e()&&t(a);if(e.endTimestamp){let h=e.fetchData.__span;if(!h)return;let S=n[h];S&&(c&&(gh(S,e),mh(S,e,i)),delete n[h]);return}let{spanOrigin:o="auto.http.browser",propagateTraceparent:l=!1}=typeof i=="object"?i:{spanOrigin:i},u=E(),p=!!te(),d=p||!!u&&Te(u),m=c&&d?Ie(bh(a,s,o)):new Xe,g=rn(m)&&p?void 0:m;if(c&&!d&&u?.recordDroppedEvent("no_parent_span","span"),e.fetchData.__span=m.spanContext().spanId,n[m.spanContext().spanId]=m,r(e.fetchData.url)){let h=e.args[0],S={...e.args[1]||{}},b=pu(h,S,_e()&&d?g:void 0,l);b&&(e.args[1]=S,S.headers=b)}if(u){let h={input:e.args,response:e.response,startTimestamp:e.startTimestamp,endTimestamp:e.endTimestamp};u.emit("beforeOutgoingRequestSpan",m,h)}return m}function mh(e,t,r){(typeof r=="object"&&r!==null?r.onRequestSpanEnd:void 0)?.(e,{headers:t.response?.headers,error:t.error})}function pu(e,t,r,n){let i=ln({span:r,propagateTraceparent:n}),s=i["sentry-trace"],a=i.baggage,c=i.traceparent;if(!s)return;let o=t.headers||(Cn(e)?e.headers:void 0);if(o)if(fh(o)){let l=new Headers(o);if(l.get("sentry-trace")||l.set("sentry-trace",s),n&&c&&!l.get("traceparent")&&l.set("traceparent",c),a){let u=l.get("baggage");u?Os(u)||l.set("baggage",`${u},${a}`):l.set("baggage",a)}return l}else if(hh(o)){let l=[...o];l.find(p=>p[0]==="sentry-trace")||l.push(["sentry-trace",s]),n&&c&&!l.find(p=>p[0]==="traceparent")&&l.push(["traceparent",c]);let u=o.find(p=>p[0]==="baggage"&&typeof p[1]=="string"&&Os(p[1]));return a&&!u&&l.push(["baggage",a]),l}else{let l="sentry-trace"in o?o["sentry-trace"]:void 0,u="traceparent"in o?o.traceparent:void 0,p="baggage"in o?o.baggage:void 0,d=p?Array.isArray(p)?[...p]:[p]:[],m=p&&(Array.isArray(p)?p.find(h=>Os(h)):Os(p));a&&!m&&d.push(a);let g=Object.assign({},o,{"sentry-trace":l??s,...d.length>0&&{baggage:d.join(",")}});return n&&c&&!u&&(g.traceparent=c),g}else return{"sentry-trace":s,...a&&{baggage:a},...c&&{traceparent:c}}}function gh(e,t){if(t.response){Qr(e,t.response.status);let r=t.response?.headers?.get("content-length");if(r){let n=parseInt(r);n>0&&e.setAttribute("http.response_content_length",n)}}else t.error&&e.setStatus({code:2,message:"internal_error"});e.end()}function Os(e){return typeof e!="string"?!1:e.split(",").some(t=>t.trim().startsWith(Yn))}function fh(e){return typeof Headers<"u"&&Er(e,Headers)}function hh(e){return Array.isArray(e)?e.every(t=>Array.isArray(t)&&t.length===2&&typeof t[0]=="string"):!1}function bh(e,t,r){if(e.startsWith("data:")){let s=Ne(e);return{name:`${t} ${s}`,attributes:lu(e,void 0,t,r)}}let n=vt(e),i=n?cn(n):e;return{name:`${t} ${i}`,attributes:lu(e,n,t,r)}}function lu(e,t,r,n){let i={url:Ne(e),type:"fetch","http.method":r,[j]:n,[de]:"http.client"};return t&&(zt(t)||(i[hs]=Ne(t.href),i[St]=Ne(t.href),i["server.address"]=t.host),t.search&&(i["http.query"]=t.search),t.hash&&(i["http.fragment"]=t.hash)),i}function uu(e,t={},r=R()){let{message:n,name:i,email:s,url:a,source:c,associatedEventId:o,tags:l}=e,u={contexts:{feedback:{contact_email:s,name:i,message:n,url:a,source:c,associated_event_id:o}},type:"feedback",level:"info",tags:l},p=r?.getClient()||E();return p&&p.emit("beforeSendFeedback",u,t),r.captureEvent(u,t)}function xs(e){if(e!==void 0)return e>=400&&e<500?"warning":e>=500?"error":void 0}var hi=T;function Po(){return"history"in hi&&!!hi.history}function _h(){if(!("fetch"in hi))return!1;try{return new Headers,new Request("data:,"),new Response,!0}catch{return!1}}function bi(e){return e&&/^function\s+\w+\(\)\s+\{\s+\[native code\]\s+\}$/.test(e.toString())}function Do(){if(typeof EdgeRuntime=="string")return!0;if(!_h())return!1;if(bi(hi.fetch))return!0;let e=!1,t=hi.document;if(t&&typeof t.createElement=="function")try{let r=t.createElement("iframe");r.hidden=!0,t.head.appendChild(r),r.contentWindow?.fetch&&(e=bi(r.contentWindow.fetch)),t.head.removeChild(r)}catch(r){_&&f.warn("Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ",r)}return e}function pr(e,t){let r="fetch",n=Le(r,e);return Pe(r,()=>mu(void 0,t)),n}function Ns(e){let t="fetch-body-resolved",r=Le(t,e);return Pe(t,()=>mu(Sh)),r}function mu(e,t=!1){t&&!Do()||fe(T,"fetch",function(r){return function(...n){let i=new Error,{method:s,url:a}=vh(n),c={args:n,fetchData:{method:s,url:a},startTimestamp:Q()*1e3,virtualError:i,headers:Eh(n)};return e||ye("fetch",{...c}),r.apply(T,n).then(async o=>(e?e(o):ye("fetch",{...c,endTimestamp:Q()*1e3,response:o}),o),o=>{ye("fetch",{...c,endTimestamp:Q()*1e3,error:o}),we(o)&&o.stack===void 0&&(o.stack=i.stack,ne(o,"framesToPop",1));let u=E()?.getOptions().enhanceFetchErrorMessages??"always";if(u!==!1&&we(o)&&o.name==="TypeError"&&(o.message==="Failed to fetch"||o.message==="Load failed"||o.message==="NetworkError when attempting to fetch resource."))try{let m=new URL(c.fetchData.url).host;u==="always"?o.message=`${o.message} (${m})`:ne(o,"__sentry_fetch_url_host__",m)}catch{}throw o})}})}async function yh(e,t){if(e?.body){let r=e.body,n=r.getReader(),i=setTimeout(()=>{r.cancel().then(null,()=>{})},90*1e3),s=!0;for(;s;){let a;try{a=setTimeout(()=>{r.cancel().then(null,()=>{})},5e3);let{done:c}=await n.read();clearTimeout(a),c&&(t(),s=!1)}catch{s=!1}finally{clearTimeout(a)}}clearTimeout(i),n.releaseLock(),r.cancel().then(null,()=>{})}}function Sh(e){let t;try{t=e.clone()}catch{return}yh(t,()=>{ye("fetch-body-resolved",{endTimestamp:Q()*1e3,response:e})})}function ks(e,t){return Ze(e)&&!!e[t]}function du(e){return typeof e=="string"?e:e?ks(e,"url")?e.url:e.toString?e.toString():"":""}function vh(e){if(e.length===0)return{method:"GET",url:""};if(e.length===2){let[r,n]=e;return{url:du(r),method:ks(n,"method")?String(n.method).toUpperCase():Cn(r)&&ks(r,"method")?String(r.method).toUpperCase():"GET"}}let t=e[0];return{url:du(t),method:ks(t,"method")?String(t.method).toUpperCase():"GET"}}function Eh(e){let[t,r]=e;try{if(typeof r=="object"&&r!==null&&"headers"in r&&r.headers)return new Headers(r.headers);if(Cn(t))return new Headers(t.headers)}catch{}}var gu=T;function Ge(){try{return gu.document.location.href}catch{return""}}function un(e,t=5){if(!gu.HTMLElement)return null;let r=e;for(let n=0;n0}function pb(){Bo++,setTimeout(()=>{Bo--})}function Dr(e,t={}){function r(i){return typeof i=="function"}if(!r(e))return e;try{if(Object.prototype.hasOwnProperty.call(e,"__sentry_wrapped__")){let s=e.__sentry_wrapped__;return typeof s=="function"?s:e}if(rr(e))return e}catch{return e}let n=function(...i){T._sentryWrappedDepth=(T._sentryWrappedDepth||0)+1;try{let s=i.map(a=>Dr(a,t));return e.apply(this,s)}catch(s){throw pb(),ar(a=>{a.addEventProcessor(c=>(t.mechanism&&(Ar(c,void 0,void 0),st(c,t.mechanism)),c.extra={...c.extra,arguments:i},c)),Mr(s)}),s}finally{T._sentryWrappedDepth=(T._sentryWrappedDepth||0)-1}};try{for(let i in e)Object.prototype.hasOwnProperty.call(e,i)&&(n[i]=e[i])}catch{}Mn(n,e),ne(e,"__sentry_wrapped__",n);try{Object.getOwnPropertyDescriptor(n,"name").configurable&&Object.defineProperty(n,"name",{get(){return e.name}})}catch{}return n}function dn(){let e=Ge(),{referrer:t}=k.document||{},{userAgent:r}=k.navigator||{},n={...t&&{Referer:t},...r&&{"User-Agent":r}};return{url:e,headers:n}}var Ls=class extends fi{constructor(t){let r=ub(t),n=k.SENTRY_SDK_SOURCE||So();xo(r,"browser",["browser"],n),super(r);let{userInfo:i}=this.getDataCollectionOptions();r._metadata?.sdk&&(r._metadata.sdk.settings={infer_ip:i?"auto":"never",...r._metadata.sdk.settings});let{sendClientReports:s}=this._options;k.document&&k.document.addEventListener("visibilitychange",()=>{k.document.visibilityState==="hidden"&&(s&&this._flushOutcomes(),queueMicrotask(()=>{this.flush()}))}),i&&this.on("beforeSendSession",Oo)}eventFromException(t,r){return Uu(this._options.stackParser,t,r,this._options.attachStacktrace)}eventFromMessage(t,r="info",n){return Fu(this._options.stackParser,t,r,n,this._options.attachStacktrace)}_prepareEvent(t,r,n,i){return t.platform=t.platform||"javascript",super._prepareEvent(t,r,n,i)}};function ub(e){return{release:typeof __SENTRY_RELEASE__=="string"?__SENTRY_RELEASE__:k.SENTRY_RELEASE?.id,sendClientReports:!0,parentSpanIsAlwaysRootSpan:!0,...e}}var Ae=typeof __SENTRY_DEBUG__>"u"||__SENTRY_DEBUG__;var I=T;var db=(e,t)=>e>t[1]?"poor":e>t[0]?"needs-improvement":"good",Nt=(e,t,r,n)=>{let i,s;return a=>{t.value>=0&&(a||n)&&(s=t.value-(i??0),(s||i===void 0)&&(i=t.value,t.delta=s,t.rating=db(t.value,r),e(t)))}};var $t=(e=!0)=>{let t=I.performance?.getEntriesByType?.("navigation")[0];if(!e||t&&t.responseStart>0&&t.responseStart$t()?.activationStart??0;function lt(e,t,r){I.document&&I.addEventListener(e,t,r)}function Ur(e,t,r){I.document&&I.removeEventListener(e,t,r)}var mn=-1,Bu=new Set,mb=()=>I.document?.visibilityState==="hidden"&&!I.document?.prerendering?0:1/0,Ps=e=>{if(gb(e)&&mn>-1){if(e.type==="visibilitychange"||e.type==="pagehide")for(let t of Bu)t();isFinite(mn)||(mn=e.type==="visibilitychange"?e.timeStamp:0,Ur("prerenderingchange",Ps,!0))}},wt=()=>{if(I.document&&mn<0){let e=ct();mn=(I.document.prerendering?void 0:globalThis.performance.getEntriesByType("visibility-state").filter(r=>r.name==="hidden"&&r.startTime>e)[0]?.startTime)??mb(),lt("visibilitychange",Ps,!0),lt("pagehide",Ps,!0),lt("prerenderingchange",Ps,!0)}return{get firstHiddenTime(){return mn},onHidden(e){Bu.add(e)}}};function gb(e){return e.type==="pagehide"||I.document?.visibilityState==="hidden"}var qu=()=>`v5-${Date.now()}-${Math.floor(Math.random()*8999999999999)+1e12}`;var Ct=(e,t=-1)=>{let r=$t(),n="navigate";return r&&(I.document?.prerendering||ct()>0?n="prerender":I.document?.wasDiscarded?n="restore":r.type&&(n=r.type.replace(/_/g,"-"))),{name:e,value:t,rating:"good",delta:0,entries:[],id:qu(),navigationType:n}};var Ho=new WeakMap;function gn(e,t){try{return Ho.get(e)||Ho.set(e,new t),Ho.get(e)}catch{return new t}}var Ds=class{constructor(){this._sessionValue=0,this._sessionEntries=[]}_processEntry(t){if(t.hadRecentInput)return;let r=this._sessionEntries[0],n=this._sessionEntries[this._sessionEntries.length-1];this._sessionValue&&r&&n&&t.startTime-n.startTime<1e3&&t.startTime-r.startTime<5e3?(this._sessionValue+=t.value,this._sessionEntries.push(t)):(this._sessionValue=t.value,this._sessionEntries=[t]),this._onAfterProcessingUnexpectedShift?.(t)}};var pt=(e,t,r={})=>{try{if(PerformanceObserver.supportedEntryTypes.includes(e)){let n=new PerformanceObserver(i=>{Promise.resolve().then(()=>{t(i.getEntries())})});return n.observe({type:e,buffered:!0,...r}),n}}catch{}};var fn=e=>{let t=!1;return()=>{t||(e(),t=!0)}};var ur=e=>{I.document?.prerendering?addEventListener("prerenderingchange",()=>e(),!0):e()};var fb=[1800,3e3],Hu=(e,t={})=>{ur(()=>{let r=wt(),n=Ct("FCP"),i,a=pt("paint",c=>{for(let o of c)o.name==="first-contentful-paint"&&(a.disconnect(),o.startTime{Hu(fn(()=>{let r=Ct("CLS",0),n,i=wt(),s=gn(t,Ds),a=o=>{for(let l of o)s._processEntry(l);s._sessionValue>r.value&&(r.value=s._sessionValue,r.entries=s._sessionEntries,n())},c=pt("layout-shift",a);c&&(n=Nt(e,r,hb,t.reportAllChanges),i.onHidden(()=>{a(c.takeRecords()),n(!0)}),I?.setTimeout?.(n))}))};var Wu=0,Go=1/0,Us=0,bb=e=>{e.forEach(t=>{t.interactionId&&(Go=Math.min(Go,t.interactionId),Us=Math.max(Us,t.interactionId),Wu=Us?(Us-Go)/7+1:0)})},Wo,Yo=()=>Wo?Wu:performance.interactionCount||0,Yu=()=>{"interactionCount"in performance||Wo||(Wo=pt("event",bb,{type:"event",buffered:!0,durationThreshold:0}))};var zo=10,zu=0,_b=()=>Yo()-zu,Fs=class{constructor(){this._longestInteractionList=[],this._longestInteractionMap=new Map}_resetInteractions(){zu=Yo(),this._longestInteractionList.length=0,this._longestInteractionMap.clear()}_estimateP98LongestInteraction(){let t=Math.min(this._longestInteractionList.length-1,Math.floor(_b()/50));return this._longestInteractionList[t]}_processEntry(t){if(this._onBeforeProcessingEntry?.(t),!(t.interactionId||t.entryType==="first-input"))return;let r=this._longestInteractionList.at(-1),n=this._longestInteractionMap.get(t.interactionId);if(n||this._longestInteractionList.lengthr._latency){if(n?t.duration>n._latency?(n.entries=[t],n._latency=t.duration):t.duration===n._latency&&t.startTime===n.entries[0].startTime&&n.entries.push(t):(n={id:t.interactionId,entries:[t],_latency:t.duration},this._longestInteractionMap.set(n.id,n),this._longestInteractionList.push(n)),this._longestInteractionList.sort((i,s)=>s._latency-i._latency),this._longestInteractionList.length>zo){let i=this._longestInteractionList.splice(zo);for(let s of i)this._longestInteractionMap.delete(s.id)}this._onAfterProcessingINPCandidate?.(n)}}};var Fr=e=>{let t=I.requestIdleCallback||I.setTimeout;I.document?.visibilityState==="hidden"?e():(e=fn(e),lt("visibilitychange",e,{once:!0,capture:!0}),lt("pagehide",e,{once:!0,capture:!0}),t(()=>{e(),Ur("visibilitychange",e,{capture:!0}),Ur("pagehide",e,{capture:!0})}))};var yb=[200,500],Sb=40,Vu=(e,t={})=>{if(!(globalThis.PerformanceEventTiming&&"interactionId"in PerformanceEventTiming.prototype))return;let r=wt();ur(()=>{Yu();let n=Ct("INP"),i,s=gn(t,Fs),a=o=>{Fr(()=>{for(let u of o)s._processEntry(u);let l=s._estimateP98LongestInteraction();l&&l._latency!==n.value&&(n.value=l._latency,n.entries=l.entries,i())})},c=pt("event",a,{durationThreshold:t.durationThreshold??Sb});i=Nt(e,n,yb,t.reportAllChanges),c&&(c.observe({type:"first-input",buffered:!0}),r.onHidden(()=>{a(c.takeRecords()),i(!0)}))})};var Bs=class{_processEntry(t){this._onBeforeProcessingEntry?.(t)}};var vb=[2500,4e3],ju=(e,t={})=>{ur(()=>{let r=wt(),n=Ct("LCP"),i,s=gn(t,Bs),a=o=>{t.reportAllChanges||(o=o.slice(-1));for(let l of o)s._processEntry(l),l.startTime{a(c.takeRecords()),c.disconnect(),i(!0)}),l=u=>{u.isTrusted&&(Fr(o),Ur(u.type,l,{capture:!0}))};for(let u of["keydown","click","visibilitychange"])lt(u,l,{capture:!0})}})};var Eb=[800,1800],Vo=e=>{I.document?.prerendering?ur(()=>Vo(e)):I.document?.readyState!=="complete"?addEventListener("load",()=>Vo(e),!0):setTimeout(e)},$u=(e,t={})=>{let r=Ct("TTFB"),n=Nt(e,r,Eb,t.reportAllChanges);Vo(()=>{let i=$t();i&&(r.value=Math.max(i.responseStart-ct(),0),r.entries=[i],n(!0))})};var _i={},qs={},Ku,Xu,Ju,Qu;function Kt(e,t=!1){return Hs("cls",e,Tb,Ku,t)}function Xt(e,t=!1){return Hs("lcp",e,Ib,Xu,t)}function jo(e){return Hs("ttfb",e,Ab,Ju)}function Br(e){return Hs("inp",e,Rb,Qu)}function ut(e,t){return Zu(e,t),qs[e]||(Ob(e),qs[e]=!0),ed(e,t)}function yi(e,t){let r=_i[e];if(r?.length)for(let n of r)try{n(t)}catch(i){Ae&&f.error(`Error while triggering instrumentation handler. +Type: ${e} +Name: ${Fe(n)} +Error:`,i)}}function Tb(){return Gu(e=>{yi("cls",{metric:e}),Ku=e},{reportAllChanges:!0})}function Ib(){return ju(e=>{yi("lcp",{metric:e}),Xu=e},{reportAllChanges:!0})}function Ab(){return $u(e=>{yi("ttfb",{metric:e}),Ju=e})}function Rb(){return Vu(e=>{yi("inp",{metric:e}),Qu=e})}function Hs(e,t,r,n,i=!1){Zu(e,t);let s;return qs[e]||(s=r(),qs[e]=!0),n&&t({metric:n}),ed(e,t,i?s:void 0)}function Ob(e){let t={};e==="event"&&(t.durationThreshold=0),pt(e,r=>{yi(e,{entries:r})},t)}function Zu(e,t){_i[e]=_i[e]||[],_i[e].push(t)}function ed(e,t,r){return()=>{r&&r();let n=_i[e];if(!n)return;let i=n.indexOf(t);i!==-1&&n.splice(i,1)}}function td(e){return"duration"in e}var xb=80,qr={};try{typeof Node<"u"&&(qr.parentNode=Object.getOwnPropertyDescriptor(Node.prototype,"parentNode").get),typeof Element<"u"&&(qr.tagName=Object.getOwnPropertyDescriptor(Element.prototype,"tagName").get,qr.id=Object.getOwnPropertyDescriptor(Element.prototype,"id").get,qr.className=Object.getOwnPropertyDescriptor(Element.prototype,"className").get,qr.getAttribute=Element.prototype.getAttribute),typeof HTMLElement<"u"&&(qr.dataset=Object.getOwnPropertyDescriptor(HTMLElement.prototype,"dataset").get)}catch{}function dr(e,t,r){let n=qr[t];if(n)try{return n.call(e,r)}catch{}let i=e[t];return typeof i=="function"?i.call(e,r):i}function se(e,t={}){if(!e)return"";try{let r=e,n=5,i=[],s=0,a=0,c=" > ",o=c.length,l,u=Array.isArray(t)?t:t.keyAttrs,p=!Array.isArray(t)&&t.maxStringLength||xb;for(;r&&s++1&&a+i.length*o+l.length>=p));)i.push(l),a+=l.length,r=dr(r,"parentNode");return i.reverse().join(c)}catch{return""}}function kb(e,t){let r=[],n=dr(e,"tagName");if(!n)return"";if(typeof HTMLElement<"u"&&e instanceof HTMLElement){let s=dr(e,"dataset");if(s){if(s.sentryComponent)return s.sentryComponent;if(s.sentryElement)return s.sentryElement}}r.push(n.toLowerCase());let i=t?.length?t.filter(s=>dr(e,"getAttribute",s)).map(s=>[s,dr(e,"getAttribute",s)]):null;if(i?.length)i.forEach(s=>{r.push(`[${s[0]}="${s[1]}"]`)});else{let s=dr(e,"id");s&&r.push(`#${s}`);let a=dr(e,"className");if(a&&Ce(a)){let c=a.split(/\s+/);for(let o of c)r.push(`.${o}`)}}for(let s of["aria-label","type","name","title","alt"]){let a=dr(e,"getAttribute",s);a&&r.push(`[${s}="${a}"]`)}return r.join("")}var rd=e=>{let t=r=>{(r.type==="pagehide"||I.document?.visibilityState==="hidden")&&e(r)};lt("visibilitychange",t,{capture:!0,once:!0}),lt("pagehide",t,{capture:!0,once:!0})};function Gs(e){return typeof e=="number"&&isFinite(e)}function Jt(e,t,r,{...n}){let i=O(e).start_timestamp;return i&&i>t&&typeof e.updateStartTime=="function"&&e.updateStartTime(t),tn(e,()=>{let s=Ie({startTime:t,...n});return s&&s.end(r),s})}function hn(e){let t=E();if(!t)return;let{name:r,transaction:n,attributes:i,startTime:s}=e,{release:a,environment:c}=t.getOptions(),{userInfo:o}=t.getDataCollectionOptions(),u=t.getIntegrationByName("Replay")?.getReplayId(),p=R(),d=p.getUser(),m=d!==void 0?d.email||d.id||d.ip_address:void 0,g;try{g=p.getScopeData().contexts.profile.profile_id}catch{}let h={release:a,environment:c,user:m||void 0,profile_id:g||void 0,replay_id:u||void 0,transaction:n,"user_agent.original":I.navigator?.userAgent,"client.address":o?"{{auto}}":void 0,...i};return Ie({name:r,attributes:h,startTime:s,experimental:{standalone:!0}})}function Mt(){return I.addEventListener&&I.performance}function Z(e){return e/1e3}function nd(e){let t="unknown",r="unknown",n="";for(let i of e){if(i==="/"){[t,r]=e.split("/");break}if(!isNaN(Number(i))){t=n==="h"?"http":n,r=e.split(n)[1];break}n+=i}return n===e&&(t=n),{name:t,version:r}}function Hr(e){try{return PerformanceObserver.supportedEntryTypes.includes(e)}catch{return!1}}function Gr(e,t){let r,n=!1;function i(c){!n&&r&&t(c,r.spanContext().spanId,r),n=!0}rd(()=>{i("pagehide")});let s=e.on("beforeStartNavigationSpan",(c,o)=>{o?.isRedirect||(i("navigation"),s(),a())}),a=e.on("afterStartPageLoadSpan",c=>{r=c,a()})}function id(e){let t=0,r;if(!Hr("layout-shift"))return;let n=Kt(({metric:i})=>{let s=i.entries[i.entries.length-1];s&&(t=i.value,r=s)},!0);Gr(e,(i,s)=>{Nb(t,r,s,i),n()})}function Nb(e,t,r,n){Ae&&f.log(`Sending CLS span (${e})`);let i=t?Z((ie()||0)+t.startTime):Q(),s=R().getScopeData().transactionName,a=t?se(t.sources[0]?.node):"Layout shift",c={[j]:"auto.http.browser.cls",[de]:"ui.webvital.cls",[De]:0,"sentry.pageload.span_id":r,"sentry.report_event":n};t?.sources&&t.sources.forEach((l,u)=>{c[`cls.source.${u+1}`]=se(l.node)});let o=hn({name:a,transaction:s,attributes:c,startTime:i});o&&(o.addEvent("cls",{[bt]:"",[_t]:e}),o.end(i))}var wb=6e4;function Wr(e){return e!=null&&e>0&&e<=wb}function sd(e){let t=0,r;if(!Hr("largest-contentful-paint"))return;let n=Xt(({metric:i})=>{let s=i.entries[i.entries.length-1];!s||!Wr(i.value)||(t=i.value,r=s)},!0);Gr(e,(i,s)=>{Cb(t,r,s,i),n()})}function Cb(e,t,r,n){if(!Wr(e))return;Ae&&f.log(`Sending LCP span (${e})`);let i=Z((ie()||0)+(t?.startTime||0)),s=R().getScopeData().transactionName,a=t?se(t.element):"Largest contentful paint",c={[j]:"auto.http.browser.lcp",[de]:"ui.webvital.lcp",[De]:0,"sentry.pageload.span_id":r,"sentry.report_event":n};t&&(t.element&&(c["lcp.element"]=se(t.element)),t.id&&(c["lcp.id"]=t.id),t.url&&(c["lcp.url"]=t.url),t.loadTime!=null&&(c["lcp.loadTime"]=t.loadTime),t.renderTime!=null&&(c["lcp.renderTime"]=t.renderTime),t.size!=null&&(c["lcp.size"]=t.size));let o=hn({name:a,transaction:s,attributes:c,startTime:i});o&&(o.addEvent("lcp",{[bt]:"millisecond",[_t]:e}),o.end(i))}function dt(e){return e&&((ie()||performance.timeOrigin)+e)/1e3}function Si(e){let t={};if(e.nextHopProtocol!=null){let{name:r,version:n}=nd(e.nextHopProtocol);t["network.protocol.version"]=n,t["network.protocol.name"]=r}return ie()||Mt()?.timeOrigin?Mb({...t,"http.request.redirect_start":dt(e.redirectStart),"http.request.redirect_end":dt(e.redirectEnd),"http.request.worker_start":dt(e.workerStart),"http.request.fetch_start":dt(e.fetchStart),"http.request.domain_lookup_start":dt(e.domainLookupStart),"http.request.domain_lookup_end":dt(e.domainLookupEnd),"http.request.connect_start":dt(e.connectStart),"http.request.secure_connection_start":dt(e.secureConnectionStart),"http.request.connection_end":dt(e.connectEnd),"http.request.request_start":dt(e.requestStart),"http.request.response_start":dt(e.responseStart),"http.request.response_end":dt(e.responseEnd),"http.request.time_to_first_byte":e.responseStart!=null?e.responseStart/1e3:void 0}):t}function Mb(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>t!=null))}var Lb=2147483647,ad=0,Qe={},Je,Ys;function $o({recordClsStandaloneSpans:e,recordLcpStandaloneSpans:t,client:r}){let n=Mt();if(n&&ie()){n.mark&&I.performance.mark("sentry-tracing-init");let i=t?sd(r):t===!1?Db():void 0,s=e?id(r):e===!1?Pb():void 0,a=Ub(),c=Fb();return()=>{a(),c(),i?.(),s?.()}}return()=>{}}function Ko(){ut("longtask",({entries:e})=>{let t=te();if(!t)return;let{op:r,start_timestamp:n}=O(t);for(let i of e){let s=Z(ie()+i.startTime),a=Z(i.duration);r==="navigation"&&n&&s{let r=te();if(r)for(let n of t.getEntries()){if(!n.scripts[0])continue;let i=Z(ie()+n.startTime),{start_timestamp:s,op:a}=O(r);if(a==="navigation"&&s&&i{let t=te();if(t){for(let r of e)if(r.name==="click"){let n=Z(ie()+r.startTime),i=Z(r.duration),s={name:se(r.target),op:`ui.interaction.${r.name}`,startTime:n,attributes:{[j]:"auto.ui.browser.metrics"}},a=un(r.target);a&&(s.attributes["ui.component_name"]=a),Jt(t,n,n+i,s)}}})}function Pb(){return Kt(({metric:e})=>{let t=e.entries[e.entries.length-1];t&&(Qe.cls={value:e.value,unit:""},Ys=t)},!0)}function Db(){return Xt(({metric:e})=>{let t=e.entries[e.entries.length-1];!t||!Wr(e.value)||(Qe.lcp={value:e.value,unit:"millisecond"},Je=t)},!0)}function Ub(){return jo(({metric:e})=>{e.entries[e.entries.length-1]&&(Qe.ttfb={value:e.value,unit:"millisecond"})})}function Fb(){return ut("paint",({entries:e})=>{let t=wt();for(let r of e){let n=r.startTime{let d=Z(p.startTime),m=Z(Math.max(0,p.duration));if(!(l==="navigation"&&u&&c+d{let p=u??`browser.web_vital.${o}.value`;e.setAttribute(p,l),Ae&&f.log("Setting web vital attribute",{[p]:l},"on pageload span")};["ttfb","fp","fcp"].forEach(o=>{Qe[o]&&c(o,Qe[o].value)}),Qe["ttfb.requestTime"]&&c("ttfb.requestTime",Qe["ttfb.requestTime"].value,"browser.web_vital.ttfb.request_time")}else i||delete Qe.cls,s||delete Qe.lcp,Object.entries(Qe).forEach(([c,o])=>{ri(c,o.value,o.unit,e)}),jb(e,t);e.setAttribute(n?"browser.performance.time_origin":"performance.timeOrigin",a),e.setAttribute(n?"browser.performance.navigation.activation_start":"performance.activationStart",ct())}od()}function od(){Je=void 0,Ys=void 0,Qe={}}function Bb(e){if(e?.entryType==="measure")try{return e.detail.devtools.track==="Components \u269B"}catch{return}}function qb(e,t,r,n,i,s){if(Bb(t)||["mark","measure"].includes(t.entryType)&&xe(t.name,s))return;let a=$t(!1),c=Z(a?a.requestStart:0),o=i+Math.max(r,c),l=i+r,u=l+n,p={[j]:"auto.resource.browser.metrics"};o!==l&&(p["sentry.browser.measure_happened_before_request"]=!0,p["sentry.browser.measure_start_time"]=o),Hb(p,t),o<=u&&Jt(e,o,u,{name:t.name,op:t.entryType,attributes:p})}function Hb(e,t){try{let r=t.detail;if(!r)return;if(typeof r=="object"){for(let[n,i]of Object.entries(r))if(i&&ze(i))e[`sentry.browser.measure.detail.${n}`]=i;else if(i!==void 0)try{e[`sentry.browser.measure.detail.${n}`]=JSON.stringify(i)}catch{}return}if(ze(r)){e["sentry.browser.measure.detail"]=r;return}try{e["sentry.browser.measure.detail"]=JSON.stringify(r)}catch{}}catch{}}function Gb(e,t,r){["unloadEvent","redirect","domContentLoadedEvent","loadEvent","connect"].forEach(n=>{Ws(e,t,n,r)}),Ws(e,t,"secureConnection",r,"TLS/SSL"),Ws(e,t,"fetch",r,"cache"),Ws(e,t,"domainLookup",r,"DNS"),Yb(e,t,r)}function Ws(e,t,r,n,i=r){let s=Wb(r),a=t[s],c=t[`${r}Start`];!c||!a||Jt(e,n+Z(c),n+Z(a),{op:`browser.${i}`,name:t.name,attributes:{[j]:"auto.ui.browser.metrics",...r==="redirect"&&t.redirectCount!=null?{"http.redirect_count":t.redirectCount}:{}}})}function Wb(e){return e==="secureConnection"?"connectEnd":e==="fetch"?"domainLookupStart":`${e}End`}function Yb(e,t,r){let n=r+Z(t.requestStart),i=r+Z(t.responseEnd),s=r+Z(t.responseStart);t.responseEnd&&(Jt(e,n,i,{op:"browser.request",name:t.name,attributes:{[j]:"auto.ui.browser.metrics"}}),Jt(e,s,i,{op:"browser.response",name:t.name,attributes:{[j]:"auto.ui.browser.metrics"}}))}function zb(e,t,r,n,i,s,a){if(t.initiatorType==="xmlhttprequest"||t.initiatorType==="fetch")return;let c=t.initiatorType?`resource.${t.initiatorType}`:"resource.other";if(a?.includes(c))return;let o={[j]:"auto.resource.browser.metrics"},l=ot(r);l.protocol&&(o["url.scheme"]=l.protocol.split(":").pop()),l.host&&(o["server.address"]=l.host),o["url.same_origin"]=r.includes(I.location.origin),o[St]=r,$b(t,o,[["responseStatus","http.response.status_code"],["transferSize","http.response_transfer_size"],["encodedBodySize","http.response_content_length"],["decodedBodySize","http.decoded_response_content_length"],["renderBlockingStatus","resource.render_blocking_status"],["deliveryType","http.response_delivery_type"]]);let u={...o,...Si(t)},p=s+n,d=p+i;Jt(e,p,d,{name:r.replace(I.location.origin,""),op:c,attributes:u})}function Vb(e,t){let r=I.navigator;if(!r)return;let n=r.connection;n&&(n.effectiveType&&e.setAttribute(t?"network.connection.effective_type":"effectiveConnectionType",n.effectiveType),n.type&&e.setAttribute(t?"network.connection.type":"connectionType",n.type),Gs(n.rtt)&&(t?e.setAttribute("network.connection.rtt",n.rtt):O(e).op==="pageload"&&ri("connection.rtt",n.rtt,"millisecond"))),Gs(r.deviceMemory)&&(t?e.setAttribute("device.memory.estimated_capacity",r.deviceMemory):e.setAttribute("deviceMemory",`${r.deviceMemory} GB`)),Gs(r.hardwareConcurrency)&&(t?e.setAttribute("device.processor_count",r.hardwareConcurrency):e.setAttribute("hardwareConcurrency",String(r.hardwareConcurrency)))}function jb(e,t){Je&&t.recordLcpOnPageloadSpan&&(Je.element&&e.setAttribute("lcp.element",se(Je.element)),Je.id&&e.setAttribute("lcp.id",Je.id),Je.url&&e.setAttribute("lcp.url",Je.url.trim().slice(0,200)),Je.loadTime!=null&&e.setAttribute("lcp.loadTime",Je.loadTime),Je.renderTime!=null&&e.setAttribute("lcp.renderTime",Je.renderTime),e.setAttribute("lcp.size",Je.size)),Ys?.sources&&t.recordClsOnPageloadSpan&&Ys.sources.forEach((r,n)=>e.setAttribute(`cls.source.${n+1}`,se(r.node)))}function $b(e,t,r){r.forEach(([n,i])=>{let s=e[n];s!=null&&(typeof s=="number"&&s{t()}}return()=>{}}var _n={click:"click",pointerdown:"click",pointerup:"click",mousedown:"click",mouseup:"click",touchstart:"click",touchend:"click",mouseover:"hover",mouseout:"hover",mouseenter:"hover",mouseleave:"hover",pointerover:"hover",pointerout:"hover",pointerenter:"hover",pointerleave:"hover",dragstart:"drag",dragend:"drag",drag:"drag",dragenter:"drag",dragleave:"drag",dragover:"drag",drop:"drag",keydown:"press",keyup:"press",keypress:"press",input:"press"};function Xb(){return Br(Jb)}var Jb=({metric:e})=>{if(e.value==null)return;let t=Z(e.value);if(t>tc)return;let r=e.entries.find(g=>g.duration===e.value&&_n[g.name]);if(!r)return;let{interactionId:n}=r,i=_n[r.name],s=Z(ie()+r.startTime),a=te(),c=a?X(a):void 0,o=n!=null?vi.get(n):void 0,l=o?.span||c,u=l?O(l).description:R().getScopeData().transactionName,p=o?.elementName||se(r.target),d={[j]:"auto.http.browser.inp",[de]:`ui.interaction.${i}`,[De]:r.duration},m=hn({name:p,transaction:u,attributes:d,startTime:s});m&&(m.addEvent("inp",{[bt]:"millisecond",[_t]:e.value}),m.end(s+t))};function cd(e){return e!=null?vi.get(e):void 0}function nc(){let e=Object.keys(_n);at()&&e.forEach(i=>{I.addEventListener(i,t,{capture:!0,passive:!0})});function t(i){let s=i.target;if(!s)return;let a=se(s),c=Math.round(i.timeStamp);if(bn.set(c,a),bn.size>50){let o=bn.keys().next().value;o!==void 0&&bn.delete(o)}}function r(i){let s=Math.round(i.startTime),a=bn.get(s);if(!a)for(let c=-5;c<=5;c++){let o=bn.get(s+c);if(o){a=o;break}}return a||""}let n=({entries:i})=>{let s=te(),a=s&&X(s);i.forEach(c=>{if(!td(c))return;let o=c.interactionId;if(o==null||vi.has(o))return;let l=c.target?se(c.target):r(c);if(ec.length>10){let u=ec.shift();vi.delete(u)}ec.push(o),vi.set(o,{span:a,elementName:l})})};ut("event",n),ut("first-input",n)}function ic(e){let{name:t,op:r,origin:n,metricName:i,value:s,attributes:a,parentSpan:c,reportEvent:o,startTime:l,endTime:u}=e,p=R().getScopeData().transactionName,d={[j]:n,[de]:r,[De]:0,[`browser.web_vital.${i}.value`]:s,[ho]:p,[fo]:p,"user_agent.original":I.navigator?.userAgent,...a};c&&Jn(c).attributes?.[de]==="pageload"&&(d["sentry.pageload.span_id"]=c.spanContext().spanId),o&&(d[`browser.web_vital.${i}.report_event`]=o);let m=Ie({name:t,attributes:d,startTime:l,parentSpan:c});m&&m.end(u??l)}function sc(e){let t=0,r;if(!Hr("largest-contentful-paint"))return;let n=Xt(({metric:i})=>{let s=i.entries[i.entries.length-1];!s||!Wr(i.value)||(t=i.value,r=s)},!0);Gr(e,(i,s,a)=>{Qb(t,r,a,i),n()})}function Qb(e,t,r,n){if(!Wr(e))return;Ae&&f.log(`Sending LCP span (${e})`);let i=ie()||0,s=Z(i),a=Z(i+(t?.startTime||0)),c=t?se(t.element):"Largest contentful paint",o={};t?.element&&(o["browser.web_vital.lcp.element"]=se(t.element)),t?.id&&(o["browser.web_vital.lcp.id"]=t.id),t?.url&&(o["browser.web_vital.lcp.url"]=t.url),t?.loadTime!=null&&(o["browser.web_vital.lcp.load_time"]=t.loadTime),t?.renderTime!=null&&(o["browser.web_vital.lcp.render_time"]=t.renderTime),t?.size!=null&&(o["browser.web_vital.lcp.size"]=t.size),ic({name:c,op:"ui.webvital.lcp",origin:"auto.http.browser.lcp",metricName:"lcp",value:e,attributes:o,parentSpan:r,reportEvent:n,startTime:s,endTime:a})}function ac(e){let t=0,r;if(!Hr("layout-shift"))return;let n=Kt(({metric:i})=>{let s=i.entries[i.entries.length-1];s&&(t=i.value,r=s)},!0);Gr(e,(i,s,a)=>{Zb(t,r,a,i),n()})}function Zb(e,t,r,n){Ae&&f.log(`Sending CLS span (${e})`);let i=t?Z((ie()||0)+t.startTime):Q(),s=t?se(t.sources[0]?.node):"Layout shift",a={};t?.sources&&t.sources.forEach((c,o)=>{a[`browser.web_vital.cls.source.${o+1}`]=se(c.node)}),ic({name:s,op:"ui.webvital.cls",origin:"auto.http.browser.cls",metricName:"cls",value:e,attributes:a,parentSpan:r,reportEvent:n,startTime:i})}function oc(){if(!Mt()||!ie())return;Br(({metric:r})=>{if(r.value==null||Z(r.value)>tc)return;let i=r.entries.find(s=>s.duration===r.value&&_n[s.name]);i&&e_(r.value,i)})}function e_(e,t){Ae&&f.log(`Sending INP span (${e})`);let r=Z(ie()+t.startTime),n=Z(e),i=_n[t.name],s=cd(t.interactionId),a=te(),c=a?X(a):void 0,o=s?.span||c,l=o?Jn(o).name:R().getScopeData().transactionName,u=s?.elementName||se(t.target);ic({name:u,op:`ui.interaction.${i}`,origin:"auto.http.browser.inp",metricName:"inp",value:e,attributes:{[De]:t.duration,[ho]:l,[fo]:l},startTime:r,endTime:r+n,parentSpan:o})}var t_=1e3,ld,cc,lc;function Ei(e){Le("dom",e),Pe("dom",r_)}function r_(){if(!I.document)return;let e=ye.bind(null,"dom"),t=pd(e,!0);I.document.addEventListener("click",t,!1),I.document.addEventListener("keypress",t,!1),["EventTarget","Node"].forEach(r=>{let i=I[r]?.prototype;i?.hasOwnProperty?.("addEventListener")&&(fe(i,"addEventListener",function(s){return function(a,c,o){if(a==="click"||a=="keypress")try{let l=this.__sentry_instrumentation_handlers__=this.__sentry_instrumentation_handlers__||{},u=l[a]=l[a]||{refCount:0};if(!u.handler){let p=pd(e);u.handler=p,s.call(this,a,p,o)}u.refCount++}catch{}return s.call(this,a,c,o)}}),fe(i,"removeEventListener",function(s){return function(a,c,o){if(a==="click"||a=="keypress")try{let l=this.__sentry_instrumentation_handlers__||{},u=l[a];u&&(u.refCount--,u.refCount<=0&&(s.call(this,a,u.handler,o),u.handler=void 0,delete l[a]),Object.keys(l).length===0&&delete this.__sentry_instrumentation_handlers__)}catch{}return s.call(this,a,c,o)}}))})}function n_(e){if(e.type!==cc)return!1;try{if(!e.target||e.target._sentryId!==lc)return!1}catch{}return!0}function i_(e,t){return e!=="keypress"?!1:t?.tagName?!(t.tagName==="INPUT"||t.tagName==="TEXTAREA"||t.isContentEditable):!0}function pd(e,t=!1){return r=>{if(!r||r._sentryCaptured)return;let n=s_(r);if(i_(r.type,n))return;ne(r,"_sentryCaptured",!0),n&&!n._sentryId&&ne(n,"_sentryId",he());let i=r.type==="keypress"?"input":r.type;n_(r)||(e({event:r,name:i,global:t}),cc=r.type,lc=n?n._sentryId:void 0),clearTimeout(ld),ld=I.setTimeout(()=>{lc=void 0,cc=void 0},t_)}}function s_(e){try{return e.target}catch{return null}}var zs;function Qt(e){let t="history";Le(t,e),Pe(t,a_)}function a_(){if(I.addEventListener("popstate",()=>{let t=I.location.href,r=zs;if(zs=t,r===t)return;ye("history",{from:r,to:t})}),!Po())return;function e(t){return function(...r){let n=r.length>2?r[2]:void 0;if(n){let i=zs,s=o_(String(n));if(zs=s,i===s)return t.apply(this,r);ye("history",{from:i,to:s})}return t.apply(this,r)}}fe(I.history,"pushState",e),fe(I.history,"replaceState",e)}function o_(e){try{return new URL(e,I.location.origin).toString()}catch{return e}}var Vs={};function js(e){let t=Vs[e];if(t)return t;let r=I[e];if(bi(r))return Vs[e]=r.bind(I);let n=I.document;if(n&&typeof n.createElement=="function")try{let i=n.createElement("iframe");i.hidden=!0,n.head.appendChild(i);let s=i.contentWindow;s?.[e]&&(r=s[e]),n.head.removeChild(i)}catch(i){Ae&&f.warn(`Could not create sandbox iframe for ${e} check, bailing to window.${e}: `,i)}return r&&(Vs[e]=r.bind(I))}function pc(e){Vs[e]=void 0}function Yr(...e){return js("setTimeout")(...e)}var Et="__sentry_xhr_v3__";function Ti(e){Le("xhr",e),Pe("xhr",c_)}function c_(){if(!I.XMLHttpRequest)return;let e=XMLHttpRequest.prototype;e.open=new Proxy(e.open,{apply(t,r,n){let i=new Error,s=Q()*1e3,a=Ce(n[0])?n[0].toUpperCase():void 0,c=l_(n[1]);if(!a||!c)return t.apply(r,n);r[Et]={method:a,url:c,request_headers:{}},a==="POST"&&c.match(/sentry_key/)&&(r.__sentry_own_request__=!0);let o=()=>{let l=r[Et];if(l&&r.readyState===4){try{l.status_code=r.status}catch{}let u={endTimestamp:Q()*1e3,startTimestamp:s,xhr:r,virtualError:i};ye("xhr",u),r.removeEventListener("readystatechange",o)}};return"onreadystatechange"in r&&typeof r.onreadystatechange=="function"?r.onreadystatechange=new Proxy(r.onreadystatechange,{apply(l,u,p){return o(),l.apply(u,p)}}):r.addEventListener("readystatechange",o),r.setRequestHeader=new Proxy(r.setRequestHeader,{apply(l,u,p){let[d,m]=p,g=u[Et];return g&&Ce(d)&&Ce(m)&&(g.request_headers[d.toLowerCase()]=m),l.apply(u,p)}}),t.apply(r,n)}}),e.send=new Proxy(e.send,{apply(t,r,n){let i=r[Et];if(!i)return t.apply(r,n);n[0]!==void 0&&(i.body=n[0]);let s={startTimestamp:Q()*1e3,xhr:r};return ye("xhr",s),t.apply(r,n)}})}function l_(e){if(Ce(e))return e;try{return e.toString()}catch{}}var p_=Symbol.for("sentry__originalRequestBody");function $s(e){return new URLSearchParams(e).toString()}function Ks(e,t=f){try{if(typeof e=="string")return[e];if(e instanceof URLSearchParams)return[e.toString()];if(e instanceof FormData)return[$s(e)];if(!e)return[void 0]}catch(r){return Ae&&t.error(r,"Failed to serialize body",e),[void 0,"BODY_PARSE_ERROR"]}return Ae&&t.log("Skipping network body because of body type",e),[void 0,"UNPARSEABLE_BODY_TYPE"]}function Xs(e=[]){if(e.length>=2&&e[1]&&typeof e[1]=="object"&&"body"in e[1])return e[1].body;if(e.length>=1&&e[0]instanceof Request){let r=e[0][p_];return r!==void 0?r:void 0}}function Ii(e){let t;try{t=e.getAllResponseHeaders()}catch(r){return Ae&&f.error(r,"Failed to get xhr response headers",e),{}}return t?t.split(`\r +`).reduce((r,n)=>{let[i,s]=n.split(": ");return s&&(r[i.toLowerCase()]=s),r},{}):{}}function uc(e){if(typeof Element>"u")return!1;try{return e instanceof Element}catch{return!1}}var ve=typeof __SENTRY_DEBUG__>"u"||__SENTRY_DEBUG__;var Js=1024,u_="Breadcrumbs",d_=((e={})=>{let t={console:!0,dom:!0,fetch:!0,history:!0,sentry:!0,xhr:!0,...e};return{name:u_,setup(r){t.console&&Co(f_(r)),t.dom&&Ei(g_(r,t.dom)),t.xhr&&Ti(h_(r)),t.fetch&&pr(b_(r)),t.history&&Qt(__(r)),t.sentry&&r.on("beforeSendEvent",m_(r))}}}),ud=d_;function m_(e){return function(r){E()===e&&tt({category:`sentry.${r.type==="transaction"?"transaction":"event"}`,event_id:r.event_id,level:r.level,message:ht(r)},{event:r})}}function g_(e,t){return function(n){if(E()!==e)return;let i,s,a=typeof t=="object"?t.serializeAttribute:void 0,c=typeof t=="object"&&typeof t.maxStringLength=="number"?t.maxStringLength:void 0;c&&c>Js&&(ve&&f.warn(`\`dom.maxStringLength\` cannot exceed ${Js}, but a value of ${c} was configured. Sentry will use ${Js} instead.`),c=Js),typeof a=="string"&&(a=[a]);try{let l=n.event,u=y_(l)?l.target:l;i=se(u,{keyAttrs:a,maxStringLength:c}),s=un(u)}catch{i=""}if(i.length===0)return;let o={category:`ui.${n.name}`,message:i};s&&(o.data={"ui.component_name":s}),tt(o,{event:n.event,name:n.name,global:n.global})}}function f_(e){return function(r){if(E()!==e)return;let n={category:"console",data:{arguments:r.args,logger:"console"},level:pn(r.level),message:Fn(r.args," ")};if(r.level==="assert")if(r.args[0]===!1)n.message=`Assertion failed: ${Fn(r.args.slice(1)," ")||"console.assert"}`,n.data.arguments=r.args.slice(1);else return;tt(n,{input:r.args,level:r.level})}}function h_(e){return function(r){if(E()!==e)return;let{startTimestamp:n,endTimestamp:i}=r,s=r.xhr[Et];if(!n||!i||!s)return;let{method:a,url:c,status_code:o,body:l}=s,u={method:a,url:c,status_code:o},p={xhr:r.xhr,input:l,startTimestamp:n,endTimestamp:i},d={category:"xhr",data:u,type:"http",level:xs(o)};e.emit("beforeOutgoingRequestBreadcrumb",d,p),tt(d,p)}}function b_(e){return function(r){if(E()!==e)return;let{startTimestamp:n,endTimestamp:i}=r;if(i&&!(r.fetchData.url.match(/sentry_key/)&&r.fetchData.method==="POST"))if(r.error){let s={data:r.error,input:r.args,startTimestamp:n,endTimestamp:i},a={category:"fetch",data:r.fetchData,level:"error",type:"http"};e.emit("beforeOutgoingRequestBreadcrumb",a,s),tt(a,s)}else{let s=r.response,a={...r.fetchData,status_code:s?.status},c={input:r.args,response:s,startTimestamp:n,endTimestamp:i},o={category:"fetch",data:a,type:"http",level:xs(a.status_code)};e.emit("beforeOutgoingRequestBreadcrumb",o,c),tt(o,c)}}}function __(e){return function(r){if(E()!==e)return;let n=r.from,i=r.to,s=ot(k.location.href),a=n?ot(n):void 0,c=ot(i);a?.path||(a=s),s.protocol===c.protocol&&s.host===c.host&&(i=c.relative),s.protocol===a.protocol&&s.host===a.host&&(n=a.relative),tt({category:"navigation",data:{from:n,to:i}})}}function y_(e){return!!e&&!!e.target}var S_="EventTarget,Window,Node,ApplicationCache,AudioTrackList,BroadcastChannel,ChannelMergerNode,CryptoOperation,EventSource,FileReader,HTMLUnknownElement,IDBDatabase,IDBRequest,IDBTransaction,KeyOperation,MediaController,MessagePort,ModalWindow,Notification,SVGElementInstance,Screen,SharedWorker,TextTrack,TextTrackCue,TextTrackList,WebSocket,WebSocketWorker,Worker,XMLHttpRequest,XMLHttpRequestEventTarget,XMLHttpRequestUpload".split(","),v_="BrowserApiErrors",E_=((e={})=>{let t={XMLHttpRequest:!0,eventTarget:!0,requestAnimationFrame:!0,setInterval:!0,setTimeout:!0,unregisterOriginalCallbacks:!1,...e};return{name:v_,setupOnce(){t.setTimeout&&fe(k,"setTimeout",dd),t.setInterval&&fe(k,"setInterval",dd),t.requestAnimationFrame&&fe(k,"requestAnimationFrame",T_),t.XMLHttpRequest&&"XMLHttpRequest"in k&&fe(XMLHttpRequest.prototype,"send",I_);let r=t.eventTarget;r&&(Array.isArray(r)?r:S_).forEach(i=>A_(i,t))}}}),md=E_;function dd(e){return function(...t){let r=t[0];return t[0]=Dr(r,{mechanism:{handled:!1,type:`auto.browser.browserapierrors.${Fe(e)}`}}),e.apply(this,t)}}function T_(e){return function(t){return e.apply(this,[Dr(t,{mechanism:{data:{handler:Fe(e)},handled:!1,type:"auto.browser.browserapierrors.requestAnimationFrame"}})])}}function I_(e){return function(...t){let r=this;return["onload","onerror","onprogress","onreadystatechange"].forEach(i=>{i in r&&typeof r[i]=="function"&&fe(r,i,function(s){let a={mechanism:{data:{handler:Fe(s)},handled:!1,type:`auto.browser.browserapierrors.xhr.${i}`}},c=rr(s);return c&&(a.mechanism.data.handler=Fe(c)),Dr(s,a)})}),e.apply(this,t)}}function A_(e,t){let n=k[e]?.prototype;n?.hasOwnProperty?.("addEventListener")&&(fe(n,"addEventListener",function(i){return function(s,a,c){try{R_(a)&&(a.handleEvent=Dr(a.handleEvent,{mechanism:{data:{handler:Fe(a),target:e},handled:!1,type:"auto.browser.browserapierrors.handleEvent"}}))}catch{}return t.unregisterOriginalCallbacks&&O_(this,s,a),i.apply(this,[s,Dr(a,{mechanism:{data:{handler:Fe(a),target:e},handled:!1,type:"auto.browser.browserapierrors.addEventListener"}}),c])}}),fe(n,"removeEventListener",function(i){return function(s,a,c){try{if(Object.prototype.hasOwnProperty.call(a,"__sentry_wrapped__")){let o=a.__sentry_wrapped__;o&&i.call(this,s,o,c)}}catch{}return i.call(this,s,a,c)}}))}function R_(e){return typeof e.handleEvent=="function"}function O_(e,t,r){e&&typeof e=="object"&&"removeEventListener"in e&&typeof e.removeEventListener=="function"&&e.removeEventListener(t,r)}var gd=(e={})=>{let t=e.lifecycle??"route";return{name:"BrowserSession",setupOnce(){if(typeof k.document>"u"){ve&&f.warn("Using the `browserSessionIntegration` in non-browser environments is not supported.");return}an({ignoreDuration:!0});let r=!1;Fr(()=>{r||(Lr(),r=!0)});let n=me(),i=n.getUser();n.addScopeListener(s=>{let a=s.getUser();(i?.id!==a?.id||i?.ip_address!==a?.ip_address)&&(i=a,r&&Lr())}),t==="route"&&Qt(({from:s,to:a})=>{s!==a&&(an({ignoreDuration:!0}),Lr(),r=!0)})}}};var x_="CultureContext",k_=(()=>({name:x_,preprocessEvent(e){let t=fd();t&&(e.contexts={...e.contexts,culture:{...t,...e.contexts?.culture}})},processSegmentSpan(e){let t=fd();t&&Yt(e,{"culture.locale":t.locale,"culture.timezone":t.timezone,"culture.calendar":t.calendar})}})),hd=k_;function fd(){try{let e=k.Intl;if(!e)return;let t=e.DateTimeFormat().resolvedOptions();return{locale:t.locale,timezone:t.timeZone,calendar:t.calendar}}catch{return}}var N_="GlobalHandlers",w_=((e={})=>{let t={onerror:!0,onunhandledrejection:!0,...e};return{name:N_,setupOnce(){Error.stackTraceLimit=50},setup(r){t.onerror&&(C_(r),bd("onerror")),t.onunhandledrejection&&(M_(r),bd("onunhandledrejection"))}}}),_d=w_;function C_(e){Gn(t=>{let{stackParser:r,attachStacktrace:n}=yd();if(E()!==e||qo())return;let{msg:i,url:s,line:a,column:c,error:o}=t,l=D_(Ms(r,o||i,void 0,n,!1),s,a,c);l.level="error",sn(l,{originalException:o,mechanism:{handled:!1,type:"auto.browser.global_handlers.onerror"}})})}function M_(e){Wn(t=>{let{stackParser:r,attachStacktrace:n}=yd();if(E()!==e||qo())return;let i=L_(t),s=ze(i)?P_(i):Ms(r,i,void 0,n,!0);s.level="error",sn(s,{originalException:i,mechanism:{handled:!1,type:"auto.browser.global_handlers.onunhandledrejection"}})})}function L_(e){if(ze(e))return e;try{if("reason"in e)return e.reason;if("detail"in e&&"reason"in e.detail)return e.detail.reason}catch{}return e}function P_(e){return{exception:{values:[{type:"UnhandledRejection",value:`Non-Error promise rejection captured with value: ${String(e)}`}]}}}function D_(e,t,r,n){let i=e.exception=e.exception||{},s=i.values=i.values||[],a=s[0]=s[0]||{},c=a.stacktrace=a.stacktrace||{},o=c.frames=c.frames||[];return o.length===0&&o.push({colno:n,lineno:r,filename:U_(t)??Ge(),function:"?",in_app:!0}),e}function bd(e){ve&&f.log(`Global Handler attached: ${e}`)}function yd(){return E()?.getOptions()||{stackParser:()=>[],attachStacktrace:!1}}function U_(e){if(!(!Ce(e)||e.length===0))return e.startsWith("data:")?`<${Ne(e,!1)}>`:e}var Sd=()=>({name:"HttpContext",preprocessEvent(e){if(!k.navigator&&!k.location&&!k.document)return;let t=dn(),r={...t.headers,...e.request?.headers};e.request={...t,...e.request,headers:r}},processSpan(e){if(!k.navigator&&!k.location&&!k.document)return;let t=dn();Yt(e,{[gp]:t.headers["User-Agent"],...e.is_segment&&{[St]:e.attributes?.[dp]!=="http.client"?t.url:void 0,[`${up}.referer`]:t.headers.Referer}})}});var F_="cause",B_=5,q_="LinkedErrors",H_=((e={})=>{let t=e.limit||B_,r=e.key||F_;return{name:q_,preprocessEvent(n,i,s){let a=s.getOptions();wo(ws,a.stackParser,r,t,n,i)}}}),vd=H_;var G_=30;var W_=50;function dc(e,t,r,n){let i={filename:e,function:t===""?"?":t,in_app:!0};return r!==void 0&&(i.lineno=r),n!==void 0&&(i.colno=n),i}var Y_=/^\s*at (\S+?)(?::(\d+))(?::(\d+))\s*$/i,z_=/^\s*at (?:(.+?\)(?: \[.+\])?|.*?) ?\((?:address at )?)?(?:async )?((?:|[-a-z]+:|.*bundle|\/)?.*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i,V_=/\((\S*)(?::(\d+))(?::(\d+))\)/,j_=/at (.+?) ?\(data:(.+?),/,$_=e=>{let t=e.match(j_);if(t)return{filename:``,function:t[1]};let r=Y_.exec(e);if(r){let[,i,s,a]=r;return dc(i,"?",+s,+a)}let n=z_.exec(e);if(n){if(n[2]?.indexOf("eval")===0){let c=V_.exec(n[2]);c&&(n[2]=c[1],n[3]=c[2],n[4]=c[3])}let[s,a]=Td(n[1]||"?",n[2]);return dc(a,s,n[3]?+n[3]:void 0,n[4]?+n[4]:void 0)}},K_=[G_,$_],X_=/^\s*(.*?)(?:\((.*?)\))?(?:^|@)?((?:[-a-z]+)?:\/.*?|\[native code\]|[^@]*(?:bundle|\d+\.js)|\/[\w\-. /=]+)(?::(\d+))?(?::(\d+))?\s*$/i,J_=/(\S+) line (\d+)(?: > eval line \d+)* > eval/i,Q_=e=>{let t=X_.exec(e);if(t){if(t[3]&&t[3].indexOf(" > eval")>-1){let s=J_.exec(t[3]);s&&(t[1]=t[1]||"eval",t[3]=s[1],t[4]=s[2],t[5]="")}let n=t[3],i=t[1]||"?";return[i,n]=Td(i,n),dc(n,i,t[4]?+t[4]:void 0,t[5]?+t[5]:void 0)}},Z_=[W_,Q_];var ey=[K_,Z_],Ed=Pn(...ey),Td=(e,t)=>{let r=e.indexOf("safari-extension")!==-1,n=e.indexOf("safari-web-extension")!==-1;return r||n?[e.indexOf("@")!==-1?e.split("@")[0]:"?",r?`safari-extension:${t}`:`safari-web-extension:${t}`]:[e,t]};var ty=40;function Id(e,t=js("fetch")){let r=0,n=0;async function i(s){let a=s.body.length;r+=a,n++;let c={body:s.body,method:"POST",referrerPolicy:"strict-origin",headers:e.headers,keepalive:r<=6e4&&n<15,...e.fetchOptions};try{let o=await t(e.url,c);return{statusCode:o.status,headers:{"x-sentry-rate-limits":o.headers.get("X-Sentry-Rate-Limits"),"retry-after":o.headers.get("Retry-After")}}}catch(o){throw pc("fetch"),o}finally{r-=a,n--}}return _s(e,i,Pr(e.bufferSize||ty))}var ry=/^HTML(\w*)Element$/;function Ad(e){if(typeof window<"u"&&e===window)return"[Window]";if(typeof document<"u"&&e===document)return"[Document]";if(uc(e)){let t=ny(e);if(ry.test(t))return`[HTMLElement: ${se(e)}]`}}function ny(e){let t=Object.getPrototypeOf(e);return t?.constructor?t.constructor.name:"null prototype"}function Rd(){return iy()?(ve&&Oe(()=>{console.error("[Sentry] You cannot use Sentry.init() in a browser extension, see: https://docs.sentry.io/platforms/javascript/best-practices/browser-extensions/")}),!0):!1}function iy(){if(typeof k.window>"u")return!1;let e=k;if(e.nw||!(e.chrome||e.browser)?.runtime?.id)return!1;let r=Ge();return!(k===k.top&&/^(?:chrome-extension|moz-extension|ms-browser-extension|safari-web-extension):\/\//.test(r))}function Od(e){return[Is(),Es(),Mo(),md(),ud(),_d(),vd(),Rs(),Sd(),hd(),gd()]}function sy(e={}){let t=!e.skipBrowserExtensionCheck&&Rd(),r=e.defaultIntegrations==null?Od():e.defaultIntegrations,n={...e,enabled:t?!1:e.enabled,stackParser:ji(e.stackParser||Ed),integrations:Wa({integrations:e.integrations,defaultIntegrations:r}),transport:e.transport||Id};return $i(Ad),Io(Ls,n)}var pe=T,Gc="sentryReplaySession",ay="replay_event",Wc="Unable to send Replay",oy=3e5,cy=9e5,ly=5e3,py=5500,uy=6e4,dy=5e3,my=3,xd=15e4,Qs=5e3,gy=3e3,fy=300,Yc=2e7,hy=4999,by=5e4,kd=36e5,_y=Object.defineProperty,yy=(e,t,r)=>t in e?_y(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,Nd=(e,t,r)=>yy(e,typeof t!="symbol"?t+"":t,r),Ee=(e=>(e[e.Document=0]="Document",e[e.DocumentType=1]="DocumentType",e[e.Element=2]="Element",e[e.Text=3]="Text",e[e.CDATA=4]="CDATA",e[e.Comment=5]="Comment",e))(Ee||{});function Sy(e){return e.nodeType===e.ELEMENT_NODE}function Oi(e){return e?.host?.shadowRoot===e}function xi(e){return Object.prototype.toString.call(e)==="[object ShadowRoot]"}function vy(e){return e.includes(" background-clip: text;")&&!e.includes(" -webkit-background-clip: text;")&&(e=e.replace(/\sbackground-clip:\s*text;/g," -webkit-background-clip: text; background-clip: text;")),e}function Ey(e){let{cssText:t}=e;if(t.split('"').length<3)return t;let r=["@import",`url(${JSON.stringify(e.href)})`];return e.layerName===""?r.push("layer"):e.layerName&&r.push(`layer(${e.layerName})`),e.supportsText&&r.push(`supports(${e.supportsText})`),e.media.length&&r.push(e.media.mediaText),r.join(" ")+";"}function na(e){try{let t=e.rules||e.cssRules;return t?vy(Array.from(t,tm).join("")):null}catch{return null}}function Ty(e){let t="";for(let r=0;rthis.removeNodeFromMap(n))}has(t){return this.idNodeMap.has(t)}hasNode(t){return this.nodeMetaMap.has(t)}add(t,r){let n=r.id;this.idNodeMap.set(n,t),this.nodeMetaMap.set(t,r)}replace(t,r){let n=this.getNode(t);if(n){let i=this.nodeMetaMap.get(n);i&&this.nodeMetaMap.set(r,i)}this.idNodeMap.set(t,r)}reset(){this.idNodeMap=new Map,this.nodeMetaMap=new WeakMap}};function Oy(){return new ia}function ya({maskInputOptions:e,tagName:t,type:r}){return t==="OPTION"&&(t="SELECT"),!!(e[t.toLowerCase()]||r&&e[r]||r==="password"||t==="INPUT"&&!r&&e.text)}function Ni({isMasked:e,element:t,value:r,maskInputFn:n}){let i=r||"";return e?(n&&(i=n(i,t)),"*".repeat(i.length)):i}function Rn(e){return e.toLowerCase()}function _c(e){return e.toUpperCase()}var wd="__rrweb_original__";function xy(e){let t=e.getContext("2d");if(!t)return!0;let r=50;for(let n=0;no!==0))return!1}return!0}function zc(e){let t=e.type;return e.hasAttribute("data-rr-is-password")?"password":t?Rn(t):null}function sa(e,t,r){return t==="INPUT"&&(r==="radio"||r==="checkbox")?e.getAttribute("value")||"":e.value}function rm(e,t){let r;try{r=new URL(e,t??window.location.href)}catch{return null}let n=/\.([0-9a-z]+)(?:$)/i;return r.pathname.match(n)?.[1]??null}var Cd={};function nm(e){let t=Cd[e];if(t)return t;let r=window.document,n=window[e];if(r&&typeof r.createElement=="function")try{let i=r.createElement("iframe");i.hidden=!0,r.head.appendChild(i);let s=i.contentWindow;s&&s[e]&&(n=s[e]),r.head.removeChild(i)}catch{}return Cd[e]=n.bind(window)}function yc(...e){return nm("setTimeout")(...e)}function im(...e){return nm("clearTimeout")(...e)}function sm(e){try{return e.contentDocument}catch{}}function ky(e){try{return e.contentWindow}catch{}}var Ny=1,wy=new RegExp("[^a-z0-9-_:]"),wi=-2;function Vc(){return Ny++}function Cy(e){if(e instanceof HTMLFormElement)return"form";let t=Rn(e.tagName);return wy.test(t)?"div":t}function My(e){let t="";return e.indexOf("//")>-1?t=e.split("/").slice(0,3).join("/"):t=e.split("/")[0],t=t.split("?")[0],t}var yn,Md,Ly=/url\((?:(')([^']*)'|(")(.*?)"|([^)]*))\)/gm,Py=/^(?:[a-z+]+:)?\/\//i,Dy=/^www\..*/i,Uy=/^(data:)([^,]*),(.*)/i;function Fy(e,t){if(!e||t.size===0)return e;try{let r=e.split(";"),n=[];for(let i of r){if(i=i.trim(),!i)continue;let s=i.indexOf(":");if(s===-1){n.push(i);continue}let a=i.slice(0,s).trim();t.has(a)||n.push(i)}return n.join("; ")+(n.length>0&&e.endsWith(";")?";":"")}catch(r){return console.warn("Error filtering CSS properties:",r),e}}function aa(e,t){return(e||"").replace(Ly,(r,n,i,s,a,c)=>{let o=i||a||c,l=n||s||"";if(!o)return r;if(Py.test(o)||Dy.test(o))return`url(${l}${o}${l})`;if(Uy.test(o))return`url(${l}${o}${l})`;if(o[0]==="/")return`url(${l}${My(t)+o}${l})`;let u=t.split("/"),p=o.split("/");u.pop();for(let d of p)d!=="."&&(d===".."?u.pop():u.push(d));return`url(${l}${u.join("/")}${l})`})}var By=/^[^ \t\n\r\u000c]+/,qy=/^[, \t\n\r\u000c]+/;function Hy(e,t){if(t.trim()==="")return t;let r=0;function n(s){let a,c=s.exec(t.substring(r));return c?(a=c[0],r+=a.length,a):""}let i=[];for(;n(qy),!(r>=t.length);){let s=n(By);if(s.slice(-1)===",")s=En(e,s.substring(0,s.length-1)),i.push(s);else{let a="";s=En(e,s);let c=!1;for(;;){let o=t.charAt(r);if(o===""){i.push((s+a).trim());break}else if(c)o===")"&&(c=!1);else if(o===","){r+=1,i.push((s+a).trim());break}else o==="("&&(c=!0);a+=o,r+=1}}}return i.join(", ")}var Ld=new WeakMap;function En(e,t){return!t||t.trim()===""?t:Sa(e,t)}function Gy(e){return!!(e.tagName==="svg"||e.ownerSVGElement)}function Sa(e,t){let r=Ld.get(e);if(r||(r=e.createElement("a"),Ld.set(e,r)),!t)t="";else if(t.startsWith("blob:")||t.startsWith("data:"))return t;return r.setAttribute("href",t),r.href}function am(e,t,r,n,i,s,a){if(!n)return n;if(r==="src"||r==="href"&&!(t==="use"&&n[0]==="#"))return En(e,n);if(r==="xlink:href"&&n[0]!=="#")return En(e,n);if(r==="background"&&(t==="table"||t==="td"||t==="th"))return En(e,n);if(r==="srcset")return Hy(e,n);if(r==="style"){let c=aa(n,Sa(e));return a&&a.size>0&&(c=Fy(c,a)),c}else if(t==="object"&&r==="data")return En(e,n);return typeof s=="function"?s(r,n,i):n}function om(e,t,r){return(e==="video"||e==="audio")&&t==="autoplay"}function Wy(e,t,r,n){try{if(n&&e.matches(n))return!1;if(typeof t=="string"){if(e.classList.contains(t))return!0}else for(let i=e.classList.length;i--;){let s=e.classList[i];if(t.test(s))return!0}if(r)return e.matches(r)}catch{}return!1}function Yy(e,t){for(let r=e.classList.length;r--;){let n=e.classList[r];if(t.test(n))return!0}return!1}function zr(e,t,r=1/0,n=0){return!e||e.nodeType!==e.ELEMENT_NODE||n>r?-1:t(e)?n:zr(e.parentNode,t,r,n+1)}function Tn(e,t){return r=>{let n=r;if(n===null)return!1;try{if(e){if(typeof e=="string"){if(n.matches(`.${e}`))return!0}else if(Yy(n,e))return!0}return!!(t&&n.matches(t))}catch{return!1}}}function On(e,t,r,n,i,s){try{let a=e.nodeType===e.ELEMENT_NODE?e:e.parentElement;if(a===null)return!1;if(a.tagName==="INPUT"){let l=a.getAttribute("autocomplete");if(["current-password","new-password","cc-number","cc-exp","cc-exp-month","cc-exp-year","cc-csc"].includes(l))return!0}let c=-1,o=-1;if(s){if(o=zr(a,Tn(n,i)),o<0)return!0;c=zr(a,Tn(t,r),o>=0?o:1/0)}else{if(c=zr(a,Tn(t,r)),c<0)return!1;o=zr(a,Tn(n,i),c>=0?c:1/0)}return c>=0?o>=0?c<=o:!0:o>=0?!1:!!s}catch{}return!!s}function zy(e,t,r){let n=ky(e);if(!n)return;let i=!1,s;try{s=n.document.readyState}catch{return}if(s!=="complete"){let c=yc(()=>{i||(t(),i=!0)},r);e.addEventListener("load",()=>{im(c),i=!0,t()});return}let a="about:blank";if(n.location.href!==a||e.src===a||e.src==="")return yc(t,0),e.addEventListener("load",t);e.addEventListener("load",t)}function Vy(e,t,r){let n=!1,i;try{i=e.sheet}catch{i=null}if(i)return;let s=yc(()=>{n||(t(),n=!0)},r);e.addEventListener("load",()=>{im(s),n=!0,t()})}function jy(e,t){let{doc:r,mirror:n,blockClass:i,blockSelector:s,unblockSelector:a,maskAllText:c,maskAttributeFn:o,maskTextClass:l,unmaskTextClass:u,maskTextSelector:p,unmaskTextSelector:d,inlineStylesheet:m,maskInputOptions:g={},maskTextFn:h,maskInputFn:S,dataURLOptions:b={},inlineImages:C,recordCanvas:q,keepIframeSrcFn:U,newlyAddedElement:Y=!1,ignoreCSSAttributes:D}=t,v=$y(r,n);switch(e.nodeType){case e.DOCUMENT_NODE:return e.compatMode!=="CSS1Compat"?{type:Ee.Document,childNodes:[],compatMode:e.compatMode}:{type:Ee.Document,childNodes:[]};case e.DOCUMENT_TYPE_NODE:return{type:Ee.DocumentType,name:e.name,publicId:e.publicId,systemId:e.systemId,rootId:v};case e.ELEMENT_NODE:return Xy(e,{doc:r,blockClass:i,blockSelector:s,unblockSelector:a,inlineStylesheet:m,maskAttributeFn:o,maskInputOptions:g,maskInputFn:S,dataURLOptions:b,inlineImages:C,recordCanvas:q,keepIframeSrcFn:U,newlyAddedElement:Y,rootId:v,maskTextClass:l,unmaskTextClass:u,maskTextSelector:p,unmaskTextSelector:d,ignoreCSSAttributes:D});case e.TEXT_NODE:return Ky(e,{doc:r,maskAllText:c,maskTextClass:l,unmaskTextClass:u,maskTextSelector:p,unmaskTextSelector:d,maskTextFn:h,maskInputOptions:g,maskInputFn:S,rootId:v});case e.CDATA_SECTION_NODE:return{type:Ee.CDATA,textContent:"",rootId:v};case e.COMMENT_NODE:return{type:Ee.Comment,textContent:e.textContent||"",rootId:v};default:return!1}}function $y(e,t){if(!t.hasNode(e))return;let r=t.getId(e);return r===1?void 0:r}function Ky(e,t){let{maskAllText:r,maskTextClass:n,unmaskTextClass:i,maskTextSelector:s,unmaskTextSelector:a,maskTextFn:c,maskInputOptions:o,maskInputFn:l,rootId:u}=t,p=e.parentNode&&e.parentNode.tagName,d=e.textContent,m=p==="STYLE"?!0:void 0,g=p==="SCRIPT"?!0:void 0,h=p==="TEXTAREA"?!0:void 0;if(m&&d){try{e.nextSibling||e.previousSibling||e.parentNode.sheet?.cssRules&&(d=na(e.parentNode.sheet))}catch(b){console.warn(`Cannot get CSS styles from text's parentNode. Error: ${b}`,e)}d=aa(d,Sa(t.doc))}g&&(d="SCRIPT_PLACEHOLDER");let S=On(e,n,s,i,a,r);if(!m&&!g&&!h&&d&&S&&(d=c?c(d,e.parentElement):d.replace(/[\S]/g,"*")),h&&d&&(o.textarea||S)&&(d=l?l(d,e.parentNode):d.replace(/[\S]/g,"*")),p==="OPTION"&&d){let b=ya({type:null,tagName:p,maskInputOptions:o});d=Ni({isMasked:On(e,n,s,i,a,b),element:e,value:d,maskInputFn:l})}return{type:Ee.Text,textContent:d||"",isStyle:m,rootId:u}}function Xy(e,t){let{doc:r,blockClass:n,blockSelector:i,unblockSelector:s,inlineStylesheet:a,maskInputOptions:c={},maskAttributeFn:o,maskInputFn:l,dataURLOptions:u={},inlineImages:p,recordCanvas:d,keepIframeSrcFn:m,newlyAddedElement:g=!1,rootId:h,maskTextClass:S,unmaskTextClass:b,maskTextSelector:C,unmaskTextSelector:q,ignoreCSSAttributes:U}=t,Y=Wy(e,n,i,s),D=Cy(e),v={},F=e.attributes.length;for(let y=0;yK.href===e.href),M=null;y&&(M=na(y)),M&&(v.rel=null,v.href=null,v.crossorigin=null,v._cssText=aa(M,y.href))}if(D==="style"&&e.sheet&&!(e.innerText||e.textContent||"").trim().length){let y=na(e.sheet);y&&(v._cssText=aa(y,Sa(r)))}if(D==="input"||D==="textarea"||D==="select"||D==="option"){let y=e,M=zc(y),K=sa(y,_c(D),M),ee=y.checked;if(M!=="submit"&&M!=="button"&&K){let re=On(y,S,C,b,q,ya({type:M,tagName:_c(D),maskInputOptions:c}));v.value=Ni({isMasked:re,element:y,value:K,maskInputFn:l})}ee&&(v.checked=ee)}if(D==="option"&&(e.selected&&!c.select?v.selected=!0:delete v.selected),D==="canvas"&&d){if(e.__context==="2d")xy(e)||(v.rr_dataURL=e.toDataURL(u.type,u.quality));else if(!("__context"in e)){let y=e.toDataURL(u.type,u.quality),M=r.createElement("canvas");M.width=e.width,M.height=e.height;let K=M.toDataURL(u.type,u.quality);y!==K&&(v.rr_dataURL=y)}}if(D==="img"&&p){yn||(yn=r.createElement("canvas"),Md=yn.getContext("2d"));let y=e,M=y.currentSrc||y.getAttribute("src")||"",K=y.crossOrigin,ee=()=>{y.removeEventListener("load",ee);try{yn.width=y.naturalWidth,yn.height=y.naturalHeight,Md.drawImage(y,0,0),v.rr_dataURL=yn.toDataURL(u.type,u.quality)}catch(re){if(y.crossOrigin!=="anonymous"){y.crossOrigin="anonymous",y.complete&&y.naturalWidth!==0?ee():y.addEventListener("load",ee);return}else console.warn(`Cannot inline img src=${M}! Error: ${re}`)}y.crossOrigin==="anonymous"&&(K?v.crossOrigin=K:y.removeAttribute("crossorigin"))};y.complete&&y.naturalWidth!==0?ee():y.addEventListener("load",ee)}if((D==="audio"||D==="video")&&(v.rr_mediaState=e.paused?"paused":"played",v.rr_mediaCurrentTime=e.currentTime),g||(e.scrollLeft&&(v.rr_scrollLeft=e.scrollLeft),e.scrollTop&&(v.rr_scrollTop=e.scrollTop)),Y){let{width:y,height:M}=e.getBoundingClientRect();v={class:v.class,rr_width:`${y}px`,rr_height:`${M}px`}}D==="iframe"&&!m(v.src)&&(!Y&&!sm(e)&&(v.rr_src=v.src),delete v.src);let x;try{customElements.get(D)&&(x=!0)}catch{}return{type:Ee.Element,tagName:D,attributes:v,childNodes:[],isSVG:Gy(e)||void 0,needBlock:Y,rootId:h,isCustom:x}}function le(e){return e==null?"":e.toLowerCase()}function Jy(e,t){if(t.comment&&e.type===Ee.Comment)return!0;if(e.type===Ee.Element){if(t.script&&(e.tagName==="script"||e.tagName==="link"&&(e.attributes.rel==="preload"||e.attributes.rel==="modulepreload")||e.tagName==="link"&&e.attributes.rel==="prefetch"&&typeof e.attributes.href=="string"&&rm(e.attributes.href)==="js"))return!0;if(t.headFavicon&&(e.tagName==="link"&&e.attributes.rel==="shortcut icon"||e.tagName==="meta"&&(le(e.attributes.name).match(/^msapplication-tile(image|color)$/)||le(e.attributes.name)==="application-name"||le(e.attributes.rel)==="icon"||le(e.attributes.rel)==="apple-touch-icon"||le(e.attributes.rel)==="shortcut icon")))return!0;if(e.tagName==="meta"){if(t.headMetaDescKeywords&&le(e.attributes.name).match(/^description|keywords$/))return!0;if(t.headMetaSocial&&(le(e.attributes.property).match(/^(og|twitter|fb):/)||le(e.attributes.name).match(/^(og|twitter):/)||le(e.attributes.name)==="pinterest"))return!0;if(t.headMetaRobots&&(le(e.attributes.name)==="robots"||le(e.attributes.name)==="googlebot"||le(e.attributes.name)==="bingbot"))return!0;if(t.headMetaHttpEquiv&&e.attributes["http-equiv"]!==void 0)return!0;if(t.headMetaAuthorship&&(le(e.attributes.name)==="author"||le(e.attributes.name)==="generator"||le(e.attributes.name)==="framework"||le(e.attributes.name)==="publisher"||le(e.attributes.name)==="progid"||le(e.attributes.property).match(/^article:/)||le(e.attributes.property).match(/^product:/)))return!0;if(t.headMetaVerification&&(le(e.attributes.name)==="google-site-verification"||le(e.attributes.name)==="yandex-verification"||le(e.attributes.name)==="csrf-token"||le(e.attributes.name)==="p:domain_verify"||le(e.attributes.name)==="verify-v1"||le(e.attributes.name)==="verification"||le(e.attributes.name)==="shopify-checkout-api-token"))return!0}}return!1}function In(e,t){let{doc:r,mirror:n,blockClass:i,blockSelector:s,unblockSelector:a,maskAllText:c,maskTextClass:o,unmaskTextClass:l,maskTextSelector:u,unmaskTextSelector:p,skipChild:d=!1,inlineStylesheet:m=!0,maskInputOptions:g={},maskAttributeFn:h,maskTextFn:S,maskInputFn:b,slimDOMOptions:C,dataURLOptions:q={},inlineImages:U=!1,recordCanvas:Y=!1,onSerialize:D,onIframeLoad:v,iframeLoadTimeout:F=5e3,onBlockedImageLoad:x,onStylesheetLoad:y,stylesheetLoadTimeout:M=5e3,keepIframeSrcFn:K=()=>!1,newlyAddedElement:ee=!1,ignoreCSSAttributes:re}=t,{preserveWhiteSpace:ue=!0}=t,W=jy(e,{doc:r,mirror:n,blockClass:i,blockSelector:s,maskAllText:c,unblockSelector:a,maskTextClass:o,unmaskTextClass:l,maskTextSelector:u,unmaskTextSelector:p,inlineStylesheet:m,maskInputOptions:g,maskAttributeFn:h,maskTextFn:S,maskInputFn:b,dataURLOptions:q,inlineImages:U,recordCanvas:Y,keepIframeSrcFn:K,newlyAddedElement:ee,ignoreCSSAttributes:re});if(!W)return console.warn(e,"not serialized"),null;let L;n.hasNode(e)?L=n.getId(e):Jy(W,C)||!ue&&W.type===Ee.Text&&!W.isStyle&&!W.textContent.trim().length?L=wi:L=Vc();let A=Object.assign(W,{id:L});if(n.add(e,A),L===wi)return null;D&&D(e);let H=!d;if(A.type===Ee.Element){H=H&&!A.needBlock;let B=e.shadowRoot;B&&xi(B)&&(A.isShadowHost=!0)}if((A.type===Ee.Document||A.type===Ee.Element)&&H){C.headWhitespace&&A.type===Ee.Element&&A.tagName==="head"&&(ue=!1);let B={doc:r,mirror:n,blockClass:i,blockSelector:s,maskAllText:c,unblockSelector:a,maskTextClass:o,unmaskTextClass:l,maskTextSelector:u,unmaskTextSelector:p,skipChild:d,inlineStylesheet:m,maskInputOptions:g,maskAttributeFn:h,maskTextFn:S,maskInputFn:b,slimDOMOptions:C,dataURLOptions:q,inlineImages:U,recordCanvas:Y,preserveWhiteSpace:ue,onSerialize:D,onIframeLoad:v,iframeLoadTimeout:F,onBlockedImageLoad:x,onStylesheetLoad:y,stylesheetLoadTimeout:M,keepIframeSrcFn:K,ignoreCSSAttributes:re},ae=e.childNodes?Array.from(e.childNodes):[];for(let oe of ae){let ce=In(oe,B);ce&&A.childNodes.push(ce)}if(Sy(e)&&e.shadowRoot)for(let oe of Array.from(e.shadowRoot.childNodes)){let ce=In(oe,B);ce&&(xi(e.shadowRoot)&&(ce.isShadow=!0),A.childNodes.push(ce))}}if(e.parentNode&&Oi(e.parentNode)&&xi(e.parentNode)&&(A.isShadow=!0),A.type===Ee.Element&&A.tagName==="iframe"&&!A.needBlock&&zy(e,()=>{let B=sm(e);if(B&&v){let ae=In(B,{doc:B,mirror:n,blockClass:i,blockSelector:s,unblockSelector:a,maskAllText:c,maskTextClass:o,unmaskTextClass:l,maskTextSelector:u,unmaskTextSelector:p,skipChild:!1,inlineStylesheet:m,maskInputOptions:g,maskAttributeFn:h,maskTextFn:S,maskInputFn:b,slimDOMOptions:C,dataURLOptions:q,inlineImages:U,recordCanvas:Y,preserveWhiteSpace:ue,onSerialize:D,onIframeLoad:v,iframeLoadTimeout:F,onStylesheetLoad:y,stylesheetLoadTimeout:M,keepIframeSrcFn:K,ignoreCSSAttributes:re});ae&&v(e,ae)}},F),A.type===Ee.Element&&A.tagName==="img"&&!e.complete&&A.needBlock){let B=e,ae=()=>{if(B.isConnected&&!B.complete&&x)try{let oe=B.getBoundingClientRect();oe.width>0&&oe.height>0&&x(B,A,oe)}catch{}B.removeEventListener("load",ae)};B.isConnected&&B.addEventListener("load",ae)}return A.type===Ee.Element&&A.tagName==="link"&&typeof A.attributes.rel=="string"&&(A.attributes.rel==="stylesheet"||A.attributes.rel==="preload"&&typeof A.attributes.href=="string"&&rm(A.attributes.href)==="css")&&Vy(e,()=>{if(y){let B=In(e,{doc:r,mirror:n,blockClass:i,blockSelector:s,unblockSelector:a,maskAllText:c,maskTextClass:o,unmaskTextClass:l,maskTextSelector:u,unmaskTextSelector:p,skipChild:!1,inlineStylesheet:m,maskInputOptions:g,maskAttributeFn:h,maskTextFn:S,maskInputFn:b,slimDOMOptions:C,dataURLOptions:q,inlineImages:U,recordCanvas:Y,preserveWhiteSpace:ue,onSerialize:D,onIframeLoad:v,iframeLoadTimeout:F,onStylesheetLoad:y,stylesheetLoadTimeout:M,keepIframeSrcFn:K,ignoreCSSAttributes:re});B&&y(e,B)}},M),A.type===Ee.Element&&delete A.needBlock,A}function Qy(e,t){let{mirror:r=new ia,blockClass:n="rr-block",blockSelector:i=null,unblockSelector:s=null,maskAllText:a=!1,maskTextClass:c="rr-mask",unmaskTextClass:o=null,maskTextSelector:l=null,unmaskTextSelector:u=null,inlineStylesheet:p=!0,inlineImages:d=!1,recordCanvas:m=!1,maskAllInputs:g=!1,maskAttributeFn:h,maskTextFn:S,maskInputFn:b,slimDOM:C=!1,dataURLOptions:q,preserveWhiteSpace:U,onSerialize:Y,onIframeLoad:D,iframeLoadTimeout:v,onBlockedImageLoad:F,onStylesheetLoad:x,stylesheetLoadTimeout:y,keepIframeSrcFn:M=()=>!1,ignoreCSSAttributes:K=new Set([])}=t||{};return In(e,{doc:e,mirror:r,blockClass:n,blockSelector:i,unblockSelector:s,maskAllText:a,maskTextClass:c,unmaskTextClass:o,maskTextSelector:l,unmaskTextSelector:u,skipChild:!1,inlineStylesheet:p,maskInputOptions:g===!0?{color:!0,date:!0,"datetime-local":!0,email:!0,month:!0,number:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0,textarea:!0,select:!0}:g===!1?{}:g,maskAttributeFn:h,maskTextFn:S,maskInputFn:b,slimDOMOptions:C===!0||C==="all"?{script:!0,comment:!0,headFavicon:!0,headWhitespace:!0,headMetaDescKeywords:C==="all",headMetaSocial:!0,headMetaRobots:!0,headMetaHttpEquiv:!0,headMetaAuthorship:!0,headMetaVerification:!0}:C===!1?{}:C,dataURLOptions:q,inlineImages:d,recordCanvas:m,preserveWhiteSpace:U,onSerialize:Y,onIframeLoad:D,iframeLoadTimeout:v,onBlockedImageLoad:F,onStylesheetLoad:x,stylesheetLoadTimeout:y,keepIframeSrcFn:M,newlyAddedElement:!1,ignoreCSSAttributes:K})}function Ye(e,t,r=document){let n={capture:!0,passive:!0};return r.addEventListener(e,t,n),()=>r.removeEventListener(e,t,n)}var Sn=`Please stop import mirror directly. Instead of that,\r +now you can use replayer.getMirror() to access the mirror instance of a replayer,\r +or you can use record.mirror to access the mirror instance during recording.`,Pd={map:{},getId(){return console.error(Sn),-1},getNode(){return console.error(Sn),null},removeNodeFromMap(){console.error(Sn)},has(){return console.error(Sn),!1},reset(){console.error(Sn)}};typeof window<"u"&&window.Proxy&&window.Reflect&&(Pd=new Proxy(Pd,{get(e,t,r){return t==="map"&&console.error(Sn),Reflect.get(e,t,r)}}));function Ci(e,t,r={}){let n=null,i=0;return function(...s){let a=Date.now();!i&&r.leading===!1&&(i=a);let c=t-(a-i),o=this;c<=0||c>t?(n&&(iS(n),n=null),i=a,e.apply(o,s)):!n&&r.trailing!==!1&&(n=va(()=>{i=r.leading===!1?0:Date.now(),n=null,e.apply(o,s)},c))}}function cm(e,t,r,n,i=window){let s=i.Object.getOwnPropertyDescriptor(e,t);return i.Object.defineProperty(e,t,n?r:{set(a){va(()=>{r.set.call(this,a)},0),s&&s.set&&s.set.call(this,a)}}),()=>cm(e,t,s||{},!0)}function jc(e,t,r){try{if(!(t in e))return()=>{};let n=e[t],i=r(n);return typeof i=="function"&&(i.prototype=i.prototype||{},Object.defineProperties(i,{__rrweb_original__:{enumerable:!1,value:n}})),e[t]=i,()=>{e[t]=n}}catch{return()=>{}}}var oa=Date.now;/[1-9][0-9]{12}/.test(Date.now().toString())||(oa=()=>new Date().getTime());function lm(e){let t=e.document;return{left:t.scrollingElement?t.scrollingElement.scrollLeft:e.pageXOffset!==void 0?e.pageXOffset:t?.documentElement.scrollLeft||t?.body?.parentElement?.scrollLeft||t?.body?.scrollLeft||0,top:t.scrollingElement?t.scrollingElement.scrollTop:e.pageYOffset!==void 0?e.pageYOffset:t?.documentElement.scrollTop||t?.body?.parentElement?.scrollTop||t?.body?.scrollTop||0}}function pm(){return window.innerHeight||document.documentElement&&document.documentElement.clientHeight||document.body&&document.body.clientHeight}function um(){return window.innerWidth||document.documentElement&&document.documentElement.clientWidth||document.body&&document.body.clientWidth}function dm(e){if(!e)return null;try{return e.nodeType===e.ELEMENT_NODE?e:e.parentElement}catch{return null}}function rt(e,t,r,n,i){if(!e)return!1;let s=dm(e);if(!s)return!1;let a=Tn(t,r);if(!i){let l=n&&s.matches(n);return a(s)&&!l}let c=zr(s,a),o=-1;return c<0?!1:(n&&(o=zr(s,Tn(null,n))),c>-1&&o<0?!0:c{let r=t[0];if(!(0 in t))throw new TypeError("1 argument is required");do if(this===r)return!0;while(r=r&&r.parentNode);return!1})}function gm(e,t){return!!(e.nodeName==="IFRAME"&&t.getMeta(e))}function fm(e,t){return!!(e.nodeName==="LINK"&&e.nodeType===e.ELEMENT_NODE&&e.getAttribute&&e.getAttribute("rel")==="stylesheet"&&t.getMeta(e))}function vc(e){return!!e?.shadowRoot}var Ec=class{constructor(){this.id=1,this.styleIDMap=new WeakMap,this.idStyleMap=new Map}getId(t){return this.styleIDMap.get(t)??-1}has(t){return this.styleIDMap.has(t)}add(t,r){if(this.has(t))return this.getId(t);let n;return r===void 0?n=this.id++:n=r,this.styleIDMap.set(t,n),this.idStyleMap.set(n,t),n}getStyle(t){return this.idStyleMap.get(t)||null}reset(){this.styleIDMap=new WeakMap,this.idStyleMap=new Map,this.id=1}generateId(){return this.id++}};function hm(e){let t=null;return e.getRootNode?.()?.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&e.getRootNode().host&&(t=e.getRootNode().host),t}function tS(e){let t=e,r;for(;r=hm(t);)t=r;return t}function rS(e){let t=e.ownerDocument;if(!t)return!1;let r=tS(e);return t.contains(r)}function bm(e){let t=e.ownerDocument;return t?t.contains(e)||rS(e):!1}var Dd={};function $c(e){let t=Dd[e];if(t)return t;let r=window.document,n=window[e];if(r&&typeof r.createElement=="function")try{let i=r.createElement("iframe");i.hidden=!0,r.head.appendChild(i);let s=i.contentWindow;s&&s[e]&&(n=s[e]),r.head.removeChild(i)}catch{}return Dd[e]=n.bind(window)}function nS(...e){return $c("requestAnimationFrame")(...e)}function va(...e){return $c("setTimeout")(...e)}function iS(...e){return $c("clearTimeout")(...e)}var G=(e=>(e[e.DomContentLoaded=0]="DomContentLoaded",e[e.Load=1]="Load",e[e.FullSnapshot=2]="FullSnapshot",e[e.IncrementalSnapshot=3]="IncrementalSnapshot",e[e.Meta=4]="Meta",e[e.Custom=5]="Custom",e[e.Plugin=6]="Plugin",e))(G||{}),P=(e=>(e[e.Mutation=0]="Mutation",e[e.MouseMove=1]="MouseMove",e[e.MouseInteraction=2]="MouseInteraction",e[e.Scroll=3]="Scroll",e[e.ViewportResize=4]="ViewportResize",e[e.Input=5]="Input",e[e.TouchMove=6]="TouchMove",e[e.MediaInteraction=7]="MediaInteraction",e[e.StyleSheetRule=8]="StyleSheetRule",e[e.CanvasMutation=9]="CanvasMutation",e[e.Font=10]="Font",e[e.Log=11]="Log",e[e.Drag=12]="Drag",e[e.StyleDeclaration=13]="StyleDeclaration",e[e.Selection=14]="Selection",e[e.AdoptedStyleSheet=15]="AdoptedStyleSheet",e[e.CustomElement=16]="CustomElement",e))(P||{}),We=(e=>(e[e.MouseUp=0]="MouseUp",e[e.MouseDown=1]="MouseDown",e[e.Click=2]="Click",e[e.ContextMenu=3]="ContextMenu",e[e.DblClick=4]="DblClick",e[e.Focus=5]="Focus",e[e.Blur=6]="Blur",e[e.TouchStart=7]="TouchStart",e[e.TouchMove_Departed=8]="TouchMove_Departed",e[e.TouchEnd=9]="TouchEnd",e[e.TouchCancel=10]="TouchCancel",e))(We||{}),Zt=(e=>(e[e.Mouse=0]="Mouse",e[e.Pen=1]="Pen",e[e.Touch=2]="Touch",e))(Zt||{}),vn=(e=>(e[e.Play=0]="Play",e[e.Pause=1]="Pause",e[e.Seeked=2]="Seeked",e[e.VolumeChange=3]="VolumeChange",e[e.RateChange=4]="RateChange",e))(vn||{}),ki;function sS(e){ki=e}function aS(){ki=void 0}var $=e=>ki?((...r)=>{try{return e(...r)}catch(n){if(ki&&ki(n)===!0)return()=>{};throw n}}):e,Ud="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",oS=typeof Uint8Array>"u"?[]:new Uint8Array(256);for(Ai=0;Ai"u"||typeof CSSStyleSheet.prototype.replaceSync!="function")return null;try{let r=new CSSStyleSheet;r.replaceSync(`x { ${t} }`);let n=r.cssRules[0];return!n||n.type!==CSSRule.STYLE_RULE?null:n.style}catch{return null}}parseWithDetachedElement(t){let r=this.getUnattachedDoc().createElement("span");return r.setAttribute("style",t),r.style}getUnattachedDoc(){if(!this.unattachedDoc)try{this.unattachedDoc=document.implementation.createHTMLDocument()}catch{this.unattachedDoc=this.doc}return this.unattachedDoc}};function Fd(e){return"__ln"in e}var Ic=class{constructor(){this.length=0,this.head=null,this.tail=null}get(t){if(t>=this.length)throw new Error("Position outside of list range");let r=this.head;for(let n=0;n`${e}@${t}`,Ac=class{constructor(){this.frozen=!1,this.locked=!1,this.texts=[],this.attributes=[],this.attributeMap=new WeakMap,this.removes=[],this.mapRemoves=[],this.movedMap={},this.addedSet=new Set,this.movedSet=new Set,this.droppedSet=new Set,this.processMutations=t=>{t.forEach(this.processMutation),this.emit()},this.emit=()=>{if(this.frozen||this.locked)return;let t=[],r=new Set,n=new Ic,i=o=>{let l=o,u=wi;for(;u===wi;)l=l&&l.nextSibling,u=l&&this.mirror.getId(l);return u},s=o=>{if(!o.parentNode||!bm(o))return;let l=Oi(o.parentNode)?this.mirror.getId(hm(o)):this.mirror.getId(o.parentNode),u=i(o);if(l===-1||u===-1)return n.addNode(o);let p=In(o,{doc:this.doc,mirror:this.mirror,blockClass:this.blockClass,blockSelector:this.blockSelector,maskAllText:this.maskAllText,unblockSelector:this.unblockSelector,maskTextClass:this.maskTextClass,unmaskTextClass:this.unmaskTextClass,maskTextSelector:this.maskTextSelector,unmaskTextSelector:this.unmaskTextSelector,skipChild:!0,newlyAddedElement:!0,inlineStylesheet:this.inlineStylesheet,maskInputOptions:this.maskInputOptions,maskAttributeFn:this.maskAttributeFn,maskTextFn:this.maskTextFn,maskInputFn:this.maskInputFn,slimDOMOptions:this.slimDOMOptions,dataURLOptions:this.dataURLOptions,recordCanvas:this.recordCanvas,inlineImages:this.inlineImages,onSerialize:d=>{gm(d,this.mirror)&&!rt(d,this.blockClass,this.blockSelector,this.unblockSelector,!1)&&this.iframeManager.addIframe(d),fm(d,this.mirror)&&this.stylesheetManager.trackLinkElement(d),vc(o)&&this.shadowDomManager.addShadowRoot(o.shadowRoot,this.doc)},onIframeLoad:(d,m)=>{if(rt(d,this.blockClass,this.blockSelector,this.unblockSelector,!1))return;this.iframeManager.attachIframe(d,m);let g=Mi(d);g&&this.canvasManager.addWindow(g),this.shadowDomManager.observeAttachShadow(d)},onStylesheetLoad:(d,m)=>{this.stylesheetManager.attachLinkElement(d,m)},onBlockedImageLoad:(d,m,{width:g,height:h})=>{this.mutationCb({adds:[],removes:[],texts:[],attributes:[{id:m.id,attributes:{style:{width:`${g}px`,height:`${h}px`}}}]})},ignoreCSSAttributes:this.ignoreCSSAttributes});p&&(t.push({parentId:l,nextId:u,node:p}),r.add(p.id))};for(;this.mapRemoves.length;)this.mirror.removeNodeFromMap(this.mapRemoves.shift());for(let o of this.movedSet)qd(this.removes,o,this.mirror)&&!this.movedSet.has(o.parentNode)||s(o);for(let o of this.addedSet)!Hd(this.droppedSet,o)&&!qd(this.removes,o,this.mirror)||Hd(this.movedSet,o)?s(o):this.droppedSet.add(o);let a=null;for(;n.length;){let o=null;if(a){let l=this.mirror.getId(a.value.parentNode),u=i(a.value);l!==-1&&u!==-1&&(o=a)}if(!o){let l=n.tail;for(;l;){let u=l;if(l=l.previous,u){let p=this.mirror.getId(u.value.parentNode);if(i(u.value)===-1)continue;if(p!==-1){o=u;break}else{let m=u.value;if(m.parentNode&&m.parentNode.nodeType===Node.DOCUMENT_FRAGMENT_NODE){let g=m.parentNode.host;if(this.mirror.getId(g)!==-1){o=u;break}}}}}}if(!o){for(;n.head;)n.removeNode(n.head.value);break}a=o.previous,n.removeNode(o.value),s(o.value)}let c={texts:this.texts.map(o=>({id:this.mirror.getId(o.node),value:o.value})).filter(o=>!r.has(o.id)).filter(o=>this.mirror.has(o.id)),attributes:this.attributes.map(o=>{let{attributes:l}=o;if(typeof l.style=="string"){let u=JSON.stringify(o.styleDiff),p=JSON.stringify(o._unchangedStyles);u.length!r.has(o.id)).filter(o=>this.mirror.has(o.id)),removes:this.removes,adds:t};!c.texts.length&&!c.attributes.length&&!c.removes.length&&!c.adds.length||(this.texts=[],this.attributes=[],this.attributeMap=new WeakMap,this.removes=[],this.addedSet=new Set,this.movedSet=new Set,this.droppedSet=new Set,this.movedMap={},this.mutationCb(c))},this.processMutation=t=>{if(!mc(t.target,this.mirror))switch(t.type){case"characterData":{let r=t.target.textContent;!rt(t.target,this.blockClass,this.blockSelector,this.unblockSelector,!1)&&r!==t.oldValue&&this.texts.push({value:On(t.target,this.maskTextClass,this.maskTextSelector,this.unmaskTextClass,this.unmaskTextSelector,this.maskAllText)&&r?this.maskTextFn?this.maskTextFn(r,dm(t.target)):r.replace(/[\S]/g,"*"):r,node:t.target});break}case"attributes":{let r=t.target,n=t.attributeName,i=t.target.getAttribute(n);if(n==="value"){let a=zc(r),c=r.tagName;i=sa(r,c,a);let o=ya({maskInputOptions:this.maskInputOptions,tagName:c,type:a}),l=On(t.target,this.maskTextClass,this.maskTextSelector,this.unmaskTextClass,this.unmaskTextSelector,o);i=Ni({isMasked:l,element:r,value:i,maskInputFn:this.maskInputFn})}if(rt(t.target,this.blockClass,this.blockSelector,this.unblockSelector,!1)||i===t.oldValue)return;let s=this.attributeMap.get(t.target);if(r.tagName==="IFRAME"&&n==="src"&&!this.keepIframeSrcFn(i))if(!Kc(r))n="rr_src";else return;if(s||(s={node:t.target,attributes:{},styleDiff:{},_unchangedStyles:{}},this.attributes.push(s),this.attributeMap.set(t.target,s)),n==="type"&&r.tagName==="INPUT"&&(t.oldValue||"").toLowerCase()==="password"&&r.setAttribute("data-rr-is-password","true"),!om(r.tagName,n)&&(s.attributes[n]=am(this.doc,Rn(r.tagName),Rn(n),i,r,this.maskAttributeFn),n==="style")){let a=t.oldValue?this.styleDeclarationParser.parse(t.oldValue):null;for(let c of Array.from(r.style)){let o=r.style.getPropertyValue(c),l=r.style.getPropertyPriority(c);o!==(a?.getPropertyValue(c)||"")||l!==(a?.getPropertyPriority(c)||"")?l===""?s.styleDiff[c]=o:s.styleDiff[c]=[o,l]:s._unchangedStyles[c]=[o,l]}if(a)for(let c of Array.from(a))r.style.getPropertyValue(c)===""&&(s.styleDiff[c]=!1)}break}case"childList":{if(rt(t.target,this.blockClass,this.blockSelector,this.unblockSelector,!0))return;t.addedNodes.forEach(r=>this.genAdds(r,t.target)),t.removedNodes.forEach(r=>{let n=this.mirror.getId(r),i=Oi(t.target)?this.mirror.getId(t.target.host):this.mirror.getId(t.target);rt(t.target,this.blockClass,this.blockSelector,this.unblockSelector,!1)||mc(r,this.mirror)||!Zy(r,this.mirror)||(this.addedSet.has(r)?(Rc(this.addedSet,r),this.droppedSet.add(r)):this.addedSet.has(t.target)&&n===-1||mm(t.target,this.mirror)||(this.movedSet.has(r)&&this.movedMap[Bd(n,i)]?Rc(this.movedSet,r):this.removes.push({parentId:i,id:n,isShadow:Oi(t.target)&&xi(t.target)?!0:void 0})),this.mapRemoves.push(r))});break}}},this.genAdds=(t,r)=>{if(!this.processedNodeManager.inOtherBuffer(t,this)&&!(this.addedSet.has(t)||this.movedSet.has(t))){if(this.mirror.hasNode(t)){if(mc(t,this.mirror))return;this.movedSet.add(t);let n=null;r&&this.mirror.hasNode(r)&&(n=this.mirror.getId(r)),n&&n!==-1&&(this.movedMap[Bd(this.mirror.getId(t),n)]=!0)}else this.addedSet.add(t),this.droppedSet.delete(t);rt(t,this.blockClass,this.blockSelector,this.unblockSelector,!1)||(t.childNodes&&t.childNodes.forEach(n=>this.genAdds(n)),vc(t)&&t.shadowRoot.childNodes.forEach(n=>{this.processedNodeManager.add(n,this),this.genAdds(n,t)}))}}}init(t){["mutationCb","blockClass","blockSelector","unblockSelector","maskAllText","maskTextClass","unmaskTextClass","maskTextSelector","unmaskTextSelector","inlineStylesheet","maskInputOptions","maskAttributeFn","maskTextFn","maskInputFn","keepIframeSrcFn","recordCanvas","inlineImages","slimDOMOptions","dataURLOptions","doc","mirror","iframeManager","stylesheetManager","shadowDomManager","canvasManager","processedNodeManager","ignoreCSSAttributes"].forEach(r=>{this[r]=t[r]}),this.styleDeclarationParser=new Tc(this.doc)}freeze(){this.frozen=!0,this.canvasManager.freeze()}unfreeze(){this.frozen=!1,this.canvasManager.unfreeze(),this.emit()}isFrozen(){return this.frozen}lock(){this.locked=!0,this.canvasManager.lock()}unlock(){this.locked=!1,this.canvasManager.unlock(),this.emit()}reset(){this.shadowDomManager.reset(),this.canvasManager.reset()}};function Rc(e,t){e.delete(t),t.childNodes?.forEach(r=>Rc(e,r))}function qd(e,t,r){return e.length===0?!1:cS(e,t,r)}function cS(e,t,r){let n=t.parentNode;for(;n;){let i=r.getId(n);if(e.some(s=>s.id===i))return!0;n=n.parentNode}return!1}function Hd(e,t){return e.size===0?!1:_m(e,t)}function _m(e,t){let{parentNode:r}=t;return r?e.has(r)?!0:_m(e,r):!1}var An=[];function Fi(e){try{if("composedPath"in e){let t=e.composedPath();if(t.length)return t[0]}else if("path"in e&&e.path.length)return e.path[0]}catch{}return e&&e.target}function ym(e,t){let r=new Ac;An.push(r),r.init(e);let n=window.MutationObserver||window.__rrMutationObserver,i=window?.Zone?.__symbol__?.("MutationObserver");i&&window[i]&&(n=window[i]);let s=new n($(a=>{e.onMutation&&e.onMutation(a)===!1||r.processMutations.bind(r)(a)}));return s.observe(t,{attributes:!0,attributeOldValue:!0,characterData:!0,characterDataOldValue:!0,childList:!0,subtree:!0}),s}function lS({mousemoveCb:e,sampling:t,doc:r,mirror:n}){if(t.mousemove===!1)return()=>{};let i=typeof t.mousemove=="number"?t.mousemove:50,s=typeof t.mousemoveCallback=="number"?t.mousemoveCallback:500,a=[],c,o=Ci($(p=>{let d=Date.now()-c;e(a.map(m=>(m.timeOffset-=d,m)),p),a=[],c=null}),s),l=$(Ci($(p=>{let d=Fi(p),{clientX:m,clientY:g}=Sc(p)?p.changedTouches[0]:p;c||(c=oa()),a.push({x:m,y:g,id:n.getId(d),timeOffset:oa()-c}),o(typeof DragEvent<"u"&&p instanceof DragEvent?P.Drag:p instanceof MouseEvent?P.MouseMove:P.TouchMove)}),i,{trailing:!1})),u=[Ye("mousemove",l,r),Ye("touchmove",l,r),Ye("drag",l,r)];return $(()=>{u.forEach(p=>p())})}function pS({mouseInteractionCb:e,doc:t,mirror:r,blockClass:n,blockSelector:i,unblockSelector:s,sampling:a}){if(a.mouseInteraction===!1)return()=>{};let c=a.mouseInteraction===!0||a.mouseInteraction===void 0?{}:a.mouseInteraction,o=[],l=null,u=p=>d=>{let m=Fi(d);if(rt(m,n,i,s,!0))return;let g=null,h=p;if("pointerType"in d){switch(d.pointerType){case"mouse":g=Zt.Mouse;break;case"touch":g=Zt.Touch;break;case"pen":g=Zt.Pen;break}g===Zt.Touch?We[p]===We.MouseDown?h="TouchStart":We[p]===We.MouseUp&&(h="TouchEnd"):Zt.Pen}else Sc(d)&&(g=Zt.Touch);g!==null?(l=g,(h.startsWith("Touch")&&g===Zt.Touch||h.startsWith("Mouse")&&g===Zt.Mouse)&&(g=null)):We[p]===We.Click&&(g=l,l=null);let S=Sc(d)?d.changedTouches[0]:d;if(!S)return;let b=r.getId(m),{clientX:C,clientY:q}=S;$(e)({type:We[h],id:b,x:C,y:q,...g!==null&&{pointerType:g}})};return Object.keys(We).filter(p=>Number.isNaN(Number(p))&&!p.endsWith("_Departed")&&c[p]!==!1).forEach(p=>{let d=Rn(p),m=u(p);if(window.PointerEvent)switch(We[p]){case We.MouseDown:case We.MouseUp:d=d.replace("mouse","pointer");break;case We.TouchStart:case We.TouchEnd:return}o.push(Ye(d,m,t))}),$(()=>{o.forEach(p=>p())})}function Sm({scrollCb:e,doc:t,mirror:r,blockClass:n,blockSelector:i,unblockSelector:s,sampling:a}){let c=$(Ci($(o=>{let l=Fi(o);if(!l||rt(l,n,i,s,!0))return;let u=r.getId(l);if(l===t&&t.defaultView){let p=lm(t.defaultView);e({id:u,x:p.left,y:p.top})}else e({id:u,x:l.scrollLeft,y:l.scrollTop})}),a.scroll||100));return Ye("scroll",c,t)}function uS({viewportResizeCb:e},{win:t}){let r=-1,n=-1,i=$(Ci($(()=>{let s=pm(),a=um();(r!==s||n!==a)&&(e({width:Number(a),height:Number(s)}),r=s,n=a)}),200));return Ye("resize",i,t)}var dS=["INPUT","TEXTAREA","SELECT"],Gd=new WeakMap;function mS({inputCb:e,doc:t,mirror:r,blockClass:n,blockSelector:i,unblockSelector:s,ignoreClass:a,ignoreSelector:c,maskInputOptions:o,maskInputFn:l,sampling:u,userTriggeredOnInput:p,maskTextClass:d,unmaskTextClass:m,maskTextSelector:g,unmaskTextSelector:h}){function S(v){let F=Fi(v),x=v.isTrusted,y=F&&_c(F.tagName);if(y==="OPTION"&&(F=F.parentElement),!F||!y||dS.indexOf(y)<0||rt(F,n,i,s,!0))return;let M=F;if(M.classList.contains(a)||c&&M.matches(c))return;let K=zc(F),ee=sa(M,y,K),re=!1,ue=ya({maskInputOptions:o,tagName:y,type:K}),W=On(F,d,g,m,h,ue);(K==="radio"||K==="checkbox")&&(re=F.checked),ee=Ni({isMasked:W,element:F,value:ee,maskInputFn:l}),b(F,p?{text:ee,isChecked:re,userTriggered:x}:{text:ee,isChecked:re});let L=F.name;K==="radio"&&L&&re&&t.querySelectorAll(`input[type="radio"][name="${L}"]`).forEach(A=>{if(A!==F){let H=Ni({isMasked:W,element:A,value:sa(A,y,K),maskInputFn:l});b(A,p?{text:H,isChecked:!re,userTriggered:!1}:{text:H,isChecked:!re})}})}function b(v,F){let x=Gd.get(v);if(!x||x.text!==F.text||x.isChecked!==F.isChecked){Gd.set(v,F);let y=r.getId(v);$(e)({...F,id:y})}}let q=(u.input==="last"?["change"]:["input","change"]).map(v=>Ye(v,$(S),t)),U=t.defaultView;if(!U)return()=>{q.forEach(v=>v())};let Y=U.Object.getOwnPropertyDescriptor(U.HTMLInputElement.prototype,"value"),D=[[U.HTMLInputElement.prototype,"value"],[U.HTMLInputElement.prototype,"checked"],[U.HTMLSelectElement.prototype,"value"],[U.HTMLTextAreaElement.prototype,"value"],[U.HTMLSelectElement.prototype,"selectedIndex"],[U.HTMLOptionElement.prototype,"selected"]];return Y&&Y.set&&q.push(...D.map(v=>cm(v[0],v[1],{set(){$(S)({target:this,isTrusted:!1})}},!1,U))),$(()=>{q.forEach(v=>v())})}function la(e){let t=[];function r(n,i){if(Zs("CSSGroupingRule")&&n.parentRule instanceof CSSGroupingRule||Zs("CSSMediaRule")&&n.parentRule instanceof CSSMediaRule||Zs("CSSSupportsRule")&&n.parentRule instanceof CSSSupportsRule||Zs("CSSConditionRule")&&n.parentRule instanceof CSSConditionRule){let a=Array.from(n.parentRule.cssRules).indexOf(n);i.unshift(a)}else if(n.parentStyleSheet){let a=Array.from(n.parentStyleSheet.cssRules).indexOf(n);i.unshift(a)}return i}return r(e,t)}function mr(e,t,r){let n,i;return e?(e.ownerNode?n=t.getId(e.ownerNode):i=r.getId(e),{styleId:i,id:n}):{}}function gS({styleSheetRuleCb:e,mirror:t,stylesheetManager:r},{win:n}){if(!n.CSSStyleSheet||!n.CSSStyleSheet.prototype)return()=>{};let i=n.CSSStyleSheet.prototype.insertRule;n.CSSStyleSheet.prototype.insertRule=new Proxy(i,{apply:$((u,p,d)=>{let[m,g]=d,{id:h,styleId:S}=mr(p,t,r.styleMirror);return(h&&h!==-1||S&&S!==-1)&&e({id:h,styleId:S,adds:[{rule:m,index:g}]}),u.apply(p,d)})});let s=n.CSSStyleSheet.prototype.deleteRule;n.CSSStyleSheet.prototype.deleteRule=new Proxy(s,{apply:$((u,p,d)=>{let[m]=d,{id:g,styleId:h}=mr(p,t,r.styleMirror);return(g&&g!==-1||h&&h!==-1)&&e({id:g,styleId:h,removes:[{index:m}]}),u.apply(p,d)})});let a;n.CSSStyleSheet.prototype.replace&&(a=n.CSSStyleSheet.prototype.replace,n.CSSStyleSheet.prototype.replace=new Proxy(a,{apply:$((u,p,d)=>{let[m]=d,{id:g,styleId:h}=mr(p,t,r.styleMirror);return(g&&g!==-1||h&&h!==-1)&&e({id:g,styleId:h,replace:m}),u.apply(p,d)})}));let c;n.CSSStyleSheet.prototype.replaceSync&&(c=n.CSSStyleSheet.prototype.replaceSync,n.CSSStyleSheet.prototype.replaceSync=new Proxy(c,{apply:$((u,p,d)=>{let[m]=d,{id:g,styleId:h}=mr(p,t,r.styleMirror);return(g&&g!==-1||h&&h!==-1)&&e({id:g,styleId:h,replaceSync:m}),u.apply(p,d)})}));let o={};ea("CSSGroupingRule")?o.CSSGroupingRule=n.CSSGroupingRule:(ea("CSSMediaRule")&&(o.CSSMediaRule=n.CSSMediaRule),ea("CSSConditionRule")&&(o.CSSConditionRule=n.CSSConditionRule),ea("CSSSupportsRule")&&(o.CSSSupportsRule=n.CSSSupportsRule));let l={};return Object.entries(o).forEach(([u,p])=>{l[u]={insertRule:p.prototype.insertRule,deleteRule:p.prototype.deleteRule},p.prototype.insertRule=new Proxy(l[u].insertRule,{apply:$((d,m,g)=>{let[h,S]=g,{id:b,styleId:C}=mr(m.parentStyleSheet,t,r.styleMirror);return(b&&b!==-1||C&&C!==-1)&&e({id:b,styleId:C,adds:[{rule:h,index:[...la(m),S||0]}]}),d.apply(m,g)})}),p.prototype.deleteRule=new Proxy(l[u].deleteRule,{apply:$((d,m,g)=>{let[h]=g,{id:S,styleId:b}=mr(m.parentStyleSheet,t,r.styleMirror);return(S&&S!==-1||b&&b!==-1)&&e({id:S,styleId:b,removes:[{index:[...la(m),h]}]}),d.apply(m,g)})})}),$(()=>{n.CSSStyleSheet.prototype.insertRule=i,n.CSSStyleSheet.prototype.deleteRule=s,a&&(n.CSSStyleSheet.prototype.replace=a),c&&(n.CSSStyleSheet.prototype.replaceSync=c),Object.entries(o).forEach(([u,p])=>{p.prototype.insertRule=l[u].insertRule,p.prototype.deleteRule=l[u].deleteRule})})}function vm({mirror:e,stylesheetManager:t},r){let n=null;r.nodeName==="#document"?n=e.getId(r):n=e.getId(r.host);let i=r.nodeName==="#document"?r.defaultView?.Document:r.ownerDocument?.defaultView?.ShadowRoot,s=i?.prototype?Object.getOwnPropertyDescriptor(i?.prototype,"adoptedStyleSheets"):void 0;return n===null||n===-1||!i||!s?()=>{}:(Object.defineProperty(r,"adoptedStyleSheets",{configurable:s.configurable,enumerable:s.enumerable,get(){return s.get?.call(this)},set(a){let c=s.set?.call(this,a);if(n!==null&&n!==-1)try{t.adoptStyleSheets(a,n)}catch{}return c}}),$(()=>{Object.defineProperty(r,"adoptedStyleSheets",{configurable:s.configurable,enumerable:s.enumerable,get:s.get,set:s.set})}))}function fS({styleDeclarationCb:e,mirror:t,ignoreCSSAttributes:r,stylesheetManager:n},{win:i}){let s=i.CSSStyleDeclaration.prototype.setProperty;i.CSSStyleDeclaration.prototype.setProperty=new Proxy(s,{apply:$((c,o,l)=>{let[u,p,d]=l;if(r.has(u))return s.apply(o,[u,p,d]);let{id:m,styleId:g}=mr(o.parentRule?.parentStyleSheet,t,n.styleMirror);return(m&&m!==-1||g&&g!==-1)&&e({id:m,styleId:g,set:{property:u,value:p,priority:d},index:la(o.parentRule)}),c.apply(o,l)})});let a=i.CSSStyleDeclaration.prototype.removeProperty;return i.CSSStyleDeclaration.prototype.removeProperty=new Proxy(a,{apply:$((c,o,l)=>{let[u]=l;if(r.has(u))return a.apply(o,[u]);let{id:p,styleId:d}=mr(o.parentRule?.parentStyleSheet,t,n.styleMirror);return(p&&p!==-1||d&&d!==-1)&&e({id:p,styleId:d,remove:{property:u},index:la(o.parentRule)}),c.apply(o,l)})}),$(()=>{i.CSSStyleDeclaration.prototype.setProperty=s,i.CSSStyleDeclaration.prototype.removeProperty=a})}function hS({mediaInteractionCb:e,blockClass:t,blockSelector:r,unblockSelector:n,mirror:i,sampling:s,doc:a}){let c=$(l=>Ci($(u=>{let p=Fi(u);if(!p||rt(p,t,r,n,!0))return;let{currentTime:d,volume:m,muted:g,playbackRate:h}=p;e({type:l,id:i.getId(p),currentTime:d,volume:m,muted:g,playbackRate:h})}),s.media||500)),o=[Ye("play",c(vn.Play),a),Ye("pause",c(vn.Pause),a),Ye("seeked",c(vn.Seeked),a),Ye("volumechange",c(vn.VolumeChange),a),Ye("ratechange",c(vn.RateChange),a)];return $(()=>{o.forEach(l=>l())})}function bS({fontCb:e,doc:t}){let r=t.defaultView;if(!r)return()=>{};let n=[],i=new WeakMap,s=r.FontFace;r.FontFace=function(o,l,u){let p=new s(o,l,u);return i.set(p,{family:o,buffer:typeof l!="string",descriptors:u,fontSource:typeof l=="string"?l:JSON.stringify(Array.from(new Uint8Array(l)))}),p};let a=jc(t.fonts,"add",function(c){return function(o){return va($(()=>{let l=i.get(o);l&&(e(l),i.delete(o))}),0),c.apply(this,[o])}});return n.push(()=>{r.FontFace=s}),n.push(a),$(()=>{n.forEach(c=>c())})}function _S(e){let{doc:t,mirror:r,blockClass:n,blockSelector:i,unblockSelector:s,selectionCb:a}=e,c=!0,o=$(()=>{let l=t.getSelection();if(!l||c&&l?.isCollapsed)return;c=l.isCollapsed||!1;let u=[],p=l.rangeCount||0;for(let d=0;d{}:jc(r.customElements,"define",function(i){return function(s,a,c){try{t({define:{name:s}})}catch{}return i.apply(this,[s,a,c])}})}function SS(e,t={}){let r=e.doc.defaultView;if(!r)return()=>{};let n;e.recordDOM&&(n=ym(e,e.doc));let i=lS(e),s=pS(e),a=Sm(e),c=uS(e,{win:r}),o=mS(e),l=hS(e),u=()=>{},p=()=>{},d=()=>{},m=()=>{};e.recordDOM&&(u=gS(e,{win:r}),p=vm(e,e.doc),d=fS(e,{win:r}),e.collectFonts&&(m=bS(e)));let g=_S(e),h=yS(e),S=[];for(let b of e.plugins)S.push(b.observer(b.callback,r,b.options));return $(()=>{An.forEach(b=>b.reset()),n?.disconnect(),i(),s(),a(),c(),o(),l(),u(),p(),d(),m(),g(),h(),S.forEach(b=>b())})}function Zs(e){return typeof window[e]<"u"}function ea(e){return!!(typeof window[e]<"u"&&window[e].prototype&&"insertRule"in window[e].prototype&&"deleteRule"in window[e].prototype)}var Li=class{constructor(t){this.generateIdFn=t,this.iframeIdToRemoteIdMap=new WeakMap,this.iframeRemoteIdToIdMap=new WeakMap}getId(t,r,n,i){let s=n||this.getIdToRemoteIdMap(t),a=i||this.getRemoteIdToIdMap(t),c=s.get(r);return c||(c=this.generateIdFn(),s.set(r,c),a.set(c,r)),c}getIds(t,r){let n=this.getIdToRemoteIdMap(t),i=this.getRemoteIdToIdMap(t);return r.map(s=>this.getId(t,s,n,i))}getRemoteId(t,r,n){let i=n||this.getRemoteIdToIdMap(t);if(typeof r!="number")return r;let s=i.get(r);return s||-1}getRemoteIds(t,r){let n=this.getRemoteIdToIdMap(t);return r.map(i=>this.getRemoteId(t,i,n))}reset(t){if(!t){this.iframeIdToRemoteIdMap=new WeakMap,this.iframeRemoteIdToIdMap=new WeakMap;return}this.iframeIdToRemoteIdMap.delete(t),this.iframeRemoteIdToIdMap.delete(t)}getIdToRemoteIdMap(t){let r=this.iframeIdToRemoteIdMap.get(t);return r||(r=new Map,this.iframeIdToRemoteIdMap.set(t,r)),r}getRemoteIdToIdMap(t){let r=this.iframeRemoteIdToIdMap.get(t);return r||(r=new Map,this.iframeRemoteIdToIdMap.set(t,r)),r}},Oc=class{constructor(){this.crossOriginIframeMirror=new Li(Vc),this.crossOriginIframeRootIdMap=new WeakMap}addIframe(){}addLoadListener(){}attachIframe(){}},xc=class{constructor(t){this.iframes=new WeakMap,this.crossOriginIframeMap=new WeakMap,this.crossOriginIframeMirror=new Li(Vc),this.crossOriginIframeRootIdMap=new WeakMap,this.mutationCb=t.mutationCb,this.wrappedEmit=t.wrappedEmit,this.stylesheetManager=t.stylesheetManager,this.recordCrossOriginIframes=t.recordCrossOriginIframes,this.crossOriginIframeStyleMirror=new Li(this.stylesheetManager.styleMirror.generateId.bind(this.stylesheetManager.styleMirror)),this.mirror=t.mirror,this.recordCrossOriginIframes&&window.addEventListener("message",this.handleMessage.bind(this))}addIframe(t){this.iframes.set(t,!0);let r=Mi(t);r&&this.crossOriginIframeMap.set(r,t)}addLoadListener(t){this.loadListener=t}attachIframe(t,r){this.mutationCb({adds:[{parentId:this.mirror.getId(t),nextId:null,node:r}],removes:[],texts:[],attributes:[],isAttachIframe:!0}),this.recordCrossOriginIframes&&Mi(t)?.addEventListener("message",this.handleMessage.bind(this)),this.loadListener?.(t);let n=Kc(t);n&&n.adoptedStyleSheets&&n.adoptedStyleSheets.length>0&&this.stylesheetManager.adoptStyleSheets(n.adoptedStyleSheets,this.mirror.getId(n))}handleMessage(t){let r=t;if(r.data.type!=="rrweb"||r.origin!==r.data.origin||!t.source)return;let i=this.crossOriginIframeMap.get(t.source);if(!i)return;let s=this.transformCrossOriginEvent(i,r.data.event);s&&this.wrappedEmit(s,r.data.isCheckout)}transformCrossOriginEvent(t,r){switch(r.type){case G.FullSnapshot:{this.crossOriginIframeMirror.reset(t),this.crossOriginIframeStyleMirror.reset(t),this.replaceIdOnNode(r.data.node,t);let n=r.data.node.id;return this.crossOriginIframeRootIdMap.set(t,n),this.patchRootIdOnNode(r.data.node,n),{timestamp:r.timestamp,type:G.IncrementalSnapshot,data:{source:P.Mutation,adds:[{parentId:this.mirror.getId(t),nextId:null,node:r.data.node}],removes:[],texts:[],attributes:[],isAttachIframe:!0}}}case G.Meta:case G.Load:case G.DomContentLoaded:return!1;case G.Plugin:return r;case G.Custom:return this.replaceIds(r.data.payload,t,["id","parentId","previousId","nextId"]),r;case G.IncrementalSnapshot:switch(r.data.source){case P.Mutation:return r.data.adds.forEach(n=>{this.replaceIds(n,t,["parentId","nextId","previousId"]),this.replaceIdOnNode(n.node,t);let i=this.crossOriginIframeRootIdMap.get(t);i&&this.patchRootIdOnNode(n.node,i)}),r.data.removes.forEach(n=>{this.replaceIds(n,t,["parentId","id"])}),r.data.attributes.forEach(n=>{this.replaceIds(n,t,["id"])}),r.data.texts.forEach(n=>{this.replaceIds(n,t,["id"])}),r;case P.Drag:case P.TouchMove:case P.MouseMove:return r.data.positions.forEach(n=>{this.replaceIds(n,t,["id"])}),r;case P.ViewportResize:return!1;case P.MediaInteraction:case P.MouseInteraction:case P.Scroll:case P.CanvasMutation:case P.Input:return this.replaceIds(r.data,t,["id"]),r;case P.StyleSheetRule:case P.StyleDeclaration:return this.replaceIds(r.data,t,["id"]),this.replaceStyleIds(r.data,t,["styleId"]),r;case P.Font:return r;case P.Selection:return r.data.ranges.forEach(n=>{this.replaceIds(n,t,["start","end"])}),r;case P.AdoptedStyleSheet:return this.replaceIds(r.data,t,["id"]),this.replaceStyleIds(r.data,t,["styleIds"]),r.data.styles?.forEach(n=>{this.replaceStyleIds(n,t,["styleId"])}),r}}return!1}replace(t,r,n,i){for(let s of i)!Array.isArray(r[s])&&typeof r[s]!="number"||(Array.isArray(r[s])?r[s]=t.getIds(n,r[s]):r[s]=t.getId(n,r[s]));return r}replaceIds(t,r,n){return this.replace(this.crossOriginIframeMirror,t,r,n)}replaceStyleIds(t,r,n){return this.replace(this.crossOriginIframeStyleMirror,t,r,n)}replaceIdOnNode(t,r){this.replaceIds(t,r,["id","rootId"]),"childNodes"in t&&t.childNodes.forEach(n=>{this.replaceIdOnNode(n,r)})}patchRootIdOnNode(t,r){t.type!==Ee.Document&&!t.rootId&&(t.rootId=r),"childNodes"in t&&t.childNodes.forEach(n=>{this.patchRootIdOnNode(n,r)})}},kc=class{init(){}addShadowRoot(){}observeAttachShadow(){}reset(){}},Nc=class{constructor(t){this.shadowDoms=new WeakSet,this.restoreHandlers=[],this.mutationCb=t.mutationCb,this.scrollCb=t.scrollCb,this.bypassOptions=t.bypassOptions,this.mirror=t.mirror,this.init()}init(){this.reset(),this.patchAttachShadow(Element,document)}addShadowRoot(t,r){if(!xi(t)||this.shadowDoms.has(t))return;this.shadowDoms.add(t),this.bypassOptions.canvasManager.addShadowRoot(t);let n=ym({...this.bypassOptions,doc:r,mutationCb:this.mutationCb,mirror:this.mirror,shadowDomManager:this},t);this.restoreHandlers.push(()=>n.disconnect()),this.restoreHandlers.push(Sm({...this.bypassOptions,scrollCb:this.scrollCb,doc:t,mirror:this.mirror})),va(()=>{t.adoptedStyleSheets&&t.adoptedStyleSheets.length>0&&this.bypassOptions.stylesheetManager.adoptStyleSheets(t.adoptedStyleSheets,this.mirror.getId(t.host)),this.restoreHandlers.push(vm({mirror:this.mirror,stylesheetManager:this.bypassOptions.stylesheetManager},t))},0)}observeAttachShadow(t){let r=Kc(t),n=Mi(t);!r||!n||this.patchAttachShadow(n.Element,r)}patchAttachShadow(t,r){let n=this;this.restoreHandlers.push(jc(t.prototype,"attachShadow",function(i){return function(s){let a=i.call(this,s);return this.shadowRoot&&bm(this)&&n.addShadowRoot(this.shadowRoot,r),a}}))}reset(){this.restoreHandlers.forEach(t=>{try{t()}catch{}}),this.restoreHandlers=[],this.shadowDoms=new WeakSet,this.bypassOptions.canvasManager.resetShadowRoots()}},wc=class{constructor(t){this.trackedLinkElements=new WeakSet,this.styleMirror=new Ec,this.mutationCb=t.mutationCb,this.adoptedStyleSheetCb=t.adoptedStyleSheetCb}attachLinkElement(t,r){"_cssText"in r.attributes&&this.mutationCb({adds:[],removes:[],texts:[],attributes:[{id:r.id,attributes:r.attributes}]}),this.trackLinkElement(t)}trackLinkElement(t){this.trackedLinkElements.has(t)||(this.trackedLinkElements.add(t),this.trackStylesheetInLinkElement(t))}adoptStyleSheets(t,r){if(t.length===0)return;let n={id:r,styleIds:[]},i=[];for(let s of t){let a;this.styleMirror.has(s)?a=this.styleMirror.getId(s):(a=this.styleMirror.add(s),i.push({styleId:a,rules:Array.from(s.rules||CSSRule,(c,o)=>({rule:tm(c),index:o}))})),n.styleIds.push(a)}i.length>0&&(n.styles=i),this.adoptedStyleSheetCb(n)}reset(){this.styleMirror.reset(),this.trackedLinkElements=new WeakSet}trackStylesheetInLinkElement(t){}},Cc=class{constructor(){this.nodeMap=new WeakMap,this.active=!1}inOtherBuffer(t,r){let n=this.nodeMap.get(t);return n&&Array.from(n).some(i=>i!==r)}add(t,r){this.active||(this.active=!0,nS(()=>{this.nodeMap=new WeakMap,this.active=!1})),this.nodeMap.set(t,(this.nodeMap.get(t)||new Set).add(r))}destroy(){}},be,pa;try{if(Array.from([1],e=>e*2)[0]!==2){let e=document.createElement("iframe");document.body.appendChild(e),Array.from=e.contentWindow?.Array.from||Array.from,document.body.removeChild(e)}}catch(e){console.debug("Unable to override Array.from",e)}var Tt=Oy();function It(e={}){let{emit:t,checkoutEveryNms:r,checkoutEveryNth:n,blockClass:i="rr-block",blockSelector:s=null,unblockSelector:a=null,ignoreClass:c="rr-ignore",ignoreSelector:o=null,maskAllText:l=!1,maskTextClass:u="rr-mask",unmaskTextClass:p=null,maskTextSelector:d=null,unmaskTextSelector:m=null,inlineStylesheet:g=!0,maskAllInputs:h,maskInputOptions:S,slimDOMOptions:b,maskAttributeFn:C,maskInputFn:q,maskTextFn:U,maxCanvasSize:Y=null,packFn:D,sampling:v={},dataURLOptions:F={},mousemoveWait:x,recordDOM:y=!0,recordCanvas:M=!1,recordCrossOriginIframes:K=!1,recordAfter:ee=e.recordAfter==="DOMContentLoaded"?e.recordAfter:"load",userTriggeredOnInput:re=!1,collectFonts:ue=!1,inlineImages:W=!1,plugins:L,keepIframeSrcFn:A=()=>!1,ignoreCSSAttributes:H=new Set([]),errorHandler:B,onMutation:ae,getCanvasManager:oe}=e;sS(B);let ce=K?window.parent===window:!0,ge=!1;if(!ce)try{window.parent.document&&(ge=!1)}catch{ge=!0}if(ce&&!t)throw new Error("emit function is required");if(!ce&&!ge)return()=>{};x!==void 0&&v.mousemove===void 0&&(v.mousemove=x),Tt.reset();let hr=h===!0?{color:!0,date:!0,"datetime-local":!0,email:!0,month:!0,number:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0,textarea:!0,select:!0,radio:!0,checkbox:!0}:S!==void 0?S:{},Pt=b===!0||b==="all"?{script:!0,comment:!0,headFavicon:!0,headWhitespace:!0,headMetaSocial:!0,headMetaRobots:!0,headMetaHttpEquiv:!0,headMetaVerification:!0,headMetaAuthorship:b==="all",headMetaDescKeywords:b==="all"}:b||{};eS();let br,Dt=0,kn=J=>{for(let mt of L||[])mt.eventProcessor&&(J=mt.eventProcessor(J));return D&&!ge&&(J=D(J)),J};be=(J,mt)=>{let z=J;if(z.timestamp=oa(),An[0]?.isFrozen()&&z.type!==G.FullSnapshot&&!(z.type===G.IncrementalSnapshot&&z.data.source===P.Mutation)&&An.forEach(Re=>Re.unfreeze()),ce)t?.(kn(z),mt);else if(ge){let Re={type:"rrweb",event:kn(z),origin:window.location.origin,isCheckout:mt};window.parent.postMessage(Re,"*")}if(z.type===G.FullSnapshot)br=z,Dt=0;else if(z.type===G.IncrementalSnapshot){if(z.data.source===P.Mutation&&z.data.isAttachIframe)return;Dt++;let Re=n&&Dt>=n,V=r&&br&&z.timestamp-br.timestamp>r;(Re||V)&&xa(!0)}};let _r=J=>{be({type:G.IncrementalSnapshot,data:{source:P.Mutation,...J}})},al=J=>be({type:G.IncrementalSnapshot,data:{source:P.Scroll,...J}}),ng=J=>be({type:G.IncrementalSnapshot,data:{source:P.CanvasMutation,...J}}),ig=J=>be({type:G.IncrementalSnapshot,data:{source:P.AdoptedStyleSheet,...J}}),yr=new wc({mutationCb:_r,adoptedStyleSheetCb:ig}),Sr=typeof __RRWEB_EXCLUDE_IFRAME__=="boolean"&&__RRWEB_EXCLUDE_IFRAME__?new Oc:new xc({mirror:Tt,mutationCb:_r,stylesheetManager:yr,recordCrossOriginIframes:K,wrappedEmit:be});for(let J of L||[])J.getMirror&&J.getMirror({nodeMirror:Tt,crossOriginIframeMirror:Sr.crossOriginIframeMirror,crossOriginIframeStyleMirror:Sr.crossOriginIframeStyleMirror});let Ra=new Cc,Oa=ES(oe,{mirror:Tt,win:window,mutationCb:J=>be({type:G.IncrementalSnapshot,data:{source:P.CanvasMutation,...J}}),recordCanvas:M,blockClass:i,blockSelector:s,unblockSelector:a,maxCanvasSize:Y,sampling:v.canvas,dataURLOptions:F,errorHandler:B}),Hi=typeof __RRWEB_EXCLUDE_SHADOW_DOM__=="boolean"&&__RRWEB_EXCLUDE_SHADOW_DOM__?new kc:new Nc({mutationCb:_r,scrollCb:al,bypassOptions:{onMutation:ae,blockClass:i,blockSelector:s,unblockSelector:a,maskAllText:l,maskTextClass:u,unmaskTextClass:p,maskTextSelector:d,unmaskTextSelector:m,inlineStylesheet:g,maskInputOptions:hr,dataURLOptions:F,maskAttributeFn:C,maskTextFn:U,maskInputFn:q,recordCanvas:M,inlineImages:W,sampling:v,slimDOMOptions:Pt,iframeManager:Sr,stylesheetManager:yr,canvasManager:Oa,keepIframeSrcFn:A,processedNodeManager:Ra,ignoreCSSAttributes:H},mirror:Tt}),xa=(J=!1)=>{if(!y)return;be({type:G.Meta,data:{href:window.location.href,width:um(),height:pm()}},J),yr.reset(),Hi.init(),An.forEach(z=>z.lock());let mt=Qy(document,{mirror:Tt,blockClass:i,blockSelector:s,unblockSelector:a,maskAllText:l,maskTextClass:u,unmaskTextClass:p,maskTextSelector:d,unmaskTextSelector:m,inlineStylesheet:g,maskAllInputs:hr,maskAttributeFn:C,maskInputFn:q,maskTextFn:U,slimDOM:Pt,dataURLOptions:F,recordCanvas:M,inlineImages:W,onSerialize:z=>{gm(z,Tt)&&Sr.addIframe(z),fm(z,Tt)&&yr.trackLinkElement(z),vc(z)&&Hi.addShadowRoot(z.shadowRoot,document)},onIframeLoad:(z,Re)=>{Sr.attachIframe(z,Re);let V=Mi(z);V&&Oa.addWindow(V),Hi.observeAttachShadow(z)},onStylesheetLoad:(z,Re)=>{yr.attachLinkElement(z,Re)},onBlockedImageLoad:(z,Re,{width:V,height:Nn})=>{_r({adds:[],removes:[],texts:[],attributes:[{id:Re.id,attributes:{style:{width:`${V}px`,height:`${Nn}px`}}}]})},keepIframeSrcFn:A,ignoreCSSAttributes:H});if(!mt)return console.warn("Failed to snapshot the document");be({type:G.FullSnapshot,data:{node:mt,initialOffset:lm(window)}}),An.forEach(z=>z.unlock()),document.adoptedStyleSheets&&document.adoptedStyleSheets.length>0&&yr.adoptStyleSheets(document.adoptedStyleSheets,Tt.getId(document))};pa=xa;try{let J=[],mt=Re=>$(SS)({onMutation:ae,mutationCb:_r,mousemoveCb:(V,Nn)=>be({type:G.IncrementalSnapshot,data:{source:Nn,positions:V}}),mouseInteractionCb:V=>be({type:G.IncrementalSnapshot,data:{source:P.MouseInteraction,...V}}),scrollCb:al,viewportResizeCb:V=>be({type:G.IncrementalSnapshot,data:{source:P.ViewportResize,...V}}),inputCb:V=>be({type:G.IncrementalSnapshot,data:{source:P.Input,...V}}),mediaInteractionCb:V=>be({type:G.IncrementalSnapshot,data:{source:P.MediaInteraction,...V}}),styleSheetRuleCb:V=>be({type:G.IncrementalSnapshot,data:{source:P.StyleSheetRule,...V}}),styleDeclarationCb:V=>be({type:G.IncrementalSnapshot,data:{source:P.StyleDeclaration,...V}}),canvasMutationCb:ng,fontCb:V=>be({type:G.IncrementalSnapshot,data:{source:P.Font,...V}}),selectionCb:V=>{be({type:G.IncrementalSnapshot,data:{source:P.Selection,...V}})},customElementCb:V=>{be({type:G.IncrementalSnapshot,data:{source:P.CustomElement,...V}})},blockClass:i,ignoreClass:c,ignoreSelector:o,maskAllText:l,maskTextClass:u,unmaskTextClass:p,maskTextSelector:d,unmaskTextSelector:m,maskInputOptions:hr,inlineStylesheet:g,sampling:v,recordDOM:y,recordCanvas:M,inlineImages:W,userTriggeredOnInput:re,collectFonts:ue,doc:Re,maskAttributeFn:C,maskInputFn:q,maskTextFn:U,keepIframeSrcFn:A,blockSelector:s,unblockSelector:a,slimDOMOptions:Pt,dataURLOptions:F,mirror:Tt,iframeManager:Sr,stylesheetManager:yr,shadowDomManager:Hi,processedNodeManager:Ra,canvasManager:Oa,ignoreCSSAttributes:H,plugins:L?.filter(V=>V.observer)?.map(V=>({observer:V.observer,options:V.options,callback:Nn=>be({type:G.Plugin,data:{plugin:V.name,payload:Nn}})}))||[]},{});Sr.addLoadListener(Re=>{try{J.push(mt(Re.contentDocument))}catch(V){console.warn(V)}});let z=()=>{xa(),J.push(mt(document))};return document.readyState==="interactive"||document.readyState==="complete"?z():(J.push(Ye("DOMContentLoaded",()=>{be({type:G.DomContentLoaded,data:{}}),ee==="DOMContentLoaded"&&z()})),J.push(Ye("load",()=>{be({type:G.Load,data:{}}),ee==="load"&&z()},window))),()=>{J.forEach(Re=>Re()),Ra.destroy(),pa=void 0,aS()}}catch(J){console.warn(J)}}function vS(e){if(!pa)throw new Error("please take full snapshot after start recording");pa(e)}It.mirror=Tt;It.takeFullSnapshot=vS;function ES(e,t){try{return e?e(t):new ca}catch{return console.warn("Unable to initialize CanvasManager"),new ca}}var Wd;(function(e){e[e.NotStarted=0]="NotStarted",e[e.Running=1]="Running",e[e.Stopped=2]="Stopped"})(Wd||(Wd={}));var TS=3,IS=5;function Xc(e){return e>9999999999?e:e*1e3}function gc(e){return e>9999999999?e/1e3:e}function Bi(e,t){t.category!=="sentry.transaction"&&(["ui.click","ui.input"].includes(t.category)?e.triggerUserActivity():e.checkAndHandleExpiredSession(),e.addUpdate(()=>(e.throttledAddEvent({type:G.Custom,timestamp:(t.timestamp||0)*1e3,data:{tag:"breadcrumb",payload:Me(t,10,1e3)}}),t.category==="console")))}var AS="button,a";function Em(e){return e.closest(AS)||e}function Tm(e){let t=Im(e);return!t||!(t instanceof Element)?t:Em(t)}function Im(e){return RS(e)?e.target:e}function RS(e){return Ze(e)&&"target"in e}var gr;function OS(e){return gr||(gr=[],xS()),gr.push(e),()=>{let t=gr?gr.indexOf(e):-1;t>-1&&gr.splice(t,1)}}function xS(){fe(pe,"open",function(e){return function(...t){if(gr)try{gr.forEach(r=>r())}catch{}return e.apply(pe,t)}})}var kS=new Set([P.Mutation,P.StyleSheetRule,P.StyleDeclaration,P.AdoptedStyleSheet,P.CanvasMutation,P.Selection,P.MediaInteraction]);function NS(e,t,r){e.handleClick(t,r)}var Mc=class{constructor(t,r,n=Bi){this._lastMutation=0,this._lastScroll=0,this._clicks=[],this._timeout=r.timeout/1e3,this._threshold=r.threshold/1e3,this._scrollTimeout=r.scrollTimeout/1e3,this._replay=t,this._ignoreSelector=r.ignoreSelector,this._addBreadcrumbEvent=n}addListeners(){let t=OS(()=>{this._lastMutation=Yd()});this._teardown=()=>{t(),this._clicks=[],this._lastMutation=0,this._lastScroll=0}}removeListeners(){this._teardown&&this._teardown(),this._checkClickTimeout&&clearTimeout(this._checkClickTimeout)}handleClick(t,r){if(CS(r,this._ignoreSelector)||!MS(t))return;let n={timestamp:gc(t.timestamp),clickBreadcrumb:t,clickCount:0,node:r};this._clicks.some(i=>i.node===n.node&&Math.abs(i.timestamp-n.timestamp)<1)||(this._clicks.push(n),this._clicks.length===1&&this._scheduleCheckClicks())}registerMutation(t=Date.now()){this._lastMutation=gc(t)}registerScroll(t=Date.now()){this._lastScroll=gc(t)}registerClick(t){let r=Em(t);this._handleMultiClick(r)}_handleMultiClick(t){this._getClicks(t).forEach(r=>{r.clickCount++})}_getClicks(t){return this._clicks.filter(r=>r.node===t)}_checkClicks(){let t=[],r=Yd();this._clicks.forEach(n=>{!n.mutationAfter&&this._lastMutation&&(n.mutationAfter=n.timestamp<=this._lastMutation?this._lastMutation-n.timestamp:void 0),!n.scrollAfter&&this._lastScroll&&(n.scrollAfter=n.timestamp<=this._lastScroll?this._lastScroll-n.timestamp:void 0),n.timestamp+this._timeout<=r&&t.push(n)});for(let n of t){let i=this._clicks.indexOf(n);i>-1&&(this._generateBreadcrumbs(n),this._clicks.splice(i,1))}this._clicks.length&&this._scheduleCheckClicks()}_generateBreadcrumbs(t){let r=this._replay,n=t.scrollAfter&&t.scrollAfter<=this._scrollTimeout,i=t.mutationAfter&&t.mutationAfter<=this._threshold,s=!n&&!i,{clickCount:a,clickBreadcrumb:c}=t;if(s){let o=Math.min(t.mutationAfter||this._timeout,this._timeout)*1e3,l=o1){let o={type:"default",message:c.message,timestamp:c.timestamp,category:"ui.multiClick",data:{...c.data,url:pe.location.href,route:r.getCurrentRoute(),clickCount:a,metric:!0}};this._addBreadcrumbEvent(r,o)}}_scheduleCheckClicks(){this._checkClickTimeout&&clearTimeout(this._checkClickTimeout),this._checkClickTimeout=Yr(()=>this._checkClicks(),1e3)}},wS=["A","BUTTON","INPUT"];function CS(e,t){return!!(!wS.includes(e.tagName)||e.tagName==="INPUT"&&!["submit","button"].includes(e.getAttribute("type")||"")||e.tagName==="A"&&(e.hasAttribute("download")||e.hasAttribute("target")&&e.getAttribute("target")!=="_self")||t&&e.matches(t))}function MS(e){return!!(e.data&&typeof e.data.nodeId=="number"&&e.timestamp)}function Yd(){return Date.now()/1e3}function LS(e,t){try{if(!PS(t))return;let{source:r}=t.data;if(kS.has(r)&&e.registerMutation(t.timestamp),r===P.Scroll&&e.registerScroll(t.timestamp),DS(t)){let{type:n,id:i}=t.data,s=It.mirror.getNode(i);s instanceof HTMLElement&&n===We.Click&&e.registerClick(s)}}catch{}}function PS(e){return e.type===TS}function DS(e){return e.data.source===P.MouseInteraction}function Lt(e){return{timestamp:Date.now()/1e3,type:"default",...e}}var Ea=(e=>(e[e.Document=0]="Document",e[e.DocumentType=1]="DocumentType",e[e.Element=2]="Element",e[e.Text=3]="Text",e[e.CDATA=4]="CDATA",e[e.Comment=5]="Comment",e))(Ea||{}),US=new Set(["id","class","aria-label","role","name","alt","title","data-test-id","data-testid","disabled","aria-disabled","data-sentry-component"]);function FS(e){let t={};!e["data-sentry-component"]&&e["data-sentry-element"]&&(e["data-sentry-component"]=e["data-sentry-element"]);for(let r in e)if(US.has(r)){let n=r;(r==="data-testid"||r==="data-test-id")&&(n="testId"),t[n]=e[r]}return t}var BS=e=>t=>{if(!e.isEnabled())return;let r=qS(t);if(!r)return;let n=t.name==="click",i=n?t.event:void 0;n&&e.clickDetector&&i?.target&&!i.altKey&&!i.metaKey&&!i.ctrlKey&&!i.shiftKey&&NS(e.clickDetector,r,Tm(t.event)),Bi(e,r)};function Am(e,t){let r=It.mirror.getId(e),n=r&&It.mirror.getNode(r),i=n&&It.mirror.getMeta(n),s=i&&GS(i)?i:null;return{message:t,data:s?{nodeId:r,node:{id:r,tagName:s.tagName,textContent:Array.from(s.childNodes).map(a=>a.type===Ea.Text&&a.textContent).filter(Boolean).map(a=>a.trim()).join(""),attributes:FS(s.attributes)}}:{}}}function qS(e){let{target:t,message:r}=HS(e);return Lt({category:`ui.${e.name}`,...Am(t,r)})}function HS(e){let t=e.name==="click",r,n=null;try{n=t?Tm(e.event):Im(e.event),r=se(n,{maxStringLength:200})||""}catch{r=""}return{target:n,message:r}}function GS(e){return e.type===Ea.Element}function WS(e,t){if(!e.isEnabled())return;e.updateUserActivity();let r=YS(t);r&&Bi(e,r)}function YS(e){let{metaKey:t,shiftKey:r,ctrlKey:n,altKey:i,key:s,target:a}=e;if(!a||zS(a)||!s)return null;let c=t||n||i,o=s.length===1;if(!c&&o)return null;let l=se(a,{maxStringLength:200})||"",u=Am(a,l);return Lt({category:"ui.keyDown",message:l,data:{...u.data,metaKey:t,shiftKey:r,ctrlKey:n,altKey:i,key:s}})}function zS(e){return e.tagName==="INPUT"||e.tagName==="TEXTAREA"||e.isContentEditable}var VS={resource:JS,paint:KS,navigation:XS};function fc(e,t){return({metric:r})=>void t.replayPerformanceEntries.push(e(r))}function jS(e){return e.map($S).filter(Boolean)}function $S(e){let t=VS[e.entryType];return t?t(e):null}function xn(e){return((ie()||pe.performance.timeOrigin)+e)/1e3}function KS(e){let{duration:t,entryType:r,name:n,startTime:i}=e,s=xn(i);return{type:r,name:n,start:s,end:s+t,data:void 0}}function XS(e){let{entryType:t,name:r,decodedBodySize:n,duration:i,domComplete:s,encodedBodySize:a,domContentLoadedEventStart:c,domContentLoadedEventEnd:o,domInteractive:l,loadEventStart:u,loadEventEnd:p,redirectCount:d,startTime:m,transferSize:g,type:h}=e;return i===0?null:{type:`${t}.${h}`,start:xn(m),end:xn(s),name:r,data:{size:g,decodedBodySize:n,encodedBodySize:a,duration:i,domInteractive:l,domContentLoadedEventStart:c,domContentLoadedEventEnd:o,loadEventStart:u,loadEventEnd:p,domComplete:s,redirectCount:d}}}function JS(e){let{entryType:t,initiatorType:r,name:n,responseEnd:i,startTime:s,decodedBodySize:a,encodedBodySize:c,responseStatus:o,transferSize:l}=e;return["fetch","xmlhttprequest"].includes(r)?null:{type:`${t}.${r}`,start:xn(s),end:xn(i),name:n,data:{size:l,statusCode:o,decodedBodySize:a,encodedBodySize:c}}}function QS(e){let t=e.entries[e.entries.length-1],r=t?.element?[t.element]:void 0;return Jc(e,"largest-contentful-paint",r)}function ZS(e){return e.sources!==void 0}function ev(e){let t=[],r=[];for(let n of e.entries)if(ZS(n)){let i=[];for(let s of n.sources)if(s.node){r.push(s.node);let a=It.mirror.getId(s.node);a&&i.push(a)}t.push({value:n.value,nodeIds:i.length?i:void 0})}return Jc(e,"cumulative-layout-shift",r,t)}function tv(e){let t=e.entries[e.entries.length-1],r=t?.target?[t.target]:void 0;return Jc(e,"interaction-to-next-paint",r)}function Jc(e,t,r,n){let i=e.value,s=e.rating,a=xn(i);return{type:"web-vital",name:t,start:a,end:a,data:{value:i,size:i,rating:s,nodeIds:r?r.map(c=>It.mirror.getId(c)):void 0,attributions:n}}}function rv(e){function t(i){e.performanceEntries.includes(i)||e.performanceEntries.push(i)}function r({entries:i}){i.forEach(t)}let n=[];return["navigation","paint","resource"].forEach(i=>{n.push(ut(i,r))}),n.push(Xt(fc(QS,e)),Kt(fc(ev,e)),Br(fc(tv,e))),()=>{n.forEach(i=>i())}}var N=typeof __SENTRY_DEBUG__>"u"||__SENTRY_DEBUG__,nv='var t=Uint8Array,n=Uint16Array,r=Int32Array,e=new t([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),i=new t([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),s=new t([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),a=function(t,e){for(var i=new n(31),s=0;s<31;++s)i[s]=e+=1<>1|(21845&c)<<1;v=(61680&(v=(52428&v)>>2|(13107&v)<<2))>>4|(3855&v)<<4,u[c]=((65280&v)>>8|(255&v)<<8)>>1}var d=function(t,r,e){for(var i=t.length,s=0,a=new n(r);s>f]=l}else for(o=new n(i),s=0;s>15-t[s]);return o},p=new t(288);for(c=0;c<144;++c)p[c]=8;for(c=144;c<256;++c)p[c]=9;for(c=256;c<280;++c)p[c]=7;for(c=280;c<288;++c)p[c]=8;var g=new t(32);for(c=0;c<32;++c)g[c]=5;var w=d(p,9,0),y=d(g,5,0),m=function(t){return(t+7)/8|0},b=function(n,r,e){return(null==e||e>n.length)&&(e=n.length),new t(n.subarray(r,e))},M=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],E=function(t,n,r){var e=new Error(n||M[t]);if(e.code=t,Error.captureStackTrace&&Error.captureStackTrace(e,E),!r)throw e;return e},z=function(t,n,r){r<<=7&n;var e=n/8|0;t[e]|=r,t[e+1]|=r>>8},_=function(t,n,r){r<<=7&n;var e=n/8|0;t[e]|=r,t[e+1]|=r>>8,t[e+2]|=r>>16},x=function(r,e){for(var i=[],s=0;sd&&(d=o[s].s);var p=new n(d+1),g=A(i[c-1],p,0);if(g>e){s=0;var w=0,y=g-e,m=1<e))break;w+=m-(1<>=y;w>0;){var M=o[s].s;p[M]=0&&w;--s){var E=o[s].s;p[E]==e&&(--p[E],++w)}g=e}return{t:new t(p),l:g}},A=function(t,n,r){return-1==t.s?Math.max(A(t.l,n,r+1),A(t.r,n,r+1)):n[t.s]=r},D=function(t){for(var r=t.length;r&&!t[--r];);for(var e=new n(++r),i=0,s=t[0],a=1,o=function(t){e[i++]=t},h=1;h<=r;++h)if(t[h]==s&&h!=r)++a;else{if(!s&&a>2){for(;a>138;a-=138)o(32754);a>2&&(o(a>10?a-11<<5|28690:a-3<<5|12305),a=0)}else if(a>3){for(o(s),--a;a>6;a-=6)o(8304);a>2&&(o(a-3<<5|8208),a=0)}for(;a--;)o(s);a=1,s=t[h]}return{c:e.subarray(0,i),n:r}},T=function(t,n){for(var r=0,e=0;e>8,t[i+2]=255^t[i],t[i+3]=255^t[i+1];for(var s=0;s4&&!H[s[K-1]];--K);var N,P,Q,R,V=v+5<<3,W=T(h,p)+T(f,g)+l,X=T(h,M)+T(f,U)+l+14+3*K+T(q,H)+2*q[16]+3*q[17]+7*q[18];if(c>=0&&V<=W&&V<=X)return k(r,m,t.subarray(c,c+v));if(z(r,m,1+(X15&&(z(r,m,tt[B]>>5&127),m+=tt[B]>>12)}}}else N=w,P=p,Q=y,R=g;for(B=0;B255){_(r,m,N[(nt=rt>>18&31)+257]),m+=P[nt+257],nt>7&&(z(r,m,rt>>23&31),m+=e[nt]);var et=31&rt;_(r,m,Q[et]),m+=R[et],et>3&&(_(r,m,rt>>5&8191),m+=i[et])}else _(r,m,N[rt]),m+=P[rt]}return _(r,m,N[256]),m+P[256]},C=new r([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),F=new t(0),I=function(){for(var t=new Int32Array(256),n=0;n<256;++n){for(var r=n,e=9;--e;)r=(1&r&&-306674912)^r>>>1;t[n]=r}return t}(),S=function(){var t=1,n=0;return{p:function(r){for(var e=t,i=n,s=0|r.length,a=0;a!=s;){for(var o=Math.min(a+2655,s);a>16),i=(65535&i)+15*(i>>16)}t=e,n=i},d:function(){return(255&(t%=65521))<<24|(65280&t)<<8|(255&(n%=65521))<<8|n>>8}}},L=function(s,a,o,h,u){if(!u&&(u={l:1},a.dictionary)){var c=a.dictionary.subarray(-32768),v=new t(c.length+s.length);v.set(c),v.set(s,c.length),s=v,u.w=c.length}return function(s,a,o,h,u,c){var v=c.z||s.length,d=new t(h+v+5*(1+Math.ceil(v/7e3))+u),p=d.subarray(h,d.length-u),g=c.l,w=7&(c.r||0);if(a){w&&(p[0]=c.r>>3);for(var y=C[a-1],M=y>>13,E=8191&y,z=(1<7e3||q>24576)&&(N>423||!g)){w=U(s,p,0,F,I,S,O,q,G,j-G,w),q=L=O=0,G=j;for(var P=0;P<286;++P)I[P]=0;for(P=0;P<30;++P)S[P]=0}var Q=2,R=0,V=E,W=J-K&32767;if(N>2&&H==T(j-W))for(var X=Math.min(M,N)-1,Y=Math.min(32767,j),Z=Math.min(258,N);W<=Y&&--V&&J!=K;){if(s[j+Q]==s[j+Q-W]){for(var $=0;$Q){if(Q=$,R=W,$>X)break;var tt=Math.min(W,$-2),nt=0;for(P=0;Pnt&&(nt=et,K=rt)}}}W+=(J=K)-(K=_[J])&32767}if(R){F[q++]=268435456|f[Q]<<18|l[R];var it=31&f[Q],st=31&l[R];O+=e[it]+i[st],++I[257+it],++S[st],B=j+Q,++L}else F[q++]=s[j],++I[s[j]]}}for(j=Math.max(j,B);j=v&&(p[w/8|0]=g,at=v),w=k(p,w+1,s.subarray(j,at))}c.i=v}return b(d,0,h+m(w)+u)}(s,null==a.level?6:a.level,null==a.mem?u.l?Math.ceil(1.5*Math.max(8,Math.min(13,Math.log(s.length)))):20:12+a.mem,o,h,u)},O=function(t,n,r){for(;r;++n)t[n]=r,r>>>=8},j=function(){function n(n,r){if("function"==typeof n&&(r=n,n={}),this.ondata=r,this.o=n||{},this.s={l:0,i:32768,w:32768,z:32768},this.b=new t(98304),this.o.dictionary){var e=this.o.dictionary.subarray(-32768);this.b.set(e,32768-e.length),this.s.i=32768-e.length}}return n.prototype.p=function(t,n){this.ondata(L(t,this.o,0,0,this.s),n)},n.prototype.push=function(n,r){this.ondata||E(5),this.s.l&&E(4);var e=n.length+this.s.z;if(e>this.b.length){if(e>2*this.b.length-32768){var i=new t(-32768&e);i.set(this.b.subarray(0,this.s.z)),this.b=i}var s=this.b.length-this.s.z;this.b.set(n.subarray(0,s),this.s.z),this.s.z=this.b.length,this.p(this.b,!1),this.b.set(this.b.subarray(-32768)),this.b.set(n.subarray(s),32768),this.s.z=n.length-s+32768,this.s.i=32766,this.s.w=32768}else this.b.set(n,this.s.z),this.s.z+=n.length;this.s.l=1&r,(this.s.z>this.s.w+8191||r)&&(this.p(this.b,r||!1),this.s.w=this.s.i,this.s.i-=2)},n.prototype.flush=function(){this.ondata||E(5),this.s.l&&E(4),this.p(this.b,!1),this.s.w=this.s.i,this.s.i-=2},n}();function q(t,n){n||(n={});var r=function(){var t=-1;return{p:function(n){for(var r=t,e=0;e>>8;t=r},d:function(){return~t}}}(),e=t.length;r.p(t);var i,s=L(t,n,10+((i=n).filename?i.filename.length+1:0),8),a=s.length;return function(t,n){var r=n.filename;if(t[0]=31,t[1]=139,t[2]=8,t[8]=n.level<2?4:9==n.level?2:0,t[9]=3,0!=n.mtime&&O(t,4,Math.floor(new Date(n.mtime||Date.now())/1e3)),r){t[3]=8;for(var e=0;e<=r.length;++e)t[e+10]=r.charCodeAt(e)}}(s,n),O(s,a-8,r.d()),O(s,a-4,e),s}var B=function(){function t(t,n){this.c=S(),this.v=1,j.call(this,t,n)}return t.prototype.push=function(t,n){this.c.p(t),j.prototype.push.call(this,t,n)},t.prototype.p=function(t,n){var r=L(t,this.o,this.v&&(this.o.dictionary?6:2),n&&4,this.s);this.v&&(function(t,n){var r=n.level,e=0==r?0:r<6?1:9==r?3:2;if(t[0]=120,t[1]=e<<6|(n.dictionary&&32),t[1]|=31-(t[0]<<8|t[1])%31,n.dictionary){var i=S();i.p(n.dictionary),O(t,2,i.d())}}(r,this.o),this.v=0),n&&O(r,r.length-4,this.c.d()),this.ondata(r,n)},t.prototype.flush=function(){j.prototype.flush.call(this)},t}(),G="undefined"!=typeof TextEncoder&&new TextEncoder,H="undefined"!=typeof TextDecoder&&new TextDecoder;try{H.decode(F,{stream:!0})}catch(t){}var J=function(){function t(t){this.ondata=t}return t.prototype.push=function(t,n){this.ondata||E(5),this.d&&E(4),this.ondata(K(t),this.d=n||!1)},t}();function K(n,r){if(G)return G.encode(n);for(var e=n.length,i=new t(n.length+(n.length>>1)),s=0,a=function(t){i[s++]=t},o=0;oi.length){var h=new t(s+8+(e-o<<1));h.set(i),i=h}var f=n.charCodeAt(o);f<128||r?a(f):f<2048?(a(192|f>>6),a(128|63&f)):f>55295&&f<57344?(a(240|(f=65536+(1047552&f)|1023&n.charCodeAt(++o))>>18),a(128|f>>12&63),a(128|f>>6&63),a(128|63&f)):(a(224|f>>12),a(128|f>>6&63),a(128|63&f))}return b(i,0,s)}const N=new class{constructor(){this._init()}clear(){this._init()}addEvent(t){if(!t)throw new Error("Adding invalid event");const n=this._hasEvents?",":"";this.stream.push(n+t),this._hasEvents=!0}finish(){this.stream.push("]",!0);const t=function(t){let n=0;for(const r of t)n+=r.length;const r=new Uint8Array(n);for(let n=0,e=0,i=t.length;n{this._deflatedData.push(t)},this.stream=new J((t,n)=>{this.deflate.push(t,n)}),this.stream.push("[")}},P={clear:()=>{N.clear()},addEvent:t=>N.addEvent(t),finish:()=>N.finish(),compress:t=>function(t){return q(K(t))}(t)};addEventListener("message",function(t){const n=t.data.method,r=t.data.id,e=t.data.arg;if(n in P&&"function"==typeof P[n])try{const t=P[n](e);postMessage({id:r,method:n,success:!0,response:t})}catch(t){postMessage({id:r,method:n,success:!1,response:t.message}),console.error(t)}}),postMessage({id:void 0,method:"init",success:!0,response:void 0});';function iv(){let e=new Blob([nv],{type:"text/javascript"});return URL.createObjectURL(e)}var zd=["log","warn","error"],ra="[Replay] ";function hc(e,t="info"){tt({category:"console",data:{logger:"replay"},level:t,message:`${ra}${e}`},{level:t})}function sv(){let e=!1,t=!1,r={exception:()=>{},infoTick:()=>{},setConfig:n=>{e=!!n.captureExceptions,t=!!n.traceInternals}};return N?(zd.forEach(n=>{r[n]=(...i)=>{f[n](ra,...i),t&&hc(i.join(""),pn(n))}}),r.exception=(n,...i)=>{i.length&&r.error&&r.error(...i),f.error(ra,n),e?Mr(n,{mechanism:{handled:!0,type:"auto.function.replay.debug"}}):t&&hc(n,"error")},r.infoTick=(...n)=>{f.log(ra,...n),t&&setTimeout(()=>hc(n[0]),0)}):zd.forEach(n=>{r[n]=()=>{}}),r}var w=sv(),Pi=class extends Error{constructor(){super(`Event buffer exceeded maximum size of ${Yc}.`)}},ua=class extends Error{constructor(){super("Worker destroyed")}},da=class{constructor(){this.events=[],this._totalSize=0,this.hasCheckout=!1,this.waitForCheckout=!1}get hasEvents(){return this.events.length>0}get type(){return"sync"}destroy(){this.events=[]}async addEvent(t){let r=JSON.stringify(t).length;if(this._totalSize+=r,this._totalSize>Yc)throw new Pi;this.events.push(t)}finish(){return new Promise(t=>{let r=this.events;this.clear(),t(JSON.stringify(r))})}clear(){this.events=[],this._totalSize=0,this.hasCheckout=!1}getEarliestTimestamp(){let t=null;for(let{timestamp:r}of this.events)(t===null||r{let n=r;if(typeof n.id!="number")return;let i=this._pending.get(n.id);if(!(!i||i.method!==n.method)){if(this._pending.delete(n.id),!n.success){N&&w.error("Error in compression worker: ",n.response),i.reject(new Error("Error in compression worker"));return}i.resolve(n.response)}},this._worker=t,this._id=0,this._pending=new Map,this._worker.addEventListener("message",this._onMessage)}ensureReady(){return this._ensureReadyPromise?this._ensureReadyPromise:(this._ensureReadyPromise=new Promise((t,r)=>{this._worker.addEventListener("message",({data:n})=>{n.success?t():(N&&w.warn("Received worker message with unsuccessful status",n),r(new Error("Received worker message with unsuccessful status")))},{once:!0}),this._worker.addEventListener("error",n=>{N&&w.warn("Failed to load Replay compression worker",n),r(new Error(`Failed to load Replay compression worker: ${n instanceof ErrorEvent&&n.message?n.message:"Unknown error. This can happen due to CSP policy restrictions, network issues, or the worker script failing to load."}`))},{once:!0})}),this._ensureReadyPromise)}destroy(){N&&w.log("Destroying compression worker"),this._worker.removeEventListener("message",this._onMessage),this._pending.forEach(t=>t.reject(new ua)),this._pending.clear(),this._worker.terminate()}postMessage(t,r){let n=this._getAndIncrementId();return new Promise((i,s)=>{this._pending.set(n,{method:t,resolve:i,reject:s});try{this._worker.postMessage({id:n,method:t,arg:r})}catch(a){this._pending.delete(n),s(a)}})}_getAndIncrementId(){return this._id++}},Pc=class{constructor(t){this._worker=new Lc(t),this._earliestTimestamp=null,this._totalSize=0,this.hasCheckout=!1,this.waitForCheckout=!1}get hasEvents(){return!!this._earliestTimestamp}get type(){return"worker"}ensureReady(){return this._worker.ensureReady()}destroy(){this._worker.destroy()}addEvent(t){let r=Xc(t.timestamp);(!this._earliestTimestamp||rYc?Promise.reject(new Pi):this._sendEventToWorker(n)}finish(){return this._finishRequest()}clear(){this._earliestTimestamp=null,this._totalSize=0,this.hasCheckout=!1,this._worker.postMessage("clear").then(null,t=>{N&&w.exception(t,'Sending "clear" message to worker failed',t)})}getEarliestTimestamp(){return this._earliestTimestamp}_sendEventToWorker(t){return this._worker.postMessage("addEvent",t)}async _finishRequest(){let t=await this._worker.postMessage("finish");return this._earliestTimestamp=null,this._totalSize=0,t}},Dc=class{constructor(t){this._fallback=new da,this._compression=new Pc(t),this._used=this._fallback,this._ensureWorkerIsLoadedPromise=this._ensureWorkerIsLoaded()}get waitForCheckout(){return this._used.waitForCheckout}get type(){return this._used.type}get hasEvents(){return this._used.hasEvents}get hasCheckout(){return this._used.hasCheckout}set hasCheckout(t){this._used.hasCheckout=t}set waitForCheckout(t){this._used.waitForCheckout=t}destroy(){this._fallback.destroy(),this._compression.destroy()}clear(){return this._used.clear()}getEarliestTimestamp(){return this._used.getEarliestTimestamp()}addEvent(t){return this._used.addEvent(t)}async finish(){return await this.ensureWorkerIsLoaded(),this._used.finish()}ensureWorkerIsLoaded(){return this._ensureWorkerIsLoadedPromise}async _ensureWorkerIsLoaded(){try{await this._compression.ensureReady()}catch(t){N&&w.exception(t,"Failed to load the compression worker, falling back to simple buffer");return}await this._switchToCompressionWorker()}async _switchToCompressionWorker(){let{events:t,hasCheckout:r,waitForCheckout:n}=this._fallback,i=[];for(let s of t)i.push(this._compression.addEvent(s));this._compression.hasCheckout=r,this._compression.waitForCheckout=n,this._used=this._compression;try{await Promise.all(i),this._fallback.clear()}catch(s){if(s instanceof ua)return;N&&w.exception(s,"Failed to add events when switching buffers.")}}};function av({useCompression:e,workerUrl:t}){if(e&&window.Worker){let r=ov(t);if(r)return r}return N&&w.log("Using simple buffer"),new da}function ov(e){try{let t=e||cv();if(!t)return;N&&w.log(`Using compression worker${e?` from ${e}`:""}`);let r=new Worker(t);return new Dc(r)}catch(t){N&&w.exception(t,"Failed to create compression worker")}}function cv(){return typeof __SENTRY_EXCLUDE_REPLAY_WORKER__>"u"||!__SENTRY_EXCLUDE_REPLAY_WORKER__?iv():""}function Qc(){try{return"sessionStorage"in pe&&!!pe.sessionStorage}catch{return!1}}function lv(e){pv(),e.session=void 0}function pv(){if(Qc())try{pe.sessionStorage.removeItem(Gc)}catch{}}function Rm(e){return e===void 0?!1:Math.random()e.getContext().initialTimestamp+e.getOptions().maxReplayDuration?(N&&w.infoTick(`Skipping event with timestamp ${r} because it is after maxReplayDuration`),!1):!0}function hv(e,t){try{if(typeof t=="function"&&gv(e))return t(e)}catch(r){return N&&w.exception(r,"An error occurred in the `beforeAddRecordingEvent` callback, skipping the event..."),null}return e}var jd=100;function Nm(e,t,r){let n=e.getContext();t&&n.traceIds.size{e.isEnabled()&&Nm(e,t.trace_id,t.name||void 0)}}function el(e){return!e.type}function Fc(e){return e.type==="transaction"}function _v(e){return e.type==="replay_event"}function $d(e){return e.type==="feedback"}function yv(e){return(t,r)=>{if(!e.isEnabled()||!el(t)&&!Fc(t))return;let n=r.statusCode;if(!(!n||n<200||n>=300)){if(Fc(t)){Sv(e,t);return}vv(e,t)}}}function Sv(e,t){Nm(e,t.contexts?.trace?.trace_id,t.transaction)}function vv(e,t){let r=e.getContext();if(t.event_id&&r.errorIds.size<100&&r.errorIds.add(t.event_id),e.recordingMode!=="buffer"||!t.tags?.replayId)return;let{beforeErrorSampling:n}=e.getOptions();typeof n=="function"&&!n(t)||Yr(async()=>{try{await e.sendBufferedReplayOrFlush()}catch(i){e.handleException(i)}})}function Ev(e){return t=>{!e.isEnabled()||!el(t)||Tv(e,t)}}function Tv(e,t){let r=t.exception?.values?.[0]?.value;if(typeof r=="string"&&(r.match(/(reactjs\.org\/docs\/error-decoder\.html\?invariant=|react\.dev\/errors\/)(418|419|422|423|425)/)||r.match(/(does not match server-rendered HTML|Hydration failed because)/i))){let n=Lt({category:"replay.hydrate-error",data:{url:Ge()}});Bi(e,n)}}function Iv(e){let t=E();t&&t.on("beforeAddBreadcrumb",r=>Av(e,r))}function Av(e,t){if(!e.isEnabled()||!wm(t))return;let r=Rv(t);r&&Bi(e,r)}function Rv(e){return!wm(e)||["fetch","xhr","sentry.event","sentry.transaction"].includes(e.category)||e.category.startsWith("ui.")?null:e.category==="console"?Ov(e):Lt(e)}function Ov(e){let t=e.data?.arguments;if(!Array.isArray(t)||t.length===0)return Lt(e);let r=!1,n=t.map(i=>{if(!i)return i;if(typeof i=="string")return i.length>Qs?(r=!0,`${i.slice(0,Qs)}\u2026`):i;if(typeof i=="object")try{let s=Me(i,7);return JSON.stringify(s).length>Qs?(r=!0,`${JSON.stringify(s,null,2).slice(0,Qs)}\u2026`):s}catch{}return i});return Lt({...e,data:{...e.data,arguments:n,...r?{_meta:{warnings:["CONSOLE_ARG_TRUNCATED"]}}:{}}})}function wm(e){return!!e.category}function xv(e,t){return e.type||!e.exception?.values?.length?!1:!!t.originalException?.__rrweb__}function ga(){let e=R().getPropagationContext().dsc;e&&delete e.replay_id;let t=te();if(t){let r=ke(t);delete r.replay_id}}function Kd(e){let t=R().getPropagationContext().dsc;t&&(t.replay_id=e);let r=te();if(r){let n=ke(r);n.replay_id=e}}function kv(e,t){e.triggerUserActivity(),e.addUpdate(()=>t.timestamp?(e.throttledAddEvent({type:G.Custom,timestamp:t.timestamp*1e3,data:{tag:"breadcrumb",payload:{timestamp:t.timestamp,type:"default",category:"sentry.feedback",data:{feedbackId:t.event_id}}}}),!1):!0)}function Nv(e,t){return e.recordingMode!=="buffer"||t.message===Wc||!t.exception||t.type?!1:Rm(e.getOptions().errorSampleRate)}function wv(e){return Object.assign((t,r)=>{if(e.session&&ma(e.session,{maxReplayDuration:e.getOptions().maxReplayDuration,sessionIdleExpire:e.timeouts.sessionIdleExpire})&&ga(),!e.isEnabled()||e.isPaused())return t;if(_v(t))return delete t.breadcrumbs,t;if(!el(t)&&!Fc(t)&&!$d(t))return t;if(!e.checkAndHandleExpiredSession())return ga(),t;if($d(t))return e.flush(),t.contexts.feedback.replay_id=e.getSessionId(),kv(e,t),t;if(xv(t,r)&&!e.getOptions()._experiments.captureExceptions)return N&&w.log("Ignoring error from rrweb internals",t),null;let i=Nv(e,t);if((i||e.recordingMode==="session")&&(t.tags={...t.tags,replayId:e.getSessionId()}),i&&e.recordingMode==="buffer"&&e.session?.sampled==="buffer"){let a=e.session;a.dirty=!0,e.getOptions().stickySession&&Ta(a)}return t},{id:"Replay"})}function Ia(e,t){return t.map(({type:r,start:n,end:i,name:s,data:a})=>{let c=e.throttledAddEvent({type:G.Custom,timestamp:n,data:{tag:"performanceSpan",payload:{op:r,description:s,startTimestamp:n,endTimestamp:i,data:a}}});return typeof c=="string"?Promise.resolve(null):c})}function Cv(e){let{from:t,to:r}=e,n=Date.now()/1e3;return{type:"navigation.push",start:n,end:n,name:r,data:{previous:t}}}function Mv(e){return t=>{if(!e.isEnabled())return;let r=Cv(t);r!==null&&(e.getContext().urls.push(r.name),e.triggerUserActivity(),e.addUpdate(()=>(Ia(e,[r]),!1)))}}function Lv(e,t){return N&&e.getOptions()._experiments.traceInternals?!1:Ro(t,E())}function Cm(e,t){e.isEnabled()&&t!==null&&(Lv(e,t.name)||e.addUpdate(()=>(Ia(e,[t]),!0)))}function Aa(e){if(!e)return;let t=new TextEncoder;try{if(typeof e=="string")return t.encode(e).length;if(e instanceof URLSearchParams)return t.encode(e.toString()).length;if(e instanceof FormData){let r=$s(e);return t.encode(r).length}if(e instanceof Blob)return e.size;if(e instanceof ArrayBuffer)return e.byteLength}catch{}}function Mm(e){if(!e)return;let t=parseInt(e,10);return isNaN(t)?void 0:t}function fa(e,t){if(!e)return{headers:{},size:void 0,_meta:{warnings:[t]}};let r={...e._meta},n=r.warnings||[];return r.warnings=[...n,t],e._meta=r,e}function Lm(e,t){if(!t)return null;let{startTimestamp:r,endTimestamp:n,url:i,method:s,statusCode:a,request:c,response:o}=t;return{type:e,start:r/1e3,end:n/1e3,name:i,data:{method:s,statusCode:a,request:c,response:o}}}function Di(e){return{headers:{},size:e,_meta:{warnings:["URL_SKIPPED"]}}}function fr(e,t,r){if(!t&&Object.keys(e).length===0)return;if(!t)return{headers:e};if(!r)return{headers:e,size:t};let n={headers:e,size:t},{body:i,warnings:s}=Pv(r);return n.body=i,s?.length&&(n._meta={warnings:s}),n}function Bc(e,t){return Object.entries(e).reduce((r,[n,i])=>{let s=n.toLowerCase();return t.includes(s)&&e[n]&&(r[s]=i),r},{})}function Pv(e){if(!e||typeof e!="string")return{body:e};let t=e.length>xd,r=Dv(e);if(t){let n=e.slice(0,xd);return r?{body:n,warnings:["MAYBE_JSON_TRUNCATED"]}:{body:`${n}\u2026`,warnings:["TEXT_TRUNCATED"]}}if(r)try{return{body:JSON.parse(e)}}catch{}return{body:e}}function Dv(e){let t=e[0],r=e[e.length-1];return t==="["&&r==="]"||t==="{"&&r==="}"}function ha(e,t){let r=Uv(e);return xe(r,t)}function Uv(e,t=pe.document.baseURI){if(e.startsWith("http://")||e.startsWith("https://")||e.startsWith(pe.location.origin))return e;let r=new URL(e,t);if(r.origin!==new URL(t).origin)return e;let n=r.href;return!e.endsWith("/")&&n.endsWith("/")?n.slice(0,-1):n}async function Fv(e,t,r){try{let n=await qv(e,t,r),i=Lm("resource.fetch",n);Cm(r.replay,i)}catch(n){N&&w.exception(n,"Failed to capture fetch breadcrumb")}}function Bv(e,t){let{input:r,response:n}=t,i=r?Xs(r):void 0,s=Aa(i),a=n?Mm(n.headers.get("content-length")):void 0;s!==void 0&&(e.data.request_body_size=s),a!==void 0&&(e.data.response_body_size=a)}async function qv(e,t,r){let n=Date.now(),{startTimestamp:i=n,endTimestamp:s=n}=t,{url:a,method:c,status_code:o=0,request_body_size:l,response_body_size:u}=e.data,p=ha(a,r.networkDetailAllowUrls)&&!ha(a,r.networkDetailDenyUrls),d=p?Hv(r,t.input,l):Di(l),m=await Gv(p,r,t.response,u);return{startTimestamp:i,endTimestamp:s,url:a,method:c,statusCode:o,request:d,response:m}}function Hv({networkCaptureBodies:e,networkRequestHeaders:t},r,n){let i=r?zv(r,t):{};if(!e)return fr(i,n,void 0);let s=Xs(r),[a,c]=Ks(s,w),o=fr(i,n,a);return c?fa(o,c):o}async function Gv(e,{networkCaptureBodies:t,networkResponseHeaders:r},n,i){if(!e&&i!==void 0)return Di(i);let s=n?Pm(n.headers,r):{};if(!n||!t&&i!==void 0)return fr(s,i,void 0);let[a,c]=await Yv(n),o=Wv(a,{networkCaptureBodies:t,responseBodySize:i,captureDetails:e,headers:s});return c?fa(o,c):o}function Wv(e,{networkCaptureBodies:t,responseBodySize:r,captureDetails:n,headers:i}){try{let s=e?.length&&r===void 0?Aa(e):r;return n?t?fr(i,s,e):fr(i,s,void 0):Di(s)}catch(s){return N&&w.exception(s,"Failed to serialize response body"),fr(i,r,void 0)}}async function Yv(e){let t=Vv(e);if(!t)return[void 0,"BODY_PARSE_ERROR"];try{return[await jv(t)]}catch(r){return r instanceof Error&&r.message.indexOf("Timeout")>-1?(N&&w.warn("Parsing text body from response timed out"),[void 0,"BODY_PARSE_TIMEOUT"]):(N&&w.exception(r,"Failed to get text body from response"),[void 0,"BODY_PARSE_ERROR"])}}function Pm(e,t){let r={};return t.forEach(n=>{e.get(n)&&(r[n]=e.get(n))}),r}function zv(e,t){return e.length===1&&typeof e[0]!="string"?Xd(e[0],t):e.length===2?Xd(e[1],t):{}}function Xd(e,t){if(!e)return{};let r=e.headers;return r?r instanceof Headers?Pm(r,t):Array.isArray(r)?{}:Bc(r,t):{}}function Vv(e){try{return e.clone()}catch(t){N&&w.exception(t,"Failed to clone response body")}}function jv(e){return new Promise((t,r)=>{let n=Yr(()=>r(new Error("Timeout while trying to read response body")),500);$v(e).then(i=>t(i),i=>r(i)).finally(()=>clearTimeout(n))})}async function $v(e){return await e.text()}async function Kv(e,t,r){try{let n=Jv(e,t,r),i=Lm("resource.xhr",n);Cm(r.replay,i)}catch(n){N&&w.exception(n,"Failed to capture xhr breadcrumb")}}function Xv(e,t){let{xhr:r,input:n}=t;if(!r)return;let i=Aa(n),s=r.getResponseHeader("content-length")?Mm(r.getResponseHeader("content-length")):eE(r.response,r.responseType);i!==void 0&&(e.data.request_body_size=i),s!==void 0&&(e.data.response_body_size=s)}function Jv(e,t,r){let n=Date.now(),{startTimestamp:i=n,endTimestamp:s=n,input:a,xhr:c}=t,{url:o,method:l,status_code:u=0,request_body_size:p,response_body_size:d}=e.data;if(!o)return null;if(!c||!ha(o,r.networkDetailAllowUrls)||ha(o,r.networkDetailDenyUrls)){let D=Di(p),v=Di(d);return{startTimestamp:i,endTimestamp:s,url:o,method:l,statusCode:u,request:D,response:v}}let m=c[Et],g=m?Bc(m.request_headers,r.networkRequestHeaders):{},h=Bc(Ii(c),r.networkResponseHeaders),[S,b]=r.networkCaptureBodies?Ks(a,w):[void 0],[C,q]=r.networkCaptureBodies?Qv(c):[void 0],U=fr(g,p,S),Y=fr(h,d,C);return{startTimestamp:i,endTimestamp:s,url:o,method:l,statusCode:u,request:b?fa(U,b):U,response:q?fa(Y,q):Y}}function Qv(e){let t=[];try{return[e.responseText]}catch(r){t.push(r)}try{return Zv(e.response,e.responseType)}catch(r){t.push(r)}return N&&w.warn("Failed to get xhr response body",...t),[void 0]}function Zv(e,t){try{if(typeof e=="string")return[e];if(e instanceof Document)return[e.body.outerHTML];if(t==="json"&&Ze(e))return[JSON.stringify(e)];if(!e)return[void 0]}catch(r){return N&&w.exception(r,"Failed to serialize body",e),[void 0,"BODY_PARSE_ERROR"]}return N&&w.log("Skipping network body because of body type",e),[void 0,"UNPARSEABLE_BODY_TYPE"]}function eE(e,t){try{let r=t==="json"&&Ze(e)?JSON.stringify(e):e;return Aa(r)}catch{return}}function tE(e){let t=E();try{let{networkDetailAllowUrls:r,networkDetailDenyUrls:n,networkCaptureBodies:i,networkRequestHeaders:s,networkResponseHeaders:a}=e.getOptions(),c={replay:e,networkDetailAllowUrls:r,networkDetailDenyUrls:n,networkCaptureBodies:i,networkRequestHeaders:s,networkResponseHeaders:a};t&&t.on("beforeAddBreadcrumb",(o,l)=>rE(c,o,l))}catch{}}function rE(e,t,r){if(t.data)try{nE(t)&&sE(r)&&(Xv(t,r),Kv(t,r,e)),iE(t)&&aE(r)&&(Bv(t,r),Fv(t,r,e))}catch(n){N&&w.exception(n,"Error when enriching network breadcrumb")}}function nE(e){return e.category==="xhr"}function iE(e){return e.category==="fetch"}function sE(e){return e?.xhr}function aE(e){return e?.input!==void 0}function oE(e){let t=E();Ei(BS(e)),Qt(Mv(e)),Iv(e),tE(e);let r=wv(e);pi(r),t&&(t.on("beforeSendEvent",Ev(e)),t.on("afterSendEvent",yv(e)),t.on("createDsc",n=>{let i=e.getSessionId();i&&e.isEnabled()&&e.recordingMode==="session"&&e.checkAndHandleExpiredSession()&&(n.replay_id=i)}),t.on("processSegmentSpan",bv(e)),t.on("spanStart",n=>{e.lastActiveSpan=n}),t.on("spanEnd",n=>{e.lastActiveSpan=n}),t.on("beforeSendFeedback",async(n,i)=>{let s=e.getSessionId();i?.includeReplay&&e.isEnabled()&&s&&n.contexts?.feedback&&(n.contexts.feedback.source==="api"&&await e.sendBufferedReplayOrFlush(),n.contexts.feedback.replay_id=s)}),t.on("openFeedbackWidget",async()=>{await e.sendBufferedReplayOrFlush()}))}async function cE(e){try{return Promise.all(Ia(e,[lE(pe.performance.memory)]))}catch{return[]}}function lE(e){let{jsHeapSizeLimit:t,totalJSHeapSize:r,usedJSHeapSize:n}=e,i=Date.now()/1e3;return{type:"memory",name:"memory",start:i,end:i,data:{memory:{jsHeapSizeLimit:t,totalJSHeapSize:r,usedJSHeapSize:n}}}}function pE(e,t,r){return go(e,t,{...r,setTimeoutImpl:Yr})}var ta=T.navigator;function uE(){return/iPhone|iPad|iPod/i.test(ta?.userAgent??"")||/Macintosh/i.test(ta?.userAgent??"")&&ta?.maxTouchPoints&&ta?.maxTouchPoints>1?{sampling:{mousemove:!1}}:{}}function dE(e){let t=!1;return(r,n)=>{try{if(!e.checkAndHandleExpiredSession()){N&&w.warn("Received replay event after session expired.");return}let i=n||!t;t=!0,mE(r),e.clickDetector&&LS(e.clickDetector,r),e.addUpdate(()=>{if(e.recordingMode==="buffer"&&i&&e.setInitialState(),!Zc(e,r,i))return!0;if(!i)return!1;let s=e.session;if(fE(e,i),e.recordingMode==="buffer"&&s&&e.eventBuffer&&!s.dirty){let a=e.eventBuffer.getEarliestTimestamp();a&&(N&&w.log(`Updating session start time to earliest event in buffer to ${new Date(a)}`),s.started=a,e.getOptions().stickySession&&Ta(s))}return s?.previousSessionId||e.recordingMode==="session"&&e.flush(),!0})}catch(i){e.handleException(i)}}}function mE(e){let t=e.data;if(!(e.type!==G.IncrementalSnapshot||!t||typeof t!="object"||!("source"in t)||t.source!==P.Mutation||!("attributes"in t)||!Array.isArray(t.attributes)))for(let r of t.attributes){let n=It.mirror.getNode(r.id),i=n&&It.mirror.getMeta(n);if(i?.type===Ea.Element)for(let[s,a]of Object.entries(r.attributes))a===null?delete i.attributes[s]:i.attributes[s]=a}}function gE(e){let t=e.getOptions();return{type:G.Custom,timestamp:Date.now(),data:{tag:"options",payload:{shouldRecordCanvas:e.isRecordingCanvas(),sessionSampleRate:t.sessionSampleRate,errorSampleRate:t.errorSampleRate,useCompressionOption:t.useCompression,blockAllMedia:t.blockAllMedia,maskAllText:t.maskAllText,maskAllInputs:t.maskAllInputs,useCompression:e.eventBuffer?e.eventBuffer.type==="worker":!1,networkDetailHasUrls:t.networkDetailAllowUrls.length>0,networkCaptureBodies:t.networkCaptureBodies,networkRequestHasHeaders:t.networkRequestHeaders.length>0,networkResponseHasHeaders:t.networkResponseHeaders.length>0}}}}function fE(e,t){!t||e.session?.segmentId!==0||Zc(e,gE(e),!1)}function hE(e){if(!e)return null;try{return e.nodeType===e.ELEMENT_NODE?e:e.parentElement}catch{return null}}function bE(e,t,r,n){return He(ti(e,en(e),n,r),[[{type:"replay_event"},e],[{type:"replay_recording",length:typeof t=="string"?new TextEncoder().encode(t).length:t.length},t]])}function _E({recordingData:e,headers:t}){let r,n=`${JSON.stringify(t)} +`;if(typeof e=="string")r=`${n}${e}`;else{let s=new TextEncoder().encode(n);r=new Uint8Array(s.length+e.length),r.set(s),r.set(e,s.length)}return r}async function yE({client:e,scope:t,replayId:r,event:n}){let i=typeof e._integrations=="object"&&e._integrations!==null&&!Array.isArray(e._integrations)?Object.keys(e._integrations):void 0,s={event_id:r,integrations:i};e.emit("preprocessEvent",n,s);let a=await oi(e.getOptions(),n,s,t,e,me());if(!a)return null;e.emit("postprocessEvent",a,s),a.platform=a.platform||"javascript";let c=e.getSdkMetadata(),{name:o,version:l,settings:u}=c?.sdk||{};return a.sdk={...a.sdk,name:o||"sentry.javascript.unknown",version:l||"0.0.0",settings:u},a}async function SE({recordingData:e,replayId:t,segmentId:r,eventContext:n,timestamp:i,session:s}){let a=_E({recordingData:e,headers:{segment_id:r}}),{urls:c,errorIds:o,traceIds:l,segmentNames:u,initialTimestamp:p}=n,d=E(),m=R(),g=d?.getTransport(),h=d?.getDsn();if(!d||!g||!h||!s.sampled)return Promise.resolve({});let S={type:ay,replay_start_timestamp:p/1e3,timestamp:i/1e3,error_ids:o,trace_ids:l,segment_names:u,urls:c,replay_id:t,segment_id:r,replay_type:s.sampled},b=await yE({scope:m,client:d,replayId:t,event:S});if(!b)return d.recordDroppedEvent("event_processor","replay"),N&&w.log("An event processor returned `null`, will not send event."),Promise.resolve({});delete b.sdkProcessingMetadata;let C=bE(b,a,h,d.getOptions().tunnel),q;try{q=await g.send(C)}catch(Y){let D=new Error(Wc);try{D.cause=Y}catch{}throw D}let U=mi({},q);if(di(U,"replay"))throw new Ui(U);if(typeof q.statusCode=="number"&&(q.statusCode<200||q.statusCode>=300))throw new ba(q.statusCode);return q}var ba=class extends Error{constructor(t){super(`Transport returned status code ${t}`)}},Ui=class extends Error{constructor(t){super("Rate limit hit"),this.rateLimits=t}},_a=class extends Error{constructor(){super("Session is too long, not sending replay")}};async function Dm(e,t={count:0,interval:dy}){let{recordingData:r,onError:n}=e;if(r.length)try{return await SE(e),!0}catch(i){if(i instanceof ba||i instanceof Ui)throw i;if(ci("Replays",{_retryCount:t.count}),n&&n(i),t.count>=my){let s=new Error(`${Wc} - max retries exceeded`);try{s.cause=i}catch{}throw s}return t.interval*=++t.count,new Promise((s,a)=>{Yr(async()=>{try{await Dm(e,t),s(!0)}catch(c){a(c)}},t.interval)})}}var Um="__THROTTLED",vE="__SKIPPED";function EE(e,t,r){let n=new Map,i=c=>{let o=c-r;n.forEach((l,u)=>{u[...n.values()].reduce((c,o)=>c+o,0),a=!1;return(...c)=>{let o=Math.floor(Date.now()/1e3);if(i(o),s()>=t){let u=a;return a=!0,u?vE:Um}a=!1;let l=n.get(o)||0;return n.set(o,l+1),e(...c)}}var qc=class{constructor({options:t,recordingOptions:r}){this.eventBuffer=null,this.performanceEntries=[],this.replayPerformanceEntries=[],this.recordingMode="session",this.timeouts={sessionIdlePause:oy,sessionIdleExpire:cy},this._lastActivity=Date.now(),this._isEnabled=!1,this._isPaused=!1,this._requiresManualStart=!1,this._hasInitializedCoreListeners=!1,this._context={errorIds:new Set,traceIds:new Set,segmentNames:new Set,urls:[],initialTimestamp:Date.now(),initialUrl:""},this._recordingOptions=r,this._options=t,this._debouncedFlush=pE(()=>this._flush(),this._options.flushMinDelay,{maxWait:this._options.flushMaxDelay}),this._throttledAddEvent=EE((a,c)=>fv(this,a,c),300,5);let{slowClickTimeout:n,slowClickIgnoreSelectors:i}=this.getOptions(),s=n?{threshold:Math.min(gy,n),timeout:n,scrollTimeout:fy,ignoreSelector:i?i.join(","):""}:void 0;if(s&&(this.clickDetector=new Mc(this,s)),N){let a=t._experiments;w.setConfig({captureExceptions:!!a.captureExceptions,traceInternals:!!a.traceInternals})}this._handleVisibilityChange=()=>{pe.document.visibilityState==="visible"?this._doChangeToForegroundTasks():this._doChangeToBackgroundTasks()},this._handleWindowBlur=()=>{let a=Lt({category:"ui.blur"});this._doChangeToBackgroundTasks(a)},this._handleWindowFocus=()=>{let a=Lt({category:"ui.focus"});this._doChangeToForegroundTasks(a)},this._handleKeyboardEvent=a=>{WS(this,a)}}getContext(){return this._context}isEnabled(){return this._isEnabled}isPaused(){return this._isPaused}isRecordingCanvas(){return!!this._canvas}getOptions(){return this._options}handleException(t){N&&w.exception(t),this._options.onError&&this._options.onError(t)}initializeSampling(t){let{errorSampleRate:r,sessionSampleRate:n}=this._options,i=r<=0&&n<=0;if(this._requiresManualStart=i,!i){if(this._initializeSessionForSampling(t),!this.session){N&&w.exception(new Error("Unable to initialize and create session"));return}this.session.sampled!==!1&&(this.recordingMode=this.session.sampled==="buffer"&&this.session.segmentId===0?"buffer":"session",N&&w.infoTick(`Starting replay in ${this.recordingMode} mode`),this._initializeRecording())}}start(){if(this._isEnabled&&this.recordingMode==="session"){N&&w.log("Recording is already in progress");return}if(this._isEnabled&&this.recordingMode==="buffer"){N&&w.log("Buffering is in progress, call `flush()` to save the replay");return}N&&w.infoTick("Starting replay in session mode"),this._updateUserActivity();let t=bc({maxReplayDuration:this._options.maxReplayDuration,sessionIdleExpire:this.timeouts.sessionIdleExpire},{stickySession:this._options.stickySession,sessionSampleRate:1,allowBuffering:!1});this.session=t,this.recordingMode="session",this._initializeRecording()}startBuffering(){if(this._isEnabled){N&&w.log("Buffering is in progress, call `flush()` to save the replay");return}N&&w.infoTick("Starting replay in buffer mode");let t=bc({sessionIdleExpire:this.timeouts.sessionIdleExpire,maxReplayDuration:this._options.maxReplayDuration},{stickySession:this._options.stickySession,sessionSampleRate:0,allowBuffering:!0});this.session=t,this.recordingMode="buffer",this._initializeRecording()}startRecording(){try{let t=this._canvas;this._stopRecording=It({...this._recordingOptions,...this.recordingMode==="buffer"?{checkoutEveryNms:uy}:this._options._experiments.continuousCheckout&&{checkoutEveryNms:Math.max(36e4,this._options._experiments.continuousCheckout)},emit:dE(this),...uE(),onMutation:this._onMutationHandler.bind(this),...t?{recordCanvas:t.recordCanvas,getCanvasManager:t.getCanvasManager,sampling:t.sampling,dataURLOptions:t.dataURLOptions}:{}})}catch(t){this.handleException(t)}}stopRecording(){try{return this._stopRecording&&(this._stopRecording(),this._stopRecording=void 0),!0}catch(t){return this.handleException(t),!1}}async stop({forceFlush:t=!1,reason:r}={}){if(!this._isEnabled)return;this._isEnabled=!1,this.recordingMode="buffer";let n=r??"manual";E()?.emit("replayEnd",{sessionId:this.session?.id,reason:n});try{N&&w.log(`Stopping Replay triggered by ${n}`),ga(),this._removeListeners(),this.stopRecording(),this._debouncedFlush.cancel(),t&&await this._flush({force:!0}),this.eventBuffer?.destroy(),this.eventBuffer=null,lv(this)}catch(i){this.handleException(i)}}pause(){this._isPaused||(this._isPaused=!0,this.stopRecording(),N&&w.log("Pausing replay"))}resume(){!this._isPaused||!this._checkSession()||(this._isPaused=!1,this.startRecording(),N&&w.log("Resuming replay"))}async sendBufferedReplayOrFlush({continueRecording:t=!0}={}){if(this.recordingMode==="session")return this.flushImmediate();let r=Date.now();N&&w.log("Converting buffer to session"),await this.flushImmediate();let n=this.stopRecording();!t||!n||this.recordingMode!=="session"&&(this.recordingMode="session",this.session&&(this.session.dirty=!1,this._updateUserActivity(r),this._updateSessionActivity(r),this._maybeSaveSession(),Kd(this.session.id)),this.startRecording())}addUpdate(t){let r=t();this.recordingMode==="buffer"||!this._isEnabled||r!==!0&&this._debouncedFlush()}triggerUserActivity(){if(this._updateUserActivity(),!this._stopRecording){if(!this._checkSession())return;this.resume();return}this.checkAndHandleExpiredSession(),this._updateSessionActivity()}updateUserActivity(){this._updateUserActivity(),this._updateSessionActivity()}conditionalFlush(){return this.recordingMode==="buffer"?Promise.resolve():this.flushImmediate()}flush(){return this._debouncedFlush()}flushImmediate(){return this._debouncedFlush(),this._debouncedFlush.flush()}cancelFlush(){this._debouncedFlush.cancel()}getSessionId(t){if(!(t&&this.session?.sampled===!1))return this.session?.id}checkAndHandleExpiredSession(){if(this._lastActivity&&Uc(this._lastActivity,this.timeouts.sessionIdlePause)&&this.session?.sampled==="session"){this.pause();return}return!!this._checkSession()}setInitialState(){let t=`${pe.location.pathname}${pe.location.hash}${pe.location.search}`,r=`${pe.location.origin}${t}`;this.performanceEntries=[],this.replayPerformanceEntries=[],this._clearContext(),this._context.initialUrl=r,this._context.initialTimestamp=Date.now(),this._context.urls.push(r)}throttledAddEvent(t,r){let n=this._throttledAddEvent(t,r);if(n===Um){let i=Lt({category:"replay.throttled"});this.addUpdate(()=>!Zc(this,{type:IS,timestamp:i.timestamp||0,data:{tag:"breadcrumb",payload:i,metric:!0}}))}return n}getCurrentRoute(){let t=this.lastActiveSpan||te(),r=t&&X(t),i=(r&&O(r).data||{})[Se];if(!(!r||!i||!["route","custom"].includes(i)))return O(r).description}_initializeRecording(){this.setInitialState(),this._updateSessionActivity(),this.eventBuffer=av({useCompression:this._options.useCompression,workerUrl:this._options.workerUrl}),this._removeListeners(),this._addListeners(),this._isEnabled=!0,this._isPaused=!1,this.session&&E()?.emit("replayStart",{sessionId:this.session.id,recordingMode:this.recordingMode}),this.startRecording(),this.recordingMode==="session"&&this.session&&Kd(this.session.id)}_initializeSessionForSampling(t){let r=this._options.errorSampleRate>0,n=bc({sessionIdleExpire:this.timeouts.sessionIdleExpire,maxReplayDuration:this._options.maxReplayDuration,previousSessionId:t},{stickySession:this._options.stickySession,sessionSampleRate:this._options.sessionSampleRate,allowBuffering:r});this.session=n}_checkSession(){if(!this.session)return!1;let t=this.session;return ma(t,{sessionIdleExpire:this.timeouts.sessionIdleExpire,maxReplayDuration:this._options.maxReplayDuration})?(this._refreshSession(t),!1):!0}async _refreshSession(t){this._isEnabled&&(await this.stop({reason:"sessionExpired"}),this.initializeSampling(t.id))}_addListeners(){try{pe.document.addEventListener("visibilitychange",this._handleVisibilityChange),pe.addEventListener("blur",this._handleWindowBlur),pe.addEventListener("focus",this._handleWindowFocus),pe.addEventListener("keydown",this._handleKeyboardEvent),this.clickDetector&&this.clickDetector.addListeners(),this._hasInitializedCoreListeners||(oE(this),this._hasInitializedCoreListeners=!0)}catch(t){this.handleException(t)}this._performanceCleanupCallback=rv(this)}_removeListeners(){try{pe.document.removeEventListener("visibilitychange",this._handleVisibilityChange),pe.removeEventListener("blur",this._handleWindowBlur),pe.removeEventListener("focus",this._handleWindowFocus),pe.removeEventListener("keydown",this._handleKeyboardEvent),this.clickDetector&&this.clickDetector.removeListeners(),this._performanceCleanupCallback&&this._performanceCleanupCallback()}catch(t){this.handleException(t)}}_doChangeToBackgroundTasks(t){if(!this.session)return;if(ma(this.session,{maxReplayDuration:this._options.maxReplayDuration,sessionIdleExpire:this.timeouts.sessionIdleExpire})){ga();return}t&&this._createCustomBreadcrumb(t),this.conditionalFlush()}_doChangeToForegroundTasks(t){if(!this.session)return;if(!this.checkAndHandleExpiredSession()){N&&w.log("Document has become active, but session has expired");return}t&&this._createCustomBreadcrumb(t)}_updateUserActivity(t=Date.now()){this._lastActivity=t}_updateSessionActivity(t=Date.now()){this.session&&(this.session.lastActivity=t,this._maybeSaveSession())}_createCustomBreadcrumb(t){this.addUpdate(()=>{this.throttledAddEvent({type:G.Custom,timestamp:t.timestamp||0,data:{tag:"breadcrumb",payload:t}})})}_addPerformanceEntries(){let t=jS(this.performanceEntries).concat(this.replayPerformanceEntries);if(this.performanceEntries=[],this.replayPerformanceEntries=[],this._requiresManualStart){let r=this._context.initialTimestamp/1e3;t=t.filter(n=>n.start>=r)}return Promise.all(Ia(this,t))}_clearContext(){this._context.errorIds.clear(),this._context.traceIds.clear(),this._context.segmentNames.clear(),this._context.urls=[]}_updateInitialTimestampFromEventBuffer(){let{session:t,eventBuffer:r}=this;if(!t||!r||this._requiresManualStart||t.segmentId)return;let n=r.getEarliestTimestamp();n&&nthis._options.maxReplayDuration+3e4)throw new _a;let n=this._popEventContext(),i=this.session.segmentId++;this._maybeSaveSession();let s=await this.eventBuffer.finish();await Dm({replayId:t,recordingData:s,segmentId:i,eventContext:n,session:this.session,timestamp:r,onError:a=>this.handleException(a)})}catch(r){this.handleException(r),this.stop({reason:"sendError"});let n=E();if(n){let i;r instanceof Ui?i="ratelimit_backoff":r instanceof _a?i="invalid":i="send_error",n.recordDroppedEvent(i,"replay")}}}async _flush({force:t=!1}={}){if(!this._isEnabled&&!t)return;if(!this.checkAndHandleExpiredSession()){N&&w.error("Attempting to finish replay event after session expired.");return}if(!this.session)return;let r=this.session.started,i=Date.now()-r;this._debouncedFlush.cancel();let s=ithis._options.maxReplayDuration+5e3;if(s||a){N&&w.log(`Session duration (${Math.floor(i/1e3)}s) is too ${s?"short":"long"}, not sending replay.`),s&&this._debouncedFlush();return}let c=this.eventBuffer;c&&this.session.segmentId===0&&!c.hasCheckout&&N&&w.log("Flushing initial segment without checkout.");let o=!!this._flushLock;this._flushLock||(this._flushLock=this._runFlush());try{await this._flushLock}catch(l){this.handleException(l)}finally{this._flushLock=void 0,o&&this._debouncedFlush()}}_maybeSaveSession(){this.session&&this._options.stickySession&&Ta(this.session)}_onMutationHandler(t){let{ignoreMutations:r}=this._options._experiments;if(r?.length&&t.some(c=>{let o=hE(c.target),l=r.join(",");return o?.matches(l)}))return!1;let n=t.length,i=this._options.mutationLimit,s=this._options.mutationBreadcrumbLimit,a=i&&n>i;if(n>s||a){let c=Lt({category:"replay.mutations",data:{count:n,limit:a}});this._createCustomBreadcrumb(c)}return a?(this.stop({reason:"mutationLimit",forceFlush:this.recordingMode==="session"}),!1):!0}};function Ri(e,t){return[...e,...t].join(",")}function TE({mask:e,unmask:t,block:r,unblock:n,ignore:i}){let s=["base","iframe[srcdoc]:not([src])"],a=Ri(e,[".sentry-mask","[data-sentry-mask]"]),c=Ri(t,[]);return{maskTextSelector:a,unmaskTextSelector:c,blockSelector:Ri(r,[".sentry-block","[data-sentry-block]",...s]),unblockSelector:Ri(n,[]),ignoreSelector:Ri(i,[".sentry-ignore","[data-sentry-ignore]",'input[type="file"]'])}}function IE({el:e,key:t,maskAttributes:r,maskAllText:n,privacyOptions:i,value:s}){if(i.unmaskTextSelector&&e.matches(i.unmaskTextSelector))return s;let a=r.includes(t),c=n&&t==="value"&&e.tagName==="INPUT"&&["submit","button"].includes(e.getAttribute("type")||"");return a||c?s.replace(/[\S]/g,"*"):s}var Jd='img,image,svg,video,object,picture,embed,map,audio,link[rel="icon"],link[rel="apple-touch-icon"]',AE=["content-length","content-type","accept"],RE=Symbol.for("sentry__originalRequestBody"),Qd=!1,Zd=!1;function OE(){if(typeof Request>"u"||Zd)return;let e=Request;try{let t=function(r,n){let i=new e(r,n);return n?.body!=null&&(i[RE]=n.body),i};t.prototype=e.prototype,T.Request=t,Zd=!0}catch{}}var xE=(e=>new Hc(e)),Hc=class{constructor({flushMinDelay:t=ly,flushMaxDelay:r=py,minReplayDuration:n=hy,maxReplayDuration:i=kd,stickySession:s=!0,useCompression:a=!0,workerUrl:c,_experiments:o={},maskAllText:l=!0,maskAllInputs:u=!0,blockAllMedia:p=!0,mutationBreadcrumbLimit:d=750,mutationLimit:m=1e4,slowClickTimeout:g=7e3,slowClickIgnoreSelectors:h=[],networkDetailAllowUrls:S=[],networkDetailDenyUrls:b=[],networkCaptureBodies:C=!0,networkRequestHeaders:q=[],networkResponseHeaders:U=[],mask:Y=[],maskAttributes:D=["title","placeholder","aria-label"],unmask:v=[],block:F=[],unblock:x=[],ignore:y=[],maskFn:M,beforeAddRecordingEvent:K,beforeErrorSampling:ee,onError:re,attachRawBodyFromRequest:ue=!1}={}){this.name="Replay";let W=TE({mask:Y,unmask:v,block:F,unblock:x,ignore:y});if(this._recordingOptions={maskAllInputs:u,maskAllText:l,maskInputOptions:{password:!0},maskTextFn:M,maskInputFn:M,maskAttributeFn:(L,A,H)=>IE({maskAttributes:D,maskAllText:l,privacyOptions:W,key:L,value:A,el:H}),...W,slimDOMOptions:"all",inlineStylesheet:!0,inlineImages:!1,collectFonts:!0,errorHandler:L=>{try{L.__rrweb__=!0}catch{}},recordCrossOriginIframes:!!o.recordCrossOriginIframes},this._initialOptions={flushMinDelay:t,flushMaxDelay:r,minReplayDuration:Math.min(n,by),maxReplayDuration:Math.min(i,kd),stickySession:s,useCompression:a,workerUrl:c,blockAllMedia:p,maskAllInputs:u,maskAllText:l,mutationBreadcrumbLimit:d,mutationLimit:m,slowClickTimeout:g,slowClickIgnoreSelectors:h,networkDetailAllowUrls:S,networkDetailDenyUrls:b,networkCaptureBodies:C,networkRequestHeaders:em(q),networkResponseHeaders:em(U),beforeAddRecordingEvent:K,beforeErrorSampling:ee,onError:re,attachRawBodyFromRequest:ue,_experiments:o},this._initialOptions.blockAllMedia&&(this._recordingOptions.blockSelector=this._recordingOptions.blockSelector?`${this._recordingOptions.blockSelector},${Jd}`:Jd,this._recordingOptions.ignoreCSSAttributes=new Set(["background-image"])),this._isInitialized&&at())throw new Error("Multiple Sentry Session Replay instances are not supported");this._isInitialized=!0}get _isInitialized(){return Qd}set _isInitialized(t){Qd=t}afterAllSetup(t){!at()||this._replay||(this._initialOptions.attachRawBodyFromRequest&&OE(),this._setup(t),this._initialize(t))}start(){this._replay&&this._replay.start()}startBuffering(){this._replay&&this._replay.startBuffering()}stop(t){return this._replay?this._replay.stop({forceFlush:t?.flush??this._replay.recordingMode==="session",reason:"manual"}):Promise.resolve()}flush(t){return this._replay?this._replay.isEnabled()?this._replay.sendBufferedReplayOrFlush(t):(this._replay.start(),Promise.resolve()):Promise.resolve()}getReplayId(t){if(this._replay?.isEnabled())return this._replay.getSessionId(t)}getRecordingMode(){if(this._replay?.isEnabled())return this._replay.recordingMode}processSpan(t){let r=this.getReplayId(!0);r&&(Yt(t,{"sentry.replay_id":r}),this.getRecordingMode()==="buffer"&&Yt(t,{"sentry._internal.replay_is_buffering":!0}))}_initialize(t){this._replay&&(this._maybeLoadFromReplayCanvasIntegration(t),this._replay.initializeSampling())}_setup(t){let r=kE(this._initialOptions,t);this._replay=new qc({options:r,recordingOptions:this._recordingOptions})}_maybeLoadFromReplayCanvasIntegration(t){try{let r=t.getIntegrationByName("ReplayCanvas");if(!r)return;this._replay._canvas=r.getOptions()}catch{}}};function kE(e,t){let r=t.getOptions(),n={sessionSampleRate:0,errorSampleRate:0,...e},i=et(r.replaysSessionSampleRate),s=et(r.replaysOnErrorSampleRate);return i==null&&s==null&&Oe(()=>{console.warn("Replay is disabled because neither `replaysSessionSampleRate` nor `replaysOnErrorSampleRate` are set.")}),i!=null&&(n.sessionSampleRate=i),s!=null&&(n.errorSampleRate=s),n}function em(e){return[...AE,...e.map(t=>t.toLowerCase())]}var Fm=new WeakMap,Bm=new WeakMap,NE=9e4,wE=["text/event-stream","application/x-ndjson","application/stream+json"],qm=()=>({name:"FetchStreamPerformance",setup(){Ns(e=>{if(e.response){let t=Fm.get(e.response);if(t&&e.endTimestamp){t.end(e.endTimestamp);let r=Bm.get(e.response);r&&clearTimeout(r)}}}),pr(e=>{if(e.endTimestamp&&e.response){let t=e.response.headers?.get("content-type")||"";if(e.response.headers?.get("content-length")||!wE.some(o=>t.startsWith(o)))return;let r=e.fetchData?.url||"",n=e.fetchData?.method||"GET",i=vt(r),s=r.startsWith("data:")?Ne(r):i?cn(i):r,a=Ie({name:`${n} ${s}`,startTime:e.endTimestamp,attributes:{url:Ne(r),"http.method":n,type:"fetch",[de]:"http.client.stream",[j]:"auto.http.browser.stream"}});Fm.set(e.response,a);let c=setTimeout(()=>{a.isRecording()&&a.end()},NE);Bm.set(e.response,c)}})}});var tl="WebVitals",Hm=(e={})=>{let t=new Set(e.ignore??[]);return{name:tl,setup(r){let n=Te(r),{enableStandaloneClsSpans:i,enableStandaloneLcpSpans:s}=e._experiments??{},a=n||t.has("cls")?void 0:i||!1,c=n||t.has("lcp")?void 0:s||!1,o=$o({recordClsStandaloneSpans:a,recordLcpStandaloneSpans:c,client:r}),l=new WeakSet;r.on("afterStartPageLoadSpan",u=>{l.add(u)}),r.on("spanEnd",u=>{l.delete(u)&&(o(),Zo(u,{recordClsOnPageloadSpan:a===!1,recordLcpOnPageloadSpan:c===!1,spanStreamingEnabled:n}))}),n?(t.has("lcp")||sc(r),t.has("cls")||ac(r),t.has("inp")||oc()):t.has("inp")||rc()},afterAllSetup(){t.has("inp")||nc()}}};function Gm(){k.document?k.document.addEventListener("visibilitychange",()=>{let e=te();if(!e)return;let t=X(e);if(k.document.hidden&&t){let r="cancelled",{op:n,status:i}=O(t);ve&&f.log(`[Tracing] Transaction: ${r} -> since tab moved to the background, op: ${n}`),i||t.setStatus({code:2,message:r}),t.setAttribute("sentry.cancellation_reason","document.hidden"),t.end()}}):ve&&f.warn("[Tracing] Could not set up background tab detection due to lack of global document")}var CE=3600,Wm="sentry_previous_trace",ME="sentry.previous_trace";function Ym(e,{linkPreviousTrace:t,consistentTraceSampling:r}){let n=t==="session-storage",i=n?DE():void 0;e.on("spanStart",a=>{if(X(a)!==a)return;let c=R().getPropagationContext();i=LE(i,a,c),n&&PE(i)});let s=!0;r&&e.on("beforeSampling",a=>{if(!i)return;let c=R(),o=c.getPropagationContext();if(s&&o.parentSpanId){s=!1;return}c.setPropagationContext({...o,dsc:{...o.dsc,sample_rate:String(i.sampleRate),sampled:String(rl(i.spanContext))},sampleRand:i.sampleRand}),a.parentSampled=rl(i.spanContext),a.parentSampleRate=i.sampleRate,a.spanAttributes={...a.spanAttributes,[Xr]:i.sampleRate}})}function LE(e,t,r){let n=O(t);function i(){try{let c=Number(n.data?.[Bt]??r.dsc?.sample_rate);return Number.isNaN(c)?0:c}catch{return 0}}let s={spanContext:t.spanContext(),startTimestamp:n.start_timestamp,sampleRate:i(),sampleRand:r.sampleRand};if(!e)return s;let a=e.spanContext;return a.traceId===n.trace_id?e:(Date.now()/1e3-e.startTimestamp<=CE&&(ve&&f.log(`Adding previous_trace \`${JSON.stringify(a)}\` link to span \`${JSON.stringify({op:n.op,...t.spanContext()})}\``),t.addLink({context:a,attributes:{[es]:"previous_trace"}}),t.setAttribute(ME,`${a.traceId}-${a.spanId}-${rl(a)?1:0}`)),s)}function PE(e){try{k.sessionStorage.setItem(Wm,JSON.stringify(e))}catch(t){ve&&f.warn("Could not store previous trace in sessionStorage",t)}}function DE(){try{let e=k.sessionStorage?.getItem(Wm);return JSON.parse(e)}catch{return}}function rl(e){return e.traceFlags===1}function zm(e){return e.split(",").some(t=>t.trim().startsWith("sentry-"))}function nl(e){try{return new URL(e,k.location.origin).href}catch{return}}function Vm(e){return e.entryType==="resource"&&"initiatorType"in e&&typeof e.nextHopProtocol=="string"&&(e.initiatorType==="fetch"||e.initiatorType==="xmlhttprequest")}function il(e){try{return new Headers(e)}catch{return}}var sl={traceFetch:!0,traceXHR:!0,enableHTTPTimings:!0,trackFetchStreamPerformance:!1};function $m(e,t){let{traceFetch:r,traceXHR:n,shouldCreateSpanForRequest:i,enableHTTPTimings:s,tracePropagationTargets:a,onRequestSpanStart:c,onRequestSpanEnd:o}={...sl,...t},l=typeof i=="function"?i:m=>!0,u=m=>FE(m,a),p={},d=e.getOptions().propagateTraceparent;r&&pr(m=>{let g=Lo(m,l,u,p,{propagateTraceparent:d,onRequestSpanEnd:o});if(g){let h=nl(m.fetchData.url),S=h?ot(h).host:void 0,b=h?Ne(h):void 0;g.setAttributes({[hs]:b,[St]:b,"server.address":S}),s&&jm(g,e),c?.(g,{headers:m.headers})}}),n&&Ti(m=>{let g=BE(m,l,u,p,d,o);g&&(s&&jm(g,e),c?.(g,{headers:il(m.xhr.__sentry_xhr_v3__?.request_headers)}))})}var UE=300;function jm(e,t){let{url:r}=O(e).data;if(!r||typeof r!="string")return;let n=()=>void setTimeout(i);if(Te(t)){let s=e.end.bind(e);e.end=a=>{let c=a??Q(),o=!1,l=()=>{o||(o=!0,setTimeout(i),s(c),clearTimeout(u))};n=l;let u=setTimeout(l,UE)}}let i=ut("resource",({entries:s})=>{s.forEach(a=>{Vm(a)&&a.name.endsWith(r)&&(e.setAttributes(Si(a)),n())})})}function FE(e,t){let r=Ge();if(r){let n,i;try{n=new URL(e,r),i=new URL(r).origin}catch{return!1}let s=n.origin===i;return t?xe(n.toString(),t)||s&&xe(n.pathname,t):s}else{let n=!!e.match(/^\/(?!\/)/);return t?xe(e,t):n}}function BE(e,t,r,n,i,s){let a=e.xhr,c=a?.[Et];if(!a||a.__sentry_own_request__||!c)return;let{url:o,method:l}=c,u=_e()&&t(o);if(e.endTimestamp){let U=a.__sentry_xhr_span_id__;if(!U)return;let Y=n[U];Y&&(u&&c.status_code!==void 0&&(Qr(Y,c.status_code),Y.end(),s?.(Y,{headers:il(Ii(a)),error:e.error})),delete n[U]);return}let p=nl(o),d=p?ot(p):ot(o),m=p?Ne(p):void 0,g=Ne(vs(o)),h=E(),S=!!te(),b=S||!!h&&Te(h),C=u&&b?Ie({name:`${l} ${g}`,attributes:{url:Ne(o),type:"xhr","http.method":l,"http.url":m,[St]:m,"server.address":d?.host,[j]:"auto.http.browser",[de]:"http.client",...d?.search&&{"http.query":d?.search},...d?.hash&&{"http.fragment":d?.hash}}}):new Xe,q=rn(C)&&S?void 0:C;return u&&!b&&h?.recordDroppedEvent("no_parent_span","span"),a.__sentry_xhr_span_id__=C.spanContext().spanId,n[a.__sentry_xhr_span_id__]=C,r(o)&&qE(a,_e()&&b?q:void 0,i),h&&h.emit("beforeOutgoingRequestSpan",C,e),C}function qE(e,t,r){let{"sentry-trace":n,baggage:i,traceparent:s}=ln({span:t,propagateTraceparent:r});n&&HE(e,n,i,s)}function HE(e,t,r,n){let i=e.__sentry_xhr_v3__?.request_headers;if(!(i?.["sentry-trace"]||!e.setRequestHeader))try{if(e.setRequestHeader("sentry-trace",t),n&&!i?.traceparent&&e.setRequestHeader("traceparent",n),r){let s=i?.baggage;(!s||!zm(s))&&e.setRequestHeader("baggage",r)}}catch{}}var GE="BrowserTracing",WE=/Googlebot|Google-InspectionTool|Storebot-Google|Bingbot|Slurp|DuckDuckBot|Baiduspider|YandexBot|Facebot|facebookexternalhit|LinkedInBot|Twitterbot|Applebot/i;function Zm(){let e=k.navigator;return e?.userAgent?WE.test(e.userAgent):!1}var YE={...nn,instrumentNavigation:!0,instrumentPageLoad:!0,markBackgroundSpan:!0,enableLongTask:!0,enableLongAnimationFrame:!0,enableInp:!0,ignoreResourceSpans:[],ignorePerformanceApiSpans:[],detectRedirects:!0,linkPreviousTrace:"in-memory",consistentTraceSampling:!1,enableReportPageLoaded:!1,_experiments:{},...sl},zE=((e={})=>{"enableElementTiming"in e&&Oe(()=>{console.warn("[Sentry] `enableElementTiming` is deprecated and no longer has any effect. Use the standalone `elementTimingIntegration` instead.")});let t={name:void 0,source:void 0},r=k.document,{enableInp:n,enableLongTask:i,enableLongAnimationFrame:s,_experiments:{enableInteractions:a,enableStandaloneClsSpans:c,enableStandaloneLcpSpans:o},beforeStartSpan:l,idleTimeout:u,finalTimeout:p,childSpanTimeout:d,markBackgroundSpan:m,traceFetch:g,traceXHR:h,trackFetchStreamPerformance:S,shouldCreateSpanForRequest:b,enableHTTPTimings:C,ignoreResourceSpans:q,ignorePerformanceApiSpans:U,instrumentPageLoad:Y,instrumentNavigation:D,detectRedirects:v,linkPreviousTrace:F,consistentTraceSampling:x,enableReportPageLoaded:y,onRequestSpanStart:M,onRequestSpanEnd:K}={...YE,...e},ee=Zm(),re,ue;function W(L,A,H=!0,B){let ae=A.op==="pageload",oe=A.name,ce=l?l(A):A,ge=vt(B||Ge()),hr={...ge?.pathname&&{[mp]:ge.pathname},...ge&&!zt(ge)&&{[St]:ge.href},...ce.attributes};if(oe!==ce.name&&(hr[Se]="custom"),ce.attributes=hr,!H){let Dt=Ve();Ie({...ce,startTime:Dt}).end(Dt);return}t.name=ce.name,t.source=hr[Se];let Pt=gs(ce,{idleTimeout:u,finalTimeout:p,childSpanTimeout:d,disableAutoFinish:ae,beforeSpanEnd:Dt=>{Qo(Dt,{ignoreResourceSpans:q,ignorePerformanceApiSpans:U,spanStreamingEnabled:Te(L)}),Jm(L,void 0);let kn=R(),_r=kn.getPropagationContext();kn.setPropagationContext({..._r,traceId:Pt.spanContext().traceId,sampled:qe(Pt),dsc:ke(Dt)}),ae&&(ue=void 0)},trimIdleSpanEndTimestamp:!y});ae&&y&&(ue=Pt),Jm(L,Pt);function br(){r&&["interactive","complete"].includes(r.readyState)&&(L.emit("idleSpanEnableAutoFinish",Pt),r.removeEventListener("readystatechange",br))}ae&&!y&&r&&(r.addEventListener("readystatechange",br),br())}return{name:GE,setup(L){if(ee){ve&&f.log("[Tracing] Skipping browserTracingIntegration setup for bot user agent.");return}if(cs(),s&&T.PerformanceObserver&&PerformanceObserver.supportedEntryTypes?.includes("long-animation-frame")?Xo():i&&Ko(),a&&Jo(),v&&r){let H=()=>{re=Q()};addEventListener("click",H,{capture:!0}),addEventListener("keydown",H,{capture:!0,passive:!0})}function A(){let H=qi(L);H&&!O(H).timestamp&&(ve&&f.log(`[Tracing] Finishing current active span with op: ${O(H).op}`),H.setAttribute(qt,"cancelled"),H.end())}L.on("startNavigationSpan",(H,B)=>{if(E()!==L)return;if(B?.isRedirect){ve&&f.warn("[Tracing] Detected redirect, navigation span will not be the root span, but a child span."),W(L,{op:"navigation.redirect",...H},!1,B.url);return}re=void 0,A();let ae=R();ae.setPropagationContext({traceId:je(),sampleRand:Math.random(),propagationSpanId:_e()?void 0:Be()}),ae.setSDKProcessingMetadata({normalizedRequest:void 0}),W(L,{op:"navigation",...H,parentSpan:null,forceTransaction:!0},!0,B?.url)}),L.on("startPageLoadSpan",(H,B={})=>{if(E()!==L)return;A();let ae=B.sentryTrace||Km("sentry-trace")||Xm("sentry-trace"),oe=B.baggage||Km("baggage")||Xm("baggage"),ce=Za(ae,oe),ge=R();ge.setPropagationContext(ce),_e()||(ge.getPropagationContext().propagationSpanId=Be()),ge.setSDKProcessingMetadata({normalizedRequest:dn()}),W(L,{op:"pageload",...H})}),L.on("endPageloadSpan",()=>{y&&ue&&(ue.setAttribute(qt,"reportPageLoaded"),ue.end())})},afterAllSetup(L){if(ee)return;L.addIntegration&&!L.getIntegrationByName?.(tl)&&L.addIntegration(Hm({ignore:n?[]:["inp"],_experiments:{enableStandaloneClsSpans:c,enableStandaloneLcpSpans:o}}));let A=Ge();if(F!=="off"&&Ym(L,{linkPreviousTrace:F,consistentTraceSampling:x}),k.location){if(Y){let H=ie();eg(L,{name:k.location.pathname,startTime:H?H/1e3:void 0,attributes:{[Se]:"url",[j]:"auto.pageload.browser"}})}D&&Qt(({to:H,from:B})=>{if(B===void 0&&A?.indexOf(H)!==-1){A=void 0;return}A=void 0;let ae=vt(H),oe=qi(L),ce=oe&&v&&jE(oe,re);tg(L,{name:ae?.pathname||k.location.pathname,attributes:{[Se]:"url",[j]:"auto.navigation.browser"}},{url:H,isRedirect:ce})})}m&&Gm(),a&&VE(L,u,p,d,t),$m(L,{traceFetch:g,traceXHR:h,tracePropagationTargets:L.getOptions().tracePropagationTargets,shouldCreateSpanForRequest:b,enableHTTPTimings:C,onRequestSpanStart:M,onRequestSpanEnd:K}),S&&L.addIntegration(qm())}}});function eg(e,t,r){e.emit("startPageLoadSpan",t,r),R().setTransactionName(t.name);let n=qi(e);return n&&e.emit("afterStartPageLoadSpan",n),n}function tg(e,t,r){let{url:n,isRedirect:i}=r||{};e.emit("beforeStartNavigationSpan",t,{isRedirect:i,url:n}),e.emit("startNavigationSpan",t,{isRedirect:i,url:n});let s=R();return s.setTransactionName(t.name),n&&!i&&s.setSDKProcessingMetadata({normalizedRequest:{...dn(),url:n}}),qi(e)}function Km(e){return k.document?.querySelector(`meta[name=${e}]`)?.getAttribute("content")||void 0}function Xm(e){return k.performance?.getEntriesByType?.("navigation")[0]?.serverTiming?.find(n=>n.name===e)?.description}function VE(e,t,r,n,i){let s=k.document,a,c=()=>{let o="ui.action.click",l=qi(e);if(l){let u=O(l).op;if(["navigation","pageload"].includes(u)){ve&&f.warn(`[Tracing] Did not create ${o} span because a pageload or navigation span is in progress.`);return}}if(a&&(a.setAttribute(qt,"interactionInterrupted"),a.end(),a=void 0),!i.name){ve&&f.warn(`[Tracing] Did not create ${o} transaction because _latestRouteName is missing.`);return}a=gs({name:i.name,op:o,attributes:{[Se]:i.source||"url"}},{idleTimeout:t,finalTimeout:r,childSpanTimeout:n})};s&&addEventListener("click",c,{capture:!0})}var rg="_sentry_idleSpan";function qi(e){return e[rg]}function Jm(e,t){ne(e,rg,t)}var Qm=1.5;function jE(e,t){let r=O(e),n=Ve(),i=r.start_timestamp;return!(n-i>Qm||t&&n-t<=Qm)}export{E as a,xl as b,uu as c,sy as d,xE as e,zE as f,tg as g}; +/*! Bundled license information: + +@sentry/core/build/esm/utils/env.js: + (*! __SENTRY_SDK_SOURCE__ *) +*/ diff --git a/browser/dist/esm/chunk-QBI2JL2F.js b/browser/dist/esm/chunk-QBI2JL2F.js new file mode 100644 index 0000000..68b4cf9 --- /dev/null +++ b/browser/dist/esm/chunk-QBI2JL2F.js @@ -0,0 +1 @@ +var a={};function r(e){a={...e}}function n(){return a.readable===!0}function o(e){return!e.search&&!e.hash&&(a.stylesheet?.(e)??!1)}function t(e){return a.protectedPage?.(e)??/(?:login|password|token|payment|checkout|bank)/i.test(e.pathname+e.search)}function c(e){return!t(e)&&!e.search&&!e.hash}function p(e){return`${e.origin}${t(e)?"/[private-page]":e.pathname}`}export{r as a,n as b,o as c,t as d,c as e,p as f}; diff --git a/browser/dist/esm/chunk-UVRZCAHX.js b/browser/dist/esm/chunk-UVRZCAHX.js new file mode 100644 index 0000000..5c97412 --- /dev/null +++ b/browser/dist/esm/chunk-UVRZCAHX.js @@ -0,0 +1 @@ +import{b as i}from"./chunk-QBI2JL2F.js";var c=["password","passcode","verificationCode","loginCode","token","secret","apiKey","cardNumber","creditCard","cvv","cvc","securityCode","bankAccount","accountNumber","routingNumber","iban"],d=["[data-feedback-secret]","[data-feedback-ui]","[data-token]",'[name="otp" i]','[name="pin" i]','[id="otp" i]','[id="pin" i]',".sentry-mask","[data-sentry-mask]",".sentry-block","[data-sentry-block]",'input[type="password"]','input[type="hidden"]','[autocomplete~="current-password"]','[autocomplete~="new-password"]','[autocomplete~="one-time-code"]','[autocomplete*="cc-" i]',...c.flatMap(t=>{let a=t.match(/[A-Z]?[a-z]+/g).map(e=>e.toLowerCase());return["name","id"].map(e=>a.map(r=>"["+e+"*="+r+" i]").join(""))}),'a[href*="token=" i]','a[href*="/invites/"]','a[href*="/secure-links/"]','a[href*="/login-links/"]','a[href*="/document-deliveries/"]'].join(",");function l(t,a){return!i()||a?.closest(d)?t.replace(/\S/g,"*"):t}var p=l,m=['img[src*="?"]','img[src*="#"]','img[src^="data:"]','img[src*="/document-deliveries/"]','img[src*="/secure-links/"]'].join(","),o=["href","srcset","action","formaction","data-page","data-token","data-reference","title","aria-label","aria-description","alt","placeholder","content","style","data-position-name","data-staff-member","data-label-code","data-edit-role","data-edit-position"],s=new Set(["class","role","type","width","height","colspan","rowspan","rows","cols","dir","lang","aria-hidden","src","value","d","viewBox","fill","stroke","stroke-width","stroke-linecap","stroke-linejoin","x","y","x1","y1","x2","y2","cx","cy","r","rx","ry","points"]);function n(t){for(let a of[t,...t.querySelectorAll("*")])for(let{name:e}of a.attributes)!s.has(e)&&!o.includes(e)&&o.push(e)}function f(){n(document.documentElement);let t=new MutationObserver(a=>{for(let e of a){e.type==="attributes"&&e.attributeName&&!s.has(e.attributeName)&&!o.includes(e.attributeName)&&o.push(e.attributeName);for(let r of e.addedNodes)r instanceof Element&&n(r)}});return t.observe(document.documentElement,{subtree:!0,childList:!0,attributes:!0}),t}export{d as a,l as b,p as c,m as d,o as e,n as f,f as g}; diff --git a/browser/dist/esm/feedbackReplay-6PAAGWVV.js b/browser/dist/esm/feedbackReplay-6PAAGWVV.js new file mode 100644 index 0000000..c0238f2 --- /dev/null +++ b/browser/dist/esm/feedbackReplay-6PAAGWVV.js @@ -0,0 +1 @@ +import{a as m,b,e as k}from"./chunk-5LBAMSSV.js";import{a as p,c as y,d as v,e as R,f as w,g}from"./chunk-UVRZCAHX.js";import{b as l,e as u}from"./chunk-QBI2JL2F.js";var t,i=!1,o=!1,r=0,d=Promise.resolve(),a;function c(){r++;let e=d,s=t?.stop({flush:!1}).catch(()=>{})??Promise.resolve();d=Promise.all([e,s]).then(()=>{})}async function f(){let e=r;await d,await Promise.resolve(),e===r&&o&&!i&&u(window.location)&&(w(document.documentElement),t?.startBuffering())}function x(){o=!0,!(t||!m())&&(g(),t=k({stickySession:!1,minReplayDuration:0,maskAllText:!l(),maskAllInputs:!l(),blockAllMedia:!l(),mask:[p],maskFn:y,maskAttributes:R,block:["script","iframe","canvas","video, audio, object, embed",p,v,'[style*="url("]',"[data-feedback-ui]"],networkCaptureBodies:!1,networkDetailAllowUrls:[],beforeAddRecordingEvent:()=>null}),b(t),window.addEventListener("popstate",c,{capture:!0}),window.addEventListener("hashchange",()=>{c(),f()}),f())}function I(){if(a)return a;i=!0;let e=t,s=e?.getReplayId(),h=r;if(!o||!e||!s||!u(window.location))return Promise.resolve(void 0);let n=(async()=>{try{return await e.flush({continueRecording:!1}),h===r&&o?s:void 0}catch{return}finally{await e.stop({flush:!1})}})();return a=n,d=n.then(()=>{}),n.finally(()=>{a===n&&(a=void 0)}),n}function E(){i=!1,c(),f()}function z(e){o=e,e?(i=!1,t?f():x()):(i=!0,c())}export{I as freezeFeedbackReplay,x as initializeFeedbackReplay,E as restartFeedbackReplay,f as resumeFeedbackReplay,z as setFeedbackReplayEnabled,c as stopFeedbackReplay}; diff --git a/browser/dist/esm/feedbackScreenshot-XN3R2P73.js b/browser/dist/esm/feedbackScreenshot-XN3R2P73.js new file mode 100644 index 0000000..fb41179 --- /dev/null +++ b/browser/dist/esm/feedbackScreenshot-XN3R2P73.js @@ -0,0 +1,2 @@ +import{a as u,b as y,d}from"./chunk-UVRZCAHX.js";import{b as f,c as b,d as m}from"./chunk-QBI2JL2F.js";function g(t){return Array.from(t.styleSheets).flatMap(n=>{if(!n.href)return[];let r=new URL(n.href,t.baseURI);if(r.origin!==new URL(t.baseURI).origin||!b(r)||r.search||r.hash)return[];try{return[Array.from(n.cssRules,o=>o.cssText).join(` +`)]}catch{return[]}})}function w(t,n){if(t.querySelectorAll(`script, iframe, canvas, video, audio, object, embed, ${u}, ${d}, [data-feedback-ui]`).forEach(e=>{e.style.visibility="hidden"}),n){t.body.style.visibility="hidden";return}let r=new Set(Array.from(t.querySelectorAll(u)).flatMap(e=>[e,...e.querySelectorAll("*")]));t.querySelectorAll(d).forEach(e=>e.removeAttribute("src"));let o=t.createTreeWalker(t.body,NodeFilter.SHOW_TEXT);for(;o.nextNode();)o.currentNode.textContent=y(o.currentNode.textContent??"",o.currentNode.parentElement);t.querySelectorAll("body, body *").forEach(e=>{let a=!f()||r.has(e),c=e,l=c.value,h=c.checked,p=e.selectedIndex;e.style.setProperty("background-image","none","important");for(let i of[...e.attributes])/^data-v-[0-9a-f]{8}$/.test(i.name)&&!i.value||(/^(?:data-|href$|srcset$|action$|formaction$|value$)/i.test(i.name)?e.removeAttribute(i.name):/^(?:title|alt|aria-label|aria-description|placeholder)$/.test(i.name)&&e.setAttribute(i.name,a?i.value.replace(/\S/g,"*"):i.value));(e.tagName==="INPUT"||e.tagName==="TEXTAREA")&&(e.value=a?"":l),e.tagName==="INPUT"&&(e.checked=a?!1:h),e.tagName==="SELECT"&&(e.selectedIndex=a?-1:p)});let s=t.createElement("style");s.textContent="*::before, *::after { content: none !important; background-image: none !important; }",t.head.append(s)}async function T(){if(m(window.location))return;let{default:t}=await import("./html2canvas-pro.esm-REK7NNFK.js"),n=window.innerWidth,r=window.innerHeight,o=g(document),s=await t(document.body,{width:n,height:r,x:window.scrollX,y:window.scrollY,scale:Math.min(1,Math.sqrt(15e5/(n*r))),backgroundColor:"#f4f8fb",logging:!1,allowTaint:!1,useCORS:!1,imageTimeout:3e3,ignoreElements:a=>a.hasAttribute("data-feedback-ui"),onclone:async a=>{for(let c of o){let l=a.createElement("style");l.textContent=c,a.head.append(l)}w(a,!1),a.body.getBoundingClientRect(),await a.fonts?.ready}}),e=await new Promise(a=>s.toBlob(a,"image/png"));if(!(!e||e.size>2e6))return{data:new Uint8Array(await e.arrayBuffer()),previewUrl:URL.createObjectURL(e)}}export{T as captureFeedbackScreenshot,g as compiledScreenshotStyles,w as sanitizeScreenshotDocument}; diff --git a/browser/dist/esm/html2canvas-pro.esm-REK7NNFK.js b/browser/dist/esm/html2canvas-pro.esm-REK7NNFK.js new file mode 100644 index 0000000..2f23d54 --- /dev/null +++ b/browser/dist/esm/html2canvas-pro.esm-REK7NNFK.js @@ -0,0 +1,16 @@ +var ho=class Gt{constructor(e={}){let t=e.window||(typeof window<"u"?window:void 0);if(!t)throw new Error("Window object is required but not available");this.window=t,this.cspNonce=e.cspNonce,this.cache=e.cache}static fromElement(e,t={}){let r=e.ownerDocument;if(!r)throw new Error("Element is not attached to a document");let s=r.defaultView;if(!s)throw new Error("Document is not attached to a window");return new Gt({window:s,...t})}clone(e={}){return new Gt({window:e.window||this.window,cspNonce:e.cspNonce??this.cspNonce,cache:e.cache??this.cache})}},go=class{constructor(A={}){this.config={maxImageTimeout:3e5,allowDataUrls:!0,...A}}validateUrl(A,e="general"){if(!A||typeof A!="string")return{valid:!1,error:"URL must be a non-empty string"};if(A.startsWith("data:"))return this.config.allowDataUrls?{valid:!0,sanitized:A}:{valid:!1,error:"Data URLs are not allowed"};if(A.startsWith("blob:"))return{valid:!0,sanitized:A};try{let t=new URL(A);if(!["http:","https:"].includes(t.protocol))return{valid:!1,error:`Protocol ${t.protocol} is not allowed. Only http and https are permitted.`};if(e==="proxy"&&this.config.allowedProxyDomains&&this.config.allowedProxyDomains.length>0){let r=t.hostname.toLowerCase();if(!this.config.allowedProxyDomains.some(s=>{let n=s.toLowerCase();return r===n||r.endsWith("."+n)}))return{valid:!1,error:`Proxy domain ${t.hostname} is not in the allowed list`}}if(e==="proxy"){if(!this.config.allowLocalhostProxy){let r=t.hostname.toLowerCase();if(r==="localhost"||r==="127.0.0.1"||r==="::1")return{valid:!1,error:"Localhost is not allowed for proxy URLs"};if(this.isPrivateIP(r))return{valid:!1,error:"Private IP addresses are not allowed for proxy URLs"};if(r.startsWith("169.254.")||r.startsWith("fe80:"))return{valid:!1,error:"Link-local addresses are not allowed for proxy URLs"}}return{valid:!0,sanitized:A,requiresRuntimeCheck:!0}}return{valid:!0,sanitized:A}}catch(t){return{valid:!1,error:`Invalid URL format: ${t instanceof Error?t.message:"Unknown error"}`}}}isPrivateIP(A){return[/^0\./,/^10\./,/^100\.(6[4-9]|[7-9][0-9]|1[0-1][0-9]|12[0-7])\./,/^127\./,/^169\.254\./,/^172\.(1[6-9]|2[0-9]|3[0-1])\./,/^192\.0\.0\./,/^192\.0\.2\./,/^192\.168\./,/^198\.(1[8-9])\./,/^198\.51\.100\./,/^203\.0\.113\./,/^2(2[4-9]|3[0-9])\./,/^24[0-9]\./,/^255\.255\.255\.255$/].some(e=>e.test(A))?!0:A.includes(":")?this.isPrivateIPv6(A):!1}isPrivateIPv6(A){let e=A.toLowerCase().trim().replace(/^\[|\]$/g,""),t=e.split("%")[0]??e;if(/^(0:){7}1$/.test(t)||t==="::1"||/^(0:){7}0$/.test(t)||t==="::")return!0;let r=this.expandIPv6(t);if(!r)return this.isPrivateIPv6Prefix(t);let s=parseInt(r.substring(0,2),16);if(s>=252&&s<=253)return!0;if(s===254){let n=parseInt(r.substring(2,4),16);if(n>=128&&n<=191)return!0}return s===255}expandIPv6(A){try{if(A.includes("::")){let e=A.split("::");if(e.length>2)return null;let t=e[0]?e[0].split(":"):[],r=e[1]?e[1].split(":"):[],s=8-t.length-r.length;if(s<0)return null;let n=Array(s).fill("0000");return[...t,...n,...r].map(o=>o.padStart(4,"0")).join(":")}else{let e=A.split(":");return e.length!==8?null:e.map(t=>t.padStart(4,"0")).join(":")}}catch{return null}}isPrivateIPv6Prefix(A){return!!(/^fc[0-9a-f]{0,2}:?/i.test(A)||/^fd[0-9a-f]{0,2}:?/i.test(A)||/^fe[89ab][0-9a-f]:?/i.test(A)||/^ff[0-9a-f]{0,2}:?/i.test(A))}validateCspNonce(A){return!A||typeof A!="string"?{valid:!1,error:"CSP nonce must be a non-empty string"}:A.length<16?{valid:!1,error:"CSP nonce is too short (minimum 16 characters recommended)"}:/^[A-Za-z0-9+/=_-]+$/.test(A)?{valid:!0,sanitized:A}:{valid:!1,error:"CSP nonce contains invalid characters"}}validateImageTimeout(A){return typeof A!="number"||isNaN(A)?{valid:!1,error:"Image timeout must be a number"}:A<0?{valid:!1,error:"Image timeout cannot be negative"}:this.config.maxImageTimeout&&A>this.config.maxImageTimeout?{valid:!1,error:`Image timeout ${A}ms exceeds maximum allowed ${this.config.maxImageTimeout}ms`}:{valid:!0,sanitized:A}}validateDimensions(A,e){if(typeof A!="number"||typeof e!="number")return{valid:!1,error:"Dimensions must be numbers"};if(isNaN(A)||isNaN(e))return{valid:!1,error:"Dimensions cannot be NaN"};if(A<=0||e<=0)return{valid:!1,error:"Dimensions must be positive"};let t=32767;return A>t||e>t?{valid:!1,error:`Dimensions exceed maximum allowed (${t}px)`}:{valid:!0,sanitized:{width:A,height:e}}}validateScale(A){return typeof A!="number"||isNaN(A)?{valid:!1,error:"Scale must be a number"}:A<=0?{valid:!1,error:"Scale must be positive"}:A>10?{valid:!1,error:"Scale factor too large (maximum 10x)"}:{valid:!0,sanitized:A}}validateElement(A){if(!A)return{valid:!1,error:"Element is required"};if(typeof A!="object")return{valid:!1,error:"Element must be an object"};let e=A;return typeof HTMLElement<"u"&&A instanceof HTMLElement?A.ownerDocument?{valid:!0}:{valid:!1,error:"Element must be attached to a document"}:e.ownerDocument?e.ownerDocument.defaultView?{valid:!0}:{valid:!1,error:"Document must be attached to a window (ownerDocument.defaultView required)"}:{valid:!1,error:"Element must be attached to a document (ownerDocument required)"}}validateOptions(A){let e=[],t=A.proxy;if(t!=null&&typeof t=="string"&&t.length>0){let r=this.validateUrl(t,"proxy");r.valid||e.push(`Proxy: ${r.error}`)}if(A.imageTimeout!==void 0){let r=this.validateImageTimeout(A.imageTimeout);r.valid||e.push(`Image timeout: ${r.error}`)}if(A.width!==void 0||A.height!==void 0){let r=A.width??800,s=A.height??600,n=this.validateDimensions(r,s);n.valid||e.push(`Dimensions: ${n.error}`)}if(A.scale!==void 0){let r=this.validateScale(A.scale);r.valid||e.push(`Scale: ${r.error}`)}if(A.cspNonce!==void 0){let r=this.validateCspNonce(A.cspNonce);r.valid||e.push(`CSP nonce: ${r.error}`)}if(this.config.customValidator){let r=this.config.customValidator(A,"options");r.valid||e.push(`Custom validation: ${r.error}`)}return e.length>0?{valid:!1,error:e.join("; ")}:{valid:!0}}};function uo(A={}){return new go({allowDataUrls:!0,maxImageTimeout:3e5,...A})}var wo=class{constructor(A,e=!0){this.context=A,this.activeMetrics=new Map,this.completedMetrics=[],this.enabled=e,this.getTime=typeof performance<"u"&&typeof performance.now=="function"?()=>performance.now():()=>Date.now()}start(A,e){this.enabled&&(this.activeMetrics.has(A)&&this.context?.logger.warn(`Performance metric '${A}' already started. Overwriting.`),this.activeMetrics.set(A,{name:A,startTime:this.getTime(),metadata:e}))}end(A){if(!this.enabled)return;let e=this.activeMetrics.get(A);if(!e){this.context?.logger.warn(`Performance metric '${A}' not found. Was start() called?`);return}return e.endTime=this.getTime(),e.duration=e.endTime-e.startTime,this.completedMetrics.push(e),this.activeMetrics.delete(A),this.context?.logger.debug(`\u23F1\uFE0F ${A}: ${e.duration.toFixed(2)}ms`,e.metadata),e}measure(A,e,t){this.start(A,t);try{let r=e();return this.end(A),r}catch(r){throw this.end(A),r}}async measureAsync(A,e,t){this.start(A,t);try{let r=await e();return this.end(A),r}catch(r){throw this.end(A),r}}getMetrics(){return[...this.completedMetrics]}getMetric(A){return this.completedMetrics.find(e=>e.name===A)}getSummary(){let A=this.completedMetrics.reduce((t,r)=>t+(r.duration||0),0),e=this.completedMetrics.map(t=>({name:t.name,duration:t.duration||0,percentage:A>0?((t.duration||0)/A*100).toFixed(1)+"%":"0%"}));return{totalDuration:A,metrics:this.getMetrics(),breakdown:e}}logSummary(){if(!this.enabled||this.completedMetrics.length===0||!this.context)return;let A=this.getSummary();this.context.logger.info(` +\u{1F4CA} Performance Summary (Total: ${A.totalDuration.toFixed(2)}ms):`),A.breakdown.sort((e,t)=>t.duration-e.duration).forEach(e=>{this.context.logger.info(` ${e.name.padEnd(20)} ${e.duration.toFixed(2).padStart(8)}ms ${e.percentage.padStart(6)}`)})}clear(){this.activeMetrics.clear(),this.completedMetrics.splice(0)}isEnabled(){return this.enabled}getActiveMetrics(){return Array.from(this.activeMetrics.keys())}},_=class ZA{constructor(e,t,r,s){this.left=e,this.top=t,this.width=r,this.height=s}add(e,t,r,s){return new ZA(this.left+e,this.top+t,this.width+r,this.height+s)}static fromClientRect(e,t){return new ZA(t.left+e.windowBounds.left,t.top+e.windowBounds.top,t.width,t.height)}static fromDOMRectList(e,t){let r=Array.from(t),s=r.find(n=>n.width!==0);return s||(s=r.find(n=>n.height!==0)),!s&&r.length>0&&(s=r[0]),s?new ZA(s.left+e.windowBounds.left,s.top+e.windowBounds.top,s.width,s.height):ZA.EMPTY}static{this.EMPTY=new ZA(0,0,0,0)}},ye=(A,e)=>_.fromClientRect(A,e.getBoundingClientRect()),Qo=A=>{let e=A.body,t=A.documentElement;if(!e||!t)throw new Error("Unable to get document size");return new _(0,0,Math.max(Math.max(e.scrollWidth,t.scrollWidth),Math.max(e.offsetWidth,t.offsetWidth),Math.max(e.clientWidth,t.clientWidth)),Math.max(Math.max(e.scrollHeight,t.scrollHeight),Math.max(e.offsetHeight,t.offsetHeight),Math.max(e.clientHeight,t.clientHeight)))},at=function(A){for(var e=[],t=0,r=A.length;t=55296&&s<=56319&&t>10)+55296,o%1024+56320)),(s+1===t||r.length>16384)&&(n+=String.fromCharCode.apply(String,r),r.length=0)}return n},xr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",fo=typeof Uint8Array>"u"?[]:new Uint8Array(256);for(se=0;se"u"?[]:new Uint8Array(256);for(ne=0;ne>4,B[s++]=(o&15)<<4|a>>2,B[s++]=(a&3)<<6|i&63;return c},Uo=function(A){for(var e=A.length,t=[],r=0;r>KA,Ut=(1<>KA)+32,Eo=65536>>Cr,Ho=(1<=0){if(e<55296||e>56319&&e<=65535)return t=this.index[e>>KA],t=(t<>KA)],t=(t<>Cr),t=this.index[t],t+=e>>KA&Ho,t=this.index[t],t=(t<"u"?[]:new Uint8Array(256);for(oe=0;oeDr?(s.push(!0),a-=Dr):s.push(!1),["normal","auto","loose"].indexOf(e)!==-1&&[8208,8211,12316,12448].indexOf(n)!==-1)return r.push(o),t.push(Xt);if(a===Ko||a===kt){if(o===0)return r.push(o),t.push(xA);var i=t[o-1];return No.indexOf(i)===-1?(r.push(r[o-1]),t.push(i)):(r.push(o),t.push(xA))}if(r.push(o),a===Oo)return t.push(e==="strict"?_t:Ie);if(a===Ns||a===To)return t.push(xA);if(a===Ro)return n>=131072&&n<=196605||n>=196608&&n<=262141?t.push(Ie):t.push(xA);t.push(a)}),[r,t,s]},mt=function(A,e,t,r){var s=r[t];if(Array.isArray(A)?A.indexOf(s)!==-1:A===s)for(var n=t;n<=r.length;){n++;var o=r[n];if(o===e)return!0;if(o!==CA)break}if(s===CA)for(var n=t;n>0;){n--;var a=r[n];if(Array.isArray(A)?A.indexOf(a)!==-1:A===a)for(var i=t;i<=r.length;){i++;var o=r[i];if(o===e)return!0;if(o!==CA)break}if(a!==CA)break}return!1},Nr=function(A,e){for(var t=A;t>=0;){var r=e[t];if(r===CA)t--;else return r}return 0},Po=function(A,e,t,r,s){if(t[r]===0)return b;var n=r-1;if(Array.isArray(s)&&s[n]===!0)return b;var o=n-1,a=n+1,i=e[n],c=o>=0?e[o]:0,B=e[a];if(i===Os&&B===Rs)return b;if($t.indexOf(i)!==-1)return Gs;if($t.indexOf(B)!==-1||ks.indexOf(B)!==-1)return b;if(Nr(n,e)===Vs)return Re;if(zt.get(A[n])===kt||(i===Te||i===Oe)&&zt.get(A[a])===kt||i===Mr||B===Mr||i===vr||[CA,Pt,ue].indexOf(i)===-1&&B===vr||[ve,ie,vo,NA,GA].indexOf(B)!==-1||Nr(n,e)===ae||mt(Ft,ae,n,e)||mt([ve,ie],_t,n,e)||mt(Tr,Tr,n,e))return b;if(i===CA)return Re;if(i===Ft||B===Ft)return b;if(B===Xt||i===Xt)return Re;if([Pt,ue,_t].indexOf(B)!==-1||i===Mo||c===Yt&&Go.indexOf(i)!==-1||i===GA&&B===Yt||B===Or||wA.indexOf(B)!==-1&&i===q||wA.indexOf(i)!==-1&&B===q||i===de&&[Ie,Te,Oe].indexOf(B)!==-1||[Ie,Te,Oe].indexOf(i)!==-1&&B===we||wA.indexOf(i)!==-1&&Rr.indexOf(B)!==-1||Rr.indexOf(i)!==-1&&wA.indexOf(B)!==-1||[de,we].indexOf(i)!==-1&&(B===q||[ae,ue].indexOf(B)!==-1&&e[a+1]===q)||[ae,ue].indexOf(i)!==-1&&B===q||i===q&&[q,GA,NA].indexOf(B)!==-1)return b;if([q,GA,NA,ve,ie].indexOf(B)!==-1)for(var l=n;l>=0;){var h=e[l];if(h===q)return b;if([GA,NA].indexOf(h)!==-1)l--;else break}if([de,we].indexOf(B)!==-1)for(var l=[ve,ie].indexOf(i)!==-1?o:n;l>=0;){var h=e[l];if(h===q)return b;if([GA,NA].indexOf(h)!==-1)l--;else break}if(Zt===i&&[Zt,ze,Wt,Jt].indexOf(B)!==-1||[ze,Wt].indexOf(i)!==-1&&[ze,$e].indexOf(B)!==-1||[$e,Jt].indexOf(i)!==-1&&B===$e||Vr.indexOf(i)!==-1&&[Or,we].indexOf(B)!==-1||Vr.indexOf(B)!==-1&&i===de||wA.indexOf(i)!==-1&&wA.indexOf(B)!==-1||i===NA&&wA.indexOf(B)!==-1||wA.concat(q).indexOf(i)!==-1&&B===ae&&Vo.indexOf(A[a])===-1||wA.concat(q).indexOf(B)!==-1&&i===ie)return b;if(i===pt&&B===pt){for(var g=t[n],u=1;g>0&&(g--,e[g]===pt);)u++;if(u%2!==0)return b}return i===Te&&B===Oe?b:Re},Xo=function(A,e){e||(e={lineBreak:"normal",wordBreak:"normal"});var t=ko(A,e.lineBreak),r=t[0],s=t[1],n=t[2];(e.wordBreak==="break-all"||e.wordBreak==="break-word")&&(s=s.map(function(a){return[q,xA,Ns].indexOf(a)!==-1?Ie:a}));var o=e.wordBreak==="keep-all"?n.map(function(a,i){return a&&A[i]>=19968&&A[i]<=40959}):void 0;return[r,s,o]},_o=(function(){function A(e,t,r,s){this.codePoints=e,this.required=t===Gs,this.start=r,this.end=s}return A.prototype.slice=function(){return R.apply(void 0,this.codePoints.slice(this.start,this.end))},A})(),Wo=function(A,e){var t=at(A),r=Xo(t,e),s=r[0],n=r[1],o=r[2],a=t.length,i=0,c=0;return{next:function(){if(c>=a)return{done:!0,value:null};for(var B=b;c{let t=A[e];if(t===void 0)throw new Error(`Missing element at index ${e}`);return t},Gr=65533,J=A=>A>=48&&A<=57,Jo=A=>A>=55296&&A<=57343,kA=A=>J(A)||A>=65&&A<=70||A>=97&&A<=102,Yo=A=>A>=97&&A<=122,Zo=A=>A>=65&&A<=90,zo=A=>Yo(A)||Zo(A),$o=A=>A>=128,Ve=A=>A===10||A===9||A===32,et=A=>zo(A)||$o(A)||A===95,kr=A=>et(A)||J(A)||A===45,qo=A=>A>=0&&A<=8||A===11||A>=14&&A<=31||A===127,QA=(A,e)=>A!==92?!1:e!==10,Ne=(A,e,t)=>A===45?et(e)||QA(e,t):et(A)?!0:!!(A===92&&QA(A,e)),Et=(A,e,t)=>A===43||A===45?J(e)?!0:e===46&&J(t):J(A===46?e:A),jo=A=>{let e=0,t=1;(A[e]===43||A[e]===45)&&(A[e]===45&&(t=-1),e++);let r=[];for(;J(A[e]??NaN);)r.push(w(A,e)),e++;let s=r.length?parseInt(R(...r),10):0;A[e]===46&&e++;let n=[];for(;J(A[e]??NaN);)n.push(w(A,e)),e++;let o=n.length,a=o?parseInt(R(...n),10):0;(A[e]===69||A[e]===101)&&e++;let i=1;(A[e]===43||A[e]===45)&&(A[e]===45&&(i=-1),e++);let c=[];for(;J(A[e]??NaN);)c.push(w(A,e)),e++;let B=c.length?parseInt(R(...c),10):0;return t*(s+a*Math.pow(10,-o))*Math.pow(10,i*B)},Ai={type:2},ei={type:3},ti={type:4},ri={type:13},si={type:8},ni={type:21},oi={type:9},ii={type:10},ai={type:11},ci={type:12},Bi={type:14},Ge={type:23},li={type:1},hi={type:25},gi={type:24},ui={type:26},wi={type:27},di={type:28},Qi={type:29},fi={type:31},qt={type:32},jt=class zA{static{this._pool=[]}static{this.MAX_POOL_SIZE=40}static get(){return zA._pool.pop()||new zA}static release(e){zA._pool.length"u"?-1:e}reconsumeCodePoint(e){this._value.unshift(e)}peekCodePoint(e){if(e>=this._value.length)return-1;let t=this._value[e];return t!==void 0?t:-1}consumeUnicodeRangeToken(){let e=[],t=this.consumeCodePoint();for(;kA(t)&&e.length<6;)e.push(t),t=this.consumeCodePoint();let r=!1;for(;t===63&&e.length<6;)e.push(t),t=this.consumeCodePoint(),r=!0;if(r)return{type:30,start:parseInt(R(...e.map(n=>n===63?48:n)),16),end:parseInt(R(...e.map(n=>n===63?70:n)),16)};let s=parseInt(R(...e),16);if(t===45&&kA(this.peekCodePoint(0))){t=this.consumeCodePoint();let n=[];for(;kA(t)&&n.length<6;)n.push(t),t=this.consumeCodePoint();return{type:30,start:s,end:parseInt(R(...n),16)}}else return{type:30,start:s,end:s}}consumeIdentLikeToken(){let e=this.consumeName();return e.toLowerCase()==="url"&&this.peekCodePoint(0)===40?(this.consumeCodePoint(),this.consumeUrlToken()):this.peekCodePoint(0)===40?(this.consumeCodePoint(),{type:19,value:e}):{type:20,value:e}}consumeUrlToken(){let e=[];if(this.consumeWhiteSpace(),this.peekCodePoint(0)===-1)return{type:22,value:""};let t=this.peekCodePoint(0);if(t===39||t===34){let r=this.consumeStringToken(this.consumeCodePoint());return r.type===0&&(this.consumeWhiteSpace(),this.peekCodePoint(0)===-1||this.peekCodePoint(0)===41)?(this.consumeCodePoint(),{type:22,value:r.value}):(this.consumeBadUrlRemnants(),Ge)}for(;;){let r=this.consumeCodePoint();if(r===-1||r===41)return{type:22,value:R(...e)};if(Ve(r))return this.consumeWhiteSpace(),this.peekCodePoint(0)===-1||this.peekCodePoint(0)===41?(this.consumeCodePoint(),{type:22,value:R(...e)}):(this.consumeBadUrlRemnants(),Ge);if(r===34||r===39||r===40||qo(r))return this.consumeBadUrlRemnants(),Ge;if(r===92)if(QA(r,this.peekCodePoint(0)))e.push(this.consumeEscapedCodePoint());else return this.consumeBadUrlRemnants(),Ge;else e.push(r)}}consumeWhiteSpace(){for(;Ve(this.peekCodePoint(0));)this.consumeCodePoint()}consumeBadUrlRemnants(){for(;;){let e=this.consumeCodePoint();if(e===41||e===-1)return;QA(e,this.peekCodePoint(0))&&this.consumeEscapedCodePoint()}}consumeStringSlice(e){let r="";for(;e>0;){let s=Math.min(5e4,e);r+=R(...this._value.splice(0,s)),e-=s}return this._value.shift(),r}consumeStringToken(e){let t="",r=0;do{let s=this._value[r];if(s===-1||s===void 0||s===e)return t+=this.consumeStringSlice(r),{type:0,value:t};if(s===10)return this._value.splice(0,r),li;if(s===92){let n=this._value[r+1];n!==-1&&n!==void 0&&(n===10?(t+=this.consumeStringSlice(r),r=-1,this._value.shift()):QA(s,n)&&(t+=this.consumeStringSlice(r),t+=R(this.consumeEscapedCodePoint()),r=-1))}r++}while(!0)}consumeNumber(){let e=[],t=4,r=this.peekCodePoint(0);for((r===43||r===45)&&e.push(this.consumeCodePoint());J(this.peekCodePoint(0));)e.push(this.consumeCodePoint());r=this.peekCodePoint(0);let s=this.peekCodePoint(1);if(r===46&&J(s))for(e.push(this.consumeCodePoint(),this.consumeCodePoint()),t=8;J(this.peekCodePoint(0));)e.push(this.consumeCodePoint());r=this.peekCodePoint(0),s=this.peekCodePoint(1);let n=this.peekCodePoint(2);if((r===69||r===101)&&((s===43||s===45)&&J(n)||J(s)))for(e.push(this.consumeCodePoint(),this.consumeCodePoint()),t=8;J(this.peekCodePoint(0));)e.push(this.consumeCodePoint());return[jo(e),t]}consumeNumericToken(){let[e,t]=this.consumeNumber(),r=this.peekCodePoint(0),s=this.peekCodePoint(1),n=this.peekCodePoint(2);return Ne(r,s,n)?{type:15,number:e,flags:t,unit:this.consumeName()}:r===37?(this.consumeCodePoint(),{type:16,number:e,flags:t}):{type:17,number:e,flags:t}}consumeEscapedCodePoint(){let e=this.consumeCodePoint();if(kA(e)){let t=R(e);for(;kA(this.peekCodePoint(0))&&t.length<6;)t+=R(this.consumeCodePoint());Ve(this.peekCodePoint(0))&&this.consumeCodePoint();let r=parseInt(t,16);return r===0||Jo(r)||r>1114111?Gr:r}return e===-1?Gr:e}consumeName(){let e="";for(;;){let t=this.consumeCodePoint();if(kr(t))e+=R(t);else if(QA(t,this.peekCodePoint(0)))e+=R(this.consumeEscapedCodePoint());else return this.reconsumeCodePoint(t),e}}},Ps=class qe{constructor(e){this._tokens=e}static create(e){let t=new jt;return t.write(e),new qe(t.read())}static parseValue(e){return qe.create(e).parseComponentValue()}static parseValues(e){return qe.create(e).parseComponentValues()}parseComponentValue(){let e=this.consumeToken();for(;e.type===31;)e=this.consumeToken();if(e.type===32)throw new SyntaxError("Error parsing CSS component value, unexpected EOF");this.reconsumeToken(e);let t=this.consumeComponentValue();do e=this.consumeToken();while(e.type===31);if(e.type===32)return t;throw new SyntaxError("Error parsing CSS component value, multiple values found when expecting only one")}parseComponentValues(){let e=[];for(;;){let t=this.consumeComponentValue();if(t.type===32)return e;e.push(t)}}consumeComponentValue(){let e=this.consumeToken();switch(e.type){case 11:case 28:case 2:return this.consumeSimpleBlock(e.type);case 19:return this.consumeFunction(e)}return e}consumeSimpleBlock(e){let t={type:e,values:[]},r=this.consumeToken();for(;;){if(r.type===32||Ui(r,e))return t;this.reconsumeToken(r),t.values.push(this.consumeComponentValue()),r=this.consumeToken()}}consumeFunction(e){let t={name:e.value,values:[],type:18};for(;;){let r=this.consumeToken();if(r.type===32||r.type===3)return t;this.reconsumeToken(r),t.values.push(this.consumeComponentValue())}}consumeToken(){let e=this._tokens.shift();return typeof e>"u"?qt:e}reconsumeToken(e){this._tokens.unshift(e)}},z=A=>A.type===15,v=A=>A.type===17,H=A=>A.type===20,Ci=A=>A.type===0,be=(A,e)=>H(A)&&A.value===e,ee=A=>A.type!==31,G=A=>A.type!==31&&A.type!==4,tA=A=>{let e=[],t=[];return A.forEach(r=>{if(r.type===4){t.length&&(e.push(t),t=[]);return}r.type!==31&&t.push(r)}),t.length&&e.push(t),e},Ui=(A,e)=>e===11&&A.type===12||e===28&&A.type===29?!0:e===2&&A.type===3,Fi=/(\d+(?:\.\d+)?|[+\-*/()])/g,Xs=A=>{let e=A.match(Fi);if(!e)return NaN;let t=[],r=[],s={"+":1,"-":1,"*":2,"/":2};for(let o of e)if(/^\d+(?:\.\d+)?$/.test(o))t.push(parseFloat(o));else if(o==="(")r.push(o);else if(o===")"){for(;r.length&&r[r.length-1]!=="(";)t.push(r.pop());if(!r.length)return NaN;r.pop()}else{for(;r.length&&(s[w(r,r.length-1)]??0)>=(s[o]??0);)t.push(r.pop());r.push(o)}for(;r.length;){let o=r.pop();if(o==="(")return NaN;t.push(o)}let n=[];for(let o of t)if(typeof o=="number")n.push(o);else{let a=n.pop(),i=n.pop();if(i===void 0||a===void 0)return NaN;switch(o){case"+":n.push(i+a);break;case"-":n.push(i-a);break;case"*":n.push(i*a);break;case"/":n.push(a===0?NaN:i/a);break;default:return NaN}}return n.length===1?n[0]??NaN:NaN},T=(A,e,t)=>Math.min(Math.max(A,e),t),Z=(A,e)=>[A[0]*e[0]+A[1]*e[1]+A[2]*e[2],A[3]*e[0]+A[4]*e[1]+A[5]*e[2],A[6]*e[0]+A[7]*e[1]+A[8]*e[2]],EA=A=>Z([3.2409699419045226,-1.537383177570094,-.4986107602930034,-.9692436362808796,1.8759675015077202,.04155505740717559,.05563007969699366,-.20397695888897652,1.0569715142428786],A),_s=A=>Z([.41239079926595934,.357584339383878,.1804807884018343,.21263900587151027,.715168678767756,.07219231536073371,.01933081871559182,.11919477979462598,.9505321522496607],A),TA=A=>{let[e,t,r]=A,s=n=>{let o=n<0?-1:1,a=Math.abs(n);return a>.0031308?o*(1.055*a**(1/2.4)-.055):12.92*n};return[s(e),s(t),s(r)]},Ws=A=>{let[e,t,r]=A,s=n=>{let o=n<0?-1:1,a=Math.abs(n);return a<=.04045?n/12.92:o*((a+.055)/1.055)**2.4};return[s(e),s(t),s(r)]},pi=A=>{let[e,t,r]=TA(EA([A[0],A[1],A[2]]));return[e,t,r,A[3]]},mi=A=>{let[e,t,r]=EA([A[0],A[1],A[2]]);return[T(Math.round(e*255),0,255),T(Math.round(t*255),0,255),T(Math.round(r*255),0,255),A[3]]},pA=A=>A.type===17||A.type===15,x=A=>A.type===16||pA(A)||Js(A),Js=A=>A.type===17&&A._calcPercentage!==void 0,Ei=A=>A.type===18&&A.name==="calc",Hi=A=>{let e=Pr(A,0);if(!e)return null;let t=Pr(A,100);if(!t)return null;let r=e.number,s=t.number-r;return s===0?e:{type:17,number:r,flags:4,_calcPercentage:s,_calcPixelOffset:r}},Ys=A=>Ei(A)?Hi(A):x(A)?A:null,Pr=(A,e=0)=>{let t=r=>{let s="";for(let n of r)if(n.type!==31){if(n.type===18)if(n.name==="calc"){let o=t(n.values);if(o===null)return null;s+=`(${o})`}else return null;else if(n.type===17)s+=n.number.toString();else if(n.type===15)n.unit==="px"?s+=n.number.toString():n.unit==="rem"||n.unit==="em"?s+=(n.number*16).toString():s+=n.number.toString();else if(n.type===16)s+=(n.number/100*e).toString();else if(n.type===6){let o=n.value;o==="+"||o==="-"||o==="*"||o==="/"?s+=` ${o} `:o==="("?s+="(":o===")"&&(s+=")")}}return s};try{let r=t(A.values);if(r===null||r.trim()==="")return null;let s=Xs(r);if(typeof s=="number"&&!isNaN(s))return{type:17,number:s,flags:4}}catch{return null}return null},Zs=A=>A.length>1?[w(A,0),w(A,1)]:[w(A,0)],M={type:17,number:0,flags:4},AA={type:16,number:50,flags:4},eA={type:16,number:100,flags:4},Qe=(A,e,t)=>{let[r,s]=A;return[m(r,e),m(typeof s<"u"?s:r,t)]},m=(A,e)=>{if(Js(A))return A._calcPercentage/100*e+A._calcPixelOffset;if(A.type===16)return A.number/100*e;if(z(A))switch(A.unit){case"rem":case"em":return 16*A.number;default:return A.number}return A.number},zs="deg",$s="grad",qs="rad",js="turn",OA={name:"angle",parse:(A,e)=>{if(e.type===15)switch(e.unit){case zs:return Math.PI*e.number/180;case $s:return Math.PI/200*e.number;case qs:return e.number;case js:return Math.PI*2*e.number}throw new Error("Unsupported angle type")}},An=A=>A.type===15&&(A.unit===zs||A.unit===$s||A.unit===qs||A.unit===js),en=A=>{switch(A.filter(H).map(e=>e.value).join(" ")){case"to bottom right":case"to right bottom":case"left top":case"top left":return[M,M];case"to top":case"bottom":return nA(0);case"to bottom left":case"to left bottom":case"right top":case"top right":return[M,eA];case"to right":case"left":return nA(90);case"to top left":case"to left top":case"right bottom":case"bottom right":return[eA,eA];case"to bottom":case"top":return nA(180);case"to top right":case"to right top":case"left bottom":case"bottom left":return[eA,M];case"to left":case"right":return nA(270)}return 0},nA=A=>Math.PI*A/180,BA=A=>(255&A)===0,L=A=>{let e=255&A,t=255&A>>8,r=255&A>>16,s=255&A>>24;return e<255?`rgba(${s},${r},${t},${e/255})`:`rgb(${s},${r},${t})`},gA=(A,e,t,r)=>(A<<24|e<<16|t<<8|Math.round(r*255)<<0)>>>0,sA=(A,e)=>{if(A.type===17)return A.number;if(A.type===16){let t=e===3?1:255;return e===3?A.number/100*t:Math.round(A.number/100*t)}return 0},RA=A=>{let e=A[0];return(e&&e.type===20?e.value:"unknown")==="from"},yi=A=>gA(T(Math.round(A[0]*255),0,255),T(Math.round(A[1]*255),0,255),T(Math.round(A[2]*255),0,255),T(A[3],0,1)),Ur=A=>{let[e,t,r,s]=A,n=TA([e,t,r]);return gA(T(Math.round(n[0]*255),0,255),T(Math.round(n[1]*255),0,255),T(Math.round(n[2]*255),0,255),s)},Ke=A=>{let e=EA([A[0],A[1],A[2]]);return Ur([e[0],e[1],e[2],A[3]])},Ii=(A,e)=>{if(RA(e.filter(G)))throw new Error("Relative color not supported for lab()");let[t,r,s,n]=ct(e),o=TA(EA(ht([t,r,s])));return gA(T(Math.round(o[0]*255),0,255),T(Math.round(o[1]*255),0,255),T(Math.round(o[2]*255),0,255),n)},bi=(A,e)=>{if(RA(e.filter(G)))throw new Error("Relative color not supported for oklab()");let[t,r,s,n]=ct(e),o=TA(EA(lt([t,r,s])));return gA(T(Math.round(o[0]*255),0,255),T(Math.round(o[1]*255),0,255),T(Math.round(o[2]*255),0,255),n)},xi=(A,e)=>{if(RA(e.filter(G)))throw new Error("Relative color not supported for oklch()");let[t,r,s,n]=sn(e),o=TA(EA(lt(Bt([t,r,s]))));return gA(T(Math.round(o[0]*255),0,255),T(Math.round(o[1]*255),0,255),T(Math.round(o[2]*255),0,255),n)},Li=(A,e)=>{if(RA(e.filter(G)))throw new Error("Relative color not supported for lch()");let[t,r,s,n]=rn(e),o=TA(EA(ht(Bt([t,r,s]))));return gA(T(Math.round(o[0]*255),0,255),T(Math.round(o[1]*255),0,255),T(Math.round(o[2]*255),0,255),n)},tn=(A,e)=>{let t=e.filter(G),r=t[0],s=t[1],n=t[2],o=t[3];return[r?(r.type===17?nA(r.number):OA.parse(A,r))/(Math.PI*2):0,s!==void 0&&x(s)?s.number/100:0,n!==void 0&&x(n)?n.number/100:0,o!==void 0&&x(o)?m(o,1):1]},Xr=(A,e)=>{if(RA(e))throw new Error("Relative color not supported for hsl()");let[t,r,s,n]=tn(A,e),o=on([t,r,s]);return gA(o[0]*255,o[1]*255,o[2]*255,r===0?1:n)},rn=A=>{let e=A.filter(G),t=e[0],r=e[1],s=e[2],n=e[4];return[t!==void 0&&x(t)?t.number:0,r!==void 0&&x(r)?r.number:0,s!==void 0&&(v(s)||z(s))?s.number:0,n!==void 0&&x(n)?m(n,1):1]},ct=A=>{let e=A.filter(G),t=e[0],r=e[1],s=e[2],n=e[4];return[t!==void 0?t.type===16?t.number/100:v(t)?t.number:0:0,r!==void 0?r.type===16?r.number/100:v(r)?r.number:0:0,s!==void 0&&(v(s)||z(s))?s.number:0,n!==void 0&&x(n)?m(n,1):1]},sn=A=>{let e=A.filter(G),t=e[0],r=e[1],s=e[2],n=e[4];return[t!==void 0?t.type===16?t.number/100:v(t)?t.number:0:0,r!==void 0?r.type===16?r.number/100:v(r)?r.number:0:0,s!==void 0&&(v(s)||z(s))?s.number:0,n!==void 0&&x(n)?m(n,1):1]},nn=A=>Z([1.0479297925449969,.022946870601609652,-.05019226628920524,.02962780877005599,.9904344267538799,-.017073799063418826,-.009243040646204504,.015055191490298152,.7518742814281371],A),Fr=A=>Z([.955473421488075,-.02309845494876471,.06325924320057072,-.0283697093338637,1.0099953980813041,.021041441191917323,.012314014864481998,-.020507649298898964,1.330365926242124],A),Ht=(A,e,t)=>(t<0&&(t+=1),t>=1&&(t-=1),t<1/6?(e-A)*t*6+A:t<1/2?e:t<2/3?(e-A)*6*(2/3-t)+A:A),on=([A,e,t])=>{if(e===0)return[t*255,t*255,t*255];let r=t<=.5?t*(e+1):t+e-t*e,s=t*2-r;return[Ht(s,r,A+1/3),Ht(s,r,A),Ht(s,r,A-1/3)]},Bt=([A,e,t])=>(e<0&&(e=0),isNaN(t)&&(t=0),[A,e*Math.cos(t*Math.PI/180),e*Math.sin(t*Math.PI/180)]),lt=A=>{let e=Z([1,.3963377773761749,.2158037573099136,1,-.1055613458156586,-.0638541728258133,1,-.0894841775298119,-1.2914855480194092],A),t=[e[0]**3,e[1]**3,e[2]**3];return Z([1.2268798758459243,-.5578149944602171,.2813910456659647,-.0405757452148008,1.112286803280317,-.0717110580655164,-.0763729366746601,-.4214933324022432,1.5869240198367816],t)},ht=A=>{let e=(A[0]+16)/116,t=A[1]/500+e,r=e-A[2]/200,s=24389/27,n=24/116,o=[(t>n?t**3:(116*t-16)/s)*.3457/.3585,A[0]>8?e**3:A[0]/s,(r>n?r**3:(116*r-16)/s)*.2958/.3585];return Fr([o[0],o[1],o[2]])},Si=(A,e)=>{let t=e.filter(G);if(t.length===3||t.length===4){let r=sA(w(t,0),0),s=sA(w(t,1),1),n=sA(w(t,2),2),o=t.length===4?sA(w(t,3),3):1,a=Ws([r/255,s/255,n/255]),[i,c,B]=_s([a[0],a[1],a[2]]);return[i,c,B,o]}return[0,0,0,1]},Ki=(A,e)=>{let[t,r,s,n]=tn(A,e),o=Ws(on([t,r,s])),[a,i,c]=_s([o[0],o[1],o[2]]);return[a,i,c,n]},Di=(A,e)=>{let[t,r,s,n]=ct(e),[o,a,i]=ht([t,r,s]);return[o,a,i,n]},Mi=(A,e)=>{let[t,r,s,n]=rn(e),[o,a,i]=ht(Bt([t,r,s]));return[o,a,i,n]},vi=(A,e)=>{let[t,r,s,n]=sn(e),[o,a,i]=lt(Bt([t,r,s]));return[o,a,i,n]},Ti=(A,e)=>{let[t,r,s,n]=ct(e),[o,a,i]=lt([t,r,s]);return[o,a,i,n]},Oi=A=>Fr([A[0],A[1],A[2]]),_r=A=>A,Ri=A=>{let[e,t,r]=nn([A[0],A[2],A[3]]);return[e,t,r,A[3]]},Wr=A=>Ke([A[0],A[1],A[2],A[3]]),Vi=A=>{let e=Oi([A[0],A[1],A[2]]);return Ke([e[0],e[1],e[2],A[3]])},Ni=A=>Z([.4865709486482162,.26566769316909306,.1982172852343625,.2289745640697488,.6917385218365064,.079286914093745,0,.04511338185890264,1.043944368900976],A),Gi=A=>Z([2.493496911941425,-.9313836179191239,-.40271078445071684,-.8294889695615747,1.7626640603183463,.023624685841943577,.03584583024378447,-.07617238926804182,.9568845240076872],A),ki=A=>{let e=t=>{let r=t<0?-1:1;return t*r<=.04045?t/12.92:r*((t+.055)/1.055)**2.4||0};return[e(A[0]),e(A[1]),e(A[2])]},Pi=A=>TA(A),Xi=A=>{let e=ki([A[0],A[1],A[2]]);return Ni([e[0],e[1],e[2]])},_i=A=>{let[e,t,r]=Pi(Gi([A[0],A[1],A[2]]));return[e,t,r,A[3]]},Wi=A=>{let e=Xi([A[0],A[1],A[2]]);return Ke([e[0],e[1],e[2],A[3]])},Ji=A=>Z([2.0415879038107465,-.5650069742788596,-.34473135077832956,-.9692436362808795,1.8759675015077202,.04155505740717557,.013444280632031142,-.11836239223101838,1.0151749943912054],A),Yi=A=>Z([.5766690429101305,.1855582379065463,.1882286462349947,.29734497525053605,.6273635662554661,.0752914584939978,.02703136138641234,.07068885253582723,.9913375368376388],A),Zi=A=>{let e=A.map(t=>(t<0?-1:1)*Math.abs(t)**2.19921875);return[e[0]??0,e[1]??0,e[2]??0]},zi=A=>{let e=A.map(t=>(t<0?-1:1)*Math.abs(t)**.4547069271758437);return[e[0]??0,e[1]??0,e[2]??0]},$i=A=>{let[e,t,r]=zi(Ji([A[0],A[1],A[2]]));return[e,t,r,A[3]]},qi=A=>{let e=EA(Yi(Zi([A[0],A[1],A[2]])));return Ur([e[0],e[1],e[2],A[3]])},ji=A=>Z([.7977666449006423,.13518129740053308,.0313477341283922,.2880748288194013,.711835234241873,8993693872564e-17,0,0,.8251046025104602],A),Aa=A=>Z([1.3457868816471583,-.25557208737979464,-.05110186497554526,-.5446307051249019,1.5082477428451468,.02052744743642139,0,0,1.2119675456389452],A),ea=A=>{let[e,t,r]=A,s=n=>n<16/512?n/16:n**1.8;return[s(e),s(t),s(r)]},ta=A=>{let[e,t,r]=A,s=n=>n>1/512?n**(1/1.8):n*16;return[s(e),s(t),s(r)]},ra=A=>{let e=ea([A[0],A[1],A[2]]);return Fr(ji([e[0],e[1],e[2]]))},sa=A=>{let[e,t,r]=ta(Aa(nn([A[0],A[1],A[2]])));return[e,t,r,A[3]]},na=A=>{let e=ra([A[0],A[1],A[2]]);return Ke([e[0],e[1],e[2],A[3]])},Ar=1.09929682680944,an=.018053968510807,oa=A=>{let e=t=>t{let e=t=>t>=an?Ar*Math.pow(t,.45)-.09929682680944008:4.5*t;return[e(A[0]),e(A[1]),e(A[2])]},aa=A=>Z([.6369580483012914,.14461690358620832,.1688809751641721,.2627002120112671,.6779980715188708,.05930171646986196,0,.028072693049087428,1.060985057710791],A),ca=A=>Z([1.716651187971268,-.355670783776392,-.25336628137366,-.666684351832489,1.616481236634939,.0157685458139111,.017639857445311,-.042770613257809,.942103121235474],A),Ba=A=>{let e=oa([A[0],A[1],A[2]]);return aa([e[0],e[1],e[2]])},la=A=>{let[e,t,r]=ia(ca([A[0],A[1],A[2]]));return[e,t,r,A[3]]},ha=A=>{let e=Ba([A[0],A[1],A[2]]);return Ke([e[0],e[1],e[2],A[3]])},aA={name:"color",parse:(A,e)=>{if(e.type===18){let t=da[e.name];if(typeof t>"u")throw new Error(`Attempting to parse an unsupported color function "${e.name}"`);return t(A,e.values)}if(e.type===5){let[t,r,s,n]=cn(e);return gA(t,r,s,n)}if(e.type===20){let t=Bn[e.value.toUpperCase()];if(typeof t<"u")return t}return 0}},cn=A=>{if(A.value.length===3){let e=A.value.substring(0,1),t=A.value.substring(1,2),r=A.value.substring(2,3);return[parseInt(e+e,16),parseInt(t+t,16),parseInt(r+r,16),1]}if(A.value.length===4){let e=A.value.substring(0,1),t=A.value.substring(1,2),r=A.value.substring(2,3),s=A.value.substring(3,4);return[parseInt(e+e,16),parseInt(t+t,16),parseInt(r+r,16),parseInt(s+s,16)/255]}if(A.value.length===6){let e=A.value.substring(0,2),t=A.value.substring(2,4),r=A.value.substring(4,6);return[parseInt(e,16),parseInt(t,16),parseInt(r,16),1]}if(A.value.length===8){let e=A.value.substring(0,2),t=A.value.substring(2,4),r=A.value.substring(4,6),s=A.value.substring(6,8);return[parseInt(e,16),parseInt(t,16),parseInt(r,16),parseInt(s,16)/255]}return[0,0,0,1]},Jr=(A,e)=>{let t=e.filter(G);if(RA(t))throw new Error("Relative color not supported for rgb()");if(t.length===3||t.length===4){let r=sA(w(t,0),0),s=sA(w(t,1),1),n=sA(w(t,2),2),o=t.length===4?sA(w(t,3),3):1;return gA(r,s,n,o)}if(t.length===5){let r=w(t,3);if(r.type===6&&r.value==="/"){let s=sA(w(t,0),0),n=sA(w(t,1),1),o=sA(w(t,2),2),a=sA(w(t,4),3);return gA(s,n,o,a)}}return 0},ga=(A,e)=>{let t=e.filter(G),r=t[0],s=r&&r.type===20?r.value:"unknown";if(RA(t)){let n=(E,I)=>{if(v(I))return I.number;let S=D=>D==="r"||D==="x"?0:D==="g"||D==="y"?1:2;if(H(I)){let D=S(I.value);return w(E,D)}let y=D=>{let $=D.filter(G),W="(";for(let k of $)W+=k.type===18&&k.name==="calc"?y(k.values):v(k)?k.number:k.type===6||H(k)?k.value:"";return W+=")",W};if(I.type===18){let D=I.values.filter(G);if(I.name==="calc"){let $=y(D).replace(/r|x/,E[0].toString()).replace(/g|y/,E[1].toString()).replace(/b|z/,E[2].toString());return Xs($)}}return null},o=w(t,1),a=o.type===18?o.name:H(o)||o.type===5?"rgb":"unknown",i=w(t,2),c=H(i)?i.value:"unknown",B=o.type===18?o.values:H(o)?[o]:[];if(H(o)){if(typeof Bn[o.value.toUpperCase()]>"u")throw new Error("Attempting to use unknown color in relative color 'from'");{let E=jA(A,o.value),I=255&E,S=255&E>>8,y=255&E>>16;B=[{type:17,number:255&E>>24,flags:1},{type:17,number:y,flags:1},{type:17,number:S,flags:1},{type:17,number:I>1?I/255:I,flags:1}]}}else if(o.type===5){let[E,I,S,y]=cn(o);B=[{type:17,number:E,flags:1},{type:17,number:I,flags:1},{type:17,number:S,flags:1},{type:17,number:y>1?y/255:y,flags:1}]}if(B.length===0)throw new Error("Attempting to use unknown color in relative color 'from'");if(c==="unknown")throw new Error("Attempting to use unknown colorspace in relative color 'to'");let l=ua[a],h=wa[c],g=Yr[c];if(typeof l>"u")throw new Error(`Attempting to parse an unsupported color space "${a}" for color() function`);if(typeof h>"u")throw new Error(`Attempting to parse an unsupported color space "${c}" for color() function`);let u=h(l(A,B)),d=n(u,w(t,3)),Q=n(u,w(t,4)),f=n(u,w(t,5)),C=t[6],p=t[7],U=C!==void 0&&C.type===6&&C.value==="/"&&p!==void 0&&v(p)?p.number:1;if(d===null||Q===null||f===null)throw new Error("Invalid relative color in color() function");if(typeof g>"u")throw new Error(`Attempting to parse an unsupported color space "${c}" for color() function`);return g([d,Q,f,U])}else{let n=s,o=Yr[n];if(typeof o>"u")throw new Error(`Attempting to parse an unsupported color space "${n}" for color() function`);let a=w(t,1),i=w(t,2),c=w(t,3),B=t[4],l=t[5];return o([v(a)?a.number:0,v(i)?i.number:0,v(c)?c.number:0,B!==void 0&&B.type===6&&B.value==="/"&&l!==void 0&&v(l)?l.number:1])}},Yr={srgb:yi,"srgb-linear":Ur,"display-p3":Wi,"a98-rgb":qi,"prophoto-rgb":na,xyz:Wr,"xyz-d50":Vi,"xyz-d65":Wr,rec2020:ha},ua={rgb:Si,hsl:Ki,lab:Di,lch:Mi,oklab:Ti,oklch:vi},wa={srgb:pi,"srgb-linear":mi,"display-p3":_i,"a98-rgb":$i,"prophoto-rgb":sa,xyz:_r,"xyz-d50":Ri,"xyz-d65":_r,rec2020:la},da={hsl:Xr,hsla:Xr,rgb:Jr,rgba:Jr,lch:Li,oklch:xi,oklab:bi,lab:Ii,color:ga},jA=(A,e)=>aA.parse(A,Ps.create(e).parseComponentValue()),Bn={ALICEBLUE:4042850303,ANTIQUEWHITE:4209760255,AQUA:16777215,AQUAMARINE:2147472639,AZURE:4043309055,BEIGE:4126530815,BISQUE:4293182719,BLACK:255,BLANCHEDALMOND:4293643775,BLUE:65535,BLUEVIOLET:2318131967,BROWN:2771004159,BURLYWOOD:3736635391,CADETBLUE:1604231423,CHARTREUSE:2147418367,CHOCOLATE:3530104575,CORAL:4286533887,CORNFLOWERBLUE:1687547391,CORNSILK:4294499583,CRIMSON:3692313855,CYAN:16777215,DARKBLUE:35839,DARKCYAN:9145343,DARKGOLDENROD:3095837695,DARKGRAY:2846468607,DARKGREEN:6553855,DARKGREY:2846468607,DARKKHAKI:3182914559,DARKMAGENTA:2332068863,DARKOLIVEGREEN:1433087999,DARKORANGE:4287365375,DARKORCHID:2570243327,DARKRED:2332033279,DARKSALMON:3918953215,DARKSEAGREEN:2411499519,DARKSLATEBLUE:1211993087,DARKSLATEGRAY:793726975,DARKSLATEGREY:793726975,DARKTURQUOISE:13554175,DARKVIOLET:2483082239,DEEPPINK:4279538687,DEEPSKYBLUE:12582911,DIMGRAY:1768516095,DIMGREY:1768516095,DODGERBLUE:512819199,FIREBRICK:2988581631,FLORALWHITE:4294635775,FORESTGREEN:579543807,FUCHSIA:4278255615,GAINSBORO:3705462015,GHOSTWHITE:4177068031,GOLD:4292280575,GOLDENROD:3668254975,GRAY:2155905279,GREEN:8388863,GREENYELLOW:2919182335,GREY:2155905279,HONEYDEW:4043305215,HOTPINK:4285117695,INDIANRED:3445382399,INDIGO:1258324735,IVORY:4294963455,KHAKI:4041641215,LAVENDER:3873897215,LAVENDERBLUSH:4293981695,LAWNGREEN:2096890111,LEMONCHIFFON:4294626815,LIGHTBLUE:2916673279,LIGHTCORAL:4034953471,LIGHTCYAN:3774873599,LIGHTGOLDENRODYELLOW:4210742015,LIGHTGRAY:3553874943,LIGHTGREEN:2431553791,LIGHTGREY:3553874943,LIGHTPINK:4290167295,LIGHTSALMON:4288707327,LIGHTSEAGREEN:548580095,LIGHTSKYBLUE:2278488831,LIGHTSLATEGRAY:2005441023,LIGHTSLATEGREY:2005441023,LIGHTSTEELBLUE:2965692159,LIGHTYELLOW:4294959359,LIME:16711935,LIMEGREEN:852308735,LINEN:4210091775,MAGENTA:4278255615,MAROON:2147483903,MEDIUMAQUAMARINE:1724754687,MEDIUMBLUE:52735,MEDIUMORCHID:3126187007,MEDIUMPURPLE:2473647103,MEDIUMSEAGREEN:1018393087,MEDIUMSLATEBLUE:2070474495,MEDIUMSPRINGGREEN:16423679,MEDIUMTURQUOISE:1221709055,MEDIUMVIOLETRED:3340076543,MIDNIGHTBLUE:421097727,MINTCREAM:4127193855,MISTYROSE:4293190143,MOCCASIN:4293178879,NAVAJOWHITE:4292783615,NAVY:33023,OLDLACE:4260751103,OLIVE:2155872511,OLIVEDRAB:1804477439,ORANGE:4289003775,ORANGERED:4282712319,ORCHID:3664828159,PALEGOLDENROD:4008225535,PALEGREEN:2566625535,PALETURQUOISE:2951671551,PALEVIOLETRED:3681588223,PAPAYAWHIP:4293907967,PEACHPUFF:4292524543,PERU:3448061951,PINK:4290825215,PLUM:3718307327,POWDERBLUE:2967529215,PURPLE:2147516671,REBECCAPURPLE:1714657791,RED:4278190335,ROSYBROWN:3163525119,ROYALBLUE:1097458175,SADDLEBROWN:2336560127,SALMON:4202722047,SANDYBROWN:4104413439,SEAGREEN:780883967,SEASHELL:4294307583,SIENNA:2689740287,SILVER:3233857791,SKYBLUE:2278484991,SLATEBLUE:1784335871,SLATEGRAY:1887473919,SLATEGREY:1887473919,SNOW:4294638335,SPRINGGREEN:16744447,STEELBLUE:1182971135,TAN:3535047935,TEAL:8421631,THISTLE:3636451583,TOMATO:4284696575,TRANSPARENT:0,TURQUOISE:1088475391,VIOLET:4001558271,WHEAT:4125012991,WHITE:4294967295,WHITESMOKE:4126537215,YELLOW:4294902015,YELLOWGREEN:2597139199},SA=A=>A.nodeType===Node.ELEMENT_NODE,ln=A=>A.nodeType===Node.TEXT_NODE,DA=A=>typeof A.className=="object",xe=A=>SA(A)&&typeof A.style<"u"&&!DA(A),Qa=A=>A.tagName==="INPUT",fa=A=>A.tagName==="HTML",hn=A=>A.tagName==="svg",pr=A=>A.tagName==="BODY",gn=A=>A.tagName==="CANVAS",Zr=A=>A.tagName==="VIDEO",er=A=>A.tagName==="IMG",un=A=>A.tagName==="IFRAME",wn=A=>A.tagName==="STYLE",Ca=A=>A.tagName==="SCRIPT",tt=A=>A.tagName==="TEXTAREA",rt=A=>A.tagName==="SELECT",fe=A=>A.tagName==="SLOT",Ua=A=>A.tagName==="LI",Fa=A=>A.tagName==="OL",zr=A=>!DA(A)&&A.tagName.indexOf("-")>0,pa=new Set(["IMG","VIDEO","AUDIO","CANVAS","IFRAME","INPUT","TEXTAREA","SELECT","BR","HR","META","LINK","BASE","COL","SOURCE","TRACK","WBR","AREA","PARAM","EMBED","OBJECT"]),ma=A=>!DA(A)&&!pa.has(A.tagName),tr={name:"list-style-type",initialValue:"none",prefix:!1,type:2,parse:(A,e)=>{switch(e){case"disc":return 0;case"circle":return 1;case"square":return 2;case"decimal":return 3;case"cjk-decimal":return 4;case"decimal-leading-zero":return 5;case"lower-roman":return 6;case"upper-roman":return 7;case"lower-greek":return 8;case"lower-alpha":return 9;case"upper-alpha":return 10;case"arabic-indic":return 11;case"armenian":return 12;case"bengali":return 13;case"cambodian":return 14;case"cjk-earthly-branch":return 15;case"cjk-heavenly-stem":return 16;case"cjk-ideographic":return 17;case"devanagari":return 18;case"ethiopic-numeric":return 19;case"georgian":return 20;case"gujarati":return 21;case"gurmukhi":return 22;case"hebrew":return 52;case"hiragana":return 23;case"hiragana-iroha":return 24;case"japanese-formal":return 25;case"japanese-informal":return 26;case"kannada":return 27;case"katakana":return 28;case"katakana-iroha":return 29;case"khmer":return 30;case"korean-hangul-formal":return 31;case"korean-hanja-formal":return 32;case"korean-hanja-informal":return 33;case"lao":return 34;case"lower-armenian":return 35;case"malayalam":return 36;case"mongolian":return 37;case"myanmar":return 38;case"oriya":return 39;case"persian":return 40;case"simp-chinese-formal":return 41;case"simp-chinese-informal":return 42;case"tamil":return 43;case"telugu":return 44;case"thai":return 45;case"tibetan":return 46;case"trad-chinese-formal":return 47;case"trad-chinese-informal":return 48;case"upper-armenian":return 49;case"disclosure-open":return 50;case"disclosure-closed":return 51;default:return-1}}},P=(A,e)=>(A&e)!==0,Ea=class{constructor(){this.counters={}}getCounterValue(A){let e=this.counters[A];return e&&e.length?w(e,e.length-1):1}getCounterValues(A){let e=this.counters[A];return e||[]}pop(A){A.forEach(e=>this.counters[e]?.pop())}parse(A){let e=A.counterIncrement,t=A.counterReset,r=!0;e!==null&&e.forEach(n=>{let o=this.counters[n.counter];if(o&&n.increment!==0){r=!1,o.length||o.push(1);let a=Math.max(0,o.length-1);o[a]=(o[a]??0)+n.increment}});let s=[];return r&&t.forEach(n=>{let o=this.counters[n.counter];s.push(n.counter),o||(o=this.counters[n.counter]=[]),o.push(n.reset)}),s}},$r={integers:[1e3,900,500,400,100,90,50,40,10,9,5,4,1],values:["M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"]},qr={integers:[9e3,8e3,7e3,6e3,5e3,4e3,3e3,2e3,1e3,900,800,700,600,500,400,300,200,100,90,80,70,60,50,40,30,20,10,9,8,7,6,5,4,3,2,1],values:["\u0554","\u0553","\u0552","\u0551","\u0550","\u054F","\u054E","\u054D","\u054C","\u054B","\u054A","\u0549","\u0548","\u0547","\u0546","\u0545","\u0544","\u0543","\u0542","\u0541","\u0540","\u053F","\u053E","\u053D","\u053C","\u053B","\u053A","\u0539","\u0538","\u0537","\u0536","\u0535","\u0534","\u0533","\u0532","\u0531"]},Ha={integers:[1e4,9e3,8e3,7e3,6e3,5e3,4e3,3e3,2e3,1e3,400,300,200,100,90,80,70,60,50,40,30,20,19,18,17,16,15,10,9,8,7,6,5,4,3,2,1],values:["\u05D9\u05F3","\u05D8\u05F3","\u05D7\u05F3","\u05D6\u05F3","\u05D5\u05F3","\u05D4\u05F3","\u05D3\u05F3","\u05D2\u05F3","\u05D1\u05F3","\u05D0\u05F3","\u05EA","\u05E9","\u05E8","\u05E7","\u05E6","\u05E4","\u05E2","\u05E1","\u05E0","\u05DE","\u05DC","\u05DB","\u05D9\u05D8","\u05D9\u05D7","\u05D9\u05D6","\u05D8\u05D6","\u05D8\u05D5","\u05D9","\u05D8","\u05D7","\u05D6","\u05D5","\u05D4","\u05D3","\u05D2","\u05D1","\u05D0"]},ya={integers:[1e4,9e3,8e3,7e3,6e3,5e3,4e3,3e3,2e3,1e3,900,800,700,600,500,400,300,200,100,90,80,70,60,50,40,30,20,10,9,8,7,6,5,4,3,2,1],values:["\u10F5","\u10F0","\u10EF","\u10F4","\u10EE","\u10ED","\u10EC","\u10EB","\u10EA","\u10E9","\u10E8","\u10E7","\u10E6","\u10E5","\u10E4","\u10F3","\u10E2","\u10E1","\u10E0","\u10DF","\u10DE","\u10DD","\u10F2","\u10DC","\u10DB","\u10DA","\u10D9","\u10D8","\u10D7","\u10F1","\u10D6","\u10D5","\u10D4","\u10D3","\u10D2","\u10D1","\u10D0"]},PA=(A,e,t,r,s,n)=>At?Le(A,s,n.length>0):r.integers.reduce((o,a,i)=>{for(;A>=a;)A-=a,o+=r.values[i];return o},"")+n,dn=(A,e,t,r)=>{let s="";do t||A--,s=r(A)+s,A/=e;while(A*e>=e);return s},O=(A,e,t,r,s)=>{let n=t-e+1;return(A<0?"-":"")+(dn(Math.abs(A),n,r,o=>R(Math.floor(o%n)+e))+s)},yA=(A,e,t=". ")=>{let r=e.length;return dn(Math.abs(A),r,!1,s=>String(e[Math.floor(s%r)]))+t},Ia=1,ba=2,xa=4,La=8,dA=(A,e,t,r,s,n)=>{if(A<-9999||A>9999)return Le(A,4,s.length>0);let o=Math.abs(A),a=s;if(o===0)return e[0]+a;for(let i=0;o>0&&i<=4;i++){let c=o%10;c===0&&P(n,Ia)&&a!==""?a=e[c]+a:c>1||c===1&&i===0||c===1&&i===1&&P(n,ba)||c===1&&i===1&&P(n,xa)&&A>100||c===1&&i>1&&P(n,La)?a=(e[c]??"")+(i>0?t[i-1]??"":"")+a:c===1&&i>0&&(a=(t[i-1]??"")+a),o=Math.floor(o/10)}return(A<0?r:"")+a},jr="\u5341\u767E\u5343\u842C",As="\u62FE\u4F70\u4EDF\u842C",es="\u30DE\u30A4\u30CA\u30B9",yt="\uB9C8\uC774\uB108\uC2A4",Le=(A,e,t)=>{let r=t?". ":"",s=t?"\u3001":"",n=t?", ":"",o=t?" ":"";switch(e){case 0:return"\u2022"+o;case 1:return"\u25E6"+o;case 2:return"\u25FE"+o;case 5:let a=O(A,48,57,!0,r);return a.length<4?`0${a}`:a;case 4:return yA(A,"\u3007\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D",s);case 6:return PA(A,1,3999,$r,3,r).toLowerCase();case 7:return PA(A,1,3999,$r,3,r);case 8:return O(A,945,969,!1,r);case 9:return O(A,97,122,!1,r);case 10:return O(A,65,90,!1,r);case 11:return O(A,1632,1641,!0,r);case 12:case 49:return PA(A,1,9999,qr,3,r);case 35:return PA(A,1,9999,qr,3,r).toLowerCase();case 13:return O(A,2534,2543,!0,r);case 14:case 30:return O(A,6112,6121,!0,r);case 15:return yA(A,"\u5B50\u4E11\u5BC5\u536F\u8FB0\u5DF3\u5348\u672A\u7533\u9149\u620C\u4EA5",s);case 16:return yA(A,"\u7532\u4E59\u4E19\u4E01\u620A\u5DF1\u5E9A\u8F9B\u58EC\u7678",s);case 17:case 48:return dA(A,"\u96F6\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D",jr,"\u8CA0",s,14);case 47:return dA(A,"\u96F6\u58F9\u8CB3\u53C3\u8086\u4F0D\u9678\u67D2\u634C\u7396",As,"\u8CA0",s,15);case 42:return dA(A,"\u96F6\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D",jr,"\u8D1F",s,14);case 41:return dA(A,"\u96F6\u58F9\u8D30\u53C1\u8086\u4F0D\u9646\u67D2\u634C\u7396",As,"\u8D1F",s,15);case 26:return dA(A,"\u3007\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D","\u5341\u767E\u5343\u4E07",es,s,0);case 25:return dA(A,"\u96F6\u58F1\u5F10\u53C2\u56DB\u4F0D\u516D\u4E03\u516B\u4E5D","\u62FE\u767E\u5343\u4E07",es,s,7);case 31:return dA(A,"\uC601\uC77C\uC774\uC0BC\uC0AC\uC624\uC721\uCE60\uD314\uAD6C","\uC2ED\uBC31\uCC9C\uB9CC",yt,n,7);case 33:return dA(A,"\u96F6\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D","\u5341\u767E\u5343\u842C",yt,n,0);case 32:return dA(A,"\u96F6\u58F9\u8CB3\u53C3\u56DB\u4E94\u516D\u4E03\u516B\u4E5D","\u62FE\u767E\u5343",yt,n,7);case 18:return O(A,2406,2415,!0,r);case 20:return PA(A,1,19999,ya,3,r);case 21:return O(A,2790,2799,!0,r);case 22:return O(A,2662,2671,!0,r);case 52:return PA(A,1,10999,Ha,3,r);case 23:return yA(A,"\u3042\u3044\u3046\u3048\u304A\u304B\u304D\u304F\u3051\u3053\u3055\u3057\u3059\u305B\u305D\u305F\u3061\u3064\u3066\u3068\u306A\u306B\u306C\u306D\u306E\u306F\u3072\u3075\u3078\u307B\u307E\u307F\u3080\u3081\u3082\u3084\u3086\u3088\u3089\u308A\u308B\u308C\u308D\u308F\u3090\u3091\u3092\u3093");case 24:return yA(A,"\u3044\u308D\u306F\u306B\u307B\u3078\u3068\u3061\u308A\u306C\u308B\u3092\u308F\u304B\u3088\u305F\u308C\u305D\u3064\u306D\u306A\u3089\u3080\u3046\u3090\u306E\u304A\u304F\u3084\u307E\u3051\u3075\u3053\u3048\u3066\u3042\u3055\u304D\u3086\u3081\u307F\u3057\u3091\u3072\u3082\u305B\u3059");case 27:return O(A,3302,3311,!0,r);case 28:return yA(A,"\u30A2\u30A4\u30A6\u30A8\u30AA\u30AB\u30AD\u30AF\u30B1\u30B3\u30B5\u30B7\u30B9\u30BB\u30BD\u30BF\u30C1\u30C4\u30C6\u30C8\u30CA\u30CB\u30CC\u30CD\u30CE\u30CF\u30D2\u30D5\u30D8\u30DB\u30DE\u30DF\u30E0\u30E1\u30E2\u30E4\u30E6\u30E8\u30E9\u30EA\u30EB\u30EC\u30ED\u30EF\u30F0\u30F1\u30F2\u30F3",s);case 29:return yA(A,"\u30A4\u30ED\u30CF\u30CB\u30DB\u30D8\u30C8\u30C1\u30EA\u30CC\u30EB\u30F2\u30EF\u30AB\u30E8\u30BF\u30EC\u30BD\u30C4\u30CD\u30CA\u30E9\u30E0\u30A6\u30F0\u30CE\u30AA\u30AF\u30E4\u30DE\u30B1\u30D5\u30B3\u30A8\u30C6\u30A2\u30B5\u30AD\u30E6\u30E1\u30DF\u30B7\u30F1\u30D2\u30E2\u30BB\u30B9",s);case 34:return O(A,3792,3801,!0,r);case 37:return O(A,6160,6169,!0,r);case 38:return O(A,4160,4169,!0,r);case 39:return O(A,2918,2927,!0,r);case 40:return O(A,1776,1785,!0,r);case 43:return O(A,3046,3055,!0,r);case 44:return O(A,3174,3183,!0,r);case 45:return O(A,3664,3673,!0,r);case 46:return O(A,3872,3881,!0,r);default:return O(A,48,57,!0,r)}},Sa={name:"display",initialValue:"inline-block",prefix:!1,type:1,parse:(A,e)=>e.filter(H).reduce((t,r)=>t|Ka(r.value),0)},Ka=A=>{switch(A){case"block":case"-webkit-box":return 2;case"inline":return 4;case"run-in":return 8;case"flow":return 16;case"flow-root":return 32;case"table":return 64;case"flex":case"-webkit-flex":return 128;case"grid":case"-ms-grid":return 256;case"ruby":return 512;case"subgrid":return 1024;case"list-item":return 2048;case"table-row-group":return 4096;case"table-header-group":return 8192;case"table-footer-group":return 16384;case"table-row":return 32768;case"table-cell":return 65536;case"table-column-group":return 131072;case"table-column":return 262144;case"table-caption":return 524288;case"ruby-base":return 1048576;case"ruby-text":return 2097152;case"ruby-base-container":return 4194304;case"ruby-text-container":return 8388608;case"contents":return 16777216;case"inline-block":return 33554432;case"inline-list-item":return 67108864;case"inline-table":return 134217728;case"inline-flex":return 268435456;case"inline-grid":return 536870912}return 0},Da={name:"float",initialValue:"none",prefix:!1,type:2,parse:(A,e)=>{switch(e){case"left":return 1;case"right":return 2;case"inline-start":return 3;case"inline-end":return 4}return 0}},Ma={name:"overflow",initialValue:"visible",prefix:!1,type:1,parse:(A,e)=>e.filter(H).map(t=>{switch(t.value){case"hidden":return 1;case"scroll":return 2;case"clip":return 3;case"auto":return 4;default:return 0}})},va={name:"text-decoration-color",initialValue:"transparent",prefix:!1,type:3,format:"color"},Ta={name:"text-decoration-line",initialValue:"none",prefix:!1,type:1,parse:(A,e)=>e.filter(H).map(t=>{switch(t.value){case"underline":return 1;case"overline":return 2;case"line-through":return 3;case"none":return 4}return 0}).filter(t=>t!==0)},Oa={name:"content",initialValue:"none",type:1,prefix:!1,parse:(A,e)=>{if(e.length===0)return[];let t=e[0];return t&&t.type===20&&t.value==="none"?[]:e}},Ra={name:"quotes",initialValue:"none",prefix:!0,type:1,parse:(A,e)=>{if(e.length===0)return null;let t=e[0];if(t&&t.type===20&&t.value==="none")return null;let r=[],s=e.filter(Ci);if(s.length%2!==0)return null;for(let n=0;n{if(!A)return"";let r=A[Math.min(e,A.length-1)];return r?t?r.open:r.close:""},Qn=(A,e)=>{let t=[],r=A.filter(ee);for(let s=0;s{if(e.length===0)return null;let t=e[0];return t&&t.type===20&&t.value==="none"?null:Qn(e,1).map(([r,s])=>({counter:r,increment:s}))}},Na={name:"counter-reset",initialValue:"none",prefix:!0,type:1,parse:(A,e)=>e.length===0?[]:Qn(e,0).filter(([t])=>t!=="none").map(([t,r])=>({counter:t,reset:r}))},Ga={name:"background-clip",initialValue:"border-box",prefix:!1,type:1,parse:(A,e)=>e.map(t=>{if(H(t))switch(t.value){case"padding-box":return 1;case"content-box":return 2;case"text":return 3}return 0})},ka={name:"background-color",initialValue:"transparent",prefix:!1,type:3,format:"color"},De=(A,e)=>{let t=aA.parse(A,w(e,0)),r=e[1];return r&&x(r)?{color:t,stop:r}:{color:t,stop:null}},fA=(A,e)=>{let t=A.map(i=>({color:i.color,stop:i.stop})),r=w(t,0),s=w(t,t.length-1);r.stop===null&&(r.stop=M),s.stop===null&&(s.stop=eA);let n=[],o=0;for(let i=0;io?n.push(B):n.push(o),o=B}else n.push(null)}let a=null;for(let i=0;i({color:i,stop:Math.max(Math.min(1,n[c]/e),0)}))},Pa=(A,e,t)=>{let r=e/2,s=t/2,n=m(A[0],e)-r,o=s-m(A[1],t);return(Math.atan2(o,n)+Math.PI*2)%(Math.PI*2)},rr=(A,e,t)=>{let r=typeof A=="number"?A:Pa(A,e,t),s=Math.abs(e*Math.sin(r))+Math.abs(t*Math.cos(r)),n=e/2,o=t/2,a=s/2,i=Math.sin(r-Math.PI/2)*a,c=Math.cos(r-Math.PI/2)*a;return[s,n-c,n+c,o-i,o+i]},cA=(A,e)=>Math.sqrt(A*A+e*e),rs=(A,e,t,r,s)=>[[0,0],[0,e],[A,0],[A,e]].reduce((n,o)=>{let[a,i]=o,c=cA(t-a,r-i);return(s?cn.optimumDistance)?{optimumCorner:o,optimumDistance:c}:n},{optimumDistance:s?1/0:-1/0,optimumCorner:null}).optimumCorner,sr=(A,e,t,r,s)=>{let n=0,o=0;switch(A.size){case 0:A.shape===0?n=o=Math.min(Math.abs(e),Math.abs(e-r),Math.abs(t),Math.abs(t-s)):A.shape===1&&(n=Math.min(Math.abs(e),Math.abs(e-r)),o=Math.min(Math.abs(t),Math.abs(t-s)));break;case 2:if(A.shape===0)n=o=Math.min(cA(e,t),cA(e,t-s),cA(e-r,t),cA(e-r,t-s));else if(A.shape===1){let a=Math.min(Math.abs(t),Math.abs(t-s))/Math.min(Math.abs(e),Math.abs(e-r)),[i,c]=rs(r,s,e,t,!0);n=cA(i-e,(c-t)/a),o=a*n}break;case 1:A.shape===0?n=o=Math.max(Math.abs(e),Math.abs(e-r),Math.abs(t),Math.abs(t-s)):A.shape===1&&(n=Math.max(Math.abs(e),Math.abs(e-r)),o=Math.max(Math.abs(t),Math.abs(t-s)));break;case 3:if(A.shape===0)n=o=Math.max(cA(e,t),cA(e,t-s),cA(e-r,t),cA(e-r,t-s));else if(A.shape===1){let a=Math.max(Math.abs(t),Math.abs(t-s))/Math.max(Math.abs(e),Math.abs(e-r)),[i,c]=rs(r,s,e,t,!1);n=cA(i-e,(c-t)/a),o=a*n}}if(Array.isArray(A.size)){let a=A.size;n=m(w(a,0),r),o=a.length===2?m(w(a,1),s):n}return[n,o]},fn=(A,e)=>{let t=nA(180),r=[];return tA(e).forEach((s,n)=>{if(n===0){let a=s[0];if(a&&a.type===20&&a.value==="to"){t=en(s);return}else if(a&&An(a)){t=OA.parse(A,a);return}}let o=De(A,s);r.push(o)}),{angle:t,stops:r,type:1}},ke=(A,e)=>{let t=nA(180),r=[];return tA(e).forEach((s,n)=>{if(n===0){let a=s[0];if(a&&a.type===20&&["top","left","right","bottom"].indexOf(a.value)!==-1){t=en(s);return}else if(a&&An(a)){t=(OA.parse(A,a)+nA(270))%nA(360);return}}let o=De(A,s);r.push(o)}),{angle:t,stops:r,type:1}},Xa=(A,e)=>{let t=nA(180),r=[],s=1,n=0,o=3,a=[];return tA(e).forEach((i,c)=>{let B=i[0];if(B){if(c===0){if(H(B)&&B.value==="linear"){s=1;return}else if(H(B)&&B.value==="radial"){s=2;return}}if(B.type===18){if(B.name==="from"){let l=aA.parse(A,w(B.values,0));r.push({stop:M,color:l})}else if(B.name==="to"){let l=aA.parse(A,w(B.values,0));r.push({stop:eA,color:l})}else if(B.name==="color-stop"){let l=B.values.filter(G);if(l.length===2){let h=aA.parse(A,w(l,1)),g=w(l,0);v(g)&&r.push({stop:{type:16,number:g.number*100,flags:g.flags},color:h})}}}}}),s===1?{angle:(t+nA(180))%nA(360),stops:r,type:s}:{size:o,shape:n,stops:r,position:a,type:s}},Cn="closest-side",Un="farthest-side",Fn="closest-corner",pn="farthest-corner",mn="circle",En="ellipse",Hn="cover",yn="contain",In=(A,e)=>{let t=0,r=3,s=[],n=[];return tA(e).forEach((o,a)=>{let i=!0;if(a===0){let c=!1;i=o.reduce((B,l)=>{if(c)if(H(l))switch(l.value){case"center":return n.push(AA),B;case"top":case"left":return n.push(M),B;case"right":case"bottom":return n.push(eA),B}else(x(l)||pA(l))&&n.push(l);else if(H(l))switch(l.value){case mn:return t=0,!1;case En:return t=1,!1;case"at":return c=!0,!1;case Cn:return r=0,!1;case Hn:case Un:return r=1,!1;case yn:case Fn:return r=2,!1;case pn:return r=3,!1}else if(pA(l)||x(l))return Array.isArray(r)||(r=[]),r.push(l),!1;return B},i)}if(i){let c=De(A,o);s.push(c)}}),{size:r,shape:t,stops:s,position:n,type:2}},Pe=(A,e)=>{let t=0,r=3,s=[],n=[];return tA(e).forEach((o,a)=>{let i=!0;if(a===0?i=o.reduce((c,B)=>{if(H(B))switch(B.value){case"center":return n.push(AA),!1;case"top":case"left":return n.push(M),!1;case"right":case"bottom":return n.push(eA),!1}else if(x(B)||pA(B))return n.push(B),!1;return c},i):a===1&&(i=o.reduce((c,B)=>{if(H(B))switch(B.value){case mn:return t=0,!1;case En:return t=1,!1;case yn:case Cn:return r=0,!1;case Un:return r=1,!1;case Fn:return r=2,!1;case Hn:case pn:return r=3,!1}else if(pA(B)||x(B))return Array.isArray(r)||(r=[]),r.push(B),!1;return c},i)),i){let c=De(A,o);s.push(c)}}),{size:r,shape:t,stops:s,position:n,type:2}},ce=(A,e)=>({...fn(A,e),type:3}),It=(A,e)=>({...In(A,e),type:4}),bt=(A,e)=>{let t=0,r=[],s=[];return tA(e).forEach((n,o)=>{let a=!0;if(o===0){let i=!1,c=!1;a=n.reduce((B,l)=>{if(H(l))switch(l.value){case"from":return i=!0,c=!1,!1;case"at":return i=!1,c=!0,!1;case"center":return r.push(AA),B;case"top":case"left":return r.push(M),B;case"right":case"bottom":return r.push(eA),B}return i?(t=OA.parse(A,l),!1):(c&&x(l)&&r.push(l),B)},!0)}a&&n.length>0&&s.push(De(A,n))}),{type:5,angle:t,position:r,stops:s}},_a=A=>A&&(z(A)&&(A.unit==="dppx"||A.unit==="x")||v(A))?A.number:1,ss=(A,e)=>{let t=tA(e),r=A.config.window.devicePixelRatio||1,s=[];for(let a of t){let i=a.find(B=>B.type===22||B.type===18);if(!i)continue;let c=a.find(B=>z(B)||v(B));s.push({imageToken:i,resolution:_a(c)})}if(s.length===0)throw new Error("image-set() requires at least one image candidate");let n=s.filter(a=>a.resolution>=r).sort((a,i)=>a.resolution-i.resolution),o=w(n.length>0?n:s.slice().sort((a,i)=>i.resolution-a.resolution),0);return te.parse(A,o.imageToken)},Wa=A=>A.type===1,bn=A=>A.type===2,Ja=A=>A.type===3,xn=A=>A.type===4,Ln=A=>A.type===5,te={name:"image",parse:(A,e)=>{if(e.type===22){let t={url:e.value,type:0};return A.cache.addImage(e.value),t}if(e.type===18){let t=Sn[e.name];if(typeof t>"u")throw new Error(`Attempting to parse an unsupported image function "${e.name}"`);return t(A,e.values)}throw new Error(`Unsupported image type ${e.type}`)}};function mr(A){return!(A.type===20&&A.value==="none")&&(A.type!==18||!!Sn[A.name])}var Sn={"linear-gradient":fn,"-moz-linear-gradient":ke,"-ms-linear-gradient":ke,"-o-linear-gradient":ke,"-webkit-linear-gradient":ke,"radial-gradient":In,"-moz-radial-gradient":Pe,"-ms-radial-gradient":Pe,"-o-radial-gradient":Pe,"-webkit-radial-gradient":Pe,"-webkit-gradient":Xa,"repeating-linear-gradient":ce,"-webkit-repeating-linear-gradient":ce,"-moz-repeating-linear-gradient":ce,"-ms-repeating-linear-gradient":ce,"-o-repeating-linear-gradient":ce,"repeating-radial-gradient":It,"-webkit-repeating-radial-gradient":It,"-moz-repeating-radial-gradient":It,"conic-gradient":bt,"-webkit-conic-gradient":bt,"-moz-conic-gradient":bt,"image-set":ss,"-webkit-image-set":ss},Kn={name:"background-image",initialValue:"none",type:1,prefix:!1,skipCache:!0,parse:(A,e)=>{if(e.length===0)return[];let t=e[0];return t&&t.type===20&&t.value==="none"?[]:e.filter(r=>G(r)&&mr(r)).map(r=>te.parse(A,r))}},Ya={name:"background-origin",initialValue:"border-box",prefix:!1,type:1,parse:(A,e)=>e.map(t=>{if(H(t))switch(t.value){case"padding-box":return 1;case"content-box":return 2}return 0})},Dn={name:"background-position",initialValue:"0% 0%",type:1,prefix:!1,parse:(A,e)=>tA(e).map(t=>t.map(Ys).filter(r=>r!==null)).map(Zs)},Mn={name:"background-repeat",initialValue:"repeat",prefix:!1,type:1,parse:(A,e)=>tA(e).map(t=>t.filter(H).map(r=>r.value).join(" ")).map(Za)},Za=A=>{switch(A){case"no-repeat":return 1;case"repeat-x":case"repeat no-repeat":return 2;case"repeat-y":case"no-repeat repeat":return 3;default:return 0}},vn={name:"background-size",initialValue:"0",prefix:!1,type:1,parse:(A,e)=>tA(e).map(t=>t.map(r=>za(r)?r:Ys(r)).filter(r=>r!==null))},za=A=>H(A)||x(A),gt=A=>({name:`border-${A}-color`,initialValue:"transparent",prefix:!1,type:3,format:"color"}),$a=gt("top"),qa=gt("right"),ja=gt("bottom"),Ac=gt("left"),ut=A=>({name:`border-${A}-radius`,initialValue:"0 0",prefix:!1,type:1,parse:(e,t)=>Zs(t.filter(x))}),ec=ut("top-left"),tc=ut("top-right"),rc=ut("bottom-right"),sc=ut("bottom-left"),wt=A=>({name:`border-${A}-style`,initialValue:"solid",prefix:!1,type:2,parse:(e,t)=>{switch(t){case"none":return 0;case"dashed":return 2;case"dotted":return 3;case"double":return 4}return 1}}),nc=wt("top"),oc=wt("right"),ic=wt("bottom"),ac=wt("left"),dt=A=>({name:`border-${A}-width`,initialValue:"0",type:0,prefix:!1,parse:(e,t)=>z(t)?t.number:0}),Tn=dt("top"),cc=dt("right"),Bc=dt("bottom"),lc=dt("left"),Ae={type:0},nr=A=>{let[e]=A;return e?H(e)?e.value==="farthest-side"?"farthest-side":"closest-side":x(e)?e:"closest-side":"closest-side"},On=A=>{let e=null,t=null;for(let r of A)if(H(r))switch(r.value){case"left":e=M;break;case"right":e=eA;break;case"top":t=M;break;case"bottom":t=eA;break;case"center":e===null?e=AA:t===null&&(t=AA)}else x(r)&&(e===null?e=r:t===null&&(t=r));return{cx:e??AA,cy:t??AA}},hc=A=>{let e=[];for(let s of A)if(s.type!==31){if(H(s)&&s.value==="round")break;x(s)&&e.push(s)}let t=e[0]??M,r=e[1]??t;return{type:1,top:t,right:r,bottom:e[2]??t,left:e[3]??r}},gc=A=>{let e=A.filter(ee),t=e.findIndex(n=>be(n,"at")),r=t===-1?e:e.slice(0,t),s=t===-1?[]:e.slice(t+1);return{type:2,radius:nr(r),...On(s)}},uc=A=>{let e=A.filter(ee),t=e.findIndex(n=>be(n,"at")),r=t===-1?e:e.slice(0,t),s=t===-1?[]:e.slice(t+1);return{type:3,rx:nr(r.slice(0,1)),ry:nr(r.slice(1,2)),...On(s)}},wc=A=>{let e=tA(A),t=[];for(let r of e){if(r.length===1&&r[0]&&H(r[0]))continue;let s=r.filter(x);s.length>=2&&t.push([w(s,0),w(s,1)])}return{type:4,points:t}},dc=A=>{let e=A.find(t=>t.type===0);return e?{type:5,d:e.value}:Ae},Qc=A=>{let e=[];for(let t of A)if(t.type!==31){if(H(t)&&t.value==="round")break;x(t)&&e.push(t)}return e.length<4?Ae:{type:6,x:w(e,0),y:w(e,1),width:w(e,2),height:w(e,3)}},fc=A=>{let e=[];for(let r of A)if(r.type!==31){if(H(r)){if(r.value==="round")break;if(r.value==="auto"){e.push("auto");continue}return Ae}x(r)&&e.push(r)}if(e.length!==4)return Ae;let t=(r,s)=>r!=="auto"?r:s==="top"||s==="left"?M:eA;return{type:1,top:t(w(e,0),"top"),right:t(w(e,1),"right"),bottom:t(w(e,2),"bottom"),left:t(w(e,3),"left")}},Cc={name:"clip-path",initialValue:"none",prefix:!1,type:0,parse:(A,e)=>{if(H(e)&&e.value==="none")return Ae;if(e.type===18)switch(e.name){case"inset":return hc(e.values);case"circle":return gc(e.values);case"ellipse":return uc(e.values);case"polygon":return wc(e.values);case"path":return dc(e.values);case"xywh":return Qc(e.values);case"rect":return fc(e.values)}return Ae}},Uc={name:"color",initialValue:"transparent",prefix:!1,type:3,format:"color"},Fc={name:"direction",initialValue:"ltr",prefix:!1,type:2,parse:(A,e)=>{switch(e){case"rtl":return 1;default:return 0}}},pc={name:"font-family",initialValue:"",prefix:!1,type:1,parse:(A,e)=>{let t=[],r=[],s=[],n=!1;return e.forEach(o=>{switch(o.type){case 20:t.push(o.value);break;case 0:n=!0,t.push(o.value);break;case 17:t.push(o.number.toString());break;case 4:r.push(t.join(" ")),s.push(n),n=!1,t.length=0}}),t.length&&(r.push(t.join(" ")),s.push(n)),r.map((o,a)=>s[a]||o.indexOf(" ")!==-1?`'${o.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/\n/g,"\\a ").replace(/\r/g,"\\d ").replace(/\f/g,"\\c ")}'`:o)}},mc={name:"font-size",initialValue:"0",prefix:!1,type:3,format:"length"},Ec={name:"letter-spacing",initialValue:"0",prefix:!1,type:0,parse:(A,e)=>e.type===20&&e.value==="normal"?0:e.type===17||e.type===15?e.number:0},Hc={name:"line-break",initialValue:"normal",prefix:!1,type:2,parse:(A,e)=>{switch(e){case"strict":return"strict";default:return"normal"}}},yc={name:"line-height",initialValue:"normal",prefix:!1,type:4},or=(A,e)=>H(A)&&A.value==="normal"?1.2*e:A.type===17?e*A.number:x(A)?m(A,e):e,Ic={name:"list-style-image",initialValue:"none",type:0,prefix:!1,skipCache:!0,parse:(A,e)=>e.type===20&&e.value==="none"?null:te.parse(A,e)},bc={name:"list-style-position",initialValue:"outside",prefix:!1,type:2,parse:(A,e)=>{switch(e){case"inside":return 0;default:return 1}}},Qt=A=>({name:`margin-${A}`,initialValue:"0",prefix:!1,type:4}),xc=Qt("top"),Lc=Qt("right"),Sc=Qt("bottom"),Kc=Qt("left"),Dc={name:"overflow-wrap",initialValue:"normal",prefix:!1,type:2,parse:(A,e)=>{switch(e){case"break-word":return"break-word";default:return"normal"}}},ft=A=>({name:`padding-${A}`,initialValue:"0",prefix:!1,type:3,format:"length-percentage"}),Mc=ft("top"),vc=ft("right"),Tc=ft("bottom"),Oc=ft("left"),Rc={name:"text-align",initialValue:"left",prefix:!1,type:2,parse:(A,e)=>{switch(e){case"right":return 2;case"center":case"justify":return 1;default:return 0}}},Vc={name:"position",initialValue:"static",prefix:!1,type:2,parse:(A,e)=>{switch(e){case"relative":return 1;case"absolute":return 2;case"fixed":return 3;case"sticky":return 4}return 0}},Nc={name:"text-shadow",initialValue:"none",type:1,prefix:!1,parse:(A,e)=>e.length===1&&be(w(e,0),"none")?[]:tA(e).map(t=>{let r={color:0,offsetX:M,offsetY:M,blur:M},s=0;for(let n=0;n{switch(e){case"uppercase":return 2;case"lowercase":return 1;case"capitalize":return 3}return 0}},kc={name:"transform",initialValue:"none",prefix:!0,type:0,parse:(A,e)=>{if(e.type===20&&e.value==="none")return null;if(e.type===18){let t=Wc[e.name];if(typeof t>"u")throw new Error(`Attempting to parse an unsupported transform function "${e.name}"`);return t(A,e.values)}return null}},Pc=(A,e)=>{let t=e.filter(r=>r.type===17).map(r=>r.number);return t.length===6?t:null},Xc=(A,e)=>{let t=e.filter(r=>r.type===17).map(r=>r.number);return t.length!==16?null:[w(t,0),w(t,1),w(t,4),w(t,5),w(t,12),w(t,13)]},_c=(A,e)=>{if(e.length!==1)return null;let t=w(e,0),r=0;if(t.type===17&&t.number===0)r=0;else if(t.type===15)r=OA.parse(A,t);else return null;let s=Math.cos(r),n=Math.sin(r);return[s,n,-n,s,0,0]},Wc={matrix:Pc,matrix3d:Xc,rotate:_c},ns={type:16,number:50,flags:4},Jc=[ns,ns],Yc={name:"transform-origin",initialValue:"50% 50%",prefix:!0,type:1,parse:(A,e)=>{let t=e.filter(x);return t.length!==2?Jc:[w(t,0),w(t,1)]}},Zc={name:"rotate",initialValue:"none",prefix:!1,type:0,parse:(A,e)=>e.type===20&&e.value==="none"?null:e.type===17&&e.number===0?0:e.type===15?OA.parse(A,e)*180/Math.PI:null},zc={name:"visibility",initialValue:"none",prefix:!1,type:2,parse:(A,e)=>{switch(e){case"hidden":return 1;case"collapse":return 2;default:return 0}}},$c={name:"word-break",initialValue:"normal",prefix:!1,type:2,parse:(A,e)=>{switch(e){case"break-all":return"break-all";case"keep-all":return"keep-all";default:return"normal"}}},qc={name:"white-space",initialValue:"normal",prefix:!1,type:2,parse:(A,e)=>{switch(e){case"pre":return"pre";case"nowrap":return"nowrap";case"pre-wrap":return"pre-wrap";case"pre-line":return"pre-line";default:return"normal"}}},Ee=A=>A!==0,xt=A=>A===3||A===4,jc={name:"writing-mode",initialValue:"horizontal-tb",prefix:!1,type:2,parse:(A,e)=>{switch(e){case"vertical-rl":return 1;case"vertical-lr":return 2;case"sideways-rl":return 3;case"sideways-lr":return 4;default:return 0}}},AB={name:"z-index",initialValue:"auto",prefix:!1,type:0,parse:(A,e)=>{if(e.type===20)return{auto:!0,order:0};if(v(e))return{auto:!1,order:e.number};throw new Error("Invalid z-index number parsed")}},Rn={name:"time",parse:(A,e)=>{if(e.type===15)switch(e.unit.toLowerCase()){case"s":return 1e3*e.number;case"ms":return e.number}throw new Error("Unsupported time type")}},eB={name:"opacity",initialValue:"1",type:0,prefix:!1,parse:(A,e)=>v(e)?e.number:1},tB={name:"text-decoration-style",initialValue:"solid",prefix:!1,type:2,parse:(A,e)=>{switch(e){case"double":return 1;case"dotted":return 2;case"dashed":return 3;case"wavy":return 4;default:return 0}}},rB={name:"text-decoration-thickness",initialValue:"auto",prefix:!1,type:0,parse:(A,e)=>{if(H(e))switch(e.value){case"auto":return"auto";case"from-font":return"from-font"}return z(e)?e.number:"auto"}},sB={name:"text-underline-offset",initialValue:"auto",prefix:!1,type:0,parse:(A,e)=>H(e)&&e.value==="auto"?"auto":z(e)?e.number:"auto"},nB={name:"font-weight",initialValue:"normal",type:0,prefix:!1,parse:(A,e)=>{if(v(e))return e.number;if(H(e))switch(e.value){case"bold":return 700;default:return 400}return 400}},oB={name:"font-variant",initialValue:"none",type:1,prefix:!1,parse:(A,e)=>e.filter(H).map(t=>t.value)},iB={name:"font-style",initialValue:"normal",prefix:!1,type:2,parse:(A,e)=>{switch(e){case"oblique":return"oblique";case"italic":return"italic";default:return"normal"}}},aB={name:"duration",initialValue:"0s",prefix:!1,type:1,parse:(A,e)=>e.filter(z).map(t=>Rn.parse(A,t))},cB={name:"box-shadow",initialValue:"none",type:1,prefix:!1,parse:(A,e)=>e.length===1&&be(w(e,0),"none")?[]:tA(e).map(t=>{let r={color:255,offsetX:M,offsetY:M,blur:M,spread:M,inset:!1},s=0;for(let n=0;n{let t=[0,1,2],r=[];return e.filter(H).forEach(s=>{switch(s.value){case"stroke":r.push(1);break;case"fill":r.push(0);break;case"markers":r.push(2)}}),t.forEach(s=>{r.indexOf(s)===-1&&r.push(s)}),r}},lB={name:"-webkit-text-stroke-color",initialValue:"currentcolor",prefix:!1,type:3,format:"color"},hB={name:"-webkit-text-stroke-width",initialValue:"0",type:0,prefix:!1,parse:(A,e)=>z(e)?e.number:0},gB={name:"-webkit-line-clamp",initialValue:"none",prefix:!0,type:0,parse:(A,e)=>e.type===20&&e.value==="none"?0:e.type===17?Math.max(0,Math.floor(e.number)):0},uB={name:"object-fit",initialValue:"fill",prefix:!1,type:1,parse:(A,e)=>e.filter(H).reduce((t,r)=>t|wB(r.value),0)},wB=A=>{switch(A){case"contain":return 2;case"cover":return 4;case"none":return 8;case"scale-down":return 16}return 0},dB={name:"text-overflow",initialValue:"clip",prefix:!1,type:2,parse:(A,e)=>{switch(e){case"ellipsis":return 1;default:return 0}}},QB={name:"image-rendering",initialValue:"auto",prefix:!1,type:2,parse:(A,e)=>{switch(e.toLowerCase()){case"crisp-edges":case"-webkit-crisp-edges":case"-moz-crisp-edges":return 1;case"pixelated":case"-webkit-optimize-contrast":return 2;case"smooth":case"high-quality":return 3;default:return 0}}},V={NORMAL:"normal",MULTIPLY:"multiply",SCREEN:"screen",OVERLAY:"overlay",DARKEN:"darken",LIGHTEN:"lighten",COLOR_DODGE:"color-dodge",COLOR_BURN:"color-burn",HARD_LIGHT:"hard-light",SOFT_LIGHT:"soft-light",DIFFERENCE:"difference",EXCLUSION:"exclusion",HUE:"hue",SATURATION:"saturation",COLOR:"color",LUMINOSITY:"luminosity"},fB=new Set(Object.values(V)),CB={name:"mix-blend-mode",initialValue:"normal",type:2,prefix:!1,parse:(A,e)=>fB.has(e)?e:V.NORMAL},Vn={name:"filter",initialValue:"none",prefix:!1,type:1,parse:(A,e)=>{if(e.length===1){let r=w(e,0);if(r.type===20&&r.value==="none")return null}let t=[];for(let r of e)if(r.type===18){let s=r,n=Nn(s.values);switch(s.name){case"blur":t.push(`blur(${n})`);break;case"brightness":case"contrast":case"invert":case"opacity":case"saturate":case"sepia":t.push(`${s.name}(${n})`);break;case"grayscale":t.push(`grayscale(${n})`);break;case"hue-rotate":t.push(`hue-rotate(${n})`);break;case"drop-shadow":t.push(`drop-shadow(${n})`)}}return t.length>0?t.join(" "):null}},Nn=A=>{let e=[];for(let t of A){if(t.type===31){e.push(" ");continue}t.type===18?e.push(`${t.name}(${Nn(t.values)})`):t.type===4?e.push(","):t.type===6?e.push(t.value):t.type===15?e.push(`${t.number}${t.unit}`):t.type===17?e.push(`${t.number}`):t.type===16?e.push(`${t.number}%`):t.type===20?e.push(t.value):t.type===5&&e.push(`#${t.value}`)}return e.join("").trim()},UB={name:"font-variant-ligatures",initialValue:"normal",prefix:!1,type:2,parse:(A,e)=>{switch(e){case"none":return 1;case"common-ligatures":return 2;case"no-common-ligatures":return 3;case"discretionary-ligatures":return 4;case"no-discretionary-ligatures":return 5;case"historical-ligatures":return 6;case"no-historical-ligatures":return 7;case"contextual":return 8;case"no-contextual":return 9;default:return 0}}},FB={name:"zoom",initialValue:"1",type:0,prefix:!1,parse:(A,e)=>e.type===16?Math.max(0,e.number/100):e.type===17?Math.max(0,e.number):1},pB={name:"object-position",initialValue:"50% 50%",prefix:!1,type:1,parse:(A,e)=>{let t=[],r=0;for(;r{let t=[],r=e.filter(G);for(let s of r)H(s)&&mB.has(s.value)&&t.push(s.value);return t.length>0?t:["normal"]}},HB={name:"border-image-source",initialValue:"none",prefix:!1,type:1,skipCache:!0,parse:(A,e)=>{if(e.length===0)return null;let t=e.filter(r=>G(r)&&mr(r));return t.length===0?null:te.parse(A,w(t,0))}},yB=A=>{let e=[...A];if(e.length===1){let t=w(e,0);e.push(t,t,t)}else e.length===2?e.push(w(e,0),w(e,1)):e.length===3&&e.push(w(e,1));return[w(e,0),w(e,1),w(e,2),w(e,3)]},IB={name:"border-image-slice",initialValue:"100%",prefix:!1,type:1,parse:(A,e)=>{let t=e.filter(ee),r=[],s=!1,n="percent";for(let B of t){if(H(B)&&B.value==="fill"){s=!0;continue}B.type===17?(r.push(B.number),n="number"):B.type===16&&(r.push(B.number),n="percent")}let[o,a,i,c]=yB(r.length>0?r:[100]);return{top:o,right:a,bottom:i,left:c,fill:s,unit:n}}},bB=A=>{switch(A){case"repeat":return 1;case"round":return 2;case"space":return 3;default:return 0}},xB={name:"border-image-repeat",initialValue:"stretch",prefix:!1,type:1,parse:(A,e)=>{let t=e.filter(ee),r=[];for(let n of t)H(n)&&r.push(bB(n.value));let s=r[0]??0;return{horizontal:s,vertical:r[1]??s}}},LB={name:"box-decoration-break",initialValue:"slice",prefix:!1,type:2,parse:(A,e)=>{switch(e){case"clone":return 1;default:return 0}}},SB={name:"accent-color",initialValue:"auto",prefix:!1,type:0,parse:(A,e)=>H(e)&&e.value==="auto"?null:aA.parse(A,e)},KB={name:"-webkit-text-fill-color",initialValue:"currentcolor",prefix:!0,type:0,parse:(A,e)=>H(e)&&e.value==="currentcolor"?null:aA.parse(A,e)},DB={name:"isolation",initialValue:"auto",prefix:!1,type:2,parse:(A,e)=>e==="isolate"?1:0},MB={name:"outline-style",initialValue:"none",prefix:!1,type:2,parse:(A,e)=>{switch(e){case"solid":return 2;case"dashed":return 3;case"dotted":return 4;case"double":return 5;case"auto":return 1;default:return 0}}},vB={name:"outline-color",initialValue:"currentcolor",prefix:!1,type:0,parse:(A,e)=>H(e)&&(e.value==="currentcolor"||e.value==="invert")?null:aA.parse(A,e)},TB={name:"outline-width",initialValue:"medium",prefix:!1,type:0,parse:Tn.parse},OB={name:"outline-offset",initialValue:"0px",prefix:!1,type:0,parse:(A,e)=>z(e)||v(e)?e.number:0},RB={name:"backdrop-filter",initialValue:"none",prefix:!1,type:1,parse:(A,e)=>Vn.parse(A,e)},VB={name:"mask-image",initialValue:"none",prefix:!1,type:1,skipCache:!0,parse:Kn.parse},NB={name:"mask-position",initialValue:"0%",prefix:!1,type:1,parse:Dn.parse},GB={name:"mask-repeat",initialValue:"repeat",prefix:!1,type:1,parse:Mn.parse},kB={name:"mask-size",initialValue:"auto",prefix:!1,type:1,parse:vn.parse},os=["dot","circle","double-circle","triangle","sesame"],PB={name:"text-emphasis-style",initialValue:"none",prefix:!1,type:1,parse:(A,e)=>{let t=e.filter(ee);if(t.length===0)return null;let r=w(t,0);if(r.type===0)return r.value;if(H(r)){if(r.value==="none")return null;if(r.value!=="filled"&&r.value!=="open"&&os.indexOf(r.value)===-1)return r.value}let s=!0,n="circle";for(let o of t)H(o)&&(o.value==="filled"?s=!0:o.value==="open"?s=!1:os.indexOf(o.value)!==-1&&(n=o.value));return{fill:s,shape:n}}},XB={name:"text-emphasis-color",initialValue:"currentcolor",prefix:!1,type:0,parse:(A,e)=>H(e)&&e.value==="currentcolor"?null:aA.parse(A,e)},_B={name:"text-emphasis-position",initialValue:"over right",prefix:!1,type:1,parse:(A,e)=>{let t=!0,r=!0;for(let s of e)if(H(s))switch(s.value){case"over":t=!0;break;case"under":t=!1;break;case"right":r=!0;break;case"left":r=!1}return{over:t,right:r}}},WB=A=>{let e=[...A];if(e.length===1){let t=w(e,0);e.push(t,t,t)}else e.length===2?e.push(w(e,0),w(e,1)):e.length===3&&e.push(w(e,1));return[w(e,0),w(e,1),w(e,2),w(e,3)]},JB=A=>H(A)&&A.value==="auto"?{kind:"auto"}:A.type===17?{kind:"number",value:A.number}:A.type===15&&A.unit==="px"?{kind:"length",value:A.number}:A.type===16?{kind:"percentage",value:A.number}:null,Gn=A=>{let e=[];for(let t of A){if(t.type===31)continue;let r=JB(t);if(!r)return null;e.push(r)}return e.length===0||e.length>4?null:WB(e)},YB={name:"border-image-width",initialValue:"auto",prefix:!1,type:1,parse:(A,e)=>{let t=Gn(e),r={kind:"auto"};return t?{top:t[0],right:t[1],bottom:t[2],left:t[3]}:{top:r,right:r,bottom:r,left:r}}},ZB={name:"border-image-outset",initialValue:"0px",prefix:!1,type:1,parse:(A,e)=>{let t=Gn(e),r={kind:"length",value:0};return t?{top:t[0],right:t[1],bottom:t[2],left:t[3]}:{top:r,right:r,bottom:r,left:r}}},zB={name:"-webkit-box-reflect",initialValue:"none",prefix:!0,type:1,skipCache:!0,parse:(A,e)=>{let t=null,r=0,s=null;for(let n of e)if(n.type!==31){if(t===null&&H(n)){if(n.value==="below"||n.value==="above"||n.value==="left"||n.value==="right"){t=n.value;continue}if(n.value==="none")return null}if(r===0&&z(n)&&n.unit==="px"){r=n.number;continue}if(s===null&&mr(n)){s=te.parse(A,n);continue}}return t===null?null:{direction:t,offset:r,mask:s}}},$B=1e4,is=[["animationDuration",aB,"animationDuration"],["backgroundClip",Ga,"backgroundClip"],["backgroundColor",ka,"backgroundColor"],["backgroundImage",Kn,"backgroundImage"],["backgroundOrigin",Ya,"backgroundOrigin"],["backgroundPosition",Dn,"backgroundPosition"],["backgroundRepeat",Mn,"backgroundRepeat"],["backgroundSize",vn,"backgroundSize"],["borderTopColor",$a,"borderTopColor"],["borderRightColor",qa,"borderRightColor"],["borderBottomColor",ja,"borderBottomColor"],["borderLeftColor",Ac,"borderLeftColor"],["borderTopLeftRadius",ec,"borderTopLeftRadius"],["borderTopRightRadius",tc,"borderTopRightRadius"],["borderBottomRightRadius",rc,"borderBottomRightRadius"],["borderBottomLeftRadius",sc,"borderBottomLeftRadius"],["borderTopStyle",nc,"borderTopStyle"],["borderRightStyle",oc,"borderRightStyle"],["borderBottomStyle",ic,"borderBottomStyle"],["borderLeftStyle",ac,"borderLeftStyle"],["borderTopWidth",Tn,"borderTopWidth"],["borderRightWidth",cc,"borderRightWidth"],["borderBottomWidth",Bc,"borderBottomWidth"],["borderLeftWidth",lc,"borderLeftWidth"],["boxShadow",cB,"boxShadow"],["clipPath",Cc,"clipPath"],["color",Uc,"color"],["direction",Fc,"direction"],["display",Sa,"display"],["fontFamily",pc,"fontFamily"],["fontSize",mc,"fontSize"],["fontStyle",iB,"fontStyle"],["fontVariant",oB,"fontVariant"],["fontWeight",nB,"fontWeight"],["letterSpacing",Ec,"letterSpacing"],["lineBreak",Hc,"lineBreak"],["lineHeight",yc,"lineHeight"],["listStyleImage",Ic,"listStyleImage"],["listStylePosition",bc,"listStylePosition"],["listStyleType",tr,"listStyleType"],["marginTop",xc,"marginTop"],["marginRight",Lc,"marginRight"],["marginBottom",Sc,"marginBottom"],["marginLeft",Kc,"marginLeft"],["opacity",eB,"opacity"],["overflowWrap",Dc,"overflowWrap"],["paddingTop",Mc,"paddingTop"],["paddingRight",vc,"paddingRight"],["paddingBottom",Tc,"paddingBottom"],["paddingLeft",Oc,"paddingLeft"],["paintOrder",BB,"paintOrder"],["position",Vc,"position"],["textAlign",Rc,"textAlign"],["textDecorationStyle",tB,"textDecorationStyle"],["textDecorationThickness",rB,"textDecorationThickness"],["textUnderlineOffset",sB,"textUnderlineOffset"],["textShadow",Nc,"textShadow"],["textTransform",Gc,"textTransform"],["textOverflow",dB,"textOverflow"],["transform",kc,"transform"],["transformOrigin",Yc,"transformOrigin"],["rotate",Zc,"rotate"],["visibility",zc,"visibility"],["webkitTextStrokeColor",lB,"webkitTextStrokeColor"],["webkitTextStrokeWidth",hB,"webkitTextStrokeWidth"],["webkitLineClamp",gB,"webkitLineClamp"],["wordBreak",$c,"wordBreak"],["whiteSpace",qc,"whiteSpace"],["writingMode",jc,"writingMode"],["zIndex",AB,"zIndex"],["objectFit",uB,"objectFit"],["imageRendering",QB,"imageRendering"],["mixBlendMode",CB,"mixBlendMode"],["filter",Vn,"filter"],["fontVariantLigatures",UB,"fontVariantLigatures"],["zoom",FB,"zoom"],["objectPosition",pB,"objectPosition"],["backgroundBlendMode",EB,"backgroundBlendMode"],["borderImageSource",HB,"borderImageSource"],["borderImageSlice",IB,"borderImageSlice"],["borderImageRepeat",xB,"borderImageRepeat"],["boxDecorationBreak",LB,"boxDecorationBreak"],["accentColor",SB,"accentColor"],["webkitTextFillColor",KB,"webkitTextFillColor"],["isolation",DB,"isolation"],["outlineColor",vB,"outlineColor"],["outlineStyle",MB,"outlineStyle"],["outlineWidth",TB,"outlineWidth"],["outlineOffset",OB,"outlineOffset"],["backdropFilter",RB,"backdropFilter"],["maskImage",VB,"maskImage"],["maskPosition",NB,"maskPosition"],["maskRepeat",GB,"maskRepeat"],["maskSize",kB,"maskSize"],["textEmphasisStyle",PB,"textEmphasisStyle"],["textEmphasisColor",XB,"textEmphasisColor"],["textEmphasisPosition",_B,"textEmphasisPosition"],["borderImageWidth",YB,"borderImageWidth"],["borderImageOutset",ZB,"borderImageOutset"],["webkitBoxReflect",zB,"webkitBoxReflect"]],as=new Map,lA=(A,e,t)=>{let r=t!==null&&typeof t<"u"?t.toString():e.initialValue;r.trim()===""&&(r=e.initialValue);let s=as.get(e);if(s){let i=s.get(r);if(i!==void 0)return s.delete(r),s.set(r,i),i}let n=jt.get();n.write(r);let o=new Ps(n.read());jt.release(n);let a=(()=>{switch(e.type){case 2:{let i=o.parseComponentValue();return e.parse(A,H(i)?i.value:e.initialValue)}case 0:return e.parse(A,o.parseComponentValue());case 1:return e.parse(A,o.parseComponentValues());case 4:return o.parseComponentValue();case 3:switch(e.format){case"angle":return OA.parse(A,o.parseComponentValue());case"color":return aA.parse(A,o.parseComponentValue());case"image":return te.parse(A,o.parseComponentValue());case"length":{let i=o.parseComponentValue();return pA(i)?i:M}case"length-percentage":{let i=o.parseComponentValue();return x(i)?i:M}case"time":return Rn.parse(A,o.parseComponentValue())}}})();if(s||(s=new Map,as.set(e,s)),!(e.skipCache||e.type===3&&e.format==="image")){if(s.size>=200){let i=s.keys().next().value;i!==void 0&&s.delete(i)}s.set(r,a)}return a},qB=class{constructor(A){this.styles=A}get topColor(){return this.styles.borderTopColor}get rightColor(){return this.styles.borderRightColor}get bottomColor(){return this.styles.borderBottomColor}get leftColor(){return this.styles.borderLeftColor}get topStyle(){return this.styles.borderTopStyle}get rightStyle(){return this.styles.borderRightStyle}get bottomStyle(){return this.styles.borderBottomStyle}get leftStyle(){return this.styles.borderLeftStyle}get topWidth(){return this.styles.borderTopWidth}get rightWidth(){return this.styles.borderRightWidth}get bottomWidth(){return this.styles.borderBottomWidth}get leftWidth(){return this.styles.borderLeftWidth}get topLeftRadius(){return this.styles.borderTopLeftRadius}get topRightRadius(){return this.styles.borderTopRightRadius}get bottomRightRadius(){return this.styles.borderBottomRightRadius}get bottomLeftRadius(){return this.styles.borderBottomLeftRadius}get imageSource(){return this.styles.borderImageSource}get imageSlice(){return this.styles.borderImageSlice}get imageRepeat(){return this.styles.borderImageRepeat}get boxShadow(){return this.styles.boxShadow}},jB=class{constructor(A){this.styles=A}get color(){return this.styles.backgroundColor}get image(){return this.styles.backgroundImage}get clip(){return this.styles.backgroundClip}get origin(){return this.styles.backgroundOrigin}get position(){return this.styles.backgroundPosition}get repeat(){return this.styles.backgroundRepeat}get size(){return this.styles.backgroundSize}get blendMode(){return this.styles.backgroundBlendMode}},Al=class{constructor(A){this.styles=A}get family(){return this.styles.fontFamily}get size(){return this.styles.fontSize}get style(){return this.styles.fontStyle}get variant(){return this.styles.fontVariant}get weight(){return this.styles.fontWeight}get ligatures(){return this.styles.fontVariantLigatures}get color(){return this.styles.color}get letterSpacing(){return this.styles.letterSpacing}get lineHeight(){return this.styles.lineHeight}get textAlign(){return this.styles.textAlign}get textTransform(){return this.styles.textTransform}get textOverflow(){return this.styles.textOverflow}get textShadow(){return this.styles.textShadow}get textDecorationColor(){return this.styles.textDecorationColor}get textDecorationLine(){return this.styles.textDecorationLine}get textDecorationStyle(){return this.styles.textDecorationStyle}get textDecorationThickness(){return this.styles.textDecorationThickness}get textUnderlineOffset(){return this.styles.textUnderlineOffset}get wordBreak(){return this.styles.wordBreak}get lineBreak(){return this.styles.lineBreak}get overflowWrap(){return this.styles.overflowWrap}get writingMode(){return this.styles.writingMode}get direction(){return this.styles.direction}get webkitTextStrokeColor(){return this.styles.webkitTextStrokeColor}get webkitTextStrokeWidth(){return this.styles.webkitTextStrokeWidth}get webkitLineClamp(){return this.styles.webkitLineClamp}get paintOrder(){return this.styles.paintOrder}},el=class{constructor(A){this.styles=A}get display(){return this.styles.display}get position(){return this.styles.position}get float(){return this.styles.float}get zIndex(){return this.styles.zIndex}get marginTop(){return this.styles.marginTop}get marginRight(){return this.styles.marginRight}get marginBottom(){return this.styles.marginBottom}get marginLeft(){return this.styles.marginLeft}get paddingTop(){return this.styles.paddingTop}get paddingRight(){return this.styles.paddingRight}get paddingBottom(){return this.styles.paddingBottom}get paddingLeft(){return this.styles.paddingLeft}get overflowX(){return this.styles.overflowX}get overflowY(){return this.styles.overflowY}get opacity(){return this.styles.opacity}get visibility(){return this.styles.visibility}get transform(){return this.styles.transform}get transformOrigin(){return this.styles.transformOrigin}get rotate(){return this.styles.rotate}get zoom(){return this.styles.zoom}get clipPath(){return this.styles.clipPath}get mixBlendMode(){return this.styles.mixBlendMode}get filter(){return this.styles.filter}get imageRendering(){return this.styles.imageRendering}get objectFit(){return this.styles.objectFit}get objectPosition(){return this.styles.objectPosition}get boxDecorationBreak(){return this.styles.boxDecorationBreak}get listStyleImage(){return this.styles.listStyleImage}get listStylePosition(){return this.styles.listStylePosition}get listStyleType(){return this.styles.listStyleType}get animationDuration(){return this.styles.animationDuration}isVisible(){return this.styles.isVisible()}isTransparent(){return this.styles.isTransparent()}isTransformed(){return this.styles.isTransformed()}isPositioned(){return this.styles.isPositioned()}isPositionedWithZIndex(){return this.styles.isPositionedWithZIndex()}isFloating(){return this.styles.isFloating()}isInlineLevel(){return this.styles.isInlineLevel()}},tl=class{get border(){return this._border??(this._border=new qB(this))}get background(){return this._background??(this._background=new jB(this))}get font(){return this._font??(this._font=new Al(this))}get layout(){return this._layout??(this._layout=new el(this))}constructor(A,e){if(e.display==="none"){this.display=0;for(let[t,r]of is)t!=="display"&&(this[t]=lA(A,r,void 0));Object.assign(this,cs(A,null));return}for(let[t,r,s]of is)this[t]=lA(A,r,e[s]);Object.assign(this,cs(A,e))}isVisible(){return this.display>0&&this.opacity>0&&this.visibility===0}isTransparent(){return BA(this.backgroundColor)}isTransformed(){return this.transform!==null||this.rotate!==null}isPositioned(){return this.position!==0}isPositionedWithZIndex(){return this.isPositioned()&&!this.zIndex.auto}isFloating(){return this.float!==0}isInlineLevel(){return P(this.display,4)||P(this.display,33554432)||P(this.display,268435456)||P(this.display,536870912)||P(this.display,67108864)||P(this.display,134217728)}},cs=(A,e)=>{let t=(s,n)=>{if(e)return e[s]??n},r=lA(A,Ma,t("overflow"));return{float:lA(A,Da,t("cssFloat")),textDecorationColor:lA(A,va,t("textDecorationColor",t("color"))),textDecorationLine:lA(A,Ta,t("textDecorationLine",t("textDecoration"))),overflowX:r[0],overflowY:r[r.length>1?1:0]}},rl=class{constructor(A,e){this.content=lA(A,Oa,e.content),this.quotes=lA(A,Ra,e.quotes)}},kn=class{constructor(A,e){this.counterIncrement=lA(A,Va,e.counterIncrement),this.counterReset=lA(A,Na,e.counterReset)}},sl="data-html2canvas-debug",nl=A=>{if(typeof A.getAttribute!="function")return 0;switch(A.getAttribute(sl)){case"all":return 1;case"clone":return 2;case"parse":return 3;case"render":return 4;default:return 0}},ir=(A,e)=>{let t=nl(A);return t===1||e===t},ol="data-html2canvas-ignore",il=class{constructor(A,e,t){this.cloneNodeFn=A,this.options=e,this.context=t}appendChildNode(A,e,t){this.safeAppendClonedChild(A,e,t)}cloneChildNodes(A,e,t){A.shadowRoot&&e.shadowRoot?(this.cloneShadowDOMChildren(A.shadowRoot,e.shadowRoot,t),this.cloneLightDOMChildren(A,e,t)):A.shadowRoot&&!e.shadowRoot?this.cloneShadowDOMAsLightDOM(A.shadowRoot,e,t):this.cloneLightDOMChildren(A,e,t)}shouldCloneChild(A){return!SA(A)||!Ca(A)&&!A.hasAttribute("data-html2canvas-ignore")&&(typeof this.options.ignoreElements!="function"||!this.options.ignoreElements(A))}shouldCloneStyleElement(A){return!this.options.copyStyles||!SA(A)||!wn(A)}safeAppendClonedChild(A,e,t){this.shouldCloneChild(e)&&this.shouldCloneStyleElement(e)&&A.appendChild(this.cloneNodeFn(e,t))}cloneAssignedNodes(A,e,t){A.forEach(r=>{this.safeAppendClonedChild(e,r,t)})}cloneSlotFallbackContent(A,e,t){for(let r=A.firstChild;r;r=r.nextSibling)this.safeAppendClonedChild(e,r,t)}cloneSlotElement(A,e,t){if(!fe(A))return;let r=A;if(typeof r.assignedNodes!="function"){this.context.logger.warn("HTMLSlotElement.assignedNodes is not available",A),this.cloneSlotFallbackContent(A,e,t);return}let s=r.assignedNodes();if(!s||!Array.isArray(s)){this.context.logger.warn("assignedNodes() did not return a valid array",A),this.cloneSlotFallbackContent(A,e,t);return}s.length>0?this.cloneAssignedNodes(s,e,t):this.cloneSlotFallbackContent(A,e,t)}cloneShadowDOMChildren(A,e,t){for(let r=A.firstChild;r;r=r.nextSibling)SA(r)&&fe(r)?this.cloneSlotElement(r,e,t):this.safeAppendClonedChild(e,r,t)}cloneLightDOMChildren(A,e,t){for(let r=A.firstChild;r;r=r.nextSibling)this.appendChildNode(e,r,t)}cloneSlotElementAsLightDOM(A,e,t){if(!fe(A))return;let r=A;if(typeof r.assignedNodes!="function"){for(let n=A.firstChild;n;n=n.nextSibling)this.appendChildNode(e,n,t);return}let s=r.assignedNodes();if(s&&Array.isArray(s)&&s.length>0)s.forEach(n=>this.appendChildNode(e,n,t));else for(let n=A.firstChild;n;n=n.nextSibling)this.appendChildNode(e,n,t)}cloneShadowDOMAsLightDOM(A,e,t){for(let r=A.firstChild;r;r=r.nextSibling)SA(r)&&fe(r)?this.cloneSlotElementAsLightDOM(r,e,t):this.appendChildNode(e,r,t)}},al=["all","d","content"],ar=(A,e)=>{let t=[];for(let r=A.length-1;r>=0;r--){let s=A.item(r);if(al.indexOf(s)===-1&&!s.startsWith("--")){let n=A.getPropertyValue(s);if(n){let o=A.getPropertyPriority(s);t.push(o?`${s}:${n} !${o}`:`${s}:${n}`)}}}return t.length>0&&(e.style.cssText=t.join(";")+";"),e},cl=":before",Bl=":after",cr="___html2canvas___pseudoelement_before",Br="___html2canvas___pseudoelement_after",Bs=`{ + content: "" !important; + display: none !important; +}`,ll=(A,e)=>{hl(A,`.${cr}${cl}${Bs} + .${Br}${Bl}${Bs}`,e)},hl=(A,e,t)=>{let r=A.ownerDocument;if(r){let s=r.createElement("style");s.textContent=e,t&&(s.nonce=t),A.appendChild(s)}},gl=class{constructor(A,e){this.context=A,this.counters=e,this.quoteDepth=0}resolvePseudoContent(A,e,t,r){if(!t)return;let s=t.content,n=e.ownerDocument;if(!n||!s||s==="none"||s==="-moz-alt-content"||t.display==="none")return;this.counters.parse(new kn(this.context,t));let o=new rl(this.context,t),a=n.createElement("html2canvaspseudoelement");ar(t,a),o.content.forEach(c=>{if(c.type===0)a.appendChild(n.createTextNode(c.value));else if(c.type===22){let B=n.createElement("img");B.src=c.value,B.style.opacity="1",a.appendChild(B)}else if(c.type===18){if(c.name==="attr"){let B=c.values.filter(H);B.length&&B[0]&&a.appendChild(n.createTextNode(A.getAttribute(B[0].value)||""))}else if(c.name==="counter"){let[B,l]=c.values.filter(G);if(B&&H(B)){let h=this.counters.getCounterValue(B.value),g=l&&H(l)?tr.parse(this.context,l.value):3;a.appendChild(n.createTextNode(Le(h,g,!1)))}}else if(c.name==="counters"){let[B,l,h]=c.values.filter(G);if(B&&H(B)){let g=this.counters.getCounterValues(B.value),u=h&&H(h)?tr.parse(this.context,h.value):3,d=l&&l.type===0?l.value:"",Q=g.map(f=>Le(f,u,!1)).join(d);a.appendChild(n.createTextNode(Q))}}}else if(c.type===20)switch(c.value){case"open-quote":a.appendChild(n.createTextNode(ts(o.quotes,this.quoteDepth++,!0)));break;case"close-quote":a.appendChild(n.createTextNode(ts(o.quotes,--this.quoteDepth,!1)));break;default:a.appendChild(n.createTextNode(c.value))}}),a.className=`${cr} ${Br}`;let i=r===0?` ${cr}`:` ${Br}`;return DA(e)?e.className.baseValue+=i:e.className+=i,a}},ul=(A,e,t)=>{let r=A.createElement("iframe");return r.className="html2canvas-container",r.style.visibility="hidden",r.style.position="fixed",r.style.left="-10000px",r.style.top="0px",r.style.border="0",r.width=e.width.toString(),r.height=e.height.toString(),r.scrolling="no",r.setAttribute(ol,"true"),(t||A.body).appendChild(r),r},wl=A=>new Promise(e=>{if(A.complete){e();return}if(!A.src){e();return}A.onload=e,A.onerror=e}),dl=A=>Promise.all([].slice.call(A.images,0).map(wl)),Ql=A=>new Promise((e,t)=>{let r=A.contentWindow;if(!r)return t("No window assigned for iframe");let s=r.document;r.onload=A.onload=()=>{r.onload=A.onload=null;let n=600,o=0,a=setInterval(()=>{o++,(s.body.childNodes.length>0&&s.readyState==="complete"||o>=n)&&(clearInterval(a),e(A))},50)}}),fl=A=>{let e="";return A&&(e+="/g,">")),A.publicId?(e+=' PUBLIC "'+A.publicId.replace(/"/g,""")+'"',A.systemId&&(e+=' "'+A.systemId.replace(/"/g,""")+'"')):A.systemId&&(e+=' SYSTEM "'+A.systemId.replace(/"/g,""")+'"'),e+=">"),e},Cl=(A,e,t)=>{A&&A.defaultView&&(e!==A.defaultView.pageXOffset||t!==A.defaultView.pageYOffset)&&A.defaultView.scrollTo(e,t)},Ul=([A,e,t])=>{A.scrollLeft=e,A.scrollTop=t},Fl=(A,e)=>{let t=A.ownerDocument.createElement("base");t.href=e;let r=A.getElementsByTagName("head").item(0);r?.insertBefore(t,r?.firstChild??null)},pl=(A,e,t,r)=>{let s=ul(e,t,r.container);if(!s.contentWindow)throw new Error("Unable to find iframe window");let n=e.defaultView.pageXOffset,o=e.defaultView.pageYOffset,a=s.contentWindow,i=a.document,c=Ql(s).then(async()=>{r.scrolledElements.forEach(Ul),a&&a.scrollTo(t.left,t.top);let g=r.onclone,u=r.clonedReferenceElement;if(typeof u>"u")throw new Error(`Error finding the ${r.referenceElementName} in the cloned document`);return i.fonts&&i.fonts.ready&&await i.fonts.ready,/(AppleWebKit)/g.test(navigator.userAgent)&&await dl(i),typeof g=="function"&&await Promise.resolve().then(()=>g(i,u)),a.scrollTo(t.left,t.top),/AppleWebKit/g.test(navigator.userAgent)&&(a.scrollY!==t.top||a.scrollX!==t.left)&&(A.logger.warn("Unable to restore scroll position for cloned document"),A.adjustWindowBounds(a.scrollX-t.left,a.scrollY-t.top)),s}),B=e.baseURI;i.open();let l=fl(document.doctype)+"";try{let g=e.defaultView,u=g&&g.trustedTypes,d=u?.getPolicy?.("html2canvas-pro");!d&&u&&(d=u.createPolicy("html2canvas-pro",{createHTML:f=>f}));let Q=d?d.createHTML(l):l;i.write(Q)}catch{i.write(l)}Cl(e,n,o),i.close();let h=i.adoptNode(r.documentElement);return Fl(h,B),i.replaceChild(h,i.documentElement),c},ml=A=>{let e=A;for(;e;){if(e.parentNode&&e.parentNode.host)return e.parentNode;let t=e.getRootNode();if(t&&t!==e.ownerDocument&&t.host)return t;e=e.parentNode}return null},Lt=class{constructor(A,e,t){if(this.context=A,this.options=t,this.scrolledElements=[],this.referenceElement=e,this.counters=new Ea,this.pseudoContents=new gl(A,this.counters),this.slotCloner=new il((r,s)=>this.cloneNode(r,s),{ignoreElements:t.ignoreElements,copyStyles:t.copyStyles??!0},A),!e.ownerDocument)throw new Error("Cloned element does not have an owner document");if(!this.options.iframeContainer){let r=ml(e);r&&(this.options.iframeContainer=r)}this.documentElement=this.cloneNode(e.ownerDocument.documentElement,!1)}toIFrame(A,e){return pl(this.context,A,e,{documentElement:this.documentElement,clonedReferenceElement:this.clonedReferenceElement,referenceElementName:this.referenceElement.nodeName,scrolledElements:this.scrolledElements,onclone:this.options.onclone,container:this.options.iframeContainer})}createElementClone(A){if(ir(A,2))debugger;if(gn(A))return this.createCanvasClone(A);if(Zr(A))return this.createVideoClone(A);if(wn(A))return this.createStyleClone(A);let e=A.cloneNode(!1);return er(e)&&(er(A)&&A.currentSrc&&A.currentSrc!==A.src&&(e.src=A.currentSrc,e.srcset=""),e.loading==="lazy"&&(e.loading="eager")),zr(e)&&!DA(e)?this.createCustomElementClone(A,e):e}createCustomElementClone(A,e){let t=document.createElement("div");t.className=e.className,ar(e.style,t);let r=e.attributes;for(let s=0;so&&typeof o.cssText=="string"?n+o.cssText:n,""),s=A.cloneNode(!1);return s.textContent=r,this.options.cspNonce&&(s.nonce=this.options.cspNonce),s}}catch(t){if(this.context.logger.error("Unable to access cssRules property",t),t.name!=="SecurityError")throw t}let e=A.cloneNode(!1);return this.options.cspNonce&&(e.nonce=this.options.cspNonce),e}createCanvasClone(A){if(this.options.inlineImages&&A.ownerDocument){let t=A.ownerDocument.createElement("img");try{return t.src=A.toDataURL(),t}catch{this.context.logger.info("Unable to inline canvas contents, canvas is tainted",A)}}let e=A.cloneNode(!1);try{e.width=A.width,e.height=A.height;let t=A.getContext("2d"),r=e.getContext("2d",{willReadFrequently:!0});if(r)if(!this.options.allowTaint&&t)r.putImageData(t.getImageData(0,0,A.width,A.height),0,0);else{let s=A.getContext("webgl2")??A.getContext("webgl");s&&s.getContextAttributes()?.preserveDrawingBuffer===!1&&this.context.logger.warn("Unable to clone WebGL context as it has preserveDrawingBuffer=false",A),r.drawImage(A,0,0)}return e}catch{this.context.logger.info("Unable to clone canvas as it is tainted",A)}return e}createVideoClone(A){let e=A.ownerDocument.createElement("canvas");e.width=A.offsetWidth,e.height=A.offsetHeight;let t=e.getContext("2d");try{return t&&(t.drawImage(A,0,0,e.width,e.height),this.options.allowTaint||t.getImageData(0,0,e.width,e.height)),e}catch{this.context.logger.info("Unable to clone video as it is tainted",A)}let r=A.ownerDocument.createElement("canvas");return r.width=A.offsetWidth,r.height=A.offsetHeight,r}appendChildNode(A,e,t){this.slotCloner.appendChildNode(A,e,t)}cloneChildNodes(A,e,t){this.slotCloner.cloneChildNodes(A,e,t)}cloneNode(A,e){if(ln(A))return document.createTextNode(A.data);if(!A.ownerDocument)return A.cloneNode(!1);let t=A.ownerDocument.defaultView;if(t&&SA(A)&&(xe(A)||DA(A))){let r=this.createElementClone(A);r.style.transitionProperty="none";let s=t.getComputedStyle(A),n=ma(A);this.referenceElement===A&&xe(r)&&(this.clonedReferenceElement=r),pr(r)&&ll(r,this.options.cspNonce);let o=this.counters.parse(new kn(this.context,s));if(n){let a=t.getComputedStyle(A,":before"),i=this.pseudoContents.resolvePseudoContent(A,r,a,0);i&&r.insertBefore(i,r.firstChild);let c=t.getComputedStyle(A,":after"),B=this.pseudoContents.resolvePseudoContent(A,r,c,1);B&&r.appendChild(B)}return zr(A)&&(e=!0),Zr(A)||this.cloneChildNodes(A,r,e),this.counters.pop(o),(s&&(this.options.copyStyles||DA(A))&&!un(A)||e)&&ar(s,r),(A.scrollTop!==0||A.scrollLeft!==0)&&this.scrolledElements.push([r,A.scrollLeft,A.scrollTop]),(tt(A)||rt(A))&&(tt(r)||rt(r))&&(r.value=A.value),r}return A.cloneNode(!1)}static destroy(A){return A.parentNode?(A.parentNode.removeChild(A),!0):!1}},ls=class{static normalizeElement(A,e){let t={};return xe(A)&&(e.animationDuration.some(r=>r>0)&&(t.animationDuration=A.style.animationDuration,A.style.animationDuration="0s"),e.transform!==null&&(t.transform=A.style.transform,A.style.transform="translate(0, 0)"),e.rotate!==null&&(t.rotate=A.style.rotate,A.style.rotate="0deg",t.transform===void 0&&(t.transform=A.style.transform,A.style.transform="translate(0, 0)"))),t}static restoreElement(A,e){xe(A)&&(e.animationDuration!==void 0&&(A.style.animationDuration=e.animationDuration),e.transform!==void 0&&(A.style.transform=e.transform),e.rotate!==void 0&&(A.style.rotate=e.rotate))}},uA=class{constructor(A,e,t={}){if(this.context=A,this.textNodes=[],this.elements=[],this.createsStackingContext=!1,this.createsRealStackingContext=!1,this.isListOwner=!1,this.debugRender=!1,ir(e,3))debugger;if(this.styles=new tl(A,A.config.window.getComputedStyle(e,null)),t.normalizeDom!==!1&&xe(e)&&(this.originalStyles=ls.normalizeElement(e,this.styles),this.originalElement=e),this.bounds=ye(this.context,e),e.tagName==="FIELDSET"){let r=e.querySelector(":scope > legend");if(r){let s=ye(this.context,r);this.legendBounds=s;let n=s.top+s.height/2-this.styles.borderTopWidth/2;this.bounds=new _(this.bounds.left,n,this.bounds.width,this.bounds.height-(n-this.bounds.top))}}ir(e,4)&&(this.debugRender=!0)}restore(){this.originalStyles&&this.originalElement&&(ls.restoreElement(this.originalElement,this.originalStyles),this.originalStyles=void 0,this.originalElement=void 0)}restoreTree(){this.restore();for(let A of this.elements)A.restoreTree()}},El="AAAAAAAAAAAAEA4AGBkAAFAaAAACAAAAAAAIABAAGAAwADgACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAAQABIAEQATAAIABAACAAQAAgAEAAIABAAVABcAAgAEAAIABAACAAQAGAAaABwAHgAgACIAI4AlgAIABAAmwCjAKgAsAC2AL4AvQDFAMoA0gBPAVYBWgEIAAgACACMANoAYgFkAWwBdAF8AX0BhQGNAZUBlgGeAaMBlQGWAasBswF8AbsBwwF0AcsBYwHTAQgA2wG/AOMBdAF8AekB8QF0AfkB+wHiAHQBfAEIAAMC5gQIAAsCEgIIAAgAFgIeAggAIgIpAggAMQI5AkACygEIAAgASAJQAlgCYAIIAAgACAAKBQoFCgUTBRMFGQUrBSsFCAAIAAgACAAIAAgACAAIAAgACABdAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABoAmgCrwGvAQgAbgJ2AggAHgEIAAgACADnAXsCCAAIAAgAgwIIAAgACAAIAAgACACKAggAkQKZAggAPADJAAgAoQKkAqwCsgK6AsICCADJAggA0AIIAAgACAAIANYC3gIIAAgACAAIAAgACABAAOYCCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAkASoB+QIEAAgACAA8AEMCCABCBQgACABJBVAFCAAIAAgACAAIAAgACAAIAAgACABTBVoFCAAIAFoFCABfBWUFCAAIAAgACAAIAAgAbQUIAAgACAAIAAgACABzBXsFfQWFBYoFigWKBZEFigWKBYoFmAWfBaYFrgWxBbkFCAAIAAgACAAIAAgACAAIAAgACAAIAMEFCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAMgFCADQBQgACAAIAAgACAAIAAgACAAIAAgACAAIAO4CCAAIAAgAiQAIAAgACABAAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAD0AggACAD8AggACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIANYFCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAMDvwAIAAgAJAIIAAgACAAIAAgACAAIAAgACwMTAwgACAB9BOsEGwMjAwgAKwMyAwsFYgE3A/MEPwMIAEUDTQNRAwgAWQOsAGEDCAAIAAgACAAIAAgACABpAzQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFIQUoBSwFCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABtAwgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABMAEwACAAIAAgACAAIABgACAAIAAgACAC/AAgACAAyAQgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACACAAIAAwAAgACAAIAAgACAAIAAgACAAIAAAARABIAAgACAAIABQASAAIAAgAIABwAEAAjgCIABsAqAC2AL0AigDQAtwC+IJIQqVAZUBWQqVAZUBlQGVAZUBlQGrC5UBlQGVAZUBlQGVAZUBlQGVAXsKlQGVAbAK6wsrDGUMpQzlDJUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAfAKAAuZA64AtwCJALoC6ADwAAgAuACgA/oEpgO6AqsD+AAIAAgAswMIAAgACAAIAIkAuwP5AfsBwwPLAwgACAAIAAgACADRA9kDCAAIAOED6QMIAAgACAAIAAgACADuA/YDCAAIAP4DyQAIAAgABgQIAAgAXQAOBAgACAAIAAgACAAIABMECAAIAAgACAAIAAgACAD8AAQBCAAIAAgAGgQiBCoECAExBAgAEAEIAAgACAAIAAgACAAIAAgACAAIAAgACAA4BAgACABABEYECAAIAAgATAQYAQgAVAQIAAgACAAIAAgACAAIAAgACAAIAFoECAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAOQEIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAB+BAcACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAEABhgSMBAgACAAIAAgAlAQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAwAEAAQABAADAAMAAwADAAQABAAEAAQABAAEAAQABHATAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAdQMIAAgACAAIAAgACAAIAMkACAAIAAgAfQMIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACACFA4kDCAAIAAgACAAIAOcBCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAIcDCAAIAAgACAAIAAgACAAIAAgACAAIAJEDCAAIAAgACADFAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABgBAgAZgQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAbAQCBXIECAAIAHkECAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABAAJwEQACjBKoEsgQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAC6BMIECAAIAAgACAAIAAgACABmBAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAxwQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAGYECAAIAAgAzgQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAigWKBYoFigWKBYoFigWKBd0FXwUIAOIF6gXxBYoF3gT5BQAGCAaKBYoFigWKBYoFigWKBYoFigWKBYoFigXWBIoFigWKBYoFigWKBYoFigWKBYsFEAaKBYoFigWKBYoFigWKBRQGCACKBYoFigWKBQgACAAIANEECAAIABgGigUgBggAJgYIAC4GMwaKBYoF0wQ3Bj4GigWKBYoFigWKBYoFigWKBYoFigWKBYoFigUIAAgACAAIAAgACAAIAAgAigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWLBf///////wQABAAEAAQABAAEAAQABAAEAAQAAwAEAAQAAgAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAQADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAUAAAAFAAUAAAAFAAUAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEAAQABAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUAAQAAAAUABQAFAAUABQAFAAAAAAAFAAUAAAAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAFAAUAAQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABwAFAAUABQAFAAAABwAHAAcAAAAHAAcABwAFAAEAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAcABwAFAAUAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAQABAAAAAAAAAAAAAAAFAAUABQAFAAAABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAcABwAHAAcAAAAHAAcAAAAAAAUABQAHAAUAAQAHAAEABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABwABAAUABQAFAAUAAAAAAAAAAAAAAAEAAQABAAEAAQABAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABwAFAAUAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUAAQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABQANAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAEAAQABAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEAAQABAAEAAQABAAEAAQABAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAABQAHAAUABQAFAAAAAAAAAAcABQAFAAUABQAFAAQABAAEAAQABAAEAAQABAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUAAAAFAAUABQAFAAUAAAAFAAUABQAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAAAAAAAAAAAAUABQAFAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAUAAAAHAAcABwAFAAUABQAFAAUABQAFAAUABwAHAAcABwAFAAcABwAAAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAUABwAHAAUABQAFAAUAAAAAAAcABwAAAAAABwAHAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAABQAFAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAABwAHAAcABQAFAAAAAAAAAAAABQAFAAAAAAAFAAUABQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAFAAUABQAFAAUAAAAFAAUABwAAAAcABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAFAAUABwAFAAUABQAFAAAAAAAHAAcAAAAAAAcABwAFAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAcABwAAAAAAAAAHAAcABwAAAAcABwAHAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAABQAHAAcABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAHAAcABwAAAAUABQAFAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAcABQAHAAcABQAHAAcAAAAFAAcABwAAAAcABwAFAAUAAAAAAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAUABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAFAAcABwAFAAUABQAAAAUAAAAHAAcABwAHAAcABwAHAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAHAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAABwAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAUAAAAFAAAAAAAAAAAABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABwAFAAUABQAFAAUAAAAFAAUAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABwAFAAUABQAFAAUABQAAAAUABQAHAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABQAFAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAcABQAFAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAHAAUABQAFAAUABQAFAAUABwAHAAcABwAHAAcABwAHAAUABwAHAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABwAHAAcABwAFAAUABwAHAAcAAAAAAAAAAAAHAAcABQAHAAcABwAHAAcABwAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAcABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAHAAUABQAFAAUABQAFAAUAAAAFAAAABQAAAAAABQAFAAUABQAFAAUABQAFAAcABwAHAAcABwAHAAUABQAFAAUABQAFAAUABQAFAAUAAAAAAAUABQAFAAUABQAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABwAFAAcABwAHAAcABwAFAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAUABQAFAAUABwAHAAUABQAHAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAcABQAFAAcABwAHAAUABwAFAAUABQAHAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABwAHAAcABwAHAAUABQAFAAUABQAFAAUABQAHAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAcABQAFAAUABQAFAAUABQAAAAAAAAAAAAUAAAAAAAAAAAAAAAAABQAAAAAABwAFAAUAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUAAAAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAABQAAAAAAAAAFAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAUABQAHAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAHAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAHAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAcABwAFAAUABQAFAAcABwAFAAUABwAHAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAcABwAFAAUABwAHAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAFAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAFAAUABQAAAAAABQAFAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAFAAcABwAAAAAAAAAAAAAABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAFAAcABwAFAAcABwAAAAcABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAFAAUABQAAAAUABQAAAAAAAAAAAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABwAFAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABQAFAAUABQAFAAUABQAFAAUABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAHAAcABQAHAAUABQAAAAAAAAAAAAAAAAAFAAAABwAHAAcABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAHAAcABwAAAAAABwAHAAAAAAAHAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAAAAAAFAAUABQAFAAUABQAFAAAAAAAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAUABQAFAAUABwAHAAUABQAFAAcABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAcABQAFAAUABQAFAAUABwAFAAcABwAFAAcABQAFAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAcABQAFAAUABQAAAAAABwAHAAcABwAFAAUABwAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAHAAUABQAFAAUABQAFAAUABQAHAAcABQAHAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAFAAcABwAFAAUABQAFAAUABQAHAAUAAAAAAAAAAAAAAAAAAAAAAAcABwAFAAUABQAFAAcABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAUABQAFAAUABQAHAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAAAAAAFAAUABwAHAAcABwAFAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABwAHAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAFAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAcABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAAAHAAUABQAFAAUABQAFAAUABwAFAAUABwAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUAAAAAAAAABQAAAAUABQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAHAAcAAAAFAAUAAAAHAAcABQAHAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAAAAAAAAAAAAAAAAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAUABQAFAAAAAAAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAABQAFAAUABQAFAAUABQAAAAUABQAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAFAAUABQAFAAUADgAOAA4ADgAOAA4ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAAAAAAAAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAMAAwADAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAAAAAAAAAAAAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAAAAAAAAAAAAsADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwACwAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAADgAOAA4AAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAAAA4ADgAOAA4ADgAOAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAAAA4AAAAOAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAADgAAAAAAAAAAAA4AAAAOAAAAAAAAAAAADgAOAA4AAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAAAA4ADgAOAA4ADgAOAA4ADgAOAAAADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4AAAAAAAAAAAAAAAAAAAAAAA4ADgAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAOAA4ADgAOAA4ADgAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAAAAAAAAA=",hs="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",Ce=typeof Uint8Array>"u"?[]:new Uint8Array(256);for(Be=0;Be>4,B[s++]=(o&15)<<4|a>>2,B[s++]=(a&3)<<6|i&63;return c},yl=function(A){for(var e=A.length,t=[],r=0;r>MA,Kt=(1<>MA)+32,Ll=65536>>Er,Sl=(1<=0){if(e<55296||e>56319&&e<=65535)return t=this.index[e>>MA],t=(t<>MA)],t=(t<>Er),t=this.index[t],t+=e>>MA&Sl,t=this.index[t],t=(t<"u"?[]:new Uint8Array(256);for(le=0;le=55296&&s<=56319&&t>10)+55296,o%1024+56320)),(s+1===t||r.length>16384)&&(n+=String.fromCharCode.apply(String,r),r.length=0)}return n},Nl=Dl(El),rA="\xD7",Rt="\xF7",Gl=function(A){return Nl.get(A)},kl=function(A,e,t){var r=t-2,s=e[r],n=e[t-1],o=e[t];if(n===Dt&&o===Mt)return rA;if(n===Dt||n===Mt||n===ws||o===Dt||o===Mt||o===ws)return Rt;if(n===Qs&&[Qs,vt,fs,Cs].indexOf(o)!==-1||(n===fs||n===vt)&&(o===vt||o===Tt)||(n===Cs||n===Tt)&&o===Tt||o===Us||o===ds||o===Ol||n===Tl)return rA;if(n===Us&&o===Fs){for(;s===ds;)s=e[--r];if(s===Fs)return rA}if(n===Ot&&o===Ot){for(var a=0;s===Ot;)a++,s=e[--r];if(a%2===0)return rA}return Rt},Pl=function(A){var e=Rl(A),t=e.length,r=0,s=0,n=e.map(Gl);return{next:function(){if(r>=t)return{done:!0,value:null};for(var o=rA;r{if(A.createRange){let t=A.createRange();if(t.getBoundingClientRect){let r=A.createElement("boundtest");r.style.height="123px",r.style.display="block",A.body.appendChild(r),t.selectNode(r);let s=t.getBoundingClientRect(),n=Math.round(s.height);if(A.body.removeChild(r),n===123)return!0}}return!1},Wl=A=>{let e=A.createElement("boundtest");e.style.width="50px",e.style.display="block",e.style.fontSize="12px",e.style.letterSpacing="0px",e.style.wordSpacing="0px",A.body.appendChild(e);let t=A.createRange();e.innerHTML=typeof"".repeat=="function"?"👨".repeat(10):"";let r=e.firstChild,s=at(r.data).map(i=>R(i)),n=0,o={},a=s.every((i,c)=>{t.setStart(r,n),t.setEnd(r,n+i.length);let B=t.getBoundingClientRect();n+=i.length;let l=B.x>o.x||B.y>o.y;return o=B,c===0?!0:l});return A.body.removeChild(e),a},Jl=()=>typeof new Image().crossOrigin<"u",Yl=()=>typeof new XMLHttpRequest().responseType=="string",Zl=A=>{let e=new Image,t=A.createElement("canvas"),r=t.getContext("2d");if(!r)return!1;e.src="data:image/svg+xml,";try{r.drawImage(e,0,0),t.toDataURL()}catch{return!1}return!0},ps=A=>A[0]===0&&A[1]===255&&A[2]===0&&A[3]===255,zl=A=>{let e=A.createElement("canvas"),t=100;e.width=t,e.height=t;let r=e.getContext("2d");if(!r)return Promise.reject(new Error("Failed to get 2D rendering context"));r.fillStyle="rgb(0, 255, 0)",r.fillRect(0,0,t,t);let s=new Image,n=e.toDataURL();s.src=n;let o=lr(t,t,0,0,s);return r.fillStyle="red",r.fillRect(0,0,t,t),hr(o).then(a=>{r.drawImage(a,0,0);let i=r.getImageData(0,0,t,t).data;r.fillStyle="red",r.fillRect(0,0,t,t);let c=A.createElement("div");return c.style.backgroundImage=`url(${n})`,c.style.height=`${t}px`,ps(i)?hr(lr(t,t,0,0,c)):Promise.reject(new Error("ForeignObject rendering not supported"))}).then(a=>(r.drawImage(a,0,0),ps(r.getImageData(0,0,t,t).data))).catch(()=>!1)},lr=(A,e,t,r,s)=>{let n="http://www.w3.org/2000/svg",o=document.createElementNS(n,"svg"),a=document.createElementNS(n,"foreignObject");return o.setAttributeNS(null,"width",A.toString()),o.setAttributeNS(null,"height",e.toString()),a.setAttributeNS(null,"width","100%"),a.setAttributeNS(null,"height","100%"),a.setAttributeNS(null,"x",t.toString()),a.setAttributeNS(null,"y",r.toString()),a.setAttributeNS(null,"externalResourcesRequired","true"),o.appendChild(a),a.appendChild(s),o},hr=A=>new Promise((e,t)=>{let r=new Image;r.onload=()=>e(r),r.onerror=t,r.src=`data:image/svg+xml;charset=utf-8,${encodeURIComponent(new XMLSerializer().serializeToString(A))}`}),X={get SUPPORT_RANGE_BOUNDS(){"use strict";let A=_l(document);return Object.defineProperty(X,"SUPPORT_RANGE_BOUNDS",{value:A}),A},get SUPPORT_WORD_BREAKING(){"use strict";let A=X.SUPPORT_RANGE_BOUNDS&&Wl(document);return Object.defineProperty(X,"SUPPORT_WORD_BREAKING",{value:A}),A},get SUPPORT_SVG_DRAWING(){"use strict";let A=Zl(document);return Object.defineProperty(X,"SUPPORT_SVG_DRAWING",{value:A}),A},get SUPPORT_FOREIGNOBJECT_DRAWING(){"use strict";let A=typeof Array.from=="function"&&typeof window.fetch=="function"?zl(document):Promise.resolve(!1);return Object.defineProperty(X,"SUPPORT_FOREIGNOBJECT_DRAWING",{value:A}),A},get SUPPORT_CORS_IMAGES(){"use strict";let A=Jl();return Object.defineProperty(X,"SUPPORT_CORS_IMAGES",{value:A}),A},get SUPPORT_RESPONSE_TYPE(){"use strict";let A=Yl();return Object.defineProperty(X,"SUPPORT_RESPONSE_TYPE",{value:A}),A},get SUPPORT_CORS_XHR(){"use strict";let A="withCredentials"in new XMLHttpRequest;return Object.defineProperty(X,"SUPPORT_CORS_XHR",{value:A}),A},get SUPPORT_NATIVE_TEXT_SEGMENTATION(){"use strict";let A=!!(typeof Intl<"u"&&Intl.Segmenter);return Object.defineProperty(X,"SUPPORT_NATIVE_TEXT_SEGMENTATION",{value:A}),A}},vA=class{constructor(A,e){this.text=A,this.bounds=e}},$l=(A,e,t,r)=>{let s=Ah(e,t),n=[],o=0;return s.forEach(a=>{if(t.textDecorationLine.length||a.trim().length>0)if(X.SUPPORT_RANGE_BOUNDS){let i=ms(r,o,a.length).getClientRects();if(i.length>1){let c=UA(a),B=0;c.forEach(l=>{n.push(new vA(l,_.fromDOMRectList(A,ms(r,B+o,l.length).getClientRects()))),B+=l.length})}else n.push(new vA(a,_.fromDOMRectList(A,i)))}else{let i=r.splitText(a.length);n.push(new vA(a,ql(A,r))),r=i}else X.SUPPORT_RANGE_BOUNDS||(r=r.splitText(a.length));o+=a.length}),n},ql=(A,e)=>{let t=e.ownerDocument;if(t){let r=t.createElement("html2canvaswrapper");r.appendChild(e.cloneNode(!0));let s=e.parentNode;if(s){s.replaceChild(r,e);let n=ye(A,r);return r.firstChild&&s.replaceChild(r.firstChild,r),n}}return _.EMPTY},ms=(A,e,t)=>{let r=A.ownerDocument;if(!r)throw new Error("Node has no owner document");let s=r.createRange();return s.setStart(A,e),s.setEnd(A,e+t),s},Es=new Map,Xn=A=>{let e=Es.get(A);if(!e){let t=Intl.Segmenter;e=new t(void 0,{granularity:A}),Es.set(A,e)}return e},UA=A=>X.SUPPORT_NATIVE_TEXT_SEGMENTATION?Array.from(Xn("grapheme").segment(A)).map(e=>e.segment):Xl(A),jl=(A,e)=>X.SUPPORT_NATIVE_TEXT_SEGMENTATION?Array.from(Xn("word").segment(A)).map(t=>t.segment):th(A,e),Ah=(A,e)=>Ee(e.writingMode)||e.letterSpacing!==0?UA(A):jl(A,e),eh=[32,160,4961,65792,65793,4153,4241],th=(A,e)=>{let t=Wo(A,{lineBreak:e.lineBreak,wordBreak:e.overflowWrap==="break-word"?"break-word":e.wordBreak}),r=[],s;for(;!(s=t.next()).done;)if(s.value){let n=at(s.value.slice()),o="";n.forEach(a=>{eh.indexOf(a)===-1?o+=R(a):(o.length&&r.push(o),r.push(R(a)),o="")}),o.length&&r.push(o)}return r},rh=class{constructor(A,e,t){this.text=sh(e.data,t.textTransform),this.text.length!==e.data.length&&(e.data=this.text),this.textBounds=$l(A,this.text,t,e)}},sh=(A,e)=>{switch(e){case 1:return A.toLowerCase();case 3:return A.replace(nh,oh);case 2:return A.toUpperCase();default:return A}},nh=/(^|\s|:|-|\(|\))([a-z])/g,oh=(A,e,t)=>A.length>0?e+t.toUpperCase():A,_n=class extends uA{constructor(A,e){super(A,e),this.src=e.currentSrc||e.src,this.intrinsicWidth=e.naturalWidth,this.intrinsicHeight=e.naturalHeight,this.context.cache.addImage(this.src)}},Wn=class extends uA{constructor(A,e){super(A,e),this.canvas=e,this.intrinsicWidth=e.width,this.intrinsicHeight=e.height}},ih=["position","inset","top","right","bottom","left","inset-inline","inset-inline-start","inset-inline-end","inset-block","inset-block-start","inset-block-end","margin","margin-top","margin-right","margin-bottom","margin-left","margin-inline","margin-inline-start","margin-inline-end","margin-block","margin-block-start","margin-block-end"],ah=(A,e)=>{let t=e.getAttribute("style");ih.forEach(s=>e.style.removeProperty(s));let r=A.serializeToString(e);return t===null?e.removeAttribute("style"):e.setAttribute("style",t),r},Jn=class extends uA{constructor(A,e){super(A,e);let t=new XMLSerializer,r=ye(A,e);e.setAttribute("width",`${r.width}px`),e.setAttribute("height",`${r.height}px`),this.svg=`data:image/svg+xml,${encodeURIComponent(ah(t,e))}`,this.intrinsicWidth=e.width.baseVal.value,this.intrinsicHeight=e.height.baseVal.value,this.context.cache.addImage(this.svg)}},Yn=class extends uA{constructor(A,e){super(A,e),this.value=e.value}},gr=class extends uA{constructor(A,e){super(A,e),this.start=e.start,this.reversed=typeof e.reversed=="boolean"&&e.reversed===!0}},ch=[{type:15,flags:0,unit:"px",number:3}],Bh=[{type:16,flags:0,number:50}],lh=A=>A.width>A.height?new _(A.left+(A.width-A.height)/2,A.top,A.height,A.height):A.width{let e=A.type==="password"?new Array(A.value.length+1).join("\u2022"):A.value;return e.length===0?A.placeholder||"":e},gh=A=>A.value.length===0&&!!A.placeholder,uh="checkbox",wh="radio",dh=1970632191,qA=class extends uA{constructor(A,e){switch(super(A,e),this.type=e.type.toLowerCase(),this.checked=e.checked,this.value=hh(e),this.isPlaceholder=gh(e),(this.type==="checkbox"||this.type==="radio")&&(this.styles.backgroundColor=3739148031,this.styles.borderTopColor=this.styles.borderRightColor=this.styles.borderBottomColor=this.styles.borderLeftColor=2779096575,this.styles.borderTopWidth=this.styles.borderRightWidth=this.styles.borderBottomWidth=this.styles.borderLeftWidth=1,this.styles.borderTopStyle=this.styles.borderRightStyle=this.styles.borderBottomStyle=this.styles.borderLeftStyle=1,this.styles.backgroundClip=[0],this.styles.backgroundOrigin=[0],this.bounds=lh(this.bounds)),this.type){case uh:this.styles.borderTopRightRadius=this.styles.borderTopLeftRadius=this.styles.borderBottomRightRadius=this.styles.borderBottomLeftRadius=ch;break;case wh:this.styles.borderTopRightRadius=this.styles.borderTopLeftRadius=this.styles.borderBottomRightRadius=this.styles.borderBottomLeftRadius=Bh}}},Zn=class extends uA{constructor(A,e){super(A,e);let t=e.options[e.selectedIndex||0];this.value=t&&t.text||""}},zn=class extends uA{constructor(A,e){super(A,e),this.value=e.value}},$n=class extends uA{constructor(A,e,t){super(A,e),this.src=e.src,this.width=parseInt(e.width,10)||0,this.height=parseInt(e.height,10)||0,this.backgroundColor=this.styles.backgroundColor,this.parseTreeFn=t;try{if(e.contentWindow&&e.contentWindow.document&&e.contentWindow.document.documentElement&&this.parseTreeFn){this.tree=this.parseTreeFn(A,e.contentWindow.document.documentElement);let r=e.contentWindow.document.documentElement?jA(A,getComputedStyle(e.contentWindow.document.documentElement).backgroundColor):0,s=e.contentWindow.document.body?jA(A,getComputedStyle(e.contentWindow.document.body).backgroundColor):0;this.backgroundColor=BA(r)?BA(s)?this.styles.backgroundColor:s:r}}catch{}}},Qh=["OL","UL","MENU"],ur=(A,e,t,r)=>{for(let s=e.firstChild,n;s;s=n)n=s.nextSibling,qn(A,s,t,r)},qn=(A,e,t,r)=>{if(ln(e)&&e.data.length>0)t.textNodes.push(new rh(A,e,t.styles));else if(SA(e))if(fe(e)&&e.assignedNodes)e.assignedNodes().forEach(s=>qn(A,s,t,r));else{let s=jn(A,e);s.styles.isVisible()&&(fh(e,s,r)?s.createsRealStackingContext=!0:Ch(s.styles)&&(s.createsStackingContext=!0),Qh.indexOf(e.tagName)!==-1&&(s.isListOwner=!0),t.elements.push(s),e.shadowRoot?ur(A,e.shadowRoot,s,r):!tt(e)&&!hn(e)&&!rt(e)&&ur(A,e,s,r))}},jn=(A,e)=>er(e)?new _n(A,e):gn(e)?new Wn(A,e):hn(e)?new Jn(A,e):Ua(e)?new Yn(A,e):Fa(e)?new gr(A,e):Qa(e)?new qA(A,e):rt(e)?new Zn(A,e):tt(e)?new zn(A,e):un(e)?new $n(A,e,Ao):new uA(A,e),Ao=(A,e)=>{let t=jn(A,e);return t.createsRealStackingContext=!0,ur(A,e,t,t),t},fh=(A,e,t)=>e.styles.isPositionedWithZIndex()||e.styles.opacity<1||!!e.styles.filter||!!e.styles.backdropFilter||e.styles.maskImage.length>0||!!e.styles.webkitBoxReflect||e.styles.isolation===1||e.styles.isTransformed()||pr(A)&&t.styles.isTransparent(),Ch=A=>A.isPositioned()||A.isFloating()?!0:P(A.display,268435456)||P(A.display,33554432)||P(A.display,536870912)||P(A.display,134217728),Hs=(A,e)=>A.length===e.length?A.some((t,r)=>t===e[r]):!1,st=(A,e,t,r,s)=>A.map((n,o)=>{switch(o){case 0:return n.add(e,t);case 1:return n.add(e+r,t);case 2:return n.add(e+r,t+s);case 3:return n.add(e,t+s)}return n}),F=class eo{constructor(e,t){this.type=0,this.x=e,this.y=t}add(e,t){return new eo(this.x+e,this.y+t)}},XA=(A,e,t)=>new F(A.x+(e.x-A.x)*t,A.y+(e.y-A.y)*t),Ue=class Fe{constructor(e,t,r,s){this.type=1,this.start=e,this.startControl=t,this.endControl=r,this.end=s}subdivide(e,t){let r=XA(this.start,this.startControl,e),s=XA(this.startControl,this.endControl,e),n=XA(this.endControl,this.end,e),o=XA(r,s,e),a=XA(s,n,e),i=XA(o,a,e);return t?new Fe(this.start,r,o,i):new Fe(i,a,n,this.end)}add(e,t){return new Fe(this.start.add(e,t),this.startControl.add(e,t),this.endControl.add(e,t),this.end.add(e,t))}reverse(){return new Fe(this.end,this.endControl,this.startControl,this.start)}},Y=A=>A.type===1,Uh=class{constructor(A){let e=A.styles,t=A.bounds,[r,s]=Qe(e.borderTopLeftRadius,t.width,t.height),[n,o]=Qe(e.borderTopRightRadius,t.width,t.height),[a,i]=Qe(e.borderBottomRightRadius,t.width,t.height),[c,B]=Qe(e.borderBottomLeftRadius,t.width,t.height),l=[];l.push((r+n)/t.width),l.push((c+a)/t.width),l.push((s+B)/t.height),l.push((o+i)/t.height);let h=Math.max(...l);h>1&&(r/=h,s/=h,n/=h,o/=h,a/=h,i/=h,c/=h,B/=h);let g=t.width-n,u=t.height-i,d=t.width-a,Q=t.height-B,f=e.borderTopWidth,C=e.borderRightWidth,p=e.borderBottomWidth,U=e.borderLeftWidth,E=m(e.paddingTop,A.bounds.width),I=m(e.paddingRight,A.bounds.width),S=m(e.paddingBottom,A.bounds.width),y=m(e.paddingLeft,A.bounds.width);this.topLeftBorderDoubleOuterBox=r>0||s>0?K(t.left+U/3,t.top+f/3,r-U/3,s-f/3,0):new F(t.left+U/3,t.top+f/3),this.topRightBorderDoubleOuterBox=r>0||s>0?K(t.left+g,t.top+f/3,n-C/3,o-f/3,1):new F(t.left+t.width-C/3,t.top+f/3),this.bottomRightBorderDoubleOuterBox=a>0||i>0?K(t.left+d,t.top+u,a-C/3,i-p/3,2):new F(t.left+t.width-C/3,t.top+t.height-p/3),this.bottomLeftBorderDoubleOuterBox=c>0||B>0?K(t.left+U/3,t.top+Q,c-U/3,B-p/3,3):new F(t.left+U/3,t.top+t.height-p/3),this.topLeftBorderDoubleInnerBox=r>0||s>0?K(t.left+U*2/3,t.top+f*2/3,r-U*2/3,s-f*2/3,0):new F(t.left+U*2/3,t.top+f*2/3),this.topRightBorderDoubleInnerBox=r>0||s>0?K(t.left+g,t.top+f*2/3,n-C*2/3,o-f*2/3,1):new F(t.left+t.width-C*2/3,t.top+f*2/3),this.bottomRightBorderDoubleInnerBox=a>0||i>0?K(t.left+d,t.top+u,a-C*2/3,i-p*2/3,2):new F(t.left+t.width-C*2/3,t.top+t.height-p*2/3),this.bottomLeftBorderDoubleInnerBox=c>0||B>0?K(t.left+U*2/3,t.top+Q,c-U*2/3,B-p*2/3,3):new F(t.left+U*2/3,t.top+t.height-p*2/3),this.topLeftBorderStroke=r>0||s>0?K(t.left+U/2,t.top+f/2,r-U/2,s-f/2,0):new F(t.left+U/2,t.top+f/2),this.topRightBorderStroke=r>0||s>0?K(t.left+g,t.top+f/2,n-C/2,o-f/2,1):new F(t.left+t.width-C/2,t.top+f/2),this.bottomRightBorderStroke=a>0||i>0?K(t.left+d,t.top+u,a-C/2,i-p/2,2):new F(t.left+t.width-C/2,t.top+t.height-p/2),this.bottomLeftBorderStroke=c>0||B>0?K(t.left+U/2,t.top+Q,c-U/2,B-p/2,3):new F(t.left+U/2,t.top+t.height-p/2),this.topLeftBorderBox=r>0||s>0?K(t.left,t.top,r,s,0):new F(t.left,t.top),this.topRightBorderBox=n>0||o>0?K(t.left+g,t.top,n,o,1):new F(t.left+t.width,t.top),this.bottomRightBorderBox=a>0||i>0?K(t.left+d,t.top+u,a,i,2):new F(t.left+t.width,t.top+t.height),this.bottomLeftBorderBox=c>0||B>0?K(t.left,t.top+Q,c,B,3):new F(t.left,t.top+t.height),this.topLeftPaddingBox=r>0||s>0?K(t.left+U,t.top+f,Math.max(0,r-U),Math.max(0,s-f),0):new F(t.left+U,t.top+f),this.topRightPaddingBox=n>0||o>0?K(t.left+Math.min(g,t.width-C),t.top+f,g>t.width+C?0:Math.max(0,n-C),Math.max(0,o-f),1):new F(t.left+t.width-C,t.top+f),this.bottomRightPaddingBox=a>0||i>0?K(t.left+Math.min(d,t.width-U),t.top+Math.min(u,t.height-p),Math.max(0,a-C),Math.max(0,i-p),2):new F(t.left+t.width-C,t.top+t.height-p),this.bottomLeftPaddingBox=c>0||B>0?K(t.left+U,t.top+Math.min(Q,t.height-p),Math.max(0,c-U),Math.max(0,B-p),3):new F(t.left+U,t.top+t.height-p),this.topLeftContentBox=r>0||s>0?K(t.left+U+y,t.top+f+E,Math.max(0,r-(U+y)),Math.max(0,s-(f+E)),0):new F(t.left+U+y,t.top+f+E),this.topRightContentBox=n>0||o>0?K(t.left+Math.min(g,t.width+U+y),t.top+f+E,g>t.width+U+y?0:n-U+y,o-(f+E),1):new F(t.left+t.width-(C+I),t.top+f+E),this.bottomRightContentBox=a>0||i>0?K(t.left+Math.min(d,t.width-(U+y)),t.top+Math.min(u,t.height+f+E),Math.max(0,a-(C+I)),i-(p+S),2):new F(t.left+t.width-(C+I),t.top+t.height-(p+S)),this.bottomLeftContentBox=c>0||B>0?K(t.left+U+y,t.top+Q,Math.max(0,c-(U+y)),B-(p+S),3):new F(t.left+U+y,t.top+t.height-(p+S))}},K=(A,e,t,r,s)=>{let n=4*((Math.sqrt(2)-1)/3),o=t*n,a=r*n,i=A+t,c=e+r;switch(s){case 0:return new Ue(new F(A,c),new F(A,c-a),new F(i-o,e),new F(i,e));case 1:return new Ue(new F(A,e),new F(A+o,e),new F(i,c-a),new F(i,c));case 2:return new Ue(new F(i,e),new F(i,e+a),new F(A+o,c),new F(A,c));default:return new Ue(new F(i,c),new F(i-o,c),new F(A,e+a),new F(A,e))}},hA=A=>[A.topLeftBorderBox,A.topRightBorderBox,A.bottomRightBorderBox,A.bottomLeftBorderBox],Fh=A=>[A.topLeftContentBox,A.topRightContentBox,A.bottomRightContentBox,A.bottomLeftContentBox],mA=A=>[A.topLeftPaddingBox,A.topRightPaddingBox,A.bottomRightPaddingBox,A.bottomLeftPaddingBox],Vt=class{constructor(A,e,t){this.offsetX=A,this.offsetY=e,this.matrix=t,this.type=0,this.target=6}},Xe=class{constructor(A,e){this.path=A,this.target=e,this.type=1}},ph=class{constructor(A){this.opacity=A,this.type=2,this.target=6}},_A=class{constructor(A){this.applyClip=A,this.type=3,this.target=6}},mh={[V.NORMAL]:"source-over",[V.MULTIPLY]:"multiply",[V.SCREEN]:"screen",[V.OVERLAY]:"overlay",[V.DARKEN]:"darken",[V.LIGHTEN]:"lighten",[V.COLOR_DODGE]:"color-dodge",[V.COLOR_BURN]:"color-burn",[V.HARD_LIGHT]:"hard-light",[V.SOFT_LIGHT]:"soft-light",[V.DIFFERENCE]:"difference",[V.EXCLUSION]:"exclusion",[V.HUE]:"hue",[V.SATURATION]:"saturation",[V.COLOR]:"color",[V.LUMINOSITY]:"luminosity"},Eh=class{constructor(A){this.mixBlendMode=A,this.type=4,this.target=6,this.compositeOperation=mh[A]}},to=class $A{constructor(e){this.type=5,this.target=6;let t=$A.parseDropShadow(e);this.shadow=t.shadow,this.safeFilterString=t.safeFilterString}static parseDropShadow(e){if(!e)return{safeFilterString:""};let t=$A.findDropShadows(e);if(t.length===0)return{safeFilterString:e};let r=$A.parseDropShadowBody(w(t,0).body),s="",n=0;for(let o of t)s+=e.slice(n,o.start),n=o.end;return s+=e.slice(n),{shadow:r,safeFilterString:s.replace(/\s+/g," ").trim()}}static findDropShadows(e){let t=[],r=/drop-shadow\(/gi,s;for(;(s=r.exec(e))!==null;){let n=s.index+12-1,o=s.index,a=1,i=n+1;for(;i0;){let B=e[i]??"";B==="("?a++:B===")"&&a--,i++}if(a!==0)break;let c=e.slice(n+1,i-1);t.push({body:c,start:o,end:i})}return t}static parseDropShadowBody(e){let t=$A.tokenizeFilterArgs(e.trim()),r=[],s;for(let n of t)$A.isCSSLength(n)?r.push(parseFloat(n)):n&&(s=n);if(!(r.length<2||r.length>3))return{offsetX:w(r,0),offsetY:w(r,1),blur:r.length>2?w(r,2):0,color:s??"rgba(0,0,0,1)"}}static tokenizeFilterArgs(e){let t=[],r="",s=0;for(let n=0;n0?r+=o:r&&(t.push(r),r=""):r+=o}return r&&t.push(r),t}static isCSSLength(e){return/^-?[\d.]+(px|em|rem|pt|cm|mm|in|pc|ex|ch|vw|vh|vmin|vmax|%)?$/i.test(e)}},ys=A=>A.type===0,nt=A=>A.type===1,Hr=A=>A.type===2,Is=A=>A.type===3,Hh=A=>A.type===4,yr=A=>A.type===5,ro=class{constructor(A){this.element=A,this.inlineLevel=[],this.nonInlineLevel=[],this.negativeZIndex=[],this.zeroOrAutoZIndexOrTransformedOrOpacity=[],this.positiveZIndex=[],this.nonPositionedFloats=[],this.nonPositionedInlineLevel=[]}},so=class{constructor(A,e){if(this.container=A,this.parent=e,this.effects=[],this.plainEffectsCache=null,this.curves=new Uh(this.container),this.container.styles.opacity<1&&this.effects.push(new ph(this.container.styles.opacity)),this.container.styles.rotate!==null){let t=this.container.styles.transformOrigin,r=this.container.bounds.left+m(t[0],this.container.bounds.width),s=this.container.bounds.top+m(t[1],this.container.bounds.height),n=this.container.styles.rotate*Math.PI/180,o=Math.cos(n),a=Math.sin(n),i=[o,a,-a,o,0,0];this.effects.push(new Vt(r,s,i))}if(this.container.styles.transform!==null){let t=this.container.styles.transformOrigin,r=this.container.bounds.left+m(t[0],this.container.bounds.width),s=this.container.bounds.top+m(t[1],this.container.bounds.height),n=this.container.styles.transform;this.effects.push(new Vt(r,s,n))}if(bs(this.container.styles)){let t=hA(this.curves),r=mA(this.curves);Hs(t,r)?this.effects.push(new Xe(t,6)):(this.effects.push(new Xe(t,2)),this.effects.push(new Xe(r,4)))}if(this.container.styles.clipPath.type!==0){let t=yh(this.container.styles.clipPath,this.container.bounds);t&&this.effects.push(t)}if(this.container.styles.mixBlendMode!==V.NORMAL&&this.effects.push(new Eh(this.container.styles.mixBlendMode)),this.container.styles.filter!==null&&this.effects.push(new to(this.container.styles.filter)),this.container.styles.zoom!==1){let t=this.container.styles.transformOrigin,r=this.container.bounds.left+m(t[0],this.container.bounds.width),s=this.container.bounds.top+m(t[1],this.container.bounds.height),n=this.container.styles.zoom,o=[n,0,0,n,0,0];this.effects.push(new Vt(r,s,o))}}getEffects(A,e){if(!e){let t=this.plainEffectsCache;t||(t=new Map,this.plainEffectsCache=t);let r=t.get(A);return r||(r=this.computeEffects(A),t.set(A,r)),r}return this.computeEffects(A,e)}computeEffects(A,e){let t=[2,3].indexOf(this.container.styles.position)===-1,r=this===e?null:this.parent,s=o=>o.effects.filter(a=>o!==e||!yr(a)&&!Hr(a)),n=s(this);for(;r;){let o=s(r).filter(a=>!nt(a));if(t||r.container.styles.position!==0||!r.parent){if(t=[2,3].indexOf(r.container.styles.position)===-1,bs(r.container.styles)){let a=hA(r.curves),i=mA(r.curves);Hs(a,i)||n.unshift(new Xe(i,6))}n.unshift(...o)}else n.unshift(...o);r=r===e?null:r.parent}return n.filter(o=>P(o.target,A))}},bs=A=>A.overflowX!==0||A.overflowY!==0,xs=(A,e,t,r,s)=>A==="closest-side"?Math.min(e-t,r-e):A==="farthest-side"?Math.max(e-t,r-e):m(A,s),yh=(A,e)=>{let{left:t,top:r,width:s,height:n}=e;switch(A.type){case 1:{let o=m(A.left,s),a=m(A.top,n),i=t+o,c=r+a,B=Math.max(0,s-o-m(A.right,s)),l=Math.max(0,n-a-m(A.bottom,n));return new _A(h=>{h.beginPath(),h.rect(i,c,B,l),h.clip()})}case 2:{let o=t+m(A.cx,s),a=r+m(A.cy,n),i;return A.radius==="closest-side"?i=Math.min(o-t,a-r,t+s-o,r+n-a):A.radius==="farthest-side"?i=Math.max(o-t,a-r,t+s-o,r+n-a):i=m(A.radius,Math.sqrt(s*s+n*n)/Math.SQRT2),new _A(c=>{c.beginPath(),c.arc(o,a,Math.max(0,i),0,Math.PI*2),c.clip()})}case 3:{let o=t+m(A.cx,s),a=r+m(A.cy,n),i=xs(A.rx,o,t,t+s,s),c=xs(A.ry,a,r,r+n,n);return new _A(B=>{B.beginPath(),B.ellipse(o,a,Math.max(0,i),Math.max(0,c),0,0,Math.PI*2),B.clip()})}case 4:{let o=A.points.map(([a,i])=>[t+m(a,s),r+m(i,n)]);return new _A(a=>{if(a.beginPath(),o.length>0){a.moveTo(w(w(o,0),0),w(w(o,0),1));for(let i=1;i{try{a||(a=new Path2D(o));let c=i.getTransform();i.translate(t,r),i.clip(a),i.setTransform(c)}catch{}})}case 6:{let o=t+m(A.x,s),a=r+m(A.y,n),i=Math.max(0,m(A.width,s)),c=Math.max(0,m(A.height,n));return new _A(B=>{B.beginPath(),B.rect(o,a,i,c),B.clip()})}case 0:return null;default:return null}},wr=(A,e,t,r)=>{A.container.elements.forEach(s=>{let n=s.createsRealStackingContext,o=s.createsStackingContext,a=new so(s,A);P(s.styles.display,2048)&&r.push(a);let i=s.isListOwner?[]:r;if(n||o){let c=n||s.styles.isPositioned()?t:e,B=new ro(a);if(s.styles.isPositioned()||s.styles.opacity<1||s.styles.isTransformed()){let l=s.styles.zIndex.order;if(l<0){let h=0;c.negativeZIndex.some((g,u)=>l>g.element.container.styles.zIndex.order?(h=u,!1):h>0),c.negativeZIndex.splice(h,0,B)}else if(l>0){let h=0;c.positiveZIndex.some((g,u)=>l>=g.element.container.styles.zIndex.order?(h=u+1,!1):h>0),c.positiveZIndex.splice(h,0,B)}else c.zeroOrAutoZIndexOrTransformedOrOpacity.push(B)}else s.styles.isFloating()?c.nonPositionedFloats.push(B):c.nonPositionedInlineLevel.push(B);wr(a,B,n?B:t,i)}else s.styles.isInlineLevel()?e.inlineLevel.push(a):e.nonInlineLevel.push(a),wr(a,e,t,i);s.isListOwner&&no(s,i)})},no=(A,e)=>{let t=A instanceof gr?A.start:1,r=A instanceof gr?A.reversed:!1;for(let s=0;s{let e=new so(A,null),t=new ro(e),r=[];return wr(e,t,t,r),no(e.container,r),t},re=A=>{let e=A.bounds,t=A.styles;return e.add(t.borderLeftWidth,t.borderTopWidth,-(t.borderRightWidth+t.borderLeftWidth),-(t.borderTopWidth+t.borderBottomWidth))},Se=A=>{let e=A.styles,t=A.bounds,r=m(e.paddingLeft,t.width),s=m(e.paddingRight,t.width),n=m(e.paddingTop,t.width),o=m(e.paddingBottom,t.width);return t.add(r+e.borderLeftWidth,n+e.borderTopWidth,-(e.borderRightWidth+e.borderLeftWidth+r+s),-(e.borderTopWidth+e.borderBottomWidth+n+o))},bh=(A,e)=>A===0?e.bounds:A===2?Se(e):re(e),xh=(A,e)=>A===0?e.bounds:A===2?Se(e):re(e),WA=(A,e,t)=>{let r=bh(LA(A.styles.backgroundOrigin,e),A),s=xh(LA(A.styles.backgroundClip,e),A),n=Lh(LA(A.styles.backgroundSize,e),t,r),[o,a]=n,i=Qe(LA(A.styles.backgroundPosition,e),r.width-o,r.height-a),c=Sh(LA(A.styles.backgroundRepeat,e),i,n,r,s),B=Math.round(r.left+i[0]),l=Math.round(r.top+i[1]);return o=Math.max(1,o),a=Math.max(1,a),[c,B,l,o,a]},JA=A=>H(A)&&A.value==="auto",_e=A=>typeof A=="number",Lh=(A,[e,t,r],s)=>{let[n,o]=A;if(!n)return[0,0];if(x(n)&&o&&x(o))return[m(n,s.width),m(o,s.height)];let a=_e(r);if(H(n)&&(n.value==="contain"||n.value==="cover"))return _e(r)?s.width/s.height{let t=A[e];return typeof t>"u"?w(A,0):t},Sh=(A,[e,t],[r,s],n,o)=>{switch(A){case 2:return[new F(Math.round(n.left),Math.round(n.top+t)),new F(Math.round(n.left+n.width),Math.round(n.top+t)),new F(Math.round(n.left+n.width),Math.round(s+n.top+t)),new F(Math.round(n.left),Math.round(s+n.top+t))];case 3:return[new F(Math.round(n.left+e),Math.round(n.top)),new F(Math.round(n.left+e+r),Math.round(n.top)),new F(Math.round(n.left+e+r),Math.round(n.height+n.top)),new F(Math.round(n.left+e),Math.round(n.height+n.top))];case 1:return[new F(Math.round(n.left+e),Math.round(n.top+t)),new F(Math.round(n.left+e+r),Math.round(n.top+t)),new F(Math.round(n.left+e+r),Math.round(n.top+t+s)),new F(Math.round(n.left+e),Math.round(n.top+t+s))];default:return[new F(Math.round(o.left),Math.round(o.top)),new F(Math.round(o.left+o.width),Math.round(o.top)),new F(Math.round(o.left+o.width),Math.round(o.height+o.top)),new F(Math.round(o.left),Math.round(o.height+o.top))]}},oA=A=>{if(A?.aborted)throw new DOMException("The operation was aborted.","AbortError")},j=class extends Error{},N=A=>{A.width=A.height=0},Kh=256,IA=new Map;function je(A){if(!A||A==="none")return{blur:0};let e=IA.get(A);if(e!==void 0)return IA.delete(A),IA.set(A,e),e;let t=Dh(A);if(IA.size>=Kh){let r=IA.keys().next().value;r!==void 0&&IA.delete(r)}return IA.set(A,t),t}function Dh(A){let e=new to(A),t=A.match(/drop-shadow\(/g)||[];if(t.length>1||t.length===1&&!e.shadow)return null;let r=e.safeFilterString.match(/^blur\((\d+(?:\.\d+)?)px\)$/);return e.safeFilterString&&!r||r&&t.length&&A.indexOf("blur(")>A.indexOf("drop-shadow(")?null:{blur:r?Number(r[1]):0,shadow:e.shadow?{x:e.shadow.offsetX,y:e.shadow.offsetY,blur:e.shadow.blur,color:e.shadow.color}:void 0}}function oo(A){return Math.ceil(3*(A.blur+(A.shadow?.blur??0))+Math.max(Math.abs(A.shadow?.x??0),Math.abs(A.shadow?.y??0)))}function ot(A){let e=document.createElement("canvas");return e.width=A.width,e.height=A.height,e}var Mh=(A,e)=>new Promise((t,r)=>{let s=a=>{clearTimeout(o),e?.removeEventListener("abort",n),a?r(a):t()},n=()=>s(new DOMException("The operation was aborted.","AbortError")),o=setTimeout(()=>s(new j("Filter surface image decode timed out")),1e4);e?.addEventListener("abort",n,{once:!0}),e?.aborted?n():A.decode().then(()=>s(),()=>s(new j("Filter surface image decode failed")))}),Ls=new WeakMap;function vh(A=document){let e=Ls.get(A);if(e!==void 0)return e;let t=A.createElement("canvas"),r=A.createElement("canvas"),s=!1;try{t.width=t.height=r.width=r.height=32;let n=t.getContext("2d"),o=r.getContext("2d");if(n&&o&&"filter"in o){n.fillStyle="#fff",n.fillRect(8,8,8,8),o.filter="blur(2px)",o.drawImage(t,0,0);let a=(o.getImageData(6,12,1,1).data[3]??0)>0;o.clearRect(0,0,32,32),o.filter="drop-shadow(12px 0px 0px rgba(255, 0, 0, 0.5))",o.drawImage(t,0,0);let i=o.getImageData(24,12,1,1).data;s=a&&(i[0]??0)>240&&(i[1]??0)<10&&(i[3]??0)>=126&&(i[3]??0)<=129}}catch{}finally{N(t),N(r)}return Ls.set(A,s),s}function Th(A,{blur:e,shadow:t},r,s,n){let o,a,i=!1;try{oA(n),o=ot(A);let c=o.getContext("2d");if(!c||!("filter"in c))return null;let B=[];if(e&&B.push(`blur(${e*s}px)`),t&&B.push(`drop-shadow(${t.x*s}px ${t.y*s}px ${t.blur*s}px ${t.color})`),c.filter=B.join(" "),c.filter==="none")return null;c.drawImage(A,0,0),oA(n),a=ot(A);let l=a.getContext("2d");return l?(l.globalAlpha=r,l.drawImage(o,0,0),oA(n),i=!0,a):null}catch{return oA(n),null}finally{o&&N(o),a&&!i&&N(a)}}async function At(A,e,t,r,s){if(oA(s),(e.blur||e.shadow)&&vh()){let n=Th(A,e,t,r,s);if(n)return n}return Oh(A,e,t,r,s)}async function Oh(A,{blur:e,shadow:t},r,s,n){if(oA(n),!e&&!t){let u=ot(A),d=u.getContext("2d");if(!d)throw N(u),new j("Filter surface canvas is unavailable");d.globalAlpha=r;try{return d.drawImage(A,0,0),u}catch{throw N(u),new j("Filter surface image cannot be drawn")}}let o="http://www.w3.org/2000/svg",a=(u,d={})=>{let Q=document.createElementNS(o,u);return Object.entries(d).forEach(([f,C])=>Q.setAttribute(f,String(C))),Q},i=a("svg",{width:A.width,height:A.height,viewBox:`0 0 ${A.width} ${A.height}`}),c=a("defs"),B=a("filter",{id:"composited-filter",filterUnits:"userSpaceOnUse",x:0,y:0,width:A.width,height:A.height,"color-interpolation-filters":"sRGB"});if(e&&B.appendChild(a("feGaussianBlur",{stdDeviation:e*s,result:"blurred-source"})),t){B.appendChild(a("feGaussianBlur",{in:e?"blurred-source":"SourceAlpha",stdDeviation:t.blur*s})),B.appendChild(a("feOffset",{dx:t.x*s,dy:t.y*s,result:"offset-shadow"})),B.appendChild(a("feFlood",{"flood-color":t.color})),B.appendChild(a("feComposite",{in2:"offset-shadow",operator:"in"}));let u=a("feMerge");u.appendChild(a("feMergeNode")),u.appendChild(a("feMergeNode",{in:e?"blurred-source":"SourceGraphic"})),B.appendChild(u)}c.appendChild(B),i.appendChild(c);let l;try{if(l=A.toDataURL("image/png"),l==="data:,")throw new Error("Canvas size is unsupported")}catch{throw new j("Filter surface pixels cannot be serialized")}i.appendChild(a("image",{width:A.width,height:A.height,href:l,filter:"url(#composited-filter)"}));let h=new Image,g;try{h.src=`data:image/svg+xml,${encodeURIComponent(new XMLSerializer().serializeToString(i))}`,await Mh(h,n),oA(n),g=ot(A);let u=g.getContext("2d");if(!u)throw new j("Filter surface canvas is unavailable");return u.globalAlpha=r,u.drawImage(h,0,0),g}catch(u){throw g&&N(g),n?.aborted&&oA(n),u instanceof j?u:new j("Filter surface image cannot be drawn")}finally{h.removeAttribute("src")}}function pe(A,e,t){let r=e*t*4;return!Number.isFinite(r)||e<=0||t<=0||e>8192||t>8192||A.pixels+r>16777216?0:(A.pixels+=r,r)}var me=(A,e)=>A.add(-e,-e,e*2,e*2),We=(A,e)=>new _(Math.min(A.left,e.left),Math.min(A.top,e.top),Math.max(A.left+A.width,e.left+e.width)-Math.min(A.left,e.left),Math.max(A.top+A.height,e.top+e.height)-Math.min(A.top,e.top));function io(A){let e=A.styles,t=A.bounds;for(let s of e.boxShadow)if(!s.inset){let n=Math.max(0,s.spread.number)+3*s.blur.number;t=We(t,me(A.bounds.add(s.offsetX.number,s.offsetY.number,0,0),n))}for(let s of A.textNodes)for(let n of s.textBounds){let o=me(n.bounds,2*m(e.fontSize,A.bounds.height)+e.webkitTextStrokeWidth);t=We(t,o);for(let a of e.textShadow)t=We(t,me(o.add(a.offsetX.number,a.offsetY.number,0,0),3*a.blur.number))}for(let s of A.elements)s.styles.isVisible()&&(t=We(t,io(s)));let r=je(e.filter);return me(t,r?oo(r):0)}function dr(A,e,t,r){let s=me(e,t),n=Math.floor(Math.max(A.left,s.left)*r)/r,o=Math.floor(Math.max(A.top,s.top)*r)/r,a=Math.ceil(Math.min(A.left+A.width,s.left+s.width)*r)/r,i=Math.ceil(Math.min(A.top+A.height,s.top+s.height)*r)/r;return new _(n,o,Math.max(0,a-n),Math.max(0,i-o))}var Rh=class{constructor(A){this.ctx=A}render(A,e){this.ctx.fillStyle=L(e.textDecorationColor||e.color);let t=1;typeof e.textDecorationThickness=="number"?t=e.textDecorationThickness:e.textDecorationThickness==="from-font"&&(t=Math.max(1,Math.floor(e.fontSize.number*.05)));let r=0;typeof e.textUnderlineOffset=="number"&&(r=e.textUnderlineOffset);let s=e.textDecorationStyle;e.textDecorationLine.forEach(n=>{let o=0;switch(n){case 1:o=A.top+A.height-t+r;break;case 2:o=A.top;break;case 3:o=A.top+(A.height/2-t/2);break;default:return}this.draw(A.left,o,A.width,t,s)})}draw(A,e,t,r,s){switch(s){case 0:this.ctx.fillRect(A,e,t,r);break;case 1:{let n=Math.max(1,r);this.ctx.fillRect(A,e,t,r),this.ctx.fillRect(A,e+r+n,t,r);break}case 2:this.drawPattern(A,e,t,r,[r,r*2]);break;case 3:this.drawPattern(A,e,t,r,[r*3,r*2]);break;case 4:this.drawWavy(A,e,t,r);break;default:this.ctx.fillRect(A,e,t,r)}}drawPattern(A,e,t,r,s){this.ctx.save(),this.ctx.beginPath(),this.ctx.setLineDash(s),this.ctx.lineWidth=r,this.ctx.strokeStyle=this.ctx.fillStyle,this.ctx.moveTo(A,e+r/2),this.ctx.lineTo(A+t,e+r/2),this.ctx.stroke(),this.ctx.restore()}drawWavy(A,e,t,r){this.ctx.save(),this.ctx.beginPath(),this.ctx.lineWidth=r,this.ctx.strokeStyle=this.ctx.fillStyle;let s=r*2,n=r*4,o=A;for(this.ctx.moveTo(o,e+r/2);oA!==void 0&&!Number.isNaN(A),ao=(A,e)=>{let t=A.measureText(Vh),r=t;return{baseline:YA(r.fontBoundingBoxAscent)?r.fontBoundingBoxAscent:YA(t.actualBoundingBoxAscent)?t.actualBoundingBoxAscent:e,height:YA(r.fontBoundingBoxAscent)&&YA(r.fontBoundingBoxDescent)?r.fontBoundingBoxAscent+r.fontBoundingBoxDescent:YA(t.actualBoundingBoxAscent)&&YA(t.actualBoundingBoxDescent)?t.actualBoundingBoxAscent+t.actualBoundingBoxDescent:e}},co=(A,e)=>ao(A,e).baseline,Nh=["-apple-system","system-ui"],Gh=1,kh=/[\u2E80-\u2FFF\u3000-\u30FF\u3400-\u4DBF\u4E00-\u9FFF\uAC00-\uD7AF\uF900-\uFAFF\uFF01-\uFFEF]/,Je=A=>kh.test(A),Ph=()=>{if(typeof navigator>"u")return null;let A=navigator.userAgent,e=/iPhone|iPad|iPod/.test(A),t=/Macintosh/.test(A)&&navigator.maxTouchPoints&&navigator.maxTouchPoints>1;if(!e&&!t)return null;for(let r of[/(?:iPhone|CPU(?:\siPhone)?)\sOS\s(\d+)[\._](\d+)/,/Version\/(\d+)\.(\d+)/]){let s=A.match(r);if(s&&s[1])return parseInt(s[1],10)}return null},Xh=A=>{let e=Ph();return e!==null&&e>=15&&e<17?A.map(t=>Nh.indexOf(t)!==-1?'-apple-system, "Helvetica Neue", Arial, sans-serif':t):A},_h=()=>(typeof window<"u"?window:void 0)?.chrome?"miter":"round",Wh=class{constructor(A){this.baselineCache=new Map,this.glyphWidthCache=null,this.ctx=A.ctx,this.options=A.options,this.decorationRenderer=new Rh(A.ctx)}cachedMeasureText(A,e){let t=this.glyphWidthCache;t||(t=new Map,this.glyphWidthCache=t);let r=A+e,s=t.get(r);return s===void 0&&(s=this.ctx.measureText(A).width,t.set(r,s)),s}iterateLettersWithLetterSpacing(A,e,t,r,s){if(Ee(r)){this.iterateVerticalGlyphs(A,e,t,r,s);return}let n=UA(A.text),o=A.bounds.top+t,a=this.ctx.font,i=A.bounds.left;for(let c of n)s(c,i,o),i+=this.cachedMeasureText(c,a)+e}iterateVerticalGlyphs(A,e,t,r,s){let n=UA(A.text),o=this.ctx.font,a=r===4?-Math.PI/2:Math.PI/2,i=A.bounds.top;for(let c=0;c0)){let g=this.ctx.textBaseline;Je(B)&&(this.ctx.textBaseline="ideographic"),s(B,A.bounds.left,i+t),this.ctx.textBaseline=g,i+=this.cachedMeasureText(B,o)+e,c++;continue}let l=c;for(;c0)c++;else break}this.ctx.save(),this.ctx.translate(A.bounds.left+t,i),this.ctx.rotate(a);let h=0;for(let g=l;g{this.ctx.fillText(s,n,o)})}renderStrokeText(A,e,t,r){this.canRenderWholeText(e,r)?this.ctx.strokeText(A.text,A.bounds.left,A.bounds.top+t):this.iterateLettersWithLetterSpacing(A,e,t,r,(s,n,o)=>{this.ctx.strokeText(s,n,o)})}renderTextStrokeWithStyle(A,e,t){!e.webkitTextStrokeWidth||!A.text.trim().length||(this.ctx.strokeStyle=L(e.webkitTextStrokeColor),this.ctx.lineWidth=e.webkitTextStrokeWidth,this.ctx.lineJoin=_h(),this.renderStrokeText(A,e.letterSpacing,t,e.writingMode),this.ctx.strokeStyle="",this.ctx.lineWidth=0,this.ctx.lineJoin="miter")}renderTextFillWithShadows(A,e,t){this.ctx.fillStyle=this.resolveFillColor(e),this.renderTextWithLetterSpacing(A,e.letterSpacing,t,e.writingMode);let r=e.textShadow;r.length&&A.text.trim().length&&(r.slice(0).reverse().forEach(s=>{this.ctx.shadowColor=L(s.color),this.ctx.shadowOffsetX=s.offsetX.number*this.options.scale,this.ctx.shadowOffsetY=s.offsetY.number*this.options.scale,this.ctx.shadowBlur=s.blur.number,this.renderTextWithLetterSpacing(A,e.letterSpacing,t,e.writingMode)}),this.ctx.shadowColor="",this.ctx.shadowOffsetX=0,this.ctx.shadowOffsetY=0,this.ctx.shadowBlur=0)}renderTextBoundWithPaintOrder(A,e,t,r){t.forEach(s=>{switch(s){case 0:this.ctx.fillStyle=this.resolveFillColor(e),this.renderTextWithLetterSpacing(A,e.letterSpacing,r,e.writingMode);break;case 1:this.renderTextStrokeWithStyle(A,e,r)}})}renderTextDecoration(A,e){this.decorationRenderer.render(A,e)}truncateTextWithEllipsis(A,e,t){let s=this.ctx.measureText("\u2026").width,n=UA(A);if(t===0){let o=c=>this.ctx.measureText(n.slice(0,c).join("")).width+s<=e,a=0,i=n.length;for(;a>1;o(c)?a=c:i=c-1}return n.slice(0,a).join("")+"\u2026"}else{let o=this.ctx.font,a=s,i=[];for(let c of n){let B=this.cachedMeasureText(c,o);if(a+B>e)break;i.push(c),a+=B+t}return i.join("")+"\u2026"}}createFontStyle(A){let e=A.fontVariant.filter(s=>s==="normal"||s==="small-caps").join(""),t=Xh(A.fontFamily).join(", "),r=z(A.fontSize)?`${A.fontSize.number}${A.fontSize.unit}`:`${A.fontSize.number}px`;return[[A.fontStyle,e,A.fontWeight,r,t].join(" "),t,r]}resolveFillColor(A){return L(A.webkitTextFillColor??A.color)}renderLineClampedText(A,e,t,r,s){let n=e.fontSize.number*1.5,o=[],a=[],i=w(A.textBounds,0).bounds.top;A.textBounds.forEach(l=>{Math.abs(l.bounds.top-i)>=n*.5?(a.length>0&&o.push(a),a=[l],i=l.bounds.top):a.push(l)}),a.length>0&&o.push(a);let c=e.webkitLineClamp;if(o.length<=c)return!1;for(let l=0;lthis.renderTextBoundWithPaintOrder(h,e,t,r));let B=o[c-1];if(B?.length&&s){let l=B.map(d=>d.text).join(""),h=w(B,0),g=s.width-(h.bounds.left-s.left),u=new vA(this.truncateTextWithEllipsis(l,g,e.letterSpacing),h.bounds);for(let d of t)d===0?(this.ctx.fillStyle=this.resolveFillColor(e),this.renderTextWithLetterSpacing(u,e.letterSpacing,r,e.writingMode)):d===1&&this.renderTextStrokeWithStyle(u,e,r)}return!0}renderEllipsisText(A,e,t,r,s){let n=e.fontSize.number*1.5,o=w(A.textBounds,0).bounds.top;if(!A.textBounds.every(c=>Math.abs(c.bounds.top-o)c.text).join("").replace(/\s+/g," ").trim();if(this.ctx.measureText(a).width<=s.width+Gh)return!1;let i=new vA(this.truncateTextWithEllipsis(a,s.width,e.letterSpacing),w(A.textBounds,0).bounds);for(let c of t)c===0?this.renderTextFillWithShadows(i,e,r):c===1&&this.renderTextStrokeWithStyle(i,e,r);return!0}measureBaselineCached(A,e){let t=this.baselineCache.get(A);return t===void 0&&(t=co(this.ctx,e),this.baselineCache.size>=64&&this.baselineCache.clear(),this.baselineCache.set(A,t)),t}async renderTextNode(A,e,t){this.glyphWidthCache=null;let[r]=this.createFontStyle(e);this.ctx.font=r??"",this.ctx.direction=e.direction===1?"rtl":"ltr",this.ctx.textAlign="left",this.ctx.textBaseline="alphabetic";let s=e.paintOrder,n=this.measureBaselineCached(r??"",e.fontSize.number);e.webkitLineClamp>0&&(e.display&2)!==0&&e.overflowY===1&&A.textBounds.length>0&&this.renderLineClampedText(A,e,s,n,t)||e.textOverflow===1&&t&&e.overflowX===1&&A.textBounds.length>0&&this.renderEllipsisText(A,e,s,n,t)||(A.textBounds.forEach(o=>{s.forEach(a=>{a===0?(this.renderTextFillWithShadows(o,e,n),e.textDecorationLine.length&&this.renderTextDecoration(o.bounds,e)):a===1&&this.renderTextStrokeWithStyle(o,e,n)})}),e.textEmphasisStyle&&this.renderTextEmphasis(A,e,n))}renderTextEmphasis(A,e,t){if(Ee(e.writingMode))return;let r=e.textEmphasisStyle;if(!r)return;let s=e.fontSize.number,n=s*.5,o=L(e.textEmphasisColor??e.color),a=e.textEmphasisPosition,i=(B,l)=>{if(typeof r=="string"){let d=this.ctx.font;this.ctx.font=d.replace(/^\S+/,`${n}px`),this.ctx.textAlign="center",this.ctx.fillText(r,B,l+n/3),this.ctx.font=d,this.ctx.textAlign="left";return}let{fill:h,shape:g}=r,u=n*(g==="dot"?.3:g==="sesame"?.26:.34);this.ctx.beginPath(),g==="sesame"?this.ctx.ellipse(B,l,u*1.3,u*.8,Math.PI/4,0,Math.PI*2):g==="triangle"?(this.ctx.moveTo(B,l-u),this.ctx.lineTo(B+u*1.1,l+u*.8),this.ctx.lineTo(B-u*1.1,l+u*.8),this.ctx.closePath()):this.ctx.arc(B,l,u,0,Math.PI*2),h?g==="double-circle"?(this.ctx.lineWidth=u*.7,this.ctx.stroke(),this.ctx.beginPath(),this.ctx.arc(B,l,u*.4,0,Math.PI*2),this.ctx.lineWidth=u*.35,this.ctx.stroke()):this.ctx.fill():(this.ctx.lineWidth=Math.max(1,u*.35),this.ctx.stroke(),g==="double-circle"&&(this.ctx.beginPath(),this.ctx.arc(B,l,u*.5,0,Math.PI*2),this.ctx.stroke()))},c=this.ctx.font;for(let B of A.textBounds){let l=B.bounds.top+t,h=a.over?l-s-n*.4:l+n*.9,g=B.bounds.left;for(let u of UA(B.text)){let d=this.cachedMeasureText(u,c);this.ctx.save();try{this.ctx.fillStyle=o,this.ctx.strokeStyle=o,this.ctx.lineWidth=1,i(g+d/2+e.letterSpacing/2,h)}finally{this.ctx.restore()}g+=d+e.letterSpacing}}}},it=(A,e)=>{e.forEach((t,r)=>{let s=Y(t)?t.start:t;r===0?A.moveTo(s.x,s.y):A.lineTo(s.x,s.y),Y(t)&&A.bezierCurveTo(t.startControl.x,t.startControl.y,t.endControl.x,t.endControl.y,t.end.x,t.end.y)})},FA=(A,e)=>{A.beginPath(),it(A,e),A.closePath()},Jh=class{constructor(A){this.maxSize=A,this._map=new Map}get(A){if(!this._map.has(A))return;let e=this._map.get(A);return this._map.delete(A),this._map.set(A,e),e}set(A,e){if(this._map.has(A))this._map.delete(A);else if(this._map.size>=this.maxSize){let t=this._map.keys().next().value;t!==void 0&&this._map.delete(t)}this._map.set(A,e)}get size(){return this._map.size}clear(){this._map.clear()}},Bo=class{constructor(A){this.patternCache=new Jh(50),this.ctx=A.ctx,this.context=A.context,this.canvas=A.canvas}async renderBackgroundImage(A){let e=A.styles.backgroundImage.length-1,t=A.styles.backgroundBlendMode,r=0;for(let s of A.styles.backgroundImage.slice(0).reverse()){if(r>0){let n=t[r]??t[0]??"normal";n!=="normal"&&(this.ctx.save(),this.ctx.globalCompositeOperation=n)}s.type===0?await this.renderBackgroundURLImage(A,s,e):Wa(s)?this.renderLinearGradient(A,s,e):Ja(s)?this.renderRepeatingLinearGradient(A,s,e):bn(s)?this.renderRadialGradient(A,s,e):xn(s)?this.renderRepeatingRadialGradient(A,s,e):Ln(s)&&this.renderConicGradient(A,s,e),r>0&&(t[r]??t[0]??"normal")!=="normal"&&this.ctx.restore(),e--,r++}}async renderBackgroundURLImage(A,e,t){let r,s=e.url;try{r=await this.context.cache.match(s)}catch(n){this.context.logger.error(`Error loading background-image ${s}`),this.context.onError?.(n instanceof Error?n:new Error(String(n)))}if(r){let n=isNaN(r.width)||r.width===0?1:r.width,o=isNaN(r.height)||r.height===0?1:r.height,[a,i,c,B,l]=WA(A,t,[n,o,n/o]),h=LA(A.styles.backgroundRepeat,t),g=h===1?"no-repeat":h===2?"repeat-x":h===3?"repeat-y":"repeat",u=`${s}|${Math.round(B)}x${Math.round(l)}|${A.styles.imageRendering}|${g}`,d=this.patternCache.get(u);if(!d){let Q=this.resizeImage(r,B,l,A.styles.imageRendering);d=this.ctx.createPattern(Q,g),this.patternCache.set(u,d)}this.renderRepeat(a,d,i,c)}}renderRepeatingLinearGradient(A,e,t){let[r,s,n,o,a]=WA(A,t,[null,null,null]),[i,c,B,l,h]=rr(e.angle,o,a),g=fA(e.stops,i||1),u=w(g,g.length-1),d=w(g,0),Q=u.stop-d.stop,f=Q*(i||1);if(f<=0){this.renderLinearGradient(A,e,t);return}let C=B-c,p=h-l,U=f/(Math.sqrt(C*C+p*p)||1),E=c,I=l,S=c+C*U,y=l+p*U,D=this.canvas.ownerDocument??document,$=`rlg|${e.angle}|${Math.round(f)}|${JSON.stringify(e.stops)}`,W=this.patternCache.get($);if(!W){let k=D.createElement("canvas"),HA=Math.max(1,Math.ceil(f));k.width=HA,k.height=HA;let VA=k.getContext("2d");if(!VA)return;let Me=VA.createLinearGradient(E-s,I-n,S-s,y-n);g.forEach(br=>{Me.addColorStop((br.stop-d.stop)/Q,L(br.color))}),VA.fillStyle=Me,VA.fillRect(0,0,HA,HA),HA>0&&(W=this.ctx.createPattern(k,"repeat"),this.patternCache.set($,W))}W&&this.renderRepeat(r,W,s,n)}renderLinearGradient(A,e,t){let[r,s,n,o,a]=WA(A,t,[null,null,null]),[i,c,B,l,h]=rr(e.angle,o,a),g=`lg|${e.angle}|${Math.round(o)}x${Math.round(a)}|${JSON.stringify(e.stops)}`,u=this.patternCache.get(g);if(!u){let d=(this.canvas.ownerDocument??document).createElement("canvas");d.width=o,d.height=a;let Q=d.getContext("2d");if(!Q)return;let f=Q.createLinearGradient(c,l,B,h);fA(e.stops,i||1).forEach(C=>f.addColorStop(C.stop,L(C.color))),Q.fillStyle=f,Q.fillRect(0,0,o,a),o>0&&a>0&&(u=this.ctx.createPattern(d,"repeat"),this.patternCache.set(g,u))}u&&this.renderRepeat(r,u,s,n)}renderRadialGradient(A,e,t){let[r,s,n,o,a]=WA(A,t,[null,null,null]),i=e.position.length===0?[AA]:e.position,c=m(w(i,0),o),B=m(w(i,i.length-1),a),[l,h]=sr(e,c,B,o,a);if((l===0||h===0)&&(l=Math.max(l,.01),h=Math.max(h,.01)),l>0&&h>0){let g=`rg|${Math.round(c)}x${Math.round(B)}|${Math.round(l)}x${Math.round(h)}|${JSON.stringify(e.stops)}`,u=fA(e.stops,l*2),d=u[u.length-1],Q=this.patternCache.get(g);if(!Q){let f=(this.canvas.ownerDocument??document).createElement("canvas");f.width=Math.ceil(l*2),f.height=Math.ceil(h*2);let C=f.getContext("2d");if(C){let p=C.createRadialGradient(l,l,0,l,l,l);u.forEach(U=>p.addColorStop(U.stop,L(U.color))),C.fillStyle=p,l!==h&&C.scale(1,h/l),C.fillRect(0,0,l*2,l*2),Q=this.ctx.createPattern(f,"no-repeat"),this.patternCache.set(g,Q)}}Q&&(this.path(r),this.ctx.save(),this.ctx.clip(),d&&(this.ctx.fillStyle=L(d.color),this.ctx.fill()),this.ctx.translate(s+c-l,n+B-h),this.ctx.fillStyle=Q,this.ctx.fillRect(0,0,l*2,h*2),this.ctx.restore())}}renderRepeatingRadialGradient(A,e,t){let[r,s,n,o,a]=WA(A,t,[null,null,null]),i=e.position.length===0?[AA]:e.position,c=m(w(i,0),o),B=m(w(i,i.length-1),a),[l,h]=sr(e,c,B,o,a);if((l===0||h===0)&&(l=Math.max(l,.01),h=Math.max(h,.01)),!(l>0&&h>0))return;let g=fA(e.stops,l*2),u=w(g,0),d=w(g,g.length-1),Q=Math.max(d.stop-u.stop,.01),f=[],C=Math.ceil(.5/Q);for(let E=0;E1)break;f.push({stop:S,color:L(I.color)})}f.push({stop:1,color:L(d.color)});let p=`rrg|${Math.round(c)}x${Math.round(B)}|${Math.round(l)}x${Math.round(h)}|${f.length}|${JSON.stringify(e.stops)}`,U=this.patternCache.get(p);if(!U){let E=(this.canvas.ownerDocument??document).createElement("canvas");E.width=Math.ceil(l*2),E.height=Math.ceil(h*2);let I=E.getContext("2d");if(I){let S=I.createRadialGradient(l,l,0,l,l,l);f.forEach(y=>S.addColorStop(y.stop,y.color)),I.fillStyle=S,l!==h&&I.scale(1,h/l),I.fillRect(0,0,l*2,h*2),U=this.ctx.createPattern(E,"no-repeat"),this.patternCache.set(p,U)}}U&&(this.path(r),this.ctx.save(),this.ctx.clip(),this.ctx.translate(s+c-l,n+B-h),this.ctx.fillStyle=U,this.ctx.fillRect(0,0,l*2,h*2),this.ctx.restore())}renderConicGradient(A,e,t){let[r,s,n,o,a]=WA(A,t,[null,null,null]),i=e.position.length===0?[AA]:e.position,c=s+m(w(i,0),o),B=n+m(w(i,i.length-1),a),l=this.ctx.createConicGradient(e.angle-Math.PI/2,c,B);fA(e.stops,1).forEach(h=>{l.addColorStop(Math.min(1,Math.max(0,h.stop)),L(h.color))}),this.path(r),this.ctx.save(),this.ctx.clip(),this.ctx.fillStyle=l,this.ctx.fill(),this.ctx.restore()}renderRepeat(A,e,t,r){this.path(A),this.ctx.fillStyle=e,this.ctx.translate(t,r),this.ctx.fill(),this.ctx.translate(-t,-r)}resizeImage(A,e,t,r){let s=(this.canvas.ownerDocument??document).createElement("canvas");s.width=Math.max(1,e),s.height=Math.max(1,t);let n=s.getContext("2d");return n?(r===2||r===1?(this.context.logger.debug("Disabling image smoothing for background image due to CSS image-rendering"),n.imageSmoothingEnabled=!1):r===3?(this.context.logger.debug("Enabling image smoothing for background image due to CSS image-rendering: smooth"),n.imageSmoothingEnabled=!0):n.imageSmoothingEnabled=this.ctx.imageSmoothingEnabled,this.ctx.imageSmoothingQuality&&(n.imageSmoothingQuality=this.ctx.imageSmoothingQuality),n.drawImage(A,0,0,A.width,A.height,0,0,e,t),s):A}path(A){FA(this.ctx,A)}},Ss=(A,e)=>{switch(e){case 0:return iA(A.topLeftBorderBox,A.topLeftPaddingBox,A.topRightBorderBox,A.topRightPaddingBox);case 1:return iA(A.topRightBorderBox,A.topRightPaddingBox,A.bottomRightBorderBox,A.bottomRightPaddingBox);case 2:return iA(A.bottomRightBorderBox,A.bottomRightPaddingBox,A.bottomLeftBorderBox,A.bottomLeftPaddingBox);default:return iA(A.bottomLeftBorderBox,A.bottomLeftPaddingBox,A.topLeftBorderBox,A.topLeftPaddingBox)}},Yh=(A,e)=>{switch(e){case 0:return iA(A.topLeftBorderBox,A.topLeftBorderDoubleOuterBox,A.topRightBorderBox,A.topRightBorderDoubleOuterBox);case 1:return iA(A.topRightBorderBox,A.topRightBorderDoubleOuterBox,A.bottomRightBorderBox,A.bottomRightBorderDoubleOuterBox);case 2:return iA(A.bottomRightBorderBox,A.bottomRightBorderDoubleOuterBox,A.bottomLeftBorderBox,A.bottomLeftBorderDoubleOuterBox);default:return iA(A.bottomLeftBorderBox,A.bottomLeftBorderDoubleOuterBox,A.topLeftBorderBox,A.topLeftBorderDoubleOuterBox)}},Zh=(A,e)=>{switch(e){case 0:return iA(A.topLeftBorderDoubleInnerBox,A.topLeftPaddingBox,A.topRightBorderDoubleInnerBox,A.topRightPaddingBox);case 1:return iA(A.topRightBorderDoubleInnerBox,A.topRightPaddingBox,A.bottomRightBorderDoubleInnerBox,A.bottomRightPaddingBox);case 2:return iA(A.bottomRightBorderDoubleInnerBox,A.bottomRightPaddingBox,A.bottomLeftBorderDoubleInnerBox,A.bottomLeftPaddingBox);default:return iA(A.bottomLeftBorderDoubleInnerBox,A.bottomLeftPaddingBox,A.topLeftBorderDoubleInnerBox,A.topLeftPaddingBox)}},zh=(A,e)=>{switch(e){case 0:return Ye(A.topLeftBorderStroke,A.topRightBorderStroke);case 1:return Ye(A.topRightBorderStroke,A.bottomRightBorderStroke);case 2:return Ye(A.bottomRightBorderStroke,A.bottomLeftBorderStroke);default:return Ye(A.bottomLeftBorderStroke,A.topLeftBorderStroke)}},Ye=(A,e)=>{let t=[];return Y(A)?t.push(A.subdivide(.5,!1)):t.push(A),Y(e)?t.push(e.subdivide(.5,!0)):t.push(e),t},iA=(A,e,t,r)=>{let s=[];return Y(A)?s.push(A.subdivide(.5,!1)):s.push(A),Y(t)?s.push(t.subdivide(.5,!0)):s.push(t),Y(r)?s.push(r.subdivide(.5,!0).reverse()):s.push(r),Y(e)?s.push(e.subdivide(.5,!1).reverse()):s.push(e),s},$h=class{constructor(A,e){this.ctx=A.ctx,this.pathCallbacks=e}async renderSolidBorder(A,e,t){this.pathCallbacks.path(Ss(t,e)),this.ctx.fillStyle=L(A),this.ctx.fill()}async renderDoubleBorder(A,e,t,r){if(e<3){await this.renderSolidBorder(A,t,r);return}let s=Yh(r,t);this.pathCallbacks.path(s),this.ctx.fillStyle=L(A),this.ctx.fill();let n=Zh(r,t);this.pathCallbacks.path(n),this.ctx.fill()}async renderDashedDottedBorder(A,e,t,r,s){this.ctx.save();let n=zh(r,t),o=Ss(r,t);s===2&&(this.pathCallbacks.path(o),this.ctx.clip());let a,i,c,B;Y(w(o,0))?(a=w(o,0).start.x,i=w(o,0).start.y):(a=w(o,0).x,i=w(o,0).y),Y(w(o,1))?(c=w(o,1).end.x,B=w(o,1).end.y):(c=w(o,1).x,B=w(o,1).y);let l;t===0||t===2?l=Math.abs(a-c):l=Math.abs(i-B),this.ctx.beginPath(),s===3?this.pathCallbacks.formatPath(n):this.pathCallbacks.formatPath(o.slice(0,2));let h=e<3?e*3:e*2,g=e<3?e*2:e;s===3&&(h=e,g=e);let u=!0;if(l<=h*2)u=!1;else if(l<=h*2+g){let d=l/(2*h+g);h*=d,g*=d}else{let d=Math.floor((l+g)/(h+g)),Q=(l-d*h)/(d-1),f=(l-(d+1)*h)/d;g=f<=0||Math.abs(g-Q){let r=A?[A.top,A.right,A.bottom,A.left]:null;return[0,1,2,3].map(s=>{let n=r?r[s]:null,o=e[s]??0;return!n||n.kind==="auto"?o:n.kind==="number"?o*(n.value??1):n.kind==="length"?n.value??0:(n.value??0)/100*(s===0||s===2?t.height:t.width)})},jh=(A,e)=>{let t=A?[A.top,A.right,A.bottom,A.left]:null,r=s=>{let n=t?t[s]:null;return n?n.kind==="number"?(e[s]??0)*(n.value??0):n.value??0:0};return{top:r(0),right:r(1),bottom:r(2),left:r(3)}},Ag=class{constructor(A){this.ctx=A}renderBorderImage(A,e,t,r,s,n,o,a,i={top:0,right:0,bottom:0,left:0}){A=A.add(-i.left,-i.top,i.left+i.right,i.top+i.bottom);let c=e.naturalWidth||e.width,B=e.naturalHeight||e.height;if(c<=0||B<=0)return;let l=Math.min(t.unit==="percent"?t.top/100*B:Math.min(t.top,B),B),h=Math.min(t.unit==="percent"?t.right/100*c:Math.min(t.right,c),c),g=Math.min(t.unit==="percent"?t.bottom/100*B:Math.min(t.bottom,B),B),u=Math.min(t.unit==="percent"?t.left/100*c:Math.min(t.left,c),c),{left:d,top:Q,width:f,height:C}=A;if(f<=0||C<=0)return;let p=Math.min(s,C),U=Math.min(n,f),E=Math.min(o,C-p),I=Math.min(a,f-U);this.drawRegion(e,0,0,u,l,d,Q,I,p),this.drawRegion(e,c-h,0,h,l,d+f-U,Q,U,p),this.drawRegion(e,c-h,B-g,h,g,d+f-U,Q+C-E,U,E),this.drawRegion(e,0,B-g,u,g,d,Q+C-E,I,E);let S=[{sx:u,sy:0,sw:c-u-h,sh:l,dx:d+I,dy:Q,dw:f-I-U,dh:p,repeat:r.horizontal},{sx:c-h,sy:l,sw:h,sh:B-l-g,dx:d+f-U,dy:Q+p,dw:U,dh:C-p-E,repeat:r.vertical},{sx:u,sy:B-g,sw:c-u-h,sh:g,dx:d+I,dy:Q+C-E,dw:f-I-U,dh:E,repeat:r.horizontal},{sx:0,sy:l,sw:u,sh:B-l-g,dx:d,dy:Q+p,dw:I,dh:C-p-E,repeat:r.vertical}];for(let y of S){if(y.sw<=0||y.sh<=0||y.dw<=0||y.dh<=0)continue;let D=y.dw>=y.dh;y.repeat===0?this.ctx.drawImage(e,y.sx,y.sy,y.sw,y.sh,y.dx,y.dy,y.dw,y.dh):(y.repeat===1||y.repeat===2)&&this.drawRepeatedEdge(e,y,D,y.repeat===2)}if(t.fill){let y=u,D=l,$=c-u-h,W=B-l-g,k=d+I,HA=Q+p,VA=f-I-U,Me=C-p-E;this.drawRegion(e,y,D,$,W,k,HA,VA,Me)}}drawRegion(A,e,t,r,s,n,o,a,i){r>0&&s>0&&a>0&&i>0&&this.ctx.drawImage(A,e,t,r,s,n,o,a,i)}drawRepeatedEdge(A,e,t,r){let s=t?e.sw:e.sh,n=t?e.dw:e.dh;if(s<=0||n<=0)return;let o,a;r?(a=Math.max(1,Math.round(n/s)),o=n/a):(o=s,a=Math.ceil(n/o)),this.ctx.save(),this.ctx.beginPath(),this.ctx.rect(e.dx,e.dy,e.dw,e.dh),this.ctx.clip();for(let i=0;iys(r)||nt(r)||Is(r),t=A.reduceRight((r,s,n)=>r!==-1?r:e(s)?n:-1,-1);for(let r=0;r0}},Nt=(A,e)=>A.length===0?void 0:A[e%A.length]??A[0],tg=(A,e,t,r)=>{let s=A?A[0]:void 0,n=A&&A.length>1?w(A,1):void 0,o=l=>l!==void 0&&H(l)?l.value:null,a=(l,h,g)=>l===void 0||H(l)?null:x(l)?m(l,h):g,i=o(s);if(i==="contain"||i==="cover"){let l=i==="contain"?Math.min(e.width/t,e.height/r):Math.max(e.width/t,e.height/r);return{width:t*l,height:r*l}}let c=a(s,e.width,t),B=a(n,e.height,r);return c===null&&B===null?(c=t,B=r):c===null?c=t/r*B:B===null&&(B=r/t*c),{width:c,height:B}},rg=(A,e,t,r,s)=>{let n=e.naturalWidth||e.width||s.width,o=e.naturalHeight||e.height||s.height,{width:a,height:i}=tg(Nt(t.maskSize,r),s,n,o),c=Nt(t.maskPosition,r)??[],B=s.left+m(w(c,0),s.width-a),l=s.top+m(w(c,c.length-1),s.height-i),h=Nt(t.maskRepeat,r)??0,g=h===0||h===2,u=h===0||h===3,d=g?Math.ceil((B-s.left)/a):0,Q=u?Math.ceil((l-s.top)/i):0,f=g?Math.ceil((s.left+s.width-B)/a):0,C=u?Math.ceil((s.top+s.height-l)/i):0;for(let p=-Q;p<=C;p++)for(let U=-d;U<=f;U++)A.drawImage(e,B+U*a,l+p*i,a,i)},sg=(A,e,t)=>{let{width:r,height:s}=t,n=e.position.length===0?[AA]:e.position,o=m(w(n,0),r),a=m(w(n,n.length-1),s),[i,c]=sr(e,o,a,r,s);i=Math.max(i,.01),c=Math.max(c,.01);let B=document.createElement("canvas");B.width=Math.ceil(i*2),B.height=Math.ceil(c*2);let l=B.getContext("2d");if(!l)return;let h=l.createRadialGradient(i,i,0,i,i,i);fA(e.stops,i*2).forEach(g=>h.addColorStop(Math.min(1,Math.max(0,g.stop)),L(g.color))),l.fillStyle=h,i!==c&&l.scale(1,c/i),l.fillRect(0,0,i*2,c*2),A.drawImage(B,t.left+o-i,t.top+a-c,i*2,c*2)},ng=(A,e,t)=>{let{width:r,height:s}=t;if(r<=0||s<=0)return;if(bn(e)||xn(e)){sg(A,e,t);return}let n=null;if(e.type===1||e.type===3){let o=e,[a,i,c,B,l]=rr(o.angle||0,r,s);n=A.createLinearGradient(i,c,B,l),fA(o.stops,a||1).forEach(h=>n.addColorStop(Math.min(1,Math.max(0,h.stop)),L(h.color)))}else if(Ln(e)){let o=e;n=A.createConicGradient(o.angle-Math.PI/2,t.left+r/2,t.top+s/2),fA(o.stops,1).forEach(a=>n.addColorStop(Math.min(1,Math.max(0,a.stop)),L(a.color)))}n&&(A.fillStyle=n,A.fillRect(t.left,t.top,r,s))},Ks=async(A,e,t,r,s)=>{for(let n=0;n{let n=0,o=0,a=A,i=e,c=t.left,B=t.top,l=t.width,h=t.height,g=l/h,u=a/i,d=s?m(s[0],1):.5,Q=s?m(s[1],1):.5;return r===2?u>g?(h=l/u,B+=(t.height-h)*Q):(l=h*u,c+=(t.width-l)*d):r===4?u>g?(a=i*g,n+=(A-a)*d):(i=a/g,o+=(e-i)*Q):r===8?(a>l?(n+=(a-l)*d,a=l):(c+=(l-a)*d,l=a),i>h?(o+=(i-h)*Q,i=h):(B+=(h-i)*Q,h=i)):r===16&&((u>g?l:h*u)<(a>l?a:l)?u>g?(h=l/u,B+=(t.height-h)*Q):(l=h*u,c+=(t.width-l)*d):(a>l?(n+=(a-l)*d,a=l):(c+=(l-a)*d,l=a),i>h?(o+=(i-h)*Q,i=h):(B+=(h-i)*Q,h=i))),{sx:n,sy:o,sw:a,sh:i,dx:c,dy:B,dw:l,dh:h}};async function ig(A,e,t,r,s,n,o,a){if(s instanceof _n)try{let i=await e.cache.match(s.src),c=A.imageSmoothingEnabled;o.imageRendering===2||o.imageRendering===1?A.imageSmoothingEnabled=!1:o.imageRendering===3&&(A.imageSmoothingEnabled=!0),a(s,n,i),A.imageSmoothingEnabled=c}catch(i){e.logger.error(`Error loading image ${s.src}`),e.onError?.(i instanceof Error?i:new Error(String(i)))}if(s instanceof Wn&&a(s,n,s.canvas),s instanceof Jn)try{a(s,n,await e.cache.match(s.svg))}catch(i){e.logger.error(`Error loading svg ${s.svg.substring(0,255)}`),e.onError?.(i instanceof Error?i:new Error(String(i)))}if(s instanceof $n&&s.tree){let i=await r(e,{scale:t.scale,backgroundColor:s.backgroundColor,x:0,y:0,width:s.width,height:s.height}).render(s.tree);s.width&&s.height&&A.drawImage(i,0,0,s.width,s.height,s.bounds.left,s.bounds.top,s.bounds.width,s.bounds.height)}}function ag(A,e,t,r,s){if(r instanceof qA){let n=Math.min(r.bounds.width,r.bounds.height);r.type==="checkbox"&&r.checked?(A.save(),t([new F(r.bounds.left+n*.39363,r.bounds.top+n*.79),new F(r.bounds.left+n*.16,r.bounds.top+n*.5549),new F(r.bounds.left+n*.27347,r.bounds.top+n*.44071),new F(r.bounds.left+n*.39694,r.bounds.top+n*.5649),new F(r.bounds.left+n*.72983,r.bounds.top+n*.23),new F(r.bounds.left+n*.84,r.bounds.top+n*.34085),new F(r.bounds.left+n*.39363,r.bounds.top+n*.79)]),A.fillStyle=L(r.styles.accentColor??707406591),A.fill(),A.restore()):r.type==="radio"&&r.checked&&(A.save(),A.beginPath(),A.arc(r.bounds.left+n/2,r.bounds.top+n/2,n/4,0,Math.PI*2,!0),A.fillStyle=L(r.styles.accentColor??707406591),A.fill(),A.restore())}if(hg(r)&&r.value.length){let[n]=e.createFontStyle(s);A.font=n??"";let o=m(s.fontSize,0),{baseline:a,height:i}=ao(A,o);A.fillStyle=r instanceof qA&&r.isPlaceholder?L(dh):L(s.color),A.textBaseline="alphabetic",A.textAlign=gg(r.styles.textAlign);let c=Se(r),B=r instanceof qA?cg(c,re(r),i):c,l=0;switch(r.styles.textAlign){case 1:l+=c.width/2;break;case 2:l+=c.width}let h=0;r instanceof qA&&(h=(c.height-i)/2);let g=c.add(l,h,0,0);A.save(),t([new F(B.left,B.top),new F(B.left+B.width,B.top),new F(B.left+B.width,B.top+B.height),new F(B.left,B.top+B.height)]),A.clip();let u=Bg(A,r.value,c.width,s.whiteSpace==="pre"||s.whiteSpace==="nowrap"),d=or(s.lineHeight,o);u.forEach((Q,f)=>{let C=g.left,p=A.measureText(Q).width;switch(s.textAlign){case 1:C+=(c.width-p)/2;break;case 2:C+=c.width-p}let U=new _(C,g.top+f*d,0,0);e.renderTextWithLetterSpacing(new vA(Q,U),s.letterSpacing,a,s.writingMode)}),A.restore(),A.textBaseline="alphabetic",A.textAlign="left"}}var cg=(A,e,t)=>A.height{let s=[],n=e.split(` +`);for(let o of n){if(r){s.push(o);continue}let a=o.split(/(\s+)/),i="";for(let c of a){let B=i+c;A.measureText(B).width<=t||i===""?i=B:(s.push(i),i=c)}s.push(i)}return s};async function lg(A,e,t,r,s,n){if(P(s.styles.display,2048)){if(s.styles.listStyleImage!==null){let o=s.styles.listStyleImage;if(o.type===0){let a=o.url;try{let i=await e.cache.match(a);A.drawImage(i,s.bounds.left-(i.width+10),s.bounds.top)}catch(i){e.logger.error(`Error loading list-style-image ${a}`),e.onError?.(i instanceof Error?i:new Error(String(i)))}}}else if(r.listValue&&s.styles.listStyleType!==-1){let[o]=t.createFontStyle(n);A.font=o??"",A.fillStyle=L(n.color),A.textBaseline="middle",A.textAlign="right";let a=new _(s.bounds.left,s.bounds.top+m(s.styles.paddingTop,s.bounds.width),s.bounds.width,or(n.lineHeight,n.fontSize.number)/2+1);t.renderTextWithLetterSpacing(new vA(r.listValue,a),n.letterSpacing,or(n.lineHeight,n.fontSize.number)/2+2,n.writingMode),A.textBaseline="bottom",A.textAlign="left"}}}var hg=A=>A instanceof zn||A instanceof Zn?!0:A instanceof qA&&A.type!=="radio"&&A.type!=="checkbox",gg=A=>{switch(A){case 1:return"center";case 2:return"right";default:return"left"}},Ds=(A,e)=>{let t=e>A?e*(1+Math.pow(A/e-1,3)):e;return Math.max(0,A+t)},Ir=(A,e)=>{if(e===0)return A;let t=A.map((i,c)=>Y(i)?{x:c%2===0?i.start.x:i.end.x,y:c%2===0?i.end.y:i.start.y,rx:Math.abs(i.end.x-i.start.x),ry:Math.abs(i.end.y-i.start.y)}:{x:i.x,y:i.y,rx:0,ry:0}),r=w(t,1).x-w(t,0).x+2*e,s=w(t,3).y-w(t,0).y+2*e;if(r<=0||s<=0)return[];let n=t.map(i=>({x:Ds(i.rx,e),y:Ds(i.ry,e)})),o=(i,c)=>c>0?i/c:1,a=Math.min(1,o(r,w(n,0).x+w(n,1).x),o(r,w(n,3).x+w(n,2).x),o(s,w(n,0).y+w(n,3).y),o(s,w(n,1).y+w(n,2).y));return A.map((i,c)=>{let B=w(t,c),l=B.x+(c===1||c===2?e:-e),h=B.y+(c>=2?e:-e);if(!Y(i))return new F(l,h);let g=w(n,c).x*a,u=w(n,c).y*a;if(!g||!u)return new F(l,h);let d=g/B.rx,Q=u/B.ry,f=C=>new F(l+(C.x-B.x)*d,h+(C.y-B.y)*Q);return new Ue(f(i.start),f(i.startControl),f(i.endControl),f(i.end))})},ug=(A,e,t)=>{let{a:r,b:s,c:n,d:o,e:a,f:i}=A;if(![r,s,n,o,a,i,e,t].every(Number.isFinite))return null;let c=r*o-s*n;if(!Number.isFinite(c)||c===0)return null;let B=(E,I)=>({x:(o*(E-a)-n*(I-i))/c,y:(-s*(E-a)+r*(I-i))/c}),l=[B(0,0),B(e,0),B(e,t),B(0,t)];if(!l.every(E=>Number.isFinite(E.x)&&Number.isFinite(E.y)))return null;let h=Math.min(...l.map(E=>E.x)),g=Math.min(...l.map(E=>E.y)),u=Math.max(...l.map(E=>E.x)),d=Math.max(...l.map(E=>E.y)),Q=r*r+s*s,f=n*n+o*o,C=r*n+s*o,p=Math.sqrt((Q+f+Math.hypot(Q-f,2*C))/2);if(!Number.isFinite(p)||p<=0)return null;let U=1e-10*Math.max(Q,f);return{matrix:A,viewport:new _(h,g,u-h,d-g),scale:p,uniform:Math.abs(Q-f)<=U&&Math.abs(C)<=U}},He=(A,e,t)=>{A.beginPath(),A.rect(e.left,e.top,e.width,e.height),t.length&&(it(A,t),A.closePath())},Qr=(A,e)=>{let t=e.spread.number,r=re(A.container);return r.width-2*t<=0||r.height-2*t<=0?[]:Ir(mA(A.curves),-t)},wg=async(A,e,t,r,s,n)=>{let o=re(e.container),a=t.blur.number/2,i=Math.ceil(3*a)+2,c=t.spread.number,B=dr((t.inset?o:e.container.bounds.add(t.offsetX.number-c,t.offsetY.number-c,2*c,2*c)).add(-i,-i,2*i,2*i),n.viewport,i,n.scale);if(!B.width||!B.height)return!0;let l=Math.ceil(B.width*n.scale),h=Math.ceil(B.height*n.scale),g=pe(s,l,h);if(!g)return!1;let u,d;try{u=A.canvas.ownerDocument.createElement("canvas"),u.width=l,u.height=h;let Q=u.getContext("2d");if(!Q)return!1;Q.scale(n.scale,n.scale),Q.translate(-B.left,-B.top);let f=t.inset?Qr(e,t):Ir(hA(e.curves),c),C=st(f,t.offsetX.number,t.offsetY.number,0,0);t.inset?He(Q,B,C):FA(Q,C),Q.fillStyle=L(t.color),Q.fill(t.inset?"evenodd":"nonzero"),d=await At(u,{blur:a},1,n.scale,r.signal),A.save();try{t.inset?(FA(A,mA(e.curves)),A.clip()):(He(A,n.viewport,hA(e.curves)),A.clip("evenodd")),A.drawImage(d,B.left,B.top,d.width/n.scale,d.height/n.scale)}finally{A.restore()}return!0}catch(Q){if(!(Q instanceof j))throw Q;return!1}finally{d&&d!==u&&N(d),u&&N(u),s.pixels-=g}},dg=async(A,e,t,r,s)=>{if(r.signal?.aborted)throw new DOMException("The operation was aborted.","AbortError");if(BA(t.color))return;let n=t.spread.number;if(!t.inset&&(e.container.bounds.width+2*n<=0||e.container.bounds.height+2*n<=0))return;let o=typeof A.getTransform=="function",a=o?A.getTransform():{a:r.scale,b:0,c:0,d:r.scale,e:-r.x*r.scale,f:-r.y*r.scale},i=ug(a,A.canvas.width,A.canvas.height);if(!i)return;let{viewport:c}=i;if(t.blur.number>0&&(t.inset||!i.uniform)&&await wg(A,e,t,r,s,i))return;let B=re(e.container);A.save();try{if(t.inset&&t.blur.number===0){FA(A,mA(e.curves)),A.clip(),He(A,B,st(Qr(e,t),t.offsetX.number,t.offsetY.number,0,0)),A.fillStyle=L(t.color),A.fill("evenodd");return}let l=Math.ceil(t.blur.number*2+Math.abs(n)+Math.abs(t.offsetX.number)+Math.abs(t.offsetY.number))+2,h=t.inset?B.add(-l,-l,2*l,2*l):e.container.bounds.add(-n,-n,2*n,2*n),{a:g,b:u,c:d,d:Q,e:f,f:C}=a,p=h.left+h.width,U=h.top+h.height,E=Math.max(g*h.left+d*h.top+f,g*p+d*h.top+f,g*p+d*U+f,g*h.left+d*U+f),I=Math.max($B,E+l*i.scale+2);t.inset?(FA(A,mA(e.curves)),A.clip()):(He(A,c,hA(e.curves)),A.clip("evenodd")),o?A.setTransform(g,u,d,Q,f-I,C):A.translate(-I/g,0),t.inset?He(A,h,Qr(e,t)):FA(A,Ir(hA(e.curves),n)),o?A.setTransform(g,u,d,Q,f,C):A.translate(I/g,0),A.shadowOffsetX=I+g*t.offsetX.number+d*t.offsetY.number,A.shadowOffsetY=u*t.offsetX.number+Q*t.offsetY.number,A.shadowBlur=t.blur.number*i.scale,A.shadowColor=L(t.color),A.fillStyle="rgb(0, 0, 0)",A.fill(t.inset?"evenodd":"nonzero")}finally{A.restore()}},Qg=class{constructor(A){this.ctx=A.ctx,this.context=A.context,this.createFontStyle=A.createFontStyle}async render(A){let e=A.container,t=e.styles,r=e.bounds;if(r.width<=0||r.height<=0)return;let s=this.ctx.canvas.ownerDocument??document,n=s.createElement("canvas"),o=Math.ceil(r.width),a=Math.ceil(r.height);n.width=o,n.height=a;let i=n.getContext("2d");if(!i)return;let[c]=this.createFontStyle(t);i.font=c??"",i.textBaseline="alphabetic",i.textAlign="left",i.direction=t.direction===1?"rtl":"ltr";let B=co(i,t.fontSize.number),l=new Bo({ctx:i,context:this.context,canvas:n,options:{width:o,height:a,scale:1}});BA(t.backgroundColor)||(i.fillStyle=L(t.backgroundColor),i.fillRect(0,0,o,a)),i.save(),i.translate(-r.left,-r.top),await l.renderBackgroundImage(e),i.restore();let h=s.createElement("canvas");h.width=o,h.height=a;let g=h.getContext("2d");if(!g)return;g.font=i.font,g.textBaseline=i.textBaseline,g.textAlign=i.textAlign,g.direction=i.direction,g.fillStyle="#000";let u=t.writingMode,d=t.letterSpacing;for(let Q of e.textNodes)for(let f of Q.textBounds){let C=f.bounds.left-r.left,p=f.bounds.top-r.top+B;d>0?this.renderTextMaskWithLetterSpacing(g,f,d,C,p,u):g.fillText(f.text,C,p)}i.globalCompositeOperation="destination-in",i.drawImage(h,0,0),this.ctx.drawImage(n,r.left,r.top)}renderTextMaskWithLetterSpacing(A,e,t,r,s,n){let o=UA(e.text),a=r;for(let i of o){if(Ee(n)){A.fillText(e.text,r,s);return}A.fillText(i,a,s),a+=A.measureText(i).width+t}}},fg=class fr{constructor(e,t,r,s={pixels:0}){this.surfaceRoot=r,this.surfaceBudget=s,this.legacySubtree=!1,this.context=e,this.options=t,this.canvas=t.canvas?t.canvas:document.createElement("canvas");let n=this.canvas.getContext("2d");if(!n)throw t.canvas||N(this.canvas),r?new j("Filter surface canvas is unavailable"):new Error("Failed to get 2D rendering context from canvas");this.ctx=n,t.canvas||(this.canvas.width=Math.floor(t.width*t.scale),this.canvas.height=Math.floor(t.height*t.scale),this.canvas.style.width=`${t.width}px`,this.canvas.style.height=`${t.height}px`),this.ctx.scale(this.options.scale,this.options.scale),this.ctx.translate(-t.x,-t.y),this.ctx.textBaseline="bottom",t.imageSmoothing!==void 0&&(this.ctx.imageSmoothingEnabled=t.imageSmoothing),t.imageSmoothingQuality&&(this.ctx.imageSmoothingQuality=t.imageSmoothingQuality),this.backgroundRenderer=new Bo({ctx:this.ctx,context:this.context,canvas:this.canvas,options:{width:t.width,height:t.height,scale:t.scale}}),this.borderRenderer=new $h({ctx:this.ctx},{path:o=>this.path(o),formatPath:o=>this.formatPath(o)}),this.borderImageRenderer=new Ag(this.ctx),this.effectsRenderer=new eg({ctx:this.ctx},{path:o=>this.path(o)}),this.textRenderer=new Wh({ctx:this.ctx,options:{scale:t.scale}}),this.textClipRenderer=new Qg({ctx:this.ctx,context:this.context,createFontStyle:o=>this.textRenderer.createFontStyle(o)}),this.context.logger.debug(`Canvas renderer initialized (${t.width}x${t.height}) with scale ${t.scale}`)}async renderStack(e){let t=e.element.container.styles;if(t.isVisible()){let r=je(t.filter),s=t.maskImage.length>0,n=t.webkitBoxReflect;if(e.element!==this.surfaceRoot&&!this.legacySubtree&&(s||n||r&&(t.filter||t.opacity<1))&&this.canComposite(e.element)){if(!await this.renderCompositedStack(e,r,s,n)){this.legacySubtree=!0;try{await this.renderStackContent(e)}finally{this.legacySubtree=!1}}return}await this.renderStackContent(e)}}canComposite(e){let t=n=>{let o=n.styles;return!o.isTransformed()&&o.zoom===1&&o.mixBlendMode===V.NORMAL&&o.clipPath.type===0&&!P(o.display,2048)&&je(o.filter)!==null},r=n=>t(n)&&n.elements.every(r),s=e.parent;for(;s&&s!==this.surfaceRoot;){if(!t(s.container))return!1;s=s.parent}return r(e.container)}async renderCompositedStack(e,t,r,s){let n=this.options.signal;if(n?.aborted)throw new DOMException("The operation was aborted.","AbortError");let o=dr(io(e.element.container),new _(this.options.x,this.options.y,this.options.width,this.options.height),t?oo(t):0,this.options.scale);if(!o.width||!o.height)return!0;let a=pe(this.surfaceBudget,Math.ceil(o.width*this.options.scale),Math.ceil(o.height*this.options.scale));if(!a)return this.context.logger.info("Filter surface budget exceeded; using the existing renderer"),!1;let i={...this.options,canvas:void 0,backgroundColor:null,x:o.left,y:o.top,width:o.width,height:o.height},c,B;try{c=new fr(this.context,i,e.element,this.surfaceBudget),await c.renderStackContent(e),c.effectsRenderer.applyEffects([]),t&&(B=await At(c.canvas,t,e.element.container.styles.opacity,i.scale,n));let l=B??c.canvas;if(r&&await this.applyMask(l,e.element.container.styles,o),n?.aborted)throw new DOMException("The operation was aborted.","AbortError");let h=e.element.effects,g=e.element.getEffects(4,this.surfaceRoot).filter(u=>!h.includes(u)||!yr(u)&&!Hr(u)&&!nt(u));return this.effectsRenderer.applyEffects(g),this.ctx.drawImage(l,i.x,i.y,l.width/i.scale,l.height/i.scale),s&&await this.drawReflection(l,e.element.container.bounds,o,s),!0}catch(l){if(!(l instanceof j))throw l;return this.context.logger.info(`${l.message}; using the existing renderer`),!1}finally{c&&N(c.canvas),B&&N(B),this.surfaceBudget.pixels-=a}}async applyMask(e,t,r){let s=e.getContext("2d");if(!s)return;let n=document.createElement("canvas");n.width=e.width,n.height=e.height;let o=n.getContext("2d");if(o){o.scale(this.options.scale,this.options.scale),o.translate(-r.left,-r.top);try{await Ks(o,t.maskImage,t,{left:r.left,top:r.top,width:r.width,height:r.height},async a=>await this.context.cache.match(a))}catch(a){this.context.logger.error(`Error rendering mask-image: ${a instanceof Error?a.message:a}`);return}s.save();try{s.setTransform(1,0,0,1,0,0),s.globalCompositeOperation="destination-in",s.drawImage(n,0,0)}finally{s.restore()}}}async drawReflection(e,t,r,s){let n=this.options.scale,o=Math.ceil(t.width*n),a=Math.ceil(t.height*n);if(o<=0||a<=0)return;let i=pe(this.surfaceBudget,o,a);if(!i)return;let c,B;try{c=document.createElement("canvas"),c.width=o,c.height=a;let l=c.getContext("2d");if(!l)return;let h=Math.round((t.left-r.left)*n),g=Math.round((t.top-r.top)*n),u=s.direction==="left"||s.direction==="right";l.save();try{u?(l.translate(o,0),l.scale(-1,1)):(l.translate(0,a),l.scale(1,-1)),l.drawImage(e,-h,-g)}finally{l.restore()}if(s.mask){B=document.createElement("canvas"),B.width=o,B.height=a;let C=B.getContext("2d");if(C){await Ks(C,[s.mask],{maskPosition:[],maskRepeat:[],maskSize:[]},{left:0,top:0,width:t.width,height:t.height},async p=>await this.context.cache.match(p)),l.save();try{u?(l.translate(o,0),l.scale(-1,1)):(l.translate(0,a),l.scale(1,-1)),l.globalCompositeOperation="destination-in",l.drawImage(B,0,0)}finally{l.restore()}}}let d=s.offset,Q=t.left,f=t.top;s.direction==="below"?f=t.top+t.height+d:s.direction==="above"?f=t.top-t.height-d:s.direction==="right"?Q=t.left+t.width+d:Q=t.left-t.width-d,this.ctx.save();try{this.ctx.filter="none",this.ctx.drawImage(c,Q,f,t.width,t.height)}finally{this.ctx.restore()}}finally{c&&N(c),B&&N(B),this.surfaceBudget.pixels-=i}}async renderNode(e){if(e.container.debugRender)debugger;e.container.styles.isVisible()&&(await this.renderNodeBackgroundAndBorders(e),await this.renderNodeContent(e))}renderReplacedElement(e,t,r){let s=r.naturalWidth||e.intrinsicWidth,n=r.naturalHeight||e.intrinsicHeight;if(r&&s>0&&n>0){let o=Se(e),a=mA(t);this.path(a),this.ctx.save(),this.ctx.clip();let{sx:i,sy:c,sw:B,sh:l,dx:h,dy:g,dw:u,dh:d}=og(s,n,o,e.styles.objectFit,e.styles.objectPosition);this.ctx.drawImage(r,i,c,B,l,h,g,u,d),this.ctx.restore()}}async renderNodeContent(e){this.effectsRenderer.applyEffects(e.getEffects(4,this.surfaceRoot));let t=e.container,r=e.curves,s=t.styles,n=Se(t);for(let o of t.textNodes)await this.textRenderer.renderTextNode(o,s,n);await ig(this.ctx,this.context,{scale:this.options.scale,backgroundColor:this.options.backgroundColor,x:this.options.x,y:this.options.y,width:this.options.width,height:this.options.height},(o,a)=>new fr(o,a),t,r,s,(o,a,i)=>this.renderReplacedElement(o,a,i)),ag(this.ctx,this.textRenderer,this.path.bind(this),t,s),await lg(this.ctx,this.context,this.textRenderer,e,t,s)}async renderStackContent(e){if(e.element.container.debugRender)debugger;let t=this.options.signal;await this.renderNodeBackgroundAndBorders(e.element);for(let r of e.negativeZIndex){if(t?.aborted)throw new DOMException("The operation was aborted.","AbortError");await this.renderStack(r)}if(t?.aborted)throw new DOMException("The operation was aborted.","AbortError");await this.renderNodeContent(e.element);for(let r of e.nonInlineLevel)await this.renderNode(r);for(let r of e.nonPositionedFloats){if(t?.aborted)throw new DOMException("The operation was aborted.","AbortError");await this.renderStack(r)}for(let r of e.nonPositionedInlineLevel){if(t?.aborted)throw new DOMException("The operation was aborted.","AbortError");await this.renderStack(r)}for(let r of e.inlineLevel)await this.renderNode(r);for(let r of e.zeroOrAutoZIndexOrTransformedOrOpacity){if(t?.aborted)throw new DOMException("The operation was aborted.","AbortError");await this.renderStack(r)}for(let r of e.positiveZIndex){if(t?.aborted)throw new DOMException("The operation was aborted.","AbortError");await this.renderStack(r)}}mask(e){this.ctx.beginPath();let t=this.options.x,r=this.options.y;this.ctx.moveTo(t,r),this.ctx.lineTo(t+this.options.width,r),this.ctx.lineTo(t+this.options.width,r+this.options.height),this.ctx.lineTo(t,r+this.options.height),this.ctx.lineTo(t,r),this.formatPath(e.slice(0).reverse()),this.ctx.closePath()}path(e){FA(this.ctx,e)}formatPath(e){it(this.ctx,e)}async renderSurfaceBoxShadow(e,t){let r=t.spread.number,s=t.blur.number/2,n=Math.ceil(3*s)+1,o=e.container.bounds.add(-r,-r,2*r,2*r);if(o.width<=0||o.height<=0)return;let a=this.options.scale,i=dr(o.add(-n,-n,2*n,2*n),new _(this.options.x-t.offsetX.number,this.options.y-t.offsetY.number,this.options.width,this.options.height),n,a);if(!i.width||!i.height)return;let c=Math.ceil(i.width*a),B=Math.ceil(i.height*a),l=pe(this.surfaceBudget,c,B);if(!l)throw new j("Box shadow surface budget exceeded");let h,g;try{h=document.createElement("canvas"),h.width=c,h.height=B;let u=h.getContext("2d");if(!u)throw new j("Box shadow surface canvas is unavailable");u.scale(a,a),u.translate(-i.left,-i.top),FA(u,st(hA(e.curves),-r,-r,2*r,2*r)),u.fillStyle=L(t.color),u.fill(),g=await At(h,{blur:s},1,a,this.options.signal),this.ctx.save();try{this.ctx.beginPath(),this.ctx.rect(this.options.x,this.options.y,this.options.width,this.options.height),it(this.ctx,hA(e.curves)),this.ctx.closePath(),this.ctx.clip("evenodd"),this.ctx.drawImage(g,i.left+t.offsetX.number,i.top+t.offsetY.number,g.width/a,g.height/a)}finally{this.ctx.restore()}}finally{h&&N(h),g&&N(g),this.surfaceBudget.pixels-=l}}async renderNodeBackgroundAndBorders(e){this.effectsRenderer.applyEffects(e.getEffects(2,this.surfaceRoot)),!this.surfaceRoot&&e.container.styles.backdropFilter&&await this.renderBackdropFilter(e);let t=e.container.styles,r=!BA(t.backgroundColor)||t.backgroundImage.length,s=Ug(t),n=[{style:t.borderTopStyle,color:t.borderTopColor,width:t.borderTopWidth},{style:t.borderRightStyle,color:t.borderRightColor,width:t.borderRightWidth},{style:t.borderBottomStyle,color:t.borderBottomColor,width:t.borderBottomWidth},{style:t.borderLeftStyle,color:t.borderLeftColor,width:t.borderLeftWidth}],o=LA(t.backgroundClip,0),a=Cg(o,e.curves);if(r||t.boxShadow.length){s&&e.container.textNodes.length>0?await this.textClipRenderer.render(e):(this.ctx.save(),this.path(a),this.ctx.clip(),BA(t.backgroundColor)||(this.ctx.fillStyle=L(t.backgroundColor),this.ctx.fill()),await this.backgroundRenderer.renderBackgroundImage(e.container),this.ctx.restore());for(let c of t.boxShadow.slice(0).reverse()){if(this.surfaceRoot&&!c.inset){await this.renderSurfaceBoxShadow(e,c);continue}await dg(this.ctx,e,c,this.options,this.surfaceBudget)}}if(t.borderImageSource){let c=t.borderImageSource;if(c.type===0){let B=c.url;try{let l=await this.context.cache.match(B);if(l){let h=e.container.bounds,g=[Math.max(0,t.borderTopWidth),Math.max(0,t.borderRightWidth),Math.max(0,t.borderBottomWidth),Math.max(0,t.borderLeftWidth)],u=jh(t.borderImageOutset,g),d=h.add(-u.left,-u.top,u.left+u.right,u.top+u.bottom),Q=qh(t.borderImageWidth,g,d);this.borderImageRenderer.renderBorderImage(h,l,t.borderImageSlice,t.borderImageRepeat,Q[0],Q[1],Q[2],Q[3],u)}}catch{this.context.logger.error(`Error loading border-image ${B}`)}}return}let i=0;for(let c of n){if(c.style!==0&&!BA(c.color)&&c.width>0){let B=async()=>{c.style===2?await this.borderRenderer.renderDashedDottedBorder(c.color,c.width,i,e.curves,2):c.style===3?await this.borderRenderer.renderDashedDottedBorder(c.color,c.width,i,e.curves,3):c.style===4?await this.borderRenderer.renderDoubleBorder(c.color,c.width,i,e.curves):await this.borderRenderer.renderSolidBorder(c.color,i,e.curves)},l=e.container.legendBounds;if(i===0&&l){let h=e.container.bounds,g=l.left-h.left,u=l.left+l.width-h.left;g>0&&(this.ctx.save(),this.ctx.beginPath(),this.ctx.rect(h.left,h.top,g,h.height),this.ctx.clip(),await B(),this.ctx.restore());let d=h.left+u,Q=h.width-u;Q>0&&(this.ctx.save(),this.ctx.beginPath(),this.ctx.rect(d,h.top,Q,h.height),this.ctx.clip(),await B(),this.ctx.restore())}else await B()}i++}this.renderOutline(e)}renderOutline(e){let t=e.container.styles;if(t.outlineStyle===0||t.outlineStyle===1)return;let r=Math.max(0,t.outlineWidth);if(r<=0)return;let s=t.outlineColor??t.color;if(BA(s))return;let n=Math.max(0,t.outlineOffset)+r/2,o=st(hA(e.curves),-n,-n,2*n,2*n);this.ctx.save();try{this.ctx.strokeStyle=L(s),this.ctx.lineWidth=r,t.outlineStyle===3?this.ctx.setLineDash([r*3,r*3]):t.outlineStyle===4&&this.ctx.setLineDash([r,r*2]),this.path(o),this.ctx.stroke()}finally{this.ctx.restore()}}async renderBackdropFilter(e){let t=je(e.container.styles.backdropFilter);if(!t||!t.blur&&!t.shadow)return;let r=e.container.bounds;if(r.width<=0||r.height<=0)return;let s=this.options.scale,n=Math.ceil(r.width*s),o=Math.ceil(r.height*s);if(n<=0||o<=0)return;let a=pe(this.surfaceBudget,n,o);if(!a)return;let i,c;try{i=document.createElement("canvas"),i.width=n,i.height=o;let B=i.getContext("2d");if(!B)return;let l=Math.round((r.left-this.options.x)*s),h=Math.round((r.top-this.options.y)*s);if(B.drawImage(this.canvas,l,h,n,o,0,0,n,o),c=await At(i,t,1,s,this.options.signal),this.options.signal?.aborted)throw new DOMException("The operation was aborted.","AbortError");this.ctx.save();try{this.ctx.filter="none",this.ctx.drawImage(c,r.left,r.top,r.width,r.height)}finally{this.ctx.restore()}}finally{i&&N(i),c&&N(c),this.surfaceBudget.pixels-=a}}async render(e){try{this.options.backgroundColor&&(this.ctx.fillStyle=L(this.options.backgroundColor),this.ctx.fillRect(this.options.x,this.options.y,this.options.width,this.options.height));let t=Ih(e);return await this.renderStack(t),this.effectsRenderer.applyEffects([]),this.canvas}catch(t){throw this.options.canvas||N(this.canvas),t}}},Cg=(A,e)=>{switch(A){case 0:return hA(e);case 2:return Fh(e);default:return mA(e)}},Ug=A=>A.backgroundClip.some(e=>e===3),Fg=class{constructor(A,e){this.context=A,this.options=e,this.canvas=e.canvas?e.canvas:document.createElement("canvas");let t=this.canvas.getContext("2d");if(!t)throw new Error("Failed to get 2D rendering context from canvas");this.ctx=t,this.canvas.width=Math.floor(e.width*e.scale),this.canvas.height=Math.floor(e.height*e.scale),this.canvas.style.width=`${e.width}px`,this.canvas.style.height=`${e.height}px`,this.ctx.scale(this.options.scale,this.options.scale),this.ctx.translate(-e.x,-e.y),this.context.logger.debug(`EXPERIMENTAL ForeignObject renderer initialized (${e.width}x${e.height} at ${e.x},${e.y}) with scale ${e.scale}`)}async render(A){if(this.options.signal?.aborted)throw new DOMException("The operation was aborted.","AbortError");let e=lr(this.options.width*this.options.scale,this.options.height*this.options.scale,this.options.scale,this.options.scale,A),t=await hr(e);return this.options.backgroundColor&&(this.ctx.fillStyle=L(this.options.backgroundColor),this.ctx.fillRect(0,0,this.options.width*this.options.scale,this.options.height*this.options.scale)),this.ctx.drawImage(t,-this.options.x*this.options.scale,-this.options.y*this.options.scale),this.canvas}},pg=class{static{this.instances={}}constructor({id:A,enabled:e}){this.id=A,this.enabled=e,this.start=Date.now()}debug(...A){this.enabled&&(typeof window<"u"&&window.console&&typeof console.debug=="function"?console.debug(this.id,`${this.getTime()}ms`,...A):this.info(...A))}getTime(){return Date.now()-this.start}info(...A){this.enabled&&typeof window<"u"&&window.console&&typeof console.info=="function"&&console.info(this.id,`${this.getTime()}ms`,...A)}warn(...A){this.enabled&&(typeof window<"u"&&window.console&&typeof console.warn=="function"?console.warn(this.id,`${this.getTime()}ms`,...A):this.info(...A))}error(...A){this.enabled&&(typeof window<"u"&&window.console&&typeof console.error=="function"?console.error(this.id,`${this.getTime()}ms`,...A):this.info(...A))}},mg=class{constructor(A,e){if(this.context=A,this._options=e,this._cache=new Map,this._pendingOperations=new Map,this._deferMode=!1,this._collectedUrls=new Set,this.maxSize=e.maxCacheSize??100,this.maxSize<1)throw new Error("Cache maxSize must be at least 1");this.maxSize>1e4&&this.context.logger.warn(`Cache maxSize ${this.maxSize} is very large and may cause memory issues. Consider using a smaller value (recommended: 100-1000).`)}startDefer(){this._deferMode=!0}async preloadAll(A=10,e){this._deferMode=!1;let t=Array.from(this._collectedUrls);if(this._collectedUrls.clear(),t.length===0)return;let r=Math.max(1,Math.min(A,100));this.context.logger.debug(`Preloading ${t.length} image(s) with concurrency ${r}`);let s=0;e?.(0,t.length);for(let n=0;nthis._addImageWithPending(i));await Promise.allSettled(a),s+=o.length,e?.(s,t.length)}}addImage(A){if(this._deferMode)return!this.has(A)&&(he(A)||Ms(A))&&this._collectedUrls.add(A),Promise.resolve();let e=this._pendingOperations.get(A);if(e)return e;if(this.has(A)){let t=this._cache.get(A);return this._cache.delete(A),this._cache.set(A,t),Promise.resolve()}return he(A)||Ms(A)?this._addImageWithPending(A):Promise.resolve()}_addImageWithPending(A){let e=this._pendingOperations.get(A);if(e)return e;let t=this._addImageInternal(A);return this._pendingOperations.set(A,t),t.finally(()=>{this._pendingOperations.delete(A)}),t}async _addImageInternal(A){let e=this._options.imageTimeout??15e3,t=this.withTimeout(this.loadImage(A),e,`Timed out (${e}ms) loading image`);t.catch(r=>{this.context.logger.error(`Failed to load image ${A}: ${r instanceof Error?r.message:"Unknown error"}`)}),this.set(A,t)}withTimeout(A,e,t){if(e<=0)return A;let r,s=new Promise((n,o)=>{r=setTimeout(()=>o(new Error(t)),e)});return Promise.race([A,s]).finally(()=>{r!==void 0&&clearTimeout(r)})}match(A){let e=this._cache.get(A);if(e)return this._cache.delete(A),this._cache.set(A,e),e.value}set(A,e){if(this._cache.has(A))this._cache.delete(A);else if(this._cache.size>=this.maxSize){let t=this._cache.keys().next().value;t!==void 0&&(this._cache.delete(t),this.context.logger.debug(`Cache: Evicted LRU entry: ${t}`))}this._cache.set(A,{value:e})}size(){return this._cache.size}getMaxSize(){return this.maxSize}clear(){this._cache.clear()}async loadImage(A){let e=this.context.originChecker,t=i=>e.isSameOrigin(i),r=typeof this._options.customIsSameOrigin=="function"?await this._options.customIsSameOrigin(A,t):t(A),s=!r&&this._options.allowTaint===!1&&!Ze(A)&&!he(A)&&typeof this._options.proxy!="string",n=!Ze(A)&&(this._options.useCORS===!0||s)&&X.SUPPORT_CORS_IMAGES&&!r,o=!Ze(A)&&!r&&!he(A)&&typeof this._options.proxy=="string"&&X.SUPPORT_CORS_XHR&&!n;if(!r&&this._options.allowTaint===!1&&!Ze(A)&&!he(A)&&!o&&!n)return;let a=A;return o&&(a=await this.proxy(a)),this.context.logger.debug(`Added image ${A.substring(0,256)}`),await new Promise((i,c)=>{let B=new Image;B.onload=()=>i(B),B.onerror=c,(Ig(a)||n)&&(B.crossOrigin="anonymous"),B.src=a,B.complete===!0&&setTimeout(()=>i(B),500)})}has(A){return this._cache.has(A)}keys(){return Promise.resolve(Array.from(this._cache.keys()))}proxy(A){let e=this._options.proxy;if(!e)throw new Error("No proxy defined");let t=A.substring(0,256);return new Promise((r,s)=>{let n=X.SUPPORT_RESPONSE_TYPE?"blob":"text",o=new XMLHttpRequest;o.onload=()=>{if(o.status===200)if(n==="text")r(o.response);else{let i=new FileReader;i.addEventListener("load",()=>r(i.result),!1),i.addEventListener("error",c=>s(c),!1),i.readAsDataURL(o.response)}else s(`Failed to proxy resource ${t} with status code ${o.status}`)},o.onerror=s;let a=e.indexOf("?")>-1?"&":"?";if(o.open("GET",`${e}${a}url=${encodeURIComponent(A)}&responseType=${n}`),n!=="text"&&o instanceof XMLHttpRequest&&(o.responseType=n),this._options.imageTimeout){let i=this._options.imageTimeout;o.timeout=i,o.ontimeout=()=>s(`Timed out (${i}ms) proxying ${t}`)}o.send()})}},Eg=/^data:image\/svg\+xml/i,Hg=/^data:image\/.*;base64,/i,yg=/^data:image\/.*/i,Ms=A=>X.SUPPORT_SVG_DRAWING||!bg(A),Ze=A=>yg.test(A),Ig=A=>Hg.test(A),he=A=>A.substring(0,4)==="blob",bg=A=>A.slice(-3).toLowerCase()==="svg"||Eg.test(A),xg=class{constructor(A){if(!A||!A.document)throw new Error("Valid window object required for OriginChecker");if(!A.location||!A.location.href)throw new Error("Window object must have valid location");this.link=A.document.createElement("a"),this.origin=this.getOrigin(A.location.href)}getOrigin(A){return this.link.href=A,this.link.href=this.link.href,this.link.protocol+this.link.hostname+this.link.port}isSameOrigin(A){return this.getOrigin(A)===this.origin}getContextOrigin(){return this.origin}},Lg=class lo{static{this.instanceCount=1}constructor(e,t,r){this.instanceName=`#${lo.instanceCount++}`,this.config=r,this.logger=new pg({id:this.instanceName,enabled:e.logging}),this.originChecker=new xg(r.window),this.cache=e.cache??r.cache??new mg(this,e),this.onError=e.onError,this._windowBounds=t}get windowBounds(){return this._windowBounds}adjustWindowBounds(e,t){this._windowBounds=this._windowBounds.add(e,t,0,0)}},Sg=A=>{["scale","width","height","imageTimeout","x","y","windowWidth","windowHeight","scrollX","scrollY"].forEach(e=>{let t=A[e];if(t!=null&&typeof t!="number"){let r=Number(t);Number.isNaN(r)||(A[e]=r)}})},Kg=A=>({allowTaint:A.allowTaint??!1,imageTimeout:A.imageTimeout??15e3,proxy:A.proxy,useCORS:A.useCORS??!1,customIsSameOrigin:A.customIsSameOrigin,maxCacheSize:A.maxCacheSize}),Dg=(A,e,t)=>({logging:A.logging??!0,cache:A.cache??e.cache,...t}),Mg=800,vg=600,vs=0,Tg=(A,e)=>{let t=e;return{windowWidth:A.windowWidth??t.innerWidth??Mg,windowHeight:A.windowHeight??t.innerHeight??vg,scrollX:A.scrollX??t.pageXOffset??vs,scrollY:A.scrollY??t.pageYOffset??vs}},Og=(A,e,t)=>({allowTaint:A.allowTaint??!1,onclone:A.onclone,ignoreElements:A.ignoreElements,iframeContainer:A.iframeContainer,inlineImages:t,copyStyles:t,cspNonce:A.cspNonce??e.cspNonce}),Rg=(A,e,t,r,s,n,o)=>({canvas:A.canvas,backgroundColor:e,signal:A.signal,scale:A.scale??o??1,x:(A.x??0)+t,y:(A.y??0)+r,width:A.width??Math.ceil(s),height:A.height??Math.ceil(n),imageSmoothing:A.imageSmoothing,imageSmoothingQuality:A.imageSmoothingQuality}),Vg=(A,e,t)=>{let r=e.ownerDocument,s=r.documentElement?jA(A,getComputedStyle(r.documentElement).backgroundColor):0,n=r.body?jA(A,getComputedStyle(r.body).backgroundColor):0,o=typeof t=="string"?jA(A,t):t===null?0:4294967295;return e===r.documentElement?BA(s)?BA(n)?o:n:s:o},bA=(A,e,t,r)=>{if(A)try{A(t,r)}catch(s){e.logger.error(`onProgress callback failed: ${s instanceof Error?s.message:String(s)}`)}},Ng=async(A,e,t)=>{if(Sg(e),!e.skipValidation){let $=e.validator||uo(),W=$.validateElement(A);if(!W.valid)throw new Error(W.error);let k=$.validateOptions(e);if(!k.valid)throw new Error(`Invalid options: ${k.error}`)}if(!A||typeof A!="object")throw new Error("Invalid element provided as first argument");let r=A.ownerDocument;if(!r)throw new Error("Element is not attached to a Document");let s=r.defaultView;if(!s)throw new Error("Document is not attached to a Window");let n=Kg(e),o=Dg(e,t,n),a=Tg(e,s),i=new _(a.scrollX,a.scrollY,a.windowWidth,a.windowHeight),c=new Lg(o,i,t),B=e.enablePerformanceMonitoring??e.logging??!1,l=new wo(c,B);l.start("total",{width:a.windowWidth,height:a.windowHeight});let h=e.signal;oA(h);let g=e.foreignObjectRendering??!1,u=Og(e,t,g);c.logger.debug(`Starting document clone with size ${i.width}x${i.height} scrolled to ${-i.left},${-i.top}`),bA(e.onProgress,c,"clone",10),l.start("clone");let d=new Lt(c,A,u),Q=d.clonedReferenceElement;if(!Q)throw new Error("Unable to find element in cloned iframe");let f=await d.toIFrame(r,i);l.end("clone"),bA(e.onProgress,c,"clone",30),h?.aborted&&((e.removeContainer??!0)&&Lt.destroy(f),oA(h));let{width:C,height:p,left:U,top:E}=pr(Q)||fa(Q)?Qo(Q.ownerDocument):ye(c,Q),I=Vg(c,Q,e.backgroundColor),S=Rg(e,I,U,E,C,p,s.devicePixelRatio??1),y,D;try{g?(c.logger.debug("Document cloned, using foreign object rendering"),l.start("render-foreignobject"),y=await new Fg(c,S).render(Q),l.end("render-foreignobject")):(c.logger.debug(`Document cloned, element located at ${U},${E} with size ${C}x${p} using computed rendering`),c.logger.debug("Starting DOM parsing"),l.start("parse"),oA(h),c.cache.startDefer(),D=Ao(c,Q),l.end("parse"),bA(e.onProgress,c,"parse",50),l.start("preload"),await c.cache.preloadAll(10,($,W)=>{bA(e.onProgress,c,"preload",50+Math.round($/W*10))}),l.end("preload"),bA(e.onProgress,c,"layout",60),I===D.styles.backgroundColor&&(D.styles.backgroundColor=0),c.logger.debug(`Starting renderer for element at ${S.x},${S.y} with size ${S.width}x${S.height}`),l.start("render"),oA(h),y=await new fg(c,S).render(D),l.end("render")),bA(e.onProgress,c,"render",90)}finally{l.start("cleanup");try{D&&D.restoreTree()}finally{(e.removeContainer??!0)&&Lt.destroy(f),l.end("cleanup")}}return l.end("total"),c.logger.debug("Finished rendering"),B&&l.logSummary(),bA(e.onProgress,c,"render",100),y},Gg=(A,e={},t)=>{let r=t||ho.fromElement(A,{cspNonce:e.cspNonce,cache:e.cache});return Ng(A,e,r)};export{ho as Html2CanvasConfig,wo as PerformanceMonitor,go as Validator,uo as createDefaultValidator,Gg as default,Gg as html2canvas}; +/*! Bundled license information: + +html2canvas-pro/dist/html2canvas-pro.esm.js: + (*! + * html2canvas-pro 2.5.0 + * Copyright (c) 2024-present yorickshan and html2canvas-pro contributors + * Released under MIT License + *) +*/ diff --git a/browser/dist/esm/index.js b/browser/dist/esm/index.js new file mode 100644 index 0000000..f39ec15 --- /dev/null +++ b/browser/dist/esm/index.js @@ -0,0 +1,3 @@ +import{a as v,c as D,d as q,f as V,g as Y}from"./chunk-5LBAMSSV.js";import{a as I,d as j,f as J}from"./chunk-QBI2JL2F.js";var K=new WeakSet;function C(t){K.has(t)||(K.add(t),t.addEventProcessor((e,r)=>{if(e.type==="feedback"||e.type==="replay_event"){delete e.user,delete e.request,delete e.breadcrumbs,delete e.extra,delete e.transaction,e.type==="replay_event"&&Object.assign(e,{urls:[]});let i=r.data?.feedbackReplayId;e.type==="feedback"&&typeof i=="string"&&/^[a-f0-9]{32}$/i.test(i)&&e.contexts?.feedback&&(e.contexts.feedback.replay_id=i)}return e}))}function k(t){return t.split(/[?#]/)[0].replace(/\/(?:login|password|tokens?|invites?|kiosk|reset)(?:\/[^\s]*)?/gi,"/[private-page]").replace(/\/[A-Za-z0-9_-]{24,}(?=\/|$)/g,"/:id").replace(/\b[0-9a-f]{8}-[0-9a-f-]{27,}\b/gi,":id").replace(/\/\d+(?=\/|$)/g,"/:id").slice(0,256)}var X=new WeakSet,ie=/^(?:http\.request\.method|http\.response\.status_code|server\.address|sentry\.(?:origin|source|sample_rate|op|exclusive_time)|type|op)$/;function ae(t){try{return new URL(t).origin}catch{return"[resource]"}}function T(t){t.op?.startsWith("ui.")?t.description="interaction":t.description&&(["pageload","navigation"].includes(t.op??"")?t.description=k(t.description):/https?:\/\//i.test(t.description)?t.description=t.description.replace(/https?:\/\/\S+/gi,ae):["pageload","navigation"].includes(t.op??"")||(t.description=t.op??"operation"),t.description=t.description.split(/[?#]/)[0].replace(/\b[^\s/]+@[^\s/]+\b/g,"[private]").slice(0,256));let e={};for(let[r,i]of Object.entries(t.data??{})){if(/^browser\.web_vital\.(?:lcp|cls|inp|fcp|ttfb)\.(?:value|load_time|render_time|size)$/.test(r)&&typeof i=="number"&&Number.isFinite(i)){e[r]=i;continue}if(r==="sentry.pageload.span_id"&&typeof i=="string"&&/^[a-f0-9]{16}$/i.test(i)){e[r]=i;continue}if(["sentry.segment.name","sentry.transaction"].includes(r)&&typeof i=="string"){e[r]=k(i);continue}if(r==="user_agent.original"&&typeof i=="string"&&typeof navigator<"u"&&i===navigator.userAgent){e[r]=i.slice(0,512);continue}!ie.test(r)||!["string","number","boolean"].includes(typeof i)||(typeof i=="string"?r==="server.address"?e[r]=/^[a-z0-9.:-]+$/i.test(i)?i:"[destination]":/^[a-z0-9_. /:-]{1,128}$/i.test(i)&&(e[r]=i):e[r]=i)}return t.data=e,t}function _(t){if(X.has(t))return;X.add(t);let e=t.getOptions(),r=e.beforeSendSpan;e.beforeSendSpan=i=>T(r?r(i):i)}function Z(){return!!v()}async function G(t){let e=v();if(!e||!t.message.trim())throw new Error("Feedback is unavailable");typeof e.addEventProcessor=="function"&&C(e),await new Promise((r,i)=>{let s,o=e.on("afterSendEvent",(f,m)=>{f.event_id===s&&(clearTimeout(c),o(),m?.statusCode&&m.statusCode>=200&&m.statusCode<300?r():i(new Error("Feedback was not accepted")))}),c=setTimeout(()=>{o(),i(new Error("Feedback timed out"))},15e3);try{s=D({message:t.message.trim(),url:t.pageUrl,source:"api",tags:{page_component:t.component}},{includeReplay:!1,data:{feedbackReplayId:t.replayId},attachments:t.screenshot?[{filename:"feedback-screenshot.png",contentType:"image/png",data:t.screenshot.data}]:[]})}catch(f){clearTimeout(c),o(),i(f)}})}function Q(t,e){return new Promise(r=>{let i=!1,s=setTimeout(()=>{i=!0,r(void 0)},8e3);t.then(o=>{clearTimeout(s),i?o&&e?.(o):r(o)}).catch(()=>{clearTimeout(s),r(void 0)})})}function z(t={}){let e={message:"",busy:!1,capturing:!1,captureState:"pending",error:"",success:!1},r=0,i=!1,s={pageUrl:"",component:""},o=()=>t.changed?.({...e});function c(){e.screenshot&&(URL.revokeObjectURL(e.screenshot.previewUrl),e.captureState="removed"),e.screenshot=void 0,o()}async function f(){if(i||t.eligible?.()===!1)return;i=!0;let p=++r;e.error="",e.success=!1,e.capturing=!0,e.captureState=j(window.location)?"private":"pending",s={pageUrl:J(window.location),component:t.component?.()??"document"},o();let l=Q(import("./feedbackScreenshot-XN3R2P73.js").then(b=>b.captureFeedbackScreenshot()),b=>URL.revokeObjectURL(b.previewUrl)),R=Q(import("./feedbackReplay-6PAAGWVV.js").then(b=>b.freezeFeedbackReplay())),[g,y]=await Promise.all([l,R]);if(p!==r){g&&URL.revokeObjectURL(g.previewUrl);return}e.screenshot=g,s.replayId=y,e.capturing=!1,e.captureState!=="private"&&(e.captureState=g?"ready":"unavailable"),o()}function m(){e.busy||(w(),import("./feedbackReplay-6PAAGWVV.js").then(p=>p.restartFeedbackReplay()))}function w(){r++,i=!1,c(),e.message="",e.capturing=!1,o()}async function S(){if(e.busy||e.capturing||t.eligible?.()===!1)return;if(e.error="",!e.message.trim()){e.error="messageRequired",o();return}if(!Z()){e.error="unavailable",o();return}let p=r;e.busy=!0,o();try{await G({...s,message:e.message,screenshot:e.screenshot}),p===r&&(e.success=!0,e.message="",c())}catch{p===r&&(e.error="sendFailed")}finally{e.busy=!1,o()}}return{state:e,open:f,close:m,cancel:w,submit:S,removeScreenshot:c,setMessage(p){e.message=p,o()}}}var ee="sentry.feedback.corner";function te(){try{let t=localStorage.getItem(ee);if(["topLeft","topRight","bottomLeft","bottomRight"].includes(t??""))return t}catch{}return"bottomRight"}function re(t){try{localStorage.setItem(ee,t)}catch{}}function H(t,e){return{x:t.endsWith("Left")?e.left:e.right,y:t.startsWith("top")?e.top:e.bottom}}function ne(t,e){return(t.y<(e.top+e.bottom)/2?"top":"bottom")+(t.x<(e.left+e.right)/2?"Left":"Right")}function oe(t,e){if(e==="ArrowLeft")return t.startsWith("top")?"topLeft":"bottomLeft";if(e==="ArrowRight")return t.startsWith("top")?"topRight":"bottomRight";if(e==="ArrowUp")return t.endsWith("Left")?"topLeft":"topRight";if(e==="ArrowDown")return t.endsWith("Left")?"bottomLeft":"bottomRight"}function $(t,e){return{x:Math.max(e.left,Math.min(e.right,t.x)),y:Math.max(e.top,Math.min(e.bottom,t.y))}}var se={title:"Feedback",open:"Send feedback",close:"Close",message:"What happened?",submit:"Send",done:"Done",remove:"Remove screenshot",success:"Thank you. Your feedback was accepted.",sendFailed:"Feedback could not be sent. Please try again.",messageRequired:"Enter a message.",unavailable:"Feedback is unavailable.",disclosure:"Opening feedback uploads the recent replay buffer. Your message and screenshot are sent only when you submit.",pending:"Preparing capture\u2026",ready:"Review your screenshot",removed:"Screenshot removed",private:"Text feedback only on this page",captureUnavailable:"Capture unavailable; you can still send text feedback.",moved:"Feedback button moved"};function ce(t={}){let e=t.eligible?.()??!0;I(t.policy??{});let r={...se,...t.labels},i=new AbortController,s=document.createElement("div");s.dataset.feedbackUi="",s.dataset.sentryBlock="",s.className=t.className??"",s.innerHTML=`

`,s.hidden=!e,document.body.append(s);let o=n=>s.querySelector(n),c=o(".sentry-feedback-trigger"),f=o("dialog"),m=o("textarea"),w=o("img"),S=o("h2");S.id=`sentry-feedback-${crypto.randomUUID()}`,S.textContent=r.title,f.setAttribute("aria-labelledby",S.id),c.setAttribute("aria-label",r.open),c.title=r.open,o(".disclosure").textContent=r.disclosure,o("label span").textContent=r.message,o(".submit").textContent=r.submit,o(".remove").textContent=r.remove,o(".close").textContent=r.close,o(".success").textContent=r.success;let p=z({eligible:()=>e&&(t.eligible?.()??!0),component:t.component,changed(n){m.value=n.message,m.disabled=n.busy,o(".submit").disabled=n.busy||n.capturing,o(".close").disabled=n.busy,o(".error").textContent=n.error?r[n.error]:"",o(".capture").textContent=n.captureState==="unavailable"?r.captureUnavailable:r[n.captureState],w.hidden=!n.screenshot,n.screenshot?w.src=n.screenshot.previewUrl:w.removeAttribute("src"),o(".remove").hidden=!n.screenshot,o("form").hidden=n.success,o(".success").hidden=!n.success,n.success&&(o(".close").textContent=r.done,o(".close").focus())}}),l=(n,a,d)=>n.addEventListener(a,d,{signal:i.signal});l(c,"click",()=>{if(P){P=!1;return}f.open||(p.open(),f.showModal(),m.focus())});let R=()=>{p.state.busy||(p.close(),f.close(),c.focus())};l(o(".close"),"click",R),l(f,"cancel",n=>{n.preventDefault(),R()}),l(o("form"),"submit",n=>{n.preventDefault(),p.submit()}),l(m,"input",()=>p.setMessage(m.value)),l(o(".remove"),"click",p.removeScreenshot);let g=()=>{p.cancel(),f.close()};l(window,"popstate",g),l(window,"hashchange",g);let y=te(),b,F=0,P=!1,u,N=window.matchMedia("(prefers-reduced-motion: reduce)");function L(){let n=getComputedStyle(o(".sentry-feedback-probe")),a=U=>parseFloat(U)||0,d=window.visualViewport,x=(d?.offsetLeft??0)+16+a(n.paddingLeft),E=(d?.offsetTop??0)+16+a(n.paddingTop);return{left:x,top:E,right:Math.max(x,(d?.offsetLeft??0)+(d?.width??innerWidth)-64-a(n.paddingRight)),bottom:Math.max(E,(d?.offsetTop??0)+(d?.height??innerHeight)-64-a(n.paddingBottom))}}function B(n){b=n,c.style.transform=`translate3d(${n.x}px,${n.y}px,0)`}function h(n=!0){cancelAnimationFrame(F);let a=H(y,L()),d=b??a;if(!n||N.matches){B(a);return}let x=performance.now(),E=U=>{let A=(U-x)/700,O=1-Math.exp(-6*A)*Math.cos(7.5*A);B($({x:d.x+(a.x-d.x)*O,y:d.y+(a.y-d.y)*O},L())),A<1?F=requestAnimationFrame(E):B(a)};F=requestAnimationFrame(E)}function W(n){y=n,re(y),o('[role="status"]').textContent=r.moved,h()}l(c,"pointerdown",n=>{let a=n;!a.isPrimary||a.button!==0||u||(cancelAnimationFrame(F),u={id:a.pointerId,start:{x:a.clientX,y:a.clientY},origin:b??H(y,L()),moved:!1},P=!1,c.setPointerCapture(a.pointerId))}),l(c,"pointermove",n=>{let a=n;if(!u||u.id!==a.pointerId)return;let d=a.clientX-u.start.x,x=a.clientY-u.start.y;!u.moved&&Math.hypot(d,x)<8||(u.moved=!0,B($({x:u.origin.x+d,y:u.origin.y+x},L())))});let M=n=>{let a=n;!u||u.id!==a.pointerId||(P=u.moved||a.type==="pointercancel",u=void 0,c.hasPointerCapture(a.pointerId)&&c.releasePointerCapture(a.pointerId),P?W(ne(b,L())):h())};return l(c,"pointerup",M),l(c,"pointercancel",M),l(c,"lostpointercapture",M),l(c,"keydown",n=>{let a=n,d=oe(y,a.key);d&&(a.preventDefault(),W(d))}),l(window,"resize",()=>h(!1)),window.visualViewport&&(l(window.visualViewport,"resize",()=>h(!1)),l(window.visualViewport,"scroll",()=>h(!1))),l(N,"change",()=>h(!1)),h(!1),e&&import("./feedbackReplay-6PAAGWVV.js").then(n=>{e&&n.setFeedbackReplayEnabled(!0)}),{controller:p,setEnabled(n){e=n,n?s.hidden=!1:(g(),s.hidden=!0),import("./feedbackReplay-6PAAGWVV.js").then(a=>a.setFeedbackReplayEnabled(n))},dispose(){e=!1,i.abort(),cancelAnimationFrame(F),p.cancel(),s.remove(),import("./feedbackReplay-6PAAGWVV.js").then(n=>n.setFeedbackReplayEnabled(!1))}}}async function Pe(t,e,r){if(!e||r<=0)return!1;if(r>=100)return!0;let i=new Uint8Array(await crypto.subtle.digest("SHA-256",new TextEncoder().encode(`${t}:${e.toLowerCase()}`)));return new DataView(i.buffer).getUint32(0)%100+1<=r}function le(t){t.transaction=k(t.transaction??"document"),delete t.request,delete t.extra,delete t.breadcrumbs,t.user&&(t.user=t.user.id?{id:t.user.id}:void 0);for(let e of t.spans??[])T(e);return t}function Le(t,e){if(e)return C(e),_(e),e;let r=v();if(r)return C(r),_(r),r;let i=/^(?:localhost|127\.|0\.0\.0\.0|\[?::1\]?$)|\.(?:localhost|test)$/.test(window.location.hostname);if(!t.enabled||i&&!t.localVerification)return;q({...t,sendDefaultPii:!1,replaysSessionSampleRate:0,replaysOnErrorSampleRate:0,integrations:[V({instrumentNavigation:!t.inertia,beforeStartSpan:o=>({...o,name:k(o.name)})})],beforeSendSpan:T,beforeSendTransaction:le});let s=v();return s&&C(s),s}function Ee(t){let e=v();if(e)return Y(e,{name:k(t),op:"navigation",attributes:{"sentry.source":"component"}})}export{I as configureCapturePolicy,z as createFeedbackController,Le as initializeBrowser,ce as mountFeedbackWidget,Pe as percentageEligible,T as sanitizeSpan,le as sanitizeTransaction,k as stablePageName,Ee as startInertiaNavigation}; diff --git a/browser/dist/sentry-box.js b/browser/dist/sentry-box.js new file mode 100644 index 0000000..fa71e66 --- /dev/null +++ b/browser/dist/sentry-box.js @@ -0,0 +1 @@ +(()=>{var t=new URL("./esm/index.js",document.currentScript.src).href,n,i=()=>n??=import(t);Object.assign(window,{SentryBox:{ready:i,initializeBrowser:async(...e)=>(await i()).initializeBrowser(...e),mountFeedbackWidget:async(...e)=>(await i()).mountFeedbackWidget(...e)}});})(); diff --git a/browser/package-lock.json b/browser/package-lock.json new file mode 100644 index 0000000..195cf6d --- /dev/null +++ b/browser/package-lock.json @@ -0,0 +1,3211 @@ +{ + "name": "@ortus/sentry-browser", + "version": "3.0.0-alpha.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@ortus/sentry-browser", + "version": "3.0.0-alpha.1", + "dependencies": { + "@sentry/browser": "10.74.0", + "html2canvas-pro": "2.5.0" + }, + "devDependencies": { + "esbuild": "0.25.12", + "jsdom": "30.0.1", + "typescript": "7.0.2", + "vitest": "4.1.11" + } + }, + "node_modules/@asamuzakjp/css-color": { + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-6.0.7.tgz", + "integrity": "sha512-vC/bk1Lz7Tn/EfU9/apOTBk80/8dyGyWMowPoV1tJ52muDGsDqt2HPT2klrFUiY60MQmQv9q8yIht15JnBgDGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^3.3.0", + "@csstools/css-color-parser": "^4.1.10", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0", + "lru-cache": "^11.5.2" + }, + "engines": { + "node": "^22.13.0 || >=24.0.0" + } + }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-8.3.2.tgz", + "integrity": "sha512-93Z1N+BQNXysodoicpOIyNh2drHfz/CTf9nnT0FEx72GJcIiwgydD7tGAr78j41LsYn3hlRn+LdGPuBLn1Bl8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "bidi-js": "^1.0.3", + "css-tree": "^3.2.1", + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.5.2" + }, + "engines": { + "node": "^22.13.0 || >=24.0.0" + } + }, + "node_modules/@bramus/specificity": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.2.tgz", + "integrity": "sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "^3.0.0" + }, + "bin": { + "specificity": "bin/cli.js" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.1.2.tgz", + "integrity": "sha512-grhRy3OKmniaAEKXMjua5z/EODX0MSqBGjunw8+j/3HQjOnahs2AGhvEOIYVUWcU6ScApbhLhVrQTX8XqrMrow==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@csstools/css-calc": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.4.3.tgz", + "integrity": "sha512-iex20d8CHVkyvg6B7UKV7uHnI2Bqo9g+EFfT9E0y+GvTvhZ/DwONJ+9aKb1dlqm0ZiGsL5RXjp0fCoJYnkeDjA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.2", + "@csstools/css-tokenizer": "^4.0.2" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.2.6.tgz", + "integrity": "sha512-iiPQ3iRWwnJkeEn6RIu6SJPr7hYrLz6XZ9s/QZl+2/LI5KQVjpl2fdmDSZKuD4xP6GMmMPgHFFXg6k1Wkz0Trg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^6.1.2", + "@csstools/css-calc": "^3.4.3" + }, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.2", + "@csstools/css-tokenizer": "^4.0.2" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.2.tgz", + "integrity": "sha512-40cSKyMvK+tq4qz6Awrlye2WGuOKt3FwPgtGg6KTfbHOWNw+Rk1rzbAtZnZ6IBhsY491HLRnDXwoyBAijmmILA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^4.0.2" + } + }, + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.15.tgz", + "integrity": "sha512-J0u7HkVl2nzSlhsiTOp4AmwcUQ3D+mGEEKfBy/7To5/y7F2OHwyLrXfrhR0SMgr4p5Lo+eaMVSeai24zUcBIxA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "peerDependencies": { + "css-tree": "^3.2.1" + }, + "peerDependenciesMeta": { + "css-tree": { + "optional": true + } + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.2.tgz", + "integrity": "sha512-OoKoR0f76dCY666JlcbhmVTs2drYj1GUXZTYTcbUgJjh9Nv41aFfZ21bPQTERm5+L5cBDo466NltB2lplS5GBw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@exodus/bytes": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.16.0.tgz", + "integrity": "sha512-IcpW84uEn3N7ETtNZMlxKhfl6Pec8rUNGOTBtWbK1FKhJxIFAptZyVrvVRVBimAJxJCgc3PxepxkdWWG4DVzfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@noble/hashes": "^1.8.0 || ^2.0.0" + }, + "peerDependenciesMeta": { + "@noble/hashes": { + "optional": true + } + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@oxc-project/types": { + "version": "0.152.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.152.0.tgz", + "integrity": "sha512-oM/5rLBm2tPkg0iBgkH/FOeR3PCDpY19GTgAZjMFM8h9WI9VW7cLgzp6nwtarYKmovavIQZ+Fe/RKX/8C8O/Rw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/oxc-project" + } + }, + "node_modules/@rolldown/binding-android-arm-eabi": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.12.tgz", + "integrity": "sha512-dB/a1214qKfHMXCpgqR4OZT+jS4kTyEXbQGJPqzobt5EwH5rX080pxE37alt3RzvR1bf1Yz/yGqRfrYAxuPw0A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.12.tgz", + "integrity": "sha512-7KHFgQ5VJxIHcLlrwrc3Xbds7oTNQT7Pgi9gQCJKrd2VGab/UksIOYp6VD8MzCstGxOKMgNamPwUCfxPdP1OHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.12.tgz", + "integrity": "sha512-3YIhqHD96nA5SaYNRBR16HnGv4oavZvXfD/ayHM+oYZ0WD/8lBAtf6zQua4kEyAvpqrluKXl0lnOBoiNby7x9w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.12.tgz", + "integrity": "sha512-UuuJ35MFw4gmFOrE9pEqIV+K3syIKveph+Qc1/ljHZVdoDW4pz/JHR/eMVom+TZGl/5OOvGJOWaOCVt3ZfqhxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.12.tgz", + "integrity": "sha512-uMvssit0a4W+/7D8CbHUvG719mH3R2jwXAlh/XcPvuHTE0g++LymF88DCGNX0HM2rBOn0xrzgXktIB6fLSJBTQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.12.tgz", + "integrity": "sha512-XcFu0R0xWnwzSf4IQgFH1rJIckPN1pLy2R+4r9IDB7Yfu/ys9cVqfa4pBrMHj7a3gl8mIR4nRNPg0e5IvEVs6g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.12.tgz", + "integrity": "sha512-260UrKgn8tz39ak+SMDOirKzr7V04M9dWPw5llW00SwBivCZoWcRBKV1d8cXnRkUmSZA3BdiUmBHWk7734Ulpw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.12.tgz", + "integrity": "sha512-5YK1I9SqDkbPgc1IA8BgDl34suqUS2q0KWnBrirm0E51YjOs6eo6dV6jbQfNE/argHRSvd0QUGgtpIoYx+WWpw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.12.tgz", + "integrity": "sha512-Rkcrmp7eFRg74yL5fXEU91JEWbdEPLevWwGtXpmhbjlD1StScbWTmO94Bhly+Mo+ketKYkdmM1vNUKeWSlx8cQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.12.tgz", + "integrity": "sha512-qvK4DuAsQc2BSjlx+Xr+IzOIvvxbGZqxFwdWfG6F518Erj0GGISyQbJ6pIappnOxlNPzNHvo/L0BwB30GZ+zVw==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.12.tgz", + "integrity": "sha512-Q9uLBO53Xd4QIq1WOycVQyPP1O4HhraEV2qqb3uTrnVw6QZih9duY4vNXOivL1xoUS1/z+W8eF4NMfl2a8Sdjw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.12.tgz", + "integrity": "sha512-3IBxWFMjbOZskDPKv8Lf9BCnahlKuHthWkYnyIxOH/QcJrFcS4EmcenthApkwr/5+nEqZlLzeYbxeMaX7A5u4g==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.12.tgz", + "integrity": "sha512-xtX61xg4LKPkPWilZU1ynKClz5Gj4bf74LML4r3eVLWumKnGjoEr1OSHQhMdbBDoYTi+yjrujvpZe2pUnqCrrA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.12.tgz", + "integrity": "sha512-At7fPB6PCaIjzgIhEZFxuT+BBFqiQibJDT4d3PhiR3f4E7bbMZF4aKblbFfEM3sETRDd1YiQx/+U/g/B/ou5Ew==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.12.tgz", + "integrity": "sha512-WIw2haVKwjuYdXkHaoC0mF8Le71TuCBxjrdKqLbJGctbBABj+ClfmNvtbOnzpq3RokNo5+V1qhtSzJyXorsklQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sentry/browser": { + "version": "10.74.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-10.74.0.tgz", + "integrity": "sha512-U6Zn+YcAgnR7bXZmpjMxivptPSsOeDKV+SlSqbJZqViOaCcZSG/vJiQr50UrdTccCwiU1LnwuOOoclJOvW+cLQ==", + "license": "MIT", + "dependencies": { + "@sentry/browser-utils": "10.74.0", + "@sentry/conventions": "^0.16.0", + "@sentry/core": "10.74.0", + "@sentry/feedback": "10.74.0", + "@sentry/replay": "10.74.0", + "@sentry/replay-canvas": "10.74.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/browser-utils": { + "version": "10.74.0", + "resolved": "https://registry.npmjs.org/@sentry/browser-utils/-/browser-utils-10.74.0.tgz", + "integrity": "sha512-/Rh3WH4i2nStdOqHpaWocbpSMFPjKhlxKQgp9vkJBSolqjJzXlIpLYXOrldZHHZLG1iDoX3PFBQkNDYcPXCg0A==", + "license": "MIT", + "dependencies": { + "@sentry/conventions": "^0.16.0", + "@sentry/core": "10.74.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/conventions": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@sentry/conventions/-/conventions-0.16.0.tgz", + "integrity": "sha512-fO9PLmHdVURcSPUpWCItWAtgKiMwGdJHbovoSEyLplX5sxs2ugvI4CBPTrkkgqhObnZOD0CnWBKDzSVQYBKEyQ==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/@sentry/core": { + "version": "10.74.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.74.0.tgz", + "integrity": "sha512-u9rY8vcZfktccwm6LznfCZlqP5C9A+p76r4/pFS1grqpuTO0m21Cl8rosnlESrDGP/Xd9tfr91rWYk0jPH8jeQ==", + "license": "MIT", + "dependencies": { + "@sentry/conventions": "^0.16.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/feedback": { + "version": "10.74.0", + "resolved": "https://registry.npmjs.org/@sentry/feedback/-/feedback-10.74.0.tgz", + "integrity": "sha512-WwUao9K2XgRIxTUTaBhm7aglhsyP7LQTGi2lxvFbXzlSagUzwew/EL2c5oqQ23Mjn94i5SY+rM4wMdgyWdtpAw==", + "license": "MIT", + "dependencies": { + "@sentry/core": "10.74.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/replay": { + "version": "10.74.0", + "resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-10.74.0.tgz", + "integrity": "sha512-amIu0zKzhQJZoWmlwfFnn/uKRGyF+Tikph3lBgYwj5XbHv4U94PQXi9Ll8CYzzLVS7BkrCVc2Hl7RvpRg5M2Yg==", + "license": "MIT", + "dependencies": { + "@sentry/browser-utils": "10.74.0", + "@sentry/core": "10.74.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/replay-canvas": { + "version": "10.74.0", + "resolved": "https://registry.npmjs.org/@sentry/replay-canvas/-/replay-canvas-10.74.0.tgz", + "integrity": "sha512-HAdu4ViRsuOD5ifphQR24HugL0geZXV8LnGQVkA8vlzZWiuYgGNqDRoUWI75IgVcCYLYSaVBoKN+jTimdzG/sQ==", + "license": "MIT", + "dependencies": { + "@sentry/core": "10.74.0", + "@sentry/replay": "10.74.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript/typescript-aix-ppc64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-aix-ppc64/-/typescript-aix-ppc64-7.0.2.tgz", + "integrity": "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-darwin-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-arm64/-/typescript-darwin-arm64-7.0.2.tgz", + "integrity": "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-darwin-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-x64/-/typescript-darwin-x64-7.0.2.tgz", + "integrity": "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-freebsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-arm64/-/typescript-freebsd-arm64-7.0.2.tgz", + "integrity": "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-freebsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-x64/-/typescript-freebsd-x64-7.0.2.tgz", + "integrity": "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-arm": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm/-/typescript-linux-arm-7.0.2.tgz", + "integrity": "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm64/-/typescript-linux-arm64-7.0.2.tgz", + "integrity": "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-loong64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-loong64/-/typescript-linux-loong64-7.0.2.tgz", + "integrity": "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-mips64el": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-mips64el/-/typescript-linux-mips64el-7.0.2.tgz", + "integrity": "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-ppc64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-ppc64/-/typescript-linux-ppc64-7.0.2.tgz", + "integrity": "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-riscv64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-riscv64/-/typescript-linux-riscv64-7.0.2.tgz", + "integrity": "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-s390x": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-s390x/-/typescript-linux-s390x-7.0.2.tgz", + "integrity": "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-x64/-/typescript-linux-x64-7.0.2.tgz", + "integrity": "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-netbsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-arm64/-/typescript-netbsd-arm64-7.0.2.tgz", + "integrity": "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-netbsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-x64/-/typescript-netbsd-x64-7.0.2.tgz", + "integrity": "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-openbsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-arm64/-/typescript-openbsd-arm64-7.0.2.tgz", + "integrity": "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-openbsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-x64/-/typescript-openbsd-x64-7.0.2.tgz", + "integrity": "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-sunos-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-sunos-x64/-/typescript-sunos-x64-7.0.2.tgz", + "integrity": "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-win32-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-arm64/-/typescript-win32-arm64-7.0.2.tgz", + "integrity": "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-win32-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-x64/-/typescript-win32-x64-7.0.2.tgz", + "integrity": "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@vitest/expect": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.11.tgz", + "integrity": "sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.1.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.1.11", + "@vitest/utils": "4.1.11", + "chai": "^6.2.2", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.11.tgz", + "integrity": "sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.11.tgz", + "integrity": "sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.1.11", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.11.tgz", + "integrity": "sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.11", + "@vitest/utils": "4.1.11", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.11.tgz", + "integrity": "sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.11.tgz", + "integrity": "sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.11", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/bidi-js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.1.0.tgz", + "integrity": "sha512-fX1Onk0tdVPC7obPWB5EbJ1z7NVhLq4m2xZLq2YXBkxzMXIGRpNMU88n0EPgWseKl12J7zXs7qrDxPK4sRs2fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, + "node_modules/chai": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.3.0.tgz", + "integrity": "sha512-XWAtwJ6OHO+tj0EKCs0Y2UamnyOxseZWltU4x2U2wh8g4AigdjwvtUjvLP2tqkA/avxHEtzxNaqGq/YGNwckKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/css-line-break": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", + "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", + "license": "MIT", + "dependencies": { + "utrie": "^1.0.2" + } + }, + "node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/data-urls": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-7.0.0.tgz", + "integrity": "sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/data-urls/node_modules/whatwg-url": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-16.0.1.tgz", + "integrity": "sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.11.0", + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/entities": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-8.1.0.tgz", + "integrity": "sha512-kxL7msIffSuh9aaFAMD7rxAIuTRMAHMeBtgHW2yUdWw732ZNh4MehkF2gdjvtdmikkaIP9bFDDJOPlsvm7avrA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-module-lexer": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz", + "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz", + "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.6.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/html2canvas-pro": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/html2canvas-pro/-/html2canvas-pro-2.5.0.tgz", + "integrity": "sha512-+xuLQWcYMGvbXtlIzVOLvNJEXqL/dY7Dbn2T4qYtJvqfPVtJ8BcNr1CrrUp/uCxne9DE/F+eZHsf1khb1dbMyg==", + "license": "MIT", + "dependencies": { + "css-line-break": "^2.1.0", + "text-segmentation": "^1.0.3" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsdom": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-30.0.1.tgz", + "integrity": "sha512-52v7mUVUfNQVYYqE1lcdaymWL0njO7lTLUog6ZvW2U5KsbiLk/GnZlVJ+qx0xfNJZ6Gn+KSpPNE52vurbxZwrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^6.0.5", + "@asamuzakjp/dom-selector": "^8.3.0", + "@bramus/specificity": "^2.4.2", + "@csstools/css-syntax-patches-for-csstree": "^1.1.7", + "@exodus/bytes": "^1.15.1", + "css-tree": "^3.2.1", + "data-urls": "^7.0.0", + "decimal.js": "^10.6.0", + "html-encoding-sniffer": "^6.0.0", + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.5.2", + "parse5": "^8.0.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^6.0.2", + "undici": "^8.9.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^8.0.1", + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^17.1.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" + }, + "peerDependencies": { + "canvas": "^3.2.3" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lru-cache": { + "version": "11.5.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.3.tgz", + "integrity": "sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/nanoid": { + "version": "3.3.19", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.19.tgz", + "integrity": "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/obug": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.2.1.tgz", + "integrity": "sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz", + "integrity": "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^8.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.28", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz", + "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.18", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rolldown": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.12.tgz", + "integrity": "sha512-8wafseiaG80xmXSfqidUNqZcylTlhmPZZt+za2m+js2sFZ8dTNlhIOV2WcbIPx2hgwPBJpEUGFAMZ9bgBBLTSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.152.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm-eabi": "1.2.12", + "@rolldown/binding-android-arm64": "1.2.12", + "@rolldown/binding-darwin-arm64": "1.2.12", + "@rolldown/binding-darwin-x64": "1.2.12", + "@rolldown/binding-freebsd-x64": "1.2.12", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.12", + "@rolldown/binding-linux-arm64-gnu": "1.2.12", + "@rolldown/binding-linux-arm64-musl": "1.2.12", + "@rolldown/binding-linux-ppc64-gnu": "1.2.12", + "@rolldown/binding-linux-s390x-gnu": "1.2.12", + "@rolldown/binding-linux-x64-gnu": "1.2.12", + "@rolldown/binding-linux-x64-musl": "1.2.12", + "@rolldown/binding-openharmony-arm64": "1.2.12", + "@rolldown/binding-win32-arm64-msvc": "1.2.12", + "@rolldown/binding-win32-x64-msvc": "1.2.12" + } + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/source-map-js": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz", + "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.3.0.tgz", + "integrity": "sha512-OtU/EgQ1kIm5KwqQpBC6ZEMXrZRui11w8zgfTWp8cdO9B8OaPsbA8bTHO2P+HNo1VlUTGMVBwPhydu6poeXiag==", + "dev": true, + "license": "MIT" + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/text-segmentation": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", + "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", + "license": "MIT", + "dependencies": { + "utrie": "^1.0.2" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.1.tgz", + "integrity": "sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyrainbow": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.2.0.tgz", + "integrity": "sha512-LgO3D9yZJjApUiuUfl9iFAwrtaX4+lok3wJIqttGoKCHlWUqHqbQpnxCf82L8FjgKsh4iGo78hqJwgL8F6To2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tldts": { + "version": "7.4.16", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.16.tgz", + "integrity": "sha512-QwBER5KMR86IIjpIiO7H/Z3IMJPsZ1A6RKPAqzTTgOyUQUSt9FdnKcqhTaJmkY6HVrgouZHZR0ncK5QxvmnQeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^7.4.16" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "7.4.16", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.16.tgz", + "integrity": "sha512-MDolfaSJtlSK5Y0A1xl3277ekubZwobpBjugknDizI9O5Rm60a1m8k4ICK+MRsCDzPygT81mp3BBf5RKDlFRfA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tough-cookie": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.2.tgz", + "integrity": "sha512-exgYmnmL/sJpR3upZfXG5PoatXQii55xAiXGXzY+sROLZ/Y+SLcp9PgJNI9Vz37HpQ74WvDcLT8eqm+kV3FzrA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^7.0.5" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", + "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/typescript": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-7.0.2.tgz", + "integrity": "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc" + }, + "engines": { + "node": ">=16.20.0" + }, + "optionalDependencies": { + "@typescript/typescript-aix-ppc64": "7.0.2", + "@typescript/typescript-darwin-arm64": "7.0.2", + "@typescript/typescript-darwin-x64": "7.0.2", + "@typescript/typescript-freebsd-arm64": "7.0.2", + "@typescript/typescript-freebsd-x64": "7.0.2", + "@typescript/typescript-linux-arm": "7.0.2", + "@typescript/typescript-linux-arm64": "7.0.2", + "@typescript/typescript-linux-loong64": "7.0.2", + "@typescript/typescript-linux-mips64el": "7.0.2", + "@typescript/typescript-linux-ppc64": "7.0.2", + "@typescript/typescript-linux-riscv64": "7.0.2", + "@typescript/typescript-linux-s390x": "7.0.2", + "@typescript/typescript-linux-x64": "7.0.2", + "@typescript/typescript-netbsd-arm64": "7.0.2", + "@typescript/typescript-netbsd-x64": "7.0.2", + "@typescript/typescript-openbsd-arm64": "7.0.2", + "@typescript/typescript-openbsd-x64": "7.0.2", + "@typescript/typescript-sunos-x64": "7.0.2", + "@typescript/typescript-win32-arm64": "7.0.2", + "@typescript/typescript-win32-x64": "7.0.2" + } + }, + "node_modules/undici": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-8.11.2.tgz", + "integrity": "sha512-u4UB2/IrKdU6lFxumHmmo1a3fCQO5tzQllRorfoRS63txhrB7xTpSn1PftwC4qEHkOaqP95fCWW4lJzwErwzhQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=22.19.0" + } + }, + "node_modules/utrie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", + "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", + "license": "MIT", + "dependencies": { + "base64-arraybuffer": "^1.0.2" + } + }, + "node_modules/vitest": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.11.tgz", + "integrity": "sha512-fhACrNXUidIbGSBr5FlbuBkO7VWC1ZyLl0DO4CU2DrQoAPxX84Ysxs+HeGQpii5lZWV1Q4gBZTTu49mF+A6Edw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.1.11", + "@vitest/mocker": "4.1.11", + "@vitest/pretty-format": "4.1.11", + "@vitest/runner": "4.1.11", + "@vitest/snapshot": "4.1.11", + "@vitest/spy": "4.1.11", + "@vitest/utils": "4.1.11", + "es-module-lexer": "^2.0.0", + "expect-type": "^1.3.0", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^4.0.0-rc.1", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.1.0", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.1.11", + "@vitest/browser-preview": "4.1.11", + "@vitest/browser-webdriverio": "4.1.11", + "@vitest/coverage-istanbul": "4.1.11", + "@vitest/coverage-v8": "4.1.11", + "@vitest/ui": "4.1.11", + "happy-dom": "*", + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/coverage-istanbul": { + "optional": true + }, + "@vitest/coverage-v8": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + }, + "vite": { + "optional": false + } + } + }, + "node_modules/vitest/node_modules/@esbuild/aix-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", + "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==", + "cpu": [ + "ppc64" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/android-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz", + "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==", + "cpu": [ + "arm" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/android-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz", + "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==", + "cpu": [ + "arm64" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/android-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz", + "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==", + "cpu": [ + "x64" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/darwin-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz", + "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==", + "cpu": [ + "arm64" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/darwin-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz", + "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==", + "cpu": [ + "x64" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz", + "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==", + "cpu": [ + "arm64" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/freebsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz", + "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==", + "cpu": [ + "x64" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz", + "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==", + "cpu": [ + "arm" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz", + "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==", + "cpu": [ + "arm64" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz", + "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==", + "cpu": [ + "ia32" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-loong64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz", + "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==", + "cpu": [ + "loong64" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-mips64el": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz", + "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==", + "cpu": [ + "mips64el" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz", + "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==", + "cpu": [ + "ppc64" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-riscv64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz", + "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==", + "cpu": [ + "riscv64" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-s390x": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz", + "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==", + "cpu": [ + "s390x" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz", + "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==", + "cpu": [ + "x64" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz", + "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==", + "cpu": [ + "arm64" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/netbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz", + "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==", + "cpu": [ + "x64" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz", + "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==", + "cpu": [ + "arm64" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/openbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz", + "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==", + "cpu": [ + "x64" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz", + "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==", + "cpu": [ + "arm64" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/sunos-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz", + "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==", + "cpu": [ + "x64" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/win32-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz", + "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==", + "cpu": [ + "arm64" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/win32-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz", + "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==", + "cpu": [ + "ia32" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/win32-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz", + "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==", + "cpu": [ + "x64" + ], + "extraneous": true, + "license": "MIT", + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@vitest/mocker": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.11.tgz", + "integrity": "sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.1.11", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/esbuild": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", + "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==", + "extraneous": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.2", + "@esbuild/android-arm": "0.28.2", + "@esbuild/android-arm64": "0.28.2", + "@esbuild/android-x64": "0.28.2", + "@esbuild/darwin-arm64": "0.28.2", + "@esbuild/darwin-x64": "0.28.2", + "@esbuild/freebsd-arm64": "0.28.2", + "@esbuild/freebsd-x64": "0.28.2", + "@esbuild/linux-arm": "0.28.2", + "@esbuild/linux-arm64": "0.28.2", + "@esbuild/linux-ia32": "0.28.2", + "@esbuild/linux-loong64": "0.28.2", + "@esbuild/linux-mips64el": "0.28.2", + "@esbuild/linux-ppc64": "0.28.2", + "@esbuild/linux-riscv64": "0.28.2", + "@esbuild/linux-s390x": "0.28.2", + "@esbuild/linux-x64": "0.28.2", + "@esbuild/netbsd-arm64": "0.28.2", + "@esbuild/netbsd-x64": "0.28.2", + "@esbuild/openbsd-arm64": "0.28.2", + "@esbuild/openbsd-x64": "0.28.2", + "@esbuild/openharmony-arm64": "0.28.2", + "@esbuild/sunos-x64": "0.28.2", + "@esbuild/win32-arm64": "0.28.2", + "@esbuild/win32-ia32": "0.28.2", + "@esbuild/win32-x64": "0.28.2" + } + }, + "node_modules/vitest/node_modules/vite": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.3.2.tgz", + "integrity": "sha512-SQr1x6W5vVSbROg7vsyXIaxK9b0G7zsT68acdWWRmnBUsgDieLCRG+Rep9WdZgcposvv/GSnr4GUUBqB3vXq6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.33.0", + "picomatch": "^4.0.7", + "postcss": "^8.5.28", + "rolldown": "~1.2.11", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.7.1", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/webidl-conversions": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", + "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20" + } + }, + "node_modules/whatwg-mimetype": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", + "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/whatwg-url": { + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-17.1.2.tgz", + "integrity": "sha512-TEZA+Zqxin7Jjsm2cjRohCmen5awh+hT6Zi3VZdqZlNRk7zvOI/9WpBFg/DWlA56bWnzwm6DuB8NS0EsxQH9uQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.15.1", + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.1" + }, + "engines": { + "node": "^22.14.0 || >=24.0.0" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/browser/package.json b/browser/package.json new file mode 100644 index 0000000..553d651 --- /dev/null +++ b/browser/package.json @@ -0,0 +1 @@ +{"name":"@ortus/sentry-browser","version":"3.0.0-alpha.1","type":"module","exports":{ ".":"./src/index.ts", "./feedback":"./src/feedback.ts", "./screenshot":"./src/feedbackScreenshot.ts", "./privacy":"./src/feedbackCapturePrivacy.ts", "./position":"./src/feedbackPosition.ts", "./replay":"./src/feedbackReplay.ts", "./controller":"./src/controller.ts" },"scripts":{"build":"node build.mjs","test":"vitest run"},"dependencies":{"@sentry/browser":"10.74.0","html2canvas-pro":"2.5.0"},"devDependencies":{"esbuild":"0.25.12","vitest":"4.1.11","jsdom":"30.0.1","typescript":"7.0.2"}} diff --git a/browser/src/clientPrivacy.ts b/browser/src/clientPrivacy.ts new file mode 100644 index 0000000..615f5bd --- /dev/null +++ b/browser/src/clientPrivacy.ts @@ -0,0 +1,15 @@ +import type { BrowserClient } from '@sentry/browser'; +const configured = new WeakSet(); +export function installClientPrivacy(client: BrowserClient) { + if (configured.has(client)) return; + configured.add(client); + client.addEventProcessor((event, hint) => { + if (event.type === 'feedback' || event.type === 'replay_event') { + delete event.user; delete event.request; delete event.breadcrumbs; delete event.extra; delete event.transaction; + if (event.type === 'replay_event') Object.assign(event, { urls: [] }); + const replayId = hint.data?.feedbackReplayId; + if (event.type === 'feedback' && typeof replayId === 'string' && /^[a-f0-9]{32}$/i.test(replayId) && event.contexts?.feedback) event.contexts.feedback.replay_id = replayId; + } + return event; + }); +} diff --git a/browser/src/controller.ts b/browser/src/controller.ts new file mode 100644 index 0000000..79ca4f9 --- /dev/null +++ b/browser/src/controller.ts @@ -0,0 +1,40 @@ +import { feedbackAvailable, sendFeedback } from './feedback'; +import { feedbackPageUrl, isPrivateFeedbackPage } from './feedbackPrivacy'; +import type { FeedbackScreenshot } from './feedbackScreenshot'; +export type CaptureState = 'pending' | 'ready' | 'removed' | 'unavailable' | 'private'; +export interface FeedbackState { message: string; busy: boolean; capturing: boolean; screenshot?: FeedbackScreenshot; captureState: CaptureState; error: '' | 'messageRequired' | 'unavailable' | 'sendFailed'; success: boolean; } +export function captureWithDeadline(pending: Promise, discard?: (value: T) => void): Promise { + return new Promise(resolve => { let expired = false; const timer = setTimeout(() => { expired = true; resolve(undefined); }, 8000); + pending.then(value => { clearTimeout(timer); if (expired) { if (value) discard?.(value); } else resolve(value); }).catch(() => { clearTimeout(timer); resolve(undefined); }); }); +} +export function createFeedbackController(options: { component?: () => string; changed?: (state: FeedbackState) => void; eligible?: () => boolean } = {}) { + const state: FeedbackState = { message: '', busy: false, capturing: false, captureState: 'pending', error: '', success: false }; + let generation = 0, opened = false; + let context: { pageUrl: string; component: string; replayId?: string } = { pageUrl: '', component: '' }; + const notify = () => options.changed?.({ ...state }); + function removeScreenshot() { if (state.screenshot) { URL.revokeObjectURL(state.screenshot.previewUrl); state.captureState = 'removed'; } state.screenshot = undefined; notify(); } + async function open() { + if (opened || options.eligible?.() === false) return; + opened = true; const current = ++generation; state.error = ''; state.success = false; state.capturing = true; + state.captureState = isPrivateFeedbackPage(window.location) ? 'private' : 'pending'; + context = { pageUrl: feedbackPageUrl(window.location), component: options.component?.() ?? 'document' }; notify(); + const capture = captureWithDeadline(import('./feedbackScreenshot').then(m => m.captureFeedbackScreenshot()), image => URL.revokeObjectURL(image.previewUrl)); + const replay = captureWithDeadline(import('./feedbackReplay').then(m => m.freezeFeedbackReplay())); + const [image, replayId] = await Promise.all([capture, replay]); + if (current !== generation) { if (image) URL.revokeObjectURL(image.previewUrl); return; } + state.screenshot = image; context.replayId = replayId; state.capturing = false; + if (state.captureState !== 'private') state.captureState = image ? 'ready' : 'unavailable'; notify(); + } + function close() { if (state.busy) return; cancel(); void import('./feedbackReplay').then(m => m.restartFeedbackReplay()); } + function cancel() { generation++; opened = false; removeScreenshot(); state.message = ''; state.capturing = false; notify(); } + async function submit() { + if (state.busy || state.capturing || options.eligible?.() === false) return; + state.error = ''; if (!state.message.trim()) { state.error = 'messageRequired'; notify(); return; } + if (!feedbackAvailable()) { state.error = 'unavailable'; notify(); return; } + const current = generation; state.busy = true; notify(); + try { await sendFeedback({ ...context, message: state.message, screenshot: state.screenshot }); if (current === generation) { state.success = true; state.message = ''; removeScreenshot(); } } + catch { if (current === generation) state.error = 'sendFailed'; } + finally { state.busy = false; notify(); } + } + return { state, open, close, cancel, submit, removeScreenshot, setMessage(message: string) { state.message = message; notify(); } }; +} diff --git a/browser/src/feedback.ts b/browser/src/feedback.ts new file mode 100644 index 0000000..517ba30 --- /dev/null +++ b/browser/src/feedback.ts @@ -0,0 +1,73 @@ +import { installClientPrivacy } from './clientPrivacy'; +import { captureFeedback, getClient } from "@sentry/browser"; +import type { FeedbackScreenshot } from "./feedbackScreenshot"; + +export function feedbackAvailable(): boolean { + return Boolean(getClient()); +} + +export async function sendFeedback(input: { + message: string; + pageUrl: string; + component: string; + replayId?: string; + screenshot?: FeedbackScreenshot; +}): Promise { + const client = getClient(); + if (!client || !input.message.trim()) { + throw new Error("Feedback is unavailable"); + } + if (typeof client.addEventProcessor === "function") installClientPrivacy(client); + // flush() only confirms that the queue drained. Listen for the actual provider + // response so blocked, rate-limited or rejected reports never show success. + await new Promise((resolve, reject) => { + let eventId: string | undefined; + const cleanup = client.on("afterSendEvent", (event, response) => { + if (event.event_id !== eventId) { + return; + } + clearTimeout(timeout); + cleanup(); + if ( + response?.statusCode && + response.statusCode >= 200 && + response.statusCode < 300 + ) { + resolve(); + } else { + reject(new Error("Feedback was not accepted")); + } + }); + const timeout = setTimeout(() => { + cleanup(); + reject(new Error("Feedback timed out")); + }, 15_000); + try { + eventId = captureFeedback( + { + message: input.message.trim(), + url: input.pageUrl, + source: "api", + tags: { page_component: input.component }, + }, + { + includeReplay: false, + data: { feedbackReplayId: input.replayId }, + attachments: input.screenshot + ? [ + { + filename: "feedback-screenshot.png", + contentType: "image/png", + data: input.screenshot.data, + }, + ] + : [], + }, + ); + } catch (error) { + clearTimeout(timeout); + cleanup(); + reject(error); + } + }); +} diff --git a/browser/src/feedbackCapturePrivacy.ts b/browser/src/feedbackCapturePrivacy.ts new file mode 100644 index 0000000..68e17db --- /dev/null +++ b/browser/src/feedbackCapturePrivacy.ts @@ -0,0 +1,171 @@ +import { readableCapture } from "./feedbackPrivacy"; +// Credential fields stay excluded even when a password is toggled to text. +const secretFieldNames = [ + "password", + "passcode", + "verificationCode", + "loginCode", + "token", + "secret", + "apiKey", + "cardNumber", + "creditCard", + "cvv", + "cvc", + "securityCode", + "bankAccount", + "accountNumber", + "routingNumber", + "iban", +]; +export const feedbackSecretSelector = [ + "[data-feedback-secret]", + "[data-feedback-ui]", + "[data-token]", + '[name="otp" i]', + '[name="pin" i]', + '[id="otp" i]', + '[id="pin" i]', + ".sentry-mask", + "[data-sentry-mask]", + ".sentry-block", + "[data-sentry-block]", + 'input[type="password"]', + 'input[type="hidden"]', + '[autocomplete~="current-password"]', + '[autocomplete~="new-password"]', + '[autocomplete~="one-time-code"]', + '[autocomplete*="cc-" i]', + ...secretFieldNames.flatMap((name) => { + const words = name + .match(/[A-Z]?[a-z]+/g)! + .map((word) => word.toLowerCase()); + return ["name", "id"].map((attribute) => + words.map((word) => "[" + attribute + "*=" + word + " i]").join(""), + ); + }), + 'a[href*="token=" i]', + 'a[href*="/invites/"]', + 'a[href*="/secure-links/"]', + 'a[href*="/login-links/"]', + 'a[href*="/document-deliveries/"]', +].join(","); + +export function maskFeedbackText( + text: string, + element?: Element | null, +): string { + return !readableCapture() || element?.closest(feedbackSecretSelector) + ? text.replace(/\S/g, "*") + : text; +} +export const maskFeedbackReplayText = maskFeedbackText; + +// Authenticated or signed media URLs must not become replay metadata. +export const feedbackBlockedMediaSelector = [ + 'img[src*="?"]', + 'img[src*="#"]', + 'img[src^="data:"]', + 'img[src*="/document-deliveries/"]', + 'img[src*="/secure-links/"]', +].join(","); + +export const feedbackReplayMaskedAttributes = [ + "href", + "srcset", + "action", + "formaction", + "data-page", + "data-token", + "data-reference", + "title", + "aria-label", + "aria-description", + "alt", + "placeholder", + "content", + "style", + "data-position-name", + "data-staff-member", + "data-label-code", + "data-edit-role", + "data-edit-position", +]; + +const safeReplayAttributes = new Set([ + "class", + "role", + "type", + "width", + "height", + "colspan", + "rowspan", + "rows", + "cols", + "dir", + "lang", + "aria-hidden", + "src", + "value", + "d", + "viewBox", + "fill", + "stroke", + "stroke-width", + "stroke-linecap", + "stroke-linejoin", + "x", + "y", + "x1", + "y1", + "x2", + "y2", + "cx", + "cy", + "r", + "rx", + "ry", + "points", +]); + +export function maskReplayAttributesInTree(root: Element) { + for (const element of [root, ...root.querySelectorAll("*")]) { + for (const { name } of element.attributes) { + if ( + !safeReplayAttributes.has(name) && + !feedbackReplayMaskedAttributes.includes(name) + ) { + feedbackReplayMaskedAttributes.push(name); + } + } + } +} + +export function observeReplayAttributePrivacy() { + maskReplayAttributesInTree(document.documentElement); + // Register before rrweb's observer. Its serializers consult this same array, + // so newly introduced attributes are masked before mutation snapshots run. + const observer = new MutationObserver((changes) => { + for (const change of changes) { + if ( + change.type === "attributes" && + change.attributeName && + !safeReplayAttributes.has(change.attributeName) && + !feedbackReplayMaskedAttributes.includes(change.attributeName) + ) { + feedbackReplayMaskedAttributes.push(change.attributeName); + } + for (const node of change.addedNodes) { + if (node instanceof Element) { + maskReplayAttributesInTree(node); + } + } + } + }); + observer.observe(document.documentElement, { + subtree: true, + childList: true, + attributes: true, + }); + return observer; +} diff --git a/browser/src/feedbackPosition.ts b/browser/src/feedbackPosition.ts new file mode 100644 index 0000000..9e24f2d --- /dev/null +++ b/browser/src/feedbackPosition.ts @@ -0,0 +1,61 @@ +export type FeedbackCorner = + "topLeft" | "topRight" | "bottomLeft" | "bottomRight"; +export type Point = { x: number; y: number }; +export type Bounds = { + left: number; + top: number; + right: number; + bottom: number; +}; +export const positionKey = "sentry.feedback.corner"; +export function readCorner(): FeedbackCorner { + try { + const saved = localStorage.getItem(positionKey); + if ( + ["topLeft", "topRight", "bottomLeft", "bottomRight"].includes(saved ?? "") + ) { + return saved as FeedbackCorner; + } + } catch {} + return "bottomRight"; +} +export function saveCorner(corner: FeedbackCorner) { + try { + localStorage.setItem(positionKey, corner); + } catch {} +} +export function cornerPoint(corner: FeedbackCorner, bounds: Bounds): Point { + return { + x: corner.endsWith("Left") ? bounds.left : bounds.right, + y: corner.startsWith("top") ? bounds.top : bounds.bottom, + }; +} +export function nearestCorner(point: Point, bounds: Bounds): FeedbackCorner { + return ((point.y < (bounds.top + bounds.bottom) / 2 ? "top" : "bottom") + + (point.x < (bounds.left + bounds.right) / 2 + ? "Left" + : "Right")) as FeedbackCorner; +} +export function keyCorner( + corner: FeedbackCorner, + key: string, +): FeedbackCorner | undefined { + if (key === "ArrowLeft") { + return corner.startsWith("top") ? "topLeft" : "bottomLeft"; + } + if (key === "ArrowRight") { + return corner.startsWith("top") ? "topRight" : "bottomRight"; + } + if (key === "ArrowUp") { + return corner.endsWith("Left") ? "topLeft" : "topRight"; + } + if (key === "ArrowDown") { + return corner.endsWith("Left") ? "bottomLeft" : "bottomRight"; + } +} +export function constrain(point: Point, bounds: Bounds): Point { + return { + x: Math.max(bounds.left, Math.min(bounds.right, point.x)), + y: Math.max(bounds.top, Math.min(bounds.bottom, point.y)), + }; +} diff --git a/browser/src/feedbackPrivacy.ts b/browser/src/feedbackPrivacy.ts new file mode 100644 index 0000000..86eb47a --- /dev/null +++ b/browser/src/feedbackPrivacy.ts @@ -0,0 +1,12 @@ +export interface CapturePolicy { + readable?: boolean; + protectedPage?: (location: Pick) => boolean; + stylesheet?: (url: URL) => boolean; +} +let policy: CapturePolicy = {}; +export function configureCapturePolicy(value: CapturePolicy) { policy = { ...value }; } +export function readableCapture() { return policy.readable === true; } +export function approvedStylesheet(url: URL) { return !url.search && !url.hash && (policy.stylesheet?.(url) ?? false); } +export function isPrivateFeedbackPage(location: Pick) { return policy.protectedPage?.(location) ?? /(?:login|password|token|payment|checkout|bank)/i.test(location.pathname + location.search); } +export function canRecordFeedbackPage(location: Pick) { return !isPrivateFeedbackPage(location) && !location.search && !location.hash; } +export function feedbackPageUrl(location: Pick) { return `${location.origin}${isPrivateFeedbackPage(location) ? '/[private-page]' : location.pathname}`; } diff --git a/browser/src/feedbackReplay.ts b/browser/src/feedbackReplay.ts new file mode 100644 index 0000000..c1f3f1a --- /dev/null +++ b/browser/src/feedbackReplay.ts @@ -0,0 +1,47 @@ +import { addIntegration, getClient, replayIntegration } from '@sentry/browser'; +import { feedbackSecretSelector, feedbackBlockedMediaSelector, feedbackReplayMaskedAttributes, maskFeedbackReplayText, maskReplayAttributesInTree, observeReplayAttributePrivacy } from './feedbackCapturePrivacy'; +import { canRecordFeedbackPage, readableCapture } from './feedbackPrivacy'; +let replay: ReturnType | undefined; +let suspended = false, enabled = false, revision = 0; +let stopping = Promise.resolve(); +let freezing: Promise | undefined; +export function stopFeedbackReplay() { + revision++; + const previous = stopping; + const stopped = replay?.stop({ flush: false }).catch(() => {}) ?? Promise.resolve(); + stopping = Promise.all([previous, stopped]).then(() => {}); +} +export async function resumeFeedbackReplay() { + const expected = revision; + await stopping; await Promise.resolve(); + if (expected === revision && enabled && !suspended && canRecordFeedbackPage(window.location)) { + maskReplayAttributesInTree(document.documentElement); replay?.startBuffering(); + } +} +export function initializeFeedbackReplay() { + enabled = true; + if (replay || !getClient()) return; + observeReplayAttributePrivacy(); + replay = replayIntegration({ stickySession: false, minReplayDuration: 0, + maskAllText: !readableCapture(), maskAllInputs: !readableCapture(), blockAllMedia: !readableCapture(), + mask: [feedbackSecretSelector], maskFn: maskFeedbackReplayText, maskAttributes: feedbackReplayMaskedAttributes, + block: ['script', 'iframe', 'canvas', 'video, audio, object, embed', feedbackSecretSelector, feedbackBlockedMediaSelector, '[style*="url("]', '[data-feedback-ui]'], + networkCaptureBodies: false, networkDetailAllowUrls: [], beforeAddRecordingEvent: () => null }); + addIntegration(replay); + window.addEventListener('popstate', stopFeedbackReplay, { capture: true }); + window.addEventListener('hashchange', () => { stopFeedbackReplay(); void resumeFeedbackReplay(); }); + void resumeFeedbackReplay(); +} +export function freezeFeedbackReplay(): Promise { + if (freezing) return freezing; + suspended = true; + const active = replay; const id = active?.getReplayId(); const expected = revision; + if (!enabled || !active || !id || !canRecordFeedbackPage(window.location)) return Promise.resolve(undefined); + const frozen = (async () => { try { await active.flush({ continueRecording: false }); return expected === revision && enabled ? id : undefined; } catch { return undefined; } finally { await active.stop({ flush: false }); } })(); + freezing = frozen; + stopping = frozen.then(() => {}); + void frozen.finally(() => { if (freezing === frozen) freezing = undefined; }); + return frozen; +} +export function restartFeedbackReplay() { suspended = false; stopFeedbackReplay(); void resumeFeedbackReplay(); } +export function setFeedbackReplayEnabled(value: boolean) { enabled = value; if (value) { suspended = false; if (replay) void resumeFeedbackReplay(); else initializeFeedbackReplay(); } else { suspended = true; stopFeedbackReplay(); } } diff --git a/browser/src/feedbackScreenshot.ts b/browser/src/feedbackScreenshot.ts new file mode 100644 index 0000000..f5bc243 --- /dev/null +++ b/browser/src/feedbackScreenshot.ts @@ -0,0 +1,165 @@ +import { + feedbackBlockedMediaSelector, + feedbackSecretSelector, + maskFeedbackText, +} from "./feedbackCapturePrivacy"; +import { isPrivateFeedbackPage, approvedStylesheet, readableCapture } from "./feedbackPrivacy"; + +export interface FeedbackScreenshot { + data: Uint8Array; + previewUrl: string; +} + +export function compiledScreenshotStyles(doc: Document): string[] { + // Capture already-loaded app CSS. A renderer iframe can otherwise parse the + // sanitized page before its external stylesheets finish loading. + return Array.from(doc.styleSheets).flatMap((sheet) => { + if (!sheet.href) { + return []; + } + const url = new URL(sheet.href, doc.baseURI); + if ( + url.origin !== new URL(doc.baseURI).origin || + !approvedStylesheet(url) || + url.search || + url.hash + ) { + return []; + } + try { + return [Array.from(sheet.cssRules, (rule) => rule.cssText).join("\n")]; + } catch { + return []; + } + }); +} + +export function sanitizeScreenshotDocument( + doc: Document, + privatePage: boolean, +) { + doc + .querySelectorAll( + `script, iframe, canvas, video, audio, object, embed, ${feedbackSecretSelector}, ${feedbackBlockedMediaSelector}, [data-feedback-ui]`, + ) + .forEach((element) => { + (element as HTMLElement).style.visibility = "hidden"; + }); + if (privatePage) { + doc.body.style.visibility = "hidden"; + return; + } + const secretElements = new Set( + Array.from(doc.querySelectorAll(feedbackSecretSelector)).flatMap( + (element) => [element, ...element.querySelectorAll("*")], + ), + ); + doc + .querySelectorAll(feedbackBlockedMediaSelector) + .forEach((element) => element.removeAttribute("src")); + const walker = doc.createTreeWalker(doc.body, NodeFilter.SHOW_TEXT); + while (walker.nextNode()) { + walker.currentNode.textContent = maskFeedbackText( + walker.currentNode.textContent ?? "", + walker.currentNode.parentElement, + ); + } + doc.querySelectorAll("body, body *").forEach((element) => { + const secret = !readableCapture() || secretElements.has(element); + const input = element as HTMLInputElement; + const value = input.value; + const checked = input.checked; + const selectedIndex = (element as HTMLSelectElement).selectedIndex; + element.style.setProperty("background-image", "none", "important"); + for (const attribute of [...element.attributes]) { + // Vue's empty scope markers contain no user data and keep scoped CSS + // matching after the clone's private attributes have been removed. + if (/^data-v-[0-9a-f]{8}$/.test(attribute.name) && !attribute.value) { + continue; + } + if ( + /^(?:data-|href$|srcset$|action$|formaction$|value$)/i.test( + attribute.name, + ) + ) { + element.removeAttribute(attribute.name); + } else if ( + /^(?:title|alt|aria-label|aria-description|placeholder)$/.test( + attribute.name, + ) + ) { + element.setAttribute( + attribute.name, + secret ? attribute.value.replace(/\S/g, "*") : attribute.value, + ); + } + } + // html2canvas adopts source-window elements into its iframe. instanceof + // against the clone window misses those controls; tag names cross realms. + if (element.tagName === "INPUT" || element.tagName === "TEXTAREA") { + (element as HTMLInputElement | HTMLTextAreaElement).value = secret + ? "" + : value; + } + if (element.tagName === "INPUT") { + (element as HTMLInputElement).checked = secret ? false : checked; + } + if (element.tagName === "SELECT") { + (element as HTMLSelectElement).selectedIndex = secret + ? -1 + : selectedIndex; + } + }); + // Generated content can expose data attributes, names or initials. + const style = doc.createElement("style"); + style.textContent = + "*::before, *::after { content: none !important; background-image: none !important; }"; + doc.head.append(style); +} + +export async function captureFeedbackScreenshot(): Promise< + FeedbackScreenshot | undefined +> { + // A blank private-page screenshot is not useful; retain the text-only report. + if (isPrivateFeedbackPage(window.location)) { + return undefined; + } + const { default: html2canvas } = await import("html2canvas-pro"); + const width = window.innerWidth; + const height = window.innerHeight; + const styles = compiledScreenshotStyles(document); + const canvas = await html2canvas(document.body, { + width, + height, + x: window.scrollX, + y: window.scrollY, + scale: Math.min(1, Math.sqrt(1_500_000 / (width * height))), + backgroundColor: "#f4f8fb", + logging: false, + allowTaint: false, + useCORS: false, + imageTimeout: 3000, + ignoreElements: (element) => element.hasAttribute("data-feedback-ui"), + onclone: async (doc) => { + for (const css of styles) { + const style = doc.createElement("style"); + style.textContent = css; + doc.head.append(style); + } + sanitizeScreenshotDocument(doc, false); + // Force style resolution before waiting for the clone's font faces. + doc.body.getBoundingClientRect(); + await doc.fonts?.ready; + }, + }); + const blob = await new Promise((resolve) => + canvas.toBlob(resolve, "image/png"), + ); + if (!blob || blob.size > 2_000_000) { + return undefined; + } + return { + data: new Uint8Array(await blob.arrayBuffer()), + previewUrl: URL.createObjectURL(blob), + }; +} diff --git a/browser/src/index.ts b/browser/src/index.ts new file mode 100644 index 0000000..1042a35 --- /dev/null +++ b/browser/src/index.ts @@ -0,0 +1,30 @@ +import { installClientPrivacy } from './clientPrivacy'; +import { sanitizeSpan, installSpanPrivacy, stablePageName } from './spanPrivacy'; +export { sanitizeSpan, stablePageName } from './spanPrivacy'; +import { init, getClient, browserTracingIntegration, startBrowserTracingNavigationSpan, type BrowserClient, type BrowserOptions, type Event } from '@sentry/browser'; +export { createFeedbackController } from './controller'; +export { configureCapturePolicy } from './feedbackPrivacy'; +export { mountFeedbackWidget } from './widget'; +export async function percentageEligible(key: string, opaqueId: string, percentage: number) { + if (!opaqueId || percentage <= 0) return false; if (percentage >= 100) return true; + const digest = new Uint8Array(await crypto.subtle.digest('SHA-256', new TextEncoder().encode(`${key}:${opaqueId.toLowerCase()}`))); + const bucket = new DataView(digest.buffer).getUint32(0) % 100 + 1; + return bucket <= percentage; +} +export function sanitizeTransaction(event: Event) { + event.transaction = stablePageName(event.transaction ?? 'document'); + delete event.request; delete event.extra; delete event.breadcrumbs; + if (event.user) event.user = event.user.id ? { id: event.user.id } : undefined; + for (const span of event.spans ?? []) sanitizeSpan(span); + return event; +} +export function initializeBrowser(config: BrowserOptions & { enabled?: boolean; localVerification?: boolean; inertia?: boolean }, client?: BrowserClient) { + if (client) { installClientPrivacy(client); installSpanPrivacy(client); return client; } + const existing = getClient(); if (existing) { installClientPrivacy(existing); installSpanPrivacy(existing); return existing; } + const local = /^(?:localhost|127\.|0\.0\.0\.0|\[?::1\]?$)|\.(?:localhost|test)$/.test(window.location.hostname); + if (!config.enabled || (local && !config.localVerification)) return undefined; + init({ ...config, sendDefaultPii: false, replaysSessionSampleRate: 0, replaysOnErrorSampleRate: 0, + integrations: [browserTracingIntegration({ instrumentNavigation: !config.inertia, beforeStartSpan: options => ({ ...options, name: stablePageName(options.name) }) })], beforeSendSpan: sanitizeSpan, beforeSendTransaction: sanitizeTransaction }); + const initialized = getClient(); if (initialized) installClientPrivacy(initialized); return initialized; +} +export function startInertiaNavigation(component: string) { const client = getClient(); if (client) return startBrowserTracingNavigationSpan(client, { name: stablePageName(component), op: 'navigation', attributes: { 'sentry.source': 'component' } }); } diff --git a/browser/src/script.ts b/browser/src/script.ts new file mode 100644 index 0000000..c3a52af --- /dev/null +++ b/browser/src/script.ts @@ -0,0 +1,5 @@ +// Script-tag entry keeps replay/screenshot dependencies in lazy ES-module chunks. +const base = new URL('./esm/index.js', (document.currentScript as HTMLScriptElement).src).href; +let loading: Promise | undefined; +const ready = () => loading ??= import(/* @vite-ignore */ base); +Object.assign(window, { SentryBox: { ready, initializeBrowser: async (...args: Parameters) => (await ready()).initializeBrowser(...args), mountFeedbackWidget: async (...args: Parameters) => (await ready()).mountFeedbackWidget(...args) } }); diff --git a/browser/src/spanPrivacy.ts b/browser/src/spanPrivacy.ts new file mode 100644 index 0000000..b7c7b53 --- /dev/null +++ b/browser/src/spanPrivacy.ts @@ -0,0 +1,35 @@ +import type { BrowserClient, SpanJSON } from '@sentry/browser'; +export function stablePageName(name: string) { return name.split(/[?#]/)[0].replace(/\/(?:login|password|tokens?|invites?|kiosk|reset)(?:\/[^\s]*)?/gi, '/[private-page]').replace(/\/[A-Za-z0-9_-]{24,}(?=\/|$)/g, '/:id').replace(/\b[0-9a-f]{8}-[0-9a-f-]{27,}\b/gi, ':id').replace(/\/\d+(?=\/|$)/g, '/:id').slice(0, 256); } +const configured = new WeakSet(); +const technicalAttributes = /^(?:http\.request\.method|http\.response\.status_code|server\.address|sentry\.(?:origin|source|sample_rate|op|exclusive_time)|type|op)$/; +function origin(value: string) { try { return new URL(value).origin; } catch { return '[resource]'; } } +export function sanitizeSpan(span: SpanJSON): SpanJSON { + if (span.op?.startsWith('ui.')) span.description = 'interaction'; + else if (span.description) { + if (['pageload', 'navigation'].includes(span.op ?? '')) span.description = stablePageName(span.description); + else if (/https?:\/\//i.test(span.description)) span.description = span.description.replace(/https?:\/\/\S+/gi, origin); + else if (!['pageload', 'navigation'].includes(span.op ?? '')) span.description = span.op ?? 'operation'; + span.description = span.description.split(/[?#]/)[0].replace(/\b[^\s/]+@[^\s/]+\b/g, '[private]').slice(0, 256); + } + const data: Record = {}; + for (const [key, value] of Object.entries(span.data ?? {})) { + if (/^browser\.web_vital\.(?:lcp|cls|inp|fcp|ttfb)\.(?:value|load_time|render_time|size)$/.test(key) && typeof value === 'number' && Number.isFinite(value)) { data[key] = value; continue; } + if (key === 'sentry.pageload.span_id' && typeof value === 'string' && /^[a-f0-9]{16}$/i.test(value)) { data[key] = value; continue; } + if (['sentry.segment.name', 'sentry.transaction'].includes(key) && typeof value === 'string') { data[key] = stablePageName(value); continue; } + if (key === 'user_agent.original' && typeof value === 'string' && typeof navigator !== 'undefined' && value === navigator.userAgent) { data[key] = value.slice(0, 512); continue; } + if (!technicalAttributes.test(key) || !['string', 'number', 'boolean'].includes(typeof value)) continue; + if (typeof value === 'string') { + if (key === 'server.address') data[key] = /^[a-z0-9.:-]+$/i.test(value) ? value : '[destination]'; + else if (/^[a-z0-9_. /:-]{1,128}$/i.test(value)) data[key] = value; + } else data[key] = value as number | boolean; + } + span.data = data; + return span; +} +export function installSpanPrivacy(client: BrowserClient) { + if (configured.has(client)) return; + configured.add(client); + const options = client.getOptions(); + const previous = options.beforeSendSpan; + options.beforeSendSpan = span => sanitizeSpan(previous ? previous(span) : span); +} diff --git a/browser/src/widget.ts b/browser/src/widget.ts new file mode 100644 index 0000000..ca21a0e --- /dev/null +++ b/browser/src/widget.ts @@ -0,0 +1,50 @@ +import { createFeedbackController } from './controller'; +import { cornerPoint, constrain, keyCorner, nearestCorner, readCorner, saveCorner, type Bounds, type Point } from './feedbackPosition'; +import { configureCapturePolicy, type CapturePolicy } from './feedbackPrivacy'; +const defaults = { title: 'Feedback', open: 'Send feedback', close: 'Close', message: 'What happened?', submit: 'Send', done: 'Done', remove: 'Remove screenshot', success: 'Thank you. Your feedback was accepted.', sendFailed: 'Feedback could not be sent. Please try again.', messageRequired: 'Enter a message.', unavailable: 'Feedback is unavailable.', disclosure: 'Opening feedback uploads the recent replay buffer. Your message and screenshot are sent only when you submit.', pending: 'Preparing capture…', ready: 'Review your screenshot', removed: 'Screenshot removed', private: 'Text feedback only on this page', captureUnavailable: 'Capture unavailable; you can still send text feedback.', moved: 'Feedback button moved' }; +export function mountFeedbackWidget(options: { eligible?: () => boolean; labels?: Partial; policy?: CapturePolicy; component?: () => string; className?: string } = {}) { + let enabled = options.eligible?.() ?? true; + configureCapturePolicy(options.policy ?? {}); + const labels = { ...defaults, ...options.labels }; const abort = new AbortController(); + const root = document.createElement('div'); root.dataset.feedbackUi = ''; root.dataset.sentryBlock = ''; root.className = options.className ?? ''; + root.innerHTML = `

`; + root.hidden = !enabled; + document.body.append(root); + const select = (selector: string) => root.querySelector(selector)!; + const trigger = select('.sentry-feedback-trigger'), dialog = select('dialog'), message = select('textarea'), image = select('img'); + const title = select('h2'); title.id = `sentry-feedback-${crypto.randomUUID()}`; title.textContent = labels.title; dialog.setAttribute('aria-labelledby', title.id); + trigger.setAttribute('aria-label', labels.open); trigger.title = labels.open; + select('.disclosure').textContent = labels.disclosure; select('label span').textContent = labels.message; + select('.submit').textContent = labels.submit; select('.remove').textContent = labels.remove; select('.close').textContent = labels.close; select('.success').textContent = labels.success; + const controller = createFeedbackController({ eligible: () => enabled && (options.eligible?.() ?? true), component: options.component, + changed(state) { message.value = state.message; message.disabled = state.busy; select('.submit').disabled = state.busy || state.capturing; select('.close').disabled = state.busy; + select('.error').textContent = state.error ? labels[state.error] : ''; select('.capture').textContent = state.captureState === 'unavailable' ? labels.captureUnavailable : labels[state.captureState]; + image.hidden = !state.screenshot; if (state.screenshot) image.src = state.screenshot.previewUrl; else image.removeAttribute('src'); select('.remove').hidden = !state.screenshot; + select('form').hidden = state.success; select('.success').hidden = !state.success; + if (state.success) { select('.close').textContent = labels.done; select('.close').focus(); } + } }); + const listen = (target: EventTarget, name: string, fn: EventListener) => target.addEventListener(name, fn, { signal: abort.signal }); + listen(trigger, 'click', () => { if (suppressClick) { suppressClick = false; return; } if (dialog.open) return; void controller.open(); dialog.showModal(); message.focus(); }); + const close = () => { if (controller.state.busy) return; controller.close(); dialog.close(); trigger.focus(); }; + listen(select('.close'), 'click', close); listen(dialog, 'cancel', event => { event.preventDefault(); close(); }); + listen(select('form'), 'submit', event => { event.preventDefault(); void controller.submit(); }); listen(message, 'input', () => controller.setMessage(message.value)); listen(select('.remove'), 'click', controller.removeScreenshot); + const cancelNavigation = () => { controller.cancel(); dialog.close(); }; + listen(window, 'popstate', cancelNavigation); listen(window, 'hashchange', cancelNavigation); + let corner = readCorner(), position: Point | undefined, frame = 0, suppressClick = false; + let pointer: { id: number; start: Point; origin: Point; moved: boolean } | undefined; + const media = window.matchMedia('(prefers-reduced-motion: reduce)'); + function bounds(): Bounds { const css = getComputedStyle(select('.sentry-feedback-probe')); const number = (s: string) => parseFloat(s) || 0; const v = window.visualViewport; const left = (v?.offsetLeft ?? 0) + 16 + number(css.paddingLeft), top = (v?.offsetTop ?? 0) + 16 + number(css.paddingTop); return { left, top, right: Math.max(left, (v?.offsetLeft ?? 0) + (v?.width ?? innerWidth) - 64 - number(css.paddingRight)), bottom: Math.max(top, (v?.offsetTop ?? 0) + (v?.height ?? innerHeight) - 64 - number(css.paddingBottom)) }; } + function place(value: Point) { position = value; trigger.style.transform = `translate3d(${value.x}px,${value.y}px,0)`; } + function settle(animate = true) { cancelAnimationFrame(frame); const target = cornerPoint(corner, bounds()), start = position ?? target; if (!animate || media.matches) { place(target); return; } const began = performance.now(); const tick = (now: number) => { const elapsed = (now - began) / 700, progress = 1 - Math.exp(-6 * elapsed) * Math.cos(7.5 * elapsed); place(constrain({ x: start.x + (target.x - start.x) * progress, y: start.y + (target.y - start.y) * progress }, bounds())); if (elapsed < 1) frame = requestAnimationFrame(tick); else place(target); }; frame = requestAnimationFrame(tick); } + function choose(next: typeof corner) { corner = next; saveCorner(corner); select('[role="status"]').textContent = labels.moved; settle(); } + listen(trigger, 'pointerdown', raw => { const event = raw as PointerEvent; if (!event.isPrimary || event.button !== 0 || pointer) return; cancelAnimationFrame(frame); pointer = { id: event.pointerId, start: { x: event.clientX, y: event.clientY }, origin: position ?? cornerPoint(corner, bounds()), moved: false }; suppressClick = false; trigger.setPointerCapture(event.pointerId); }); + listen(trigger, 'pointermove', raw => { const event = raw as PointerEvent; if (!pointer || pointer.id !== event.pointerId) return; const dx = event.clientX - pointer.start.x, dy = event.clientY - pointer.start.y; if (!pointer.moved && Math.hypot(dx, dy) < 8) return; pointer.moved = true; place(constrain({ x: pointer.origin.x + dx, y: pointer.origin.y + dy }, bounds())); }); + const end = (raw: Event) => { const event = raw as PointerEvent; if (!pointer || pointer.id !== event.pointerId) return; suppressClick = pointer.moved || event.type === 'pointercancel'; pointer = undefined; if (trigger.hasPointerCapture(event.pointerId)) trigger.releasePointerCapture(event.pointerId); if (suppressClick) choose(nearestCorner(position!, bounds())); else settle(); }; + listen(trigger, 'pointerup', end); listen(trigger, 'pointercancel', end); listen(trigger, 'lostpointercapture', end); + listen(trigger, 'keydown', raw => { const event = raw as KeyboardEvent; const next = keyCorner(corner, event.key); if (next) { event.preventDefault(); choose(next); } }); + listen(window, 'resize', () => settle(false)); if (window.visualViewport) { listen(window.visualViewport, 'resize', () => settle(false)); listen(window.visualViewport, 'scroll', () => settle(false)); } listen(media, 'change', () => settle(false)); settle(false); + if (enabled) void import('./feedbackReplay').then(m => { if (enabled) m.setFeedbackReplayEnabled(true); }); + return { controller, setEnabled(value: boolean) { enabled = value; if (!value) { cancelNavigation(); root.hidden = true; } else root.hidden = false; void import('./feedbackReplay').then(m => m.setFeedbackReplayEnabled(value)); }, dispose() { enabled = false; abort.abort(); cancelAnimationFrame(frame); controller.cancel(); root.remove(); void import('./feedbackReplay').then(m => m.setFeedbackReplayEnabled(false)); } }; +} diff --git a/browser/tests/conservativePrivacy.test.ts b/browser/tests/conservativePrivacy.test.ts new file mode 100644 index 0000000..528c2e6 --- /dev/null +++ b/browser/tests/conservativePrivacy.test.ts @@ -0,0 +1,5 @@ +import { expect, it } from 'vitest'; +import { configureCapturePolicy } from '../src/feedbackPrivacy'; +import { maskFeedbackText } from '../src/feedbackCapturePrivacy'; +import { sanitizeScreenshotDocument } from '../src/feedbackScreenshot'; +it('defaults to masking ordinary text and form values', () => { configureCapturePolicy({}); document.body.innerHTML = '

Personal name

'; expect(maskFeedbackText('Personal name', document.querySelector('p'))).toBe('******** ****'); sanitizeScreenshotDocument(document, false); expect(document.body.textContent).not.toContain('Personal'); expect(document.querySelector('input')!.value).toBe(''); }); diff --git a/browser/tests/controller.test.ts b/browser/tests/controller.test.ts new file mode 100644 index 0000000..33b9cb3 --- /dev/null +++ b/browser/tests/controller.test.ts @@ -0,0 +1,14 @@ +import { afterEach, beforeEach, expect, it, vi } from 'vitest'; +import { configureCapturePolicy } from '../src/feedbackPrivacy'; +import { createFeedbackController, captureWithDeadline } from '../src/controller'; +const mock = vi.hoisted(() => ({ send: vi.fn(), capture: vi.fn(), freeze: vi.fn(), restart: vi.fn() })); +vi.mock('../src/feedback', () => ({ feedbackAvailable: () => true, sendFeedback: mock.send })); +vi.mock('../src/feedbackScreenshot', () => ({ captureFeedbackScreenshot: mock.capture })); +vi.mock('../src/feedbackReplay', () => ({ freezeFeedbackReplay: mock.freeze, restartFeedbackReplay: mock.restart })); +beforeEach(() => { vi.clearAllMocks(); configureCapturePolicy({ readable: false }); history.replaceState({}, '', '/'); mock.capture.mockResolvedValue(undefined); mock.freeze.mockResolvedValue('a'.repeat(32)); URL.revokeObjectURL = vi.fn(); }); +afterEach(() => vi.useRealTimers()); +it('retains failed feedback for retry and only confirms accepted delivery', async () => { const controller = createFeedbackController(); await controller.open(); controller.setMessage('Keep this'); mock.send.mockRejectedValueOnce(Error('rejected')); await controller.submit(); expect(controller.state.message).toBe('Keep this'); expect(controller.state.success).toBe(false); mock.send.mockResolvedValue(undefined); await controller.submit(); expect(controller.state.success).toBe(true); expect(controller.state.message).toBe(''); }); +it('discards stale screenshot results and revokes their object URLs after navigation', async () => { let resolve!: (value: unknown) => void; mock.capture.mockReturnValue(new Promise(r => resolve = r)); const controller = createFeedbackController(); const opening = controller.open(); await vi.waitFor(() => expect(mock.capture).toHaveBeenCalled()); controller.cancel(); resolve({ previewUrl: 'blob:stale', data: new Uint8Array() }); await opening; expect(controller.state.screenshot).toBeUndefined(); expect(URL.revokeObjectURL).toHaveBeenCalledWith('blob:stale'); }); +it('allows text feedback after screenshot capture fails', async () => { mock.capture.mockRejectedValue(Error('renderer failed')); const controller = createFeedbackController(); await controller.open(); expect(controller.state.captureState).toBe('unavailable'); controller.setMessage('Text works'); mock.send.mockResolvedValue(undefined); await controller.submit(); expect(controller.state.success).toBe(true); }); +it('keeps the eight second deadline and discards a late result', async () => { vi.useFakeTimers(); let resolve!: (value: string) => void; const discard = vi.fn(); const result = captureWithDeadline(new Promise(r => resolve = r), discard); await vi.advanceTimersByTimeAsync(8000); expect(await result).toBeUndefined(); resolve('late'); await Promise.resolve(); expect(discard).toHaveBeenCalledWith('late'); }); +it('does not load captures when ineligible', async () => { const controller = createFeedbackController({ eligible: () => false }); await controller.open(); expect(mock.capture).not.toHaveBeenCalled(); }); diff --git a/browser/tests/feedback.test.ts b/browser/tests/feedback.test.ts new file mode 100644 index 0000000..9519c8f --- /dev/null +++ b/browser/tests/feedback.test.ts @@ -0,0 +1,103 @@ +import { configureCapturePolicy } from "../src/feedbackPrivacy"; +configureCapturePolicy({ readable: true, stylesheet: url => url.pathname.startsWith("/includes/build/") }); +// @vitest-environment jsdom +import { afterEach, expect, it, vi } from "vitest"; +import { init, getClient } from "@sentry/browser"; +import { feedbackAvailable, sendFeedback } from "../src/feedback"; +type Envelope = Parameters< + NonNullable>["sendEnvelope"] +>[0]; + +afterEach(async () => { + vi.useRealTimers(); + await getClient()?.close(100); +}); + +function transport(statusCode: number) { + const envelopes: Envelope[] = []; + init({ + dsn: "https://public@example.com/1", + defaultIntegrations: false, + transport: () => ({ + send: async (envelope) => { + envelopes.push(envelope); + return { statusCode }; + }, + flush: async () => true, + }), + }); + return envelopes; +} + +it("uses the real SDK to send a feedback event with a PNG attachment", async () => { + const envelopes = transport(200); + expect(feedbackAvailable()).toBe(true); + await sendFeedback({ + message: " The save button did not respond ", + pageUrl: "https://example.com/productions/1", + component: "Productions/Show", + screenshot: { data: new Uint8Array([1, 2, 3]), previewUrl: "blob:preview" }, + }); + const items = envelopes[0][1]; + expect(items[0][0].type).toBe("feedback"); + expect(items[0][1]).toMatchObject({ + contexts: { + feedback: { + message: "The save button did not respond", + url: "https://example.com/productions/1", + source: "api", + }, + }, + tags: { page_component: "Productions/Show" }, + }); + expect(items[1][0]).toMatchObject({ + type: "attachment", + filename: "feedback-screenshot.png", + content_type: "image/png", + }); + expect(items[1][1]).toEqual(new Uint8Array([1, 2, 3])); +}); + +it("rejects provider rejection instead of reporting queue-drained success", async () => { + transport(429); + await expect( + sendFeedback({ + message: "Save failed", + pageUrl: "https://example.com/", + component: "Main/Index", + }), + ).rejects.toThrow("not accepted"); +}); + +it("rejects a timed-out submission even when the transport queue is stalled", async () => { + vi.useFakeTimers(); + init({ + dsn: "https://public@example.com/1", + defaultIntegrations: false, + transport: () => ({ + send: () => new Promise(() => {}), + flush: async () => true, + }), + }); + const report = expect( + sendFeedback({ + message: "Save failed", + pageUrl: "https://example.com/", + component: "Main/Index", + }), + ).rejects.toThrow("timed out"); + await vi.advanceTimersByTimeAsync(15_000); + await report; +}); + +it("rejects blank feedback before creating an envelope", async () => { + const envelopes = transport(200); + await expect( + sendFeedback({ + message: " ", + pageUrl: "https://example.com/", + component: "Main/Index", + }), + ).rejects.toThrow(); + expect(envelopes).toHaveLength(0); +}); diff --git a/browser/tests/feedbackAttributes.test.ts b/browser/tests/feedbackAttributes.test.ts new file mode 100644 index 0000000..cd11e8d --- /dev/null +++ b/browser/tests/feedbackAttributes.test.ts @@ -0,0 +1,47 @@ +import { configureCapturePolicy } from "../src/feedbackPrivacy"; +configureCapturePolicy({ readable: true, stylesheet: url => url.pathname.startsWith("/includes/build/") }); +// @vitest-environment jsdom +import { expect, it } from "vitest"; +import { + feedbackReplayMaskedAttributes, + observeReplayAttributePrivacy, + maskFeedbackReplayText, +} from "../src/feedbackCapturePrivacy"; + +it("masks arbitrary inherited and dynamically added attributes before the recorder observer", async () => { + document.body.innerHTML = '
'; + const privacy = observeReplayAttributePrivacy(); + expect(feedbackReplayMaskedAttributes).toContain("csrftoken"); + expect(feedbackReplayMaskedAttributes).not.toContain("class"); + let recorded = false; + const recorder = new MutationObserver(() => { + expect(feedbackReplayMaskedAttributes).toContain("new-private-value"); + expect(feedbackReplayMaskedAttributes).toContain("nested-private-value"); + recorded = true; + }); + recorder.observe(document.body, { + attributes: true, + subtree: true, + childList: true, + }); + document.querySelector("main")!.setAttribute("new-private-value", "PRIVATE"); + const child = document.createElement("span"); + child.setAttribute("nested-private-value", "PRIVATE"); + document.body.append(child); + await new Promise((resolve) => queueMicrotask(resolve)); + expect(recorded).toBe(true); + privacy.disconnect(); + recorder.disconnect(); + document.body.innerHTML = ""; +}); + +it("retains ordinary input text and excludes credential fields", () => { + const input = document.createElement("input"); + expect(maskFeedbackReplayText("Email", input)).toBe("Email"); + input.name = "password"; + input.type = "text"; + expect(maskFeedbackReplayText("secret", input)).toBe("******"); + expect(maskFeedbackReplayText("Email", document.createElement("label"))).toBe( + "Email", + ); +}); diff --git a/browser/tests/feedbackCaptureIntegration.test.ts b/browser/tests/feedbackCaptureIntegration.test.ts new file mode 100644 index 0000000..a29123c --- /dev/null +++ b/browser/tests/feedbackCaptureIntegration.test.ts @@ -0,0 +1,87 @@ +import { configureCapturePolicy } from "../src/feedbackPrivacy"; +configureCapturePolicy({ readable: true, stylesheet: url => url.pathname.startsWith("/includes/build/") }); +// @vitest-environment jsdom +import { afterEach, expect, it, vi } from "vitest"; +import { getClient, init, type Envelope } from "@sentry/browser"; +import { inflateSync, gunzipSync } from "node:zlib"; +import { + initializeFeedbackReplay, + resumeFeedbackReplay, + freezeFeedbackReplay, + setFeedbackReplayEnabled, +} from "../src/feedbackReplay"; + +vi.mock("@inertiajs/vue3", () => ({ router: { on: vi.fn() } })); +afterEach(async () => { + setFeedbackReplayEnabled(false); + await getClient()?.close(); + vi.unstubAllGlobals(); + document.body.innerHTML = ""; +}); + +it("records readable evaluations and input changes with the real SDK, excluding credential and payment fields", async () => { + history.replaceState({}, "", "/productions/123"); + // Run the SDK's browser/Electron-renderer path inside jsdom's Node host. + vi.stubGlobal( + "process", + new Proxy(process, { + get: (target, key) => + key === "type" ? "renderer" : Reflect.get(target, key), + }), + ); + const envelopes: Envelope[] = []; + init({ + dsn: "https://public@example.test/1", + defaultIntegrations: false, + replaysSessionSampleRate: 0, + replaysOnErrorSampleRate: 0, + transport: () => ({ + send: async (envelope) => { + envelopes.push(envelope); + return { statusCode: 200 }; + }, + flush: async () => true, + }), + }); + document.body.innerHTML = `

Jane Smith

Excellent audition

SECRET_CONTAINER
`; + initializeFeedbackReplay(); + await resumeFeedbackReplay(); + const evaluation = document.querySelector("textarea")!; + evaluation.value = "Improved diction"; + evaluation.dispatchEvent(new Event("input", { bubbles: true })); + const password = document.querySelector( + 'input[name="password"]', + )!; + password.value = "SECRET_CHANGED"; + password.dispatchEvent(new Event("input", { bubbles: true })); + const inserted = document.createElement("input"); + inserted.name = "api_key"; + inserted.value = "SECRET_INSERTED"; + document.body.append(inserted); + inserted.dispatchEvent(new Event("input", { bubbles: true })); + await new Promise((resolve) => setTimeout(resolve, 100)); + expect(await freezeFeedbackReplay()).toBeTruthy(); + const recordings = envelopes + .flatMap(([, items]) => + items + .filter(([header]) => header.type === "replay_recording") + .map(([, payload]) => { + if (!(payload instanceof Uint8Array)) { + return String(payload); + } + let bytes = payload; + if (bytes[0] === 0x1f && bytes[1] === 0x8b) { + bytes = gunzipSync(bytes); + } else if (bytes[0] === 0x78) { + bytes = inflateSync(bytes); + } + return new TextDecoder().decode(bytes); + }), + ) + .join("\n"); + expect(recordings).toContain("Jane Smith"); + expect(recordings).toContain("Strong performance"); + expect(recordings).toContain("Improved diction"); + expect(recordings).toContain("jane@example.test"); + expect(recordings).not.toContain("SECRET_"); +}, 10_000); diff --git a/browser/tests/feedbackScreenshot.test.ts b/browser/tests/feedbackScreenshot.test.ts new file mode 100644 index 0000000..15919de --- /dev/null +++ b/browser/tests/feedbackScreenshot.test.ts @@ -0,0 +1,103 @@ +import { configureCapturePolicy } from "../src/feedbackPrivacy"; +configureCapturePolicy({ readable: true, stylesheet: url => url.pathname.startsWith("/includes/build/") }); +// @vitest-environment jsdom +import { afterEach, expect, it } from "vitest"; +import { + compiledScreenshotStyles, + sanitizeScreenshotDocument, +} from "../src/feedbackScreenshot"; +afterEach(() => { + document.body.innerHTML = ""; +}); +it("keeps evaluation text, ordinary values, selections, and safe images while removing secrets", () => { + document.body.innerHTML = `

Jane Smith

Excellent audition

SECRET_LINK
Roster
SECRET_FEEDBACK
`; + sanitizeScreenshotDocument(document, false); + expect(document.querySelector("h1")?.textContent).toBe("Jane Smith"); + expect(document.querySelector('input[name="email"]')?.value).toBe( + "jane@example.test", + ); + expect(document.querySelector('textarea[name="evaluation"]')?.value).toBe( + "Strong performance", + ); + expect(document.querySelector("select")?.selectedIndex).toBe(0); + expect(document.querySelector('input[type="checkbox"]')?.checked).toBe(true); + expect(document.querySelector('input[name="password"]')?.value).toBe(""); + expect( + document.querySelector('input[autocomplete="one-time-code"]')?.value, + ).toBe(""); + expect(document.querySelector('input[name="card_number"]')?.value).toBe(""); + expect(document.querySelectorAll("textarea")[1]?.value).toBe(""); + expect(document.querySelector("a")?.hasAttribute("href")).toBe(false); + expect(document.querySelector("img")?.getAttribute("src")).toBe("/logo.png"); + expect(document.querySelectorAll("img")[1]?.hasAttribute("src")).toBe(false); + expect(document.body.innerHTML).not.toContain("SECRET"); +}); +it("hides the entire clone for private screens", () => { + document.body.innerHTML = "

Private invitation

"; + sanitizeScreenshotDocument(document, true); + expect(document.body.style.visibility).toBe("hidden"); + document.body.removeAttribute("style"); +}); + +it("keeps empty compiled Vue style markers while removing private data attributes", () => { + document.body.innerHTML = + '

Send feedback

Evaluation

'; + sanitizeScreenshotDocument(document, false); + expect(document.querySelector("main")?.hasAttribute("data-v-1234abcd")).toBe( + true, + ); + expect(document.querySelector("h1")?.hasAttribute("data-v-1234abcd")).toBe( + true, + ); + expect(document.querySelector("p")?.hasAttribute("data-v-deadbeef")).toBe( + false, + ); + expect(document.body.innerHTML).not.toContain("PRIVATE"); +}); + +it("copies loaded compiled CSS without depending on a second stylesheet fetch", () => { + const doc = document.implementation.createHTMLDocument(); + const base = doc.createElement("base"); + base.href = "https://communiarts.com/"; + doc.head.append(base); + const style = doc.createElement("style"); + style.textContent = "main[data-v-1234abcd] { display: grid; color: teal; }"; + document.head.append(style); + const sheet = style.sheet!; + Object.defineProperty(sheet, "href", { + configurable: true, + value: "https://communiarts.com/includes/build/assets/app.css", + }); + Object.defineProperty(doc, "styleSheets", { value: [sheet] }); + expect(compiledScreenshotStyles(doc).join("\n")).toContain("display: grid"); + Object.defineProperty(sheet, "href", { + configurable: true, + value: "https://other.example/private.css", + }); + expect(compiledScreenshotStyles(doc)).toEqual([]); + Object.defineProperty(sheet, "href", { + configurable: true, + value: "https://communiarts.com/private.css?token=PRIVATE", + }); + expect(compiledScreenshotStyles(doc)).toEqual([]); + style.remove(); +}); + +it("clears fields adopted from another window without changing the source field", () => { + const iframe = document.createElement("iframe"); + document.body.append(iframe); + const clone = iframe.contentDocument!; + const input = document.createElement("input"); + input.name = "password"; + input.value = "PRIVATE_TYPED"; + const source = input.cloneNode(true) as HTMLInputElement; + document.body.append(source); + clone.body.append(clone.adoptNode(input)); + const OtherInput = (iframe.contentWindow as Window & typeof globalThis) + .HTMLInputElement; + expect(input instanceof OtherInput).toBe(false); + sanitizeScreenshotDocument(clone, false); + expect(input.value).toBe(""); + expect(source.value).toBe("PRIVATE_TYPED"); + iframe.remove(); +}); diff --git a/browser/tests/replay.test.ts b/browser/tests/replay.test.ts new file mode 100644 index 0000000..059a2ef --- /dev/null +++ b/browser/tests/replay.test.ts @@ -0,0 +1,99 @@ +// @vitest-environment jsdom +import { beforeEach, expect, it, vi } from "vitest"; + +const mock = vi.hoisted(() => ({ + before: undefined as (() => void) | undefined, + navigate: undefined as (() => void) | undefined, + replay: { + startBuffering: vi.fn(), + stop: vi.fn().mockResolvedValue(undefined), + flush: vi.fn().mockResolvedValue(undefined), + getReplayId: vi.fn().mockReturnValue("replay-id"), + }, +})); +vi.mock("@sentry/browser", () => ({ + getClient: () => ({}), + addIntegration: vi.fn(), + replayIntegration: () => mock.replay, +})); +vi.mock("@inertiajs/vue3", () => ({ + router: { + on: (event: "before" | "navigate", callback: () => void) => { + mock[event] = callback; + }, + }, +})); + +beforeEach(async () => { + vi.resetModules(); + vi.clearAllMocks(); + mock.replay.flush.mockResolvedValue(undefined); + mock.replay.getReplayId.mockReturnValue("replay-id"); + const { configureCapturePolicy } = await import("../src/feedbackPrivacy"); configureCapturePolicy({ protectedPage: location => /invite/.test(location.pathname) }); + history.replaceState({}, "", "/productions/1"); +}); + +it("starts a manual buffer and discards it before private navigation", async () => { + const replay = await import("../src/feedbackReplay"); + replay.initializeFeedbackReplay(); + await replay.resumeFeedbackReplay(); + expect(mock.replay.startBuffering).toHaveBeenCalled(); + replay.stopFeedbackReplay(); + expect(mock.replay.stop).toHaveBeenCalledWith({ flush: false }); + history.replaceState({}, "", "/invites/PRIVATE"); + mock.replay.startBuffering.mockClear(); + await replay.resumeFeedbackReplay(); + expect(mock.replay.startBuffering).not.toHaveBeenCalled(); +}); + +it("does not flush a disabled integration into continuous session recording", async () => { + const replay = await import("../src/feedbackReplay"); + replay.initializeFeedbackReplay(); + mock.replay.getReplayId.mockReturnValue(undefined as unknown as string); + expect(await replay.freezeFeedbackReplay()).toBeUndefined(); + expect(mock.replay.flush).not.toHaveBeenCalled(); +}); + +it("freezes the pre-click buffer without continuing recording", async () => { + const replay = await import("../src/feedbackReplay"); + replay.initializeFeedbackReplay(); + expect(await replay.freezeFeedbackReplay()).toBe("replay-id"); + expect(mock.replay.flush).toHaveBeenCalledWith({ continueRecording: false }); + expect(mock.replay.stop).toHaveBeenCalledWith({ flush: false }); +}); + +it("waits for an in-flight flush before starting a replacement buffer", async () => { + let finish!: () => void; + mock.replay.flush.mockReturnValueOnce( + new Promise((resolve) => { + finish = resolve; + }), + ); + const replay = await import("../src/feedbackReplay"); + replay.initializeFeedbackReplay(); + await replay.resumeFeedbackReplay(); + const frozen = replay.freezeFeedbackReplay(); + mock.replay.startBuffering.mockClear(); + replay.restartFeedbackReplay(); + await Promise.resolve(); + expect(mock.replay.startBuffering).not.toHaveBeenCalled(); + finish(); + await frozen; + await replay.resumeFeedbackReplay(); + expect(mock.replay.startBuffering).toHaveBeenCalled(); +}); + +it("discards recordings on feature revocation and will not restart or flush them", async () => { + const replay = await import("../src/feedbackReplay"); + replay.setFeedbackReplayEnabled(true); + await replay.resumeFeedbackReplay(); + mock.replay.startBuffering.mockClear(); + replay.setFeedbackReplayEnabled(false); + expect(mock.replay.stop).toHaveBeenCalledWith({ flush: false }); + void replay.resumeFeedbackReplay(); + replay.restartFeedbackReplay(); + await replay.resumeFeedbackReplay(); + expect(mock.replay.startBuffering).not.toHaveBeenCalled(); + expect(await replay.freezeFeedbackReplay()).toBeUndefined(); + expect(mock.replay.flush).not.toHaveBeenCalled(); +}); diff --git a/browser/tests/tracing.test.ts b/browser/tests/tracing.test.ts new file mode 100644 index 0000000..99fe352 --- /dev/null +++ b/browser/tests/tracing.test.ts @@ -0,0 +1,28 @@ +import { expect, it, vi } from 'vitest'; +import { initializeBrowser, sanitizeSpan, sanitizeTransaction, stablePageName, percentageEligible } from '../src/index'; +vi.mock('@sentry/browser', () => ({ init: vi.fn(), getClient: () => undefined, browserTracingIntegration: () => ({}), startBrowserTracingNavigationSpan: vi.fn(), captureFeedback: vi.fn() })); +it('keeps stable navigation identities and strips URL credentials from spans', () => { expect(stablePageName('/people/123?token=private')).toBe('/people/:id'); const event = sanitizeTransaction({ transaction: '/people/123?token=private', spans: [{ description: 'GET https://user:password@api.test/private?token=secret', data: { 'http.request.method': 'GET', 'http.request.body': 'secret' } }] } as never); expect(JSON.stringify(event)).not.toContain('secret'); expect(JSON.stringify(event)).not.toContain('password'); }); +it('honors explicit local verification and reuses a supplied client', () => { const supplied = { addEventProcessor: vi.fn(), getOptions: () => ({}) } as never; expect(initializeBrowser({ enabled: false, dsn: 'https://key@host/1' }, supplied)).toBe(supplied); expect(initializeBrowser({ enabled: false })).toBeUndefined(); }); +it('uses stable percentage buckets matching the server SHA256 algorithm', async () => { const { webcrypto } = await import('node:crypto'); vi.stubGlobal('crypto', webcrypto); expect(await percentageEligible('feedback', 'USER', 50)).toBe(await percentageEligible('feedback', 'user', 50)); expect(await percentageEligible('feedback', '', 100)).toBe(false); expect(await percentageEligible('feedback', 'user', 100)).toBe(true); vi.unstubAllGlobals(); }); + +it('sanitizes standalone UI/resource spans and composes supplied-client filters exactly once', () => { + const options = { beforeSendSpan: vi.fn(span => ({ ...span, data: { ...span.data, 'sentry.secret': 'PRIVATE' } })) }; + const previous = options.beforeSendSpan; + const client = { addEventProcessor: vi.fn(), getOptions: () => options } as never; + initializeBrowser({ enabled: false }, client); initializeBrowser({ enabled: false }, client); + const result = options.beforeSendSpan({ op: 'ui.interaction.click', description: 'button#PRIVATE[email=PRIVATE]', data: { 'http.request.body': 'PRIVATE', 'browser.script': 'PRIVATE', 'sentry.origin': 'auto.ui.browser', 'server.address': 'https://user:PRIVATE@host.test/?token=PRIVATE' } } as never); + expect(JSON.stringify(result)).not.toContain('PRIVATE'); expect(result.description).toBe('interaction'); + expect(previous).toHaveBeenCalledOnce(); + expect(result.data['sentry.origin']).toBe('auto.ui.browser'); + const resource = sanitizeSpan({ op: 'resource.script', description: 'https://user:PRIVATE@host.test/private?token=PRIVATE', data: {} } as never); + expect(resource.description).toBe('https://host.test'); +}); + +it('retains numeric standalone Web Vitals while excluding element and URL attributes', () => { + const result = sanitizeSpan({ op: 'ui.webvital.lcp', description: '#PRIVATE', data: { 'browser.web_vital.lcp.value': 68, 'browser.web_vital.lcp.render_time': 60, 'browser.web_vital.lcp.element': '#PRIVATE', 'browser.web_vital.lcp.url': 'https://host/private?token=PRIVATE', 'sentry.op': 'ui.webvital.lcp', 'sentry.pageload.span_id': '0123456789abcdef', 'user_agent.original': navigator.userAgent }, measurements: { lcp: { value: 68, unit: 'millisecond' } } } as never); + expect(JSON.stringify(result)).not.toContain('PRIVATE'); + expect(result.data['browser.web_vital.lcp.value']).toBe(68); + expect(result.data['sentry.op']).toBe('ui.webvital.lcp'); + expect(result.measurements?.lcp.value).toBe(68); + expect(result.data['user_agent.original']).toBe(navigator.userAgent); +}); diff --git a/browser/vitest.config.ts b/browser/vitest.config.ts new file mode 100644 index 0000000..1bc7232 --- /dev/null +++ b/browser/vitest.config.ts @@ -0,0 +1,2 @@ +import { defineConfig } from 'vitest/config'; +export default defineConfig({ test: { environment: 'jsdom', include: ['tests/**/*.test.ts'] } }); diff --git a/build/Build.cfc b/build/Build.cfc index b15a671..b50619e 100644 --- a/build/Build.cfc +++ b/build/Build.cfc @@ -12,17 +12,19 @@ component { variables.cwd = getCWD().reReplace( "\.$", "" ); variables.artifactsDir = cwd & "/.artifacts"; variables.buildDir = cwd & "/.tmp"; - variables.apidDocsDir = variables.buildDir & "/apidocs"; + variables.apidDocsDir = variables.buildDir & "/apidocs"; variables.apiDocsURL = "http://localhost:60299/apidocs/"; variables.testRunner = "http://localhost:60299/tests/runner.cfm"; // Source Excludes Not Added to final binary variables.excludes = [ "build", - "node-modules", + "node[_-]modules", + "(^|/)modules(/|$)", + "browser/tests", "resources", "test-harness", - "(package|package-lock).json", + "^/?(package|package-lock).json$", "webpack.config.js", "server-.*\.json", "docker-compose.yml", @@ -36,28 +38,42 @@ component { variables.apidDocsDir ].each( function( item ){ if ( directoryExists( item ) ) { - directoryDelete( item, true ); + deleteBuildTree( item ); } // Create directories directoryCreate( item, true, true ); } ); // Create Mappings - fileSystemUtil.createMapping( - "coldbox", - variables.cwd & "test-harness/coldbox" - ); + fileSystemUtil.createMapping( "coldbox", variables.cwd & "test-harness/coldbox" ); return this; } + /** Delete build files without traversing symlinks into another checkout. */ + private function deleteBuildTree( required string path ){ + var files = createObject( "java", "java.nio.file.Files" ); + var root = createObject( "java", "java.io.File" ).init( arguments.path ).toPath(); + var stream = files.walk( root, javacast( "java.nio.file.FileVisitOption[]", [] ) ); + try { + var iterator = stream + .sorted( createObject( "java", "java.util.Comparator" ).reverseOrder() ) + .iterator(); + while ( iterator.hasNext() ) { + files.deleteIfExists( iterator.next() ); + } + } finally { + stream.close(); + } + } + /** * Run the build process: test, build source, docs, checksums * * @projectName The project name used for resources and slugs - * @version The version you are building - * @buldID The build identifier - * @branch The branch you are building + * @version The version you are building + * @buldID The build identifier + * @branch The branch you are building */ function run( required projectName, @@ -68,6 +84,12 @@ component { // Create project mapping fileSystemUtil.createMapping( arguments.projectName, variables.cwd ); + // Browser bundles are shipped so consuming CFML/BoxLang applications need no Node build. + command( "!npm --prefix browser run build" ).run(); + if ( shell.getExitCode() ) { + return error( "Browser build failed" ); + } + // Build the source buildSource( argumentCollection = arguments ); @@ -94,10 +116,10 @@ component { command( "testbox run" ) .params( - runner = variables.testRunner, - verbose = true, - outputFile = "#variables.cwd#/test-harness/results/test-results", - outputFormats="json,antjunit" + runner = variables.testRunner, + verbose = true, + outputFile = "#variables.cwd#/test-harness/results/test-results", + outputFormats = "json,antjunit" ) .run(); @@ -111,9 +133,9 @@ component { * Build the source * * @projectName The project name used for resources and slugs - * @version The version you are building - * @buldID The build identifier - * @branch The branch you are building + * @version The version you are building + * @buldID The build identifier + * @branch The branch you are building */ function buildSource( required projectName, @@ -133,18 +155,11 @@ component { // Project Build Dir variables.projectBuildDir = variables.buildDir & "/#projectName#"; - directoryCreate( - variables.projectBuildDir, - true, - true - ); + directoryCreate( variables.projectBuildDir, true, true ); // Copy source print.blueLine( "Copying source to build folder..." ).toConsole(); - copy( - variables.cwd, - variables.projectBuildDir - ); + copy( variables.cwd, variables.projectBuildDir ); // Create build ID fileWrite( @@ -183,10 +198,7 @@ component { ); // Copy box.json for convenience - fileCopy( - "#variables.projectBuildDir#/box.json", - variables.exportsDir - ); + fileCopy( "#variables.projectBuildDir#/box.json", variables.exportsDir ); } /** @@ -263,7 +275,11 @@ component { function( path ){ var isExcluded = false; variables.excludes.each( function( item ){ - if ( path.replaceNoCase( variables.cwd, "", "all" ).reFindNoCase( item ) ) { + if ( + path.replaceNoCase( variables.cwd, "", "all" ) + .reReplace( "^/+", "" ) + .reFindNoCase( item ) + ) { isExcluded = true; } } ); @@ -276,11 +292,9 @@ component { fileCopy( item, target ); } else { print.greenLine( "Copying directory #item#" ).toConsole(); - directoryCopy( - item, - target & "/" & item.replace( src, "" ), - true - ); + var childTarget = target & "/" & listLast( item, "/\" ); + directoryCreate( childTarget, true, true ); + copy( item, childTarget, true ); } } ); } @@ -295,15 +309,13 @@ component { /** * Ensure the export directory exists at artifacts/NAME/VERSION/ */ - private function ensureExportDir( - required projectName, - version = "1.0.0" - ){ - if ( structKeyExists( variables, "exportsDir" ) && directoryExists( variables.exportsDir ) ){ + private function ensureExportDir( required projectName, version = "1.0.0" ){ + if ( structKeyExists( variables, "exportsDir" ) && directoryExists( variables.exportsDir ) ) { return; } // Prepare exports directory variables.exportsDir = variables.artifactsDir & "/#projectName#/#arguments.version#"; directoryCreate( variables.exportsDir, true, true ); } + } diff --git a/docs/observability.md b/docs/observability.md new file mode 100644 index 0000000..8df7a24 --- /dev/null +++ b/docs/observability.md @@ -0,0 +1,128 @@ +# Observability and feedback for CFML and BoxLang + +All new integrations are opt-in. Existing error APIs, LogBox appender settings, standalone construction, and thread-safe WireBox initialization remain available. Version 3.0.0-alpha.1 is a preview requiring the accompanying qb/cbq hooks; it is not a published stable release. + +## Server setup + +```cfml +moduleSettings.sentry = { + DSN: getSystemSetting( "SENTRY_DSN", "" ), + environment: "production", + release: "my-release", + tracesSampleRate: 1, + enableRequestTracing: true, + queryAdapter: "auto", + databaseSystem: "postgresql", + enableQueueTracing: true, + enableLogs: true, + enableStructuredLogBoxAppender: true, + logMessageMode: "category", + enableMetrics: true, + enableMonitors: true, + monitorSlugs: [ "hourly-work" ], + tracePropagationTargets: [ "https://app.example.test" ], + trustIncomingTrace: false +}; +``` + +The same struct works in BoxLang. Standalone usage: `new sentry.models.SentryService( settings )`. Pass the same service across operations; call `shutdown()` at application shutdown. Add `sentry.endRequest()` in Application.cfc/Application.bx `onRequestEnd` to cover early redirects and aborted requests. ColdBox postProcess finishes ordinary requests after rendering. Route-template transaction names fall back to handler/action. Response status is read from the servlet response; explicit `endRequest(statusCode=303)` is also supported. + +Use a trustIncomingTrace callback at your ingress boundary. Reject public forged trace headers unless the request is from an approved browser/proxy boundary. Parent sampling decisions are honored; malformed/all-zero IDs are ignored. Propagation targets compare exact scheme/host/port and reject URL userinfo. Baggage carries only allowlisted technical sampling context. Use requestFilter, attributeFilter, beforeSendSignal, and beforeSendFeedback to filter signals. Application bodies, SQL bindings/results, job payloads, cached values, and credentials are never needed by instrumentation. + +```cfml +sentry.withTraceContext( headers, function( root ) { + return sentry.withSpan( "load inventory", function( span ) { + span.setAttribute( "organization.id", opaqueOrganizationId ); + return loadInventory(); + } ); +}, "inventory work", "task" ); +``` + +`startTransaction(name,op,headers,trusted)` creates a root handle; activate it with `getObservability().setScope({span:root})` for explicit/manual lifecycles and restore the previous scope in finally. `startSpan`, `withSpan`, `getTraceHeaders`, and `withTraceContext` support nesting. Handles have `setAttribute`, `setStatus`, `getContext`, and atomic `finish`. Disabled/unsampled spans are harmless. Always pass trace headers explicitly across worker boundaries; ThreadLocal context is not implicitly inherited. Telemetry delivery uses an independent two-thread Java HTTP executor, bounded pending envelopes (64), bounded signal buffers (100 per type), 2,000ms timeout, five-second flushing, category rate limits, and shutdown flushing. `getObservability().getTransport().getDiagnostics()` distinguishes accepted, rejected, pending, and dropped envelopes. HTTP acceptance is not a guarantee of indexing. + +## Queries + +On Lucee 6+, compose your existing application listener: + +```cfml +this.query.listener = sentry.createLuceeQueryListener( + listener = existingListener, + databaseSystem = "postgresql" +); +// Set queryAdapter="lucee" so qb does not produce a second span. +``` + +Native global listeners are officially scoped to Lucee 6+ ([Lucee documentation](https://docs.lucee.org/recipes/query-listener.html)); older engines are not automatically enabled. Existing before/after/error returns and transformations are preserved. Each thread has a nesting stack; use the manual wrapper for asynchronous query modes whose callbacks do not execute on that thread. + +BoxLang auto selects application-scoped preQueryExecute/postQueryExecute/onQueryExecuteError only when the runtime exposes ON_QUERY_EXECUTE_ERROR. Earlier runtimes fall back to qb. The upstream hook includes PendingQuery identity, context, elapsed milliseconds, and the unchanged exception. Cached execution events include cached/dbtype and correlate with the same pending identity. The currently tested server runtime lacks that error event: successful native direct queries were exercised separately, but automatic configuration deliberately uses qb there. Connection acquisition/build failures occurring before native PRE remain a manual-wrapper boundary. + +qb's new onQBExecuteException closes the original preQBExecute span and preserves the database exception even if an observer fails. Pretend queries are skipped. Adobe CF and runtimes without complete native coverage use these hooks plus: + +```cfml +result = sentry.withQuerySpan( sql, function( span ) { + return queryExecute( sql, parameters, options ); +}, "postgresql" ); +``` + +An explicit query wrapper suppresses native/qb span creation for its execution. SQL literals/comments/numbers are scrubbed; unsupported quoting fails closed. Cached queries and query-of-queries have distinct attributes/operations and are not reported as database round trips. Generic SQL scrubbing is conservative; use signal filters if your schema/identifiers themselves contain sensitive information. + +## Queues, caches, external calls and scheduled work + +cbq reserves job properties.__sentry for enqueue timestamp, trace headers, and publish ID. New Scheduled/Started/Exited/Finished hooks carry an immutable executionId and attempt. Started/Exited bracket the actual worker body; Finished may run on a different thread. Handles are keyed by executionId, completion is atomic, and a late success cannot overwrite a timed-out attempt. Request/worker scopes are restored in finally; retention is bounded. Success, manual release, cancellation and failure statuses are recorded. Existing chain/batch paths dispatch through these boundaries. Their comprehensive provider/retry matrices remain deferred. + +`getInstrumentedCache(name)` delegates CacheBox operations without serializing values; false/zero/empty-string values are hits. `inject="sentryCache:featureFlags"` is available to ColdBox consumers. The decorator forwards other methods but does not implement the ICacheProvider interface; use its underlying provider for consumers requiring that nominal type. + +`withHttpSpan(url,callback,method)` calls callback(span,headers), records safe origin/method, and propagates only to configured targets. Set `http.response.status_code` from the response; exceptions record internal_error and rethrow. Never pass body or signed URL attributes. `captureLog(message,level,attributes)` emits structured INFO+ logs. The bridge accepts configurable application category prefixes, excludes framework/query debug chatter and extraInfo, and does not capture another error event. category mode emits a fixed diagnostic message with its technical category; use sanitized message mode only for an approved logging policy. + +`counter`, `gauge`, and `distribution` emit typed trace_metric items with optional units/attributes. Request counts/durations, job outcomes/durations, and cache reads are seeded by integrations. `captureQueueMetrics(destination,depth,oldestAgeSeconds)` and `captureRuntimeGauges()` sample queue depth/age and inexpensive heap/thread values; schedule readers at a minute interval, not every idle poll. + +```cfml +sentry.withMonitor( "hourly-work", function(){ return performWork(); }, { + schedule: { type: "interval", value: 1, unit: "hour" }, + checkin_margin: 2, max_runtime: 10 +} ); +``` + +`captureCheckIn` and `withMonitor` use matching check-in IDs. Choose monitorSlugs according to your entitlement. Productive outbox work can use withTraceContext without a check-in for every two-second poll. + +## Browser installation + +Releases contain browser/dist/sentry-box.js and lazy ES-module chunks; plain layouts require no Node build. Alias only that directory (for example `/sentry-assets` to the installed module's browser/dist). Never expose the module root, settings, or application source. Browser sources/package metadata are also included for Vue bundler consumers. + +CFML layout: + +```cfml + + + +``` + +BoxLang layout uses `#JSONSerialize(sentry.getBrowserConfig())#` in the same initializer. Or import `/sentry-assets/esm/index.js` directly. Configure settings.browser with dsn, enabled, and optional localVerification/tracesSampleRate. getBrowserConfig exposes only public DSN/environment/release/sampling/targets. Encode JSON safely for your layout/CSP and never include arbitrary untrusted strings in an inline script. + +Official SDK document tracing supplies supported LCP/CLS/INP/FCP/TTFB and resource/request timings. initializeBrowser reuses a supplied/existing client and otherwise creates one. For Inertia set inertia=true, start navigation explicitly using startInertiaNavigation(component), and finish on the navigation lifecycle. Subsequent navigation spans do not reuse document Web Vitals. Stable identities, URLs, interactions, and attributes are sanitized. Localhost/development verification must be enabled explicitly. Browser entry points rely on modern ES modules, crypto.subtle, AbortController and HTMLDialogElement; older browser compatibility is deferred. + +## Feedback policy + +Native `captureFeedback(message,page,associatedEventId,replayId,attachments,wait)` returns a receipt/event ID: queued is distinct from accepted, rejected, failed, disabled, filtered or dropped. Attachments are binary, bounded to 2MB, with safe filenames. Waiting is appropriate when confirming delivery. Browser confirmation waits for the matching event's ingestion 2xx; a generic SDK flush never proves acceptance. + +The default widget offers pointer/touch/keyboard activation, drag-to-corner persistence, safe areas, focus restoration, reduced motion, configurable labels/className, review/removal, retry and object-URL cleanup. The custom controller is framework independent. Labels/disclosure should be translated by the host application. Screenshots include sanitized visible form state and use a configurable same-origin stylesheet policy. Limits are 1.5 million pixels, 2MB PNG, and eight seconds; capture failure preserves text feedback. + +Capture defaults to conservative masking. Approved readable policy is explicit: configureCapturePolicy({readable:true,...}) or widget.policy. Shared exclusions cover dynamic/show-password controls, credentials, login codes, tokens, card/bank fields, hidden controls, explicit mask/block markers, unsafe attributes, signed media, hidden application state, network bodies, console/custom replay events. Protected-page/media and stylesheet rules are configurable. Replay is prohibited on query/fragment URLs. Eligible users lazy-load replay/screenshot code; setEnabled(false) stops recording and discards the buffer. percentageEligible uses a stable SHA256 rollout bucket matching the server. Feature-flag persistence and tenant authorization belong to the application. + +Opening feedback immediately uploads the recent replay buffer. Message/PNG upload only on submission. The UI discloses this. Buffer freeze/restart/navigation operations guard overlapping flushes and stale captures. Automatic session and error replay sampling remain zero. Readable capture can contain personal information; Sentry project access is separate from tenant permissions. Review that access before enabling a readable policy. + +## Dashboards and profiling + +Use environment/release filters and stable route identities. Useful saved queries: `span.op:http.server` with p95(span.duration) grouped by transaction; `span.op:db*` grouped by span.description; `span.op:queue.process` with messaging.message.receive.latency/retry count; `span.op:cache.get` with cache.hit; `span.op:http.client span.status:internal_error`; metric.name:queue.depth/queue.oldest_age; metric.name:http.server.duration; and check-in monitor health. Availability of specialized feature screens is distinct from span ingestion and depends on the provider's conventions/entitlements. + +Browser profiling needs a separate browser support/Document-Policy and overhead evaluation. This module does not enable profiling. JVM profiling would require an evaluated Java SDK/JFR integration; heap/thread gauges are not profiles. No profiling compatibility or overhead result is claimed. + +See verification.md for commands, exact versions, provider proof and deferred checks. + +Lucee 6 global listener cache classification requires the query result metadata to include cached (for queryExecute, an existing result option). Missing cache metadata is marked db.cache_status=unknown. Query-of-queries bypassed global listeners in 6.2.8.20; instrument those explicitly with withQuerySpan. Existing error handlers retain their handling behavior; absent one, the adapter throws the original query exception. See the [Lucee listener contract](https://docs.lucee.org/recipes/query-listener.html). diff --git a/docs/verification.md b/docs/verification.md new file mode 100644 index 0000000..68a407b --- /dev/null +++ b/docs/verification.md @@ -0,0 +1,69 @@ +# Verification record + +Work is isolated in sentry-observability, qb-sentry-hooks, cbq-sentry-hooks, boxlang-sentry-hooks, and CommuniArts worktree 084b. No production deployment or hosted workflow dispatch was performed. + +## Reproducible local checks + +Start CommandBox on an isolated port with the module test-harness webroot and /moduleroot/sentry alias. Install ColdBox/TestBox and module dependencies with CommandBox. Start `node test-harness/support/receiver.mjs` (loopback 60320). Set SENTRY_CBQ_SOURCE to the owning cbq checkout to include its focused hook specs. Run tests/telemetry-runner.cfm and tests/runner.cfm?directory=&bundles=tests.specs.SentryTests,tests.specs.SentryWiringTests&reporter=json. Receiver /state contains decoded JSON items and base64 binary items, while /reset can simulate delay/status/category limits. The browser feedback.html fixture uses synthetic data only. Run `npm --prefix browser test` and `npm --prefix browser run build`. Native query smoke is separate from capability-selected automatic instrumentation. + +The harness and CommuniArts server run BoxLang 1.18.0+66 (build 2026-10-02), despite CommandBox's engine target metadata saying 1.18.6+62. Java is Temurin 21.0.10+7 arm64, Runwar 6.1.8. Lucee targeted listener verification uses 6.2.8.20, Java 21.0.10 and Runwar 5.2.7. The BoxLang upstream JUnit source build includes the new event; the application runtime has not consumed that runtime build. + +Transport checks exercise Unicode/real binary lengths, matching receipts, 429 category limits, unavailable ingestion, pending bounds and shutdown. Span checks cover malformed/all-zero headers, trusted parent sampling/baggage, nesting, failures, isolation, exact-origin propagation, completion once, redirect cleanup, manual/native de-duplication, zero/false/empty cached values, and Lucee listener composition. Queue tests include completion on another thread, timeout followed by late exit, synchronous observer exceptions, bulk enqueue failures, and an actual asynchronous cbq timeout. Hook JUnit tests preserve exception identity/correlation and cached event identity without introducing new DDL. + +Browser tests cover screenshot privacy, unsaved values, protected pages, capture deadlines, replay races, navigation cancellation, stale object URLs, eligibility and rejected-delivery retry. A Chromium generic widget capture produced a 1426x1051 PNG (61,900 bytes): visible edited note retained, synthetic displayed password and explicit masked content absent. Decoded real SDK replay payloads also excluded those secrets. Sentry played the uploaded replay and seeking reached 00:10 in the 14-second recording. CommuniArts sign-in to password recovery navigation rendered on communiarts.localhost:60321, with initial sentry-trace metadata and no anonymous feedback eligibility. + +## Provider recognition + +The CommuniArts Developer plan showed 5M spans, 5GB logs, 5GB application metrics, 1GB attachments, and one Cron monitor. No trial/billing changes were made. Synthetic traffic used sentry-verification and no application/customer records. + +Backend trace e8b904f3221b4924a4817a69472cebe3 was indexed with http.server, db.query, http.client, cache.get and queue.process spans. A structured log and sentry.verification.requests counter were indexed with that trace. All three envelopes received HTTP acceptance. Browser trace 55ad848cf4ce4b7e94bba8888bafe4d3 included document LCP 68ms, FCP 68ms, and TTFB 13.3ms. Replay 787f30f633f44fd9b75a0f7269542f4f was indexed under sentry-verification, played, and sought. Synthetic browser feedback received matching ingestion acceptance and is visible as COMMUNIARTS-FRONTEND-C in Spam. Its provider PNG preserves the unsaved synthetic note and masks the displayed password; the feedback links to the replay above. Cross-project trace 0167f55b73064debb5e26914c5f74c67 connects frontend http.client 8c13e6b93b3d8fc1 to backend http.server 5ce5ba73ca5b49eb. + +## Boundaries + +Focused success does not establish deployment readiness. Full hosted CI, browser matrices, Adobe CF/older Lucee compatibility, comprehensive queue retry/release/chain/batch/provider matrices, profiling and production traffic remain deferred. Native BoxLang caught direct-query errors require the proposed runtime release; qb hooks and withQuerySpan cover the current application. Browser SDK support determines which vitals are emitted: INP needs qualifying interactions and CLS needs layout shifts; absence of those in a static synthetic page is not failure. + +## Acceptance follow-up: 2026-10-04 + +The existing Sentry-built [Queries](https://communiarts.sentry.io/dashboard/10036763/?environment=sentry-verification), [Queues](https://communiarts.sentry.io/dashboard/10036787/?environment=sentry-verification), and [Caches](https://communiarts.sentry.io/dashboard/10036789/?environment=sentry-verification) dashboards recognize the synthetic spans. Queries groups SQL as `SELECT %s` and shows duration/throughput. Queues shows destination `synthetic`, processing count and 1ms average wait. Caches shows the verification transaction, hit/miss ratio and throughput. These are actual dashboard rows, separate from HTTP acceptance and Explore indexing. No dashboard definitions, billing, trial, or feedback classifications were changed. A fresh backend trace `cf17d77abbe443a385a38a2364c8c2f9` received three accepted envelopes and was indexed with all five operation types. + +Aligned the decorator's hashed `cache.key` with Sentry's array convention; only this bounded scalar array is permitted through the span filter. Logs/metrics continue to use scalar typed attributes, and bindings, results and arbitrary arrays remain excluded. Queue retries use `messaging.message.retry.count`, and publish spans include the assigned message ID. Cache value size remains omitted rather than inspecting or serializing values. The focused telemetry suites pass 17/17 and existing error/API wiring passes 27/27 on BoxLang 1.18.0+66. This follow-up did not remap the optional three cbq harness specs; their earlier results remain the earlier evidence. + +CommuniArts consumes published qb 14.1.0 and cbq 7.0.2. Its rollback-scoped request spec also verifies a caught direct PostgreSQL failure through `withQuerySpan`, alongside qb success/failure and wrapper de-duplication: four completed spans, correct failure statuses and restored parent scope. It passes 1/1 on the current runtime, without installing the unmerged BoxLang PR. + +A temporary synthetic account signed in through the normal CommuniArts login, qualified through the existing selected-user feature flag, and captured an unsaved organization form. No organization was created. The local receiver accepted matching feedback event `08673e8bf20e4e12a199bd7433d11717` with a 1426x1051, 119,281-byte PNG and replay `ad8a1c68fa9041b2a29c830838f7b036`. Decoded real SDK replay data retained ordinary form content and excluded the fixture password and feedback dialog message. + +The separate real-provider build produced feedback [COMMUNIARTS-FRONTEND-D](https://communiarts.sentry.io/issues/7772468793/) with event `0d2099487b3f4671b590f5f1a28d86f9`, PNG attachment `24796233267` (121,012 bytes, 1426x1051), replay `471eb33a7047486e8f85b21b80f70393` and trace `09d9f62ef0464848a08e6899dfda9b45`. The downloaded provider PNG preserves both unsaved form values. Sentry replay playback and seeking to 00:55 work. The report is not spam; Sentry's generated title describes a failure, but the original message explicitly states this is synthetic and no organization was created. Document-load metrics include LCP 1392ms, FCP 1228ms, TTFB 578ms and CLS 0.0442. Nine focused CommuniArts Vitest files pass 67/67; the targeted build passes at 518.6 KiB initial gzip. The fixture account, feature selection and temporary verification endpoint were removed; the subsequent guest page has no feedback trigger. + +A separate keyboard-input replay `6daa9882747e417c8ed48fc59ecf133f` retains the unsaved organization name and subdomain at its final 00:53 frame. Opening feedback uploaded that replay without submitting another message or screenshot. Playback seeking was checked through Sentry's visible replay controls. + +The full CommuniArts Vitest sweep also exposed existing pageMetadata registry and kiosk CheckIn sharing-payload mismatches in untouched files. Focused observability/feedback specs are the acceptance proof for this change; do not present them as a complete JavaScript-suite pass. + +Native Lucee 6.2.8.20 PostgreSQL verification passed success, caught failure, composed SQL transformation, cached result metadata, and manual/native de-duplication (six spans). Without a caller-supplied result option, Lucee supplies only executionTime, so cache status is unknown rather than incorrectly reported as a database round trip. This Lucee runtime bypassed global listeners for query-of-queries; use the manual wrapper for that coverage. + +Earlier focused results: module telemetry and cbq hook specs 20/20; existing module API/wiring 27/27; browser companion 28/28; CommuniArts backend integration and unit specs 26/26; CommuniArts focused feedback/tracing Vitest 70/70. The complete CommuniArts Vitest run passed 803 and failed the two pre-existing contracts noted above. That application build passed its initial JavaScript gzip budget at 518.3 KiB. + +Queue regression checks also verify worker-start timestamps, wait time excluding processing, retry counts, cancellation after worker exit, and persisted chain propagation after callback scope cleanup. The package build produced a source ZIP including browser source/package metadata and bundled assets, excluding node_modules and installed modules. Cleanup was verified against an external symlink sentinel. + +Native BoxLang/CFML captureFeedback with the captured 61,900-byte PNG received HTTP 200 for event 14625ba2371241fbb0f651fcfe3e80e2. Sentry indexed attachment 24792376268 as sentry-verification.png, image/png, 61,900 bytes; this confirms binary attachment recognition independently of the HTTP receipt. Browser feedback visibility and replay playback were verified in the frontend project; the native feedback entry itself was not inspected in the backend feedback UI. + +Standalone browser spans also use beforeSendSpan sanitization, including clients supplied by consumers. This removes interaction selectors and unapproved attributes even when the SDK sends a span outside a transaction envelope. + +An untargeted qb harness run also passed 3,356 specs, failed one timestamp/default-value expectation (UTC versus local time), and errored on 28 specs using unavailable evaluate/isBoxLang/URL encoding helpers or toStartWith matchers in this harness. These broader compatibility checks are not qualified; the explicitly selected failure-hook specs passed 2/2. No complete qb-suite pass is claimed. + +Standalone Web Vitals retain numeric measurements, safe pageload linkage, and the browser-provided user agent needed for scoring; element selectors, media URLs, and arbitrary custom attributes remain excluded. + +## CI failure repair: 2026-10-04 + +The failing head `39865b9` had three infrastructure problems: the workflow did not start the local envelope receiver, the root harness referenced the sentry mapping before creating it, and the tests application called a BoxLang-only environment BIF on CFML engines. The workflow now starts and checks the receiver, retains its log as an artifact, and probes a non-throwing health template with HTTP failure detection. Environment lookup uses Java System.getenv. Formatting uses CommandBox CFFormat 0.21.0 in both local and CI checks, with no automatic formatting commits. + +The local engine runs also exposed module compatibility issues. Adobe rejects local declarations that reuse argument names and direct indexing of a struct literal. Lucee rejects slicing an empty pending array and returns false for every() on an empty array. Transport now handles an empty flush explicitly. Adobe on Java 21 cannot reflect on non-exported JDK HTTP implementation classes; JavaHttp invokes methods declared on exported HTTP/Future interfaces instead. This requires no extra JVM access flags or consumer JAR. The public-interface approach follows the [Java Method invocation contract](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/reflect/Method.html#invoke(java.lang.Object,java.lang.Object...)). + +Queue cleanup iterates a Java key array rather than relying on engine-specific entrySet iteration. Metadata lookup guards missing keys explicitly. Observer catches increment a thread-safe diagnostic count exposed by getObservationFailureCount(), without exporting exception contents or invoking telemetry recursively. Regression specs assert zero observer failures during timeout/retry and chained publication. The cross-thread fixture holds the original observer in a Java AtomicReference because Adobe copies CFML thread arguments. The query-listener fixture uses an actual caught exception rather than an artificial exception struct. + +With ColdBox 7.5.2+27 and TestBox 3.2.0, the default harness passes 45/45 on BoxLang 1.18.0+66, Lucee 6.2.8.20, and Adobe CF 2023 update 25 (2023,0,25,330977), using Java 21.0.10+7. Checks include real Unicode/binary transport, delivery receipts, rejection, rate limits, unavailable ingestion, bounded waits, empty shutdown, and queue scope/completion regressions. The legacy TestBox reporter identifies BoxLang as Lucee 6.0.0; the actual BoxLang version above comes from the runtime startup log. + +ColdBox 6.11.0+20 also passes 45/45 on Lucee 6.2.8.20. Runtime version was checked through the active controller rather than inferred from dependency files. Repeating CFFormat produces no tracked changes; a deliberately unformatted directory fixture is rejected with exit code 1. + +The fresh local Adobe engine needed the zip and debugger packages already configured by CI, plus Commons IO 2.4 copied from an installed Adobe distribution into this isolated engine to restore CF file operations. That engine adjustment is separate from the module source; this local Adobe result does not qualify a pristine runtime artifact. The additional Adobe/ColdBox 6 run remained unqualified: after a framework-switch restart, the local engine lost its hot-installed package state and failed during compiler bootstrap, before module tests. Its cached earlier run was excluded after checking the active controller version. Full hosted matrix results remain separate until the repaired commit runs. CommuniArts, browser assets, provider state, and production deployment were not changed by this repair. + +The first repaired CI head `a721025` passed formatting and the BoxLang, Lucee 6, Adobe 2018, and Adobe 2021 jobs. It exposed Lucee 5's compiler failure for a catch nested inside a finally block, plus Adobe 2023's missing Commons IO when a synthetic Windows path triggered its virtual filesystem. Span wrappers now call a separate best-effort completion helper, retain original callback results/exceptions and scope restoration, and count completion failures. Source context accepts local files via java.io.File and skips source/function parsing for missing files; it does not load a CF virtual filesystem for foreign trace paths. Existing Windows-path coverage asserts empty source context, and the function-name fixture uses a real readable template and checks its source lines. The added completion-failure regression raises the default suite to 46 specs. Local Lucee 5.4.8.2 and Adobe 2023 update 25 pass 46/46 with ColdBox 7.5.2. The health probe retains an error response body when failing to improve startup diagnostics. diff --git a/interceptors/Observability.cfc b/interceptors/Observability.cfc new file mode 100644 index 0000000..69a21ad --- /dev/null +++ b/interceptors/Observability.cfc @@ -0,0 +1,74 @@ +/** Optional ColdBox request lifecycle. */ +component { + + property name="sentry" inject="SentryService@sentry"; + function onRequestCapture( event, interceptData ){ + try { + var telemetry = variables.sentry.getObservability(); + var settings = variables.sentry.getSettings(); + if ( !settings.enableRequestTracing ) { + return; + } + if ( isCustomFunction( settings.requestFilter ) && !settings.requestFilter( arguments.event ) ) { + return; + } + var headers = getHTTPRequestData( false ).headers; + var trusted = isCustomFunction( settings.trustIncomingTrace ) ? settings.trustIncomingTrace( + headers, + arguments.event + ) : settings.trustIncomingTrace; + var state = { + previous : telemetry.getScope(), + span : telemetry.startTransaction( + requestName( arguments.event ), + "http.server", + headers, + trusted + ) + }; + arguments.event.setPrivateValue( "_sentryRequest", state ); + telemetry.setScope( { span : state.span, requestState : state } ); + } catch ( any ignored ) { + } + } + function preProcess( event, interceptData ){ + try { + var state = arguments.event.getPrivateValue( "_sentryRequest", {} ); + if ( state.keyExists( "span" ) ) { + state.span.rename( requestName( arguments.event ) ); + arguments.event.setPrivateValue( "sentryTraceHeaders", variables.sentry.getTraceHeaders() ); + } + } catch ( any ignored ) { + } + } + function postProcess( event, interceptData ){ + complete( arguments.event ); + } + function onException( event, interceptData ){ + try { + var state = arguments.event.getPrivateValue( "_sentryRequest", {} ); + if ( state.keyExists( "span" ) ) { + state.span.setStatus( "internal_error" ); + } + } catch ( any ignored ) { + } + } + private function complete( required any event ){ + try { + var state = arguments.event.getPrivateValue( "_sentryRequest", {} ); + if ( state.keyExists( "span" ) ) { + state.span.rename( requestName( arguments.event ) ); + variables.sentry.endRequest(); + } + } catch ( any ignored ) { + } + } + private function requestName( required any event ){ + var route = arguments.event.getCurrentRoute(); + if ( !isSimpleValue( route ) || !len( route ) ) { + route = arguments.event.getCurrentEvent(); + } + return arguments.event.getHTTPMethod() & " " & route; + } + +} diff --git a/interceptors/QueryObservability.cfc b/interceptors/QueryObservability.cfc new file mode 100644 index 0000000..991046d --- /dev/null +++ b/interceptors/QueryObservability.cfc @@ -0,0 +1,47 @@ +/** qb fallback; one adapter produces each execution's span. */ +component { + + property name="sentry" inject="SentryService@sentry"; + function preQBExecute( event, interceptData ){ + try { + if ( arguments.interceptData.pretend ?: false ) { + return; + } + var telemetry = variables.sentry.getObservability(); + if ( variables.sentry.getSettings().queryAdapter != "qb" ) { + return; + } + var current = telemetry.getScope(); + if ( current.keyExists( "manualQuerySpan" ) ) { + return; + } + var span = telemetry.startSpan( + telemetry.scrubSQL( arguments.interceptData.sql ), + "db.query", + { "db.system" : variables.sentry.getSettings().databaseSystem ?: "other" } + ); + arguments.interceptData[ "_sentryExecution" ] = { span : span, previous : current }; + var next = structCopy( current ); + next.span = span; + telemetry.setScope( next ); + } catch ( any ignored ) { + } + } + function postQBExecute( event, interceptData ){ + complete( arguments.interceptData ); + } + function onQBExecuteException( event, interceptData ){ + complete( arguments.interceptData, "internal_error" ); + } + private function complete( required struct data, string status = "ok" ){ + try { + var execution = arguments.data[ "_sentryExecution" ] ?: {}; + if ( execution.keyExists( "span" ) ) { + execution.span.finish( arguments.status ); + variables.sentry.getObservability().setScope( execution.previous ); + } + } catch ( any ignored ) { + } + } + +} diff --git a/interceptors/QueueObservability.cfc b/interceptors/QueueObservability.cfc new file mode 100644 index 0000000..ddf14d6 --- /dev/null +++ b/interceptors/QueueObservability.cfc @@ -0,0 +1,269 @@ +/** Handles are keyed by immutable execution IDs, never by callback thread or mutable job state. */ +component { + + property name ="sentry" inject="SentryService@sentry"; + variables.attempts = createObject( "java", "java.util.concurrent.ConcurrentHashMap" ).init(); + variables.publishes = createObject( "java", "java.util.concurrent.ConcurrentHashMap" ).init(); + variables.execution = createObject( "java", "java.lang.ThreadLocal" ).init(); + variables.observationFailures= createObject( "java", "java.util.concurrent.atomic.AtomicLong" ).init( 0 ); + function onCBQJobAdded( event, interceptData ){ + try { + if ( !variables.sentry.getSettings().enableQueueTracing ) { + return; + } + var job = arguments.interceptData.job; + var telemetry = variables.sentry.getObservability(); + for ( var publishId in variables.publishes.keySet().toArray() ) { + var published = variables.publishes.get( publishId ); + if ( !isNull( published ) && telemetry.timestamp() - published.created > 3600 ) { + var expired = variables.publishes.remove( publishId ); + if ( !isNull( expired ) ) { + expired.span.finish( "deadline_exceeded" ); + if ( expired.ownsRoot ) { + expired.root.finish( "deadline_exceeded" ); + } + } + } + } + var previous = telemetry.getScope(); + var ownsRoot = !previous.keyExists( "span" ) || previous.span.isFinished(); + var properties = job.getProperties(); + var existingMetadata = properties.keyExists( "__sentry" ) ? properties[ "__sentry" ] : {}; + var continued = previous.keyExists( "span" ) ? variables.sentry.getTraceHeaders() : ( + existingMetadata.headers ?: {} + ); + var root = !ownsRoot ? previous.span : telemetry.startTransaction( + "publish " & ( job.getQueue() ?: "default" ), + "queue.task", + continued, + true + ); + telemetry.setScope( { "span" : root } ); + var publish = telemetry.startSpan( + "publish " & ( job.getQueue() ?: "default" ), + "queue.publish", + { "messaging.destination.name" : job.getQueue() ?: "default" } + ); + telemetry.setScope( { "span" : publish } ); + var metadata = { + "headers" : variables.sentry.getTraceHeaders(), + "enqueuedAt" : telemetry.timestamp(), + "publishId" : telemetry.id() + }; + telemetry.setScope( previous ); + properties[ "__sentry" ] = metadata; + try { + for ( var config in job.getChained() ) { + param config.properties = {}; + config.properties[ "__sentry" ] = { + "headers" : metadata.headers, + "enqueuedAt" : metadata.enqueuedAt + }; + } + } catch ( any unavailableChain ) { + variables.observationFailures.incrementAndGet(); + } + if ( variables.publishes.size() < 1024 ) { + variables.publishes.put( + metadata.publishId, + { + "span" : publish, + "root" : root, + "ownsRoot" : ownsRoot, + "created" : telemetry.timestamp() + } + ); + } else { + publish.finish( "resource_exhausted" ); + if ( ownsRoot ) { + root.finish( "resource_exhausted" ); + } + } + } catch ( any ignored ) { + variables.observationFailures.incrementAndGet(); + } finally { + if ( !isNull( local.previous ) ) { + telemetry.setScope( previous ); + } + } + } + function onCBQJobPublished( event, interceptData ){ + finishPublish( arguments.interceptData.job, "ok" ); + } + function onCBQJobPublishException( event, interceptData ){ + finishPublish( arguments.interceptData.job, "internal_error" ); + } + private function finishPublish( required any job, required string status ){ + try { + var properties = arguments.job.getProperties(); + var metadata = properties.keyExists( "__sentry" ) ? properties[ "__sentry" ] : {}; + var state = variables.publishes.remove( metadata.publishId ?: "" ); + if ( !isNull( state ) ) { + state.span.setAttribute( "messaging.message.id", toString( arguments.job.getId() ) ); + state.span.finish( arguments.status ); + if ( state.ownsRoot ) { + state.root.finish( arguments.status ); + } + } + } catch ( any ignored ) { + variables.observationFailures.incrementAndGet(); + } + } + function onCBQJobAttemptScheduled( event, interceptData ){ + try { + if ( !variables.sentry.getSettings().enableQueueTracing ) { + return; + } + var telemetry = variables.sentry.getObservability(); + // Bound abandoned work even if a worker never starts after a timeout/shutdown. + for ( var executionId in variables.attempts.keySet().toArray() ) { + var scheduled = variables.attempts.get( executionId ); + if ( !isNull( scheduled ) && telemetry.timestamp() - scheduled.created > 3600 ) { + scheduled.span.finish( "deadline_exceeded" ); + scheduled.root.finish( "deadline_exceeded" ); + variables.attempts.remove( executionId ); + } + } + if ( variables.attempts.size() >= 1024 ) { + return; + } + var job = arguments.interceptData.job; + var properties = job.getProperties(); + var metadata = properties.keyExists( "__sentry" ) ? properties[ "__sentry" ] : {}; + var root = telemetry.startTransaction( + "job " & job.getMapping(), + "queue.task", + metadata.headers ?: {}, + true + ); + var previous = telemetry.getScope(); + var span = root; + try { + telemetry.setScope( { "span" : root } ); + span = telemetry.startSpan( "process " & job.getMapping(), "queue.process" ); + } finally { + telemetry.setScope( previous ); + } + span.setAttribute( "messaging.destination.name", job.getQueue() ?: "default" ); + span.setAttribute( "messaging.message.id", toString( job.getId() ) ); + try { + if ( job.isBatchJob() ) { + span.setAttribute( "messaging.batch.id", toString( job.getBatchId() ) ); + } + } catch ( any unavailableBatch ) { + variables.observationFailures.incrementAndGet(); + } + span.setAttribute( "messaging.message.retry.count", max( 0, arguments.interceptData.attempt - 1 ) ); + span.setAttribute( + "messaging.message.receive.latency", + max( 0, ( telemetry.timestamp() - ( metadata.enqueuedAt ?: telemetry.timestamp() ) ) * 1000 ) + ); + variables.attempts.putIfAbsent( + arguments.interceptData.executionId, + { + "span" : span, + "root" : root, + "exited" : false, + "created" : telemetry.timestamp(), + "enqueuedAt" : metadata.enqueuedAt ?: telemetry.timestamp(), + "started" : 0 + } + ); + } catch ( any ignored ) { + variables.observationFailures.incrementAndGet(); + } + } + function onCBQJobExecutionStarted( event, interceptData ){ + try { + var attempt = variables.attempts.get( arguments.interceptData.executionId ); + if ( isNull( attempt ) ) { + return; + } + var telemetry = variables.sentry.getObservability(); + var stack = variables.execution.get() ?: []; + stack.append( { + "previous" : telemetry.getScope(), + "attempt" : attempt, + "id" : arguments.interceptData.executionId + } ); + variables.execution.set( stack ); + telemetry.setScope( { "span" : attempt.span } ); + var startedAt = telemetry.timestamp(); + if ( attempt.span.markStarted( startedAt ) ) { + attempt.started = startedAt; + var waitTime = max( 0, ( startedAt - attempt.enqueuedAt ) * 1000 ); + attempt.span.setAttribute( "messaging.message.receive.latency", waitTime ); + variables.sentry.distribution( + "queue.wait.duration", + waitTime, + {}, + "millisecond" + ); + } + } catch ( any ignored ) { + variables.observationFailures.incrementAndGet(); + } + } + function onCBQJobExecutionExited( event, interceptData ){ + try { + var stack = variables.execution.get() ?: []; + if ( !stack.len() ) { + return; + } + var execution = stack[ stack.len() ]; + if ( execution.id != arguments.interceptData.executionId ) { + return; + } + variables.sentry.getObservability().setScope( execution.previous ); + stack.deleteAt( stack.len() ); + if ( !stack.len() ) { + variables.execution.remove(); + } + execution.attempt.exited = true; + if ( execution.attempt.span.isFinished() ) { + variables.attempts.remove( execution.id ); + } + } catch ( any ignored ) { + variables.observationFailures.incrementAndGet(); + } + } + function onCBQJobAttemptFinished( event, interceptData ){ + try { + var attempt = variables.attempts.get( arguments.interceptData.executionId ); + if ( isNull( attempt ) ) { + return; + } + var status = arguments.interceptData.status; + attempt.span.setAttribute( "messaging.message.released", status == "released" ); + if ( attempt.span.finish( status == "released" ? "ok" : status ) ) { + var telemetry = variables.sentry.getObservability(); + var previous = telemetry.getScope(); + try { + telemetry.setScope( { "span" : attempt.root } ); + variables.sentry.counter( "queue.attempts", 1, { "outcome" : status } ); + variables.sentry.distribution( + "queue.processing.duration", + attempt.started > 0 ? ( telemetry.timestamp() - attempt.started ) * 1000 : 0, + { "outcome" : status }, + "millisecond" + ); + } finally { + telemetry.setScope( previous ); + } + attempt.root.finish( status == "released" ? "ok" : status ); + } + if ( attempt.exited ) { + variables.attempts.remove( arguments.interceptData.executionId ); + } + } catch ( any ignored ) { + variables.observationFailures.incrementAndGet(); + } + } + function getPendingAttemptCount(){ + return variables.attempts.size(); + } + function getObservationFailureCount(){ + return variables.observationFailures.get(); + } + +} diff --git a/models/SentryService.cfc b/models/SentryService.cfc index 49373b5..4cf856c 100644 --- a/models/SentryService.cfc +++ b/models/SentryService.cfc @@ -193,6 +193,10 @@ component accessors=true singleton threadSafe { setExtraInfoUDFs( settings.extraInfoUDFs ); settings.appRoot = normalizeSlashes( settings.appRoot ); + if ( !isNull( variables.observability ) ) { + variables.observability.shutdown(); + } + variables.observability = new telemetry.Observability( this, variables.settings ); // in a non ColdBox context, ensure functionLineNums exists // so this service can still be used if functionLineNums @@ -206,6 +210,90 @@ component accessors=true singleton threadSafe { } } + + function percentageEligible(){ + return variables.observability.percentageEligible( argumentCollection = arguments ); + } + function createLuceeQueryListener( any listener, string databaseSystem = "other" ){ + return new telemetry.LuceeQueryListener( + variables.observability, + arguments.listener ?: {}, + arguments.databaseSystem + ); + } + function endRequest(){ + return variables.observability.endRequest( argumentCollection = arguments ); + } + function getObservability(){ + return variables.observability; + } + function startTransaction(){ + return variables.observability.startTransaction( argumentCollection = arguments ); + } + function startSpan(){ + return variables.observability.startSpan( argumentCollection = arguments ); + } + function withSpan(){ + return variables.observability.withSpan( argumentCollection = arguments ); + } + function getTraceHeaders(){ + return variables.observability.getTraceHeaders( argumentCollection = arguments ); + } + function withTraceContext(){ + return variables.observability.withTraceContext( argumentCollection = arguments ); + } + function getTraceContext(){ + return variables.observability.getTraceContext( argumentCollection = arguments ); + } + function withQuerySpan(){ + return variables.observability.withQuerySpan( argumentCollection = arguments ); + } + function withHttpSpan(){ + return variables.observability.withHttpSpan( argumentCollection = arguments ); + } + function captureFeedback(){ + return variables.observability.captureFeedback( argumentCollection = arguments ); + } + function captureLog(){ + return variables.observability.captureLog( argumentCollection = arguments ); + } + function counter(){ + return variables.observability.counter( argumentCollection = arguments ); + } + function gauge(){ + return variables.observability.gauge( argumentCollection = arguments ); + } + function distribution(){ + return variables.observability.distribution( argumentCollection = arguments ); + } + function captureCheckIn(){ + return variables.observability.captureCheckIn( argumentCollection = arguments ); + } + function withMonitor(){ + return variables.observability.withMonitor( argumentCollection = arguments ); + } + function getBrowserConfig(){ + return variables.observability.getBrowserConfig( argumentCollection = arguments ); + } + function flush(){ + return variables.observability.flush( argumentCollection = arguments ); + } + function shutdown(){ + return variables.observability.shutdown( argumentCollection = arguments ); + } + function captureQueueMetrics(){ + return variables.observability.captureQueueMetrics( argumentCollection = arguments ); + } + function captureRuntimeGauges(){ + return variables.observability.captureRuntimeGauges( argumentCollection = arguments ); + } + function getInstrumentedCache( string name = "default" ){ + return new telemetry.InstrumentedCache( + variables.wirebox.getInstance( "cachebox:" & arguments.name ), + variables.observability + ); + } + /** * Parses a valid Sentry DSN * @@ -539,7 +627,7 @@ component accessors=true singleton threadSafe { }; // The name of the function being called - var functionName = functionLineNums.findTagContextFunction( thisTCItem ); + var functionName = sourceCtx.available ? functionLineNums.findTagContextFunction( thisTCItem ) : ""; if ( len( functionName ) ) { thisStackItem[ "function" ] = functionName; } @@ -789,10 +877,13 @@ component accessors=true singleton threadSafe { var result = { "pre_context" : [], "context_line" : "", - "post_context" : [] + "post_context" : [], + "available" : false }; - if ( !fileExists( arguments.templatePath ) ) { + // Treat trace paths as local files, never as CF virtual-filesystem schemes. + var sourceFile = createObject( "java", "java.io.File" ).init( arguments.templatePath ); + if ( !sourceFile.isFile() ) { return result; } @@ -802,6 +893,7 @@ component accessors=true singleton threadSafe { arrayAppend( fileArray, fileReadLine( f ) ); } fileClose( f ); + result.available = true; var fileLen = arrayLen( fileArray ); @@ -1111,6 +1203,13 @@ component accessors=true singleton threadSafe { getInterceptorService().announce( "onSentryEventCapture", { "event" : arguments.captureStruct } ); } + var traceContext = variables.observability.getTraceContext(); + if ( !traceContext.isEmpty() ) { + if ( !arguments.captureStruct.keyExists( "contexts" ) ) { + arguments.captureStruct.contexts = {}; + } + arguments.captureStruct.contexts.trace = traceContext; + } // serialize data jsonCapture = serializeJSON( arguments.captureStruct ); @@ -1125,7 +1224,7 @@ component accessors=true singleton threadSafe { } // post message - if ( arguments.useThread ) { + if ( arguments.useThread && getSentryEventEndpoint() != "envelope" ) { cfthread( action = "run", name = "sentry-thread-" & createUUID(), @@ -1169,6 +1268,16 @@ component accessors=true singleton threadSafe { required string json, string traceParent = "" ){ + if ( getSentryEventEndpoint() == "envelope" ) { + variables.observability.sendSignal( + "event", + deserializeJSON( arguments.json ), + "error", + [], + !getAsync() + ); + return; + } var http = {}; // send to sentry via REST API Call var httpBody = arguments.json; @@ -1235,12 +1344,15 @@ component accessors=true singleton threadSafe { } /** - * Get UTC time values using the ISO mask shared by CFML and native BoxLang. + * Get matching UTC values from one truncated epoch second on every engine. */ private struct function getTimeVars( date time = now() ){ - var timeVars = { - "unix" : toString( int( time.getTime() / 1000 ) ), - "iso" : dateTimeFormat( time, "iso", "UTC" ) + var unixSeconds = int( time.getTime() / 1000 ); + var timeVars = { + "unix" : toString( unixSeconds ), + "iso" : createObject( "java", "java.time.Instant" ) + .ofEpochSecond( javacast( "long", unixSeconds ) ) + .toString() }; return timeVars; } diff --git a/models/StructuredLogAppender.cfc b/models/StructuredLogAppender.cfc new file mode 100644 index 0000000..0a62976 --- /dev/null +++ b/models/StructuredLogAppender.cfc @@ -0,0 +1,37 @@ +/** Opt-in structured logs. Does not capture a second error event or log extraInfo. */ +component extends="coldbox.system.logging.AbstractAppender" { + + function init( + required name, + struct properties = {}, + layout = "", + numeric levelMin = 0, + numeric levelMax = 3 + ){ + super.init( argumentCollection = arguments ); + return this; + } + function logMessage( required any logEvent ){ + try { + var category = arguments.logEvent.getCategory(); + var allow = getProperty( "categories", [ "app." ] ); + var accepted = false; + for ( var prefix in allow ) { + if ( left( category, len( prefix ) ) == prefix ) { + accepted = true; + } + } + if ( !accepted || reFindNoCase( "sentry|qb|coldbox|bindings", category ) ) { + return; + } + var service = propertyExists( "sentryService" ) ? getProperty( "sentryService" ) : application.wirebox.getInstance( "SentryService@sentry" ); + service.captureLog( + getProperty( "messageMode", "sanitized" ) == "category" ? "Application diagnostic" : arguments.logEvent.getMessage(), + lCase( this.logLevels.lookup( arguments.logEvent.getSeverity() ) ), + { category : category } + ); + } catch ( any ignored ) { + } + } + +} diff --git a/models/dsl/CacheDSL.cfc b/models/dsl/CacheDSL.cfc new file mode 100644 index 0000000..15963b8 --- /dev/null +++ b/models/dsl/CacheDSL.cfc @@ -0,0 +1,19 @@ +/** WireBox injection: sentryCache:providerName. */ +component implements="coldbox.system.ioc.dsl.IDSLBuilder" { + + function init( required any injector ){ + variables.injector = arguments.injector; + return this; + } + function process( + required any definition, + any targetObject, + any targetID + ){ + var name = listRest( arguments.definition.dsl, ":" ); + return variables.injector + .getInstance( "SentryService@sentry" ) + .getInstrumentedCache( len( name ) ? name : "default" ); + } + +} diff --git a/models/telemetry/BoxLangQueryListener.cfc b/models/telemetry/BoxLangQueryListener.cfc new file mode 100644 index 0000000..c19973e --- /dev/null +++ b/models/telemetry/BoxLangQueryListener.cfc @@ -0,0 +1,68 @@ +/** Runtime events are global; this listener accepts only its owning application's context. */ +component { + + function init( + required any telemetry, + required string applicationName, + string databaseSystem = "other" + ){ + variables.telemetry = arguments.telemetry; + variables.applicationName = arguments.applicationName; + variables.databaseSystem = arguments.databaseSystem; + variables.pending = createObject( "java", "java.util.concurrent.ConcurrentHashMap" ).init(); + return this; + } + private function owns( required struct data ){ + try { + var applicationContext = arguments.data.context.getParentOfType( + createObject( "java", "java.lang.Class" ).forName( "ortus.boxlang.runtime.context.ApplicationBoxContext" ) + ); + return !isNull( applicationContext ) && applicationContext + .getApplication() + .getName() + .toString() == variables.applicationName; + } catch ( any ignored ) { + return false; + } + } + function preQueryExecute( required struct data ){ + try { + if ( !owns( arguments.data ) || variables.telemetry.getScope().keyExists( "manualQuerySpan" ) ) { + return; + } + var span = variables.telemetry.startSpan( + variables.telemetry.scrubSQL( arguments.data.sql ), + ( arguments.data.cached ?: false ) ? "db.query.cache" : ( + ( arguments.data.dbtype ?: "" ) == "query" ? "db.query.qoq" : "db.query" + ), + { + "db.system" : variables.databaseSystem, + "db.operation" : uCase( listFirst( trim( arguments.data.sql ), " " ) ), + "db.cached" : arguments.data.cached ?: false + } + ); + variables.pending.put( arguments.data.pendingQuery, span ); + } catch ( any ignored ) { + } + } + function postQueryExecute( required struct data ){ + complete( arguments.data, "ok" ); + } + function onQueryExecuteError( required struct data ){ + complete( arguments.data, "internal_error" ); + } + private function complete( required struct data, required string status ){ + try { + var span = variables.pending.remove( arguments.data.pendingQuery ); + if ( !isNull( span ) ) { + span.setAttribute( "db.cached", arguments.data.result.cached ?: false ); + if ( isNumeric( arguments.data.executionTime ?: "" ) ) { + span.setAttribute( "db.execution.duration", arguments.data.executionTime ); + } + span.finish( arguments.status ); + } + } catch ( any ignored ) { + } + } + +} diff --git a/models/telemetry/EnvelopeTransport.cfc b/models/telemetry/EnvelopeTransport.cfc new file mode 100644 index 0000000..2cc4d61 --- /dev/null +++ b/models/telemetry/EnvelopeTransport.cfc @@ -0,0 +1,219 @@ +/** Bounded, independent Java HTTP transport. No application/cbq worker is used. */ +component { + + function init( + required struct settings, + required string endpoint, + required string auth, + boolean enabled = true + ){ + variables[ "settings" ] = arguments.settings; + variables[ "endpoint" ] = arguments.endpoint; + variables[ "auth" ] = arguments.auth; + variables[ "enabled" ] = arguments.enabled; + variables[ "id" ] = createUUID(); + variables[ "pending" ] = []; + variables[ "limits" ] = {}; + variables[ "dropped" ] = 0; + variables[ "responses" ] = { "accepted" : 0, "rejected" : 0 }; + variables[ "closed" ] = false; + variables[ "executor" ] = createObject( "java", "java.util.concurrent.Executors" ).newFixedThreadPool( + javacast( "int", 2 ) + ); + variables[ "http" ] = new JavaHttp(); + variables[ "client" ] = variables.http.createClient( variables.executor, settings.transportTimeout ); + return this; + } + function send( + required string eventId, + required array items, + string category = "error", + boolean wait = false + ){ + var receipt = new Receipt( eventId = arguments.eventId, state = "disabled" ); + if ( !variables.enabled || variables.closed ) { + return receipt; + } + lock name="sentry-transport-#variables.id#" type="exclusive" timeout="2" { + reap(); + if ( variables.pending.len() >= variables.settings.maxPendingEnvelopes || limited( arguments.category ) ) { + variables.dropped++; + return new Receipt( eventId = arguments.eventId, state = "dropped" ); + } + try { + var permittedItems = arguments.items.filter( function( item ){ + return item.type != "attachment" || !limited( "attachment" ); + } ); + var bytes = encodeEnvelope( arguments.eventId, permittedItems ); + var future = variables.http.sendAsync( + variables.client, + variables.endpoint, + variables.auth, + bytes, + variables.settings.transportTimeout + ); + receipt = new Receipt( + arguments.eventId, + "queued", + future, + this, + arguments.category + ); + variables.pending.append( receipt ); + } catch ( any failure ) { + receipt = new Receipt( arguments.eventId, "failed" ); + } + } + if ( arguments.wait ) { + receipt.awaitDelivery( variables.settings.transportTimeout ); + } + return receipt; + } + function encodeEnvelope( required string eventId, required array items ){ + var output = createObject( "java", "java.io.ByteArrayOutputStream" ).init(); + output.write( + charsetDecode( + serializeJSON( { + "event_id" : arguments.eventId, + "sent_at" : createObject( "java", "java.time.Instant" ).now().toString() + } ) & chr( 10 ), + "UTF-8" + ) + ); + for ( var item in arguments.items ) { + var data = isBinary( item.payload ) ? item.payload : charsetDecode( + isSimpleValue( item.payload ) ? item.payload : serializeJSON( item.payload ), + "UTF-8" + ); + var header = { + "type" : item.type, + "length" : arrayLen( data ), + "content_type" : "application/json" + }; + header.append( item.headers ?: {}, true ); + if ( item.type == "log" || item.type == "trace_metric" ) { + header[ "item_count" ] = item.payload.items.len(); + header[ "content_type" ] = item.type == "log" ? "application/vnd.sentry.items.log+json" : "application/vnd.sentry.items.trace-metric+json"; + } + output.write( charsetDecode( serializeJSON( header ) & chr( 10 ), "UTF-8" ) ); + output.write( data ); + output.write( javacast( "int", 10 ) ); + } + return output.toByteArray(); + } + function observeResponse( required any response ){ + lock name="sentry-response-#variables.id#" type="exclusive" timeout="2" { + var code = getResponseStatusCode( arguments.response ); + var state = code >= 200 && code < 300 ? "accepted" : "rejected"; + variables.responses[ state ]++; + } + var rateHeader = variables.http + .headers( arguments.response ) + .firstValue( "X-Sentry-Rate-Limits" ) + .orElse( "" ); + for ( var entry in listToArray( rateHeader ) ) { + var parts = listToArray( entry, ":", true ); + if ( parts.len() >= 2 && isNumeric( parts[ 1 ] ) ) { + var categories = len( parts[ 2 ] ) ? listToArray( parts[ 2 ], ";" ) : [ "all" ]; + for ( var category in categories ) { + setLimit( category, val( parts[ 1 ] ) ); + } + } + } + if ( getResponseStatusCode( arguments.response ) == 429 && !len( rateHeader ) ) { + var retry = variables.http + .headers( arguments.response ) + .firstValue( "Retry-After" ) + .orElse( "60" ); + var seconds = isNumeric( retry ) ? val( retry ) : 60; + if ( !isNumeric( retry ) ) { + try { + seconds = max( + 0, + ( + createObject( "java", "java.time.ZonedDateTime" ) + .parse( + retry, + createObject( "java", "java.time.format.DateTimeFormatter" ).RFC_1123_DATE_TIME + ) + .toInstant() + .toEpochMilli() - epochMillis() + ) / 1000 + ); + } catch ( any ignored ) { + } + } + setLimit( "all", seconds ); + } + } + function getResponseStatusCode( required any response ){ + return variables.http.statusCode( arguments.response ); + } + function isDeliveryDone( required any future ){ + return variables.http.isDone( arguments.future ); + } + function awaitResponse( required any future, required numeric timeoutMilliseconds ){ + return variables.http.awaitResponse( arguments.future, arguments.timeoutMilliseconds ); + } + private function setLimit( required string category, required numeric seconds ){ + lock name="sentry-limits-#variables.id#" type="exclusive" timeout="2" { + variables.limits[ arguments.category ] = max( + variables.limits[ arguments.category ] ?: 0, + epochMillis() + arguments.seconds * 1000 + ); + } + } + private function limited( required string category ){ + var categories = { + "log" : "log_item", + "trace_metric" : "metric", + "check_in" : "monitor" + }; + arguments.category = categories[ arguments.category ] ?: arguments.category; + return ( variables.limits.all ?: 0 ) > epochMillis() || ( variables.limits[ arguments.category ] ?: 0 ) > epochMillis(); + } + private function reap(){ + for ( var i = variables.pending.len(); i >= 1; i-- ) { + if ( variables.pending[ i ].getStatus() != "queued" ) { + variables.pending.deleteAt( i ); + } + } + } + private function epochMillis(){ + return createObject( "java", "java.lang.System" ).currentTimeMillis(); + } + function flush( numeric timeoutMilliseconds = 2000 ){ + var deadline= epochMillis() + arguments.timeoutMilliseconds; + var snapshot= []; + lock name ="sentry-transport-#variables.id#" type="exclusive" timeout="2" { + if ( !variables.pending.isEmpty() ) { + snapshot = variables.pending.slice( 1 ); + } + } + for ( var receipt in snapshot ) { + receipt.awaitDelivery( max( 1, deadline - epochMillis() ) ); + } + return snapshot.isEmpty() || snapshot.every( function( receipt ){ + return receipt.getStatus() != "queued"; + } ); + } + function shutdown( numeric timeoutMilliseconds = 2000 ){ + variables[ "closed" ] = true; + var complete = flush( arguments.timeoutMilliseconds ); + variables.executor.shutdown(); + return complete; + } + function getDiagnostics(){ + lock name="sentry-transport-#variables.id#" type="exclusive" timeout="2" { + reap(); + return { + "pending" : variables.pending.len(), + "accepted" : variables.responses.accepted, + "rejected" : variables.responses.rejected, + "dropped" : variables.dropped, + "closed" : variables.closed + }; + } + } + +} diff --git a/models/telemetry/InstrumentedCache.cfc b/models/telemetry/InstrumentedCache.cfc new file mode 100644 index 0000000..6cb37c8 --- /dev/null +++ b/models/telemetry/InstrumentedCache.cfc @@ -0,0 +1,122 @@ +/** Delegates the complete provider surface; never inspects or serializes cached values. */ +component { + + function init( required any provider, required any telemetry ){ + variables[ "provider" ] = arguments.provider; + variables[ "telemetry" ] = arguments.telemetry; + return this; + } + function get( required any objectKey ){ + return read( "get", arguments ); + } + function getQuiet( required any objectKey ){ + return read( "getQuiet", arguments ); + } + function lookup( required any objectKey ){ + return read( "lookup", arguments, true ); + } + function lookupQuiet( required any objectKey ){ + return read( "lookupQuiet", arguments, true ); + } + private function read( + required string method, + required struct args, + boolean lookup = false + ){ + var providerMethod = arguments.method; + var params = arguments.args; + var isLookup = arguments.lookup; + return variables.telemetry.withSpan( + "cache read", + function( span ){ + var value = invoke( variables.provider, providerMethod, params ); + var hit = isLookup ? value : !isNull( value ); + span.setAttribute( "cache.hit", hit ); + variables.telemetry.counter( + "cache.read", + 1, + { "outcome" : hit ? "hit" : "miss" } + ); + return value; + }, + "cache.get", + { + "cache.key" : normalizeKey( params.objectKey ), + "cache.name" : variables.provider.getName() + } + ); + } + function set(){ + return mutate( "set", arguments, "cache.put" ); + } + function setQuiet(){ + return mutate( "setQuiet", arguments, "cache.put" ); + } + function clear(){ + return mutate( "clear", arguments, "cache.remove" ); + } + function clearQuiet(){ + return mutate( "clearQuiet", arguments, "cache.remove" ); + } + function clearAll(){ + return mutate( "clearAll", arguments, "cache.flush" ); + } + private function mutate( + required string method, + required struct args, + required string op + ){ + var providerMethod = arguments.method; + var params = arguments.args; + return variables.telemetry.withSpan( + "cache write", + function( span ){ + var result = invoke( variables.provider, providerMethod, params ); + span.setAttribute( "cache.write", true ); + return result; + }, + arguments.op, + { + "cache.key" : normalizeKey( params.objectKey ?: params[ "1" ] ?: "all" ), + "cache.name" : variables.provider.getName() + } + ); + } + function getOrSet( + required any objectKey, + required function produce, + any timeout, + any lastAccessTimeout, + struct extra = {} + ){ + var args = arguments; + return variables.telemetry.withSpan( + "cache getOrSet", + function( span ){ + var produced = false; + var callback = function(){ + produced = true; + return args.produce(); + }; + var params = structCopy( args ); + params[ "produce" ] = callback; + var result = invoke( variables.provider, "getOrSet", params ); + span.setAttribute( "cache.hit", !produced ); + return result; + }, + "cache.get", + { "cache.key" : normalizeKey( arguments.objectKey ) } + ); + } + private function normalizeKey( required any key ){ + return [ "sha256:" & left( lCase( hash( toString( arguments.key ), "SHA-256" ) ), 16 ) ]; + } + function onMissingMethod( required string missingMethodName, required struct missingMethodArguments ){ + return invoke( + variables.provider, + arguments.missingMethodName, + arguments.missingMethodArguments + ); + } + +} diff --git a/models/telemetry/JavaHttp.cfc b/models/telemetry/JavaHttp.cfc new file mode 100644 index 0000000..3ba45b6 --- /dev/null +++ b/models/telemetry/JavaHttp.cfc @@ -0,0 +1,157 @@ +/** Invoke exported HTTP interfaces; Adobe reflection cannot access JDK implementation classes. */ +component { + + function init(){ + variables.javaClass = createObject( "java", "java.lang.Class" ); + variables.methods = { + clientExecutor : resolve( + "java.net.http.HttpClient$Builder", + "executor", + [ "java.util.concurrent.Executor" ] + ), + clientTimeout : resolve( + "java.net.http.HttpClient$Builder", + "connectTimeout", + [ "java.time.Duration" ] + ), + clientBuild : resolve( "java.net.http.HttpClient$Builder", "build" ), + requestTimeout : resolve( + "java.net.http.HttpRequest$Builder", + "timeout", + [ "java.time.Duration" ] + ), + requestHeader : resolve( + "java.net.http.HttpRequest$Builder", + "header", + [ "java.lang.String", "java.lang.String" ] + ), + requestPost : resolve( + "java.net.http.HttpRequest$Builder", + "POST", + [ "java.net.http.HttpRequest$BodyPublisher" ] + ), + requestBuild : resolve( "java.net.http.HttpRequest$Builder", "build" ), + sendAsync : resolve( + "java.net.http.HttpClient", + "sendAsync", + [ + "java.net.http.HttpRequest", + "java.net.http.HttpResponse$BodyHandler" + ] + ), + statusCode : resolve( "java.net.http.HttpResponse", "statusCode" ), + headers : resolve( "java.net.http.HttpResponse", "headers" ), + futureDone : resolve( "java.util.concurrent.Future", "isDone" ), + futureGet : resolve( + "java.util.concurrent.Future", + "get", + [ "long", "java.util.concurrent.TimeUnit" ] + ) + }; + return this; + } + private function resolve( + required string owner, + required string methodName, + array types = [] + ){ + var parameterClasses = arguments.types.map( function( type ){ + if ( type == "long" ) { + return createObject( "java", "java.lang.Long" ).TYPE; + } + return variables.javaClass.forName( type ); + } ); + return variables.javaClass + .forName( arguments.owner ) + .getMethod( arguments.methodName, javacast( "java.lang.Class[]", parameterClasses ) ); + } + private function call( + required string methodName, + required any target, + array args = [] + ){ + return variables.methods[ arguments.methodName ].invoke( + arguments.target, + javacast( "java.lang.Object[]", arguments.args ) + ); + } + private function duration( required numeric milliseconds ){ + return createObject( "java", "java.time.Duration" ).ofMillis( javacast( "long", arguments.milliseconds ) ); + } + function createClient( required any executor, required numeric timeoutMilliseconds ){ + var builder = createObject( "java", "java.net.http.HttpClient" ).newBuilder(); + call( + "clientExecutor", + builder, + [ arguments.executor ] + ); + call( + "clientTimeout", + builder, + [ duration( arguments.timeoutMilliseconds ) ] + ); + return call( "clientBuild", builder ); + } + function sendAsync( + required any client, + required string url, + required string auth, + required any bytes, + required numeric timeoutMilliseconds + ){ + var builder = createObject( "java", "java.net.http.HttpRequest" ).newBuilder( + createObject( "java", "java.net.URI" ).create( arguments.url ) + ); + call( + "requestTimeout", + builder, + [ duration( arguments.timeoutMilliseconds ) ] + ); + call( + "requestHeader", + builder, + [ "X-Sentry-Auth", arguments.auth ] + ); + call( + "requestHeader", + builder, + [ + "Content-Type", + "application/x-sentry-envelope" + ] + ); + call( + "requestPost", + builder, + [ createObject( "java", "java.net.http.HttpRequest$BodyPublishers" ).ofByteArray( arguments.bytes ) ] + ); + return call( + "sendAsync", + arguments.client, + [ + call( "requestBuild", builder ), + createObject( "java", "java.net.http.HttpResponse$BodyHandlers" ).discarding() + ] + ); + } + function statusCode( required any response ){ + return call( "statusCode", arguments.response ); + } + function headers( required any response ){ + return call( "headers", arguments.response ); + } + function isDone( required any future ){ + return call( "futureDone", arguments.future ); + } + function awaitResponse( required any future, required numeric timeoutMilliseconds ){ + return call( + "futureGet", + arguments.future, + [ + javacast( "long", arguments.timeoutMilliseconds ), + createObject( "java", "java.util.concurrent.TimeUnit" ).MILLISECONDS + ] + ); + } + +} diff --git a/models/telemetry/LuceeQueryListener.cfc b/models/telemetry/LuceeQueryListener.cfc new file mode 100644 index 0000000..ddd5ad2 --- /dev/null +++ b/models/telemetry/LuceeQueryListener.cfc @@ -0,0 +1,109 @@ +/** Install on Lucee 6+ as this.query.listener. Wraps an existing listener without changing its return contract. */ +component { + + function init( + required any telemetry, + any listener, + string databaseSystem = "other" + ){ + variables.telemetry = arguments.telemetry; + variables.listener = arguments.listener ?: {}; + variables.databaseSystem = arguments.databaseSystem; + variables.executions = createObject( "java", "java.lang.ThreadLocal" ).init(); + return this; + } + function before( caller, args ){ + var result = delegate( "before", arguments ) ?: {}; + try { + // Lucee applies the returned args after this callback; observe that transformed SQL. + var sql = result.args.sql ?: result.sql ?: arguments.args.sql ?: ""; + var stack = variables.executions.get() ?: []; + if ( variables.telemetry.getScope().keyExists( "manualQuerySpan" ) ) { + stack.append( { "manual" : true } ); + variables.executions.set( stack ); + return result; + } + var span = variables.telemetry.startSpan( + variables.telemetry.scrubSQL( sql ), + "db.query", + { + "db.system" : variables.databaseSystem, + "db.operation" : uCase( listFirst( trim( sql ), " " ) ) + } + ); + stack.append( span ); + variables.executions.set( stack ); + } catch ( any ignored ) { + } + return result; + } + function after( caller, args, result, meta ){ + complete( + "ok", + arguments.meta ?: {}, + arguments.args ?: {}, + arguments.result ?: javacast( "null", "" ) + ); + return delegate( "after", arguments ); + } + function error( args, caller, meta, exception ){ + complete( "internal_error" ); + if ( structKeyExists( variables.listener, "error" ) ) { + return delegate( "error", arguments ); + } + // Lucee treats an installed error callback as handling the failure. + throw( object = arguments.exception ); + } + private function complete( + required string status, + struct meta = {}, + struct args = {}, + any queryResult + ){ + try { + var stack = variables.executions.get() ?: []; + if ( stack.len() ) { + var span = stack[ stack.len() ]; + stack.deleteAt( stack.len() ); + if ( structKeyExists( span, "manual" ) ) { + if ( !stack.len() ) { + variables.executions.remove(); + } + return; + } + var cached = arguments.meta.cached ?: "unknown"; + if ( !arguments.meta.keyExists( "cached" ) && !isNull( arguments.queryResult ) ) { + try { + cached = arguments.queryResult.isCached(); + } catch ( any unavailable ) { + } + } + if ( isBoolean( cached ) ) { + span.setAttribute( "db.cached", cached ); + } else { + span.setAttribute( "db.cache_status", "unknown" ); + } + span.setAttribute( "db.query_of_queries", ( arguments.args.dbtype ?: "" ) == "query" ); + if ( isNumeric( arguments.meta.executionTime ?: "" ) ) { + span.setAttribute( "db.execution.duration", arguments.meta.executionTime ); + } + span.finish( arguments.status ); + } + if ( !stack.len() ) { + variables.executions.remove(); + } + } catch ( any ignored ) { + } + } + private function delegate( required string method, required struct args ){ + if ( structKeyExists( variables.listener, arguments.method ) ) { + return invoke( + variables.listener, + arguments.method, + arguments.args + ); + } + return javacast( "null", "" ); + } + +} diff --git a/models/telemetry/Observability.cfc b/models/telemetry/Observability.cfc new file mode 100644 index 0000000..60797e2 --- /dev/null +++ b/models/telemetry/Observability.cfc @@ -0,0 +1,902 @@ +/** Framework-independent telemetry; execution scopes are never kept on a singleton. */ +component { + + function init( required any owner, required struct settings ){ + variables[ "owner" ] = arguments.owner; + variables[ "settings" ] = arguments.settings; + variables.settings.append( defaults(), false ); + variables[ "scope" ] = createObject( "java", "java.lang.ThreadLocal" ).init(); + variables[ "completionFailures" ] = createObject( "java", "java.util.concurrent.atomic.AtomicLong" ).init( + 0 + ); + variables[ "sequence" ] = createObject( "java", "java.util.concurrent.atomic.AtomicLong" ).init( 0 ); + variables[ "transport" ] = new EnvelopeTransport( + variables.settings, + owner.getSentryUrl() & "/api/" & owner.getProjectID() & "/envelope/", + "Sentry sentry_version=7,sentry_key=" & owner.getPublicKey() & ",sentry_client=sentry.cfml/3.0.0", + owner.getEnabled() + ); + variables[ "buffers" ] = { "log" : [], "trace_metric" : [] }; + variables[ "bufferId" ] = createUUID(); + if ( variables.settings.enableLogs || variables.settings.enableMetrics ) { + variables.flusher = createObject( "java", "java.util.concurrent.Executors" ).newSingleThreadScheduledExecutor(); + variables.flusher.scheduleWithFixedDelay( + createDynamicProxy( new SignalFlusher( this ), [ "java.lang.Runnable" ] ), + javacast( "long", 5 ), + javacast( "long", 5 ), + createObject( "java", "java.util.concurrent.TimeUnit" ).SECONDS + ); + } + return this; + } + function defaults(){ + return { + "tracesSampleRate" : 0, + "maxSpans" : 1000, + "transportTimeout" : 2000, + "maxPendingEnvelopes" : 64, + "enableRequestTracing" : false, + "queryAdapter" : "none", + "enableQueueTracing" : false, + "enableLogs" : false, + "enableStructuredLogBoxAppender" : false, + "logMessageMode" : "sanitized", + "enableMetrics" : false, + "enableMonitors" : false, + "monitorSlugs" : [], + "beforeSendSignal" : "", + "beforeSendFeedback" : "", + "tracePropagationTargets" : [], + "browser" : {}, + "trustIncomingTrace" : false, + "requestFilter" : "", + "attributeFilter" : "" + }; + } + function registerBoxLangQueries( required string applicationName, string databaseSystem = "other" ){ + var runtime = createObject( "java", "ortus.boxlang.runtime.BoxRuntime" ).getInstance(); + var listener = new BoxLangQueryListener( + this, + arguments.applicationName, + arguments.databaseSystem + ); + runtime.getInterceptorService().register( listener ); + variables.nativeQueryListener = listener; + return listener; + } + function configureQueryInstrumentation( required string applicationName ){ + if ( variables.settings.queryAdapter == "auto" || variables.settings.queryAdapter == "boxlang" ) { + try { + // Partial native listeners cannot close caught direct-query failures. Prefer complete fallback. + createObject( "java", "ortus.boxlang.runtime.events.BoxEvent" ).valueOf( "ON_QUERY_EXECUTE_ERROR" ); + registerBoxLangQueries( arguments.applicationName, variables.settings.databaseSystem ?: "other" ); + variables.settings.queryAdapter = "boxlang"; + } catch ( any unavailable ) { + variables.settings.queryAdapter = "qb"; + } + } + return variables.settings.queryAdapter; + } + function percentageEligible( + required string key, + required string opaqueId, + required numeric percentage + ){ + if ( !len( arguments.opaqueId ) || arguments.percentage <= 0 ) { + return false; + } + if ( arguments.percentage >= 100 ) { + return true; + } + var prefix = left( hash( arguments.key & ":" & lCase( arguments.opaqueId ), "SHA-256" ), 8 ); + return ( inputBaseN( prefix, 16 ) % 100 ) + 1 <= arguments.percentage; + } + function getMaxSpans(){ + return variables.settings.maxSpans; + } + function timestamp(){ + return createObject( "java", "java.lang.System" ).currentTimeMillis() / 1000; + } + function id(){ + return lCase( replace( createUUID(), "-", "", "all" ) ); + } + function responseStatus(){ + try { + return getPageContext().getResponse().getStatus(); + } catch ( any ignored ) { + } + try { + return getBoxContext().getResponse().getStatus(); + } catch ( any ignored ) { + } + return 200; + } + function endRequest( numeric statusCode = 0 ){ + var current = getScope(); + if ( !current.keyExists( "requestState" ) ) { + return; + } + var span = current.requestState.span; + try { + if ( !span.isFinished() ) { + var code = arguments.statusCode > 0 ? arguments.statusCode : responseStatus(); + span.setAttribute( "http.response.status_code", code ); + if ( code >= 500 ) { + span.setStatus( "internal_error" ); + } + counter( + "http.server.requests", + 1, + { + "route" : span.toPayload().description, + "http.response.status_code" : code + } + ); + distribution( + "http.server.duration", + max( 0, timestamp() - span.toPayload().start_timestamp ) * 1000, + { "route" : span.toPayload().description }, + "millisecond" + ); + span.finish(); + flushSignals(); + } + } finally { + setScope( current.requestState.previous ); + } + } + function getScope(){ + return variables.scope.get() ?: {}; + } + function setScope( required struct scope ){ + variables.scope.set( arguments.scope ); + } + function clearScope(){ + variables.scope.remove(); + } + function startTransaction( + required string name, + string op = "http.server", + struct headers = {}, + boolean trusted = false + ){ + var parent = arguments.trusted ? parseHeaders( arguments.headers ) : {}; + var sampled = variables.owner.getEnabled() && ( + parent.keyExists( "sampled" ) ? parent.sampled : rand() < variables.settings.tracesSampleRate + ); + var data = { + "trace_id" : parent.trace_id ?: id(), + "span_id" : left( id(), 16 ), + "op" : arguments.op, + "description" : safeName( arguments.name ), + "start_timestamp" : timestamp(), + "status" : "ok", + "data" : {} + }; + if ( parent.keyExists( "parent_span_id" ) ) { + data[ "parent_span_id" ] = parent.parent_span_id; + } + return new Span( this, data, sampled ).setBaggage( parent.baggage ?: "" ); + } + function startSpan( + required string name, + string op = "function", + struct attributes = {} + ){ + var current = getScope(); + if ( !current.keyExists( "span" ) || current.span.isFinished() ) { + return new Span( + this, + { + "trace_id" : id(), + "span_id" : left( id(), 16 ), + "op" : arguments.op, + "description" : arguments.op == "db.query" ? scrubSQL( arguments.name ) : safeName( + arguments.name + ), + "start_timestamp" : timestamp(), + "data" : {}, + "status" : "ok" + }, + false + ); + } + var parent = current.span.getContext(); + return new Span( + this, + { + "trace_id" : parent.trace_id, + "span_id" : left( id(), 16 ), + "parent_span_id" : parent.span_id, + "op" : arguments.op, + "description" : arguments.op == "db.query" ? scrubSQL( arguments.name ) : safeName( + arguments.name + ), + "start_timestamp" : timestamp(), + "status" : "ok", + "data" : sanitizeAttributes( arguments.attributes ) + }, + current.span.isSampled(), + current.span.getRoot() + ); + } + function withSpan( + required string name, + required function callback, + string op = "function", + struct attributes = {} + ){ + var previous = getScope(); + var span = startSpan( + arguments.name, + arguments.op, + arguments.attributes + ); + var next = structCopy( previous ); + next[ "span" ] = span; + setScope( next ); + try { + return arguments.callback( span ); + } catch ( any failure ) { + span.setStatus( "internal_error" ); + rethrow; + } finally { + setScope( previous ); + finishSafely( span ); + } + } + function withTraceContext( + required struct context, + required function callback, + string name = "background", + string op = "task" + ){ + var previous = getScope(); + var span = startTransaction( + arguments.name, + arguments.op, + arguments.context, + true + ); + setScope( { "span" : span } ); + try { + return arguments.callback( span ); + } catch ( any failure ) { + span.setStatus( "internal_error" ); + rethrow; + } finally { + setScope( previous ); + finishSafely( span ); + } + } + private function finishSafely( required any span ){ + try { + arguments.span.finish(); + } catch ( any unavailable ) { + variables.completionFailures.incrementAndGet(); + } + } + function getCompletionFailureCount(){ + return variables.completionFailures.get(); + } + function getTraceHeaders( string url = "" ){ + if ( len( arguments.url ) && !isPropagationTarget( arguments.url ) ) { + return {}; + } + var current = getScope(); + if ( !current.keyExists( "span" ) ) { + return {}; + } + var context = current.span.getContext(); + var baggage = current.span.getBaggage(); + if ( !find( "sentry-public_key=", baggage ) ) { + baggage = listAppend( baggage, "sentry-public_key=" & variables.owner.getPublicKey() ); + } + return { + "sentry-trace" : context.trace_id & "-" & context.span_id & "-" & ( context.sampled ? "1" : "0" ), + "baggage" : baggage & ",sentry-trace_id=" & context.trace_id & ",sentry-sampled=" & ( + context.sampled ? "true" : "false" + ) + }; + } + function parseHeaders( required struct headers ){ + var trace = headers[ "sentry-trace" ] ?: ""; + if ( + !reFindNoCase( "^[a-f0-9]{32}-[a-f0-9]{16}(-[01])?$", trace ) || reFind( + "^0{32}-|^[^-]+-0{16}", + trace + ) + ) { + return {}; + } + var parts = listToArray( trace, "-" ); + var result = { + "trace_id" : lCase( parts[ 1 ] ), + "parent_span_id" : lCase( parts[ 2 ] ) + }; + if ( parts.len() == 3 ) { + result[ "sampled" ] = parts[ 3 ] == "1"; + } + var members = []; + for ( var member in listToArray( left( arguments.headers[ "baggage" ] ?: "", 8192 ) ) ) { + // Carry trusted, technical dynamic sampling context only; never a raw transaction/user label. + if ( + reFind( + "^sentry-(public_key|release|environment|sample_rate|sample_rand)=[A-Za-z0-9._%+-]{1,256}$", + trim( member ) + ) + ) { + members.append( trim( member ) ); + } + } + result[ "baggage" ] = members.toList(); + return result; + } + function getTraceContext(){ + var current = getScope(); + return current.keyExists( "span" ) ? current.span.getContext() : {}; + } + function completeTransaction( required any transaction ){ + try { + var data = arguments.transaction.toPayload(); + var event = baseEvent(); + event[ "type" ] = "transaction"; + event[ "transaction" ] = data.description; + event[ "start_timestamp" ] = data.start_timestamp; + event[ "timestamp" ] = data.timestamp; + event[ "contexts" ] = { + "trace" : { + "trace_id" : data.trace_id, + "span_id" : data.span_id, + "op" : data.op, + "status" : data.status, + "data" : data.data + } + }; + if ( data.keyExists( "parent_span_id" ) ) { + event.contexts.trace[ "parent_span_id" ] = data.parent_span_id; + } + event[ "spans" ] = []; + for ( var child in arguments.transaction.getChildren() ) { + if ( event.spans.len() < variables.settings.maxSpans ) { + event.spans.append( child.toPayload() ); + } + } + sendSignal( "transaction", event, "transaction" ); + } catch ( any ignored ) { + } + } + function baseEvent(){ + return { + "event_id" : id(), + "timestamp" : timestamp(), + "platform" : "cfml", + "release" : variables.settings.release, + "environment" : variables.settings.environment + }; + } + function sendSignal( + required string type, + required struct payload, + required string category, + array attachments = [], + boolean wait = false + ){ + var data = arguments.payload; + try { + var filter = arguments.type == "feedback" ? variables.settings.beforeSendFeedback : variables.settings.beforeSendSignal; + if ( isCustomFunction( filter ) ) { + data = filter( data, arguments.type ); + if ( isNull( data ) ) { + return new Receipt( arguments.payload.event_id ?: id(), "filtered" ); + } + } + var items = [ { "type" : arguments.type, "payload" : data } ]; + for ( var attachment in arguments.attachments ) { + if ( !isBinary( attachment.data ) || arrayLen( attachment.data ) > 2097152 ) { + return new Receipt( data.event_id ?: id(), "invalid" ); + } + items.append( { + "type" : "attachment", + "payload" : attachment.data, + "headers" : { + "filename" : reReplace( + attachment.filename ?: "attachment.bin", + "[^a-zA-Z0-9._-]", + "_", + "all" + ), + "content_type" : attachment.contentType ?: "application/octet-stream" + } + } ); + } + return variables.transport.send( + data.event_id ?: id(), + items, + arguments.category, + arguments.wait + ); + } catch ( any ignored ) { + return new Receipt( arguments.payload.event_id ?: id(), "failed" ); + } + } + function captureFeedback( + required string message, + string page = "", + string associatedEventId = "", + string replayId = "", + array attachments = [], + boolean wait = false + ){ + var data = baseEvent(); + data[ "type" ] = "feedback"; + data[ "level" ] = "info"; + data[ "contexts" ] = { + "feedback" : { + "message" : trim( arguments.message ), + "url" : safePageURL( arguments.page ) + } + }; + if ( len( arguments.associatedEventId ) ) { + if ( !reFindNoCase( "^[a-f0-9]{32}$", arguments.associatedEventId ) ) { + return new Receipt( data.event_id, "invalid" ); + } + data.contexts.feedback[ "associated_event_id" ] = arguments.associatedEventId; + } + if ( len( arguments.replayId ) ) { + if ( !reFindNoCase( "^[a-f0-9]{32}$", arguments.replayId ) ) { + return new Receipt( data.event_id, "invalid" ); + } + data.contexts.feedback[ "replay_id" ] = arguments.replayId; + } + var context = getTraceContext(); + if ( !context.isEmpty() ) { + data.contexts[ "trace" ] = context; + } + if ( + !len( data.contexts.feedback.message ) || createObject( "java", "java.lang.String" ) + .init( data.contexts.feedback.message ) + .codePointCount( 0, len( data.contexts.feedback.message ) ) > 4096 + ) { + return new Receipt( data.event_id, "invalid" ); + } + return sendSignal( + "feedback", + data, + "user_report", + arguments.attachments, + arguments.wait + ); + } + function withQuerySpan( + required string sql, + required function callback, + string databaseSystem = "other", + boolean cached = false, + boolean queryOfQueries = false + ){ + var queryCallback = arguments.callback; + return withSpan( + scrubSQL( arguments.sql ), + function( span ){ + var previous = getScope(); + var next = structCopy( previous ); + next.manualQuerySpan = span; + setScope( next ); + try { + return queryCallback( span ); + } finally { + setScope( previous ); + } + }, + arguments.queryOfQueries ? "db.query.qoq" : ( arguments.cached ? "db.query.cache" : "db.query" ), + { + "db.system" : arguments.databaseSystem, + "db.operation" : uCase( listFirst( trim( arguments.sql ), " " ) ), + "db.cached" : arguments.cached + } + ); + } + function withHttpSpan( + required string url, + required function callback, + string method = "GET" + ){ + var destination = safeURL( arguments.url ); + var headers = getTraceHeaders( arguments.url ); + var httpCallback = arguments.callback; + return withSpan( + arguments.method & " " & destination, + function( span ){ + return httpCallback( span, headers ); + }, + "http.client", + { + "http.request.method" : arguments.method, + "server.address" : destination + } + ); + } + function isPropagationTarget( required string url ){ + try { + var destination = createObject( "java", "java.net.URI" ).create( arguments.url ); + for ( var target in variables.settings.tracePropagationTargets ) { + var trusted = createObject( "java", "java.net.URI" ).create( target ); + if ( + destination.getScheme() == trusted.getScheme() && destination.getHost() == trusted.getHost() && destination.getPort() == trusted.getPort() && isNull( + destination.getUserInfo() + ) + ) { + return true; + } + } + } catch ( any ignored ) { + } + return false; + } + function captureLog( + required string message, + string level = "info", + struct attributes = {} + ){ + if ( !variables.settings.enableLogs ) { + return; + } + var levels = { + "info" : 9, + "warn" : 13, + "warning" : 13, + "error" : 17, + "fatal" : 21 + }; + if ( !levels.keyExists( lCase( arguments.level ) ) ) { + return; + } + var data = { + "timestamp" : timestamp(), + "level" : lCase( arguments.level ), + "severity_number" : levels[ lCase( arguments.level ) ], + "body" : sanitizeText( arguments.message ), + "attributes" : typedAttributes( arguments.attributes ) + }; + var context = getTraceContext(); + data[ "trace_id" ] = context.trace_id ?: id(); + if ( context.keyExists( "span_id" ) ) { + data[ "span_id" ] = context.span_id; + } + bufferSignal( "log", data ); + } + function counter( + required string name, + numeric value = 1, + struct attributes = {}, + string unit = "none" + ){ + metric( type = "counter", argumentCollection = arguments ); + } + function gauge( + required string name, + required numeric value, + struct attributes = {}, + string unit = "none" + ){ + metric( type = "gauge", argumentCollection = arguments ); + } + function distribution( + required string name, + required numeric value, + struct attributes = {}, + string unit = "none" + ){ + metric( type = "distribution", argumentCollection = arguments ); + } + private function metric( + required string type, + required string name, + required numeric value, + struct attributes = {}, + string unit = "none" + ){ + if ( !variables.settings.enableMetrics ) { + return; + } + var attrs = typedAttributes( arguments.attributes ); + attrs[ "sentry.timestamp.sequence" ] = { + "type" : "integer", + "value" : variables.sequence.getAndIncrement() + }; + var data = { + "timestamp" : timestamp(), + "name" : safeName( arguments.name ), + "value" : arguments.value, + "type" : arguments.type, + "unit" : arguments.unit, + "attributes" : attrs + }; + var context = getTraceContext(); + data[ "trace_id" ] = context.trace_id ?: id(); + if ( context.keyExists( "span_id" ) ) { + data[ "span_id" ] = context.span_id; + } + bufferSignal( "trace_metric", data ); + } + private function bufferSignal( required string type, required struct entry ){ + lock name="sentry-buffer-#variables.bufferId#" type="exclusive" timeout="2" { + variables.buffers[ arguments.type ].append( arguments.entry ); + if ( variables.buffers[ arguments.type ].len() >= 100 ) { + flushSignals(); + } + } + } + function flushSignals(){ + lock name="sentry-buffer-#variables.bufferId#" type="exclusive" timeout="2" { + for ( var type in variables.buffers ) { + if ( !variables.buffers[ type ].isEmpty() ) { + var items = variables.buffers[ type ]; + variables.buffers[ type ] = []; + sendSignal( + type, + { "items" : items }, + type == "log" ? "log_item" : "metric" + ); + } + } + } + } + function captureCheckIn( + required string slug, + required string status, + string checkInId = "", + numeric duration = 0, + struct monitorConfig = {} + ){ + var checkId = len( arguments.checkInId ) ? arguments.checkInId : id(); + if ( + !variables.settings.enableMonitors || ( + variables.settings.monitorSlugs.len() && !variables.settings.monitorSlugs.find( arguments.slug ) + ) + ) { + return checkId; + } + var data = { + "check_in_id" : checkId, + "monitor_slug" : arguments.slug, + "status" : arguments.status, + "environment" : variables.settings.environment, + "release" : variables.settings.release, + "duration" : arguments.duration + }; + if ( !arguments.monitorConfig.isEmpty() ) { + data[ "monitor_config" ] = arguments.monitorConfig; + } + sendSignal( "check_in", data, "monitor" ); + return checkId; + } + function withMonitor( + required string slug, + required function callback, + struct monitorConfig = {} + ){ + var checkId = captureCheckIn( + arguments.slug, + "in_progress", + "", + 0, + arguments.monitorConfig + ); + var started = timestamp(); + try { + var result = arguments.callback(); + captureCheckIn( + arguments.slug, + "ok", + checkId, + timestamp() - started + ); + return result; + } catch ( any failure ) { + captureCheckIn( + arguments.slug, + "error", + checkId, + timestamp() - started + ); + rethrow; + } + } + function captureQueueMetrics( + required string destination, + required numeric depth, + required numeric oldestAgeSeconds + ){ + gauge( + "queue.depth", + max( 0, arguments.depth ), + { "messaging.destination.name" : safeName( arguments.destination ) } + ); + gauge( + "queue.oldest_age", + max( 0, arguments.oldestAgeSeconds ), + { "messaging.destination.name" : safeName( arguments.destination ) }, + "second" + ); + } + function captureRuntimeGauges(){ + var memory = createObject( "java", "java.lang.management.ManagementFactory" ) + .getMemoryMXBean() + .getHeapMemoryUsage(); + gauge( "jvm.heap.used", memory.getUsed(), {}, "byte" ); + gauge( + "jvm.threads", + createObject( "java", "java.lang.management.ManagementFactory" ).getThreadMXBean().getThreadCount() + ); + } + function getBrowserConfig(){ + var browser = variables.settings.browser; + return { + "dsn" : browser.dsn ?: "", + "environment" : variables.settings.environment, + "release" : variables.settings.release, + "tracesSampleRate" : browser.tracesSampleRate ?: variables.settings.tracesSampleRate, + "tracePropagationTargets" : variables.settings.tracePropagationTargets, + "enabled" : browser.enabled ?: false, + "localVerification" : browser.localVerification ?: false, + "replaysSessionSampleRate" : 0, + "replaysOnErrorSampleRate" : 0 + }; + } + function sanitizeAttributes( required struct attributes ){ + var result = {}; + for ( var key in arguments.attributes ) { + // Sentry's cache convention uses an array. Keep this exception narrow: + // arbitrary structures, bindings and cached values remain excluded. + if ( key == "cache.key" && isArray( arguments.attributes[ key ] ) ) { + var keys = []; + for ( var item in arguments.attributes[ key ] ) { + if ( !isSimpleValue( item ) || keys.len() >= 100 ) { + continue; + } + keys.append( sanitizeText( left( toString( item ), 512 ) ) ); + } + result[ key ] = keys; + continue; + } + if ( + reFindNoCase( + "password|token|secret|authorization|cookie|binding|payload|body|email|username|card|bank|result", + key + ) || !isSimpleValue( arguments.attributes[ key ] ) + ) { + continue; + } + var value = arguments.attributes[ key ]; + result[ left( key, 128 ) ] = isNumeric( value ) || isBoolean( value ) ? value : sanitizeText( + left( toString( value ), 512 ) + ); + } + if ( isCustomFunction( variables.settings.attributeFilter ) ) { + try { + return variables.settings.attributeFilter( result ); + } catch ( any ignored ) { + return {}; + } + } + return result; + } + private function typedAttributes( required struct attributes ){ + var result = {}; + var safe = sanitizeAttributes( arguments.attributes ); + safe[ "sentry.environment" ] = variables.settings.environment; + safe[ "sentry.release" ] = variables.settings.release; + for ( var key in safe ) { + // Logs and trace metrics have scalar typed attributes only. + if ( !isSimpleValue( safe[ key ] ) ) { + continue; + } + result[ key ] = { + "type" : isBoolean( safe[ key ] ) && !isNumeric( safe[ key ] ) ? "boolean" : ( + isNumeric( safe[ key ] ) ? "double" : "string" + ), + "value" : safe[ key ] + }; + } + return result; + } + function sanitizeText( required string text ){ + return reReplaceNoCase( + arguments.text, + "(password|token|secret|authorization|cookie|api[_-]?key)\s*[:=]\s*\S+", + "\1=[Filtered]", + "all" + ); + } + function safeName( required string name ){ + var sanitizedName = reReplaceNoCase( + arguments.name, + "[a-f0-9]{8}-[a-f0-9-]{27,}|/[0-9]+(?=/|$)", + "/:id", + "all" + ); + return left( + reReplace( + listFirst( listFirst( sanitizedName, "?" ), "##" ), + "[\r\n]", + "", + "all" + ), + 256 + ); + } + function safePageURL( required string url ){ + try { + var uri = createObject( "java", "java.net.URI" ).create( arguments.url ); + var path = uri.getPath() ?: "/"; + if ( reFindNoCase( "token|password|payment|checkout|invite|kiosk|login|reset", path ) ) { + path = "/[private-page]"; + } + return safeURL( arguments.url ) & safeName( path ); + } catch ( any ignored ) { + return ""; + } + } + function safeURL( required string url ){ + try { + var uri = createObject( "java", "java.net.URI" ).create( arguments.url ); + if ( isNull( uri.getHost() ) || !listFindNoCase( "http,https", uri.getScheme() ?: "" ) ) { + return ""; + } + return uri.getScheme() & "://" & uri.getHost() & ( uri.getPort() > 0 ? ":" & uri.getPort() : "" ); + } catch ( any ignored ) { + return ""; + } + } + function scrubSQL( required string sql ){ + // Unsupported quoting is discarded rather than risking exporting literals. + if ( find( "$", arguments.sql ) || find( "`", arguments.sql ) || find( "\\", arguments.sql ) ) { + return uCase( listFirst( trim( arguments.sql ), " " ) ) & " [Filtered]"; + } + var scrubbed = reReplace( + arguments.sql, + "(?s)/\*.*?\*/|--[^\r\n]*", + " ", + "all" + ); + scrubbed = reReplace( + scrubbed, + "'([^']|'')*'|""([^""]|"""")*""", + "?", + "all" + ); + scrubbed = reReplace( scrubbed, "\b[0-9]+(\.[0-9]+)?\b", "?", "all" ); + if ( find( "'", scrubbed ) || find( """", scrubbed ) ) { + return "[Filtered SQL]"; + } + return left( reReplace( scrubbed, "\s+", " ", "all" ), 1024 ); + } + function getTransport(){ + return variables.transport; + } + function flush( numeric timeoutMilliseconds = 2000 ){ + flushSignals(); + return variables.transport.flush( arguments.timeoutMilliseconds ); + } + function shutdown( numeric timeoutMilliseconds = 2000 ){ + if ( !isNull( variables.nativeQueryListener ) ) { + createObject( "java", "ortus.boxlang.runtime.BoxRuntime" ) + .getInstance() + .getInterceptorService() + .unregister( + createObject( "java", "ortus.boxlang.runtime.interop.DynamicObject" ).of( + variables.nativeQueryListener + ) + ); + } + if ( !isNull( variables.flusher ) ) { + variables.flusher.shutdown(); + } + flushSignals(); + clearScope(); + return variables.transport.shutdown( arguments.timeoutMilliseconds ); + } + +} diff --git a/models/telemetry/Receipt.cfc b/models/telemetry/Receipt.cfc new file mode 100644 index 0000000..74494d0 --- /dev/null +++ b/models/telemetry/Receipt.cfc @@ -0,0 +1,56 @@ +/** Delivery acknowledgement. HTTP acceptance is distinct from enqueueing. */ +component { + + function init( + required string eventId, + string state = "queued", + any future, + any transport, + string category = "error" + ){ + variables[ "id" ] = arguments.eventId; + variables[ "state" ] = arguments.state; + variables[ "future" ] = arguments.future ?: javacast( "null", "" ); + variables[ "transport" ] = arguments.transport ?: javacast( "null", "" ); + variables[ "category" ] = arguments.category; + variables[ "code" ] = 0; + variables[ "observed" ] = createObject( "java", "java.util.concurrent.atomic.AtomicBoolean" ).init( false ); + return this; + } + function getEventId(){ + return variables.id; + } + function getStatus(){ + if ( variables.state == "queued" && variables.transport.isDeliveryDone( variables.future ) ) { + awaitDelivery( 1 ); + } + return variables.state; + } + function getStatusCode(){ + getStatus(); + return variables.code; + } + function isAccepted(){ + return getStatus() == "accepted"; + } + function awaitDelivery( numeric timeoutMilliseconds = 2000 ){ + if ( variables.state != "queued" ) { + return this; + } + try { + var response = variables.transport.awaitResponse( variables.future, arguments.timeoutMilliseconds ); + variables[ "code" ] = variables.transport.getResponseStatusCode( response ); + variables[ "state" ] = variables.code >= 200 && variables.code < 300 ? "accepted" : "rejected"; + if ( variables.observed.compareAndSet( false, true ) ) { + variables.transport.observeResponse( response ); + } + } catch ( any failure ) { + // A wait timeout leaves the request pending; network failures complete it. + if ( variables.transport.isDeliveryDone( variables.future ) ) { + variables[ "state" ] = "failed"; + } + } + return this; + } + +} diff --git a/models/telemetry/SignalFlusher.cfc b/models/telemetry/SignalFlusher.cfc new file mode 100644 index 0000000..8cdd95d --- /dev/null +++ b/models/telemetry/SignalFlusher.cfc @@ -0,0 +1,14 @@ +component { + + function init( required any telemetry ){ + variables.telemetry = arguments.telemetry; + return this; + } + function run(){ + try { + variables.telemetry.flushSignals(); + } catch ( any ignored ) { + } + } + +} diff --git a/models/telemetry/Span.cfc b/models/telemetry/Span.cfc new file mode 100644 index 0000000..f50a6c3 --- /dev/null +++ b/models/telemetry/Span.cfc @@ -0,0 +1,112 @@ +/** A handle may be completed from any thread. Only the first completion wins. */ +component { + + function init( + required any telemetry, + required struct data, + boolean sampled = false, + any root + ){ + variables[ "baggage" ] = ""; + variables[ "telemetry" ] = arguments.telemetry; + variables[ "data" ] = arguments.data; + variables[ "sampled" ] = arguments.sampled; + variables[ "isRoot" ] = isNull( arguments.root ); + variables[ "root" ] = arguments.root ?: this; + variables[ "done" ] = createObject( "java", "java.util.concurrent.atomic.AtomicBoolean" ).init( false ); + variables[ "children" ] = createObject( "java", "java.util.concurrent.ConcurrentLinkedQueue" ).init(); + variables[ "id" ] = createUUID(); + return this; + } + function getContext(){ + return { + "trace_id" : variables.data.trace_id, + "span_id" : variables.data.span_id, + "sampled" : variables.sampled + }; + } + function rename( required string name ){ + variables.data[ "description" ] = variables.telemetry.safeName( arguments.name ); + return this; + } + function setBaggage( required string value ){ + variables.baggage = arguments.value; + return this; + } + function getBaggage(){ + return variables.isRoot ? variables.baggage : variables.root.getBaggage(); + } + function getRoot(){ + return variables.root; + } + function isSampled(){ + return variables.sampled; + } + function isFinished(){ + return variables.done.get(); + } + function setAttribute( required string name, required any value ){ + lock name="sentry-span-#variables.id#" type="exclusive" timeout="2" throwOnTimeout="false" { + if ( !isFinished() ) { + variables.data.data[ arguments.name ] = arguments.value; + } + } + return this; + } + function setStatus( required string status ){ + lock name="sentry-span-#variables.id#" type="exclusive" timeout="2" throwOnTimeout="false" { + if ( !isFinished() ) { + variables.data[ "status" ] = arguments.status; + } + } + return this; + } + function addChild( required any child ){ + if ( variables.children.size() < variables.telemetry.getMaxSpans() ) { + variables.children.add( arguments.child ); + } + } + /** Queue execution starts on the worker, which may be later than scheduling. */ + function markStarted( required numeric timestamp ){ + lock name="sentry-span-#variables.id#" type="exclusive" timeout="2" throwOnTimeout="false" { + if ( isFinished() ) { + return false; + } + variables.data[ "start_timestamp" ] = arguments.timestamp; + } + return true; + } + + function finish( string status = "" ){ + lock name="sentry-span-#variables.id#" type="exclusive" timeout="2" throwOnTimeout="false" { + if ( !variables.done.compareAndSet( false, true ) ) { + return false; + } + if ( len( arguments.status ) ) { + variables.data[ "status" ] = arguments.status; + } + variables.data[ "timestamp" ] = variables.telemetry.timestamp(); + if ( variables.sampled ) { + if ( variables.isRoot ) { + variables.telemetry.completeTransaction( this ); + } else { + variables.root.addChild( this ); + } + } + } + return true; + } + function toPayload(){ + var payload = duplicate( variables.data ); + payload[ "data" ] = variables.telemetry.sanitizeAttributes( payload.data ); + return payload; + } + function getChildren(){ + var children = []; + for ( var child in variables.children.toArray() ) { + children.append( child ); + } + return children; + } + +} diff --git a/readme.md b/readme.md index 2655c16..df96cfd 100644 --- a/readme.md +++ b/readme.md @@ -237,3 +237,7 @@ Holy Ghost which is given unto us. ." Romans 5:5 ### THE DAILY BREAD > "I am the way, and the truth, and the life; no one comes to the Father, but by me (JESUS)" Jn 14:1-12 + +## Observability and portable feedback + +See [configuration and APIs](docs/observability.md) and the [verification record](docs/verification.md) for tracing, runtime query adapters, cbq attempts, caches, outbound requests, structured logs, metrics, check-ins, Web Vitals, and CFML/BoxLang browser feedback installation. New integrations are opt-in. diff --git a/test-harness/Application.cfc b/test-harness/Application.cfc index 40b6196..ef87f26 100644 --- a/test-harness/Application.cfc +++ b/test-harness/Application.cfc @@ -4,7 +4,7 @@ Copyright 2005-2007 ColdBox Framework by Luis Majano and Ortus Solutions, Corp www.ortussolutions.com ******************************************************************************** */ -component{ +component { // UPDATE THE NAME OF THE MODULE IN TESTING BELOW request.MODULE_NAME = "sentry"; @@ -12,51 +12,65 @@ component{ // Application properties this.name = hash( getCurrentTemplatePath() ); this.sessionManagement = true; - this.sessionTimeout = createTimeSpan(0,0,15,0); - this.setClientCookies = true; + this.sessionTimeout = createTimespan( 0, 0, 15, 0 ); + this.setClientCookies = true; - /************************************** + /************************************** LUCEE Specific Settings **************************************/ // buffer the output of a tag/function body to output in case of a exception - this.bufferOutput = true; + this.bufferOutput = true; // Activate Gzip Compression - this.compression = false; + this.compression = false; // Turn on/off white space managemetn - this.whiteSpaceManagement = "smart"; + this.whiteSpaceManagement = "smart"; // Turn on/off remote cfc content whitespace this.suppressRemoteComponentContent = false; // COLDBOX STATIC PROPERTY, DO NOT CHANGE UNLESS THIS IS NOT THE ROOT OF YOUR COLDBOX APP - COLDBOX_APP_ROOT_PATH = getDirectoryFromPath( getCurrentTemplatePath() ); + COLDBOX_APP_ROOT_PATH = getDirectoryFromPath( getCurrentTemplatePath() ); // The web server mapping to this application. Used for remote purposes or static purposes - COLDBOX_APP_MAPPING = ""; + COLDBOX_APP_MAPPING = ""; // COLDBOX PROPERTIES - COLDBOX_CONFIG_FILE = ""; + COLDBOX_CONFIG_FILE = ""; // COLDBOX APPLICATION KEY OVERRIDE - COLDBOX_APP_KEY = ""; + COLDBOX_APP_KEY = ""; - // Mappings + // Mappings this.mappings[ "/root" ] = COLDBOX_APP_ROOT_PATH; // Map back to its root - moduleRootPath = REReplaceNoCase( this.mappings[ "/root" ], "#request.MODULE_NAME#(\\|/)test-harness(\\|/)", "" ); - modulePath = REReplaceNoCase( this.mappings[ "/root" ], "test-harness(\\|/)", "" ); + moduleRootPath = reReplaceNoCase( + this.mappings[ "/root" ], + "#request.MODULE_NAME#(\\|/)test-harness(\\|/)", + "" + ); + modulePath = reReplaceNoCase( + this.mappings[ "/root" ], + "test-harness(\\|/)", + "" + ); // Module Root + Path Mappings - this.mappings[ "/moduleroot" ] = moduleRootPath; + this.mappings[ "/moduleroot" ] = moduleRootPath; + this.mappings[ "/moduleroot/sentry" ] = modulePath; this.mappings[ "/#request.MODULE_NAME#" ] = modulePath; + this.mappings[ "/dependencies" ] = modulePath & "/modules"; // application start public boolean function onApplicationStart(){ - application.cbBootstrap = new coldbox.system.Bootstrap( COLDBOX_CONFIG_FILE, COLDBOX_APP_ROOT_PATH, COLDBOX_APP_KEY, COLDBOX_APP_MAPPING ); + application.cbBootstrap = new coldbox.system.Bootstrap( + COLDBOX_CONFIG_FILE, + COLDBOX_APP_ROOT_PATH, + COLDBOX_APP_KEY, + COLDBOX_APP_MAPPING + ); application.cbBootstrap.loadColdbox(); return true; } // request start - public boolean function onRequestStart(String targetPage){ - + public boolean function onRequestStart( String targetPage ){ // Process ColdBox Request application.cbBootstrap.onRequestStart( arguments.targetPage ); @@ -68,11 +82,11 @@ component{ } public void function onSessionEnd( struct sessionScope, struct appScope ){ - arguments.appScope.cbBootStrap.onSessionEnd( argumentCollection=arguments ); + arguments.appScope.cbBootStrap.onSessionEnd( argumentCollection = arguments ); } public boolean function onMissingTemplate( template ){ - return application.cbBootstrap.onMissingTemplate( argumentCollection=arguments ); + return application.cbBootstrap.onMissingTemplate( argumentCollection = arguments ); } -} \ No newline at end of file +} diff --git a/test-harness/assets/sentry b/test-harness/assets/sentry new file mode 120000 index 0000000..c486223 --- /dev/null +++ b/test-harness/assets/sentry @@ -0,0 +1 @@ +../../browser/dist \ No newline at end of file diff --git a/test-harness/config/Coldbox.cfc b/test-harness/config/Coldbox.cfc index 41364c0..7622afd 100644 --- a/test-harness/config/Coldbox.cfc +++ b/test-harness/config/Coldbox.cfc @@ -11,7 +11,7 @@ //Development Settings reinitPassword = "", handlersIndexAutoReload = true, - modulesExternalLocation = [], + modulesExternalLocation = [ "/dependencies" ], //Implicit Events defaultEvent = "", @@ -43,7 +43,7 @@ // Module Directives modules = { // An array of modules names to load, empty means all of them - include = [], + include = [ "funclinenums" ], // An array of modules names to NOT load, empty means none exclude = [] }; diff --git a/test-harness/feedback.html b/test-harness/feedback.html new file mode 100644 index 0000000..cc66c7f --- /dev/null +++ b/test-harness/feedback.html @@ -0,0 +1,3 @@ +Sentry verification harness

Sentry verification harness

All feedback and replay data goes to a local byte-preserving receiver.

SYNTHETIC-MASKED
diff --git a/test-harness/health.cfm b/test-harness/health.cfm new file mode 100644 index 0000000..6c7f9b6 --- /dev/null +++ b/test-harness/health.cfm @@ -0,0 +1,4 @@ + +setting showDebugOutput=false; +writeOutput( "ok" ); + diff --git a/test-harness/lucee-native-query/Application.cfc b/test-harness/lucee-native-query/Application.cfc new file mode 100644 index 0000000..fa5b3e8 --- /dev/null +++ b/test-harness/lucee-native-query/Application.cfc @@ -0,0 +1,32 @@ +component { + + this.name = "SentryLuceeNativeQueryVerification"; + this.mappings[ "/sentry" ] = getDirectoryFromPath( getCurrentTemplatePath() ) & "../../"; + configPath = getDirectoryFromPath( getCurrentTemplatePath() ) & "../../.tmp/lucee-query-db.json"; + if ( fileExists( configPath ) ) { + this.datasources.verification = deserializeJSON( fileRead( configPath ) ); + this.datasource = "verification"; + } + this.query.listener = { + before : function( caller, args ){ + return request.listener.before( argumentCollection = arguments ); + }, + after : function( caller, args, result, meta ){ + return request.listener.after( argumentCollection = arguments ); + }, + error : function( args, caller, meta, exception ){ + return request.listener.error( argumentCollection = arguments ); + } + }; + function onRequestStart( targetPage ){ + request.sentry = new sentry.models.SentryService( { + DSN : "http://public@127.0.0.1:60320/1", + tracesSampleRate : 1 + } ); + request.listener = request.sentry.createLuceeQueryListener( databaseSystem = "postgresql" ); + } + function onRequestEnd( targetPage ){ + request.sentry.shutdown(); + } + +} diff --git a/test-harness/lucee-native-query/query-listener.cfm b/test-harness/lucee-native-query/query-listener.cfm new file mode 100644 index 0000000..38e5004 --- /dev/null +++ b/test-harness/lucee-native-query/query-listener.cfm @@ -0,0 +1,16 @@ + +setting showDebugOutput=false; +t = request.sentry.getObservability(); root = request.sentry.startTransaction( "Lucee native query listener verification" ); t.setScope( { "span" : root } ); +result = queryExecute( "SELECT 1 AS id" ); +caught = false; +try { queryExecute( "SELECT missing_column_for_sentry_verification" ); } catch( any expected ) { caught = true; } +queryExecute( "SELECT 2 AS id", [], { cachedWithin : createTimeSpan( 0, 0, 0, 30 ), result : "verificationMetadata" } ); +queryExecute( "SELECT 2 AS id", [], { cachedWithin : createTimeSpan( 0, 0, 0, 30 ), result : "verificationMetadata" } ); +request.listener = request.sentry.createLuceeQueryListener( listener = { before : function( caller, args ) { args.sql = "SELECT 3 AS id"; return arguments; } }, databaseSystem = "postgresql" ); +transformed = queryExecute( "SELECT 99 AS id" ); +request.sentry.withQuerySpan( "SELECT 4 AS id", function( span ){ return queryExecute( "SELECT 4 AS id" ); }, "postgresql" ); +payloads = []; for( span in root.getChildren() ) { payloads.append( span.toPayload() ); } +if ( !caught || transformed.id[1] != 3 || payloads.len() != 6 || !( payloads[4].data["db.cached"] ?: false ) || payloads[2].status != "internal_error" ) { throw( message = "Native query listener regression" ); } +root.finish(); +writeOutput( serializeJSON( { "version" : server.lucee.version, "caught" : caught, "transformedId" : transformed.id[1], "spans" : payloads } ) ); + \ No newline at end of file diff --git a/test-harness/support/receiver.mjs b/test-harness/support/receiver.mjs new file mode 100644 index 0000000..82be686 --- /dev/null +++ b/test-harness/support/receiver.mjs @@ -0,0 +1,27 @@ +// Local byte-preserving envelope receiver. Bind only to loopback. +import http from 'node:http'; +const envelopes = []; +let mode = { status: 200, delay: 0, headers: {} }; +http.createServer(async (request, response) => { + response.setHeader('Access-Control-Allow-Origin', '*'); + response.setHeader('Access-Control-Allow-Headers', 'content-type,sentry-trace,baggage'); + response.setHeader('Access-Control-Allow-Methods', 'POST,GET,OPTIONS'); + if (request.method === 'OPTIONS') { response.writeHead(204); response.end(); return; } + const chunks = []; for await (const chunk of request) chunks.push(chunk); + const body = Buffer.concat(chunks); + if (request.url === '/state') { response.setHeader('Content-Type', 'application/json'); response.end(JSON.stringify(envelopes)); return; } + if (request.url === '/reset') { envelopes.length = 0; mode = body.length ? JSON.parse(body) : { status: 200, delay: 0, headers: {} }; response.end('{}'); return; } + try { + let offset = 0; + function line() { const end = body.indexOf(10, offset); if (end < 0) throw Error('Missing newline'); const value = body.subarray(offset, end).toString(); offset = end + 1; return JSON.parse(value); } + const header = line(); const items = []; + while (offset < body.length) { + const itemHeader = line(); const length = itemHeader.length ?? (body.indexOf(10, offset) < 0 ? body.length - offset : body.indexOf(10, offset) - offset); const bytes = body.subarray(offset, offset + length); offset += length; + if (bytes.length !== length || (offset < body.length && body[offset++] !== 10)) throw Error('Incorrect byte length'); + items.push({ header: itemHeader, payload: ['attachment', 'replay_recording'].includes(itemHeader.type) ? bytes.toString('base64') : JSON.parse(bytes.toString('utf8')) }); + } + envelopes.push({ header, items }); + const reply = mode; + setTimeout(() => { response.writeHead(reply.status ?? 200, reply.headers ?? {}); response.end('{}'); }, reply.delay ?? 0); + } catch (error) { response.writeHead(400); response.end(error.message); } +}).listen(60320, '127.0.0.1'); diff --git a/test-harness/tests/Application.cfc b/test-harness/tests/Application.cfc index c6c1fa3..dfc5603 100644 --- a/test-harness/tests/Application.cfc +++ b/test-harness/tests/Application.cfc @@ -32,7 +32,13 @@ component { "" ); this.mappings[ "/moduleroot" ] = moduleRootPath; - this.mappings[ "/#request.MODULE_NAME#" ] = moduleRootPath & "#request.MODULE_NAME#"; + this.mappings[ "/#request.MODULE_NAME#" ] = reReplaceNoCase( rootPath, "test-harness(\\|/)", "" ); + this.mappings[ "/moduleroot/sentry" ] = this.mappings[ "/sentry" ]; + cbqSource = createObject( "java", "java.lang.System" ).getenv( "SENTRY_CBQ_SOURCE" ); + if ( !isNull( cbqSource ) && len( cbqSource ) ) { + this.mappings[ "/cbq" ] = cbqSource; + } + this.mappings[ "/dependencies" ] = this.mappings[ "/sentry" ] & "/modules"; /** @@ -46,18 +52,21 @@ component { // New ColdBox Virtual Application Starter request.coldBoxVirtualApp= new coldbox.system.testing.VirtualApp(); - // If hitting the runner or specs, prep our virtual app - if ( getBaseTemplatePath().replace( expandPath( "/tests" ), "" ).reFindNoCase( "(runner|specs)" ) ) { - request.coldBoxVirtualApp.startup(); - } - - // Reload for fresh results + // Reload before startup: a partially activated optional integration must not block recovery. if ( structKeyExists( url, "fwreinit" ) ) { - if ( structKeyExists( server, "lucee" ) ) { - pagePoolClear(); + try { + request.coldBoxVirtualApp.shutdown(); + } catch ( any incompleteStartup ) { + createObject( "java", "java.lang.System" ).err.println( + "Test harness cleanup failed: " & incompleteStartup.message + ); } - // ormReload(); - request.coldBoxVirtualApp.restart(); + structDelete( application, "cbController" ); + structDelete( application, "wirebox" ); + structDelete( application, "cachebox" ); + } + if ( getBaseTemplatePath().replace( expandPath( "/tests" ), "" ).reFindNoCase( "(runner|specs)" ) ) { + request.coldBoxVirtualApp.startup(); } return true; diff --git a/test-harness/tests/native-query-smoke.cfm b/test-harness/tests/native-query-smoke.cfm new file mode 100644 index 0000000..28034b5 --- /dev/null +++ b/test-harness/tests/native-query-smoke.cfm @@ -0,0 +1,10 @@ + +service = new sentry.models.SentryService( { DSN : "http://public@127.0.0.1:60320/1", tracesSampleRate : 1 } ); +t = service.getObservability(); +listener = t.registerBoxLangQueries( getApplicationMetadata().name ); +root = service.startTransaction( "native query proof" ); t.setScope( { span : root } ); +rows = queryNew( "id", "integer", [ { id : 1 } ] ); +result = queryExecute( "select id from rows", [], { dbtype : "query" } ); +writeOutput( serializeJSON( { "spans" : root.getChildren().len(), "payloads" : root.getChildren().map( ( span ) => span.toPayload() ) } ) ); +root.finish(); service.shutdown(); + diff --git a/test-harness/tests/specs/ExecutionIsolationSpec.cfc b/test-harness/tests/specs/ExecutionIsolationSpec.cfc new file mode 100644 index 0000000..2031eee --- /dev/null +++ b/test-harness/tests/specs/ExecutionIsolationSpec.cfc @@ -0,0 +1,246 @@ +component extends="testbox.system.BaseSpec" { + + function run(){ + describe( "isolated execution and cache observation", function(){ + beforeEach( function(){ + variables.service = new sentry.models.SentryService( { + DSN : "http://public@127.0.0.1:60320/1", + tracesSampleRate : 1, + enableQueueTracing : true + } ); + variables.telemetry = variables.service.getObservability(); + } ); + afterEach( function(){ + variables.service.shutdown(); + } ); + it( "preserves trusted sampling baggage without credential labels", function(){ + var root = variables.service.startTransaction( + "task", + "task", + { + "sentry-trace" : repeatString( "a", 32 ) & "-" & repeatString( "b", 16 ) & "-1", + "baggage" : "sentry-release=release-1,sentry-user_id=PRIVATE,other=PRIVATE" + }, + true + ); + variables.telemetry.setScope( { span : root } ); + var headers = variables.service.getTraceHeaders(); + expect( headers.baggage ).toInclude( "release-1" ); + expect( headers.baggage ).notToInclude( "PRIVATE" ); + root.finish(); + } ); + it( "closes a timed out attempt on another thread and cleans the worker scope after late exit", function(){ + var interceptor = createMock( "sentry.interceptors.QueueObservability" ).$property( + "sentry", + "variables", + variables.service + ); + var properties = {}; + var job = { + getProperties : function(){ + return properties; + }, + getId : function(){ + return "synthetic-id"; + }, + getQueue : function(){ + return "synthetic"; + }, + getMapping : function(){ + return "SyntheticJob"; + }, + isBatchJob : function(){ + return false; + } + }; + var observation = { job : job, executionId : "attempt-1", attempt : 1 }; + var prior = variables.service.startTransaction( "request" ); + variables.telemetry.setScope( { span : prior } ); + interceptor.onCBQJobAttemptScheduled( {}, observation ); + var scheduledAt = variables.telemetry.timestamp(); + sleep( 40 ); + interceptor.onCBQJobExecutionStarted( {}, observation ); + expect( variables.telemetry.getScope().span.toPayload().start_timestamp - scheduledAt ).toBeGTE( + 0.025 + ); + expect( + variables.telemetry.getScope().span.toPayload().data[ "messaging.message.receive.latency" ] + ).toBeGTE( 25 ); + var context = variables.service.getTraceContext(); + var attemptSpan = variables.telemetry.getScope().span; + var observerReference = createObject( "java", "java.util.concurrent.atomic.AtomicReference" ).init( + interceptor + ); + var callbackThread= "sentry-test-" & replace( createUUID(), "-", "", "all" ); + thread name =callbackThread action="run" observer=observerReference data=observation { + attributes.data.status = "deadline_exceeded"; + attributes.observer.get().onCBQJobAttemptFinished( {}, attributes.data ); + } + thread action="join" name=callbackThread timeout=5000; + expect( cfthread[ callbackThread ].status ).toBe( "COMPLETED" ); + expect( attemptSpan.toPayload().status ).toBe( "deadline_exceeded" ); + observation.status = "ok"; + interceptor.onCBQJobAttemptFinished( {}, observation ); + expect( attemptSpan.toPayload().status ).toBe( "deadline_exceeded" ); + interceptor.onCBQJobExecutionExited( {}, observation ); + expect( variables.service.getTraceContext().span_id ).toBe( prior.getContext().span_id ); + expect( interceptor.getPendingAttemptCount() ).toBe( 0 ); + observation.executionId = "attempt-2"; + observation.attempt = 2; + interceptor.onCBQJobAttemptScheduled( {}, observation ); + interceptor.onCBQJobExecutionStarted( {}, observation ); + var retrySpan = variables.telemetry.getScope().span; + expect( retrySpan.toPayload().data[ "messaging.message.retry.count" ] ).toBe( 1 ); + interceptor.onCBQJobExecutionExited( {}, observation ); + observation.status = "cancelled"; + interceptor.onCBQJobAttemptFinished( {}, observation ); + expect( retrySpan.toPayload().status ).toBe( "cancelled" ); + expect( interceptor.getPendingAttemptCount() ).toBe( 0 ); + expect( variables.service.getTraceContext().span_id ).toBe( prior.getContext().span_id ); + prior.finish(); + expect( interceptor.getObservationFailureCount() ).toBe( 0 ); + } ); + it( "persists trace context for chained publication after callback scope cleanup", function(){ + var observer = createMock( "sentry.interceptors.QueueObservability" ).$property( + "sentry", + "variables", + variables.service + ); + var props = {}; + var chain = [ { properties : {} } ]; + var job = { + getId : () => "synthetic-first", + getProperties : () => props, + getQueue : () => "synthetic", + getChained : () => chain + }; + var root = variables.service.startTransaction( "chain request" ); + variables.telemetry.setScope( { span : root } ); + observer.onCBQJobAdded( {}, { job : job } ); + var initial = props[ "__sentry" ].headers[ "sentry-trace" ]; + expect( chain[ 1 ].properties[ "__sentry" ].headers[ "sentry-trace" ] ).toBe( initial ); + observer.onCBQJobPublished( {}, { job : job } ); + expect( root.getChildren().len() ).toBe( 1 ); + expect( root.getChildren()[ 1 ].toPayload().data[ "messaging.message.id" ] ).toBe( "synthetic-first" ); + variables.telemetry.clearScope(); + var continuation = chain[ 1 ].properties; + var nextJob = { + getId : () => "synthetic-next", + getProperties : () => continuation, + getQueue : () => "synthetic", + getChained : () => [] + }; + observer.onCBQJobAdded( {}, { job : nextJob } ); + expect( continuation[ "__sentry" ].headers[ "sentry-trace" ] ).notToBe( initial ); + expect( continuation[ "__sentry" ].headers[ "sentry-trace" ].left( 32 ) ).toBe( + root.getContext().trace_id + ); + observer.onCBQJobPublished( {}, { job : nextJob } ); + expect( variables.telemetry.getScope().isEmpty() ).toBeTrue(); + root.finish(); + expect( observer.getObservationFailureCount() ).toBe( 0 ); + } ); + it( "finishes a redirected request once and restores the previous scope", function(){ + var previous = { "test" : true }; + var span = variables.service.startTransaction( "GET /redirect" ); + variables.telemetry.setScope( { + "span" : span, + "requestState" : { "span" : span, "previous" : previous } + } ); + variables.service.endRequest( statusCode = 303 ); + expect( span.toPayload().data[ "http.response.status_code" ] ).toBe( 303 ); + expect( variables.telemetry.getScope() ).toBe( previous ); + expect( span.finish() ).toBeFalse(); + } ); + it( "does not duplicate a manual query span when a runtime listener observes it", function(){ + var root = variables.service.startTransaction( "query wrapper" ); + variables.telemetry.setScope( { "span" : root } ); + var listener = variables.service.createLuceeQueryListener(); + variables.service.withQuerySpan( "SELECT 'PRIVATE'", function( span ){ + listener.before( {}, { sql : "SELECT 'PRIVATE'" } ); + listener.after( {}, {}, {}, {} ); + return 42; + } ); + expect( root.getChildren().len() ).toBe( 1 ); + root.finish(); + } ); + it( "keeps false, zero, and empty cached values as hits while delegating the provider", function(){ + var values = { "false" : false, "zero" : 0, "empty" : "" }; + var provider = { + getName : function(){ + return "synthetic"; + }, + get : function( objectKey ){ + return values[ objectKey ]; + }, + getCacheID : function(){ + return "original"; + } + }; + var cache = new sentry.models.telemetry.InstrumentedCache( provider, variables.telemetry ); + var root = variables.service.startTransaction( "cache test" ); + variables.telemetry.setScope( { span : root } ); + expect( cache.get( "false" ) ).toBeFalse(); + expect( cache.get( "zero" ) ).toBe( 0 ); + expect( cache.get( "empty" ) ).toBe( "" ); + expect( cache.getCacheID() ).toBe( "original" ); + for ( var child in root.getChildren() ) { + expect( child.toPayload().data[ "cache.hit" ] ).toBeTrue(); + expect( child.toPayload().data[ "cache.key" ] ).toBeArray(); + expect( child.toPayload().data[ "cache.key" ][ 1 ] ).toInclude( "sha256:" ); + expect( child.toPayload().data ).notToHaveKey( "cache.item_size" ); + } + root.finish(); + } ); + it( "preserves failures unless an existing Lucee error listener handles them", function(){ + var listener = variables.service.createLuceeQueryListener(); + var root = variables.service.startTransaction( "listener error" ); + variables.telemetry.setScope( { span : root } ); + listener.before( {}, { sql : "SELECT 'PRIVATE' AS id" } ); + var failure = {}; + try { + throw( type = "SentryTest.QueryFailure", message = "original failure" ); + } catch ( SentryTest.QueryFailure original ) { + failure = original; + } + try { + listener.error( {}, {}, {}, failure ); + fail( "Failure must reach the caller" ); + } catch ( SentryTest.QueryFailure caught ) { + expect( caught.message ).toBe( failure.message ); + } + expect( root.getChildren()[ 1 ].toPayload().status ).toBe( "internal_error" ); + expect( root.getChildren()[ 1 ].toPayload().description ).toBe( "SELECT ? AS id" ); + var composed = variables.service.createLuceeQueryListener( + listener = { + error : function(){ + return { result : "handled" }; + } + } + ); + composed.before( {}, { sql : "SELECT missing" } ); + expect( composed.error( {}, {}, {}, failure ).result ).toBe( "handled" ); + root.finish(); + } ); + it( "composes Lucee transformations without exporting callback values", function(){ + var existing = { + before : function( caller, args ){ + args.sql = "SELECT 'PRIVATE'"; + return { args : args }; + }, + after : function(){ + return { result : "unchanged" }; + } + }; + var listener = new sentry.models.telemetry.LuceeQueryListener( variables.telemetry, existing ); + var root = variables.service.startTransaction( "listener" ); + variables.telemetry.setScope( { span : root } ); + expect( listener.before( {}, { sql : "SELECT original" } ).args.sql ).toBe( "SELECT 'PRIVATE'" ); + expect( listener.after( {}, {}, {}, {} ).result ).toBe( "unchanged" ); + expect( root.getChildren()[ 1 ].toPayload().description ).notToInclude( "PRIVATE" ); + root.finish(); + } ); + } ); + } + +} diff --git a/test-harness/tests/specs/ObservabilitySpec.cfc b/test-harness/tests/specs/ObservabilitySpec.cfc new file mode 100644 index 0000000..b85fa83 --- /dev/null +++ b/test-harness/tests/specs/ObservabilitySpec.cfc @@ -0,0 +1,151 @@ +component extends="testbox.system.BaseSpec" { + + function run(){ + describe( "Native observability", function(){ + beforeEach( function(){ + variables.service = new sentry.models.SentryService( { + DSN : "http://public@127.0.0.1:60320/1", + async : false, + tracesSampleRate : 1, + enableLogs : true, + enableMetrics : true, + enableMonitors : true, + tracePropagationTargets : [ "https://api.example.test" ] + } ); + variables.telemetry = variables.service.getObservability(); + } ); + afterEach( function(){ + variables.service.shutdown(); + } ); + it( "honors parent sampling and rejects malformed headers", function(){ + var off = variables.service.startTransaction( + "off", + "task", + { "sentry-trace" : repeatString( "a", 32 ) & "-" & repeatString( "b", 16 ) & "-0" }, + true + ); + expect( off.isSampled() ).toBeFalse(); + expect( variables.telemetry.parseHeaders( { "sentry-trace" : "invalid" } ) ).toBeEmpty(); + expect( + variables.telemetry.parseHeaders( { "sentry-trace" : repeatString( "0", 32 ) & "-" & repeatString( "b", 16 ) } ) + ).toBeEmpty(); + } ); + it( "restores nesting and exception scopes, completes once", function(){ + var root = variables.service.startTransaction( "GET /things/:id" ); + variables.telemetry.setScope( { span : root } ); + expect( + variables.service.withSpan( "child", function( span ){ + expect( variables.service.getTraceContext().span_id ).toBe( span.getContext().span_id ); + return 42; + } ) + ).toBe( 42 ); + expect( function(){ + variables.service.withSpan( "failed", function( span ){ + throw( type = "TestFailure", message = "expected" ); + } ); + } ).toThrow( "TestFailure" ); + expect( variables.service.getTraceContext().span_id ).toBe( root.getContext().span_id ); + expect( root.getChildren().len() ).toBe( 2 ); + expect( root.finish() ).toBeTrue(); + expect( root.finish( "internal_error" ) ).toBeFalse(); + expect( root.toPayload().status ).toBe( "ok" ); + } ); + it( "preserves callback results and failures when span completion fails", function(){ + var telemetry = prepareMock( variables.telemetry ); + var previous = { test : true }; + telemetry.setScope( previous ); + var brokenSpan = { + setStatus : function(){ + }, + finish : function(){ + throw( type = "TelemetryCompletionFailure", message = "synthetic completion failure" ); + } + }; + telemetry.$( "startSpan", brokenSpan ); + telemetry.$( "startTransaction", brokenSpan ); + expect( + telemetry.withSpan( "test", function(){ + return 42; + } ) + ).toBe( 42 ); + expect( + telemetry.withTraceContext( {}, function(){ + return 43; + } ) + ).toBe( 43 ); + expect( function(){ + telemetry.withSpan( "test", function(){ + throw( type = "OriginalFailure", message = "original" ); + } ); + } ).toThrow( "OriginalFailure" ); + expect( function(){ + telemetry.withTraceContext( {}, function(){ + throw( type = "OriginalFailure", message = "original" ); + } ); + } ).toThrow( "OriginalFailure" ); + expect( telemetry.getScope() ).toBe( previous ); + expect( telemetry.getCompletionFailureCount() ).toBe( 4 ); + } ); + it( "propagates to exact trusted origins only", function(){ + variables.telemetry.setScope( { span : variables.service.startTransaction( "task" ) } ); + expect( variables.service.getTraceHeaders( "https://api.example.test/path?token=secret" ) ).notToBeEmpty(); + expect( variables.service.getTraceHeaders( "https://api.example.test.evil/path" ) ).toBeEmpty(); + expect( variables.service.getTraceHeaders( "https://password@api.example.test/path" ) ).toBeEmpty(); + } ); + it( "sends feedback with Unicode and real binary attachments", function(){ + var receipt = variables.service.captureFeedback( + message = "Synthetic café 🎭", + page = "https://app.example.test/path?token=secret", + attachments = [ + { + filename : "capture.png", + contentType : "image/png", + data : binaryDecode( "89504e470d0a1a0a000102ff", "hex" ) + } + ], + wait = true + ); + expect( receipt.getStatus() ).toBe( "accepted" ); + expect( receipt.getEventId().len() ).toBe( 32 ); + expect( variables.service.captureFeedback( message = " " ).getStatus() ).toBe( "invalid" ); + } ); + it( "scrubs literals and unsafe attributes", function(){ + expect( + variables.telemetry.scrubSQL( "select * from people where secret = 'dont-export' and id = 42" ) + ).notToInclude( "dont-export" ); + expect( variables.telemetry.scrubSQL( "select $$private$$" ) ).notToInclude( "private" ); + expect( + variables.telemetry.sanitizeAttributes( { + password : "secret", + "db.bindings" : "data", + outcome : "ok" + } ) + ).toHaveLength( 1 ); + } ); + it( "buffers structured logs and trace metrics and matches check-ins", function(){ + var safe = variables.telemetry.sanitizeAttributes( { + "cache.key" : [ "sha256:synthetic", { "password" : "secret" } ], + "other.array" : [ "secret" ], + "db.bindings" : [ "secret" ] + } ); + expect( safe ).toHaveLength( 1 ); + expect( safe[ "cache.key" ] ).toBe( [ "sha256:synthetic" ] ); + variables.service.captureLog( + "Synthetic operation", + "info", + { outcome : "ok", "cache.key" : [ "sha256:synthetic" ] } + ); + variables.service.counter( "request.count" ); + variables.service.gauge( "queue.depth", 3 ); + variables.service.distribution( "request.duration", 7, {}, "millisecond" ); + expect( + variables.service.withMonitor( "synthetic-monitor", function(){ + return 42; + } ) + ).toBe( 42 ); + expect( variables.service.flush() ).toBeTrue(); + } ); + } ); + } + +} diff --git a/test-harness/tests/specs/SentryTests.cfc b/test-harness/tests/specs/SentryTests.cfc index 0ad755d..13abb7a 100644 --- a/test-harness/tests/specs/SentryTests.cfc +++ b/test-harness/tests/specs/SentryTests.cfc @@ -546,6 +546,10 @@ component extends="coldbox.system.testing.BaseTestCase" appMapping="/root" { // Should be normalized to forward slashes expect( frames[ 1 ].filename ).toInclude( "C:/wwwroot/app/index.cfm" ); expect( frames[ 1 ].lineno ).toBe( 42 ); + expect( frames[ 1 ].context_line ).toBeEmpty(); + expect( frames[ 1 ].pre_context ).toBeEmpty(); + expect( frames[ 1 ].post_context ).toBeEmpty(); + expect( frames[ 1 ] ).notToHaveKey( "function" ); } ); it( "deduplicates repeated template+line combinations in tagContext", function(){ @@ -573,7 +577,7 @@ component extends="coldbox.system.testing.BaseTestCase" appMapping="/root" { expect( frames.len() ).toBe( 2 ); } ); - it( "finds function names via functionLineNums for synthetic tagContext frames", function(){ + it( "finds function names and source context for readable template frames", function(){ var service = prepareMock( getSentry() ); service.setEnabled( true ); service.$( "post" ); @@ -590,8 +594,8 @@ component extends="coldbox.system.testing.BaseTestCase" appMapping="/root" { "type" : "application", "TagContext" : [], "StackTrace" : "java.lang.NullPointerException - at com_example_handler_cfc$cf.call(/app/handler.cfc:42) - at com_example_interceptor_cfc$cf.call(/app/interceptor.cfc:15)" + at com_example_handler_cfc$cf.call(#getCurrentTemplatePath()#:1) + at com_example_interceptor_cfc$cf.call(#getCurrentTemplatePath()#:6)" }; service.captureException( exception = testException, showJavaStackTrace = true ); @@ -601,6 +605,10 @@ component extends="coldbox.system.testing.BaseTestCase" appMapping="/root" { // functionLineNums.findTagContextFunction() is called during frame building expect( mockFLN.$count( "findTagContextFunction" ) ).toBe( 2 ); + expect( frames[ 1 ].function ).toBe( "MyApp.handler" ); + expect( frames[ 2 ].function ).toBe( "MyApp.interceptor" ); + expect( frames[ 1 ].context_line ).toInclude( "loadColdbox" ); + expect( frames[ 2 ].context_line ).toInclude( "/**" ); } ); it( "skips invalid line numbers in stack trace template references", function(){ diff --git a/test-harness/tests/specs/SentryTimestampTests.cfc b/test-harness/tests/specs/SentryTimestampTests.cfc index aabccb2..01d3889 100644 --- a/test-harness/tests/specs/SentryTimestampTests.cfc +++ b/test-harness/tests/specs/SentryTimestampTests.cfc @@ -13,6 +13,11 @@ component extends="testbox.system.BaseSpec" { "instant" : "2026-09-14T00:49:38Z", "unix" : "1789346978" }, + { + "instant" : "2026-09-14T00:49:38.900Z", + "iso" : "2026-09-14T00:49:38Z", + "unix" : "1789346978" + }, { "instant" : "2026-01-01T00:00:00Z", "unix" : "1767225600" @@ -28,7 +33,7 @@ component extends="testbox.system.BaseSpec" { ); var timestamps = service.getTimeVars( reference ); - expect( timestamps.iso ).toBe( sample.instant ); + expect( timestamps.iso ).toBe( sample.iso ?: sample.instant ); expect( timestamps.unix ).toBe( sample.unix ); } } ); diff --git a/test-harness/tests/specs/TransportFailureSpec.cfc b/test-harness/tests/specs/TransportFailureSpec.cfc new file mode 100644 index 0000000..58206f6 --- /dev/null +++ b/test-harness/tests/specs/TransportFailureSpec.cfc @@ -0,0 +1,131 @@ +component extends="testbox.system.BaseSpec" { + + function run(){ + describe( "bounded envelope transport", function(){ + function receiver( struct mode = {} ){ + cfhttp( url = "http://127.0.0.1:60320/reset", method = "post" ) { + cfhttpparam( type = "body", value = serializeJSON( arguments.mode ) ); + } + } + afterEach( function(){ + receiver(); + } ); + it( "flushes and shuts down with no pending envelopes", function(){ + var service = new sentry.models.SentryService( { DSN : "http://public@127.0.0.1:60320/1" } ); + try { + expect( service.flush() ).toBeTrue(); + } finally { + expect( service.shutdown() ).toBeTrue(); + } + expect( + service + .getObservability() + .getTransport() + .getDiagnostics() + .closed + ).toBeTrue(); + } ); + it( "distinguishes rejected delivery and honors category rate limits", function(){ + receiver( { + "status" : 429, + "delay" : 0, + "headers" : { "X-Sentry-Rate-Limits" : "60:user_report::,60:log_item::" } + } ); + var service = new sentry.models.SentryService( { DSN : "http://public@127.0.0.1:60320/1", async : false } ); + try { + expect( service.captureFeedback( message = "Synthetic", wait = true ).getStatus() ).toBe( "rejected" ); + expect( service.captureFeedback( message = "Retry", wait = true ).getStatus() ).toBe( "dropped" ); + expect( + service + .getObservability() + .sendSignal( + "transaction", + { event_id : repeatString( "a", 32 ) }, + "transaction", + [], + true + ) + .getStatus() + ).toBe( "rejected" ); + } finally { + service.shutdown(); + } + } ); + it( "limits attachments independently and observes each response once", function(){ + receiver( { + status : 200, + "headers" : { "X-Sentry-Rate-Limits" : "60:attachment::,60:metric::" } + } ); + var service = new sentry.models.SentryService( { DSN : "http://public@127.0.0.1:60320/1" } ); + try { + var receipt = service.captureFeedback( message = "First", wait = true ); + receipt.awaitDelivery(); + receipt.awaitDelivery(); + expect( + service + .getObservability() + .getTransport() + .getDiagnostics() + .accepted + ).toBe( 1 ); + expect( + service + .captureFeedback( + message = "No attachment", + attachments = [ + { + filename : "verification.bin", + data : charsetDecode( "synthetic", "UTF-8" ) + } + ], + wait = true + ) + .isAccepted() + ).toBeTrue(); + cfhttp( url = "http://127.0.0.1:60320/state" ); + var received = deserializeJSON( cfhttp.fileContent ); + expect( received[ 2 ].items.len() ).toBe( 1 ); + expect( + service + .getObservability() + .sendSignal( + "trace_metric", + { items : [] }, + "trace_metric", + [], + true + ) + .getStatus() + ).toBe( "dropped" ); + } finally { + service.shutdown(); + } + } ); + it( "bounds pending requests and handles unavailable ingestion", function(){ + receiver( { "status" : 200, "delay" : 300, "headers" : {} } ); + var service = new sentry.models.SentryService( { + DSN : "http://public@127.0.0.1:60320/1", + maxPendingEnvelopes : 1 + } ); + try { + var first = service.captureFeedback( message = "First" ); + expect( first.getStatus() ).toBe( "queued" ); + expect( service.captureFeedback( message = "Second" ).getStatus() ).toBe( "dropped" ); + expect( first.awaitDelivery( 1000 ).getStatus() ).toBe( "accepted" ); + } finally { + service.shutdown(); + } + var unavailable = new sentry.models.SentryService( { + DSN : "http://public@127.0.0.1:60329/1", + transportTimeout : 100 + } ); + try { + expect( unavailable.captureFeedback( message = "Offline", wait = true ).isAccepted() ).toBeFalse(); + } finally { + unavailable.shutdown(); + } + } ); + } ); + } + +} diff --git a/test-harness/tests/telemetry-runner.cfm b/test-harness/tests/telemetry-runner.cfm new file mode 100644 index 0000000..b8cabb3 --- /dev/null +++ b/test-harness/tests/telemetry-runner.cfm @@ -0,0 +1,6 @@ + +setting showDebugOutput=false; +bundles = "tests.specs.ObservabilitySpec,tests.specs.TransportFailureSpec,tests.specs.ExecutionIsolationSpec"; +if ( directoryExists( expandPath( "/cbq/tests" ) ) ) { bundles &= ",cbq.tests.specs.unit.ObservabilityHooksSpec"; } +writeOutput( new testbox.system.TestBox( bundles = bundles ).run( reporter = "json" ) ); + diff --git a/test-harness/tests/telemetry-smoke.cfm b/test-harness/tests/telemetry-smoke.cfm new file mode 100644 index 0000000..9bf5e72 --- /dev/null +++ b/test-harness/tests/telemetry-smoke.cfm @@ -0,0 +1,10 @@ + +service = new sentry.models.SentryService( { DSN : "http://public@127.0.0.1:60320/1", async : false, tracesSampleRate : 1, enableLogs : true, enableMetrics : true, enableMonitors : true } ); +t = service.getObservability(); +root = service.startTransaction( "GET /things/:id" ); +t.setScope( { span : root } ); +result = service.withSpan( "child", ( span ) => 42 ); +root.finish(); +writeOutput( serializeJSON( { result : result, headers : service.getTraceHeaders(), payload : root.toPayload(), diagnostics : t.getTransport().getDiagnostics() } ) ); +service.shutdown(); +