@atomm-developer/generator-workbench 0.1.8 → 0.1.9

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
@@ -117,6 +117,8 @@ The shell layout mode above is different from the route capability mode. When th
117
117
 
118
118
  This is useful when the host site embeds a generator inside an `iframe` and wants a lighter shell surface. If the route omits `mode` or uses `mode=full`, the existing shell behavior stays unchanged.
119
119
 
120
+ In this embed route, the shell also removes the top bar and `#sidebar-footer` export container from the DOM entirely. The underlying workbench methods and bridge actions still exist, but the shell chrome is no longer rendered inside the iframe.
121
+
120
122
  When `?mode=embed` is active, the workbench also boots an iframe bridge compatible with the main-site generator protocol:
121
123
 
122
124
  - outgoing ready signal: `generator_pageLoaded`
package/dist/index.es.js CHANGED
@@ -1197,7 +1197,7 @@ const WORKBENCH_SHELL_STYLES = `
1197
1197
  `;
1198
1198
  const WORKBENCH_VUE_TEMPLATE = `
1199
1199
  <div class="shell">
1200
- <header v-if="state.shellMode !== 'template'" class="topbar app-topbar">
1200
+ <header v-show="state.showTopbar" class="topbar app-topbar">
1201
1201
  <div class="logo-area app-topbar-main" data-role="logo-area">
1202
1202
  <img
1203
1203
  :src="state.logoSrc"
@@ -1378,7 +1378,12 @@ const WORKBENCH_VUE_TEMPLATE = `
1378
1378
  <main class="canvas-host" data-role="canvas-host"></main>
1379
1379
  <aside class="panel-sidebar" data-role="panel-sidebar">
1380
1380
  <div class="panel-host" data-role="panel-host"></div>
1381
- <div id="sidebar-footer" class="sidebar-footer-export panel-actions" data-role="panel-actions">
1381
+ <div
1382
+ v-show="state.showSidebarFooter"
1383
+ id="sidebar-footer"
1384
+ class="sidebar-footer-export panel-actions"
1385
+ data-role="panel-actions"
1386
+ >
1382
1387
  <xt-dropdown-menu
1383
1388
  trigger="click"
1384
1389
  :portal-disabled="true"
