@stacksjs/desktop 0.2.279 → 0.2.280

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -313,6 +313,88 @@ await showSuccessToast('File saved successfully!')
313
313
  await showErrorToast('Failed to save file', 5000)
314
314
  ```
315
315
 
316
+ ### Self-Updating
317
+
318
+ An installed app can replace itself from its own GitHub releases.
319
+
320
+ ```typescript
321
+ import { createSelfUpdater } from '@stacksjs/desktop'
322
+
323
+ const updater = await createSelfUpdater({
324
+ repository: 'stacksjs/barista',
325
+ currentVersion: '0.3.0',
326
+ autoDownload: false,
327
+ })
328
+
329
+ const update = await updater.checkForUpdates()
330
+ if (update) {
331
+ await updater.downloadUpdate()
332
+ await updater.installUpdate() // verifies, swaps the bundle, relaunches
333
+ }
334
+ ```
335
+
336
+ `createSelfUpdater` finds two things by itself that are easy to get wrong by hand:
337
+
338
+ - **which bundle to replace** — the outermost `.app` above `process.execPath`, so a
339
+ helper or XPC service inside the app still updates the whole app, and a `bun run`
340
+ in development throws instead of swapping a directory in your source tree;
341
+ - **who is allowed to publish updates** — the Apple Developer Team ID that signed the
342
+ copy already on disk. You do not configure your own team ID, and you cannot get it
343
+ wrong by copying an example.
344
+
345
+ #### What is checked before the bundle is swapped
346
+
347
+ On macOS, the SHA-256 in the manifest is the weakest of the three checks, not the
348
+ strongest — whoever can rewrite the manifest can rewrite the hash with it. So the
349
+ staged bundle also has to satisfy the two questions Gatekeeper asks at launch:
350
+
351
+ | Check | Tool | Rejects |
352
+ |---|---|---|
353
+ | Signature intact | `codesign --verify --deep --strict` | tampered or re-packed bundles |
354
+ | Notarized by Apple | `spctl -a -t exec` | anything Apple has not scanned |
355
+ | Signed by *your* team | `TeamIdentifier` from `codesign -dv` | notarized builds from other developers |
356
+
357
+ Only after all three pass is the quarantine flag cleared and the bundle swapped, and
358
+ the swap is two renames inside the install directory — so a failure never leaves the
359
+ user without an app.
360
+
361
+ Set `requireSameTeam: false` only when a build genuinely changes teams; without it
362
+ the updater will accept any notarized bundle, and notarization is available to every
363
+ Apple developer account there is.
364
+
365
+ #### Publishing an update
366
+
367
+ Attach an `update.json` to the release, beside the `.dmg`:
368
+
369
+ ```typescript
370
+ import { createGitHubUpdateManifest, UPDATE_MANIFEST_ASSET } from '@stacksjs/desktop'
371
+
372
+ const manifest = createGitHubUpdateManifest({
373
+ repository: 'stacksjs/barista',
374
+ version: '0.3.1',
375
+ artifacts: { darwin: 'dist/Barista-0.3.1.dmg' },
376
+ })
377
+
378
+ await Bun.write(UPDATE_MANIFEST_ASSET, JSON.stringify(manifest, null, 2))
379
+ ```
380
+
381
+ Generate it **after** notarization. Stapling the ticket rewrites the DMG, so a
382
+ manifest built before that step carries a hash no download can ever match.
383
+
384
+ #### Relaunching a launcher/agent app
385
+
386
+ The default relaunch opens the new bundle and quits the launcher — the process that
387
+ spawned this one. That is right for the shape stx desktop apps have, where one binary
388
+ runs as a launcher, an agent and a window; calling `process.exit(0)` from the agent
389
+ would kill a child and leave the window open on a dead server. Override `relaunch`,
390
+ or compose `relaunchBundle` and `quitLauncher`, for anything different.
391
+
392
+ #### Bundle primitives
393
+
394
+ The pieces are exported individually for installers, CI checks, and "am I running the
395
+ build I think I am?": `verifyBundleTrust`, `readBundleIdentity`, `extractBundle`,
396
+ `swapBundle`, `clearQuarantine`, `canReplaceBundle`, and `bundlePathForExecutable`.
397
+
316
398
  ## API Reference
317
399
 
318
400
  ### Window Management
package/dist/index.d.ts CHANGED
@@ -75,9 +75,14 @@ export type {
75
75
  export type { DesktopConfig } from './window';
76
76
  export type { PackageConfig, PackageResult } from './packaging';
77
77
  export type {
78
+ BundleIdentity,
79
+ BundleTrustPolicy,
80
+ BundleTrustResult,
78
81
  GitHubManifestOptions,
79
82
  GitHubUpdaterOptions,
80
83
  PlatformUpdate,
84
+ RelaunchOptions,
85
+ SelfUpdaterOptions,
81
86
  UpdateManifest,
82
87
  UpdaterConfig,
83
88
  UpdaterEvent,
@@ -415,12 +420,23 @@ export { craftBinaryNotFoundMessage, pack, packageApp, resolveCraftBinary } from
415
420
  // =============================================================================
416
421
  export {
417
422
  AutoUpdater,
423
+ bundlePathForExecutable,
424
+ canReplaceBundle,
425
+ clearQuarantine,
418
426
  createGitHubUpdateManifest,
419
427
  createGitHubUpdater,
428
+ createSelfUpdater,
429
+ extractBundle,
420
430
  generateUpdateManifest,
421
431
  githubLatestAssetUrl,
422
432
  githubReleaseAssetUrl,
433
+ quitLauncher,
434
+ readBundleIdentity,
435
+ relaunchBundle,
436
+ runningBundleTeamId,
437
+ swapBundle,
423
438
  UPDATE_MANIFEST_ASSET,
439
+ verifyBundleTrust,
424
440
  } from './self-update';
425
441
  // =============================================================================
426
442
  // Power Management / Caffeinate
package/dist/index.js CHANGED
@@ -1,86 +1,86 @@
1
1
  // @bun
2
- import{$ as rZ,$a as r0,A as TZ,Aa as z0,B as LZ,Ba as M0,C as DZ,Ca as T0,D as PZ,Da as L0,E as WZ,Ea as D0,F as AZ,Fa as P0,G as NZ,Ga as W0,H as xZ,Ha as A0,I as IZ,Ia as N0,J as kZ,Ja as x0,K as CZ,Ka as I0,L as HZ,La as k0,M as vZ,Ma as C0,N as wZ,Na as H0,O as fZ,Oa as v0,P as SZ,Pa as w0,Q as gZ,Qa as f0,R as bZ,Ra as S0,S as uZ,Sa as g0,T as yZ,Ta as b0,U as hZ,Ua as u0,V as mZ,Va as y0,W as cZ,Wa as h0,X as dZ,Xa as m0,Y as C,Ya as c0,Z as UQ,Za as d0,_ as pZ,_a as p0,a as lY,aa as nZ,ab as n0,b as aY,ba as oZ,bb as o0,c as iY,ca as lZ,cb as l0,d as sY,da as aZ,db as a0,e as tY,ea as iZ,f as eY,fa as sZ,g as QZ,ga as tZ,h as YZ,ha as eZ,i as ZZ,ia as Q0,j as XZ,ja as Y0,k as $Z,ka as Z0,l as JZ,la as X0,m as GZ,ma as $0,n as qZ,na as J0,o as RZ,oa as G0,p as KZ,pa as q0,q as UZ,qa as R0,r as EZ,ra as K0,s as _Z,sa as U0,t as FZ,ta as E0,u as BZ,ua as _0,v as jZ,va as F0,w as VZ,wa as B0,x as OZ,xa as j0,y as zZ,ya as V0,z as MZ,za as O0}from"./chunk-r69bmd7g.js";import{eb as N}from"./chunk-h05t5fn6.js";function z(Q="stx"){return`${Q}-${Date.now()}-${Math.random().toString(36).substring(2,9)}`}function F(Q){return Q.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}function O(...Q){return Q.filter(Boolean).join(" ")}function V(Q){if(!Q)return"";return Object.entries(Q).map(([Y,Z])=>`${Y.replace(/([A-Z])/g,"-$1").toLowerCase()}: ${Z}`).join("; ")}function FQ(Q){let{text:Y,variant:Z="primary",size:X="medium",disabled:$=!1,loading:G=!1,icon:K,iconPosition:q="left",id:J=z("btn"),className:E,style:U}=Q,_=O("stx-button",`stx-button--${Z}`,`stx-button--${X}`,$&&"stx-button--disabled",G&&"stx-button--loading",E),R=V(U),B=K?`<span class="stx-button-icon">${K}</span>`:"",j=G?'<span class="stx-button-spinner"></span>':"",M=q==="left"?`${B}${j}<span class="stx-button-text">${F(Y)}</span>`:`<span class="stx-button-text">${F(Y)}</span>${B}${j}`;return`<button id="${J}" class="${_}" ${$||G?"disabled":""} ${R?`style='${R}'`:""}>${M}</button>`}function BQ(Q){let{value:Y="",placeholder:Z="",type:X="text",disabled:$=!1,readonly:G=!1,maxLength:K,minLength:q,pattern:J,required:E=!1,autocomplete:U,label:_,error:R,hint:B,id:j=z("input"),className:M,style:T}=Q,L=O("stx-input",R&&"stx-input--error",$&&"stx-input--disabled",M),w=V(T),_Q=[`type="${X}"`,`id="${j}"`,`class="${L}"`,Y&&`value="${F(Y)}"`,Z&&`placeholder="${F(Z)}"`,$&&"disabled",G&&"readonly",E&&"required",K&&`maxlength="${K}"`,q&&`minlength="${q}"`,J&&`pattern="${F(J)}"`,U&&`autocomplete="${U}"`,w&&`style="${w}"`].filter(Boolean).join(" "),H="";if(_)H+=`<label class="stx-input-label" for="${j}">${F(_)}</label>`;if(H+=`<input ${_Q} />`,R)H+=`<div class="stx-input-error">${F(R)}</div>`;else if(B)H+=`<div class="stx-input-hint">${F(B)}</div>`;return`<div class="stx-input-wrapper">${H}</div>`}function jQ(Q){let{checked:Y=!1,label:Z,disabled:X=!1,indeterminate:$=!1,id:G=z("checkbox"),className:K,style:q}=Q,J=O("stx-checkbox",X&&"stx-checkbox--disabled",K),E=V(q),U=['type="checkbox"',`id="${G}"`,Y&&"checked",X&&"disabled",$&&'data-indeterminate="true"'].filter(Boolean).join(" ");return`
3
- <label class="${J}" ${E?`style="${E}"`:""}>
2
+ import{$ as $1,$a as $2,A as w0,Aa as H1,B as f0,Ba as v1,C as S0,Ca as w1,D as g0,Da as f1,E as b0,Ea as S1,F as y0,Fa as g1,G as u0,Ga as b1,H as h0,Ha as y1,I as m0,Ia as u1,J as c0,Ja as h1,K as d0,Ka as m1,L as p0,La as c1,M as r0,Ma as d1,N as n0,Na as p1,O as o0,Oa as r1,P as l0,Pa as n1,Q as a0,Qa as o1,R as i0,Ra as l1,S as s0,Sa as a1,T as t0,Ta as i1,U as e0,Ua as s1,V as Y1,Va as t1,W as Z1,Wa as e1,X as Q1,Xa as Y2,Y as x,Ya as Z2,Z as VY,Za as Q2,_ as X1,_a as X2,a as R0,aa as J1,ab as J2,b as q0,ba as G1,bb as G2,c as K0,ca as R1,cb as R2,d as U0,da as q1,db as q2,e as _0,ea as K1,f as E0,fa as U1,g as F0,ga as _1,h as j0,ha as E1,i as B0,ia as F1,j as V0,ja as j1,k as O0,ka as B1,l as z0,la as V1,m as M0,ma as O1,n as L0,na as z1,o as T0,oa as M1,p as D0,pa as L1,q as W0,qa as T1,r as P0,ra as D1,s as A0,sa as W1,t as N0,ta as P1,u as k0,ua as A1,v as C0,va as N1,w as I0,wa as k1,x as x0,xa as C1,y as H0,ya as I1,z as v0,za as x1}from"./chunk-r69bmd7g.js";import{eb as N}from"./chunk-h05t5fn6.js";function z(Y="stx"){return`${Y}-${Date.now()}-${Math.random().toString(36).substring(2,9)}`}function F(Y){return Y.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}function O(...Y){return Y.filter(Boolean).join(" ")}function V(Y){if(!Y)return"";return Object.entries(Y).map(([Z,Q])=>`${Z.replace(/([A-Z])/g,"-$1").toLowerCase()}: ${Q}`).join("; ")}function MY(Y){let{text:Z,variant:Q="primary",size:X="medium",disabled:$=!1,loading:J=!1,icon:K,iconPosition:R="left",id:G=z("btn"),className:_,style:U}=Y,E=O("stx-button",`stx-button--${Q}`,`stx-button--${X}`,$&&"stx-button--disabled",J&&"stx-button--loading",_),q=V(U),j=K?`<span class="stx-button-icon">${K}</span>`:"",B=J?'<span class="stx-button-spinner"></span>':"",M=R==="left"?`${j}${B}<span class="stx-button-text">${F(Z)}</span>`:`<span class="stx-button-text">${F(Z)}</span>${j}${B}`;return`<button id="${G}" class="${E}" ${$||J?"disabled":""} ${q?`style='${q}'`:""}>${M}</button>`}function LY(Y){let{value:Z="",placeholder:Q="",type:X="text",disabled:$=!1,readonly:J=!1,maxLength:K,minLength:R,pattern:G,required:_=!1,autocomplete:U,label:E,error:q,hint:j,id:B=z("input"),className:M,style:L}=Y,T=O("stx-input",q&&"stx-input--error",$&&"stx-input--disabled",M),f=V(L),zY=[`type="${X}"`,`id="${B}"`,`class="${T}"`,Z&&`value="${F(Z)}"`,Q&&`placeholder="${F(Q)}"`,$&&"disabled",J&&"readonly",_&&"required",K&&`maxlength="${K}"`,R&&`minlength="${R}"`,G&&`pattern="${F(G)}"`,U&&`autocomplete="${U}"`,f&&`style="${f}"`].filter(Boolean).join(" "),H="";if(E)H+=`<label class="stx-input-label" for="${B}">${F(E)}</label>`;if(H+=`<input ${zY} />`,q)H+=`<div class="stx-input-error">${F(q)}</div>`;else if(j)H+=`<div class="stx-input-hint">${F(j)}</div>`;return`<div class="stx-input-wrapper">${H}</div>`}function TY(Y){let{checked:Z=!1,label:Q,disabled:X=!1,indeterminate:$=!1,id:J=z("checkbox"),className:K,style:R}=Y,G=O("stx-checkbox",X&&"stx-checkbox--disabled",K),_=V(R),U=['type="checkbox"',`id="${J}"`,Z&&"checked",X&&"disabled",$&&'data-indeterminate="true"'].filter(Boolean).join(" ");return`
3
+ <label class="${G}" ${_?`style="${_}"`:""}>
4
4
  <input ${U} />
5
5
  <span class="stx-checkbox-box"></span>
6
- ${Z?`<span class="stx-checkbox-label">${F(Z)}</span>`:""}
6
+ ${Q?`<span class="stx-checkbox-label">${F(Q)}</span>`:""}
7
7
  </label>
8
- `}function VQ(Q){let{value:Y=50,min:Z=0,max:X=100,step:$=1,disabled:G=!1,label:K,showValue:q=!0,id:J=z("slider"),className:E,style:U}=Q,_=O("stx-slider",G&&"stx-slider--disabled",E),R=V(U),B=['type="range"',`id="${J}"`,`value="${Y}"`,`min="${Z}"`,`max="${X}"`,`step="${$}"`,G&&"disabled"].filter(Boolean).join(" "),j="";if(K)j+=`<label class="stx-slider-label" for="${J}">${F(K)}</label>`;if(j+=`<div class="stx-slider-track"><input ${B} /></div>`,q)j+=`<span class="stx-slider-value">${Y}</span>`;return`<div class="${_}" ${R?`style='${R}'`:""}>${j}</div>`}function OQ(Q){let{value:Y,max:Z=100,variant:X="default",size:$="medium",showLabel:G=!1,indeterminate:K=!1,id:q=z("progress"),className:J,style:E}=Q,U=Math.min(100,Math.max(0,Y/Z*100)),_=O("stx-progress",`stx-progress--${X}`,`stx-progress--${$}`,K&&"stx-progress--indeterminate",J),R=V(E);return`
9
- <div id="${q}" class="${_}" role="progressbar" aria-valuenow="${Y}" aria-valuemin="0" aria-valuemax="${Z}" ${R?`style="${R}"`:""}>
8
+ `}function DY(Y){let{value:Z=50,min:Q=0,max:X=100,step:$=1,disabled:J=!1,label:K,showValue:R=!0,id:G=z("slider"),className:_,style:U}=Y,E=O("stx-slider",J&&"stx-slider--disabled",_),q=V(U),j=['type="range"',`id="${G}"`,`value="${Z}"`,`min="${Q}"`,`max="${X}"`,`step="${$}"`,J&&"disabled"].filter(Boolean).join(" "),B="";if(K)B+=`<label class="stx-slider-label" for="${G}">${F(K)}</label>`;if(B+=`<div class="stx-slider-track"><input ${j} /></div>`,R)B+=`<span class="stx-slider-value">${Z}</span>`;return`<div class="${E}" ${q?`style='${q}'`:""}>${B}</div>`}function WY(Y){let{value:Z,max:Q=100,variant:X="default",size:$="medium",showLabel:J=!1,indeterminate:K=!1,id:R=z("progress"),className:G,style:_}=Y,U=Math.min(100,Math.max(0,Z/Q*100)),E=O("stx-progress",`stx-progress--${X}`,`stx-progress--${$}`,K&&"stx-progress--indeterminate",G),q=V(_);return`
9
+ <div id="${R}" class="${E}" role="progressbar" aria-valuenow="${Z}" aria-valuemin="0" aria-valuemax="${Q}" ${q?`style="${q}"`:""}>
10
10
  <div class="stx-progress-bar" style="width: ${K?"100%":`${U}%`}"></div>
11
- ${G?`<span class="stx-progress-label">${Math.round(U)}%</span>`:""}
11
+ ${J?`<span class="stx-progress-label">${Math.round(U)}%</span>`:""}
12
12
  </div>
13
- `}function zQ(Q){let{text:Y,variant:Z="default",size:X="medium",id:$=z("badge"),className:G,style:K}=Q,q=O("stx-badge",`stx-badge--${Z}`,`stx-badge--${X}`,G),J=V(K);return`<span id="${$}" class="${q}" ${J?`style='${J}'`:""}>${F(Y)}</span>`}function MQ(Q){let{src:Y,alt:Z="",name:X,size:$="medium",shape:G="circle",id:K=z("avatar"),className:q,style:J}=Q,E=typeof $==="number"?"":`stx-avatar--${$}`,U=typeof $==="number"?`width: ${$}px; height: ${$}px;`:"",_=O("stx-avatar",E,`stx-avatar--${G}`,q),R=[U,V(J)].filter(Boolean).join(" "),B=X?X.split(" ").map((j)=>j[0]).join("").toUpperCase().slice(0,2):"";if(Y)return`<div id="${K}" class="${_}" ${R?`style="${R}"`:""}>
14
- <img src="${F(Y)}" alt="${F(Z)}" class="stx-avatar-img" />
15
- </div>`;return`<div id="${K}" class="${_}" ${R?`style="${R}"`:""}>
16
- <span class="stx-avatar-initials">${B}</span>
17
- </div>`}function TQ(Q){let{title:Y,subtitle:Z,content:X,image:$,footer:G,variant:K="default",id:q=z("card"),className:J,style:E}=Q,U=O("stx-card",`stx-card--${K}`,J),_=V(E),R="";if($)R+=`<div class="stx-card-image"><img src="${F($)}" alt="" /></div>`;if(R+='<div class="stx-card-body">',Y)R+=`<h3 class="stx-card-title">${F(Y)}</h3>`;if(Z)R+=`<p class="stx-card-subtitle">${F(Z)}</p>`;if(X)R+=`<div class="stx-card-content">${F(X)}</div>`;if(R+="</div>",G)R+=`<div class="stx-card-footer">${F(G)}</div>`;return`<div id="${q}" class="${U}" ${_?`style='${_}'`:""}>${R}</div>`}function LQ(Q){let{tabs:Y,activeTab:Z,variant:X="default",id:$=z("tabs"),className:G,style:K}=Q,q=O("stx-tabs",`stx-tabs--${X}`,G),J=V(K),E=Y.map((U,_)=>{let R=Z?U.value===Z:_===0;return`<button class="${O("stx-tab",R&&"stx-tab--active",U.disabled&&"stx-tab--disabled")}" data-value="${F(U.value)}" ${U.disabled?"disabled":""} role="tab" aria-selected="${R}">${F(U.label)}</button>`}).join("");return`<div id="${$}" class="${q}" role="tablist" ${J?`style='${J}'`:""}>${E}</div>`}function DQ(Q){let{options:Y,value:Z,placeholder:X="Select...",disabled:$=!1,id:G=z("dropdown"),className:K,style:q}=Q,J=O("stx-dropdown",$&&"stx-dropdown--disabled",K),E=V(q),U=Y.map((R)=>{let B=R.value===Z?"selected":"",j=R.disabled?"disabled":"";return`<option value="${F(R.value)}" ${B} ${j}>${F(R.label)}</option>`}).join(""),_=Z?"":`<option value="" disabled selected>${F(X)}</option>`;return`<select id="${G}" class="${J}" ${$?"disabled":""} ${E?`style='${E}'`:""}>${_}${U}</select>`}function PQ(Q){let{value:Y=0,max:Z=5,readonly:X=!1,size:$="medium",allowHalf:G=!1,id:K=z("rating"),className:q,style:J}=Q,E=O("stx-rating",`stx-rating--${$}`,X&&"stx-rating--readonly",q),U=V(J),_="";for(let R=1;R<=Z;R++){let B=R<=Y,j=G&&R-0.5===Y;_+=`<span class="stx-star ${B?"stx-star--filled":j?"stx-star--half":""}" data-value="${R}">\u2605</span>`}return`<div id="${K}" class="${E}" role="slider" aria-valuenow="${Y}" aria-valuemin="0" aria-valuemax="${Z}" ${U?`style='${U}'`:""}>${_}</div>`}function WQ(Q){let{value:Y,name:Z,checked:X=!1,label:$,disabled:G=!1,id:K=z("radio"),className:q,style:J}=Q,E=O("stx-radio",G&&"stx-radio--disabled",q),U=V(J),_=['type="radio"',`id="${K}"`,`name="${F(Z)}"`,`value="${F(Y)}"`,X&&"checked",G&&"disabled"].filter(Boolean).join(" ");return`
18
- <label class="${E}" ${U?`style="${U}"`:""}>
19
- <input ${_} />
13
+ `}function PY(Y){let{text:Z,variant:Q="default",size:X="medium",id:$=z("badge"),className:J,style:K}=Y,R=O("stx-badge",`stx-badge--${Q}`,`stx-badge--${X}`,J),G=V(K);return`<span id="${$}" class="${R}" ${G?`style='${G}'`:""}>${F(Z)}</span>`}function AY(Y){let{src:Z,alt:Q="",name:X,size:$="medium",shape:J="circle",id:K=z("avatar"),className:R,style:G}=Y,_=typeof $==="number"?"":`stx-avatar--${$}`,U=typeof $==="number"?`width: ${$}px; height: ${$}px;`:"",E=O("stx-avatar",_,`stx-avatar--${J}`,R),q=[U,V(G)].filter(Boolean).join(" "),j=X?X.split(" ").map((B)=>B[0]).join("").toUpperCase().slice(0,2):"";if(Z)return`<div id="${K}" class="${E}" ${q?`style="${q}"`:""}>
14
+ <img src="${F(Z)}" alt="${F(Q)}" class="stx-avatar-img" />
15
+ </div>`;return`<div id="${K}" class="${E}" ${q?`style="${q}"`:""}>
16
+ <span class="stx-avatar-initials">${j}</span>
17
+ </div>`}function NY(Y){let{title:Z,subtitle:Q,content:X,image:$,footer:J,variant:K="default",id:R=z("card"),className:G,style:_}=Y,U=O("stx-card",`stx-card--${K}`,G),E=V(_),q="";if($)q+=`<div class="stx-card-image"><img src="${F($)}" alt="" /></div>`;if(q+='<div class="stx-card-body">',Z)q+=`<h3 class="stx-card-title">${F(Z)}</h3>`;if(Q)q+=`<p class="stx-card-subtitle">${F(Q)}</p>`;if(X)q+=`<div class="stx-card-content">${F(X)}</div>`;if(q+="</div>",J)q+=`<div class="stx-card-footer">${F(J)}</div>`;return`<div id="${R}" class="${U}" ${E?`style='${E}'`:""}>${q}</div>`}function kY(Y){let{tabs:Z,activeTab:Q,variant:X="default",id:$=z("tabs"),className:J,style:K}=Y,R=O("stx-tabs",`stx-tabs--${X}`,J),G=V(K),_=Z.map((U,E)=>{let q=Q?U.value===Q:E===0;return`<button class="${O("stx-tab",q&&"stx-tab--active",U.disabled&&"stx-tab--disabled")}" data-value="${F(U.value)}" ${U.disabled?"disabled":""} role="tab" aria-selected="${q}">${F(U.label)}</button>`}).join("");return`<div id="${$}" class="${R}" role="tablist" ${G?`style='${G}'`:""}>${_}</div>`}function CY(Y){let{options:Z,value:Q,placeholder:X="Select...",disabled:$=!1,id:J=z("dropdown"),className:K,style:R}=Y,G=O("stx-dropdown",$&&"stx-dropdown--disabled",K),_=V(R),U=Z.map((q)=>{let j=q.value===Q?"selected":"",B=q.disabled?"disabled":"";return`<option value="${F(q.value)}" ${j} ${B}>${F(q.label)}</option>`}).join(""),E=Q?"":`<option value="" disabled selected>${F(X)}</option>`;return`<select id="${J}" class="${G}" ${$?"disabled":""} ${_?`style='${_}'`:""}>${E}${U}</select>`}function IY(Y){let{value:Z=0,max:Q=5,readonly:X=!1,size:$="medium",allowHalf:J=!1,id:K=z("rating"),className:R,style:G}=Y,_=O("stx-rating",`stx-rating--${$}`,X&&"stx-rating--readonly",R),U=V(G),E="";for(let q=1;q<=Q;q++){let j=q<=Z,B=J&&q-0.5===Z;E+=`<span class="stx-star ${j?"stx-star--filled":B?"stx-star--half":""}" data-value="${q}">\u2605</span>`}return`<div id="${K}" class="${_}" role="slider" aria-valuenow="${Z}" aria-valuemin="0" aria-valuemax="${Q}" ${U?`style='${U}'`:""}>${E}</div>`}function xY(Y){let{value:Z,name:Q,checked:X=!1,label:$,disabled:J=!1,id:K=z("radio"),className:R,style:G}=Y,_=O("stx-radio",J&&"stx-radio--disabled",R),U=V(G),E=['type="radio"',`id="${K}"`,`name="${F(Q)}"`,`value="${F(Z)}"`,X&&"checked",J&&"disabled"].filter(Boolean).join(" ");return`
18
+ <label class="${_}" ${U?`style="${U}"`:""}>
19
+ <input ${E} />
20
20
  <span class="stx-radio-circle"></span>
21
21
  ${$?`<span class="stx-radio-label">${F($)}</span>`:""}
22
22
  </label>
23
- `}function AQ(Q){let{value:Y="#3498db",disabled:Z=!1,label:X,presetColors:$=["#e74c3c","#f39c12","#27ae60","#3498db","#9b59b6","#1abc9c","#34495e","#000000"],id:G=z("color"),className:K,style:q}=Q,J=O("stx-color-picker",Z&&"stx-color-picker--disabled",K),E=V(q),U="";if(X)U+=`<label class="stx-color-picker-label" for="${G}">${F(X)}</label>`;if(U+=`<div class="stx-color-picker-input">
24
- <input type="color" id="${G}" value="${F(Y)}" ${Z?"disabled":""} />
25
- <span class="stx-color-picker-value">${F(Y)}</span>
26
- </div>`,$.length>0){U+='<div class="stx-color-picker-presets">';for(let _ of $)U+=`<button class="stx-color-preset" style="background: ${F(_)}" data-color="${F(_)}" ${Z?"disabled":""}></button>`;U+="</div>"}return`<div class="${J}" ${E?`style='${E}'`:""}>${U}</div>`}function NQ(Q){let{value:Y,min:Z,max:X,disabled:$=!1,label:G,placeholder:K="Select date",showClear:q=!0,id:J=z("date"),className:E,style:U}=Q,_=O("stx-date-picker",$&&"stx-date-picker--disabled",E),R=V(U),B=Y instanceof Date?Y.toISOString().split("T")[0]:Y||"",j=Z instanceof Date?Z.toISOString().split("T")[0]:Z,M=X instanceof Date?X.toISOString().split("T")[0]:X,T=['type="date"',`id="${J}"`,B&&`value="${B}"`,j&&`min="${j}"`,M&&`max="${M}"`,$&&"disabled",`placeholder="${F(K)}"`].filter(Boolean).join(" "),L="";if(G)L+=`<label class="stx-date-picker-label" for="${J}">${F(G)}</label>`;return L+=`<div class="stx-date-picker-input">
27
- <input ${T} />
28
- ${q&&B?'<button class="stx-date-picker-clear" type="button">&times;</button>':""}
29
- </div>`,`<div class="${_}" ${R?`style='${R}'`:""}>${L}</div>`}function xQ(Q){let{value:Y="",disabled:Z=!1,label:X,step:$=60,min:G,max:K,id:q=z("time"),className:J,style:E}=Q,U=O("stx-time-picker",Z&&"stx-time-picker--disabled",J),_=V(E),R=['type="time"',`id="${q}"`,Y&&`value="${F(Y)}"`,`step="${$}"`,G&&`min="${F(G)}"`,K&&`max="${F(K)}"`,Z&&"disabled"].filter(Boolean).join(" "),B="";if(X)B+=`<label class="stx-time-picker-label" for="${q}">${F(X)}</label>`;return B+=`<input ${R} class="stx-time-picker-input" />`,`<div class="${U}" ${_?`style='${_}'`:""}>${B}</div>`}function IQ(Q){let{options:Y,value:Z="",placeholder:X="Search...",disabled:$=!1,label:G,loading:K=!1,id:q=z("autocomplete"),className:J,style:E}=Q,U=O("stx-autocomplete",$&&"stx-autocomplete--disabled",J),_=V(E),R=Y.find((M)=>M.value===Z),B=R?R.label:Z,j="";if(G)j+=`<label class="stx-autocomplete-label" for="${q}">${F(G)}</label>`;j+=`<div class="stx-autocomplete-input-wrapper">
30
- <input type="text" id="${q}" value="${F(B)}" placeholder="${F(X)}" ${$?"disabled":""} autocomplete="off" class="stx-autocomplete-input" />
23
+ `}function HY(Y){let{value:Z="#3498db",disabled:Q=!1,label:X,presetColors:$=["#e74c3c","#f39c12","#27ae60","#3498db","#9b59b6","#1abc9c","#34495e","#000000"],id:J=z("color"),className:K,style:R}=Y,G=O("stx-color-picker",Q&&"stx-color-picker--disabled",K),_=V(R),U="";if(X)U+=`<label class="stx-color-picker-label" for="${J}">${F(X)}</label>`;if(U+=`<div class="stx-color-picker-input">
24
+ <input type="color" id="${J}" value="${F(Z)}" ${Q?"disabled":""} />
25
+ <span class="stx-color-picker-value">${F(Z)}</span>
26
+ </div>`,$.length>0){U+='<div class="stx-color-picker-presets">';for(let E of $)U+=`<button class="stx-color-preset" style="background: ${F(E)}" data-color="${F(E)}" ${Q?"disabled":""}></button>`;U+="</div>"}return`<div class="${G}" ${_?`style='${_}'`:""}>${U}</div>`}function vY(Y){let{value:Z,min:Q,max:X,disabled:$=!1,label:J,placeholder:K="Select date",showClear:R=!0,id:G=z("date"),className:_,style:U}=Y,E=O("stx-date-picker",$&&"stx-date-picker--disabled",_),q=V(U),j=Z instanceof Date?Z.toISOString().split("T")[0]:Z||"",B=Q instanceof Date?Q.toISOString().split("T")[0]:Q,M=X instanceof Date?X.toISOString().split("T")[0]:X,L=['type="date"',`id="${G}"`,j&&`value="${j}"`,B&&`min="${B}"`,M&&`max="${M}"`,$&&"disabled",`placeholder="${F(K)}"`].filter(Boolean).join(" "),T="";if(J)T+=`<label class="stx-date-picker-label" for="${G}">${F(J)}</label>`;return T+=`<div class="stx-date-picker-input">
27
+ <input ${L} />
28
+ ${R&&j?'<button class="stx-date-picker-clear" type="button">&times;</button>':""}
29
+ </div>`,`<div class="${E}" ${q?`style='${q}'`:""}>${T}</div>`}function wY(Y){let{value:Z="",disabled:Q=!1,label:X,step:$=60,min:J,max:K,id:R=z("time"),className:G,style:_}=Y,U=O("stx-time-picker",Q&&"stx-time-picker--disabled",G),E=V(_),q=['type="time"',`id="${R}"`,Z&&`value="${F(Z)}"`,`step="${$}"`,J&&`min="${F(J)}"`,K&&`max="${F(K)}"`,Q&&"disabled"].filter(Boolean).join(" "),j="";if(X)j+=`<label class="stx-time-picker-label" for="${R}">${F(X)}</label>`;return j+=`<input ${q} class="stx-time-picker-input" />`,`<div class="${U}" ${E?`style='${E}'`:""}>${j}</div>`}function fY(Y){let{options:Z,value:Q="",placeholder:X="Search...",disabled:$=!1,label:J,loading:K=!1,id:R=z("autocomplete"),className:G,style:_}=Y,U=O("stx-autocomplete",$&&"stx-autocomplete--disabled",G),E=V(_),q=Z.find((M)=>M.value===Q),j=q?q.label:Q,B="";if(J)B+=`<label class="stx-autocomplete-label" for="${R}">${F(J)}</label>`;B+=`<div class="stx-autocomplete-input-wrapper">
30
+ <input type="text" id="${R}" value="${F(j)}" placeholder="${F(X)}" ${$?"disabled":""} autocomplete="off" class="stx-autocomplete-input" />
31
31
  ${K?'<span class="stx-autocomplete-spinner"></span>':""}
32
- </div>`,j+='<ul class="stx-autocomplete-list">';for(let M of Y)j+=`<li class="stx-autocomplete-item ${M.value===Z?"stx-autocomplete-item--selected":""}" data-value="${F(M.value)}">${F(M.label)}</li>`;return j+="</ul>",`<div class="${U}" ${_?`style='${_}'`:""}>${j}</div>`}function kQ(Q){let{text:Y,htmlFor:Z,required:X=!1,size:$="medium",id:G=z("label"),className:K,style:q}=Q,J=O("stx-label",`stx-label--${$}`,K),E=V(q);return`<label id="${G}" class="${J}" ${Z?`for='${F(Z)}'`:""} ${E?`style='${E}'`:""}>${F(Y)}${X?'<span class="stx-label-required">*</span>':""}</label>`}function CQ(Q){let{src:Y,alt:Z="",width:X,height:$,objectFit:G="cover",fallback:K,loading:q="lazy",id:J=z("image"),className:E,style:U}=Q,_=O("stx-image",E),R={objectFit:G};if(X)R.width=typeof X==="number"?`${X}px`:X;if($)R.height=typeof $==="number"?`${$}px`:$;let B=[V(R),V(U)].filter(Boolean).join("; "),j=K?`onerror="this.src='${F(K)}'"`:"";return`<img id="${J}" class="${_}" src="${F(Y)}" alt="${F(Z)}" loading="${q}" ${B?`style='${B}'`:""} ${j} />`}function HQ(Q){let{text:Y,variant:Z="default",size:X="medium",removable:$=!1,icon:G,id:K=z("chip"),className:q,style:J}=Q,E=O("stx-chip",`stx-chip--${Z}`,`stx-chip--${X}`,q),U=V(J),_="";if(G)_+=`<span class="stx-chip-icon">${G}</span>`;if(_+=`<span class="stx-chip-text">${F(Y)}</span>`,$)_+='<button class="stx-chip-remove" type="button">&times;</button>';return`<span id="${K}" class="${E}" ${U?`style='${U}'`:""}>${_}</span>`}function vQ(Q){let{text:Y,position:Z="top",delay:X=200,children:$,id:G=z("tooltip"),className:K,style:q}=Q,J=O("stx-tooltip-wrapper",K),E=V(q);return`<div id="${G}" class="${J}" ${E?`style="${E}"`:""} data-tooltip="${F(Y)}" data-position="${Z}" data-delay="${X}">
32
+ </div>`,B+='<ul class="stx-autocomplete-list">';for(let M of Z)B+=`<li class="stx-autocomplete-item ${M.value===Q?"stx-autocomplete-item--selected":""}" data-value="${F(M.value)}">${F(M.label)}</li>`;return B+="</ul>",`<div class="${U}" ${E?`style='${E}'`:""}>${B}</div>`}function SY(Y){let{text:Z,htmlFor:Q,required:X=!1,size:$="medium",id:J=z("label"),className:K,style:R}=Y,G=O("stx-label",`stx-label--${$}`,K),_=V(R);return`<label id="${J}" class="${G}" ${Q?`for='${F(Q)}'`:""} ${_?`style='${_}'`:""}>${F(Z)}${X?'<span class="stx-label-required">*</span>':""}</label>`}function gY(Y){let{src:Z,alt:Q="",width:X,height:$,objectFit:J="cover",fallback:K,loading:R="lazy",id:G=z("image"),className:_,style:U}=Y,E=O("stx-image",_),q={objectFit:J};if(X)q.width=typeof X==="number"?`${X}px`:X;if($)q.height=typeof $==="number"?`${$}px`:$;let j=[V(q),V(U)].filter(Boolean).join("; "),B=K?`onerror="this.src='${F(K)}'"`:"";return`<img id="${G}" class="${E}" src="${F(Z)}" alt="${F(Q)}" loading="${R}" ${j?`style='${j}'`:""} ${B} />`}function bY(Y){let{text:Z,variant:Q="default",size:X="medium",removable:$=!1,icon:J,id:K=z("chip"),className:R,style:G}=Y,_=O("stx-chip",`stx-chip--${Q}`,`stx-chip--${X}`,R),U=V(G),E="";if(J)E+=`<span class="stx-chip-icon">${J}</span>`;if(E+=`<span class="stx-chip-text">${F(Z)}</span>`,$)E+='<button class="stx-chip-remove" type="button">&times;</button>';return`<span id="${K}" class="${_}" ${U?`style='${U}'`:""}>${E}</span>`}function yY(Y){let{text:Z,position:Q="top",delay:X=200,children:$,id:J=z("tooltip"),className:K,style:R}=Y,G=O("stx-tooltip-wrapper",K),_=V(R);return`<div id="${J}" class="${G}" ${_?`style="${_}"`:""} data-tooltip="${F(Z)}" data-position="${Q}" data-delay="${X}">
33
33
  ${$}
34
- <span class="stx-tooltip stx-tooltip--${Z}">${F(Y)}</span>
35
- </div>`}function wQ(Q){let{direction:Y="vertical",showScrollbar:Z=!0,smooth:X=!0,height:$,width:G,children:K,id:q=z("scroll"),className:J,style:E}=Q,U=O("stx-scroll-view",`stx-scroll-view--${Y}`,!Z&&"stx-scroll-view--hide-scrollbar",X&&"stx-scroll-view--smooth",J),_={};if($)_.height=typeof $==="number"?`${$}px`:$;if(G)_.width=typeof G==="number"?`${G}px`:G;let R=[V(_),V(E)].filter(Boolean).join("; ");return`<div id="${q}" class="${U}" ${R?`style='${R}'`:""}>${K}</div>`}function fQ(Q){let{direction:Y="horizontal",sizes:Z=[50,50],resizable:X=!0,children:$,id:G=z("split"),className:K,style:q}=Q,J=O("stx-split-view",`stx-split-view--${Y}`,X&&"stx-split-view--resizable",K),E=V(q),U=Y==="horizontal"?"width":"height";return`<div id="${G}" class="${J}" ${E?`style="${E}"`:""}>
36
- <div class="stx-split-pane" style="${U}: ${Z[0]}%">${$[0]}</div>
34
+ <span class="stx-tooltip stx-tooltip--${Q}">${F(Z)}</span>
35
+ </div>`}function uY(Y){let{direction:Z="vertical",showScrollbar:Q=!0,smooth:X=!0,height:$,width:J,children:K,id:R=z("scroll"),className:G,style:_}=Y,U=O("stx-scroll-view",`stx-scroll-view--${Z}`,!Q&&"stx-scroll-view--hide-scrollbar",X&&"stx-scroll-view--smooth",G),E={};if($)E.height=typeof $==="number"?`${$}px`:$;if(J)E.width=typeof J==="number"?`${J}px`:J;let q=[V(E),V(_)].filter(Boolean).join("; ");return`<div id="${R}" class="${U}" ${q?`style='${q}'`:""}>${K}</div>`}function hY(Y){let{direction:Z="horizontal",sizes:Q=[50,50],resizable:X=!0,children:$,id:J=z("split"),className:K,style:R}=Y,G=O("stx-split-view",`stx-split-view--${Z}`,X&&"stx-split-view--resizable",K),_=V(R),U=Z==="horizontal"?"width":"height";return`<div id="${J}" class="${G}" ${_?`style="${_}"`:""}>
36
+ <div class="stx-split-pane" style="${U}: ${Q[0]}%">${$[0]}</div>
37
37
  ${X?'<div class="stx-split-divider"></div>':""}
38
- <div class="stx-split-pane" style="${U}: ${Z[1]}%">${$[1]}</div>
39
- </div>`}function SQ(Q){let{items:Y,multiple:Z=!1,defaultOpen:X=[],id:$=z("accordion"),className:G,style:K}=Q,q=O("stx-accordion",G),J=V(K),E="";return Y.forEach((U,_)=>{let R=X.includes(_),B=O("stx-accordion-item",R&&"stx-accordion-item--open",U.disabled&&"stx-accordion-item--disabled");E+=`<div class="${B}" data-index="${_}">
40
- <button class="stx-accordion-header" ${U.disabled?"disabled":""} aria-expanded="${R}" data-multiple="${Z}">
38
+ <div class="stx-split-pane" style="${U}: ${Q[1]}%">${$[1]}</div>
39
+ </div>`}function mY(Y){let{items:Z,multiple:Q=!1,defaultOpen:X=[],id:$=z("accordion"),className:J,style:K}=Y,R=O("stx-accordion",J),G=V(K),_="";return Z.forEach((U,E)=>{let q=X.includes(E),j=O("stx-accordion-item",q&&"stx-accordion-item--open",U.disabled&&"stx-accordion-item--disabled");_+=`<div class="${j}" data-index="${E}">
40
+ <button class="stx-accordion-header" ${U.disabled?"disabled":""} aria-expanded="${q}" data-multiple="${Q}">
41
41
  <span class="stx-accordion-title">${F(U.title)}</span>
42
42
  <span class="stx-accordion-icon">\u25BC</span>
43
43
  </button>
44
- <div class="stx-accordion-content" ${R?"":"hidden"}>
44
+ <div class="stx-accordion-content" ${q?"":"hidden"}>
45
45
  ${F(U.content)}
46
46
  </div>
47
- </div>`}),`<div id="${$}" class="${q}" ${J?`style='${J}'`:""}>${E}</div>`}function gQ(Q){let{steps:Y,currentStep:Z,orientation:X="horizontal",id:$=z("stepper"),className:G,style:K}=Q,q=O("stx-stepper",`stx-stepper--${X}`,G),J=V(K),E="";return Y.forEach((U,_)=>{let R=O("stx-step",_<Z&&"stx-step--completed",_===Z&&"stx-step--active");if(E+=`<div class="${R}" data-step="${_}">
47
+ </div>`}),`<div id="${$}" class="${R}" ${G?`style='${G}'`:""}>${_}</div>`}function cY(Y){let{steps:Z,currentStep:Q,orientation:X="horizontal",id:$=z("stepper"),className:J,style:K}=Y,R=O("stx-stepper",`stx-stepper--${X}`,J),G=V(K),_="";return Z.forEach((U,E)=>{let q=O("stx-step",E<Q&&"stx-step--completed",E===Q&&"stx-step--active");if(_+=`<div class="${q}" data-step="${E}">
48
48
  <div class="stx-step-indicator">
49
- ${_<Z?"\u2713":_+1}
49
+ ${E<Q?"\u2713":E+1}
50
50
  </div>
51
51
  <div class="stx-step-content">
52
52
  <div class="stx-step-label">${F(U.label)}</div>
53
53
  ${U.description?`<div class="stx-step-description">${F(U.description)}</div>`:""}
54
54
  </div>
55
- </div>`,_<Y.length-1)E+='<div class="stx-step-connector"></div>'}),`<div id="${$}" class="${q}" ${J?`style='${J}'`:""}>${E}</div>`}function bQ(Q){let{open:Y=!1,title:Z,size:X="medium",closable:$=!0,children:G,footer:K,id:q=z("modal"),className:J,style:E}=Q,U=O("stx-modal-component",`stx-modal-component--${X}`,J),_=V(E);if(!Y)return`<div id="${q}" class="${U} stx-modal-component--hidden" ${_?`style='${_}'`:""}></div>`;let R='<div class="stx-modal-component-overlay">';if(R+='<div class="stx-modal-component-dialog">',Z||$){if(R+='<div class="stx-modal-component-header">',Z)R+=`<h3 class="stx-modal-component-title">${F(Z)}</h3>`;if($)R+='<button class="stx-modal-component-close">&times;</button>';R+="</div>"}if(R+=`<div class="stx-modal-component-body">${G}</div>`,K)R+=`<div class="stx-modal-component-footer">${K}</div>`;return R+="</div></div>",`<div id="${q}" class="${U}" ${_?`style='${_}'`:""}>${R}</div>`}function uQ(Q){let{items:Y,selectable:Z=!1,multiSelect:X=!1,emptyMessage:$="No items",id:G=z("list"),className:K,style:q}=Q,J=O("stx-list-view",Z&&"stx-list-view--selectable",X&&"stx-list-view--multi",K),E=V(q);if(Y.length===0)return`<div id="${G}" class="${J}" ${E?`style="${E}"`:""}>
55
+ </div>`,E<Z.length-1)_+='<div class="stx-step-connector"></div>'}),`<div id="${$}" class="${R}" ${G?`style='${G}'`:""}>${_}</div>`}function dY(Y){let{open:Z=!1,title:Q,size:X="medium",closable:$=!0,children:J,footer:K,id:R=z("modal"),className:G,style:_}=Y,U=O("stx-modal-component",`stx-modal-component--${X}`,G),E=V(_);if(!Z)return`<div id="${R}" class="${U} stx-modal-component--hidden" ${E?`style='${E}'`:""}></div>`;let q='<div class="stx-modal-component-overlay">';if(q+='<div class="stx-modal-component-dialog">',Q||$){if(q+='<div class="stx-modal-component-header">',Q)q+=`<h3 class="stx-modal-component-title">${F(Q)}</h3>`;if($)q+='<button class="stx-modal-component-close">&times;</button>';q+="</div>"}if(q+=`<div class="stx-modal-component-body">${J}</div>`,K)q+=`<div class="stx-modal-component-footer">${K}</div>`;return q+="</div></div>",`<div id="${R}" class="${U}" ${E?`style='${E}'`:""}>${q}</div>`}function pY(Y){let{items:Z,selectable:Q=!1,multiSelect:X=!1,emptyMessage:$="No items",id:J=z("list"),className:K,style:R}=Y,G=O("stx-list-view",Q&&"stx-list-view--selectable",X&&"stx-list-view--multi",K),_=V(R);if(Z.length===0)return`<div id="${J}" class="${G}" ${_?`style="${_}"`:""}>
56
56
  <div class="stx-list-view-empty">${F($)}</div>
57
- </div>`;let U='<ul class="stx-list-view-items">';for(let _ of Y){let R=O("stx-list-view-item",_.selected&&"stx-list-view-item--selected");U+=`<li class="${R}" data-id="${F(_.id)}" ${Z?'tabindex="0"':""}>${_.content}</li>`}return U+="</ul>",`<div id="${G}" class="${J}" ${E?`style='${E}'`:""}>${U}</div>`}function yQ(Q){let{columns:Y,data:Z,striped:X=!1,bordered:$=!1,hoverable:G=!0,sortBy:K,sortOrder:q,id:J=z("table"),className:E,style:U}=Q,_=O("stx-table",X&&"stx-table--striped",$&&"stx-table--bordered",G&&"stx-table--hoverable",E),R=V(U),B="<table>";B+="<thead><tr>";for(let j of Y){let T=j.key===K?`stx-table-sorted stx-table-sorted--${q}`:"",L=j.sortable?'data-sortable="true"':"",w=j.width?`style="width: ${j.width}"`:"";B+=`<th class="${T}" ${L} ${w} data-key="${F(j.key)}">${F(j.label)}${j.sortable?'<span class="stx-table-sort-icon"></span>':""}</th>`}B+="</tr></thead>",B+="<tbody>";for(let j of Z){B+="<tr>";for(let M of Y){let T=j[M.key];B+=`<td>${T!=null?F(String(T)):""}</td>`}B+="</tr>"}return B+="</tbody></table>",`<div id="${J}" class="${_}" ${R?`style='${R}'`:""}>${B}</div>`}function p(Q,Y,Z,X){let $=Y.includes(Q.key),G=Z.includes(Q.key),K=Q.children&&Q.children.length>0,J=`<div class="${O("stx-tree-node",G&&"stx-tree-node--selected",Q.disabled&&"stx-tree-node--disabled")}" data-key="${F(Q.key)}">`;if(J+='<div class="stx-tree-node-content">',K)J+=`<span class="stx-tree-toggle ${$?"stx-tree-toggle--expanded":""}">\u25B6</span>`;else J+='<span class="stx-tree-toggle-placeholder"></span>';if(X)J+=`<input type="checkbox" class="stx-tree-checkbox" ${G?"checked":""} ${Q.disabled?"disabled":""} />`;if(Q.icon)J+=`<span class="stx-tree-icon">${Q.icon}</span>`;if(J+=`<span class="stx-tree-label">${F(Q.label)}</span>`,J+="</div>",K&&$){J+='<div class="stx-tree-children">';for(let E of Q.children)J+=p(E,Y,Z,X);J+="</div>"}return J+="</div>",J}function hQ(Q){let{nodes:Y,expandedKeys:Z=[],selectedKeys:X=[],checkable:$=!1,id:G=z("tree"),className:K,style:q}=Q,J=O("stx-tree-view",$&&"stx-tree-view--checkable",K),E=V(q),U="";for(let _ of Y)U+=p(_,Z,X,$);return`<div id="${G}" class="${J}" role="tree" ${E?`style='${E}'`:""}>${U}</div>`}function mQ(Q){let{columns:Y,data:Z,pagination:X,selectable:$=!1,id:G=z("datagrid"),className:K,style:q}=Q,J=O("stx-data-grid",$&&"stx-data-grid--selectable",K),E=V(q),U='<div class="stx-data-grid-table-wrapper">';if(U+='<table class="stx-data-grid-table">',U+="<thead><tr>",$)U+='<th class="stx-data-grid-select-all"><input type="checkbox" /></th>';for(let _ of Y){let R=_.width?`style="width: ${_.width}"`:"";U+=`<th ${R}>
57
+ </div>`;let U='<ul class="stx-list-view-items">';for(let E of Z){let q=O("stx-list-view-item",E.selected&&"stx-list-view-item--selected");U+=`<li class="${q}" data-id="${F(E.id)}" ${Q?'tabindex="0"':""}>${E.content}</li>`}return U+="</ul>",`<div id="${J}" class="${G}" ${_?`style='${_}'`:""}>${U}</div>`}function rY(Y){let{columns:Z,data:Q,striped:X=!1,bordered:$=!1,hoverable:J=!0,sortBy:K,sortOrder:R,id:G=z("table"),className:_,style:U}=Y,E=O("stx-table",X&&"stx-table--striped",$&&"stx-table--bordered",J&&"stx-table--hoverable",_),q=V(U),j="<table>";j+="<thead><tr>";for(let B of Z){let L=B.key===K?`stx-table-sorted stx-table-sorted--${R}`:"",T=B.sortable?'data-sortable="true"':"",f=B.width?`style="width: ${B.width}"`:"";j+=`<th class="${L}" ${T} ${f} data-key="${F(B.key)}">${F(B.label)}${B.sortable?'<span class="stx-table-sort-icon"></span>':""}</th>`}j+="</tr></thead>",j+="<tbody>";for(let B of Q){j+="<tr>";for(let M of Z){let L=B[M.key];j+=`<td>${L!=null?F(String(L)):""}</td>`}j+="</tr>"}return j+="</tbody></table>",`<div id="${G}" class="${E}" ${q?`style='${q}'`:""}>${j}</div>`}function o(Y,Z,Q,X){let $=Z.includes(Y.key),J=Q.includes(Y.key),K=Y.children&&Y.children.length>0,G=`<div class="${O("stx-tree-node",J&&"stx-tree-node--selected",Y.disabled&&"stx-tree-node--disabled")}" data-key="${F(Y.key)}">`;if(G+='<div class="stx-tree-node-content">',K)G+=`<span class="stx-tree-toggle ${$?"stx-tree-toggle--expanded":""}">\u25B6</span>`;else G+='<span class="stx-tree-toggle-placeholder"></span>';if(X)G+=`<input type="checkbox" class="stx-tree-checkbox" ${J?"checked":""} ${Y.disabled?"disabled":""} />`;if(Y.icon)G+=`<span class="stx-tree-icon">${Y.icon}</span>`;if(G+=`<span class="stx-tree-label">${F(Y.label)}</span>`,G+="</div>",K&&$){G+='<div class="stx-tree-children">';for(let _ of Y.children)G+=o(_,Z,Q,X);G+="</div>"}return G+="</div>",G}function nY(Y){let{nodes:Z,expandedKeys:Q=[],selectedKeys:X=[],checkable:$=!1,id:J=z("tree"),className:K,style:R}=Y,G=O("stx-tree-view",$&&"stx-tree-view--checkable",K),_=V(R),U="";for(let E of Z)U+=o(E,Q,X,$);return`<div id="${J}" class="${G}" role="tree" ${_?`style='${_}'`:""}>${U}</div>`}function oY(Y){let{columns:Z,data:Q,pagination:X,selectable:$=!1,id:J=z("datagrid"),className:K,style:R}=Y,G=O("stx-data-grid",$&&"stx-data-grid--selectable",K),_=V(R),U='<div class="stx-data-grid-table-wrapper">';if(U+='<table class="stx-data-grid-table">',U+="<thead><tr>",$)U+='<th class="stx-data-grid-select-all"><input type="checkbox" /></th>';for(let E of Z){let q=E.width?`style="width: ${E.width}"`:"";U+=`<th ${q}>
58
58
  <div class="stx-data-grid-header-cell">
59
- <span>${F(_.label)}</span>
60
- ${_.sortable?'<button class="stx-data-grid-sort">\u21C5</button>':""}
61
- ${_.filterable?'<button class="stx-data-grid-filter">\u22BB</button>':""}
59
+ <span>${F(E.label)}</span>
60
+ ${E.sortable?'<button class="stx-data-grid-sort">\u21C5</button>':""}
61
+ ${E.filterable?'<button class="stx-data-grid-filter">\u22BB</button>':""}
62
62
  </div>
63
- </th>`}U+="</tr></thead>",U+="<tbody>";for(let _ of Z){if(U+="<tr>",$)U+='<td class="stx-data-grid-select"><input type="checkbox" /></td>';for(let R of Y){let B=_[R.key];U+=`<td>${B!=null?F(String(B)):""}</td>`}U+="</tr>"}if(U+="</tbody></table></div>",X){let _=Math.ceil(X.total/X.pageSize);U+=`<div class="stx-data-grid-pagination">
64
- <span class="stx-data-grid-page-info">Page ${X.page} of ${_} (${X.total} items)</span>
63
+ </th>`}U+="</tr></thead>",U+="<tbody>";for(let E of Q){if(U+="<tr>",$)U+='<td class="stx-data-grid-select"><input type="checkbox" /></td>';for(let q of Z){let j=E[q.key];U+=`<td>${j!=null?F(String(j)):""}</td>`}U+="</tr>"}if(U+="</tbody></table></div>",X){let E=Math.ceil(X.total/X.pageSize);U+=`<div class="stx-data-grid-pagination">
64
+ <span class="stx-data-grid-page-info">Page ${X.page} of ${E} (${X.total} items)</span>
65
65
  <div class="stx-data-grid-page-buttons">
66
66
  <button class="stx-data-grid-page-btn" ${X.page<=1?"disabled":""}>\u25C0</button>
67
- <button class="stx-data-grid-page-btn" ${X.page>=_?"disabled":""}>\u25B6</button>
67
+ <button class="stx-data-grid-page-btn" ${X.page>=E?"disabled":""}>\u25B6</button>
68
68
  </div>
69
- </div>`}return`<div id="${G}" class="${J}" ${E?`style='${E}'`:""}>${U}</div>`}function cQ(Q){let{type:Y,data:Z,options:X={},width:$="100%",height:G=300,id:K=z("chart"),className:q,style:J}=Q,E=O("stx-chart",`stx-chart--${Y}`,q),U={width:typeof $==="number"?`${$}px`:$,height:typeof G==="number"?`${G}px`:G},_=[V(U),V(J)].filter(Boolean).join("; "),R=JSON.stringify({type:Y,data:Z,options:X});return`<div id="${K}" class="${E}" style="${_}" data-chart='${F(R)}'>
69
+ </div>`}return`<div id="${J}" class="${G}" ${_?`style='${_}'`:""}>${U}</div>`}function lY(Y){let{type:Z,data:Q,options:X={},width:$="100%",height:J=300,id:K=z("chart"),className:R,style:G}=Y,_=O("stx-chart",`stx-chart--${Z}`,R),U={width:typeof $==="number"?`${$}px`:$,height:typeof J==="number"?`${J}px`:J},E=[V(U),V(G)].filter(Boolean).join("; "),q=JSON.stringify({type:Z,data:Q,options:X});return`<div id="${K}" class="${_}" style="${E}" data-chart='${F(q)}'>
70
70
  <div class="stx-chart-placeholder">
71
71
  ${X.title?`<div class="stx-chart-title">${F(X.title)}</div>`:""}
72
- <div class="stx-chart-type">${Y.charAt(0).toUpperCase()+Y.slice(1)} Chart</div>
73
- <div class="stx-chart-info">${Z.datasets.length} dataset(s), ${Z.labels.length} labels</div>
72
+ <div class="stx-chart-type">${Z.charAt(0).toUpperCase()+Z.slice(1)} Chart</div>
73
+ <div class="stx-chart-info">${Q.datasets.length} dataset(s), ${Q.labels.length} labels</div>
74
74
  </div>
75
- </div>`}function dQ(Q){let{value:Y="",language:Z="plaintext",theme:X="dark",lineNumbers:$=!0,readOnly:G=!1,height:K=300,tabSize:q=2,wordWrap:J=!1,id:E=z("code"),className:U,style:_}=Q,R=O("stx-code-editor",`stx-code-editor--${X}`,$&&"stx-code-editor--line-numbers",G&&"stx-code-editor--readonly",J&&"stx-code-editor--wrap",U),B={height:typeof K==="number"?`${K}px`:K},j=[V(B),V(_)].filter(Boolean).join("; "),M=Y.split(`
76
- `),T="";if($){T+='<div class="stx-code-editor-gutter">';for(let L=1;L<=M.length;L++)T+=`<div class="stx-code-editor-line-number">${L}</div>`;T+="</div>"}return T+=`<pre class="stx-code-editor-content"><code class="language-${F(Z)}">${F(Y)}</code></pre>`,`<div id="${E}" class="${R}" style="${j}" data-language="${F(Z)}" data-tab-size="${q}">${T}</div>`}function pQ(Q){let{src:Y,type:Z="video",poster:X,autoplay:$=!1,loop:G=!1,muted:K=!1,controls:q=!0,width:J,height:E,id:U=z("media"),className:_,style:R}=Q,B=O("stx-media-player",`stx-media-player--${Z}`,_),j={};if(J)j.width=typeof J==="number"?`${J}px`:J;if(E)j.height=typeof E==="number"?`${E}px`:E;let M=[V(j),V(R)].filter(Boolean).join("; "),T=[`id="${U}-media"`,`src="${F(Y)}"`,q&&"controls",$&&"autoplay",G&&"loop",K&&"muted",Z==="video"&&X&&`poster="${F(X)}"`].filter(Boolean).join(" "),L=Z==="video"?`<video ${T}>Your browser does not support the video tag.</video>`:`<audio ${T}>Your browser does not support the audio tag.</audio>`;return`<div id="${U}" class="${B}" ${M?`style='${M}'`:""}>${L}</div>`}function rQ(Q){if(Q===void 0)return"";let Y=["B","KB","MB","GB"],Z=Q,X=0;while(Z>=1024&&X<Y.length-1)Z/=1024,X++;return`${Z.toFixed(1)} ${Y[X]}`}function nQ(Q){let{files:Y,viewMode:Z="list",showHidden:X=!1,selectable:$=!0,id:G=z("files"),className:K,style:q}=Q,J=O("stx-file-explorer",`stx-file-explorer--${Z}`,K),E=V(q),U=X?Y:Y.filter((R)=>!R.name.startsWith(".")),_="";if(Z==="list"){_='<table class="stx-file-explorer-list"><thead><tr><th>Name</th><th>Size</th><th>Modified</th></tr></thead><tbody>';for(let R of U){let B=R.icon||(R.type==="folder"?"\uD83D\uDCC1":"\uD83D\uDCC4"),j=R.type==="file"?rQ(R.size):"",M=R.modified?R.modified.toLocaleDateString():"";_+=`<tr class="stx-file-explorer-item ${$?"stx-file-explorer-item--selectable":""}" data-path="${F(R.path)}" data-type="${R.type}">
77
- <td><span class="stx-file-explorer-icon">${B}</span>${F(R.name)}</td>
78
- <td>${j}</td>
75
+ </div>`}function aY(Y){let{value:Z="",language:Q="plaintext",theme:X="dark",lineNumbers:$=!0,readOnly:J=!1,height:K=300,tabSize:R=2,wordWrap:G=!1,id:_=z("code"),className:U,style:E}=Y,q=O("stx-code-editor",`stx-code-editor--${X}`,$&&"stx-code-editor--line-numbers",J&&"stx-code-editor--readonly",G&&"stx-code-editor--wrap",U),j={height:typeof K==="number"?`${K}px`:K},B=[V(j),V(E)].filter(Boolean).join("; "),M=Z.split(`
76
+ `),L="";if($){L+='<div class="stx-code-editor-gutter">';for(let T=1;T<=M.length;T++)L+=`<div class="stx-code-editor-line-number">${T}</div>`;L+="</div>"}return L+=`<pre class="stx-code-editor-content"><code class="language-${F(Q)}">${F(Z)}</code></pre>`,`<div id="${_}" class="${q}" style="${B}" data-language="${F(Q)}" data-tab-size="${R}">${L}</div>`}function iY(Y){let{src:Z,type:Q="video",poster:X,autoplay:$=!1,loop:J=!1,muted:K=!1,controls:R=!0,width:G,height:_,id:U=z("media"),className:E,style:q}=Y,j=O("stx-media-player",`stx-media-player--${Q}`,E),B={};if(G)B.width=typeof G==="number"?`${G}px`:G;if(_)B.height=typeof _==="number"?`${_}px`:_;let M=[V(B),V(q)].filter(Boolean).join("; "),L=[`id="${U}-media"`,`src="${F(Z)}"`,R&&"controls",$&&"autoplay",J&&"loop",K&&"muted",Q==="video"&&X&&`poster="${F(X)}"`].filter(Boolean).join(" "),T=Q==="video"?`<video ${L}>Your browser does not support the video tag.</video>`:`<audio ${L}>Your browser does not support the audio tag.</audio>`;return`<div id="${U}" class="${j}" ${M?`style='${M}'`:""}>${T}</div>`}function sY(Y){if(Y===void 0)return"";let Z=["B","KB","MB","GB"],Q=Y,X=0;while(Q>=1024&&X<Z.length-1)Q/=1024,X++;return`${Q.toFixed(1)} ${Z[X]}`}function tY(Y){let{files:Z,viewMode:Q="list",showHidden:X=!1,selectable:$=!0,id:J=z("files"),className:K,style:R}=Y,G=O("stx-file-explorer",`stx-file-explorer--${Q}`,K),_=V(R),U=X?Z:Z.filter((q)=>!q.name.startsWith(".")),E="";if(Q==="list"){E='<table class="stx-file-explorer-list"><thead><tr><th>Name</th><th>Size</th><th>Modified</th></tr></thead><tbody>';for(let q of U){let j=q.icon||(q.type==="folder"?"\uD83D\uDCC1":"\uD83D\uDCC4"),B=q.type==="file"?sY(q.size):"",M=q.modified?q.modified.toLocaleDateString():"";E+=`<tr class="stx-file-explorer-item ${$?"stx-file-explorer-item--selectable":""}" data-path="${F(q.path)}" data-type="${q.type}">
77
+ <td><span class="stx-file-explorer-icon">${j}</span>${F(q.name)}</td>
78
+ <td>${B}</td>
79
79
  <td>${M}</td>
80
- </tr>`}_+="</tbody></table>"}else{_='<div class="stx-file-explorer-grid">';for(let R of U){let B=R.icon||(R.type==="folder"?"\uD83D\uDCC1":"\uD83D\uDCC4");_+=`<div class="stx-file-explorer-item ${$?"stx-file-explorer-item--selectable":""}" data-path="${F(R.path)}" data-type="${R.type}">
81
- <div class="stx-file-explorer-icon">${B}</div>
82
- <div class="stx-file-explorer-name">${F(R.name)}</div>
83
- </div>`}_+="</div>"}return`<div id="${G}" class="${J}" ${E?`style='${E}'`:""}>${_}</div>`}function oQ(Q){let{url:Y,width:Z="100%",height:X=400,sandbox:$=!0,allowScripts:G=!0,id:K=z("webview"),className:q,style:J}=Q,E=O("stx-webview",q),U={width:typeof Z==="number"?`${Z}px`:Z,height:typeof X==="number"?`${X}px`:X},_=[V(U),V(J)].filter(Boolean).join("; "),R=[];if($){if(R.push("allow-same-origin"),G)R.push("allow-scripts")}let B=$?`sandbox="${R.join(" ")}"`:"";return`<iframe id="${K}" class="${E}" src="${F(Y)}" style="${_}" ${B} loading="lazy" frameborder="0"></iframe>`}var lQ=["Button","TextInput","Checkbox","RadioButton","Slider","ColorPicker","DatePicker","TimePicker","Autocomplete","Label","ImageView","ProgressBar","Avatar","Badge","Chip","Card","Tooltip","Toast","ScrollView","SplitView","Accordion","Stepper","Modal","Tabs","Dropdown","ListView","Table","TreeView","DataGrid","Chart","Rating","CodeEditor","MediaPlayer","FileExplorer","WebView"],aQ=`
80
+ </tr>`}E+="</tbody></table>"}else{E='<div class="stx-file-explorer-grid">';for(let q of U){let j=q.icon||(q.type==="folder"?"\uD83D\uDCC1":"\uD83D\uDCC4");E+=`<div class="stx-file-explorer-item ${$?"stx-file-explorer-item--selectable":""}" data-path="${F(q.path)}" data-type="${q.type}">
81
+ <div class="stx-file-explorer-icon">${j}</div>
82
+ <div class="stx-file-explorer-name">${F(q.name)}</div>
83
+ </div>`}E+="</div>"}return`<div id="${J}" class="${G}" ${_?`style='${_}'`:""}>${E}</div>`}function eY(Y){let{url:Z,width:Q="100%",height:X=400,sandbox:$=!0,allowScripts:J=!0,id:K=z("webview"),className:R,style:G}=Y,_=O("stx-webview",R),U={width:typeof Q==="number"?`${Q}px`:Q,height:typeof X==="number"?`${X}px`:X},E=[V(U),V(G)].filter(Boolean).join("; "),q=[];if($){if(q.push("allow-same-origin"),J)q.push("allow-scripts")}let j=$?`sandbox="${q.join(" ")}"`:"";return`<iframe id="${K}" class="${_}" src="${F(Z)}" style="${E}" ${j} loading="lazy" frameborder="0"></iframe>`}var YZ=["Button","TextInput","Checkbox","RadioButton","Slider","ColorPicker","DatePicker","TimePicker","Autocomplete","Label","ImageView","ProgressBar","Avatar","Badge","Chip","Card","Tooltip","Toast","ScrollView","SplitView","Accordion","Stepper","Modal","Tabs","Dropdown","ListView","Table","TreeView","DataGrid","Chart","Rating","CodeEditor","MediaPlayer","FileExplorer","WebView"],ZZ=`
84
84
  /* Button */
85
85
  .stx-button {
86
86
  display: inline-flex;
@@ -437,7 +437,7 @@ import{$ as rZ,$a as r0,A as TZ,Aa as z0,B as LZ,Ba as M0,C as DZ,Ca as T0,D as
437
437
  .stx-chip--warning { background: #3a2a1a; }
438
438
  .stx-chip--error { background: #3a1a1a; }
439
439
  }
440
- `;import r from"process";function iQ(){if(r.platform)return r.platform;return"unknown"}function o(){if(typeof window<"u"&&window.craft?.tray)return!0;return!1}function l(Q,Y){if(Q.type==="separator")return{id:`sep-${Y}`,label:"",type:"separator"};let Z={id:`item-${Y}-${Q.label.replace(/\s+/g,"-").toLowerCase()}`,label:Q.label,type:Q.type||"normal",enabled:Q.enabled!==!1};if(Q.accelerator)Z.shortcut=Q.accelerator;if(Q.type==="checkbox")Z.checked=Q.checked||!1;if(Q.type==="submenu"&&Q.submenu)Z.submenu=Q.submenu.map((X,$)=>l(X,$));return Z}function b(Q){return Q.map((Y,Z)=>l(Y,Z))}function a(Q,Y=0){if(Q.type==="separator")return'<hr class="stx-tray-separator" />';let Z=" ".repeat(Y),X=Q.enabled===!1?"disabled":"",$=Q.checked?"\u2713 ":"",G=Q.accelerator?`<span class="accelerator">${Q.accelerator}</span>`:"",K=`${Z}<div class="stx-tray-item ${X}" data-action="${Q.label}">`;if(K+=`<span class="label">${$}${Q.label}</span>${G}`,Q.type==="submenu"&&Q.submenu){K+='<span class="arrow">\u25B8</span>',K+='<div class="stx-tray-submenu">';for(let q of Q.submenu)K+=a(q,Y+1);K+="</div>"}return K+="</div>",K}function sQ(Q){let Y='<div class="stx-tray-menu">';for(let Z of Q)Y+=a(Z);return Y+="</div>",Y}var A=new Map;function tQ(){return`tray-${Date.now()}-${Math.random().toString(36).substring(2,9)}`}var n=!1;function eQ(){if(n||typeof window>"u")return;window.addEventListener("craft:tray:menu",(Q)=>{let{action:Y}=Q.detail;for(let Z of A.values()){let X=Z.handlers.get(Y);if(X){X();break}}}),n=!0}async function i(Q={}){let Y=tQ(),Z=iQ(),X=o(),$={icon:Q.icon||"",tooltip:Q.tooltip||"stx Application",menu:Q.menu||[],visible:!0},G=new Map;for(let q of Q.menu||[]){if(q.type!=="separator"&&q.onClick)G.set(q.label,q.onClick);if(q.type==="submenu"&&q.submenu){for(let J of q.submenu)if(J.type!=="separator"&&J.onClick)G.set(J.label,J.onClick)}}if(A.set(Y,{state:$,handlers:G}),X){eQ();let q=window;try{if($.tooltip)await q.craft.tray.setTitle({title:$.tooltip}),await q.craft.tray.setTooltip({tooltip:$.tooltip});if($.icon)await q.craft.tray.setIcon({icon:$.icon});let J=b($.menu);await q.craft.tray.setMenu({items:J}),console.log(`[stx-tray] Native tray created for ${Z}`)}catch(J){console.warn("[stx-tray] Failed to create native tray:",J)}}else console.log("[stx-tray] Created simulated tray (not in Craft window)"),console.log(`[stx-tray] ID: ${Y}`),console.log(`[stx-tray] Tooltip: ${$.tooltip}`),console.log(`[stx-tray] Menu items: ${$.menu.length}`);return{id:Y,setIcon:(q)=>{if($.icon=q,X)window.craft.tray.setIcon({icon:q}).catch((E)=>{console.warn("[stx-tray] Failed to set icon:",E)});console.log(`[stx-tray:${Y}] Icon updated`)},setTooltip:(q)=>{if($.tooltip=q,X)window.craft.tray.setTooltip({tooltip:q}).catch((E)=>{console.warn("[stx-tray] Failed to set tooltip:",E)});console.log(`[stx-tray:${Y}] Tooltip: ${q}`)},setMenu:(q)=>{$.menu=q,G.clear();for(let J of q){if(J.type!=="separator"&&J.onClick)G.set(J.label,J.onClick);if(J.type==="submenu"&&J.submenu){for(let E of J.submenu)if(E.type!=="separator"&&E.onClick)G.set(E.label,E.onClick)}}if(X){let J=window,E=b(q);J.craft.tray.setMenu({items:E}).catch((U)=>{console.warn("[stx-tray] Failed to set menu:",U)})}console.log(`[stx-tray:${Y}] Menu updated (${q.length} items)`)},destroy:()=>{if($.visible=!1,A.delete(Y),X)window.craft.tray.destroy?.().catch((J)=>{console.warn("[stx-tray] Failed to destroy tray:",J)});console.log(`[stx-tray:${Y}] Destroyed`)}}}var QY=i;function YY(){return Array.from(A.keys())}function ZY(Q){let Y=A.get(Q);if(!Y)return null;let Z=o();return{id:Q,setIcon:(X)=>{if(Y.state.icon=X,Z)window.craft.tray.setIcon({icon:X}).catch(()=>{})},setTooltip:(X)=>{if(Y.state.tooltip=X,Z)window.craft.tray.setTooltip({tooltip:X}).catch(()=>{})},setMenu:(X)=>{if(Y.state.menu=X,Z){let $=window,G=b(X);$.craft.tray.setMenu({items:G}).catch(()=>{})}},destroy:()=>{if(A.delete(Q),Z)window.craft.tray.destroy?.().catch(()=>{})}}}function XY(Q,Y){let Z=A.get(Q);if(!Z)return!1;let X=Z.handlers.get(Y);if(X)return X(),!0;return!1}function $Y(Q){let Y=A.get(Q);if(!Y)return null;return sQ(Y.state.menu)}function JY(){return`
440
+ `;import l from"process";function QZ(){if(l.platform)return l.platform;return"unknown"}function i(){if(typeof window<"u"&&window.craft?.tray)return!0;return!1}function s(Y,Z){if(Y.type==="separator")return{id:`sep-${Z}`,label:"",type:"separator"};let Q={id:`item-${Z}-${Y.label.replace(/\s+/g,"-").toLowerCase()}`,label:Y.label,type:Y.type||"normal",enabled:Y.enabled!==!1};if(Y.accelerator)Q.shortcut=Y.accelerator;if(Y.type==="checkbox")Q.checked=Y.checked||!1;if(Y.type==="submenu"&&Y.submenu)Q.submenu=Y.submenu.map((X,$)=>s(X,$));return Q}function u(Y){return Y.map((Z,Q)=>s(Z,Q))}function t(Y,Z=0){if(Y.type==="separator")return'<hr class="stx-tray-separator" />';let Q=" ".repeat(Z),X=Y.enabled===!1?"disabled":"",$=Y.checked?"\u2713 ":"",J=Y.accelerator?`<span class="accelerator">${Y.accelerator}</span>`:"",K=`${Q}<div class="stx-tray-item ${X}" data-action="${Y.label}">`;if(K+=`<span class="label">${$}${Y.label}</span>${J}`,Y.type==="submenu"&&Y.submenu){K+='<span class="arrow">\u25B8</span>',K+='<div class="stx-tray-submenu">';for(let R of Y.submenu)K+=t(R,Z+1);K+="</div>"}return K+="</div>",K}function XZ(Y){let Z='<div class="stx-tray-menu">';for(let Q of Y)Z+=t(Q);return Z+="</div>",Z}var A=new Map;function $Z(){return`tray-${Date.now()}-${Math.random().toString(36).substring(2,9)}`}var a=!1;function JZ(){if(a||typeof window>"u")return;window.addEventListener("craft:tray:menu",(Y)=>{let{action:Z}=Y.detail;for(let Q of A.values()){let X=Q.handlers.get(Z);if(X){X();break}}}),a=!0}async function e(Y={}){let Z=$Z(),Q=QZ(),X=i(),$={icon:Y.icon||"",tooltip:Y.tooltip||"stx Application",menu:Y.menu||[],visible:!0},J=new Map;for(let R of Y.menu||[]){if(R.type!=="separator"&&R.onClick)J.set(R.label,R.onClick);if(R.type==="submenu"&&R.submenu){for(let G of R.submenu)if(G.type!=="separator"&&G.onClick)J.set(G.label,G.onClick)}}if(A.set(Z,{state:$,handlers:J}),X){JZ();let R=window;try{if($.tooltip)await R.craft.tray.setTitle({title:$.tooltip}),await R.craft.tray.setTooltip({tooltip:$.tooltip});if($.icon)await R.craft.tray.setIcon({icon:$.icon});let G=u($.menu);await R.craft.tray.setMenu({items:G}),console.log(`[stx-tray] Native tray created for ${Q}`)}catch(G){console.warn("[stx-tray] Failed to create native tray:",G)}}else console.log("[stx-tray] Created simulated tray (not in Craft window)"),console.log(`[stx-tray] ID: ${Z}`),console.log(`[stx-tray] Tooltip: ${$.tooltip}`),console.log(`[stx-tray] Menu items: ${$.menu.length}`);return{id:Z,setIcon:(R)=>{if($.icon=R,X)window.craft.tray.setIcon({icon:R}).catch((_)=>{console.warn("[stx-tray] Failed to set icon:",_)});console.log(`[stx-tray:${Z}] Icon updated`)},setTooltip:(R)=>{if($.tooltip=R,X)window.craft.tray.setTooltip({tooltip:R}).catch((_)=>{console.warn("[stx-tray] Failed to set tooltip:",_)});console.log(`[stx-tray:${Z}] Tooltip: ${R}`)},setMenu:(R)=>{$.menu=R,J.clear();for(let G of R){if(G.type!=="separator"&&G.onClick)J.set(G.label,G.onClick);if(G.type==="submenu"&&G.submenu){for(let _ of G.submenu)if(_.type!=="separator"&&_.onClick)J.set(_.label,_.onClick)}}if(X){let G=window,_=u(R);G.craft.tray.setMenu({items:_}).catch((U)=>{console.warn("[stx-tray] Failed to set menu:",U)})}console.log(`[stx-tray:${Z}] Menu updated (${R.length} items)`)},destroy:()=>{if($.visible=!1,A.delete(Z),X)window.craft.tray.destroy?.().catch((G)=>{console.warn("[stx-tray] Failed to destroy tray:",G)});console.log(`[stx-tray:${Z}] Destroyed`)}}}var GZ=e;function RZ(){return Array.from(A.keys())}function qZ(Y){let Z=A.get(Y);if(!Z)return null;let Q=i();return{id:Y,setIcon:(X)=>{if(Z.state.icon=X,Q)window.craft.tray.setIcon({icon:X}).catch(()=>{})},setTooltip:(X)=>{if(Z.state.tooltip=X,Q)window.craft.tray.setTooltip({tooltip:X}).catch(()=>{})},setMenu:(X)=>{if(Z.state.menu=X,Q){let $=window,J=u(X);$.craft.tray.setMenu({items:J}).catch(()=>{})}},destroy:()=>{if(A.delete(Y),Q)window.craft.tray.destroy?.().catch(()=>{})}}}function KZ(Y,Z){let Q=A.get(Y);if(!Q)return!1;let X=Q.handlers.get(Z);if(X)return X(),!0;return!1}function UZ(Y){let Z=A.get(Y);if(!Z)return null;return XZ(Z.state.menu)}function _Z(){return`
441
441
  // STX Desktop Tray Bridge
442
442
  // Provides convenient wrappers around window.craft.tray APIs
443
443
  window.stxTray = {
@@ -450,7 +450,7 @@ window.stxTray = {
450
450
  // Check if tray is available
451
451
  isAvailable: () => typeof window.craft?.tray !== 'undefined',
452
452
  };
453
- `}var GY=`
453
+ `}var EZ=`
454
454
  .stx-tray-menu {
455
455
  background: #2d2d2d;
456
456
  border-radius: 8px;
@@ -516,7 +516,7 @@ window.stxTray = {
516
516
  .stx-tray-item:hover > .stx-tray-submenu {
517
517
  display: block;
518
518
  }
519
- `;import W from"process";import{existsSync as qY}from"fs";import{dirname as RY,join as KY}from"path";import{craftBinaryNotFoundMessage as s,resolveCraftBinary as UY}from"craft-native";var x={};function EY(Q){x={...x,...Q}}function _Y(){return{...x}}function FY(){x={}}function u(Q){if(!Q.sidebarConfig)return;let Y={...Q.sidebarConfig};if(Y.variant==="desktop")Y.material=Y.material??"sidebar",Y.backgroundEffect=Y.backgroundEffect??"shimmer",Y.allowsVibrancy=Y.allowsVibrancy??!0;return Y}function f(){let Q=RY(W.execPath),Y=Q.includes(".app/Contents/MacOS")?KY(Q,"craft"):void 0,Z=[W.env.CRAFT_BINARY_PATH,x.craftBinaryPath,...x.additionalSearchPaths||[],Y];for(let X of Z)if(X&&qY(X))return X;return UY()}var D=new Map;function y(Q){let Y=D.get(Q);if(!Y||Y.closed)return;Y.closed=!0;for(let Z of Y.closeListeners??[])try{Z()}catch(X){console.warn(`[stx/desktop] window ${Q} close listener threw:`,X)}Y.closeListeners?.clear()}var BY=50;async function h(Q,Y){let Z=Y.show().then(()=>({failed:!1}),($)=>({failed:!0,error:$})),X=await Promise.race([Z,new Promise(($)=>setTimeout(()=>$(null),BY))]);if(X?.failed)throw X.error;Z.then(()=>y(Q))}function jY(){return Array.from(D.keys())}function VY(Q){let Y=D.get(Q);if(!Y)return null;return S(Q,Y.app)}function OY(){for(let[Q,Y]of D)try{Y.app?.close?.()}catch(Z){console.warn(`Failed to close window ${Q}:`,Z)}D.clear()}function S(Q,Y){return{id:Q,show:()=>{console.log(`[stx/desktop] Window ${Q} shown`)},hide:()=>{console.log("[stx/desktop] To hide window, use window.craft.window.hide() from inside the webview")},close:()=>{let Z=D.get(Q);if(Z?.app)Z.app.close(),y(Q),D.delete(Q),console.log(`[stx/desktop] Window ${Q} closed`)},onClosed:(Z)=>{let X=D.get(Q);if(!X||X.closed)return queueMicrotask(Z),()=>{};return X.closeListeners??=new Set,X.closeListeners.add(Z),()=>X.closeListeners?.delete(Z)},focus:()=>{console.log("[stx/desktop] To focus window, use window.craft.window.focus() from inside the webview")},minimize:()=>{console.log("[stx/desktop] To minimize window, use window.craft.window.minimize() from inside the webview")},maximize:()=>{console.log("[stx/desktop] To maximize window, use window.craft.window.maximize() from inside the webview")},restore:()=>{console.log("[stx/desktop] To restore window, use window.craft.window.show() from inside the webview")},setTitle:(Z)=>{console.log(`[stx/desktop] To set title, use window.craft.window.setTitle({ title: "${Z}" }) from inside the webview`)},loadURL:(Z)=>{console.log(`[stx/desktop] To navigate, use window.location.href = "${Z}" from inside the webview`)},reload:()=>{console.log("[stx/desktop] To reload, use window.craft.window.reload() from inside the webview")}}}function m(Q,Y={}){let Z=["--url",Q,"--title",Y.title||"stx Desktop","--width",String(Y.width??1200),"--height",String(Y.height??800)];if(Y.darkMode)Z.push("--dark");if(Y.hotReload)Z.push("--hot-reload");if(Y.resizable===!1)Z.push("--no-resize");if(Y.frameless)Z.push("--frameless");if(Y.alwaysOnTop)Z.push("--always-on-top");if(Y.titlebarHidden)Z.push("--titlebar-hidden");if(Y.systemTray)Z.push("--system-tray");if(Y.hideDockIcon)Z.push("--hide-dock-icon");if(Y.devTools===!1)Z.push("--no-devtools");if(Y.nativeSidebar)Z.push("--native-sidebar");if(Y.sidebarWidth!==void 0)Z.push("--sidebar-width",String(Y.sidebarWidth));let X=u(Y);if(X)Z.push("--sidebar-config",JSON.stringify(X));return Z}async function zY(Q,Y={}){let Z=`craft-window-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,X=f();try{let{createApp:$}=await import("craft-native"),G=$({url:Q,craftPath:X,window:{title:Y.title||"stx Desktop",width:Y.width??1200,height:Y.height??800,darkMode:Y.darkMode??!1,hotReload:Y.hotReload??!1,resizable:Y.resizable??!0,frameless:Y.frameless??!1,alwaysOnTop:Y.alwaysOnTop??!1,titlebarHidden:Y.titlebarHidden??!1,systemTray:Y.systemTray??!1,hideDockIcon:Y.hideDockIcon??!1,devTools:Y.devTools??!1,nativeSidebar:Y.nativeSidebar??!1,sidebarWidth:Y.sidebarWidth,sidebarConfig:u(Y)}});return D.set(Z,{app:G,url:Q,options:Y}),await h(Z,G),S(Z,G)}catch{try{let{spawn:$}=await import("child_process"),G=$(X,m(Q,Y),{stdio:"inherit"});G.on("error",(q)=>{console.error(q.code==="ENOENT"?s(X):`craft child error: ${q.message}`)});let K={close:()=>G.kill()};return D.set(Z,{app:K,url:Q,options:Y}),G.on("exit",()=>y(Z)),S(Z,K)}catch($){return console.error("Failed to spawn craft binary:",$.message),null}}}async function MY(Q,Y={}){let Z=`http://localhost:${Q}/`;if(W.env.NODE_ENV==="test"||W.env.BUN_TEST)return console.warn("\u26A0 Skipping native window in test environment"),console.log("(Skipping browser fallback in test environment)"),!1;try{let{createApp:$}=await import("craft-native");console.log("\u26A1 Opening native window via craft-native\u2026");let G=!Y.nativeSidebar,K=u(Y),q=$({url:Z,craftPath:f(),window:{title:Y.title||"stx Development",width:Y.width||1400,height:Y.height||900,resizable:!0,systemTray:G,darkMode:Y.darkMode??!0,hotReload:Y.hotReload??!0,devTools:!0,titlebarHidden:Y.titlebarHidden??!1,nativeSidebar:Y.nativeSidebar??!1,sidebarWidth:Y.sidebarWidth??260,sidebarConfig:K}}),J=`dev-window-${Q}`;return D.set(J,{app:q,url:Z,options:Y}),await h(J,q),console.log(`\u2713 Native window opened at ${Z}`),!0}catch{let $=f();try{console.log(`\u26A1 Opening native window via craft binary (${$})\u2026`);let{spawn:G}=await import("child_process"),K=G($,m(Z,{title:"stx Development",width:1400,height:900,hotReload:!0,...Y}),{stdio:"inherit"});K.on("exit",()=>W.exit(0)),K.on("error",(J)=>{console.warn(J.code==="ENOENT"?s($):`craft child error: ${J.message}`)});let q=`dev-window-${Q}`;return D.set(q,{app:{close:()=>K.kill()},url:Z,options:Y}),console.log(`\u2713 Native window opened at ${Z}`),!0}catch(G){console.warn("\u26A0 Could not spawn craft binary:",G.message)}if(W.env.NODE_ENV==="test"||W.env.BUN_TEST)return console.log("(Skipping browser fallback in test environment)"),!1;console.log("\uD83D\uDCF1 Opening in browser instead\u2026");try{let{spawn:G}=await import("child_process"),K=W.platform;return G(K==="darwin"?"open":K==="win32"?"cmd":"xdg-open",K==="win32"?["/c","start",Z]:[Z],{detached:!0,stdio:"ignore"}).unref(),console.log(`\u2713 Browser opened at ${Z}`),!0}catch(G){return console.error("Could not open browser:",G),console.log(`Please open manually: ${Z}`),!1}}}async function TY(Q,Y={}){let{title:Z="stx Desktop",width:X=1200,height:$=800,darkMode:G=!1,hotReload:K=!1,resizable:q=!0,frameless:J=!1,alwaysOnTop:E=!1}=Y;try{let{createApp:U}=await import("craft-native"),_=f(),R=U({html:Q,craftPath:_,window:{title:Z,width:X,height:$,darkMode:G,hotReload:K,resizable:q,frameless:J,alwaysOnTop:E}}),B=`craft-window-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;return D.set(B,{app:R,url:"html-content",options:Y}),await h(B,R),S(B,R)}catch(U){return console.error("Failed to create window with HTML:",U),null}}function LY(){try{return N.resolve("craft-native"),!0}catch{return!1}}function DY(){return`
519
+ `;import P from"process";import{existsSync as FZ}from"fs";import{dirname as jZ,join as BZ}from"path";import{craftBinaryNotFoundMessage as YY,resolveCraftBinary as VZ}from"craft-native";var k={};function OZ(Y){k={...k,...Y}}function zZ(){return{...k}}function MZ(){k={}}function h(Y){if(!Y.sidebarConfig)return;let Z={...Y.sidebarConfig};if(Z.variant==="desktop")Z.material=Z.material??"sidebar",Z.backgroundEffect=Z.backgroundEffect??"shimmer",Z.allowsVibrancy=Z.allowsVibrancy??!0;return Z}function S(){let Y=jZ(P.execPath),Z=Y.includes(".app/Contents/MacOS")?BZ(Y,"craft"):void 0,Q=[P.env.CRAFT_BINARY_PATH,k.craftBinaryPath,...k.additionalSearchPaths||[],Z];for(let X of Q)if(X&&FZ(X))return X;return VZ()}var D=new Map;function m(Y){let Z=D.get(Y);if(!Z||Z.closed)return;Z.closed=!0;for(let Q of Z.closeListeners??[])try{Q()}catch(X){console.warn(`[stx/desktop] window ${Y} close listener threw:`,X)}Z.closeListeners?.clear()}var LZ=50;async function c(Y,Z){let Q=Z.show().then(()=>({failed:!1}),($)=>({failed:!0,error:$})),X=await Promise.race([Q,new Promise(($)=>setTimeout(()=>$(null),LZ))]);if(X?.failed)throw X.error;Q.then(()=>m(Y))}function TZ(){return Array.from(D.keys())}function DZ(Y){let Z=D.get(Y);if(!Z)return null;return g(Y,Z.app)}function WZ(){for(let[Y,Z]of D)try{Z.app?.close?.()}catch(Q){console.warn(`Failed to close window ${Y}:`,Q)}D.clear()}function g(Y,Z){return{id:Y,show:()=>{console.log(`[stx/desktop] Window ${Y} shown`)},hide:()=>{console.log("[stx/desktop] To hide window, use window.craft.window.hide() from inside the webview")},close:()=>{let Q=D.get(Y);if(Q?.app)Q.app.close(),m(Y),D.delete(Y),console.log(`[stx/desktop] Window ${Y} closed`)},onClosed:(Q)=>{let X=D.get(Y);if(!X||X.closed)return queueMicrotask(Q),()=>{};return X.closeListeners??=new Set,X.closeListeners.add(Q),()=>X.closeListeners?.delete(Q)},focus:()=>{console.log("[stx/desktop] To focus window, use window.craft.window.focus() from inside the webview")},minimize:()=>{console.log("[stx/desktop] To minimize window, use window.craft.window.minimize() from inside the webview")},maximize:()=>{console.log("[stx/desktop] To maximize window, use window.craft.window.maximize() from inside the webview")},restore:()=>{console.log("[stx/desktop] To restore window, use window.craft.window.show() from inside the webview")},setTitle:(Q)=>{console.log(`[stx/desktop] To set title, use window.craft.window.setTitle({ title: "${Q}" }) from inside the webview`)},loadURL:(Q)=>{console.log(`[stx/desktop] To navigate, use window.location.href = "${Q}" from inside the webview`)},reload:()=>{console.log("[stx/desktop] To reload, use window.craft.window.reload() from inside the webview")}}}function d(Y,Z={}){let Q=["--url",Y,"--title",Z.title||"stx Desktop","--width",String(Z.width??1200),"--height",String(Z.height??800)];if(Z.darkMode)Q.push("--dark");if(Z.hotReload)Q.push("--hot-reload");if(Z.resizable===!1)Q.push("--no-resize");if(Z.frameless)Q.push("--frameless");if(Z.alwaysOnTop)Q.push("--always-on-top");if(Z.titlebarHidden)Q.push("--titlebar-hidden");if(Z.systemTray)Q.push("--system-tray");if(Z.hideDockIcon)Q.push("--hide-dock-icon");if(Z.devTools===!1)Q.push("--no-devtools");if(Z.nativeSidebar)Q.push("--native-sidebar");if(Z.sidebarWidth!==void 0)Q.push("--sidebar-width",String(Z.sidebarWidth));let X=h(Z);if(X)Q.push("--sidebar-config",JSON.stringify(X));return Q}async function PZ(Y,Z={}){let Q=`craft-window-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,X=S();try{let{createApp:$}=await import("craft-native"),J=$({url:Y,craftPath:X,window:{title:Z.title||"stx Desktop",width:Z.width??1200,height:Z.height??800,darkMode:Z.darkMode??!1,hotReload:Z.hotReload??!1,resizable:Z.resizable??!0,frameless:Z.frameless??!1,alwaysOnTop:Z.alwaysOnTop??!1,titlebarHidden:Z.titlebarHidden??!1,systemTray:Z.systemTray??!1,hideDockIcon:Z.hideDockIcon??!1,devTools:Z.devTools??!1,nativeSidebar:Z.nativeSidebar??!1,sidebarWidth:Z.sidebarWidth,sidebarConfig:h(Z)}});return D.set(Q,{app:J,url:Y,options:Z}),await c(Q,J),g(Q,J)}catch{try{let{spawn:$}=await import("child_process"),J=$(X,d(Y,Z),{stdio:"inherit"});J.on("error",(R)=>{console.error(R.code==="ENOENT"?YY(X):`craft child error: ${R.message}`)});let K={close:()=>J.kill()};return D.set(Q,{app:K,url:Y,options:Z}),J.on("exit",()=>m(Q)),g(Q,K)}catch($){return console.error("Failed to spawn craft binary:",$.message),null}}}async function AZ(Y,Z={}){let Q=`http://localhost:${Y}/`;if(P.env.NODE_ENV==="test"||P.env.BUN_TEST)return console.warn("\u26A0 Skipping native window in test environment"),console.log("(Skipping browser fallback in test environment)"),!1;try{let{createApp:$}=await import("craft-native");console.log("\u26A1 Opening native window via craft-native\u2026");let J=!Z.nativeSidebar,K=h(Z),R=$({url:Q,craftPath:S(),window:{title:Z.title||"stx Development",width:Z.width||1400,height:Z.height||900,resizable:!0,systemTray:J,darkMode:Z.darkMode??!0,hotReload:Z.hotReload??!0,devTools:!0,titlebarHidden:Z.titlebarHidden??!1,nativeSidebar:Z.nativeSidebar??!1,sidebarWidth:Z.sidebarWidth??260,sidebarConfig:K}}),G=`dev-window-${Y}`;return D.set(G,{app:R,url:Q,options:Z}),await c(G,R),console.log(`\u2713 Native window opened at ${Q}`),!0}catch{let $=S();try{console.log(`\u26A1 Opening native window via craft binary (${$})\u2026`);let{spawn:J}=await import("child_process"),K=J($,d(Q,{title:"stx Development",width:1400,height:900,hotReload:!0,...Z}),{stdio:"inherit"});K.on("exit",()=>P.exit(0)),K.on("error",(G)=>{console.warn(G.code==="ENOENT"?YY($):`craft child error: ${G.message}`)});let R=`dev-window-${Y}`;return D.set(R,{app:{close:()=>K.kill()},url:Q,options:Z}),console.log(`\u2713 Native window opened at ${Q}`),!0}catch(J){console.warn("\u26A0 Could not spawn craft binary:",J.message)}if(P.env.NODE_ENV==="test"||P.env.BUN_TEST)return console.log("(Skipping browser fallback in test environment)"),!1;console.log("\uD83D\uDCF1 Opening in browser instead\u2026");try{let{spawn:J}=await import("child_process"),K=P.platform;return J(K==="darwin"?"open":K==="win32"?"cmd":"xdg-open",K==="win32"?["/c","start",Q]:[Q],{detached:!0,stdio:"ignore"}).unref(),console.log(`\u2713 Browser opened at ${Q}`),!0}catch(J){return console.error("Could not open browser:",J),console.log(`Please open manually: ${Q}`),!1}}}async function NZ(Y,Z={}){let{title:Q="stx Desktop",width:X=1200,height:$=800,darkMode:J=!1,hotReload:K=!1,resizable:R=!0,frameless:G=!1,alwaysOnTop:_=!1}=Z;try{let{createApp:U}=await import("craft-native"),E=S(),q=U({html:Y,craftPath:E,window:{title:Q,width:X,height:$,darkMode:J,hotReload:K,resizable:R,frameless:G,alwaysOnTop:_}}),j=`craft-window-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;return D.set(j,{app:q,url:"html-content",options:Z}),await c(j,q),g(j,q)}catch(U){return console.error("Failed to create window with HTML:",U),null}}function kZ(){try{return N.resolve("craft-native"),!0}catch{return!1}}function CZ(){return`
520
520
  // STX Desktop Window Bridge
521
521
  // Provides convenient wrappers around window.craft APIs
522
522
  window.stxWindow = {
@@ -557,30 +557,30 @@ window.stxWindow = {
557
557
 
558
558
  // Expose as global for backwards compatibility
559
559
  window.desktop = window.stxWindow;
560
- `}import{pack as PY,packageApp as WY}from"craft-native";import{craftBinaryNotFoundMessage as AY,resolveCraftBinary as NY}from"craft-native";import{AutoUpdater as t,generateUpdateManifest as e}from"craft-native";var QQ="update.json";function YQ(Q,Y){return`https://github.com/${Q}/releases/latest/download/${Y}`}function ZQ(Q,Y,Z){return`https://github.com/${Q}/releases/download/${Y}/${Z}`}function xY(Q){let{repository:Y,manifestAsset:Z=QQ,...X}=Q;return new t({...X,updateUrl:YQ(Y,Z)})}function IY(Q){let Y=Q.tag??`v${Q.version}`,Z={};for(let[X,$]of Object.entries(Q.artifacts)){if(!$)continue;Z[X]={path:$,url:ZQ(Q.repository,Y,$.split("/").pop())}}return e({version:Q.version,releaseNotes:Q.releaseNotes,platforms:Z})}import{existsSync as c,mkdirSync as kY,readFileSync as CY,watch as HY,writeFileSync as vY}from"fs";import{homedir as wY,platform as fY}from"os";import{dirname as SY,join as v}from"path";function gY(Q){let Y=fY(),Z=wY();switch(Y){case"darwin":return v(Z,"Library","Application Support",Q);case"win32":return v(process.env.APPDATA||v(Z,"AppData","Roaming"),Q);default:return v(Z,".config",Q)}}class XQ{_defaults;_data;_path;_changeHandlers=new Map;_anyChangeHandlers=new Set;_watcher=null;_writeTimer=null;_writing=!1;constructor(Q){this._defaults={...Q.defaults};let Y=Q.path?SY(Q.path):gY(Q.name);if(this._path=Q.path||v(Y,"preferences.json"),!c(Y))kY(Y,{recursive:!0});if(this._data=this._load(),Q.watch!==!1)this._setupWatcher()}get path(){return this._path}get(Q){if(Q in this._data)return this._data[Q];return this._defaults[Q]}set(Q,Y){let Z=this.get(Q);if(JSON.stringify(Z)===JSON.stringify(Y))return;this._data[Q]=Y,this._scheduleSave(),this._notifyChange(Q,Y,Z)}getAll(){return{...this._defaults,...this._data}}has(Q){return Q in this._data}delete(Q){if(!(Q in this._data))return;let Y=this._data[Q];delete this._data[Q],this._scheduleSave(),this._notifyChange(Q,this._defaults[Q],Y)}reset(){let Q={...this._data};this._data={},this._save();for(let Y of Object.keys(Q)){let Z=this._defaults[Y];this._notifyChange(Y,Z,Q[Y])}}onChange(Q,Y){let Z=Q;if(!this._changeHandlers.has(Z))this._changeHandlers.set(Z,new Set);return this._changeHandlers.get(Z).add(Y),()=>{this._changeHandlers.get(Z)?.delete(Y)}}onAnyChange(Q){return this._anyChangeHandlers.add(Q),()=>{this._anyChangeHandlers.delete(Q)}}close(){if(this._watcher)this._watcher.close(),this._watcher=null;if(this._writeTimer)clearTimeout(this._writeTimer),this._writeTimer=null,this._save()}_load(){try{if(c(this._path)){let Q=CY(this._path,"utf-8");return JSON.parse(Q)}}catch{}return{}}_save(){this._writing=!0;try{let Q=JSON.stringify({...this._defaults,...this._data},null,2);vY(this._path,Q,"utf-8")}catch(Q){console.error(`Failed to save preferences to ${this._path}:`,Q)}finally{setTimeout(()=>{this._writing=!1},100)}}_scheduleSave(){if(this._writeTimer)clearTimeout(this._writeTimer);this._writeTimer=setTimeout(()=>{this._writeTimer=null,this._save()},50)}_setupWatcher(){try{if(!c(this._path))this._save();this._watcher=HY(this._path,()=>{if(this._writing)return;let Q=this._load(),Y={...this._data};this._data=Q;let Z=new Set([...Object.keys(Y),...Object.keys(Q)]);for(let X of Z){let $=X in Y?Y[X]:this._defaults[X],G=X in Q?Q[X]:this._defaults[X];if(JSON.stringify($)!==JSON.stringify(G))this._notifyChange(X,G,$)}})}catch{}}_notifyChange(Q,Y,Z){let X=this._changeHandlers.get(Q);if(X)for(let $ of X)try{$(Y,Z)}catch{}for(let $ of this._anyChangeHandlers)try{$(Q,Y,Z)}catch{}}}function bY(Q){return new XQ(Q)}import{existsSync as I,mkdirSync as $Q,readFileSync as uY,unlinkSync as JQ,writeFileSync as GQ}from"fs";import{homedir as g,platform as qQ}from"os";import{join as k}from"path";function RQ(Q){let Y=Q.toLowerCase().replace(/[^a-z0-9]/g,"-");return k(g(),"Library","LaunchAgents",`com.${Y}.plist`)}function KQ(Q){let Y=process.env.XDG_CONFIG_HOME||k(g(),".config");return k(Y,"autostart",`${Q.toLowerCase()}.desktop`)}async function yY(Q,Y){let Z=Y.appName||"StxApp",X=RQ(Z),$=k(g(),"Library","LaunchAgents");if(Q){let G=Y.appPath||process.execPath,K=Y.args||[],q=[G,...K],J=`<?xml version="1.0" encoding="UTF-8"?>
560
+ `}import{pack as IZ,packageApp as xZ}from"craft-native";import{craftBinaryNotFoundMessage as HZ,resolveCraftBinary as vZ}from"craft-native";import{spawn as wZ}from"child_process";import v from"process";import{AutoUpdater as ZY,canReplaceBundle as fZ,clearQuarantine as SZ,extractBundle as gZ,generateUpdateManifest as QY,readBundleIdentity as p,swapBundle as bZ,verifyBundleTrust as yZ}from"craft-native";var XY="update.json";function $Y(Y,Z){return`https://github.com/${Y}/releases/latest/download/${Z}`}function JY(Y,Z,Q){return`https://github.com/${Y}/releases/download/${Z}/${Q}`}function GY(Y){let{repository:Z,manifestAsset:Q=XY,...X}=Y;return new ZY({...X,updateUrl:$Y(Z,Q)})}function uZ(Y){let Z=Y.tag??`v${Y.version}`,Q={};for(let[X,$]of Object.entries(Y.artifacts)){if(!$)continue;Q[X]={path:$,url:JY(Y.repository,Z,$.split("/").pop())}}return QY({version:Y.version,releaseNotes:Y.releaseNotes,platforms:Q})}function b(Y=v.execPath){let Z=Y.split("/");for(let Q=0;Q<Z.length;Q++)if(Z[Q].endsWith(".app"))return Z.slice(0,Q+1).join("/");return null}async function hZ(){let Y=b();if(!Y)return null;return(await p(Y)).teamId}function RY(){let Y=v.ppid;if(Y>1)try{v.kill(Y,"SIGTERM");return}catch{}v.exit(0)}function qY(Y={}){let Z=Y.appPath??b(),Q=Y.quit??(()=>v.exit(0));if(Z)wZ("/usr/bin/open",["-n",Z],{detached:!0,stdio:"ignore"}).unref();let X=Y.quitDelayMs??0;if(X>0){setTimeout(Q,X).unref?.();return}Q()}async function mZ(Y){let{appPath:Z,requireSameTeam:Q=!0,macos:X,...$}=Y,J=Z??b();if(!J)throw Error("createSelfUpdater: this process is not running from an .app bundle, so there is nothing to update. Pass `appPath` explicitly, or skip the updater in development.");let K=X?.teamId??(Q?(await p(J)).teamId??void 0:void 0);return GY({...$,appPath:J,macos:{...X,teamId:K},relaunch:Y.relaunch??((R)=>qY({appPath:R,quit:RY,quitDelayMs:250}))})}import{existsSync as r,mkdirSync as cZ,readFileSync as dZ,watch as pZ,writeFileSync as rZ}from"fs";import{homedir as nZ,platform as oZ}from"os";import{dirname as lZ,join as w}from"path";function aZ(Y){let Z=oZ(),Q=nZ();switch(Z){case"darwin":return w(Q,"Library","Application Support",Y);case"win32":return w(process.env.APPDATA||w(Q,"AppData","Roaming"),Y);default:return w(Q,".config",Y)}}class KY{_defaults;_data;_path;_changeHandlers=new Map;_anyChangeHandlers=new Set;_watcher=null;_writeTimer=null;_writing=!1;constructor(Y){this._defaults={...Y.defaults};let Z=Y.path?lZ(Y.path):aZ(Y.name);if(this._path=Y.path||w(Z,"preferences.json"),!r(Z))cZ(Z,{recursive:!0});if(this._data=this._load(),Y.watch!==!1)this._setupWatcher()}get path(){return this._path}get(Y){if(Y in this._data)return this._data[Y];return this._defaults[Y]}set(Y,Z){let Q=this.get(Y);if(JSON.stringify(Q)===JSON.stringify(Z))return;this._data[Y]=Z,this._scheduleSave(),this._notifyChange(Y,Z,Q)}getAll(){return{...this._defaults,...this._data}}has(Y){return Y in this._data}delete(Y){if(!(Y in this._data))return;let Z=this._data[Y];delete this._data[Y],this._scheduleSave(),this._notifyChange(Y,this._defaults[Y],Z)}reset(){let Y={...this._data};this._data={},this._save();for(let Z of Object.keys(Y)){let Q=this._defaults[Z];this._notifyChange(Z,Q,Y[Z])}}onChange(Y,Z){let Q=Y;if(!this._changeHandlers.has(Q))this._changeHandlers.set(Q,new Set);return this._changeHandlers.get(Q).add(Z),()=>{this._changeHandlers.get(Q)?.delete(Z)}}onAnyChange(Y){return this._anyChangeHandlers.add(Y),()=>{this._anyChangeHandlers.delete(Y)}}close(){if(this._watcher)this._watcher.close(),this._watcher=null;if(this._writeTimer)clearTimeout(this._writeTimer),this._writeTimer=null,this._save()}_load(){try{if(r(this._path)){let Y=dZ(this._path,"utf-8");return JSON.parse(Y)}}catch{}return{}}_save(){this._writing=!0;try{let Y=JSON.stringify({...this._defaults,...this._data},null,2);rZ(this._path,Y,"utf-8")}catch(Y){console.error(`Failed to save preferences to ${this._path}:`,Y)}finally{setTimeout(()=>{this._writing=!1},100)}}_scheduleSave(){if(this._writeTimer)clearTimeout(this._writeTimer);this._writeTimer=setTimeout(()=>{this._writeTimer=null,this._save()},50)}_setupWatcher(){try{if(!r(this._path))this._save();this._watcher=pZ(this._path,()=>{if(this._writing)return;let Y=this._load(),Z={...this._data};this._data=Y;let Q=new Set([...Object.keys(Z),...Object.keys(Y)]);for(let X of Q){let $=X in Z?Z[X]:this._defaults[X],J=X in Y?Y[X]:this._defaults[X];if(JSON.stringify($)!==JSON.stringify(J))this._notifyChange(X,J,$)}})}catch{}}_notifyChange(Y,Z,Q){let X=this._changeHandlers.get(Y);if(X)for(let $ of X)try{$(Z,Q)}catch{}for(let $ of this._anyChangeHandlers)try{$(Y,Z,Q)}catch{}}}function iZ(Y){return new KY(Y)}import{existsSync as C,mkdirSync as UY,readFileSync as sZ,unlinkSync as _Y,writeFileSync as EY}from"fs";import{homedir as y,platform as FY}from"os";import{join as I}from"path";function jY(Y){let Z=Y.toLowerCase().replace(/[^a-z0-9]/g,"-");return I(y(),"Library","LaunchAgents",`com.${Z}.plist`)}function BY(Y){let Z=process.env.XDG_CONFIG_HOME||I(y(),".config");return I(Z,"autostart",`${Y.toLowerCase()}.desktop`)}async function tZ(Y,Z){let Q=Z.appName||"StxApp",X=jY(Q),$=I(y(),"Library","LaunchAgents");if(Y){let J=Z.appPath||process.execPath,K=Z.args||[],R=[J,...K],G=`<?xml version="1.0" encoding="UTF-8"?>
561
561
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
562
562
  <plist version="1.0">
563
563
  <dict>
564
564
  <key>Label</key>
565
- <string>com.${Z.toLowerCase().replace(/[^a-z0-9]/g,"-")}</string>
565
+ <string>com.${Q.toLowerCase().replace(/[^a-z0-9]/g,"-")}</string>
566
566
  <key>ProgramArguments</key>
567
567
  <array>
568
- ${q.map((E)=>` <string>${dY(E)}</string>`).join(`
568
+ ${R.map((_)=>` <string>${Q0(_)}</string>`).join(`
569
569
  `)}
570
570
  </array>
571
571
  <key>RunAtLoad</key>
572
572
  <true/>
573
573
  <key>KeepAlive</key>
574
574
  <false/>
575
- ${Y.isHidden?` <key>ProcessType</key>
575
+ ${Z.isHidden?` <key>ProcessType</key>
576
576
  <string>Background</string>`:""}
577
577
  </dict>
578
- </plist>`;if(!I($))$Q($,{recursive:!0});GQ(X,J,"utf-8")}else if(I(X))JQ(X)}async function hY(Q,Y){let Z=Y.appName||"StxApp",X=KQ(Z),$=k(process.env.XDG_CONFIG_HOME||k(g(),".config"),"autostart");if(Q){let G=Y.appPath||process.execPath,K=Y.args||[],q=[G,...K].join(" "),J=`[Desktop Entry]
578
+ </plist>`;if(!C($))UY($,{recursive:!0});EY(X,G,"utf-8")}else if(C(X))_Y(X)}async function eZ(Y,Z){let Q=Z.appName||"StxApp",X=BY(Q),$=I(process.env.XDG_CONFIG_HOME||I(y(),".config"),"autostart");if(Y){let J=Z.appPath||process.execPath,K=Z.args||[],R=[J,...K].join(" "),G=`[Desktop Entry]
579
579
  Type=Application
580
- Name=${Z}
581
- Exec=${q}
580
+ Name=${Q}
581
+ Exec=${R}
582
582
  Terminal=false
583
583
  StartupNotify=false
584
- ${Y.isHidden?`X-GNOME-Autostart-enabled=true
584
+ ${Z.isHidden?`X-GNOME-Autostart-enabled=true
585
585
  NoDisplay=true`:""}
586
- `;if(!I($))$Q($,{recursive:!0});GQ(X,J,"utf-8")}else if(I(X))JQ(X)}async function mY(Q){return I(RQ(Q))}async function cY(Q){let Y=KQ(Q);if(!I(Y))return!1;try{let Z=uY(Y,"utf-8");if(Z.includes("X-GNOME-Autostart-enabled=false"))return!1;if(Z.includes("Hidden=true"))return!1;return!0}catch{return!1}}function dY(Q){return Q.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}async function pY(Q,Y={}){let Z=qQ();switch(Z){case"darwin":return yY(Q,Y);case"linux":return hY(Q,Y);default:throw Error(`Auto-launch is not yet supported on ${Z}`)}}async function rY(Q){let Y=Q||"StxApp";switch(qQ()){case"darwin":return mY(Y);case"linux":return cY(Y);default:return!1}}function EQ(Q){if(Q.separator)return{id:Q.id||"",title:"",type:"separator"};return{id:Q.id||"",title:Q.title||"",icon:Q.icon,shortcut:Q.shortcut,enabled:Q.disabled?!1:void 0,submenu:Q.submenu?.map(EQ)}}var nY={available(){return C("nativeUI")},async show(Q){if(!Q.items||Q.items.length===0)throw Error("contextMenu.show requires at least one item");if(!C("nativeUI"))return!1;return await window.craft.nativeUI.showContextMenu({targetId:Q.targetId||"",targetType:"general",x:Math.round(Q.x),y:Math.round(Q.y),items:Q.items.map(EQ)}),!0},onAction(Q){return UQ("craft:menu:action",Q)}};var oY={accentColor:()=>P("system","accentColor",()=>""),highlightColor:()=>P("system","highlightColor",()=>""),language:()=>P("system","language",()=>{if(typeof navigator>"u")return"";return navigator.language?.split("-")[0]||""}),locale:()=>P("system","locale",()=>{if(typeof navigator>"u")return"";return navigator.language||""}),timezone:()=>P("system","timezone",()=>{try{return Intl.DateTimeFormat().resolvedOptions().timeZone||""}catch{return""}}),is24HourTime:()=>P("system","is24HourTime",()=>{try{let Q=new Intl.DateTimeFormat([],{hour:"numeric"}).resolvedOptions();return Q.hourCycle==="h23"||Q.hourCycle==="h24"}catch{return!1}}),reduceMotion:()=>P("system","reduceMotion",()=>d("(prefers-reduced-motion: reduce)")),reduceTransparency:()=>P("system","reduceTransparency",()=>d("(prefers-reduced-transparency: reduce)")),increaseContrast:()=>P("system","increaseContrast",()=>d("(prefers-contrast: more)")),systemVersion:()=>P("system","systemVersion",()=>""),hostname:()=>P("system","hostname",()=>""),username:()=>P("system","username",()=>""),async openPreferences(){if(C("system"))await window.craft.system.openPreferences()}};async function P(Q,Y,Z){if(C(Q))return await window.craft[Q][Y]();return await Z()}function d(Q){if(typeof window>"u"||!window.matchMedia)return!1;return window.matchMedia(Q).matches}export{Z0 as windowEvents,N0 as watchScreenSharing,m0 as vision,Y0 as updater,gZ as unregisterHotkey,bZ as unregisterAllHotkeys,XY as triggerTrayAction,E0 as touchbar,aZ as theme,S0 as tags,oY as system,$0 as standardMenus,y0 as spotlight,h0 as speechRecognition,F0 as speech,V0 as signPayload,eY as showWarningToast,RZ as showWarningModal,AZ as showWarningDialog,iY as showToast,tY as showSuccessToast,UZ as showSuccessModal,MZ as showSaveDialog,EZ as showQuestionModal,zZ as showOpenDialog,GZ as showModal,TZ as showMessageBox,sY as showInfoToast,qZ as showInfoModal,QZ as showErrorToast,KZ as showErrorModal,WZ as showErrorDialog,PZ as showConfirmDialog,LZ as showColorPicker,DZ as showAlertDialog,aY as showAlert,oZ as shell,EY as setDesktopConfig,pY as setAutoLaunch,r0 as serviceMenu,n0 as serial,A0 as screenSharing,L0 as screenCapture,G0 as screen,NY as resolveCraftBinary,FY as resetDesktopConfig,lY as requestNotificationPermission,SZ as registerHotkey,j0 as redactPII,BZ as prompt,K0 as printing,R0 as permissions,g0 as pdf,wZ as parseShortcut,WY as packageApp,PY as pack,MY as openDevWindow,YZ as notify,rZ as notifications,Q0 as network,U0 as nativeAutoLaunch,c0 as midi,J0 as menu,b0 as log,T0 as location,C0 as localServer,M0 as liveActivities,q0 as keychain,LY as isWebviewAvailable,sZ as isDragOutAvailable,kZ as isCaffeinated,a0 as isAvailable,rY as isAutoLaunchEnabled,O0 as iap,I0 as hasFocusShortcuts,z0 as handoff,lZ as globalShortcuts,ZQ as githubReleaseAssetUrl,YQ as githubLatestAssetUrl,DY as getWindowBridgeScript,VY as getWindow,ZY as getTrayInstance,JY as getTrayBridgeScript,$Y as getSimulatedTrayHTML,uZ as getRegisteredHotkeys,NZ as getDialogBridgeScript,_Y as getDesktopConfig,l0 as getCapability,o0 as getCapabilities,CZ as getCaffeinateStatus,jY as getActiveWindowIds,YY as getActiveTrayInstances,jZ as getActiveModalCount,$Z as getActiveAlertCount,e as generateUpdateManifest,nZ as fs,cZ as formatTime,fZ as formatShortcut,HZ as formatRemainingTime,vZ as formatDuration,dZ as formatCompact,k0 as focusShortcutsReady,x0 as focus,f0 as fileAssociations,iZ as dragOut,XZ as dismissAllAlerts,ZZ as dismissAlertById,mZ as delay,tZ as deepLinks,IZ as decaffeinate,TY as createWindowWithHTML,zY as createWindow,oQ as createWebView,hQ as createTreeView,vQ as createTooltip,yZ as createTimer,xQ as createTimePicker,BQ as createTextInput,LQ as createTabs,yQ as createTable,i as createSystemTray,gQ as createStepper,fQ as createSplitView,VQ as createSlider,wQ as createScrollView,PQ as createRating,WQ as createRadioButton,OQ as createProgressBar,bY as createPreferences,bQ as createModalComponent,QY as createMenubar,pQ as createMediaPlayer,uQ as createListView,kQ as createLabel,hZ as createInterval,CQ as createImageView,xY as createGitHubUpdater,IY as createGitHubUpdateManifest,nQ as createFileExplorer,DQ as createDropdown,NQ as createDatePicker,mQ as createDataGrid,AQ as createColorPicker,dQ as createCodeEditor,HQ as createChip,jQ as createCheckbox,cQ as createChart,TQ as createCard,FQ as createButton,zQ as createBadge,MQ as createAvatar,IQ as createAutocomplete,SQ as createAccordion,B0 as crashReporter,m as craftWindowArguments,AY as craftBinaryNotFoundMessage,d0 as coreml,p0 as continuityCamera,nY as contextMenu,_Z as confirm,OY as closeAllWindows,VZ as closeAllModals,pZ as clipboard,xZ as caffeinate,u0 as bonjour,_0 as bluetooth,H0 as biometric,eZ as battery,v0 as audio,w0 as appleScript,X0 as appInfo,FZ as alert,QQ as UPDATE_MANIFEST_ASSET,GY as TRAY_MENU_STYLES,JZ as TOAST_STYLES,OZ as MODAL_STYLES,D0 as MIN_WATCH_INTERVAL_MS,P0 as MAX_WATCH_INTERVAL_MS,W0 as DEFAULT_WATCH_INTERVAL_MS,aQ as COMPONENT_STYLES,t as AutoUpdater,lQ as AVAILABLE_COMPONENTS};
586
+ `;if(!C($))UY($,{recursive:!0});EY(X,G,"utf-8")}else if(C(X))_Y(X)}async function Y0(Y){return C(jY(Y))}async function Z0(Y){let Z=BY(Y);if(!C(Z))return!1;try{let Q=sZ(Z,"utf-8");if(Q.includes("X-GNOME-Autostart-enabled=false"))return!1;if(Q.includes("Hidden=true"))return!1;return!0}catch{return!1}}function Q0(Y){return Y.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}async function X0(Y,Z={}){let Q=FY();switch(Q){case"darwin":return tZ(Y,Z);case"linux":return eZ(Y,Z);default:throw Error(`Auto-launch is not yet supported on ${Q}`)}}async function $0(Y){let Z=Y||"StxApp";switch(FY()){case"darwin":return Y0(Z);case"linux":return Z0(Z);default:return!1}}function OY(Y){if(Y.separator)return{id:Y.id||"",title:"",type:"separator"};return{id:Y.id||"",title:Y.title||"",icon:Y.icon,shortcut:Y.shortcut,enabled:Y.disabled?!1:void 0,submenu:Y.submenu?.map(OY)}}var J0={available(){return x("nativeUI")},async show(Y){if(!Y.items||Y.items.length===0)throw Error("contextMenu.show requires at least one item");if(!x("nativeUI"))return!1;return await window.craft.nativeUI.showContextMenu({targetId:Y.targetId||"",targetType:"general",x:Math.round(Y.x),y:Math.round(Y.y),items:Y.items.map(OY)}),!0},onAction(Y){return VY("craft:menu:action",Y)}};var G0={accentColor:()=>W("system","accentColor",()=>""),highlightColor:()=>W("system","highlightColor",()=>""),language:()=>W("system","language",()=>{if(typeof navigator>"u")return"";return navigator.language?.split("-")[0]||""}),locale:()=>W("system","locale",()=>{if(typeof navigator>"u")return"";return navigator.language||""}),timezone:()=>W("system","timezone",()=>{try{return Intl.DateTimeFormat().resolvedOptions().timeZone||""}catch{return""}}),is24HourTime:()=>W("system","is24HourTime",()=>{try{let Y=new Intl.DateTimeFormat([],{hour:"numeric"}).resolvedOptions();return Y.hourCycle==="h23"||Y.hourCycle==="h24"}catch{return!1}}),reduceMotion:()=>W("system","reduceMotion",()=>n("(prefers-reduced-motion: reduce)")),reduceTransparency:()=>W("system","reduceTransparency",()=>n("(prefers-reduced-transparency: reduce)")),increaseContrast:()=>W("system","increaseContrast",()=>n("(prefers-contrast: more)")),systemVersion:()=>W("system","systemVersion",()=>""),hostname:()=>W("system","hostname",()=>""),username:()=>W("system","username",()=>""),async openPreferences(){if(x("system"))await window.craft.system.openPreferences()}};async function W(Y,Z,Q){if(x(Y))return await window.craft[Y][Z]();return await Q()}function n(Y){if(typeof window>"u"||!window.matchMedia)return!1;return window.matchMedia(Y).matches}export{B1 as windowEvents,u1 as watchScreenSharing,Y2 as vision,yZ as verifyBundleTrust,j1 as updater,a0 as unregisterHotkey,i0 as unregisterAllHotkeys,KZ as triggerTrayAction,P1 as touchbar,q1 as theme,l1 as tags,G0 as system,bZ as swapBundle,O1 as standardMenus,t1 as spotlight,e1 as speechRecognition,N1 as speech,I1 as signPayload,E0 as showWarningToast,T0 as showWarningModal,y0 as showWarningDialog,K0 as showToast,_0 as showSuccessToast,W0 as showSuccessModal,v0 as showSaveDialog,P0 as showQuestionModal,H0 as showOpenDialog,M0 as showModal,w0 as showMessageBox,U0 as showInfoToast,L0 as showInfoModal,F0 as showErrorToast,D0 as showErrorModal,b0 as showErrorDialog,g0 as showConfirmDialog,f0 as showColorPicker,S0 as showAlertDialog,q0 as showAlert,G1 as shell,OZ as setDesktopConfig,X0 as setAutoLaunch,$2 as serviceMenu,J2 as serial,y1 as screenSharing,f1 as screenCapture,M1 as screen,hZ as runningBundleTeamId,vZ as resolveCraftBinary,MZ as resetDesktopConfig,R0 as requestNotificationPermission,qY as relaunchBundle,l0 as registerHotkey,C1 as redactPII,p as readBundleIdentity,RY as quitLauncher,k0 as prompt,D1 as printing,T1 as permissions,a1 as pdf,n0 as parseShortcut,xZ as packageApp,IZ as pack,AZ as openDevWindow,j0 as notify,$1 as notifications,F1 as network,W1 as nativeAutoLaunch,Z2 as midi,z1 as menu,i1 as log,w1 as location,d1 as localServer,v1 as liveActivities,L1 as keychain,kZ as isWebviewAvailable,U1 as isDragOutAvailable,c0 as isCaffeinated,q2 as isAvailable,$0 as isAutoLaunchEnabled,x1 as iap,m1 as hasFocusShortcuts,H1 as handoff,R1 as globalShortcuts,JY as githubReleaseAssetUrl,$Y as githubLatestAssetUrl,CZ as getWindowBridgeScript,DZ as getWindow,qZ as getTrayInstance,_Z as getTrayBridgeScript,UZ as getSimulatedTrayHTML,s0 as getRegisteredHotkeys,u0 as getDialogBridgeScript,zZ as getDesktopConfig,R2 as getCapability,G2 as getCapabilities,d0 as getCaffeinateStatus,TZ as getActiveWindowIds,RZ as getActiveTrayInstances,C0 as getActiveModalCount,O0 as getActiveAlertCount,QY as generateUpdateManifest,J1 as fs,Z1 as formatTime,o0 as formatShortcut,p0 as formatRemainingTime,r0 as formatDuration,Q1 as formatCompact,c1 as focusShortcutsReady,h1 as focus,o1 as fileAssociations,gZ as extractBundle,K1 as dragOut,V0 as dismissAllAlerts,B0 as dismissAlertById,Y1 as delay,_1 as deepLinks,m0 as decaffeinate,NZ as createWindowWithHTML,PZ as createWindow,eY as createWebView,nY as createTreeView,yY as createTooltip,t0 as createTimer,wY as createTimePicker,LY as createTextInput,kY as createTabs,rY as createTable,e as createSystemTray,cY as createStepper,hY as createSplitView,DY as createSlider,mZ as createSelfUpdater,uY as createScrollView,IY as createRating,xY as createRadioButton,WY as createProgressBar,iZ as createPreferences,dY as createModalComponent,GZ as createMenubar,iY as createMediaPlayer,pY as createListView,SY as createLabel,e0 as createInterval,gY as createImageView,GY as createGitHubUpdater,uZ as createGitHubUpdateManifest,tY as createFileExplorer,CY as createDropdown,vY as createDatePicker,oY as createDataGrid,HY as createColorPicker,aY as createCodeEditor,bY as createChip,TY as createCheckbox,lY as createChart,NY as createCard,MY as createButton,PY as createBadge,AY as createAvatar,fY as createAutocomplete,mY as createAccordion,k1 as crashReporter,d as craftWindowArguments,HZ as craftBinaryNotFoundMessage,Q2 as coreml,X2 as continuityCamera,J0 as contextMenu,A0 as confirm,WZ as closeAllWindows,I0 as closeAllModals,X1 as clipboard,SZ as clearQuarantine,fZ as canReplaceBundle,h0 as caffeinate,b as bundlePathForExecutable,s1 as bonjour,A1 as bluetooth,p1 as biometric,E1 as battery,r1 as audio,n1 as appleScript,V1 as appInfo,N0 as alert,XY as UPDATE_MANIFEST_ASSET,EZ as TRAY_MENU_STYLES,z0 as TOAST_STYLES,x0 as MODAL_STYLES,S1 as MIN_WATCH_INTERVAL_MS,g1 as MAX_WATCH_INTERVAL_MS,b1 as DEFAULT_WATCH_INTERVAL_MS,ZZ as COMPONENT_STYLES,ZY as AutoUpdater,YZ as AVAILABLE_COMPONENTS};
@@ -1,5 +1,6 @@
1
- import { AutoUpdater, generateUpdateManifest } from 'craft-native';
2
- import type { UpdateManifest, UpdaterConfig } from 'craft-native';
1
+ import { AutoUpdater, canReplaceBundle, clearQuarantine, extractBundle, generateUpdateManifest, readBundleIdentity, swapBundle, verifyBundleTrust } from 'craft-native';
2
+ import type { BundleIdentity, BundleTrustPolicy, BundleTrustResult, UpdateManifest, UpdaterConfig } from 'craft-native';
3
+ export type { BundleIdentity, BundleTrustPolicy, BundleTrustResult };
3
4
  export type { PlatformUpdate, UpdateManifest, UpdaterConfig, UpdaterEvent, UpdateProgress } from 'craft-native';
4
5
  /**
5
6
  * URL of an asset on the repository's newest release.
@@ -21,6 +22,60 @@ export declare function createGitHubUpdater(options: GitHubUpdaterOptions): Auto
21
22
  * its URL at the release's own tag.
22
23
  */
23
24
  export declare function createGitHubUpdateManifest(options: GitHubManifestOptions): UpdateManifest;
25
+ /**
26
+ * The `.app` the current process is running out of, or null outside one.
27
+ *
28
+ * Every self-updating app needs this and every one of them derives it
29
+ * differently — usually as `../../..` from `process.execPath`, which is right
30
+ * for `Foo.app/Contents/MacOS/Foo` and wrong for anything nested deeper.
31
+ *
32
+ * The *outermost* `.app` is the answer, not the nearest one. Apps embed whole
33
+ * bundles inside themselves — XPC services, login items, a Sparkle updater —
34
+ * and a process running from one of those is still part of the app the user
35
+ * launched and installed. Taking the nearest bundle would have such a process
36
+ * replace the fragment it happens to live in and leave the rest of the app at
37
+ * the old version.
38
+ *
39
+ * Returns null for `bun run` in development, rather than pointing the updater
40
+ * at a directory in the source tree.
41
+ */
42
+ export declare function bundlePathForExecutable(execPath?: string): string | null;
43
+ /**
44
+ * Team ID of the bundle this process is running from, or null.
45
+ *
46
+ * This is what makes "only install updates from us" a default rather than a
47
+ * configuration step: an app does not have to know or hardcode its own Team
48
+ * ID, because the copy already on disk is signed with it.
49
+ */
50
+ export declare function runningBundleTeamId(): Promise<string | null>;
51
+ /**
52
+ * Quit the launcher that started this process.
53
+ *
54
+ * The stx desktop shape is one binary running as three processes: a launcher,
55
+ * the agent it spawns, and the native window. Only the launcher can bring the
56
+ * other two down, and it is this process's parent — so a `SIGTERM` there is
57
+ * what "quit the app" means from inside the agent.
58
+ */
59
+ export declare function quitLauncher(): void;
60
+ /**
61
+ * Start a fresh copy of the bundle, then stand the current one down.
62
+ *
63
+ * `open -n` rather than executing the binary directly: it goes through
64
+ * LaunchServices, which registers the newly swapped bundle, gives it its own
65
+ * activation and Dock entry, and starts it detached from this process — so
66
+ * the new copy is not a child of the one that is about to exit.
67
+ */
68
+ export declare function relaunchBundle(options?: RelaunchOptions): void;
69
+ /**
70
+ * A GitHub-Releases updater for the app that is running, wired to the checks
71
+ * macOS itself performs.
72
+ *
73
+ * Two things it does that a bare {@link AutoUpdater} cannot: it finds its own
74
+ * bundle, and it pins the signing team to whatever signed that bundle. Both
75
+ * are facts about the running app, so neither has to be configured, and an app
76
+ * cannot get them subtly wrong by copying an example.
77
+ */
78
+ export declare function createSelfUpdater(options: SelfUpdaterOptions): Promise<AutoUpdater>;
24
79
  /** Manifest asset name an app publishes alongside its release artifacts. */
25
80
  export declare const UPDATE_MANIFEST_ASSET: 'update.json';
26
81
  export declare interface GitHubUpdaterOptions extends Omit<UpdaterConfig, 'updateUrl'> {
@@ -38,4 +93,23 @@ export declare interface GitHubManifestOptions {
38
93
  linux?: string
39
94
  }
40
95
  }
96
+ // =============================================================================
97
+ // Relaunching
98
+ // =============================================================================
99
+ export declare interface RelaunchOptions {
100
+ appPath?: string
101
+ quit?: () => void
102
+ quitDelayMs?: number
103
+ }
104
+ // =============================================================================
105
+ // Self-updater
106
+ // =============================================================================
107
+ export declare interface SelfUpdaterOptions extends Omit<GitHubUpdaterOptions, 'appPath'> {
108
+ appPath?: string
109
+ requireSameTeam?: boolean
110
+ }
41
111
  export { AutoUpdater, generateUpdateManifest };
112
+ // The macOS bundle primitives, forwarded so an app never has to reach past
113
+ // `@stacksjs/desktop` into Craft for the half of self-updating that is file
114
+ // operations rather than HTTP.
115
+ export { canReplaceBundle, clearQuarantine, extractBundle, readBundleIdentity, swapBundle, verifyBundleTrust };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/desktop",
3
3
  "type": "module",
4
- "version": "0.2.279",
4
+ "version": "0.2.280",
5
5
  "description": "Native desktop application framework for stx (powered by Craft)",
6
6
  "author": "Chris Breuer <chris@stacksjs.org>",
7
7
  "license": "MIT",
@@ -59,6 +59,6 @@
59
59
  "typecheck": "bun tsc --noEmit"
60
60
  },
61
61
  "dependencies": {
62
- "craft-native": ">=0.0.76"
62
+ "craft-native": ">=0.0.88"
63
63
  }
64
64
  }