@@ -1436,7 +1441,7 @@ const WORKBENCH_VUE_TEMPLATE = `
1436
1441
  </div>
1437
1442
 
1438
1443
  <div
1439
- v-if="state.shellMode === 'shell'"
1444
+ v-show="state.shellMode === 'shell' && state.showSidebarFooter"
1440
1445
  id="sidebar-footer"
1441
1446
  class="sidebar-footer-export panel-actions sidebar-footer-floating"
1442
1447
  data-role="panel-actions"
@@ -1856,8 +1861,11 @@ function createDefaultAtommProUser() {
1856
1861
  }
1857
1862
  function stateFromConfig(vue, config, invitationReady) {
1858
1863
  var _a;
1864
+ const shellChromeVisible = config.shellChromeVisible !== false;
1859
1865
  return vue.reactive({
1860
1866
  shellMode: config.mode || "full",
1867
+ showTopbar: shellChromeVisible && config.mode !== "template",
1868
+ showSidebarFooter: shellChromeVisible,
1861
1869
  logoText: config.logoText || config.title,
1862
1870
  logoSrc: config.logoUrl || "https://storage-us.atomm.com/resource/xart/static/agent/imgs/atomm-logo.svg",
1863
1871
  panelTarget: config.panelTarget || "right",
@@ -2340,9 +2348,11 @@ function createIframeBridge(args) {
2340
2348
  });
2341
2349
  return;
2342
2350
  case "generator_setGeneratorData":
2351
+ console.log("generator_setGeneratorData =======> data", data);
2343
2352
  void Promise.resolve(handlers.setGeneratorData(data || {}));
2344
2353
  return;
2345
2354
  case "generator_loadTemplateData":
2355
+ console.log("generator_loadTemplateData =======> data", data);
2346
2356
  void handlers.loadTemplateData(data || {}).then((payload) => {
2347
2357
  post("generator_toTemplateLoaded", {
2348
2358
  template: (payload == null ? void 0 : payload.template) || (data && "template" in data ? data.template : data) || null
@@ -3526,7 +3536,8 @@ class GeneratorWorkbenchElement extends HTMLElement {
3526
3536
  cloudEnabled: false,
3527
3537
  historyEnabled: false,
3528
3538
  autoSaveEnabled: false,
3529
- creditsEnabled: false
3539
+ creditsEnabled: false,
3540
+ shellChromeVisible: false
3530
3541
  };
3531
3542
  }
3532
3543
  getEffectiveSdk() {
package/dist/index.umd.js CHANGED
@@ -1 +1 @@
1
- !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).GeneratorWorkbench={})}(this,function(t){"use strict";var e=Object.defineProperty,n=(t,n,o)=>((t,n,o)=>n in t?e(t,n,{enumerable:!0,configurable:!0,writable:!0,value:o}):t[n]=o)(t,"symbol"!=typeof n?n+"":n,o),o="undefined"!=typeof document?document.currentScript:null;function i(t){const e=null==t?void 0:t.trim();return e?`__atomm_sdk_billing_free_period__${e}`:null}function a(t,e=Date.now()){const n=i(t);if(!n)return null;try{const t=localStorage.getItem(n);if(!t)return null;const o=Number(t);return!Number.isFinite(o)||o<=e?(localStorage.removeItem(n),null):o}catch{return null}}function r(t,e=Date.now()){const n=a(t,e);return n?Math.max(0,Math.ceil((n-e)/1e3)):0}function s(t,e,n=Date.now()){if(!(null==t?void 0:t.isEnabled))return t||null;const o=r(e,n);return o<=0||t.inFreePeriod&&t.freePeriodRemaining>=o?t:{...t,inFreePeriod:!0,freePeriodRemaining:o}}function l(t,e){if(!t)throw new Error(e)}function d(t,e){const n=(null==e?void 0:e.length)?new Set(e):null;return t.groups.map(t=>{var e;const o=t.fields.map(t=>{var e,o,i;const a=null==(o=null==(e=t.bind)?void 0:e.path)?void 0:o.trim();return a?n&&!n.has(a)?null:{id:t.id,label:(null==(i=t.label)?void 0:i.trim())||t.id||a,path:a}:null}).filter(t=>Boolean(t));return{id:t.id,title:(null==(e=t.title)?void 0:e.trim())||t.id,fields:o}}).filter(t=>t.fields.length>0)}function c(t,e){var n;if(null==(n=t.generatorId)?void 0:n.trim())return t.generatorId.trim();const o=e.meta;if(o&&"object"==typeof o&&"generatorId"in o&&"string"==typeof o.generatorId&&o.generatorId.trim())return o.generatorId.trim();throw new Error("[generator-workbench] generatorId is required in panelSchema.generatorId or state.meta.generatorId")}function u(t){const{sdk:e,runtime:n,config:o}=t;function i(){var t;const e=n.getState(),i=n.getPanelSchema(),a=d(i,null==(t=o.getTemplateFieldPaths)?void 0:t.call(o,i)),r=a.flatMap(t=>t.fields.map(t=>t.path));return l(r.length>0,"[generator-workbench] exportTemplate requires at least one panel field path"),{generatorId:c(i,e),state:e,panelSchema:i,fieldGroups:a,selectedFieldPaths:r}}return{async importTemplate(t){const o=await t.text(),i=e.template.parse(o);let a;return await e.template.applyToRuntime(n,i,{onPanelFilter(t){a=t}}),{template:i,panelFilter:a}},prepareTemplateExport:i,buildTemplate(t){var n;const a=i(),r=(null==t?void 0:t.length)?d(a.panelSchema,t).flatMap(t=>t.fields.map(t=>t.path)):a.selectedFieldPaths;l(r.length>0,"[generator-workbench] exportTemplate requires at least one panel field path");return e.template.build({generatorId:a.generatorId,state:a.state,panelSchema:a.panelSchema,selectedFieldPaths:r,templateMeta:null==(n=o.getTemplateMeta)?void 0:n.call(o)})},async exportTemplate(t){const n=this.buildTemplate(t);return e.template.download(n),{template:n}}}}function p(t,e,n){return t.dispatchEvent(new CustomEvent(e,{detail:n,bubbles:!0,composed:!0}))}function h(t,e){const n=t.querySelector(e);if(!n)throw new Error(`[generator-workbench] required DOM node not found: ${e}`);return n}const m="data:image/svg+xml,%3csvg%20width='24'%20height='24'%20viewBox='0%200%2024%2024'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3ccircle%20cx='12'%20cy='12'%20r='9'%20fill='url(%23paint0_linear_503_69253)'/%3e%3cg%20filter='url(%23filter0_d_503_69253)'%3e%3crect%20x='7.75781'%20y='12'%20width='6'%20height='6'%20rx='1'%20transform='rotate(-45%207.75781%2012)'%20fill='url(%23paint1_linear_503_69253)'/%3e%3c/g%3e%3cdefs%3e%3cfilter%20id='filter0_d_503_69253'%20x='2.17188'%20y='4.17188'%20width='19.6572'%20height='19.6562'%20filterUnits='userSpaceOnUse'%20color-interpolation-filters='sRGB'%3e%3cfeFlood%20flood-opacity='0'%20result='BackgroundImageFix'/%3e%3cfeColorMatrix%20in='SourceAlpha'%20type='matrix'%20values='0%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%20127%200'%20result='hardAlpha'/%3e%3cfeOffset%20dy='2'/%3e%3cfeGaussianBlur%20stdDeviation='3'/%3e%3cfeComposite%20in2='hardAlpha'%20operator='out'/%3e%3cfeColorMatrix%20type='matrix'%20values='0%200%200%200%201%200%200%200%200%200.206957%200%200%200%200%200.0670085%200%200%200%201%200'/%3e%3cfeBlend%20mode='normal'%20in2='BackgroundImageFix'%20result='effect1_dropShadow_503_69253'/%3e%3cfeBlend%20mode='normal'%20in='SourceGraphic'%20in2='effect1_dropShadow_503_69253'%20result='shape'/%3e%3c/filter%3e%3clinearGradient%20id='paint0_linear_503_69253'%20x1='12'%20y1='3'%20x2='12'%20y2='21'%20gradientUnits='userSpaceOnUse'%3e%3cstop%20stop-color='%23FFA346'/%3e%3cstop%20offset='1'%20stop-color='%23FF7C23'/%3e%3c/linearGradient%3e%3clinearGradient%20id='paint1_linear_503_69253'%20x1='13.2327'%20y1='12.5252'%20x2='8.63652'%20y2='18.5356'%20gradientUnits='userSpaceOnUse'%3e%3cstop%20stop-color='white'/%3e%3cstop%20offset='1'%20stop-color='%23FFD3B5'/%3e%3c/linearGradient%3e%3c/defs%3e%3c/svg%3e",g="data:image/svg+xml,%3Csvg%20viewBox%3D'0%200%201088%201024'%20xmlns%3D'http%3A//www.w3.org/2000/svg'%3E%3Cpath%20d%3D'M416%20128v85.312h-128A42.688%2042.688%200%200%200%20245.312%20256v512c0%2023.552%2019.136%2042.688%2042.688%2042.688h512a42.688%2042.688%200%200%200%2042.688-42.688V597.312H928V768a128%20128%200%200%201-128%20128h-512a128%20128%200%200%201-128-128V256a128%20128%200%200%201%20128-128h128z'%20fill%3D'%23ffffff'/%3E%3Cpath%20d%3D'M723.52%20520.832L924.352%20320l-200.832-200.832-60.352%2060.352%2097.856%2097.792h-67.712A298.688%20298.688%200%200%200%20394.688%20576v85.312H480V576a213.312%20213.312%200%200%201%20213.312-213.312h67.712l-97.856%2097.792%2060.352%2060.352z'%20fill%3D'%23ffffff'/%3E%3C/svg%3E",v=`\n <div class="shell">\n <header v-if="state.shellMode !== 'template'" class="topbar app-topbar">\n <div class="logo-area app-topbar-main" data-role="logo-area">\n <img\n :src="state.logoSrc"\n :alt="state.logoText || 'Atomm'"\n class="brand-logo"\n data-role="brand-logo"\n draggable="false"\n />\n <div class="app-topbar-nav">\n <xt-button\n v-show="state.templateEnabled"\n type="secondary"\n size="small"\n data-role="import-template"\n @click="callbacks.onImportTemplate()"\n >导入模板</xt-button>\n <xt-button\n v-show="state.templateEnabled"\n type="secondary"\n size="small"\n data-role="export-template"\n @click="callbacks.onExportTemplate()"\n >生成模板</xt-button>\n <div class="workbench-host-actions">\n <xt-button\n v-show="state.cloudEnabled"\n type="secondary"\n size="small"\n data-role="save-cloud"\n :loading="state.cloudSaveLoading"\n @click="callbacks.onSaveCloud()"\n >保存草稿</xt-button>\n <xt-button\n v-show="state.historyEnabled"\n type="secondary"\n size="small"\n data-role="open-history"\n :loading="state.historyLoading"\n @click="callbacks.onOpenHistory()"\n >历史记录</xt-button>\n </div>\n </div>\n </div>\n <div class="app-topbar-auth">\n <button\n v-if="state.invitationEnabled"\n type="button"\n class="invite-entry"\n data-role="open-invitation"\n @click="callbacks.onOpenInvitation()"\n >\n <img\n src="https://storage-us.atomm.com/resource/static/atomm/icon/Vector.svg"\n alt=""\n class="invite-entry-icon"\n draggable="false"\n />\n <span class="invite-entry-text">{{ state.invitationButtonText }}</span>\n </button>\n <div\n v-if="state.isLogin && state.creditsEnabled"\n class="topbar-credits-badge"\n data-role="topbar-credits"\n title="Remaining credits"\n >\n <img src="${m}" alt="" class="credits-token-icon" draggable="false" />\n <span class="topbar-credits-value" data-role="topbar-credits-value">{{ state.creditsBalance }}</span>\n </div>\n\n <div\n v-if="state.isLogin && state.avatarMenuTrigger === 'hover'"\n class="auth-hover-card"\n >\n <div class="auth-avatar-trigger" data-role="avatar-button" tabindex="0">\n <div class="auth-avatar">\n <img\n v-if="state.avatarSrc"\n :src="state.avatarSrc"\n alt="Avatar"\n data-role="avatar-image"\n />\n <span v-else data-role="avatar-image">{{ state.avatarText }}</span>\n </div>\n </div>\n <div class="auth-hover-panel">\n <div class="auth-popover-body" data-role="avatar-menu">\n <div class="auth-popover-header">\n <div class="auth-avatar auth-avatar--lg">\n <img v-if="state.avatarSrc" :src="state.avatarSrc" alt="Avatar" />\n <span v-else>{{ state.avatarText }}</span>\n </div>\n <div class="auth-popover-user-text">\n <span class="auth-popover-name">{{ state.authDisplayName }}</span>\n <span class="auth-popover-sub">{{ state.authSubline }}</span>\n </div>\n </div>\n <div class="auth-popover-divider"></div>\n <div class="auth-popover-action" data-role="logout" @click="callbacks.onLogout()">\n Logout\n </div>\n </div>\n </div>\n </div>\n\n <xt-dropdown-menu\n v-else-if="state.isLogin"\n trigger="click"\n :portal-disabled="true"\n placement="bottomRight"\n >\n <template #trigger>\n <div class="auth-avatar-trigger" data-role="avatar-button">\n <div class="auth-avatar">\n <img\n v-if="state.avatarSrc"\n :src="state.avatarSrc"\n alt="Avatar"\n data-role="avatar-image"\n />\n <span v-else data-role="avatar-image">{{ state.avatarText }}</span>\n </div>\n </div>\n </template>\n <template #overlay>\n <div class="auth-popover-body" data-role="avatar-menu">\n <div class="auth-popover-header">\n <div class="auth-avatar auth-avatar--lg">\n <img v-if="state.avatarSrc" :src="state.avatarSrc" alt="Avatar" />\n <span v-else>{{ state.avatarText }}</span>\n </div>\n <div class="auth-popover-user-text">\n <span class="auth-popover-name">{{ state.authDisplayName }}</span>\n <span class="auth-popover-sub">{{ state.authSubline }}</span>\n </div>\n </div>\n <div class="auth-popover-divider"></div>\n <div class="auth-popover-action" data-role="logout" @click="callbacks.onLogout()">\n Logout\n </div>\n </div>\n </template>\n </xt-dropdown-menu>\n\n <button\n type="button"\n class="auth-avatar-button auth-avatar-button--guest"\n data-role="login"\n v-if="!state.isLogin"\n @click="callbacks.onLogin()"\n >\n <div class="auth-avatar auth-avatar--guest">\n <img\n src="https://storage-us.atomm.com/resource/xart/static/agent/imgs/no-login.png"\n alt="Login"\n data-role="guest-avatar-image"\n draggable="false"\n />\n </div>\n </button>\n </div>\n </header>\n\n <div\n class="workspace"\n :class="[\n state.shellMode === 'shell'\n ? 'shell-mode-shell'\n : (state.panelTarget === 'left' ? 'panel-left' : 'panel-right'),\n ]"\n data-role="workspace"\n >\n <main\n v-if="state.shellMode === 'shell'"\n class="workspace-host"\n data-role="workspace-host"\n ></main>\n <template v-else>\n <main class="canvas-host" data-role="canvas-host"></main>\n <aside class="panel-sidebar" data-role="panel-sidebar">\n <div class="panel-host" data-role="panel-host"></div>\n <div id="sidebar-footer" class="sidebar-footer-export panel-actions" data-role="panel-actions">\n <xt-dropdown-menu\n trigger="click"\n :portal-disabled="true"\n placement="topLeft"\n domTriggerClass="sidebar-export-trigger-btn-wrap"\n :show-trigger-icon="false"\n domContentClass="sidebar-export-dropdown-menu"\n >\n <template #trigger>\n <xt-button class="sidebar-export-trigger-btn" block data-role="fab-trigger">\n <template #icon>\n <img\n src="${g}"\n alt=""\n width="16"\n height="16"\n draggable="false"\n />\n </template>\n Export\n <template #append-icon>\n <div v-if="state.showExportCreditsHint" class="export-credits-hint">\n <img v-if="state.showExportCreditsIcon" data-role="export-credits-icon" src="${m}" alt="" class="credits-token-icon credits-token-icon--sm" draggable="false" />\n <span class="export-credits-hint-value" data-role="export-credits-value">{{ state.exportCreditsHintText }}</span>\n </div>\n </template>\n </xt-button>\n </template>\n <template #overlay>\n <div class="export-overlay-menu fab-menu-content" data-role="fab-menu">\n <div\n v-show="state.exportEnabled"\n class="export-overlay-item"\n data-role="export-svg"\n @click="callbacks.onExportSvg()"\n >\n <span class="export-overlay-item-icon export-overlay-item-icon--svg"></span>\n Download\n </div>\n <div\n v-show="state.studioEnabled"\n class="export-overlay-item"\n data-role="open-in-studio"\n @click="callbacks.onOpenInStudio()"\n >\n <span class="export-overlay-item-icon export-overlay-item-icon--studio"></span>\n Open in Studio\n </div>\n </div>\n </template>\n </xt-dropdown-menu>\n </div>\n </aside>\n </template>\n </div>\n\n <div\n v-if="state.shellMode === 'shell'"\n id="sidebar-footer"\n class="sidebar-footer-export panel-actions sidebar-footer-floating"\n data-role="panel-actions"\n >\n <xt-dropdown-menu\n trigger="click"\n :portal-disabled="true"\n placement="topLeft"\n domTriggerClass="sidebar-export-trigger-btn-wrap"\n :show-trigger-icon="false"\n domContentClass="sidebar-export-dropdown-menu"\n >\n <template #trigger>\n <xt-button class="sidebar-export-trigger-btn" data-role="fab-trigger">\n <template #icon>\n <img\n src="${g}"\n alt=""\n width="16"\n height="16"\n draggable="false"\n />\n </template>\n Export\n <template #append-icon>\n <div v-if="state.showExportCreditsHint" class="export-credits-hint">\n <img v-if="state.showExportCreditsIcon" data-role="export-credits-icon" src="${m}" alt="" class="credits-token-icon credits-token-icon--sm" draggable="false" />\n <span class="export-credits-hint-value" data-role="export-credits-value">{{ state.exportCreditsHintText }}</span>\n </div>\n </template>\n </xt-button>\n </template>\n <template #overlay>\n <div class="export-overlay-menu fab-menu-content" data-role="fab-menu">\n <div\n v-show="state.exportEnabled"\n class="export-overlay-item"\n data-role="export-svg"\n @click="callbacks.onExportSvg()"\n >\n <span class="export-overlay-item-icon export-overlay-item-icon--svg"></span>\n Download\n </div>\n <div\n v-show="state.studioEnabled"\n class="export-overlay-item"\n data-role="open-in-studio"\n @click="callbacks.onOpenInStudio()"\n >\n <span class="export-overlay-item-icon export-overlay-item-icon--studio"></span>\n Open in Studio\n </div>\n </div>\n </template>\n </xt-dropdown-menu>\n </div>\n\n <input\n data-role="template-file-input"\n type="file"\n accept="application/json"\n style="display:none"\n @change="callbacks.onFileChange($event)"\n />\n\n <xt-modal\n :model-value="state.templateDialogOpen"\n title="发布模板"\n :show-footer="false"\n :portal-disabled="true"\n @update:model-value="callbacks.onToggleTemplateDialog($event)"\n >\n <div\n v-if="state.templateDialogOpen"\n class="template-export-modal"\n data-role="template-export-modal"\n >\n \n <div class="template-export-groups">\n <div\n v-for="group in state.templateFieldGroups"\n :key="group.id"\n class="template-export-group"\n >\n <div class="template-export-group-title">{{ group.title }}</div>\n <div class="template-export-field-list">\n <div\n v-for="field in group.fields"\n :key="field.path"\n class="template-export-field"\n data-role="template-export-field"\n >\n <xt-checkbox\n :model-value="state.templateSelectedFieldPaths.includes(field.path)"\n :disabled="state.templateExportLoading"\n @update:model-value="callbacks.onToggleTemplateField(field.path, $event)"\n >{{ field.label }}</xt-checkbox>\n <div class="template-export-field-path">{{ field.path }}</div>\n </div>\n </div>\n </div>\n </div>\n\n <div class="template-export-footer">\n <xt-button\n type="secondary"\n :disabled="state.templateExportLoading"\n @click="callbacks.onCloseTemplateDialog()"\n >取消</xt-button>\n <xt-button\n type="primary"\n data-role="template-export-confirm"\n :loading="state.templateExportLoading"\n :disabled="state.templateSelectedFieldPaths.length === 0"\n @click="callbacks.onConfirmTemplateExport()"\n >发布模板</xt-button>\n </div>\n </div>\n </xt-modal>\n\n <xt-modal\n :model-value="state.historyDialogOpen"\n title="历史记录"\n :show-footer="false"\n :portal-disabled="true"\n @update:model-value="!$event && callbacks.onCloseHistory()"\n >\n <div\n v-if="state.historyDialogOpen"\n class="history-dialog"\n data-role="history-dialog"\n >\n <div\n v-if="state.historyError"\n class="history-dialog-error"\n data-role="history-error"\n >{{ state.historyError }}</div>\n\n <div\n v-else-if="state.historyItems.length === 0 && !state.historyLoading"\n class="history-dialog-empty"\n data-role="history-empty"\n >暂无历史记录</div>\n\n <div class="history-list" v-else data-role="history-list">\n <div\n v-for="item in state.historyItems"\n :key="item.id"\n class="history-item"\n data-role="history-item"\n >\n <div class="history-item-title">{{ item.title }}</div>\n <div class="history-item-meta">#{{ item.id }}</div>\n <div class="history-item-actions">\n <xt-button\n type="secondary"\n size="small"\n :disabled="state.historyRestoreLoading"\n :data-role="'history-restore-' + item.id"\n @click="callbacks.onRestoreHistory(item.id)"\n >恢复</xt-button>\n <xt-button\n type="secondary"\n size="small"\n :disabled="state.historyDeleteLoading"\n :data-role="'history-delete-' + item.id"\n @click="callbacks.onDeleteHistory(item.id)"\n >删除</xt-button>\n </div>\n </div>\n </div>\n </div>\n </xt-modal>\n\n <XtAtommProContext\n v-if="state.invitationEnabled && state.invitationReady"\n :env="state.atommProEnv"\n :domain="state.atommProDomain"\n :utoken="state.authToken"\n :user="state.atommProUser"\n >\n <InvitationModal\n ref="invitationModalRef"\n :z-index="state.invitationZIndex"\n :show-link="state.invitationShowLink"\n />\n </XtAtommProContext>\n </div>\n`,f=new URL("../atomm-pro/dist-browser/atomm-pro.css","undefined"==typeof document&&"undefined"==typeof location?require("url").pathToFileURL(__filename).href:"undefined"==typeof document?location.href:o&&"SCRIPT"===o.tagName.toUpperCase()&&o.src||new URL("index.umd.js",document.baseURI).href).toString(),b=new URL("../atomm-pro/dist-browser/atomm-pro.js","undefined"==typeof document&&"undefined"==typeof location?require("url").pathToFileURL(__filename).href:"undefined"==typeof document?location.href:o&&"SCRIPT"===o.tagName.toUpperCase()&&o.src||new URL("index.umd.js",document.baseURI).href).toString();function y(t){return new Promise(e=>{setTimeout(e,t)})}const x=new Map;let w=null;const _=new Map,k=new Map;function C(){return globalThis.Vue}function E(t){return new Error(`[generator-workbench] failed to auto-load Vue 3 runtime from ${t}`)}async function S(t){const e=C();return e&&"function"==typeof e.createApp?e:function(t){const e=x.get(t);if(e)return e;const n=new Promise((e,n)=>{const o=C();if(o&&"function"==typeof o.createApp)return void e(o);const i=()=>{const o=C();o&&"function"==typeof o.createApp?e(o):(x.delete(t),n(E(t)))},a=()=>{x.delete(t),n(E(t))},r=Array.from(document.querySelectorAll("script")).find(e=>e.src===t);if(r)return r.addEventListener("load",i,{once:!0}),void r.addEventListener("error",a,{once:!0});const s=document.createElement("script");s.src=t,s.async=!0,s.dataset.generatorWorkbenchVue="true",s.addEventListener("load",i,{once:!0}),s.addEventListener("error",a,{once:!0}),(document.head||document.body||document.documentElement).appendChild(s)});return x.set(t,n),n}(t.vueScriptUrl||"https://unpkg.com/vue@3/dist/vue.global.prod.js")}function T(){return globalThis.AtommUI}function I(){return globalThis.Pinia}function P(){return globalThis.VueRouter}function R(){return globalThis.VueI18n}function U(){return globalThis.AtommPro}function L(t,e,n){const o=n();if(o)return Promise.resolve(o);const i=`${e}:${t}`,a=_.get(i);if(a)return a;const r=new Promise(o=>{const a=document.querySelector(`script[data-${e}="true"][src="${t}"]`),r=()=>o(n()),s=()=>{_.delete(i),o(void 0)};if(a)return a.addEventListener("load",r,{once:!0}),void a.addEventListener("error",s,{once:!0});const l=document.createElement("script");l.src=t,l.async=!0,l.dataset[e]="true",l.addEventListener("load",r,{once:!0}),l.addEventListener("error",s,{once:!0}),function(t){(document.head||document.body||document.documentElement).appendChild(t)}(l)});return _.set(i,r),r}async function D(t,e){const n=await function(t){const e=k.get(t);if(e)return e;const n=fetch(t).then(async e=>e.ok?e.text():(k.delete(t),null)).catch(()=>(k.delete(t),null));return k.set(t,n),n}(e),o=n?function(t){return t.replace(/(^|})\s*:root(?=\s*{)/g,"$1:host")}(n):null;if(o){const n=document.createElement("style");n.dataset.generatorWorkbenchStyleUrl=e,n.textContent=o,t.appendChild(n)}else{const n=document.createElement("link");n.rel="stylesheet",n.href=e,t.appendChild(n)}}async function A(t){const e=document.head.querySelector(`style[data-generator-workbench-global-style-url="${t}"]`),n=document.head.querySelector(`link[data-generator-workbench-global-style-url="${t}"]`);if(e||n)return;const o=document.createElement("link");o.rel="stylesheet",o.href=t,o.dataset.generatorWorkbenchGlobalStyleUrl=t,(document.head||document.body||document.documentElement).appendChild(o)}function B(t){var e;return(null==(e=t.atommProLocale)?void 0:e.trim())?t.atommProLocale.trim():"undefined"!=typeof navigator&&navigator.language.startsWith("zh")?"zh-CN":"en-US"}function F(t){return t.atommProEnv||"prod"}function H(t){return t.atommProDomain||"atomm"}function q(t){return!1!==t.invitationEnabled}function O(t){t.component("xt-button",{inheritAttrs:!0,template:'<button v-bind="$attrs"><slot name="icon" /><slot /><slot name="append-icon" /></button>'}),t.component("xt-avatar",{inheritAttrs:!0,template:'<span v-bind="$attrs"><slot /></span>'}),t.component("xt-dropdown-menu",{inheritAttrs:!0,template:'<div v-bind="$attrs"><slot name="trigger" /><slot name="overlay" /><slot /></div>'}),t.component("xt-hover-card",{inheritAttrs:!0,template:'<div v-bind="$attrs"><slot name="trigger" /><slot name="content" /></div>'}),t.component("xt-modal",{inheritAttrs:!1,props:{modelValue:{type:Boolean,default:!1},title:{type:String,default:""}},emits:["update:modelValue"],template:'\n <div v-if="modelValue" v-bind="$attrs">\n <div>{{ title }}</div>\n <slot />\n </div>\n '}),t.component("xt-checkbox",{inheritAttrs:!1,props:{modelValue:{type:Boolean,default:!1},label:{type:String,default:""},disabled:{type:Boolean,default:!1}},emits:["update:modelValue","change"],template:'\n <label v-bind="$attrs">\n <input\n type="checkbox"\n :checked="modelValue"\n :disabled="disabled"\n @change="$emit(\'update:modelValue\', $event.target.checked)"\n />\n <span><slot>{{ label }}</slot></span>\n </label>\n '})}async function M(t){const e=T();return e||(n=t.atommUiScriptUrl||"https://minio-download.makeblock.com/resource/atomm-ui-umd/dist-browser/atomm-ui.js",w||(w=L(n,"generatorWorkbenchAtommUi",T),w));var n}async function z(t,e={}){if(!e.force&&!q(t))return null;const[n,o,i]=await Promise.all([L(t.piniaScriptUrl||"https://unpkg.com/pinia@3/dist/pinia.iife.prod.js","generatorWorkbenchPinia",I),L(t.vueRouterScriptUrl||"https://unpkg.com/vue-router@4/dist/vue-router.global.prod.js","generatorWorkbenchVueRouter",P),L(t.vueI18nScriptUrl||"https://unpkg.com/vue-i18n@11/dist/vue-i18n.global.prod.js","generatorWorkbenchVueI18n",R)]);if(!n||!o||!i)return null;const a=await L(t.atommProScriptUrl||b,"generatorWorkbenchAtommPro",U);return a?{pinia:n,vueRouter:o,vueI18n:i,atommPro:a}:null}async function $(t,e){var n,o,i,a;const r=await S(e);!function(){const t=globalThis;t.process?t.process.env?t.process.env.NODE_ENV||(t.process.env.NODE_ENV="production"):t.process.env={NODE_ENV:"production"}:t.process={env:{NODE_ENV:"production"}}}();const s=await z(e);await async function(t,e){const n=e.atommUiCssUrl||"https://minio-download.makeblock.com/resource/atomm-ui-umd/dist-browser/atomm-ui.min.css";if(await D(t,n),await A(n),q(e)){const n=e.atommProCssUrl||f;await D(t,n),await A(n)}const o=document.createElement("style");o.textContent="\n :host {\n display: block;\n height: 100%;\n color: #111827;\n font-family: Inter, \"Montserrat\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n --bg-soft: #f3f4f6;\n --border-default: #e5e7eb;\n --text-primary: #111827;\n --text-secondary: #4b5563;\n --text-muted: #9ca3af;\n }\n\n * {\n box-sizing: border-box;\n }\n\n [data-workbench-vue-root] {\n height: 100%;\n }\n\n .shell {\n height: 100%;\n display: flex;\n flex-direction: column;\n background:\n radial-gradient(rgba(17, 24, 39, 0.06) 1px, transparent 1px),\n linear-gradient(180deg, rgba(255, 255, 255, 0.7), rgba(249, 250, 251, 0.96));\n background-size: 20px 20px, auto;\n }\n\n .topbar,\n .app-topbar {\n height: 64px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 0 24px;\n background: rgba(255, 255, 255,1);\n border-bottom: 1px solid var(--border-default);\n backdrop-filter: blur(12px);\n position: relative;\n z-index: 20;\n }\n\n .logo-area,\n .app-topbar-main {\n display: flex;\n align-items: center;\n gap: 18px;\n min-width: 0;\n flex: 1;\n }\n\n .app-topbar-nav {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n }\n\n .workspace {\n flex: 1;\n min-height: 0;\n display: grid;\n grid-template-columns: minmax(0, 1fr) 320px;\n }\n\n .workspace.shell-mode-shell {\n display: block;\n position: relative;\n }\n\n .workspace-host {\n height: 100%;\n min-height: 0;\n position: relative;\n }\n\n .workspace.panel-left {\n grid-template-columns: 320px minmax(0, 1fr);\n }\n\n .workspace.panel-right .canvas-host {\n grid-column: 1;\n }\n\n .workspace.panel-right .panel-sidebar {\n grid-column: 2;\n }\n\n .workspace.panel-left .panel-sidebar {\n grid-column: 1;\n }\n\n .workspace.panel-left .canvas-host {\n grid-column: 2;\n }\n\n .panel-sidebar {\n min-height: 0;\n display: flex;\n flex-direction: column;\n background: #ffffff;\n }\n\n .panel-host {\n flex: 1;\n min-height: 0;\n overflow: auto;\n }\n\n .canvas-host {\n position: relative;\n min-height: 480px;\n display: grid;\n place-items: center;\n }\n\n .brand-logo {\n height: 32px;\n width: 92px;\n display: block;\n cursor: pointer;\n flex: 0 0 auto;\n }\n\n .app-topbar-auth {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 12px;\n flex: 0 0 auto;\n }\n\n .topbar-credits-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0;\n color: #2d3541;\n font-size: 14px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n cursor: default;\n }\n\n .topbar-credits-value {\n font-variant-numeric: tabular-nums;\n }\n\n .invite-entry {\n appearance: none;\n border: 0;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 6px;\n border-radius: 6px;\n background: #fcf3ed;\n cursor: pointer;\n user-select: none;\n white-space: nowrap;\n transition: all 0.3s;\n }\n\n .invite-entry:hover:not(:disabled) {\n background:\n linear-gradient(\n 0deg,\n rgba(255, 124, 35, 0.2) 0%,\n rgba(255, 124, 35, 0.2) 100%\n ),\n #fcf3ed;\n }\n\n .invite-entry:disabled {\n opacity: 0.48;\n cursor: not-allowed;\n }\n\n .invite-entry-icon {\n width: 14px;\n height: 14px;\n flex: 0 0 auto;\n display: block;\n user-select: none;\n -webkit-user-drag: none;\n }\n\n .invite-entry-text {\n color: #ff7c23;\n font-size: 12px;\n font-weight: 600;\n line-height: 1;\n }\n\n .credits-token-icon {\n width: 20px;\n height: 20px;\n flex: 0 0 16px;\n user-select: none;\n -webkit-user-drag: none;\n }\n\n .credits-token-icon--sm {\n width: 16px;\n height: 16px;\n flex-basis: 16px;\n }\n\n .auth-avatar-trigger {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px 4px 4px;\n border-radius: 999px;\n cursor: pointer;\n transition: background 150ms ease;\n }\n\n .auth-avatar-button {\n appearance: none;\n border: 0;\n background: transparent;\n cursor: pointer;\n }\n\n .auth-avatar-button--guest {\n padding: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n }\n\n\n .auth-avatar {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n display: grid;\n place-items: center;\n overflow: hidden;\n flex: 0 0 auto;\n background: #f3f4f6;\n color: var(--text-secondary);\n font-size: 14px;\n font-weight: 600;\n }\n\n .auth-avatar--lg {\n width: 40px;\n height: 40px;\n font-size: 14px;\n }\n\n .auth-avatar--guest {\n background: transparent;\n }\n\n .auth-avatar img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n }\n\n .auth-popover-body {\n min-width: 200px;\n padding: 4px 0;\n }\n\n .auth-popover-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n }\n\n .auth-popover-user-text {\n min-width: 0;\n flex: 1;\n }\n\n .auth-popover-name {\n display: block;\n font-size: 14px;\n font-weight: 600;\n color: var(--text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .auth-popover-sub {\n display: block;\n margin-top: 2px;\n font-size: 12px;\n color: var(--text-secondary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .auth-popover-divider {\n height: 1px;\n background: var(--border-default);\n margin: 4px 0;\n }\n\n .auth-popover-action {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n font-size: 13px;\n color: var(--text-secondary);\n cursor: pointer;\n transition: all 150ms ease;\n }\n\n .auth-popover-action:hover {\n background: var(--bg-soft);\n color: var(--text-primary);\n }\n\n .auth-hover-card {\n position: relative;\n display: inline-flex;\n align-items: center;\n z-index: 99999;\n }\n\n .auth-hover-panel {\n position: absolute;\n top: calc(100% + 8px);\n right: 0;\n z-index: 999999;\n min-width: 200px;\n background: #fff;\n border: 1px solid var(--border-default);\n border-radius: 12px;\n box-shadow: 0 8px 28px rgba(17, 24, 39, 0.12);\n opacity: 0;\n transform: translateY(4px);\n pointer-events: none;\n transition: opacity 150ms ease, transform 150ms ease;\n }\n\n .auth-hover-card:hover .auth-hover-panel,\n .auth-hover-card:focus-within .auth-hover-panel {\n opacity: 1;\n transform: translateY(-6px);\n pointer-events: auto;\n }\n\n .panel-actions,\n #sidebar-footer {\n flex-shrink: 0;\n width: 262px;\n display: flex;\n align-items: center;\n }\n\n .panel-sidebar #sidebar-footer {\n padding: 14px 24px;\n flex-shrink: 0;\n width: auto;\n display: flex;\n align-items: center;\n \n }\n\n .sidebar-footer-floating {\n position: fixed;\n right: 24px;\n bottom: 24px;\n z-index: 30;\n width: auto;\n padding: 0;\n border-top: 0;\n background: transparent;\n box-shadow: none;\n }\n\n .sidebar-footer-floating .sidebar-export-trigger-btn,\n .sidebar-footer-floating .sidebar-export-trigger-btn-wrap,\n .sidebar-footer-floating .sidebar-export-trigger-btn-wrap {\n width: auto;\n }\n\n .sidebar-footer-floating .sidebar-export-trigger-btn {\n min-width: 180px;\n box-shadow: 0 12px 28px rgba(17, 24, 39, 0.18);\n }\n\n .sidebar-footer-export {\n width: 100%;\n }\n\n .sidebar-footer-export .sidebar-export-trigger-btn,\n .sidebar-footer-export .sidebar-export-trigger-btn-wrap,\n .sidebar-export-trigger-btn-wrap {\n width: 100%;\n }\n\n .sidebar-export-dropdown-menu {\n width: 268px;\n }\n\n .sidebar-export-trigger-btn img {\n margin-right: 4px;\n }\n\n .export-credits-hint {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 2px;\n padding: 0;\n font-size: 12px;\n font-weight: 600;\n line-height: 1;\n color: #ff7c23;\n margin-left: 10px;\n white-space: nowrap;\n }\n\n .export-credits-hint-value {\n width: 100%;\n background: linear-gradient(90deg, #fce1bf, #ecb678 67.02%, #f9c991);\n border-radius: 4px;\n gap: 2px;\n height: 16px;\n padding: 2px 4px;\n font-size: 10px;\n font-weight: 600;\n line-height: 16px;\n color: #581e06;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n\n .export-overlay-menu,\n .fab-menu-content {\n padding: 4px;\n }\n\n .export-overlay-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-radius: 6px;\n font-size: 14px;\n color: var(--text-primary);\n cursor: pointer;\n transition: background 120ms ease;\n user-select: none;\n }\n\n .export-overlay-item:hover {\n background: var(--bg-soft);\n }\n\n .export-overlay-item-icon {\n width: 16px;\n height: 16px;\n display: inline-block;\n flex: 0 0 auto;\n background-repeat: no-repeat;\n background-position: center;\n background-size: contain;\n }\n\n .export-overlay-item-icon--svg {\n background-image: url(\"data:image/svg+xml,%3c?xml%20version='1.0'%20standalone='no'?%3e%3c!DOCTYPE%20svg%20PUBLIC%20'-//W3C//DTD%20SVG%201.1//EN'%20'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3e%3csvg%20t='1775118703519'%20class='icon'%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20p-id='12828'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20width='200'%20height='200'%3e%3cpath%20d='M469.333333%20596.053333V128h85.333334v468.053333l208.64-160.554666%2052.053333%2067.669333-277.333333%20213.333333a42.666667%2042.666667%200%200%201-52.053334%200l-277.333333-213.333333%2052.053333-67.669333L469.333333%20596.053333zM896%20896H128v-85.333333h768v85.333333z'%20p-id='12829'%3e%3c/path%3e%3c/svg%3e\");\n }\n\n .export-overlay-item-icon--studio {\n background-image: url(\"data:image/svg+xml,%3c?xml%20version='1.0'%20standalone='no'?%3e%3c!DOCTYPE%20svg%20PUBLIC%20'-//W3C//DTD%20SVG%201.1//EN'%20'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3e%3csvg%20t='1775118714051'%20class='icon'%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20p-id='12988'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20width='200'%20height='200'%3e%3cpath%20d='M197.553231%20309.169231h128.945231l85.858461%2085.858461-64.512%2064.827077-150.291692-150.685538z%20m472.694154%2021.267692L509.006769%20492.307692l182.429539%20183.059693H562.491077L444.494769%20557.056%20326.498462%20675.288615H197.553231l364.937846-366.119384h128.945231l-21.188923%2021.267692z'%20p-id='12989'%3e%3c/path%3e%3cpath%20d='M157.538462%200a157.538462%20157.538462%200%200%200-157.538462%20157.538462v682.692923a157.538462%20157.538462%200%200%200%20157.538462%20157.538461h236.307692v-105.078154H157.538462a52.539077%2052.539077%200%200%201-52.539077-52.460307V157.538462c0-28.987077%2023.552-52.539077%2052.539077-52.539077h577.614769c29.065846%200%2052.539077%2023.552%2052.539077%2052.539077v393.846153h104.999384V157.538462a157.538462%20157.538462%200%200%200-157.538461-157.538462H157.538462z'%20p-id='12990'%3e%3c/path%3e%3cpath%20d='M789.267692%20681.038769l159.113846%20159.113846-159.113846%20159.113847-55.689846-55.611077%2064.039385-64.039385H551.384615v-78.769231h246.232616l-64.039385-64.039384%2055.689846-55.768616z'%20p-id='12991'%3e%3c/path%3e%3c/svg%3e\");\n }\n\n .workspace.panel-right .panel-sidebar {\n border-left: 1px solid var(--border-default);\n }\n\n .workspace.panel-left .panel-sidebar {\n border-right: 1px solid var(--border-default);\n }\n\n .template-export-modal {\n display: grid;\n gap: 16px;\n }\n\n \n\n .template-export-groups {\n display: grid;\n gap: 12px;\n max-height: 360px;\n overflow: auto;\n }\n\n .template-export-group {\n display: grid;\n gap: 10px;\n padding: 14px 16px;\n border: 1px solid var(--border-default);\n border-radius: 12px;\n background: #ffffff;\n }\n\n .template-export-group-title {\n font-size: 13px;\n font-weight: 700;\n color: var(--text-primary);\n }\n\n .template-export-field-list {\n display: grid;\n gap: 10px;\n }\n\n .template-export-field {\n display: grid;\n gap: 4px;\n }\n\n .template-export-field-path {\n padding-left: 28px;\n font-size: 12px;\n color: var(--text-muted);\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n }\n\n .template-export-footer {\n display: flex;\n justify-content: flex-end;\n gap: 12px;\n padding: 8px 24px;\n }\n\n .workbench-host-actions {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n }\n\n .history-dialog {\n display: grid;\n gap: 16px;\n }\n\n .history-dialog-error {\n color: #b91c1c;\n font-size: 13px;\n }\n\n .history-dialog-empty {\n color: var(--text-secondary);\n font-size: 13px;\n }\n\n .history-list {\n display: grid;\n gap: 12px;\n max-height: 360px;\n overflow: auto;\n }\n\n .history-item {\n display: grid;\n gap: 10px;\n padding: 14px 16px;\n border: 1px solid var(--border-default);\n border-radius: 12px;\n background: #ffffff;\n }\n\n .history-item-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--text-primary);\n }\n\n .history-item-meta {\n font-size: 12px;\n color: var(--text-muted);\n }\n\n .history-item-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n }\n",t.appendChild(o)}(t,e);const l=function(t,e,n){var o;return t.reactive({shellMode:e.mode||"full",logoText:e.logoText||e.title,logoSrc:e.logoUrl||"https://storage-us.atomm.com/resource/xart/static/agent/imgs/atomm-logo.svg",panelTarget:e.panelTarget||"right",avatarMenuTrigger:e.avatarMenuTrigger||"hover",templateEnabled:!1!==e.templateEnabled,creditsEnabled:!1!==e.creditsEnabled,invitationEnabled:q(e),invitationReady:n,invitationConfigKey:(null==(o=e.invitationConfigKey)?void 0:o.trim())||"",invitationButtonText:e.invitationButtonText||"Earn Credits",invitationShowLink:!0===e.invitationShowLink,invitationZIndex:e.invitationZIndex||2e3,atommProEnv:F(e),atommProDomain:H(e),authToken:"",atommProUser:{userName:"",userHandle:"",avatar:""},exportEnabled:!1!==e.exportEnabled,studioEnabled:!1!==e.studioEnabled,cloudEnabled:!0===e.cloudEnabled,historyEnabled:!0===e.historyEnabled,isLogin:!1,avatarSrc:"",avatarText:"U",authDisplayName:"",authSubline:"",creditsBalance:0,showExportCreditsHint:!1,showExportCreditsIcon:!1,exportCreditsHintText:"",loginLoading:!1,cloudSaveLoading:!1,historyDialogOpen:!1,historyLoading:!1,historyRestoreLoading:!1,historyDeleteLoading:!1,historyError:"",historyItems:[],templateDialogOpen:!1,templateExportLoading:!1,templateSelectedFieldPaths:[],templateFieldGroups:[]})}(r,e,null!==s),d={onLogin:()=>{},onOpenInvitation:()=>{},onLogout:()=>{},onImportTemplate:()=>{},onExportTemplate:()=>{},onSaveCloud:()=>{},onOpenHistory:()=>{},onCloseHistory:()=>{},onRestoreHistory:()=>{},onDeleteHistory:()=>{},onCloseTemplateDialog:()=>{},onToggleTemplateDialog:()=>{},onToggleTemplateField:()=>{},onConfirmTemplateExport:()=>{},onExportSvg:()=>{},onOpenInStudio:()=>{},onFileChange:()=>{}},c=r.ref(null),u=document.createElement("div");u.setAttribute("data-workbench-vue-root",""),t.appendChild(u);const p=await M(e),m=s?s.vueRouter.createRouter({history:(null==(o=(n=s.vueRouter).createMemoryHistory)?void 0:o.call(n))||(null==(a=(i=s.vueRouter).createWebHashHistory)?void 0:a.call(i))||{},routes:[{path:"/",component:{template:"<div />"}}]}):null,g=s?s.vueI18n.createI18n({legacy:!1,locale:B(e),fallbackLocale:B(e),globalInjection:!0,messages:e.atommProMessages||{"en-US":{},"zh-CN":{}},missingWarn:!1,fallbackWarn:!1}):null,b=r.createApp({setup:()=>({state:l,callbacks:d,invitationModalRef:c}),template:v});p?b.use(p):O(b),s||function(t){t.component("XtAtommProContext",{inheritAttrs:!0,template:'<div v-bind="$attrs"><slot /></div>'}),t.component("InvitationModal",{template:'<div data-role="stub-invitation-modal"></div>',methods:{open(){}}})}(b),s&&(b.use(s.pinia.createPinia()),m&&b.use(m),g&&b.use(g),b.use(s.atommPro)),b.mount(u);const x=function(t){return{root:t,workspace:h(t,'[data-role="workspace"]'),logoArea:t.querySelector('[data-role="logo-area"]'),workspaceHost:t.querySelector('[data-role="workspace-host"]'),canvasHost:t.querySelector('[data-role="canvas-host"]'),panelHost:t.querySelector('[data-role="panel-host"]'),templateFileInput:h(t,'[data-role="template-file-input"]')}}(t);let w=null;return{state:l,callbacks:d,app:b,refs:x,openInvitationModal:()=>{var t,e;const n=c.value,o=(null==n?void 0:n.open)||(null==(e=null==(t=null==n?void 0:n.$)?void 0:t.exposed)?void 0:e.open);null==o||o({configKey:l.invitationConfigKey||"default",showDetail:!1})},requestCreditsPurchase:async t=>{if(!w){await A(e.atommProCssUrl||f);const t=await z(e,{force:!0});if(!t)throw new Error("[generator-workbench] atomm-pro runtime is not available");w=function(t){var e,n,o,i;const{vue:a,state:r,config:s,runtime:l,atommUi:d}=t,c=a.ref(null),u=document.createElement("div");u.style.display="none",(document.body||document.documentElement).appendChild(u);const p=a.createApp({setup:()=>({state:r,bridgeRef:c}),template:'\n <XtAtommProContext\n :env="state.atommProEnv"\n :domain="state.atommProDomain"\n :utoken="state.authToken"\n :user="state.atommProUser"\n >\n <WorkbenchPayServiceBridge ref="bridgeRef" />\n </XtAtommProContext>\n '});return p.component("WorkbenchPayServiceBridge",{setup(t,e){var n,o,i;const{expose:r}=e,s=null==(n=a.getCurrentInstance)?void 0:n.call(a),d=null==(i=(o=l.atommPro).usePayService)?void 0:i.call(o,s);return r({purchase:t=>{if(!(null==d?void 0:d.purchase))throw new Error("[generator-workbench] atomm-pro pay service is not ready");return d.purchase(t)}}),{}},template:'<div data-role="pay-service-bridge" style="display:none"></div>'}),d?p.use(d):O(p),p.use(l.pinia.createPinia()),p.use(l.vueRouter.createRouter({history:(null==(n=(e=l.vueRouter).createMemoryHistory)?void 0:n.call(e))||(null==(i=(o=l.vueRouter).createWebHashHistory)?void 0:i.call(o))||{},routes:[{path:"/",component:{template:"<div />"}}]})),p.use(l.vueI18n.createI18n({legacy:!1,locale:B(s),fallbackLocale:B(s),globalInjection:!0,messages:s.atommProMessages||{"en-US":{},"zh-CN":{}},missingWarn:!1,fallbackWarn:!1})),p.use(l.atommPro),p.mount(u),{purchase:async t=>{const e=l.atommPro.AtommProContext;if((null==e?void 0:e.use)&&!e.payConfig){e.use({env:r.atommProEnv,domain:r.atommProDomain,utoken:r.authToken,user:r.atommProUser,watch:!0});const t=Date.now()+3e3;for(;!e.payConfig&&Date.now()<t;)await y(25)}const n=c.value;if(!(null==n?void 0:n.purchase))throw new Error("[generator-workbench] atomm-pro pay bridge is not ready");return n.purchase(t)},dispose:()=>{p.unmount(),u.remove()}}}({vue:r,state:l,config:e,runtime:t,atommUi:p})}return w.purchase(t)},disposeCreditsPurchaseBridge:()=>{null==w||w.dispose(),w=null}}}function N(t){t.disposeCreditsPurchaseBridge(),t.app.unmount()}function G(t){const{targetWindow:e=window,parentWindow:n=window.parent,targetOrigin:o="*",validateOrigin:i,handlers:a}=t;let r=!1;const s=(t,e)=>{r||(Q("outgoing",{type:t,data:e,targetOrigin:o}),n.postMessage({type:t,data:e},o))},l=(t,e)=>{Q("error",{type:"generator_toTemplateError",action:t,message:K(e)}),s("generator_toTemplateError",{action:t,message:K(e)})},d=t=>{if(r)return;if(i&&!i(t.origin,t))return;const e=t.data;if(!e||"object"!=typeof e)return;const n="type"in e&&"string"==typeof e.type?e.type:"",o="data"in e?e.data:void 0;switch(Q("incoming",{type:n,data:o,origin:t.origin}),n){case"generator_getGeneratorData":return void a.getGeneratorData().then(t=>{s("generator_toGeneratorData",t)}).catch(t=>{l("getGeneratorData",t)});case"generator_setGeneratorData":return void Promise.resolve(a.setGeneratorData(o||{}));case"generator_loadTemplateData":return void a.loadTemplateData(o||{}).then(t=>{s("generator_toTemplateLoaded",{template:(null==t?void 0:t.template)||(o&&"template"in o?o.template:o)||null})}).catch(t=>{l("loadTemplateData",t)});case"generator_getTemplateData":return void a.getTemplateData().then(t=>{s("generator_toTemplateData",t)}).catch(t=>{l("getTemplateData",t)});case"generator_getFile":{const t=function(t){return"openInStudio"===t||"cover"===t?t:"download"}(null==o?void 0:o.action);return void a.getFile(t).then(t=>{s("generator_toFile",t)}).catch(e=>{((t,e)=>{Q("error",{type:"generator_toFileError",action:t,message:K(e)}),s("generator_toFileError",{action:t,message:K(e)})})(t,e)})}case"generator_getTemplateFieldOptions":return void l("getTemplateFieldOptions",new Error("Template field options are not supported"));case"generator_publishTemplate":return void l("publishTemplate",new Error("Template publishing is not supported"));default:return}};return e.addEventListener("message",d),s("generator_pageLoaded"),{dispose(){r||(Q("lifecycle",{type:"dispose"}),r=!0,e.removeEventListener("message",d))}}}async function W(t){var e,n;const{action:o,sdk:i,runtime:a,config:r,element:s}=t,l={sdk:i,runtime:a,element:s},d=await Promise.resolve(null==(n=null==(e=r.embedBridge)?void 0:e.getExportData)?void 0:n.call(e,o,l))||await async function(t,e){const n=t.export,o=n.provider;if(!o)return null;const i=function(t){if("openInStudio"===t)return"studio";return t}(e),a="cover"===e?"png":"svg";if("function"==typeof o.getExportData){const t=await Promise.resolve(o.getExportData(i,a));if(t)return t}if("function"==typeof o.getExportCanvas){const t=await Promise.resolve(o.getExportCanvas(i));if(t)return{type:"canvas",canvas:t}}return null}(i,o);if(!d)throw new Error("No export data available");return{action:o,...await j(d)}}async function V(t){var e,n;const{sdk:o,runtime:i,config:a,element:r}=t;return await Promise.resolve(null==(n=null==(e=a.embedBridge)?void 0:e.getOriginImageUrl)?void 0:n.call(e,{sdk:o,runtime:i,element:r}))||""}async function j(t){switch(t.type){case"canvas":return{base64:t.canvas.toDataURL("image/png"),mimeType:"image/png",ext:"png"};case"dataUrl":{const e=X(t.dataUrl);return{base64:t.dataUrl,mimeType:e,ext:Z(e)}}case"svg":return{base64:Y(t.svgString),mimeType:"image/svg+xml",ext:"svg"};case"blob":{const e=await J(t.blob),n=t.blob.type||X(e);return{base64:e,mimeType:n,ext:Z(n)}}case"url":{const e=await fetch(t.url);if(!e.ok)throw new Error(`Failed to fetch export URL: ${e.status}`);const n=await e.blob(),o=await J(n),i=n.type||X(o);return{base64:o,mimeType:i,ext:Z(i)}}}}function K(t){return t instanceof Error?t.message:String(t)}function X(t){var e;return(null==(e=t.match(/^data:(image\/[a-zA-Z0-9.+-]+);/))?void 0:e[1])||"image/png"}function Z(t){var e;return"image/svg+xml"===t?"svg":"image/jpeg"===t?"jpg":(null==(e=t.split("/")[1])?void 0:e.split("+")[0])||"png"}function Y(t){const e=encodeURIComponent(t).replace(/%([0-9A-F]{2})/g,(t,e)=>String.fromCharCode(Number.parseInt(e,16)));return`data:image/svg+xml;base64,${btoa(e)}`}function J(t){return new Promise((e,n)=>{const o=new FileReader;o.onload=()=>{"string"==typeof o.result?e(o.result):n(new Error("Failed to read blob as data URL"))},o.onerror=()=>{n(o.error||new Error("Failed to read blob as data URL"))},o.readAsDataURL(t)})}function Q(t,e){new URLSearchParams(window.location.search).get("bridgeDebug")}const tt={title:"",mode:"full",templateEnabled:!0,exportEnabled:!0,studioEnabled:!0,autoMount:!0,panelTarget:"right",avatarMenuTrigger:"hover"};function et(t){return"shell"===t.mode}function nt(){return"embed"===new URLSearchParams(window.location.search).get("mode")?"embed":"full"}class ot extends HTMLElement{constructor(){super(),n(this,"_sdk",null),n(this,"_runtime",null),n(this,"_config",{...tt}),n(this,"_mounted",!1),n(this,"_state",{authStatus:{isLogin:!1,userInfo:null},creditsBalance:0,billingUsage:null,cloudRecordId:null,lastSavedAt:null,historyItems:[],historyDrawerOpen:!1,historyError:null,saveError:null,busy:{login:!1,importTemplate:!1,exportTemplate:!1,exportSvg:!1,openInStudio:!1,cloudSave:!1,historyLoad:!1,historyRestore:!1,historyDelete:!1},menu:{avatarOpen:!1,fabOpen:!1}}),n(this,"_cleanupAuth"),n(this,"_cleanupCredits"),n(this,"_cleanupBilling"),n(this,"_cleanupRuntimeSubscription"),n(this,"_cloudAutoSaveScheduler"),n(this,"_runtimeCloudSaveTimer",null),n(this,"_billingCountdownTimer",null),n(this,"_authController"),n(this,"_templateController"),n(this,"_exportController"),n(this,"_cloudController"),n(this,"_historyController"),n(this,"_runtimeController"),n(this,"_shellContext"),n(this,"_iframeBridge"),n(this,"handleRuntimeCloudSaveRequest",t=>{if(!t.detail)return;this._runtimeCloudSaveTimer&&clearTimeout(this._runtimeCloudSaveTimer);const e=t.detail;this._runtimeCloudSaveTimer=setTimeout(()=>{this._runtimeCloudSaveTimer=null;const t=this.getRouteCloudRecordId()??this._state.cloudRecordId;t?this.performCloudSave({...e,id:t}):this.handleError("runtime",new Error("[generator-workbench] gid is required for runtime cloud save requests"))},2e3)}),this.attachShadow({mode:"open"})}get sdk(){return this._sdk}set sdk(t){this._sdk=t}get runtime(){return this._runtime}set runtime(t){this._runtime=t}get config(){return this._config}set config(t){var e;this._config=(e=t,{...tt,...e}),this._mounted&&this.render()}connectedCallback(){!1!==this._config.autoMount&&!this._mounted&&this._sdk&&this._runtime&&this.mount()}disconnectedCallback(){this.unmount()}async mount(){var t,e,n;if(this._mounted)return;if(!this.shadowRoot)throw new Error("[generator-workbench] shadowRoot is required");if(!this._sdk)throw new Error("[generator-workbench] sdk is required before mount()");if(!this._runtime)throw new Error("[generator-workbench] runtime is required before mount()");await this.render(),this.bindControllers(),this.bindShellCallbacks(),this.bindAuthState(),this.bindRuntimeCloudSaveEvent(),await this.initializeCloudRecordFromRoute(),this.bindAutoSave(),await this.syncBillingState();const o=this.requireRefs();if(et(this._config)){const e=o.workspaceHost;if(!e)throw new Error("[generator-workbench] workspace host is required in shell mode");await(null==(t=this._runtimeController)?void 0:t.mountWorkspace(e))}else{const t=o.canvasHost,i=o.panelHost;if(!t||!i)throw new Error("[generator-workbench] canvas host and panel host are required in full/template mode");await(null==(e=this._runtimeController)?void 0:e.mountCanvas(t)),await(null==(n=this._runtimeController)?void 0:n.mountPanel(i,this._state.activePanelFilter))}this.bindIframeBridge(),this._mounted=!0,p(this,"workbench-ready",{sdk:this._sdk,runtime:this._runtime})}async unmount(){var t,e,n,o,i,a,r;null==(t=this._cleanupAuth)||t.call(this),this._cleanupAuth=void 0,null==(e=this._cleanupCredits)||e.call(this),this._cleanupCredits=void 0,null==(n=this._cleanupBilling)||n.call(this),this._cleanupBilling=void 0,null==(o=this._cleanupRuntimeSubscription)||o.call(this),this._cleanupRuntimeSubscription=void 0,null==(i=this._cloudAutoSaveScheduler)||i.dispose(),this._cloudAutoSaveScheduler=void 0,this._runtimeCloudSaveTimer&&(clearTimeout(this._runtimeCloudSaveTimer),this._runtimeCloudSaveTimer=null),this.clearBillingCountdownTimer(),null==(a=this._iframeBridge)||a.dispose(),this._iframeBridge=void 0,this.removeEventListener("runtime-cloud-save-request",this.handleRuntimeCloudSaveRequest),await(null==(r=this._runtimeController)?void 0:r.unmountAll()),this._shellContext&&(N(this._shellContext),this._shellContext=void 0),this._mounted=!1}refreshLayout(){}async importTemplate(t){try{const e=await this.requireTemplateController().importTemplate(t);this._state.activePanelFilter=e.panelFilter;const n=this.requireRefs();if(this._runtimeController&&!et(this._config)){const t=n.panelHost;if(!t)throw new Error("[generator-workbench] panel host is required for template import");await this._runtimeController.remountPanel(t,e.panelFilter)}p(this,"template-imported",e)}catch(e){this.handleError("template",e)}}async exportTemplate(){return this.exportTemplateWithFields()}async exportTemplateWithFields(t){try{this._state.busy.exportTemplate=!0,this._shellContext&&(this._shellContext.state.templateExportLoading=!0);p(this,"template-exported",await this.requireTemplateController().exportTemplate(t)),t&&this.closeTemplateExportDialog()}catch(e){this.handleError("template",e)}finally{this._state.busy.exportTemplate=!1,this._shellContext&&(this._shellContext.state.templateExportLoading=!1)}}async exportSvg(){try{p(this,"svg-export",await this.requireExportController().exportSvg())}catch(t){this.handleError("export",t)}}async openInStudio(){try{p(this,"studio-open",await this.requireExportController().openInStudio())}catch(t){this.handleError("export",t)}}async setAuthToken(t){var e,n;const o=t.trim();if(!o)throw new Error("[generator-workbench] token is required");if(!this._sdk)throw new Error("[generator-workbench] sdk is required before setAuthToken()");const i=null==(n=(e=this._sdk).getAppKey)?void 0:n.call(e);if(!i)throw new Error("[generator-workbench] sdk.getAppKey() is required for setAuthToken()");if("function"!=typeof this._sdk.auth.syncToken)throw new Error("[generator-workbench] sdk.auth.syncToken() is required for setAuthToken()");try{localStorage.setItem(`__atomm_sdk_token__${i}`,o)}catch{}await this._sdk.auth.syncToken(o)}async saveToCloud(){await this.performCloudSave()}async loadHistory(t){try{this._state.busy.historyLoad=!0,this._shellContext&&(this._shellContext.state.historyLoading=!0),p(this,"history-load-start",{options:t});const e=await this.requireHistoryController().loadList(t);this._state.historyItems=e.items,this._state.historyError=null,this.syncHistoryUI(),p(this,"history-loaded",{result:e})}catch(e){this._state.historyError=e instanceof Error?e.message:String(e),this.syncHistoryUI(),this.handleError("runtime",e)}finally{this._state.busy.historyLoad=!1,this._shellContext&&(this._shellContext.state.historyLoading=!1)}}async restoreHistoryItem(t){try{this._state.busy.historyRestore=!0,this._shellContext&&(this._shellContext.state.historyRestoreLoading=!0),p(this,"history-restore-start",{itemId:t});const e=await this.requireHistoryController().restoreItem(t);this._state.cloudRecordId=e.id,this._state.historyError=null,this.syncHistoryUI(),p(this,"history-restored",{itemId:t,record:e})}catch(e){this._state.historyError=e instanceof Error?e.message:String(e),this.syncHistoryUI(),this.handleError("runtime",e)}finally{this._state.busy.historyRestore=!1,this._shellContext&&(this._shellContext.state.historyRestoreLoading=!1)}}async deleteHistoryItem(t){try{this._state.busy.historyDelete=!0,this._shellContext&&(this._shellContext.state.historyDeleteLoading=!0),p(this,"history-delete-start",{itemId:t});const e=await this.requireHistoryController().deleteItem(t);this._state.historyItems=this._state.historyItems.filter(e=>e.id!==t),this._state.historyError=null,this.syncHistoryUI(),p(this,"history-deleted",e)}catch(e){this._state.historyError=e instanceof Error?e.message:String(e),this.syncHistoryUI(),this.handleError("runtime",e)}finally{this._state.busy.historyDelete=!1,this._shellContext&&(this._shellContext.state.historyDeleteLoading=!1)}}async render(){this.shadowRoot&&(this._shellContext&&(N(this._shellContext),this.shadowRoot.innerHTML=""),this._shellContext=await $(this.shadowRoot,this.getEffectiveConfig()),this.syncAuthUI(),this.syncBillingUI(),this.syncInvitationConfigKey(),this.syncHistoryUI())}bindControllers(){var t;const e=this.getEffectiveSdk(),n=this.getEffectiveConfig();e&&this._runtime&&(this._authController=function(t){const{sdk:e}=t;return{getStatus:()=>e.auth.getStatus(),subscribe:t=>(t(e.auth.getStatus()),e.auth.onChange(t)),async login(){await e.auth.login()},async logout(){await e.auth.logout()}}}({sdk:e}),this._templateController=u({sdk:e,runtime:this._runtime,config:n}),this._exportController=function(t){const{sdk:e,runtime:n,config:o,element:i,requestCreditsPurchase:a}=t;async function r(){if(!e.auth.getStatus().isLogin&&(await e.auth.login(),!e.auth.getStatus().isLogin))throw new Error("[generator-workbench] login is required before export")}async function l(){var t,n;return(null==(t=e.billing)?void 0:t.getUsage)?s(await e.billing.getUsage(),null==(n=e.getAppKey)?void 0:n.call(e)):null}async function d(t){if(!(null==t?void 0:t.isEnabled)||t.inFreePeriod||t.freeRemaining>0)return t;if(t.creditsPerUse<=t.creditsBalance)return t;if(!a)throw new Error("[generator-workbench] credits purchase is not available");if(!(await a({zIndex:2e3,trace:{source:"generator-workbench"}})).done)return null;const e=await l();if(!(null==e?void 0:e.isEnabled))return e;if(e.inFreePeriod||e.freeRemaining>0)return e;if(e.creditsPerUse<=e.creditsBalance)return e;throw new Error("[generator-workbench] credits balance is still insufficient after purchase")}async function c(t){var n,o,i;(null==t?void 0:t.isEnabled)&&!t.inFreePeriod&&(null==(n=e.billing)?void 0:n.consume)&&(await e.billing.consume(),t.freeRemaining<=0&&await(null==(i=(o=e.billing).refreshCredits)?void 0:i.call(o)))}return{async exportSvg(){var t;await(null==(t=o.beforeExportSvg)?void 0:t.call(o,{sdk:e,runtime:n,element:i})),await r();const a=await l(),s=await d(a);if(!a)return e.export.download({format:"svg"});if(!s)return{success:!1,fileName:""};const u=await e.export.download({format:"svg"});return await c(s),u},async openInStudio(){var t;await(null==(t=o.beforeOpenInStudio)?void 0:t.call(o,{sdk:e,runtime:n,element:i})),await r();const a=await l(),s=await d(a);if(!a)return e.export.openInStudio({format:"svg"});if(!s)return{success:!1};const u=await e.export.openInStudio({format:"svg"});return await c(s),u}}}({sdk:e,runtime:this._runtime,config:n,element:this,requestCreditsPurchase:!1===n.creditsEnabled||null==(t=this._shellContext)?void 0:t.requestCreditsPurchase}),this._cloudController=e.cloud?function(t){const{sdk:e,runtime:n,config:o,element:i}=t;function a(){if(!e.cloud)throw new Error("[generator-workbench] sdk.cloud is required for cloud actions");return e.cloud}function r(){return{sdk:e,runtime:n,element:i,state:n.getState()}}async function s(){var t,n,o,i;if(!(null==(n=(t=e.auth).getToken)?void 0:n.call(t).trim())&&(await e.auth.login(),!(null==(i=(o=e.auth).getToken)?void 0:i.call(o).trim())))throw new Error("[generator-workbench] sdk.auth.getToken() is required after login")}async function l(t){var e,n;await s();const i=a(),l={...r(),state:t.snapshot};await(null==(e=o.onBeforeCloudSave)?void 0:e.call(o,l));const d=await i.save(t);return await(null==(n=o.onAfterCloudSave)?void 0:n.call(o,d,l)),d}async function d(){var t;const e=r();return l((null==(t=o.getCloudSaveOptions)?void 0:t.call(o,e))??{title:o.title||"Draft",snapshot:e.state})}return{save:d,saveWithOptions:l,restore:async function(t){await s();const e=a(),o=await e.restore(t);return await n.setState(o.snapshot,{source:"cloud-history"}),o},scheduleAutoSave:function(t){const e=o.autoSaveDebounceMs??1500;let n=null;return{trigger(){n&&clearTimeout(n),n=setTimeout(()=>{n=null,d().then(e=>{null==t||t(e)})},e)},dispose(){n&&(clearTimeout(n),n=null)}}}}}({sdk:e,runtime:this._runtime,config:n,element:this}):void 0,this._historyController=e.history?function(t){const{sdk:e,runtime:n,config:o,element:i}=t;function a(){if(!e.history)throw new Error("[generator-workbench] sdk.history is required for history actions");return e.history}function r(t){return{sdk:e,runtime:n,element:i,itemId:t}}return{loadList:async t=>a().getList(t),async restoreItem(t){var e,i;const s=r(t),l=a();await(null==(e=o.onBeforeHistoryRestore)?void 0:e.call(o,s));const d=await l.getDetail(t);return await n.setState(d.snapshot,{source:"cloud-history"}),await(null==(i=o.onAfterHistoryRestore)?void 0:i.call(o,d,s)),d},async deleteItem(t){var e,n;const i=r(t),s=a();return await(null==(e=o.onBeforeHistoryDelete)?void 0:e.call(o,i)),await s.delete(t),await(null==(n=o.onAfterHistoryDelete)?void 0:n.call(o,i)),{itemId:t}}}}({sdk:e,runtime:this._runtime,config:n,element:this}):void 0,this._runtimeController=function(t){const{runtime:e}=t;let n=null,o=null;async function i(t,n){null==o||o.unmount(),o=await Promise.resolve(e.mount({mode:"embed",target:"panel",container:t,panelFilter:n}))}return{mountWorkspace:async function(t){null==n||n.unmount(),null==o||o.unmount(),n=await Promise.resolve(e.mount({mode:"full",target:"full",container:t})),o=null},mountCanvas:async function(t){null==n||n.unmount(),n=await Promise.resolve(e.mount({mode:"embed",target:"canvas",container:t}))},mountPanel:i,async remountPanel(t,e){await i(t,e)},async unmountAll(){null==n||n.unmount(),null==o||o.unmount(),n=null,o=null}}}({runtime:this._runtime}))}bindShellCallbacks(){if(!this._shellContext)return;const{callbacks:t}=this._shellContext;t.onLogin=()=>{this.handleLogin()},t.onOpenInvitation=()=>{this.handleInvitationEntry()},t.onLogout=()=>{this.handleLogout()},t.onImportTemplate=()=>{this.requireRefs().templateFileInput.click()},t.onExportTemplate=()=>{this.openTemplateExportDialog()},t.onCloseTemplateDialog=()=>{this.closeTemplateExportDialog()},t.onToggleTemplateDialog=t=>{t||this.closeTemplateExportDialog()},t.onToggleTemplateField=(t,e)=>{this.toggleTemplateExportField(t,e)},t.onConfirmTemplateExport=()=>{var t;this.exportTemplateWithFields((null==(t=this._shellContext)?void 0:t.state.templateSelectedFieldPaths)||[])},t.onExportSvg=()=>{this.exportSvg()},t.onOpenInStudio=()=>{this.openInStudio()},t.onSaveCloud=()=>{this.saveToCloud()},t.onOpenHistory=()=>{this.openHistoryDialog()},t.onCloseHistory=()=>{this.closeHistoryDialog()},t.onRestoreHistory=t=>{this.restoreHistoryItem(t)},t.onDeleteHistory=t=>{this.deleteHistoryItem(t)},t.onFileChange=t=>{var e;const n=t.target,o=null==(e=n.files)?void 0:e[0];o&&(this.importTemplate(o),n.value="")}}openTemplateExportDialog(){try{if(!this._shellContext)return;const t=this.requireTemplateController().prepareTemplateExport();this._shellContext.state.templateFieldGroups=t.fieldGroups.map(t=>({...t,fields:t.fields.map(t=>({...t}))})),this._shellContext.state.templateSelectedFieldPaths=[...t.selectedFieldPaths],this._shellContext.state.templateDialogOpen=!0}catch(t){this.handleError("template",t)}}closeTemplateExportDialog(){this._shellContext&&(this._shellContext.state.templateDialogOpen=!1,this._shellContext.state.templateFieldGroups=[],this._shellContext.state.templateSelectedFieldPaths=[])}async openHistoryDialog(){this._shellContext&&(this._state.historyDrawerOpen=!0,this._shellContext.state.historyDialogOpen=!0),await this.loadHistory()}closeHistoryDialog(){this._state.historyDrawerOpen=!1,this._shellContext&&(this._shellContext.state.historyDialogOpen=!1)}toggleTemplateExportField(t,e){if(!this._shellContext)return;const n=new Set(this._shellContext.state.templateSelectedFieldPaths);e?n.add(t):n.delete(t),this._shellContext.state.templateSelectedFieldPaths=Array.from(n)}async applyTemplatePayload(t){if(!this._runtime)throw new Error("[generator-workbench] runtime is required for template bridge actions");if(!this._sdk)throw new Error("[generator-workbench] sdk is required for template bridge actions");let e;if(await this._sdk.template.applyToRuntime(this._runtime,t,{onPanelFilter:t=>{e=t}}),e&&(this._state.activePanelFilter=e,this._runtimeController&&!et(this._config))){const t=this.requireRefs().panelHost;if(!t)throw new Error("[generator-workbench] panel host is required for template bridge actions");await this._runtimeController.remountPanel(t,e)}return{template:t,panelFilter:e}}async tryResolveIframeBridgeFile(t,e,n){try{if(!this._runtime)return;return await W({action:t,sdk:e,runtime:this._runtime,config:n,element:this})}catch{return}}bindAuthState(){var t;const e=this.requireAuthController();null==(t=this._cleanupAuth)||t.call(this),this._cleanupAuth=e.subscribe(t=>{this._state.authStatus=t,this.syncAuthUI(),this.syncBillingState(t),p(this,"auth-change",t)}),this.bindBillingSubscriptions()}bindIframeBridge(){var t,e,n;if(null==(t=this._iframeBridge)||t.dispose(),this._iframeBridge=void 0,"embed"!==nt()||!this._runtime)return;const o=this._sdk;if(!o)return;const i=this._config,a=this._runtime;this._iframeBridge=G({targetOrigin:(null==(e=i.embedBridge)?void 0:e.targetOrigin)||"*",validateOrigin:null==(n=i.embedBridge)?void 0:n.validateOrigin,handlers:{getGeneratorData:async()=>{const t=a.getState(),e=await V({sdk:o,runtime:a,config:i,element:this}),n=await this.tryResolveIframeBridgeFile("cover",o,i);return{info:t,cover:(null==n?void 0:n.base64)||"",originImageUrl:e}},setGeneratorData:async t=>{const e=t.info&&"object"==typeof t.info&&!Array.isArray(t.info)?t.info:t;await a.setState(e,{source:"iframe-bridge",originImageUrl:"string"==typeof t.originImageUrl?t.originImageUrl:""})},loadTemplateData:async t=>{const e=t.template&&"object"==typeof t.template&&!Array.isArray(t.template)?t.template:t;if(!e||"object"!=typeof e||Array.isArray(e))throw new Error("Template payload is empty");return{template:(await this.applyTemplatePayload(e)).template}},getTemplateData:async()=>{const t=this.requireTemplateController().buildTemplate(),e=a.getState(),n=await V({sdk:o,runtime:a,config:i,element:this}),r=await this.tryResolveIframeBridgeFile("cover",o,i);return{template:t,info:e,cover:(null==r?void 0:r.base64)||"",originImageUrl:n}},getFile:async t=>W({action:t,sdk:o,runtime:a,config:i,element:this})}})}bindAutoSave(){var t,e,n;const o=this.getEffectiveSdk(),i=this.getEffectiveConfig();null==(t=this._cleanupRuntimeSubscription)||t.call(this),this._cleanupRuntimeSubscription=void 0,null==(e=this._cloudAutoSaveScheduler)||e.dispose(),this._cloudAutoSaveScheduler=void 0,i.autoSaveEnabled&&(null==(n=this._runtime)?void 0:n.subscribe)&&(null==o?void 0:o.cloud)&&(this._cloudAutoSaveScheduler=this.requireCloudController().scheduleAutoSave(t=>{this._state.cloudRecordId=t.id,this._state.lastSavedAt=Date.now(),this._state.saveError=null}),this._cleanupRuntimeSubscription=this._runtime.subscribe(()=>{var t;null==(t=this._cloudAutoSaveScheduler)||t.trigger()}))}bindRuntimeCloudSaveEvent(){const t=this.getEffectiveSdk(),e=this.getEffectiveConfig();this.removeEventListener("runtime-cloud-save-request",this.handleRuntimeCloudSaveRequest),e.cloudEnabled&&(null==t?void 0:t.cloud)&&this.addEventListener("runtime-cloud-save-request",this.handleRuntimeCloudSaveRequest)}async initializeCloudRecordFromRoute(){const t=this.getEffectiveSdk();if(!this.getEffectiveConfig().cloudEnabled||!(null==t?void 0:t.cloud))return;const e=this.getRouteCloudRecordId();if(e){try{const t=await this.requireCloudController().restore(e);this._state.cloudRecordId=t.id,this._state.lastSavedAt=t.updatedAt,this._state.saveError=null}catch(o){this._state.saveError=o instanceof Error?o.message:String(o),this.handleError("runtime",o)}return}const n=await this.performCloudSave(void 0,{emitEvents:!1});n&&this.setRouteCloudRecordId(n.id)}async performCloudSave(t,e={}){var n;const{emitEvents:o=!0}=e;try{this._state.busy.cloudSave=!0,this._shellContext&&(this._shellContext.state.cloudSaveLoading=!0);const e=(null==t?void 0:t.snapshot)??(null==(n=this._runtime)?void 0:n.getState())??{};o&&p(this,"cloud-save-start",{state:e});const i=t?await this.requireCloudController().saveWithOptions(t):await this.requireCloudController().save();return this._state.cloudRecordId=i.id,this._state.lastSavedAt=Date.now(),this._state.saveError=null,o&&p(this,"cloud-saved",{result:i}),i}catch(i){return this._state.saveError=i instanceof Error?i.message:String(i),void this.handleError("runtime",i)}finally{this._state.busy.cloudSave=!1,this._shellContext&&(this._shellContext.state.cloudSaveLoading=!1)}}getRouteCloudRecordId(){const t=new URLSearchParams(window.location.search).get("gid"),e=Number(t);return Number.isInteger(e)&&e>0?e:null}setRouteCloudRecordId(t){const e=new URL(window.location.href);e.searchParams.set("gid",String(t)),window.history.replaceState(window.history.state,"",`${e.pathname}${e.search}${e.hash}`)}bindBillingSubscriptions(){var t,e;const n=this.getEffectiveSdk();null==(t=this._cleanupCredits)||t.call(this),this._cleanupCredits=void 0,null==(e=this._cleanupBilling)||e.call(this),this._cleanupBilling=void 0;const o=null==n?void 0:n.credits;"function"==typeof(null==o?void 0:o.onChange)&&(this._cleanupCredits=o.onChange(t=>{this._state.creditsBalance=Number(t)||0,this.syncBillingUI()}));const i=null==n?void 0:n.billing;"function"==typeof(null==i?void 0:i.onChange)&&(this._cleanupBilling=i.onChange(t=>{this.applyBillingUsage(t)}))}syncAuthUI(){var t,e,n,o,i,a,r,s;if(!this._shellContext)return;const{state:l}=this._shellContext,{isLogin:d,userInfo:c}=this._state.authStatus,u=(null==(t=null==c?void 0:c.userName)?void 0:t.trim())||(null==(e=null==c?void 0:c.email)?void 0:e.trim())||(null==(n=null==c?void 0:c.phoneNumber)?void 0:n.trim())||"",p=u?u.charAt(0).toUpperCase():"U",h=(null==(o=null==c?void 0:c.email)?void 0:o.trim())||((null==c?void 0:c.phoneNumber)?`${c.phoneZone||""}${c.phoneNumber}`:"Connected to Generator SDK"),m="function"==typeof(null==(a=null==(i=this._sdk)?void 0:i.auth)?void 0:a.getToken)?this._sdk.auth.getToken():"",g=u||"Generator User",v=(null==(r=null==c?void 0:c.email)?void 0:r.trim())||(null==(s=null==c?void 0:c.phoneNumber)?void 0:s.trim())||g.toLowerCase().replace(/\s+/g,"-");l.isLogin=d,l.avatarSrc=d&&(null==c?void 0:c.headpic)||"",l.avatarText=p,l.authDisplayName=u,l.authSubline=d?h:"",l.authToken=d?m:"",l.atommProUser=d?{id:null==c?void 0:c.uid,userName:g,userHandle:v,avatar:(null==c?void 0:c.headpic)||""}:{userName:"",userHandle:"",avatar:""}}syncBillingUI(){if(!this._shellContext)return;const{state:t}=this._shellContext,e=this._state.billingUsage;t.creditsEnabled=!1!==this.getEffectiveConfig().creditsEnabled,t.creditsBalance=this._state.creditsBalance,t.showExportCreditsHint=Boolean(this._state.authStatus.isLogin&&(null==e?void 0:e.isEnabled)),t.showExportCreditsIcon=Boolean(t.showExportCreditsHint&&!(null==e?void 0:e.inFreePeriod)&&((null==e?void 0:e.freeRemaining)??0)<=0),t.exportCreditsHintText=this.resolveExportCreditsHintText(e)}syncInvitationConfigKey(){var t,e,n,o;if(!this._shellContext)return;const i=null==(t=this._config.invitationConfigKey)?void 0:t.trim(),a=null==(o=null==(n=null==(e=this._sdk)?void 0:e.getAppKey)?void 0:n.call(e))?void 0:o.trim(),r=a?`generator_${a}`:"";this._shellContext.state.invitationConfigKey=i||r||"default"}syncHistoryUI(){if(!this._shellContext)return;const{state:t}=this._shellContext;t.historyDialogOpen=this._state.historyDrawerOpen,t.historyItems=this._state.historyItems.map(t=>({...t})),t.historyError=this._state.historyError||""}applyBillingUsage(t){const e=this.applyPersistedBillingUsage(t);this._state.billingUsage=e,e&&"number"==typeof e.creditsBalance&&(this._state.creditsBalance=e.creditsBalance),this.persistBillingCountdown(e),this.syncBillingUI(),this.syncBillingCountdown()}resetBillingState(){this.clearBillingCountdownTimer(),function(t){const e=i(t);if(e)try{localStorage.removeItem(e)}catch{}}(this.getSdkAppKey()),this._state.creditsBalance=0,this._state.billingUsage=null,this.syncBillingUI()}getSdkAppKey(){var t,e,n;return(null==(n=null==(e=null==(t=this._sdk)?void 0:t.getAppKey)?void 0:e.call(t))?void 0:n.trim())||null}applyPersistedBillingUsage(t){return s(t,this.getSdkAppKey())}persistBillingCountdown(t){!function(t,e,n=Date.now()){const o=i(t);if(o)try{if(e>0)return void localStorage.setItem(o,String(n+1e3*e));localStorage.removeItem(o)}catch{}}(this.getSdkAppKey(),(null==t?void 0:t.inFreePeriod)?t.freePeriodRemaining:0)}resolveExportCreditsHintText(t){return this._state.authStatus.isLogin&&(null==t?void 0:t.isEnabled)?t.inFreePeriod?`${t.freePeriodRemaining}s`:t.freeRemaining>0?`${t.freeRemaining}/${t.freeTotal}`:String(t.creditsPerUse):""}clearBillingCountdownTimer(){this._billingCountdownTimer&&(clearInterval(this._billingCountdownTimer),this._billingCountdownTimer=null)}syncBillingCountdown(){var t;this.clearBillingCountdownTimer(),this._state.authStatus.isLogin&&(null==(t=this._state.billingUsage)?void 0:t.inFreePeriod)&&(this._billingCountdownTimer=setInterval(()=>{var t,e,n,o;const i=this.getSdkAppKey(),s=r(i),l=a(i),d=null==(n=null==(e=null==(t=this._sdk)?void 0:t.billing)?void 0:e.getCachedUsage)?void 0:n.call(e);l&&(null==(o=this._state.billingUsage)?void 0:o.isEnabled)?this._state.billingUsage={...this._state.billingUsage,inFreePeriod:!0,freePeriodRemaining:s}:d&&(this._state.billingUsage=this.applyPersistedBillingUsage(d)),this._state.billingUsage&&"number"==typeof this._state.billingUsage.creditsBalance&&(this._state.creditsBalance=this._state.billingUsage.creditsBalance),this.syncBillingUI(),l&&s>0||d&&d.inFreePeriod||this.clearBillingCountdownTimer()},1e3))}async syncBillingState(t=this._state.authStatus){var e,n,o,i,a,r,s,l;const d=this.getEffectiveSdk();if(!t.isLogin||!d)return void this.resetBillingState();if(!d.credits&&!d.billing)return void this.resetBillingState();const c=null==(n=null==(e=d.credits)?void 0:e.getCachedBalance)?void 0:n.call(e);"number"==typeof c&&(this._state.creditsBalance=c);const u=null==(i=null==(o=d.billing)?void 0:o.getCachedUsage)?void 0:i.call(o);u?this.applyBillingUsage(u):this.syncBillingUI();try{const[t,e]=await Promise.all([null==(r=null==(a=d.credits)?void 0:a.getBalance)?void 0:r.call(a),null==(l=null==(s=d.billing)?void 0:s.getUsage)?void 0:l.call(s)]);if("number"==typeof(null==t?void 0:t.quota)&&(this._state.creditsBalance=t.quota),e)return void this.applyBillingUsage(e);this.syncBillingUI()}catch(p){this.handleError("auth",p)}}getEffectiveConfig(){return"embed"!==nt()?this._config:{...this._config,invitationEnabled:!1,cloudEnabled:!1,historyEnabled:!1,autoSaveEnabled:!1,creditsEnabled:!1}}getEffectiveSdk(){return this._sdk?"embed"!==nt()?this._sdk:{...this._sdk,credits:void 0,billing:void 0,cloud:void 0,history:void 0}:null}async handleLogin(){try{this._state.busy.login=!0,this._shellContext&&(this._shellContext.state.loginLoading=!0),await this.requireAuthController().login()}catch(t){this.handleError("auth",t)}finally{this._state.busy.login=!1,this._shellContext&&(this._shellContext.state.loginLoading=!1)}}async handleInvitationEntry(){var t;try{if(!this._state.authStatus.isLogin){await this.handleLogin();const t=this.requireAuthController().getStatus();t.isLogin&&(this._state.authStatus=t,this.syncAuthUI(),this.syncBillingState(t))}if(!this.requireAuthController().getStatus().isLogin)return;null==(t=this._shellContext)||t.openInvitationModal()}catch(e){this.handleError("auth",e)}}async handleLogout(){try{await this.requireAuthController().logout()}catch(t){this.handleError("auth",t)}}handleError(t,e){var n,o;const i=e instanceof Error?e:new Error(String(e));null==(o=(n=this._config).onError)||o.call(n,i,t),p(this,"workbench-error",{source:t,error:i})}requireRefs(){if(!this._shellContext)throw new Error("[generator-workbench] shell context is not ready");return this._shellContext.refs}requireAuthController(){if(!this._authController)throw new Error("[generator-workbench] auth controller is not ready");return this._authController}requireTemplateController(){if(!this._templateController)throw new Error("[generator-workbench] template controller is not ready");return this._templateController}requireExportController(){if(!this._exportController)throw new Error("[generator-workbench] export controller is not ready");return this._exportController}requireCloudController(){if(!this._cloudController)throw new Error("[generator-workbench] cloud controller is not ready");return this._cloudController}requireHistoryController(){if(!this._historyController)throw new Error("[generator-workbench] history controller is not ready");return this._historyController}}const it="generator-workbench";t.GENERATOR_WORKBENCH_TAG_NAME=it,t.GeneratorWorkbenchElement=ot,t.defineGeneratorWorkbench=function(t=it){const e=customElements.get(t);return e||(customElements.define(t,ot),ot)},Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})});
1
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).GeneratorWorkbench={})}(this,function(t){"use strict";var e=Object.defineProperty,n=(t,n,o)=>((t,n,o)=>n in t?e(t,n,{enumerable:!0,configurable:!0,writable:!0,value:o}):t[n]=o)(t,"symbol"!=typeof n?n+"":n,o),o="undefined"!=typeof document?document.currentScript:null;function a(t){const e=null==t?void 0:t.trim();return e?`__atomm_sdk_billing_free_period__${e}`:null}function i(t,e=Date.now()){const n=a(t);if(!n)return null;try{const t=localStorage.getItem(n);if(!t)return null;const o=Number(t);return!Number.isFinite(o)||o<=e?(localStorage.removeItem(n),null):o}catch{return null}}function r(t,e=Date.now()){const n=i(t,e);return n?Math.max(0,Math.ceil((n-e)/1e3)):0}function s(t,e,n=Date.now()){if(!(null==t?void 0:t.isEnabled))return t||null;const o=r(e,n);return o<=0||t.inFreePeriod&&t.freePeriodRemaining>=o?t:{...t,inFreePeriod:!0,freePeriodRemaining:o}}function l(t,e){if(!t)throw new Error(e)}function d(t,e){const n=(null==e?void 0:e.length)?new Set(e):null;return t.groups.map(t=>{var e;const o=t.fields.map(t=>{var e,o,a;const i=null==(o=null==(e=t.bind)?void 0:e.path)?void 0:o.trim();return i?n&&!n.has(i)?null:{id:t.id,label:(null==(a=t.label)?void 0:a.trim())||t.id||i,path:i}:null}).filter(t=>Boolean(t));return{id:t.id,title:(null==(e=t.title)?void 0:e.trim())||t.id,fields:o}}).filter(t=>t.fields.length>0)}function c(t,e){var n;if(null==(n=t.generatorId)?void 0:n.trim())return t.generatorId.trim();const o=e.meta;if(o&&"object"==typeof o&&"generatorId"in o&&"string"==typeof o.generatorId&&o.generatorId.trim())return o.generatorId.trim();throw new Error("[generator-workbench] generatorId is required in panelSchema.generatorId or state.meta.generatorId")}function u(t){const{sdk:e,runtime:n,config:o}=t;function a(){var t;const e=n.getState(),a=n.getPanelSchema(),i=d(a,null==(t=o.getTemplateFieldPaths)?void 0:t.call(o,a)),r=i.flatMap(t=>t.fields.map(t=>t.path));return l(r.length>0,"[generator-workbench] exportTemplate requires at least one panel field path"),{generatorId:c(a,e),state:e,panelSchema:a,fieldGroups:i,selectedFieldPaths:r}}return{async importTemplate(t){const o=await t.text(),a=e.template.parse(o);let i;return await e.template.applyToRuntime(n,a,{onPanelFilter(t){i=t}}),{template:a,panelFilter:i}},prepareTemplateExport:a,buildTemplate(t){var n;const i=a(),r=(null==t?void 0:t.length)?d(i.panelSchema,t).flatMap(t=>t.fields.map(t=>t.path)):i.selectedFieldPaths;l(r.length>0,"[generator-workbench] exportTemplate requires at least one panel field path");return e.template.build({generatorId:i.generatorId,state:i.state,panelSchema:i.panelSchema,selectedFieldPaths:r,templateMeta:null==(n=o.getTemplateMeta)?void 0:n.call(o)})},async exportTemplate(t){const n=this.buildTemplate(t);return e.template.download(n),{template:n}}}}function p(t,e,n){return t.dispatchEvent(new CustomEvent(e,{detail:n,bubbles:!0,composed:!0}))}function h(t,e){const n=t.querySelector(e);if(!n)throw new Error(`[generator-workbench] required DOM node not found: ${e}`);return n}const m="data:image/svg+xml,%3csvg%20width='24'%20height='24'%20viewBox='0%200%2024%2024'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3ccircle%20cx='12'%20cy='12'%20r='9'%20fill='url(%23paint0_linear_503_69253)'/%3e%3cg%20filter='url(%23filter0_d_503_69253)'%3e%3crect%20x='7.75781'%20y='12'%20width='6'%20height='6'%20rx='1'%20transform='rotate(-45%207.75781%2012)'%20fill='url(%23paint1_linear_503_69253)'/%3e%3c/g%3e%3cdefs%3e%3cfilter%20id='filter0_d_503_69253'%20x='2.17188'%20y='4.17188'%20width='19.6572'%20height='19.6562'%20filterUnits='userSpaceOnUse'%20color-interpolation-filters='sRGB'%3e%3cfeFlood%20flood-opacity='0'%20result='BackgroundImageFix'/%3e%3cfeColorMatrix%20in='SourceAlpha'%20type='matrix'%20values='0%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%20127%200'%20result='hardAlpha'/%3e%3cfeOffset%20dy='2'/%3e%3cfeGaussianBlur%20stdDeviation='3'/%3e%3cfeComposite%20in2='hardAlpha'%20operator='out'/%3e%3cfeColorMatrix%20type='matrix'%20values='0%200%200%200%201%200%200%200%200%200.206957%200%200%200%200%200.0670085%200%200%200%201%200'/%3e%3cfeBlend%20mode='normal'%20in2='BackgroundImageFix'%20result='effect1_dropShadow_503_69253'/%3e%3cfeBlend%20mode='normal'%20in='SourceGraphic'%20in2='effect1_dropShadow_503_69253'%20result='shape'/%3e%3c/filter%3e%3clinearGradient%20id='paint0_linear_503_69253'%20x1='12'%20y1='3'%20x2='12'%20y2='21'%20gradientUnits='userSpaceOnUse'%3e%3cstop%20stop-color='%23FFA346'/%3e%3cstop%20offset='1'%20stop-color='%23FF7C23'/%3e%3c/linearGradient%3e%3clinearGradient%20id='paint1_linear_503_69253'%20x1='13.2327'%20y1='12.5252'%20x2='8.63652'%20y2='18.5356'%20gradientUnits='userSpaceOnUse'%3e%3cstop%20stop-color='white'/%3e%3cstop%20offset='1'%20stop-color='%23FFD3B5'/%3e%3c/linearGradient%3e%3c/defs%3e%3c/svg%3e",g="data:image/svg+xml,%3Csvg%20viewBox%3D'0%200%201088%201024'%20xmlns%3D'http%3A//www.w3.org/2000/svg'%3E%3Cpath%20d%3D'M416%20128v85.312h-128A42.688%2042.688%200%200%200%20245.312%20256v512c0%2023.552%2019.136%2042.688%2042.688%2042.688h512a42.688%2042.688%200%200%200%2042.688-42.688V597.312H928V768a128%20128%200%200%201-128%20128h-512a128%20128%200%200%201-128-128V256a128%20128%200%200%201%20128-128h128z'%20fill%3D'%23ffffff'/%3E%3Cpath%20d%3D'M723.52%20520.832L924.352%20320l-200.832-200.832-60.352%2060.352%2097.856%2097.792h-67.712A298.688%20298.688%200%200%200%20394.688%20576v85.312H480V576a213.312%20213.312%200%200%201%20213.312-213.312h67.712l-97.856%2097.792%2060.352%2060.352z'%20fill%3D'%23ffffff'/%3E%3C/svg%3E",v=`\n <div class="shell">\n <header v-show="state.showTopbar" class="topbar app-topbar">\n <div class="logo-area app-topbar-main" data-role="logo-area">\n <img\n :src="state.logoSrc"\n :alt="state.logoText || 'Atomm'"\n class="brand-logo"\n data-role="brand-logo"\n draggable="false"\n />\n <div class="app-topbar-nav">\n <xt-button\n v-show="state.templateEnabled"\n type="secondary"\n size="small"\n data-role="import-template"\n @click="callbacks.onImportTemplate()"\n >导入模板</xt-button>\n <xt-button\n v-show="state.templateEnabled"\n type="secondary"\n size="small"\n data-role="export-template"\n @click="callbacks.onExportTemplate()"\n >生成模板</xt-button>\n <div class="workbench-host-actions">\n <xt-button\n v-show="state.cloudEnabled"\n type="secondary"\n size="small"\n data-role="save-cloud"\n :loading="state.cloudSaveLoading"\n @click="callbacks.onSaveCloud()"\n >保存草稿</xt-button>\n <xt-button\n v-show="state.historyEnabled"\n type="secondary"\n size="small"\n data-role="open-history"\n :loading="state.historyLoading"\n @click="callbacks.onOpenHistory()"\n >历史记录</xt-button>\n </div>\n </div>\n </div>\n <div class="app-topbar-auth">\n <button\n v-if="state.invitationEnabled"\n type="button"\n class="invite-entry"\n data-role="open-invitation"\n @click="callbacks.onOpenInvitation()"\n >\n <img\n src="https://storage-us.atomm.com/resource/static/atomm/icon/Vector.svg"\n alt=""\n class="invite-entry-icon"\n draggable="false"\n />\n <span class="invite-entry-text">{{ state.invitationButtonText }}</span>\n </button>\n <div\n v-if="state.isLogin && state.creditsEnabled"\n class="topbar-credits-badge"\n data-role="topbar-credits"\n title="Remaining credits"\n >\n <img src="${m}" alt="" class="credits-token-icon" draggable="false" />\n <span class="topbar-credits-value" data-role="topbar-credits-value">{{ state.creditsBalance }}</span>\n </div>\n\n <div\n v-if="state.isLogin && state.avatarMenuTrigger === 'hover'"\n class="auth-hover-card"\n >\n <div class="auth-avatar-trigger" data-role="avatar-button" tabindex="0">\n <div class="auth-avatar">\n <img\n v-if="state.avatarSrc"\n :src="state.avatarSrc"\n alt="Avatar"\n data-role="avatar-image"\n />\n <span v-else data-role="avatar-image">{{ state.avatarText }}</span>\n </div>\n </div>\n <div class="auth-hover-panel">\n <div class="auth-popover-body" data-role="avatar-menu">\n <div class="auth-popover-header">\n <div class="auth-avatar auth-avatar--lg">\n <img v-if="state.avatarSrc" :src="state.avatarSrc" alt="Avatar" />\n <span v-else>{{ state.avatarText }}</span>\n </div>\n <div class="auth-popover-user-text">\n <span class="auth-popover-name">{{ state.authDisplayName }}</span>\n <span class="auth-popover-sub">{{ state.authSubline }}</span>\n </div>\n </div>\n <div class="auth-popover-divider"></div>\n <div class="auth-popover-action" data-role="logout" @click="callbacks.onLogout()">\n Logout\n </div>\n </div>\n </div>\n </div>\n\n <xt-dropdown-menu\n v-else-if="state.isLogin"\n trigger="click"\n :portal-disabled="true"\n placement="bottomRight"\n >\n <template #trigger>\n <div class="auth-avatar-trigger" data-role="avatar-button">\n <div class="auth-avatar">\n <img\n v-if="state.avatarSrc"\n :src="state.avatarSrc"\n alt="Avatar"\n data-role="avatar-image"\n />\n <span v-else data-role="avatar-image">{{ state.avatarText }}</span>\n </div>\n </div>\n </template>\n <template #overlay>\n <div class="auth-popover-body" data-role="avatar-menu">\n <div class="auth-popover-header">\n <div class="auth-avatar auth-avatar--lg">\n <img v-if="state.avatarSrc" :src="state.avatarSrc" alt="Avatar" />\n <span v-else>{{ state.avatarText }}</span>\n </div>\n <div class="auth-popover-user-text">\n <span class="auth-popover-name">{{ state.authDisplayName }}</span>\n <span class="auth-popover-sub">{{ state.authSubline }}</span>\n </div>\n </div>\n <div class="auth-popover-divider"></div>\n <div class="auth-popover-action" data-role="logout" @click="callbacks.onLogout()">\n Logout\n </div>\n </div>\n </template>\n </xt-dropdown-menu>\n\n <button\n type="button"\n class="auth-avatar-button auth-avatar-button--guest"\n data-role="login"\n v-if="!state.isLogin"\n @click="callbacks.onLogin()"\n >\n <div class="auth-avatar auth-avatar--guest">\n <img\n src="https://storage-us.atomm.com/resource/xart/static/agent/imgs/no-login.png"\n alt="Login"\n data-role="guest-avatar-image"\n draggable="false"\n />\n </div>\n </button>\n </div>\n </header>\n\n <div\n class="workspace"\n :class="[\n state.shellMode === 'shell'\n ? 'shell-mode-shell'\n : (state.panelTarget === 'left' ? 'panel-left' : 'panel-right'),\n ]"\n data-role="workspace"\n >\n <main\n v-if="state.shellMode === 'shell'"\n class="workspace-host"\n data-role="workspace-host"\n ></main>\n <template v-else>\n <main class="canvas-host" data-role="canvas-host"></main>\n <aside class="panel-sidebar" data-role="panel-sidebar">\n <div class="panel-host" data-role="panel-host"></div>\n <div\n v-show="state.showSidebarFooter"\n id="sidebar-footer"\n class="sidebar-footer-export panel-actions"\n data-role="panel-actions"\n >\n <xt-dropdown-menu\n trigger="click"\n :portal-disabled="true"\n placement="topLeft"\n domTriggerClass="sidebar-export-trigger-btn-wrap"\n :show-trigger-icon="false"\n domContentClass="sidebar-export-dropdown-menu"\n >\n <template #trigger>\n <xt-button class="sidebar-export-trigger-btn" block data-role="fab-trigger">\n <template #icon>\n <img\n src="${g}"\n alt=""\n width="16"\n height="16"\n draggable="false"\n />\n </template>\n Export\n <template #append-icon>\n <div v-if="state.showExportCreditsHint" class="export-credits-hint">\n <img v-if="state.showExportCreditsIcon" data-role="export-credits-icon" src="${m}" alt="" class="credits-token-icon credits-token-icon--sm" draggable="false" />\n <span class="export-credits-hint-value" data-role="export-credits-value">{{ state.exportCreditsHintText }}</span>\n </div>\n </template>\n </xt-button>\n </template>\n <template #overlay>\n <div class="export-overlay-menu fab-menu-content" data-role="fab-menu">\n <div\n v-show="state.exportEnabled"\n class="export-overlay-item"\n data-role="export-svg"\n @click="callbacks.onExportSvg()"\n >\n <span class="export-overlay-item-icon export-overlay-item-icon--svg"></span>\n Download\n </div>\n <div\n v-show="state.studioEnabled"\n class="export-overlay-item"\n data-role="open-in-studio"\n @click="callbacks.onOpenInStudio()"\n >\n <span class="export-overlay-item-icon export-overlay-item-icon--studio"></span>\n Open in Studio\n </div>\n </div>\n </template>\n </xt-dropdown-menu>\n </div>\n </aside>\n </template>\n </div>\n\n <div\n v-show="state.shellMode === 'shell' && state.showSidebarFooter"\n id="sidebar-footer"\n class="sidebar-footer-export panel-actions sidebar-footer-floating"\n data-role="panel-actions"\n >\n <xt-dropdown-menu\n trigger="click"\n :portal-disabled="true"\n placement="topLeft"\n domTriggerClass="sidebar-export-trigger-btn-wrap"\n :show-trigger-icon="false"\n domContentClass="sidebar-export-dropdown-menu"\n >\n <template #trigger>\n <xt-button class="sidebar-export-trigger-btn" data-role="fab-trigger">\n <template #icon>\n <img\n src="${g}"\n alt=""\n width="16"\n height="16"\n draggable="false"\n />\n </template>\n Export\n <template #append-icon>\n <div v-if="state.showExportCreditsHint" class="export-credits-hint">\n <img v-if="state.showExportCreditsIcon" data-role="export-credits-icon" src="${m}" alt="" class="credits-token-icon credits-token-icon--sm" draggable="false" />\n <span class="export-credits-hint-value" data-role="export-credits-value">{{ state.exportCreditsHintText }}</span>\n </div>\n </template>\n </xt-button>\n </template>\n <template #overlay>\n <div class="export-overlay-menu fab-menu-content" data-role="fab-menu">\n <div\n v-show="state.exportEnabled"\n class="export-overlay-item"\n data-role="export-svg"\n @click="callbacks.onExportSvg()"\n >\n <span class="export-overlay-item-icon export-overlay-item-icon--svg"></span>\n Download\n </div>\n <div\n v-show="state.studioEnabled"\n class="export-overlay-item"\n data-role="open-in-studio"\n @click="callbacks.onOpenInStudio()"\n >\n <span class="export-overlay-item-icon export-overlay-item-icon--studio"></span>\n Open in Studio\n </div>\n </div>\n </template>\n </xt-dropdown-menu>\n </div>\n\n <input\n data-role="template-file-input"\n type="file"\n accept="application/json"\n style="display:none"\n @change="callbacks.onFileChange($event)"\n />\n\n <xt-modal\n :model-value="state.templateDialogOpen"\n title="发布模板"\n :show-footer="false"\n :portal-disabled="true"\n @update:model-value="callbacks.onToggleTemplateDialog($event)"\n >\n <div\n v-if="state.templateDialogOpen"\n class="template-export-modal"\n data-role="template-export-modal"\n >\n \n <div class="template-export-groups">\n <div\n v-for="group in state.templateFieldGroups"\n :key="group.id"\n class="template-export-group"\n >\n <div class="template-export-group-title">{{ group.title }}</div>\n <div class="template-export-field-list">\n <div\n v-for="field in group.fields"\n :key="field.path"\n class="template-export-field"\n data-role="template-export-field"\n >\n <xt-checkbox\n :model-value="state.templateSelectedFieldPaths.includes(field.path)"\n :disabled="state.templateExportLoading"\n @update:model-value="callbacks.onToggleTemplateField(field.path, $event)"\n >{{ field.label }}</xt-checkbox>\n <div class="template-export-field-path">{{ field.path }}</div>\n </div>\n </div>\n </div>\n </div>\n\n <div class="template-export-footer">\n <xt-button\n type="secondary"\n :disabled="state.templateExportLoading"\n @click="callbacks.onCloseTemplateDialog()"\n >取消</xt-button>\n <xt-button\n type="primary"\n data-role="template-export-confirm"\n :loading="state.templateExportLoading"\n :disabled="state.templateSelectedFieldPaths.length === 0"\n @click="callbacks.onConfirmTemplateExport()"\n >发布模板</xt-button>\n </div>\n </div>\n </xt-modal>\n\n <xt-modal\n :model-value="state.historyDialogOpen"\n title="历史记录"\n :show-footer="false"\n :portal-disabled="true"\n @update:model-value="!$event && callbacks.onCloseHistory()"\n >\n <div\n v-if="state.historyDialogOpen"\n class="history-dialog"\n data-role="history-dialog"\n >\n <div\n v-if="state.historyError"\n class="history-dialog-error"\n data-role="history-error"\n >{{ state.historyError }}</div>\n\n <div\n v-else-if="state.historyItems.length === 0 && !state.historyLoading"\n class="history-dialog-empty"\n data-role="history-empty"\n >暂无历史记录</div>\n\n <div class="history-list" v-else data-role="history-list">\n <div\n v-for="item in state.historyItems"\n :key="item.id"\n class="history-item"\n data-role="history-item"\n >\n <div class="history-item-title">{{ item.title }}</div>\n <div class="history-item-meta">#{{ item.id }}</div>\n <div class="history-item-actions">\n <xt-button\n type="secondary"\n size="small"\n :disabled="state.historyRestoreLoading"\n :data-role="'history-restore-' + item.id"\n @click="callbacks.onRestoreHistory(item.id)"\n >恢复</xt-button>\n <xt-button\n type="secondary"\n size="small"\n :disabled="state.historyDeleteLoading"\n :data-role="'history-delete-' + item.id"\n @click="callbacks.onDeleteHistory(item.id)"\n >删除</xt-button>\n </div>\n </div>\n </div>\n </div>\n </xt-modal>\n\n <XtAtommProContext\n v-if="state.invitationEnabled && state.invitationReady"\n :env="state.atommProEnv"\n :domain="state.atommProDomain"\n :utoken="state.authToken"\n :user="state.atommProUser"\n >\n <InvitationModal\n ref="invitationModalRef"\n :z-index="state.invitationZIndex"\n :show-link="state.invitationShowLink"\n />\n </XtAtommProContext>\n </div>\n`,f=new URL("../atomm-pro/dist-browser/atomm-pro.css","undefined"==typeof document&&"undefined"==typeof location?require("url").pathToFileURL(__filename).href:"undefined"==typeof document?location.href:o&&"SCRIPT"===o.tagName.toUpperCase()&&o.src||new URL("index.umd.js",document.baseURI).href).toString(),b=new URL("../atomm-pro/dist-browser/atomm-pro.js","undefined"==typeof document&&"undefined"==typeof location?require("url").pathToFileURL(__filename).href:"undefined"==typeof document?location.href:o&&"SCRIPT"===o.tagName.toUpperCase()&&o.src||new URL("index.umd.js",document.baseURI).href).toString();function y(t){return new Promise(e=>{setTimeout(e,t)})}const x=new Map;let w=null;const _=new Map,C=new Map;function k(){return globalThis.Vue}function E(t){return new Error(`[generator-workbench] failed to auto-load Vue 3 runtime from ${t}`)}async function S(t){const e=k();return e&&"function"==typeof e.createApp?e:function(t){const e=x.get(t);if(e)return e;const n=new Promise((e,n)=>{const o=k();if(o&&"function"==typeof o.createApp)return void e(o);const a=()=>{const o=k();o&&"function"==typeof o.createApp?e(o):(x.delete(t),n(E(t)))},i=()=>{x.delete(t),n(E(t))},r=Array.from(document.querySelectorAll("script")).find(e=>e.src===t);if(r)return r.addEventListener("load",a,{once:!0}),void r.addEventListener("error",i,{once:!0});const s=document.createElement("script");s.src=t,s.async=!0,s.dataset.generatorWorkbenchVue="true",s.addEventListener("load",a,{once:!0}),s.addEventListener("error",i,{once:!0}),(document.head||document.body||document.documentElement).appendChild(s)});return x.set(t,n),n}(t.vueScriptUrl||"https://unpkg.com/vue@3/dist/vue.global.prod.js")}function T(){return globalThis.AtommUI}function I(){return globalThis.Pinia}function P(){return globalThis.VueRouter}function R(){return globalThis.VueI18n}function U(){return globalThis.AtommPro}function L(t,e,n){const o=n();if(o)return Promise.resolve(o);const a=`${e}:${t}`,i=_.get(a);if(i)return i;const r=new Promise(o=>{const i=document.querySelector(`script[data-${e}="true"][src="${t}"]`),r=()=>o(n()),s=()=>{_.delete(a),o(void 0)};if(i)return i.addEventListener("load",r,{once:!0}),void i.addEventListener("error",s,{once:!0});const l=document.createElement("script");l.src=t,l.async=!0,l.dataset[e]="true",l.addEventListener("load",r,{once:!0}),l.addEventListener("error",s,{once:!0}),function(t){(document.head||document.body||document.documentElement).appendChild(t)}(l)});return _.set(a,r),r}async function D(t,e){const n=await function(t){const e=C.get(t);if(e)return e;const n=fetch(t).then(async e=>e.ok?e.text():(C.delete(t),null)).catch(()=>(C.delete(t),null));return C.set(t,n),n}(e),o=n?function(t){return t.replace(/(^|})\s*:root(?=\s*{)/g,"$1:host")}(n):null;if(o){const n=document.createElement("style");n.dataset.generatorWorkbenchStyleUrl=e,n.textContent=o,t.appendChild(n)}else{const n=document.createElement("link");n.rel="stylesheet",n.href=e,t.appendChild(n)}}async function A(t){const e=document.head.querySelector(`style[data-generator-workbench-global-style-url="${t}"]`),n=document.head.querySelector(`link[data-generator-workbench-global-style-url="${t}"]`);if(e||n)return;const o=document.createElement("link");o.rel="stylesheet",o.href=t,o.dataset.generatorWorkbenchGlobalStyleUrl=t,(document.head||document.body||document.documentElement).appendChild(o)}function B(t){var e;return(null==(e=t.atommProLocale)?void 0:e.trim())?t.atommProLocale.trim():"undefined"!=typeof navigator&&navigator.language.startsWith("zh")?"zh-CN":"en-US"}function F(t){return t.atommProEnv||"prod"}function H(t){return t.atommProDomain||"atomm"}function q(t){return!1!==t.invitationEnabled}function O(t){t.component("xt-button",{inheritAttrs:!0,template:'<button v-bind="$attrs"><slot name="icon" /><slot /><slot name="append-icon" /></button>'}),t.component("xt-avatar",{inheritAttrs:!0,template:'<span v-bind="$attrs"><slot /></span>'}),t.component("xt-dropdown-menu",{inheritAttrs:!0,template:'<div v-bind="$attrs"><slot name="trigger" /><slot name="overlay" /><slot /></div>'}),t.component("xt-hover-card",{inheritAttrs:!0,template:'<div v-bind="$attrs"><slot name="trigger" /><slot name="content" /></div>'}),t.component("xt-modal",{inheritAttrs:!1,props:{modelValue:{type:Boolean,default:!1},title:{type:String,default:""}},emits:["update:modelValue"],template:'\n <div v-if="modelValue" v-bind="$attrs">\n <div>{{ title }}</div>\n <slot />\n </div>\n '}),t.component("xt-checkbox",{inheritAttrs:!1,props:{modelValue:{type:Boolean,default:!1},label:{type:String,default:""},disabled:{type:Boolean,default:!1}},emits:["update:modelValue","change"],template:'\n <label v-bind="$attrs">\n <input\n type="checkbox"\n :checked="modelValue"\n :disabled="disabled"\n @change="$emit(\'update:modelValue\', $event.target.checked)"\n />\n <span><slot>{{ label }}</slot></span>\n </label>\n '})}async function M(t){const e=T();return e||(n=t.atommUiScriptUrl||"https://minio-download.makeblock.com/resource/atomm-ui-umd/dist-browser/atomm-ui.js",w||(w=L(n,"generatorWorkbenchAtommUi",T),w));var n}async function z(t,e={}){if(!e.force&&!q(t))return null;const[n,o,a]=await Promise.all([L(t.piniaScriptUrl||"https://unpkg.com/pinia@3/dist/pinia.iife.prod.js","generatorWorkbenchPinia",I),L(t.vueRouterScriptUrl||"https://unpkg.com/vue-router@4/dist/vue-router.global.prod.js","generatorWorkbenchVueRouter",P),L(t.vueI18nScriptUrl||"https://unpkg.com/vue-i18n@11/dist/vue-i18n.global.prod.js","generatorWorkbenchVueI18n",R)]);if(!n||!o||!a)return null;const i=await L(t.atommProScriptUrl||b,"generatorWorkbenchAtommPro",U);return i?{pinia:n,vueRouter:o,vueI18n:a,atommPro:i}:null}async function $(t,e){var n,o,a,i;const r=await S(e);!function(){const t=globalThis;t.process?t.process.env?t.process.env.NODE_ENV||(t.process.env.NODE_ENV="production"):t.process.env={NODE_ENV:"production"}:t.process={env:{NODE_ENV:"production"}}}();const s=await z(e);await async function(t,e){const n=e.atommUiCssUrl||"https://minio-download.makeblock.com/resource/atomm-ui-umd/dist-browser/atomm-ui.min.css";if(await D(t,n),await A(n),q(e)){const n=e.atommProCssUrl||f;await D(t,n),await A(n)}const o=document.createElement("style");o.textContent="\n :host {\n display: block;\n height: 100%;\n color: #111827;\n font-family: Inter, \"Montserrat\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n --bg-soft: #f3f4f6;\n --border-default: #e5e7eb;\n --text-primary: #111827;\n --text-secondary: #4b5563;\n --text-muted: #9ca3af;\n }\n\n * {\n box-sizing: border-box;\n }\n\n [data-workbench-vue-root] {\n height: 100%;\n }\n\n .shell {\n height: 100%;\n display: flex;\n flex-direction: column;\n background:\n radial-gradient(rgba(17, 24, 39, 0.06) 1px, transparent 1px),\n linear-gradient(180deg, rgba(255, 255, 255, 0.7), rgba(249, 250, 251, 0.96));\n background-size: 20px 20px, auto;\n }\n\n .topbar,\n .app-topbar {\n height: 64px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 0 24px;\n background: rgba(255, 255, 255,1);\n border-bottom: 1px solid var(--border-default);\n backdrop-filter: blur(12px);\n position: relative;\n z-index: 20;\n }\n\n .logo-area,\n .app-topbar-main {\n display: flex;\n align-items: center;\n gap: 18px;\n min-width: 0;\n flex: 1;\n }\n\n .app-topbar-nav {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n }\n\n .workspace {\n flex: 1;\n min-height: 0;\n display: grid;\n grid-template-columns: minmax(0, 1fr) 320px;\n }\n\n .workspace.shell-mode-shell {\n display: block;\n position: relative;\n }\n\n .workspace-host {\n height: 100%;\n min-height: 0;\n position: relative;\n }\n\n .workspace.panel-left {\n grid-template-columns: 320px minmax(0, 1fr);\n }\n\n .workspace.panel-right .canvas-host {\n grid-column: 1;\n }\n\n .workspace.panel-right .panel-sidebar {\n grid-column: 2;\n }\n\n .workspace.panel-left .panel-sidebar {\n grid-column: 1;\n }\n\n .workspace.panel-left .canvas-host {\n grid-column: 2;\n }\n\n .panel-sidebar {\n min-height: 0;\n display: flex;\n flex-direction: column;\n background: #ffffff;\n }\n\n .panel-host {\n flex: 1;\n min-height: 0;\n overflow: auto;\n }\n\n .canvas-host {\n position: relative;\n min-height: 480px;\n display: grid;\n place-items: center;\n }\n\n .brand-logo {\n height: 32px;\n width: 92px;\n display: block;\n cursor: pointer;\n flex: 0 0 auto;\n }\n\n .app-topbar-auth {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 12px;\n flex: 0 0 auto;\n }\n\n .topbar-credits-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0;\n color: #2d3541;\n font-size: 14px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n cursor: default;\n }\n\n .topbar-credits-value {\n font-variant-numeric: tabular-nums;\n }\n\n .invite-entry {\n appearance: none;\n border: 0;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 6px;\n border-radius: 6px;\n background: #fcf3ed;\n cursor: pointer;\n user-select: none;\n white-space: nowrap;\n transition: all 0.3s;\n }\n\n .invite-entry:hover:not(:disabled) {\n background:\n linear-gradient(\n 0deg,\n rgba(255, 124, 35, 0.2) 0%,\n rgba(255, 124, 35, 0.2) 100%\n ),\n #fcf3ed;\n }\n\n .invite-entry:disabled {\n opacity: 0.48;\n cursor: not-allowed;\n }\n\n .invite-entry-icon {\n width: 14px;\n height: 14px;\n flex: 0 0 auto;\n display: block;\n user-select: none;\n -webkit-user-drag: none;\n }\n\n .invite-entry-text {\n color: #ff7c23;\n font-size: 12px;\n font-weight: 600;\n line-height: 1;\n }\n\n .credits-token-icon {\n width: 20px;\n height: 20px;\n flex: 0 0 16px;\n user-select: none;\n -webkit-user-drag: none;\n }\n\n .credits-token-icon--sm {\n width: 16px;\n height: 16px;\n flex-basis: 16px;\n }\n\n .auth-avatar-trigger {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px 4px 4px;\n border-radius: 999px;\n cursor: pointer;\n transition: background 150ms ease;\n }\n\n .auth-avatar-button {\n appearance: none;\n border: 0;\n background: transparent;\n cursor: pointer;\n }\n\n .auth-avatar-button--guest {\n padding: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n }\n\n\n .auth-avatar {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n display: grid;\n place-items: center;\n overflow: hidden;\n flex: 0 0 auto;\n background: #f3f4f6;\n color: var(--text-secondary);\n font-size: 14px;\n font-weight: 600;\n }\n\n .auth-avatar--lg {\n width: 40px;\n height: 40px;\n font-size: 14px;\n }\n\n .auth-avatar--guest {\n background: transparent;\n }\n\n .auth-avatar img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n }\n\n .auth-popover-body {\n min-width: 200px;\n padding: 4px 0;\n }\n\n .auth-popover-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n }\n\n .auth-popover-user-text {\n min-width: 0;\n flex: 1;\n }\n\n .auth-popover-name {\n display: block;\n font-size: 14px;\n font-weight: 600;\n color: var(--text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .auth-popover-sub {\n display: block;\n margin-top: 2px;\n font-size: 12px;\n color: var(--text-secondary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .auth-popover-divider {\n height: 1px;\n background: var(--border-default);\n margin: 4px 0;\n }\n\n .auth-popover-action {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n font-size: 13px;\n color: var(--text-secondary);\n cursor: pointer;\n transition: all 150ms ease;\n }\n\n .auth-popover-action:hover {\n background: var(--bg-soft);\n color: var(--text-primary);\n }\n\n .auth-hover-card {\n position: relative;\n display: inline-flex;\n align-items: center;\n z-index: 99999;\n }\n\n .auth-hover-panel {\n position: absolute;\n top: calc(100% + 8px);\n right: 0;\n z-index: 999999;\n min-width: 200px;\n background: #fff;\n border: 1px solid var(--border-default);\n border-radius: 12px;\n box-shadow: 0 8px 28px rgba(17, 24, 39, 0.12);\n opacity: 0;\n transform: translateY(4px);\n pointer-events: none;\n transition: opacity 150ms ease, transform 150ms ease;\n }\n\n .auth-hover-card:hover .auth-hover-panel,\n .auth-hover-card:focus-within .auth-hover-panel {\n opacity: 1;\n transform: translateY(-6px);\n pointer-events: auto;\n }\n\n .panel-actions,\n #sidebar-footer {\n flex-shrink: 0;\n width: 262px;\n display: flex;\n align-items: center;\n }\n\n .panel-sidebar #sidebar-footer {\n padding: 14px 24px;\n flex-shrink: 0;\n width: auto;\n display: flex;\n align-items: center;\n \n }\n\n .sidebar-footer-floating {\n position: fixed;\n right: 24px;\n bottom: 24px;\n z-index: 30;\n width: auto;\n padding: 0;\n border-top: 0;\n background: transparent;\n box-shadow: none;\n }\n\n .sidebar-footer-floating .sidebar-export-trigger-btn,\n .sidebar-footer-floating .sidebar-export-trigger-btn-wrap,\n .sidebar-footer-floating .sidebar-export-trigger-btn-wrap {\n width: auto;\n }\n\n .sidebar-footer-floating .sidebar-export-trigger-btn {\n min-width: 180px;\n box-shadow: 0 12px 28px rgba(17, 24, 39, 0.18);\n }\n\n .sidebar-footer-export {\n width: 100%;\n }\n\n .sidebar-footer-export .sidebar-export-trigger-btn,\n .sidebar-footer-export .sidebar-export-trigger-btn-wrap,\n .sidebar-export-trigger-btn-wrap {\n width: 100%;\n }\n\n .sidebar-export-dropdown-menu {\n width: 268px;\n }\n\n .sidebar-export-trigger-btn img {\n margin-right: 4px;\n }\n\n .export-credits-hint {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 2px;\n padding: 0;\n font-size: 12px;\n font-weight: 600;\n line-height: 1;\n color: #ff7c23;\n margin-left: 10px;\n white-space: nowrap;\n }\n\n .export-credits-hint-value {\n width: 100%;\n background: linear-gradient(90deg, #fce1bf, #ecb678 67.02%, #f9c991);\n border-radius: 4px;\n gap: 2px;\n height: 16px;\n padding: 2px 4px;\n font-size: 10px;\n font-weight: 600;\n line-height: 16px;\n color: #581e06;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n\n .export-overlay-menu,\n .fab-menu-content {\n padding: 4px;\n }\n\n .export-overlay-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-radius: 6px;\n font-size: 14px;\n color: var(--text-primary);\n cursor: pointer;\n transition: background 120ms ease;\n user-select: none;\n }\n\n .export-overlay-item:hover {\n background: var(--bg-soft);\n }\n\n .export-overlay-item-icon {\n width: 16px;\n height: 16px;\n display: inline-block;\n flex: 0 0 auto;\n background-repeat: no-repeat;\n background-position: center;\n background-size: contain;\n }\n\n .export-overlay-item-icon--svg {\n background-image: url(\"data:image/svg+xml,%3c?xml%20version='1.0'%20standalone='no'?%3e%3c!DOCTYPE%20svg%20PUBLIC%20'-//W3C//DTD%20SVG%201.1//EN'%20'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3e%3csvg%20t='1775118703519'%20class='icon'%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20p-id='12828'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20width='200'%20height='200'%3e%3cpath%20d='M469.333333%20596.053333V128h85.333334v468.053333l208.64-160.554666%2052.053333%2067.669333-277.333333%20213.333333a42.666667%2042.666667%200%200%201-52.053334%200l-277.333333-213.333333%2052.053333-67.669333L469.333333%20596.053333zM896%20896H128v-85.333333h768v85.333333z'%20p-id='12829'%3e%3c/path%3e%3c/svg%3e\");\n }\n\n .export-overlay-item-icon--studio {\n background-image: url(\"data:image/svg+xml,%3c?xml%20version='1.0'%20standalone='no'?%3e%3c!DOCTYPE%20svg%20PUBLIC%20'-//W3C//DTD%20SVG%201.1//EN'%20'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3e%3csvg%20t='1775118714051'%20class='icon'%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20p-id='12988'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20width='200'%20height='200'%3e%3cpath%20d='M197.553231%20309.169231h128.945231l85.858461%2085.858461-64.512%2064.827077-150.291692-150.685538z%20m472.694154%2021.267692L509.006769%20492.307692l182.429539%20183.059693H562.491077L444.494769%20557.056%20326.498462%20675.288615H197.553231l364.937846-366.119384h128.945231l-21.188923%2021.267692z'%20p-id='12989'%3e%3c/path%3e%3cpath%20d='M157.538462%200a157.538462%20157.538462%200%200%200-157.538462%20157.538462v682.692923a157.538462%20157.538462%200%200%200%20157.538462%20157.538461h236.307692v-105.078154H157.538462a52.539077%2052.539077%200%200%201-52.539077-52.460307V157.538462c0-28.987077%2023.552-52.539077%2052.539077-52.539077h577.614769c29.065846%200%2052.539077%2023.552%2052.539077%2052.539077v393.846153h104.999384V157.538462a157.538462%20157.538462%200%200%200-157.538461-157.538462H157.538462z'%20p-id='12990'%3e%3c/path%3e%3cpath%20d='M789.267692%20681.038769l159.113846%20159.113846-159.113846%20159.113847-55.689846-55.611077%2064.039385-64.039385H551.384615v-78.769231h246.232616l-64.039385-64.039384%2055.689846-55.768616z'%20p-id='12991'%3e%3c/path%3e%3c/svg%3e\");\n }\n\n .workspace.panel-right .panel-sidebar {\n border-left: 1px solid var(--border-default);\n }\n\n .workspace.panel-left .panel-sidebar {\n border-right: 1px solid var(--border-default);\n }\n\n .template-export-modal {\n display: grid;\n gap: 16px;\n }\n\n \n\n .template-export-groups {\n display: grid;\n gap: 12px;\n max-height: 360px;\n overflow: auto;\n }\n\n .template-export-group {\n display: grid;\n gap: 10px;\n padding: 14px 16px;\n border: 1px solid var(--border-default);\n border-radius: 12px;\n background: #ffffff;\n }\n\n .template-export-group-title {\n font-size: 13px;\n font-weight: 700;\n color: var(--text-primary);\n }\n\n .template-export-field-list {\n display: grid;\n gap: 10px;\n }\n\n .template-export-field {\n display: grid;\n gap: 4px;\n }\n\n .template-export-field-path {\n padding-left: 28px;\n font-size: 12px;\n color: var(--text-muted);\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n }\n\n .template-export-footer {\n display: flex;\n justify-content: flex-end;\n gap: 12px;\n padding: 8px 24px;\n }\n\n .workbench-host-actions {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n }\n\n .history-dialog {\n display: grid;\n gap: 16px;\n }\n\n .history-dialog-error {\n color: #b91c1c;\n font-size: 13px;\n }\n\n .history-dialog-empty {\n color: var(--text-secondary);\n font-size: 13px;\n }\n\n .history-list {\n display: grid;\n gap: 12px;\n max-height: 360px;\n overflow: auto;\n }\n\n .history-item {\n display: grid;\n gap: 10px;\n padding: 14px 16px;\n border: 1px solid var(--border-default);\n border-radius: 12px;\n background: #ffffff;\n }\n\n .history-item-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--text-primary);\n }\n\n .history-item-meta {\n font-size: 12px;\n color: var(--text-muted);\n }\n\n .history-item-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n }\n",t.appendChild(o)}(t,e);const l=function(t,e,n){var o;const a=!1!==e.shellChromeVisible;return t.reactive({shellMode:e.mode||"full",showTopbar:a&&"template"!==e.mode,showSidebarFooter:a,logoText:e.logoText||e.title,logoSrc:e.logoUrl||"https://storage-us.atomm.com/resource/xart/static/agent/imgs/atomm-logo.svg",panelTarget:e.panelTarget||"right",avatarMenuTrigger:e.avatarMenuTrigger||"hover",templateEnabled:!1!==e.templateEnabled,creditsEnabled:!1!==e.creditsEnabled,invitationEnabled:q(e),invitationReady:n,invitationConfigKey:(null==(o=e.invitationConfigKey)?void 0:o.trim())||"",invitationButtonText:e.invitationButtonText||"Earn Credits",invitationShowLink:!0===e.invitationShowLink,invitationZIndex:e.invitationZIndex||2e3,atommProEnv:F(e),atommProDomain:H(e),authToken:"",atommProUser:{userName:"",userHandle:"",avatar:""},exportEnabled:!1!==e.exportEnabled,studioEnabled:!1!==e.studioEnabled,cloudEnabled:!0===e.cloudEnabled,historyEnabled:!0===e.historyEnabled,isLogin:!1,avatarSrc:"",avatarText:"U",authDisplayName:"",authSubline:"",creditsBalance:0,showExportCreditsHint:!1,showExportCreditsIcon:!1,exportCreditsHintText:"",loginLoading:!1,cloudSaveLoading:!1,historyDialogOpen:!1,historyLoading:!1,historyRestoreLoading:!1,historyDeleteLoading:!1,historyError:"",historyItems:[],templateDialogOpen:!1,templateExportLoading:!1,templateSelectedFieldPaths:[],templateFieldGroups:[]})}(r,e,null!==s),d={onLogin:()=>{},onOpenInvitation:()=>{},onLogout:()=>{},onImportTemplate:()=>{},onExportTemplate:()=>{},onSaveCloud:()=>{},onOpenHistory:()=>{},onCloseHistory:()=>{},onRestoreHistory:()=>{},onDeleteHistory:()=>{},onCloseTemplateDialog:()=>{},onToggleTemplateDialog:()=>{},onToggleTemplateField:()=>{},onConfirmTemplateExport:()=>{},onExportSvg:()=>{},onOpenInStudio:()=>{},onFileChange:()=>{}},c=r.ref(null),u=document.createElement("div");u.setAttribute("data-workbench-vue-root",""),t.appendChild(u);const p=await M(e),m=s?s.vueRouter.createRouter({history:(null==(o=(n=s.vueRouter).createMemoryHistory)?void 0:o.call(n))||(null==(i=(a=s.vueRouter).createWebHashHistory)?void 0:i.call(a))||{},routes:[{path:"/",component:{template:"<div />"}}]}):null,g=s?s.vueI18n.createI18n({legacy:!1,locale:B(e),fallbackLocale:B(e),globalInjection:!0,messages:e.atommProMessages||{"en-US":{},"zh-CN":{}},missingWarn:!1,fallbackWarn:!1}):null,b=r.createApp({setup:()=>({state:l,callbacks:d,invitationModalRef:c}),template:v});p?b.use(p):O(b),s||function(t){t.component("XtAtommProContext",{inheritAttrs:!0,template:'<div v-bind="$attrs"><slot /></div>'}),t.component("InvitationModal",{template:'<div data-role="stub-invitation-modal"></div>',methods:{open(){}}})}(b),s&&(b.use(s.pinia.createPinia()),m&&b.use(m),g&&b.use(g),b.use(s.atommPro)),b.mount(u);const x=function(t){return{root:t,workspace:h(t,'[data-role="workspace"]'),logoArea:t.querySelector('[data-role="logo-area"]'),workspaceHost:t.querySelector('[data-role="workspace-host"]'),canvasHost:t.querySelector('[data-role="canvas-host"]'),panelHost:t.querySelector('[data-role="panel-host"]'),templateFileInput:h(t,'[data-role="template-file-input"]')}}(t);let w=null;return{state:l,callbacks:d,app:b,refs:x,openInvitationModal:()=>{var t,e;const n=c.value,o=(null==n?void 0:n.open)||(null==(e=null==(t=null==n?void 0:n.$)?void 0:t.exposed)?void 0:e.open);null==o||o({configKey:l.invitationConfigKey||"default",showDetail:!1})},requestCreditsPurchase:async t=>{if(!w){await A(e.atommProCssUrl||f);const t=await z(e,{force:!0});if(!t)throw new Error("[generator-workbench] atomm-pro runtime is not available");w=function(t){var e,n,o,a;const{vue:i,state:r,config:s,runtime:l,atommUi:d}=t,c=i.ref(null),u=document.createElement("div");u.style.display="none",(document.body||document.documentElement).appendChild(u);const p=i.createApp({setup:()=>({state:r,bridgeRef:c}),template:'\n <XtAtommProContext\n :env="state.atommProEnv"\n :domain="state.atommProDomain"\n :utoken="state.authToken"\n :user="state.atommProUser"\n >\n <WorkbenchPayServiceBridge ref="bridgeRef" />\n </XtAtommProContext>\n '});return p.component("WorkbenchPayServiceBridge",{setup(t,e){var n,o,a;const{expose:r}=e,s=null==(n=i.getCurrentInstance)?void 0:n.call(i),d=null==(a=(o=l.atommPro).usePayService)?void 0:a.call(o,s);return r({purchase:t=>{if(!(null==d?void 0:d.purchase))throw new Error("[generator-workbench] atomm-pro pay service is not ready");return d.purchase(t)}}),{}},template:'<div data-role="pay-service-bridge" style="display:none"></div>'}),d?p.use(d):O(p),p.use(l.pinia.createPinia()),p.use(l.vueRouter.createRouter({history:(null==(n=(e=l.vueRouter).createMemoryHistory)?void 0:n.call(e))||(null==(a=(o=l.vueRouter).createWebHashHistory)?void 0:a.call(o))||{},routes:[{path:"/",component:{template:"<div />"}}]})),p.use(l.vueI18n.createI18n({legacy:!1,locale:B(s),fallbackLocale:B(s),globalInjection:!0,messages:s.atommProMessages||{"en-US":{},"zh-CN":{}},missingWarn:!1,fallbackWarn:!1})),p.use(l.atommPro),p.mount(u),{purchase:async t=>{const e=l.atommPro.AtommProContext;if((null==e?void 0:e.use)&&!e.payConfig){e.use({env:r.atommProEnv,domain:r.atommProDomain,utoken:r.authToken,user:r.atommProUser,watch:!0});const t=Date.now()+3e3;for(;!e.payConfig&&Date.now()<t;)await y(25)}const n=c.value;if(!(null==n?void 0:n.purchase))throw new Error("[generator-workbench] atomm-pro pay bridge is not ready");return n.purchase(t)},dispose:()=>{p.unmount(),u.remove()}}}({vue:r,state:l,config:e,runtime:t,atommUi:p})}return w.purchase(t)},disposeCreditsPurchaseBridge:()=>{null==w||w.dispose(),w=null}}}function N(t){t.disposeCreditsPurchaseBridge(),t.app.unmount()}function G(t){const{targetWindow:e=window,parentWindow:n=window.parent,targetOrigin:o="*",validateOrigin:a,handlers:i}=t;let r=!1;const s=(t,e)=>{r||(Q("outgoing",{type:t,data:e,targetOrigin:o}),n.postMessage({type:t,data:e},o))},l=(t,e)=>{Q("error",{type:"generator_toTemplateError",action:t,message:K(e)}),s("generator_toTemplateError",{action:t,message:K(e)})},d=t=>{if(r)return;if(a&&!a(t.origin,t))return;const e=t.data;if(!e||"object"!=typeof e)return;const n="type"in e&&"string"==typeof e.type?e.type:"",o="data"in e?e.data:void 0;switch(Q("incoming",{type:n,data:o,origin:t.origin}),n){case"generator_getGeneratorData":return void i.getGeneratorData().then(t=>{s("generator_toGeneratorData",t)}).catch(t=>{l("getGeneratorData",t)});case"generator_setGeneratorData":return void Promise.resolve(i.setGeneratorData(o||{}));case"generator_loadTemplateData":return void i.loadTemplateData(o||{}).then(t=>{s("generator_toTemplateLoaded",{template:(null==t?void 0:t.template)||(o&&"template"in o?o.template:o)||null})}).catch(t=>{l("loadTemplateData",t)});case"generator_getTemplateData":return void i.getTemplateData().then(t=>{s("generator_toTemplateData",t)}).catch(t=>{l("getTemplateData",t)});case"generator_getFile":{const t=function(t){return"openInStudio"===t||"cover"===t?t:"download"}(null==o?void 0:o.action);return void i.getFile(t).then(t=>{s("generator_toFile",t)}).catch(e=>{((t,e)=>{Q("error",{type:"generator_toFileError",action:t,message:K(e)}),s("generator_toFileError",{action:t,message:K(e)})})(t,e)})}case"generator_getTemplateFieldOptions":return void l("getTemplateFieldOptions",new Error("Template field options are not supported"));case"generator_publishTemplate":return void l("publishTemplate",new Error("Template publishing is not supported"));default:return}};return e.addEventListener("message",d),s("generator_pageLoaded"),{dispose(){r||(Q("lifecycle",{type:"dispose"}),r=!0,e.removeEventListener("message",d))}}}async function V(t){var e,n;const{action:o,sdk:a,runtime:i,config:r,element:s}=t,l={sdk:a,runtime:i,element:s},d=await Promise.resolve(null==(n=null==(e=r.embedBridge)?void 0:e.getExportData)?void 0:n.call(e,o,l))||await async function(t,e){const n=t.export,o=n.provider;if(!o)return null;const a=function(t){if("openInStudio"===t)return"studio";return t}(e),i="cover"===e?"png":"svg";if("function"==typeof o.getExportData){const t=await Promise.resolve(o.getExportData(a,i));if(t)return t}if("function"==typeof o.getExportCanvas){const t=await Promise.resolve(o.getExportCanvas(a));if(t)return{type:"canvas",canvas:t}}return null}(a,o);if(!d)throw new Error("No export data available");return{action:o,...await j(d)}}async function W(t){var e,n;const{sdk:o,runtime:a,config:i,element:r}=t;return await Promise.resolve(null==(n=null==(e=i.embedBridge)?void 0:e.getOriginImageUrl)?void 0:n.call(e,{sdk:o,runtime:a,element:r}))||""}async function j(t){switch(t.type){case"canvas":return{base64:t.canvas.toDataURL("image/png"),mimeType:"image/png",ext:"png"};case"dataUrl":{const e=X(t.dataUrl);return{base64:t.dataUrl,mimeType:e,ext:Z(e)}}case"svg":return{base64:Y(t.svgString),mimeType:"image/svg+xml",ext:"svg"};case"blob":{const e=await J(t.blob),n=t.blob.type||X(e);return{base64:e,mimeType:n,ext:Z(n)}}case"url":{const e=await fetch(t.url);if(!e.ok)throw new Error(`Failed to fetch export URL: ${e.status}`);const n=await e.blob(),o=await J(n),a=n.type||X(o);return{base64:o,mimeType:a,ext:Z(a)}}}}function K(t){return t instanceof Error?t.message:String(t)}function X(t){var e;return(null==(e=t.match(/^data:(image\/[a-zA-Z0-9.+-]+);/))?void 0:e[1])||"image/png"}function Z(t){var e;return"image/svg+xml"===t?"svg":"image/jpeg"===t?"jpg":(null==(e=t.split("/")[1])?void 0:e.split("+")[0])||"png"}function Y(t){const e=encodeURIComponent(t).replace(/%([0-9A-F]{2})/g,(t,e)=>String.fromCharCode(Number.parseInt(e,16)));return`data:image/svg+xml;base64,${btoa(e)}`}function J(t){return new Promise((e,n)=>{const o=new FileReader;o.onload=()=>{"string"==typeof o.result?e(o.result):n(new Error("Failed to read blob as data URL"))},o.onerror=()=>{n(o.error||new Error("Failed to read blob as data URL"))},o.readAsDataURL(t)})}function Q(t,e){new URLSearchParams(window.location.search).get("bridgeDebug")}const tt={title:"",mode:"full",templateEnabled:!0,exportEnabled:!0,studioEnabled:!0,autoMount:!0,panelTarget:"right",avatarMenuTrigger:"hover"};function et(t){return"shell"===t.mode}function nt(){return"embed"===new URLSearchParams(window.location.search).get("mode")?"embed":"full"}class ot extends HTMLElement{constructor(){super(),n(this,"_sdk",null),n(this,"_runtime",null),n(this,"_config",{...tt}),n(this,"_mounted",!1),n(this,"_state",{authStatus:{isLogin:!1,userInfo:null},creditsBalance:0,billingUsage:null,cloudRecordId:null,lastSavedAt:null,historyItems:[],historyDrawerOpen:!1,historyError:null,saveError:null,busy:{login:!1,importTemplate:!1,exportTemplate:!1,exportSvg:!1,openInStudio:!1,cloudSave:!1,historyLoad:!1,historyRestore:!1,historyDelete:!1},menu:{avatarOpen:!1,fabOpen:!1}}),n(this,"_cleanupAuth"),n(this,"_cleanupCredits"),n(this,"_cleanupBilling"),n(this,"_cleanupRuntimeSubscription"),n(this,"_cloudAutoSaveScheduler"),n(this,"_runtimeCloudSaveTimer",null),n(this,"_billingCountdownTimer",null),n(this,"_authController"),n(this,"_templateController"),n(this,"_exportController"),n(this,"_cloudController"),n(this,"_historyController"),n(this,"_runtimeController"),n(this,"_shellContext"),n(this,"_iframeBridge"),n(this,"handleRuntimeCloudSaveRequest",t=>{if(!t.detail)return;this._runtimeCloudSaveTimer&&clearTimeout(this._runtimeCloudSaveTimer);const e=t.detail;this._runtimeCloudSaveTimer=setTimeout(()=>{this._runtimeCloudSaveTimer=null;const t=this.getRouteCloudRecordId()??this._state.cloudRecordId;t?this.performCloudSave({...e,id:t}):this.handleError("runtime",new Error("[generator-workbench] gid is required for runtime cloud save requests"))},2e3)}),this.attachShadow({mode:"open"})}get sdk(){return this._sdk}set sdk(t){this._sdk=t}get runtime(){return this._runtime}set runtime(t){this._runtime=t}get config(){return this._config}set config(t){var e;this._config=(e=t,{...tt,...e}),this._mounted&&this.render()}connectedCallback(){!1!==this._config.autoMount&&!this._mounted&&this._sdk&&this._runtime&&this.mount()}disconnectedCallback(){this.unmount()}async mount(){var t,e,n;if(this._mounted)return;if(!this.shadowRoot)throw new Error("[generator-workbench] shadowRoot is required");if(!this._sdk)throw new Error("[generator-workbench] sdk is required before mount()");if(!this._runtime)throw new Error("[generator-workbench] runtime is required before mount()");await this.render(),this.bindControllers(),this.bindShellCallbacks(),this.bindAuthState(),this.bindRuntimeCloudSaveEvent(),await this.initializeCloudRecordFromRoute(),this.bindAutoSave(),await this.syncBillingState();const o=this.requireRefs();if(et(this._config)){const e=o.workspaceHost;if(!e)throw new Error("[generator-workbench] workspace host is required in shell mode");await(null==(t=this._runtimeController)?void 0:t.mountWorkspace(e))}else{const t=o.canvasHost,a=o.panelHost;if(!t||!a)throw new Error("[generator-workbench] canvas host and panel host are required in full/template mode");await(null==(e=this._runtimeController)?void 0:e.mountCanvas(t)),await(null==(n=this._runtimeController)?void 0:n.mountPanel(a,this._state.activePanelFilter))}this.bindIframeBridge(),this._mounted=!0,p(this,"workbench-ready",{sdk:this._sdk,runtime:this._runtime})}async unmount(){var t,e,n,o,a,i,r;null==(t=this._cleanupAuth)||t.call(this),this._cleanupAuth=void 0,null==(e=this._cleanupCredits)||e.call(this),this._cleanupCredits=void 0,null==(n=this._cleanupBilling)||n.call(this),this._cleanupBilling=void 0,null==(o=this._cleanupRuntimeSubscription)||o.call(this),this._cleanupRuntimeSubscription=void 0,null==(a=this._cloudAutoSaveScheduler)||a.dispose(),this._cloudAutoSaveScheduler=void 0,this._runtimeCloudSaveTimer&&(clearTimeout(this._runtimeCloudSaveTimer),this._runtimeCloudSaveTimer=null),this.clearBillingCountdownTimer(),null==(i=this._iframeBridge)||i.dispose(),this._iframeBridge=void 0,this.removeEventListener("runtime-cloud-save-request",this.handleRuntimeCloudSaveRequest),await(null==(r=this._runtimeController)?void 0:r.unmountAll()),this._shellContext&&(N(this._shellContext),this._shellContext=void 0),this._mounted=!1}refreshLayout(){}async importTemplate(t){try{const e=await this.requireTemplateController().importTemplate(t);this._state.activePanelFilter=e.panelFilter;const n=this.requireRefs();if(this._runtimeController&&!et(this._config)){const t=n.panelHost;if(!t)throw new Error("[generator-workbench] panel host is required for template import");await this._runtimeController.remountPanel(t,e.panelFilter)}p(this,"template-imported",e)}catch(e){this.handleError("template",e)}}async exportTemplate(){return this.exportTemplateWithFields()}async exportTemplateWithFields(t){try{this._state.busy.exportTemplate=!0,this._shellContext&&(this._shellContext.state.templateExportLoading=!0);p(this,"template-exported",await this.requireTemplateController().exportTemplate(t)),t&&this.closeTemplateExportDialog()}catch(e){this.handleError("template",e)}finally{this._state.busy.exportTemplate=!1,this._shellContext&&(this._shellContext.state.templateExportLoading=!1)}}async exportSvg(){try{p(this,"svg-export",await this.requireExportController().exportSvg())}catch(t){this.handleError("export",t)}}async openInStudio(){try{p(this,"studio-open",await this.requireExportController().openInStudio())}catch(t){this.handleError("export",t)}}async setAuthToken(t){var e,n;const o=t.trim();if(!o)throw new Error("[generator-workbench] token is required");if(!this._sdk)throw new Error("[generator-workbench] sdk is required before setAuthToken()");const a=null==(n=(e=this._sdk).getAppKey)?void 0:n.call(e);if(!a)throw new Error("[generator-workbench] sdk.getAppKey() is required for setAuthToken()");if("function"!=typeof this._sdk.auth.syncToken)throw new Error("[generator-workbench] sdk.auth.syncToken() is required for setAuthToken()");try{localStorage.setItem(`__atomm_sdk_token__${a}`,o)}catch{}await this._sdk.auth.syncToken(o)}async saveToCloud(){await this.performCloudSave()}async loadHistory(t){try{this._state.busy.historyLoad=!0,this._shellContext&&(this._shellContext.state.historyLoading=!0),p(this,"history-load-start",{options:t});const e=await this.requireHistoryController().loadList(t);this._state.historyItems=e.items,this._state.historyError=null,this.syncHistoryUI(),p(this,"history-loaded",{result:e})}catch(e){this._state.historyError=e instanceof Error?e.message:String(e),this.syncHistoryUI(),this.handleError("runtime",e)}finally{this._state.busy.historyLoad=!1,this._shellContext&&(this._shellContext.state.historyLoading=!1)}}async restoreHistoryItem(t){try{this._state.busy.historyRestore=!0,this._shellContext&&(this._shellContext.state.historyRestoreLoading=!0),p(this,"history-restore-start",{itemId:t});const e=await this.requireHistoryController().restoreItem(t);this._state.cloudRecordId=e.id,this._state.historyError=null,this.syncHistoryUI(),p(this,"history-restored",{itemId:t,record:e})}catch(e){this._state.historyError=e instanceof Error?e.message:String(e),this.syncHistoryUI(),this.handleError("runtime",e)}finally{this._state.busy.historyRestore=!1,this._shellContext&&(this._shellContext.state.historyRestoreLoading=!1)}}async deleteHistoryItem(t){try{this._state.busy.historyDelete=!0,this._shellContext&&(this._shellContext.state.historyDeleteLoading=!0),p(this,"history-delete-start",{itemId:t});const e=await this.requireHistoryController().deleteItem(t);this._state.historyItems=this._state.historyItems.filter(e=>e.id!==t),this._state.historyError=null,this.syncHistoryUI(),p(this,"history-deleted",e)}catch(e){this._state.historyError=e instanceof Error?e.message:String(e),this.syncHistoryUI(),this.handleError("runtime",e)}finally{this._state.busy.historyDelete=!1,this._shellContext&&(this._shellContext.state.historyDeleteLoading=!1)}}async render(){this.shadowRoot&&(this._shellContext&&(N(this._shellContext),this.shadowRoot.innerHTML=""),this._shellContext=await $(this.shadowRoot,this.getEffectiveConfig()),this.syncAuthUI(),this.syncBillingUI(),this.syncInvitationConfigKey(),this.syncHistoryUI())}bindControllers(){var t;const e=this.getEffectiveSdk(),n=this.getEffectiveConfig();e&&this._runtime&&(this._authController=function(t){const{sdk:e}=t;return{getStatus:()=>e.auth.getStatus(),subscribe:t=>(t(e.auth.getStatus()),e.auth.onChange(t)),async login(){await e.auth.login()},async logout(){await e.auth.logout()}}}({sdk:e}),this._templateController=u({sdk:e,runtime:this._runtime,config:n}),this._exportController=function(t){const{sdk:e,runtime:n,config:o,element:a,requestCreditsPurchase:i}=t;async function r(){if(!e.auth.getStatus().isLogin&&(await e.auth.login(),!e.auth.getStatus().isLogin))throw new Error("[generator-workbench] login is required before export")}async function l(){var t,n;return(null==(t=e.billing)?void 0:t.getUsage)?s(await e.billing.getUsage(),null==(n=e.getAppKey)?void 0:n.call(e)):null}async function d(t){if(!(null==t?void 0:t.isEnabled)||t.inFreePeriod||t.freeRemaining>0)return t;if(t.creditsPerUse<=t.creditsBalance)return t;if(!i)throw new Error("[generator-workbench] credits purchase is not available");if(!(await i({zIndex:2e3,trace:{source:"generator-workbench"}})).done)return null;const e=await l();if(!(null==e?void 0:e.isEnabled))return e;if(e.inFreePeriod||e.freeRemaining>0)return e;if(e.creditsPerUse<=e.creditsBalance)return e;throw new Error("[generator-workbench] credits balance is still insufficient after purchase")}async function c(t){var n,o,a;(null==t?void 0:t.isEnabled)&&!t.inFreePeriod&&(null==(n=e.billing)?void 0:n.consume)&&(await e.billing.consume(),t.freeRemaining<=0&&await(null==(a=(o=e.billing).refreshCredits)?void 0:a.call(o)))}return{async exportSvg(){var t;await(null==(t=o.beforeExportSvg)?void 0:t.call(o,{sdk:e,runtime:n,element:a})),await r();const i=await l(),s=await d(i);if(!i)return e.export.download({format:"svg"});if(!s)return{success:!1,fileName:""};const u=await e.export.download({format:"svg"});return await c(s),u},async openInStudio(){var t;await(null==(t=o.beforeOpenInStudio)?void 0:t.call(o,{sdk:e,runtime:n,element:a})),await r();const i=await l(),s=await d(i);if(!i)return e.export.openInStudio({format:"svg"});if(!s)return{success:!1};const u=await e.export.openInStudio({format:"svg"});return await c(s),u}}}({sdk:e,runtime:this._runtime,config:n,element:this,requestCreditsPurchase:!1===n.creditsEnabled||null==(t=this._shellContext)?void 0:t.requestCreditsPurchase}),this._cloudController=e.cloud?function(t){const{sdk:e,runtime:n,config:o,element:a}=t;function i(){if(!e.cloud)throw new Error("[generator-workbench] sdk.cloud is required for cloud actions");return e.cloud}function r(){return{sdk:e,runtime:n,element:a,state:n.getState()}}async function s(){var t,n,o,a;if(!(null==(n=(t=e.auth).getToken)?void 0:n.call(t).trim())&&(await e.auth.login(),!(null==(a=(o=e.auth).getToken)?void 0:a.call(o).trim())))throw new Error("[generator-workbench] sdk.auth.getToken() is required after login")}async function l(t){var e,n;await s();const a=i(),l={...r(),state:t.snapshot};await(null==(e=o.onBeforeCloudSave)?void 0:e.call(o,l));const d=await a.save(t);return await(null==(n=o.onAfterCloudSave)?void 0:n.call(o,d,l)),d}async function d(){var t;const e=r();return l((null==(t=o.getCloudSaveOptions)?void 0:t.call(o,e))??{title:o.title||"Draft",snapshot:e.state})}return{save:d,saveWithOptions:l,restore:async function(t){await s();const e=i(),o=await e.restore(t);return await n.setState(o.snapshot,{source:"cloud-history"}),o},scheduleAutoSave:function(t){const e=o.autoSaveDebounceMs??1500;let n=null;return{trigger(){n&&clearTimeout(n),n=setTimeout(()=>{n=null,d().then(e=>{null==t||t(e)})},e)},dispose(){n&&(clearTimeout(n),n=null)}}}}}({sdk:e,runtime:this._runtime,config:n,element:this}):void 0,this._historyController=e.history?function(t){const{sdk:e,runtime:n,config:o,element:a}=t;function i(){if(!e.history)throw new Error("[generator-workbench] sdk.history is required for history actions");return e.history}function r(t){return{sdk:e,runtime:n,element:a,itemId:t}}return{loadList:async t=>i().getList(t),async restoreItem(t){var e,a;const s=r(t),l=i();await(null==(e=o.onBeforeHistoryRestore)?void 0:e.call(o,s));const d=await l.getDetail(t);return await n.setState(d.snapshot,{source:"cloud-history"}),await(null==(a=o.onAfterHistoryRestore)?void 0:a.call(o,d,s)),d},async deleteItem(t){var e,n;const a=r(t),s=i();return await(null==(e=o.onBeforeHistoryDelete)?void 0:e.call(o,a)),await s.delete(t),await(null==(n=o.onAfterHistoryDelete)?void 0:n.call(o,a)),{itemId:t}}}}({sdk:e,runtime:this._runtime,config:n,element:this}):void 0,this._runtimeController=function(t){const{runtime:e}=t;let n=null,o=null;async function a(t,n){null==o||o.unmount(),o=await Promise.resolve(e.mount({mode:"embed",target:"panel",container:t,panelFilter:n}))}return{mountWorkspace:async function(t){null==n||n.unmount(),null==o||o.unmount(),n=await Promise.resolve(e.mount({mode:"full",target:"full",container:t})),o=null},mountCanvas:async function(t){null==n||n.unmount(),n=await Promise.resolve(e.mount({mode:"embed",target:"canvas",container:t}))},mountPanel:a,async remountPanel(t,e){await a(t,e)},async unmountAll(){null==n||n.unmount(),null==o||o.unmount(),n=null,o=null}}}({runtime:this._runtime}))}bindShellCallbacks(){if(!this._shellContext)return;const{callbacks:t}=this._shellContext;t.onLogin=()=>{this.handleLogin()},t.onOpenInvitation=()=>{this.handleInvitationEntry()},t.onLogout=()=>{this.handleLogout()},t.onImportTemplate=()=>{this.requireRefs().templateFileInput.click()},t.onExportTemplate=()=>{this.openTemplateExportDialog()},t.onCloseTemplateDialog=()=>{this.closeTemplateExportDialog()},t.onToggleTemplateDialog=t=>{t||this.closeTemplateExportDialog()},t.onToggleTemplateField=(t,e)=>{this.toggleTemplateExportField(t,e)},t.onConfirmTemplateExport=()=>{var t;this.exportTemplateWithFields((null==(t=this._shellContext)?void 0:t.state.templateSelectedFieldPaths)||[])},t.onExportSvg=()=>{this.exportSvg()},t.onOpenInStudio=()=>{this.openInStudio()},t.onSaveCloud=()=>{this.saveToCloud()},t.onOpenHistory=()=>{this.openHistoryDialog()},t.onCloseHistory=()=>{this.closeHistoryDialog()},t.onRestoreHistory=t=>{this.restoreHistoryItem(t)},t.onDeleteHistory=t=>{this.deleteHistoryItem(t)},t.onFileChange=t=>{var e;const n=t.target,o=null==(e=n.files)?void 0:e[0];o&&(this.importTemplate(o),n.value="")}}openTemplateExportDialog(){try{if(!this._shellContext)return;const t=this.requireTemplateController().prepareTemplateExport();this._shellContext.state.templateFieldGroups=t.fieldGroups.map(t=>({...t,fields:t.fields.map(t=>({...t}))})),this._shellContext.state.templateSelectedFieldPaths=[...t.selectedFieldPaths],this._shellContext.state.templateDialogOpen=!0}catch(t){this.handleError("template",t)}}closeTemplateExportDialog(){this._shellContext&&(this._shellContext.state.templateDialogOpen=!1,this._shellContext.state.templateFieldGroups=[],this._shellContext.state.templateSelectedFieldPaths=[])}async openHistoryDialog(){this._shellContext&&(this._state.historyDrawerOpen=!0,this._shellContext.state.historyDialogOpen=!0),await this.loadHistory()}closeHistoryDialog(){this._state.historyDrawerOpen=!1,this._shellContext&&(this._shellContext.state.historyDialogOpen=!1)}toggleTemplateExportField(t,e){if(!this._shellContext)return;const n=new Set(this._shellContext.state.templateSelectedFieldPaths);e?n.add(t):n.delete(t),this._shellContext.state.templateSelectedFieldPaths=Array.from(n)}async applyTemplatePayload(t){if(!this._runtime)throw new Error("[generator-workbench] runtime is required for template bridge actions");if(!this._sdk)throw new Error("[generator-workbench] sdk is required for template bridge actions");let e;if(await this._sdk.template.applyToRuntime(this._runtime,t,{onPanelFilter:t=>{e=t}}),e&&(this._state.activePanelFilter=e,this._runtimeController&&!et(this._config))){const t=this.requireRefs().panelHost;if(!t)throw new Error("[generator-workbench] panel host is required for template bridge actions");await this._runtimeController.remountPanel(t,e)}return{template:t,panelFilter:e}}async tryResolveIframeBridgeFile(t,e,n){try{if(!this._runtime)return;return await V({action:t,sdk:e,runtime:this._runtime,config:n,element:this})}catch{return}}bindAuthState(){var t;const e=this.requireAuthController();null==(t=this._cleanupAuth)||t.call(this),this._cleanupAuth=e.subscribe(t=>{this._state.authStatus=t,this.syncAuthUI(),this.syncBillingState(t),p(this,"auth-change",t)}),this.bindBillingSubscriptions()}bindIframeBridge(){var t,e,n;if(null==(t=this._iframeBridge)||t.dispose(),this._iframeBridge=void 0,"embed"!==nt()||!this._runtime)return;const o=this._sdk;if(!o)return;const a=this._config,i=this._runtime;this._iframeBridge=G({targetOrigin:(null==(e=a.embedBridge)?void 0:e.targetOrigin)||"*",validateOrigin:null==(n=a.embedBridge)?void 0:n.validateOrigin,handlers:{getGeneratorData:async()=>{const t=i.getState(),e=await W({sdk:o,runtime:i,config:a,element:this}),n=await this.tryResolveIframeBridgeFile("cover",o,a);return{info:t,cover:(null==n?void 0:n.base64)||"",originImageUrl:e}},setGeneratorData:async t=>{const e=t.info&&"object"==typeof t.info&&!Array.isArray(t.info)?t.info:t;await i.setState(e,{source:"iframe-bridge",originImageUrl:"string"==typeof t.originImageUrl?t.originImageUrl:""})},loadTemplateData:async t=>{const e=t.template&&"object"==typeof t.template&&!Array.isArray(t.template)?t.template:t;if(!e||"object"!=typeof e||Array.isArray(e))throw new Error("Template payload is empty");return{template:(await this.applyTemplatePayload(e)).template}},getTemplateData:async()=>{const t=this.requireTemplateController().buildTemplate(),e=i.getState(),n=await W({sdk:o,runtime:i,config:a,element:this}),r=await this.tryResolveIframeBridgeFile("cover",o,a);return{template:t,info:e,cover:(null==r?void 0:r.base64)||"",originImageUrl:n}},getFile:async t=>V({action:t,sdk:o,runtime:i,config:a,element:this})}})}bindAutoSave(){var t,e,n;const o=this.getEffectiveSdk(),a=this.getEffectiveConfig();null==(t=this._cleanupRuntimeSubscription)||t.call(this),this._cleanupRuntimeSubscription=void 0,null==(e=this._cloudAutoSaveScheduler)||e.dispose(),this._cloudAutoSaveScheduler=void 0,a.autoSaveEnabled&&(null==(n=this._runtime)?void 0:n.subscribe)&&(null==o?void 0:o.cloud)&&(this._cloudAutoSaveScheduler=this.requireCloudController().scheduleAutoSave(t=>{this._state.cloudRecordId=t.id,this._state.lastSavedAt=Date.now(),this._state.saveError=null}),this._cleanupRuntimeSubscription=this._runtime.subscribe(()=>{var t;null==(t=this._cloudAutoSaveScheduler)||t.trigger()}))}bindRuntimeCloudSaveEvent(){const t=this.getEffectiveSdk(),e=this.getEffectiveConfig();this.removeEventListener("runtime-cloud-save-request",this.handleRuntimeCloudSaveRequest),e.cloudEnabled&&(null==t?void 0:t.cloud)&&this.addEventListener("runtime-cloud-save-request",this.handleRuntimeCloudSaveRequest)}async initializeCloudRecordFromRoute(){const t=this.getEffectiveSdk();if(!this.getEffectiveConfig().cloudEnabled||!(null==t?void 0:t.cloud))return;const e=this.getRouteCloudRecordId();if(e){try{const t=await this.requireCloudController().restore(e);this._state.cloudRecordId=t.id,this._state.lastSavedAt=t.updatedAt,this._state.saveError=null}catch(o){this._state.saveError=o instanceof Error?o.message:String(o),this.handleError("runtime",o)}return}const n=await this.performCloudSave(void 0,{emitEvents:!1});n&&this.setRouteCloudRecordId(n.id)}async performCloudSave(t,e={}){var n;const{emitEvents:o=!0}=e;try{this._state.busy.cloudSave=!0,this._shellContext&&(this._shellContext.state.cloudSaveLoading=!0);const e=(null==t?void 0:t.snapshot)??(null==(n=this._runtime)?void 0:n.getState())??{};o&&p(this,"cloud-save-start",{state:e});const a=t?await this.requireCloudController().saveWithOptions(t):await this.requireCloudController().save();return this._state.cloudRecordId=a.id,this._state.lastSavedAt=Date.now(),this._state.saveError=null,o&&p(this,"cloud-saved",{result:a}),a}catch(a){return this._state.saveError=a instanceof Error?a.message:String(a),void this.handleError("runtime",a)}finally{this._state.busy.cloudSave=!1,this._shellContext&&(this._shellContext.state.cloudSaveLoading=!1)}}getRouteCloudRecordId(){const t=new URLSearchParams(window.location.search).get("gid"),e=Number(t);return Number.isInteger(e)&&e>0?e:null}setRouteCloudRecordId(t){const e=new URL(window.location.href);e.searchParams.set("gid",String(t)),window.history.replaceState(window.history.state,"",`${e.pathname}${e.search}${e.hash}`)}bindBillingSubscriptions(){var t,e;const n=this.getEffectiveSdk();null==(t=this._cleanupCredits)||t.call(this),this._cleanupCredits=void 0,null==(e=this._cleanupBilling)||e.call(this),this._cleanupBilling=void 0;const o=null==n?void 0:n.credits;"function"==typeof(null==o?void 0:o.onChange)&&(this._cleanupCredits=o.onChange(t=>{this._state.creditsBalance=Number(t)||0,this.syncBillingUI()}));const a=null==n?void 0:n.billing;"function"==typeof(null==a?void 0:a.onChange)&&(this._cleanupBilling=a.onChange(t=>{this.applyBillingUsage(t)}))}syncAuthUI(){var t,e,n,o,a,i,r,s;if(!this._shellContext)return;const{state:l}=this._shellContext,{isLogin:d,userInfo:c}=this._state.authStatus,u=(null==(t=null==c?void 0:c.userName)?void 0:t.trim())||(null==(e=null==c?void 0:c.email)?void 0:e.trim())||(null==(n=null==c?void 0:c.phoneNumber)?void 0:n.trim())||"",p=u?u.charAt(0).toUpperCase():"U",h=(null==(o=null==c?void 0:c.email)?void 0:o.trim())||((null==c?void 0:c.phoneNumber)?`${c.phoneZone||""}${c.phoneNumber}`:"Connected to Generator SDK"),m="function"==typeof(null==(i=null==(a=this._sdk)?void 0:a.auth)?void 0:i.getToken)?this._sdk.auth.getToken():"",g=u||"Generator User",v=(null==(r=null==c?void 0:c.email)?void 0:r.trim())||(null==(s=null==c?void 0:c.phoneNumber)?void 0:s.trim())||g.toLowerCase().replace(/\s+/g,"-");l.isLogin=d,l.avatarSrc=d&&(null==c?void 0:c.headpic)||"",l.avatarText=p,l.authDisplayName=u,l.authSubline=d?h:"",l.authToken=d?m:"",l.atommProUser=d?{id:null==c?void 0:c.uid,userName:g,userHandle:v,avatar:(null==c?void 0:c.headpic)||""}:{userName:"",userHandle:"",avatar:""}}syncBillingUI(){if(!this._shellContext)return;const{state:t}=this._shellContext,e=this._state.billingUsage;t.creditsEnabled=!1!==this.getEffectiveConfig().creditsEnabled,t.creditsBalance=this._state.creditsBalance,t.showExportCreditsHint=Boolean(this._state.authStatus.isLogin&&(null==e?void 0:e.isEnabled)),t.showExportCreditsIcon=Boolean(t.showExportCreditsHint&&!(null==e?void 0:e.inFreePeriod)&&((null==e?void 0:e.freeRemaining)??0)<=0),t.exportCreditsHintText=this.resolveExportCreditsHintText(e)}syncInvitationConfigKey(){var t,e,n,o;if(!this._shellContext)return;const a=null==(t=this._config.invitationConfigKey)?void 0:t.trim(),i=null==(o=null==(n=null==(e=this._sdk)?void 0:e.getAppKey)?void 0:n.call(e))?void 0:o.trim(),r=i?`generator_${i}`:"";this._shellContext.state.invitationConfigKey=a||r||"default"}syncHistoryUI(){if(!this._shellContext)return;const{state:t}=this._shellContext;t.historyDialogOpen=this._state.historyDrawerOpen,t.historyItems=this._state.historyItems.map(t=>({...t})),t.historyError=this._state.historyError||""}applyBillingUsage(t){const e=this.applyPersistedBillingUsage(t);this._state.billingUsage=e,e&&"number"==typeof e.creditsBalance&&(this._state.creditsBalance=e.creditsBalance),this.persistBillingCountdown(e),this.syncBillingUI(),this.syncBillingCountdown()}resetBillingState(){this.clearBillingCountdownTimer(),function(t){const e=a(t);if(e)try{localStorage.removeItem(e)}catch{}}(this.getSdkAppKey()),this._state.creditsBalance=0,this._state.billingUsage=null,this.syncBillingUI()}getSdkAppKey(){var t,e,n;return(null==(n=null==(e=null==(t=this._sdk)?void 0:t.getAppKey)?void 0:e.call(t))?void 0:n.trim())||null}applyPersistedBillingUsage(t){return s(t,this.getSdkAppKey())}persistBillingCountdown(t){!function(t,e,n=Date.now()){const o=a(t);if(o)try{if(e>0)return void localStorage.setItem(o,String(n+1e3*e));localStorage.removeItem(o)}catch{}}(this.getSdkAppKey(),(null==t?void 0:t.inFreePeriod)?t.freePeriodRemaining:0)}resolveExportCreditsHintText(t){return this._state.authStatus.isLogin&&(null==t?void 0:t.isEnabled)?t.inFreePeriod?`${t.freePeriodRemaining}s`:t.freeRemaining>0?`${t.freeRemaining}/${t.freeTotal}`:String(t.creditsPerUse):""}clearBillingCountdownTimer(){this._billingCountdownTimer&&(clearInterval(this._billingCountdownTimer),this._billingCountdownTimer=null)}syncBillingCountdown(){var t;this.clearBillingCountdownTimer(),this._state.authStatus.isLogin&&(null==(t=this._state.billingUsage)?void 0:t.inFreePeriod)&&(this._billingCountdownTimer=setInterval(()=>{var t,e,n,o;const a=this.getSdkAppKey(),s=r(a),l=i(a),d=null==(n=null==(e=null==(t=this._sdk)?void 0:t.billing)?void 0:e.getCachedUsage)?void 0:n.call(e);l&&(null==(o=this._state.billingUsage)?void 0:o.isEnabled)?this._state.billingUsage={...this._state.billingUsage,inFreePeriod:!0,freePeriodRemaining:s}:d&&(this._state.billingUsage=this.applyPersistedBillingUsage(d)),this._state.billingUsage&&"number"==typeof this._state.billingUsage.creditsBalance&&(this._state.creditsBalance=this._state.billingUsage.creditsBalance),this.syncBillingUI(),l&&s>0||d&&d.inFreePeriod||this.clearBillingCountdownTimer()},1e3))}async syncBillingState(t=this._state.authStatus){var e,n,o,a,i,r,s,l;const d=this.getEffectiveSdk();if(!t.isLogin||!d)return void this.resetBillingState();if(!d.credits&&!d.billing)return void this.resetBillingState();const c=null==(n=null==(e=d.credits)?void 0:e.getCachedBalance)?void 0:n.call(e);"number"==typeof c&&(this._state.creditsBalance=c);const u=null==(a=null==(o=d.billing)?void 0:o.getCachedUsage)?void 0:a.call(o);u?this.applyBillingUsage(u):this.syncBillingUI();try{const[t,e]=await Promise.all([null==(r=null==(i=d.credits)?void 0:i.getBalance)?void 0:r.call(i),null==(l=null==(s=d.billing)?void 0:s.getUsage)?void 0:l.call(s)]);if("number"==typeof(null==t?void 0:t.quota)&&(this._state.creditsBalance=t.quota),e)return void this.applyBillingUsage(e);this.syncBillingUI()}catch(p){this.handleError("auth",p)}}getEffectiveConfig(){return"embed"!==nt()?this._config:{...this._config,invitationEnabled:!1,cloudEnabled:!1,historyEnabled:!1,autoSaveEnabled:!1,creditsEnabled:!1,shellChromeVisible:!1}}getEffectiveSdk(){return this._sdk?"embed"!==nt()?this._sdk:{...this._sdk,credits:void 0,billing:void 0,cloud:void 0,history:void 0}:null}async handleLogin(){try{this._state.busy.login=!0,this._shellContext&&(this._shellContext.state.loginLoading=!0),await this.requireAuthController().login()}catch(t){this.handleError("auth",t)}finally{this._state.busy.login=!1,this._shellContext&&(this._shellContext.state.loginLoading=!1)}}async handleInvitationEntry(){var t;try{if(!this._state.authStatus.isLogin){await this.handleLogin();const t=this.requireAuthController().getStatus();t.isLogin&&(this._state.authStatus=t,this.syncAuthUI(),this.syncBillingState(t))}if(!this.requireAuthController().getStatus().isLogin)return;null==(t=this._shellContext)||t.openInvitationModal()}catch(e){this.handleError("auth",e)}}async handleLogout(){try{await this.requireAuthController().logout()}catch(t){this.handleError("auth",t)}}handleError(t,e){var n,o;const a=e instanceof Error?e:new Error(String(e));null==(o=(n=this._config).onError)||o.call(n,a,t),p(this,"workbench-error",{source:t,error:a})}requireRefs(){if(!this._shellContext)throw new Error("[generator-workbench] shell context is not ready");return this._shellContext.refs}requireAuthController(){if(!this._authController)throw new Error("[generator-workbench] auth controller is not ready");return this._authController}requireTemplateController(){if(!this._templateController)throw new Error("[generator-workbench] template controller is not ready");return this._templateController}requireExportController(){if(!this._exportController)throw new Error("[generator-workbench] export controller is not ready");return this._exportController}requireCloudController(){if(!this._cloudController)throw new Error("[generator-workbench] cloud controller is not ready");return this._cloudController}requireHistoryController(){if(!this._historyController)throw new Error("[generator-workbench] history controller is not ready");return this._historyController}}const at="generator-workbench";t.GENERATOR_WORKBENCH_TAG_NAME=at,t.GeneratorWorkbenchElement=ot,t.defineGeneratorWorkbench=function(t=at){const e=customElements.get(t);return e||(customElements.define(t,ot),ot)},Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atomm-developer/generator-workbench",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Unified generator shell based on Web Components",
5
5
  "keywords": [
6
6
  "atomm",