@goodandready/dsh-subscriptions 0.6.70 โ†’ 0.6.72

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/lib/client.js CHANGED
@@ -4,6 +4,7 @@ window.__ModuleLoader__.load({
4
4
  var module = { exports: {} }
5
5
  var exports = module.exports
6
6
  const React = require('react')
7
+ const h = React.createElement
7
8
 
8
9
  // Modular translator: shared by component subscriptions and helpers.
9
10
  let t = (key) => key
@@ -22,12 +23,12 @@ window.__ModuleLoader__.load({
22
23
  }
23
24
  render() {
24
25
  if (this.state.hasError) {
25
- return React.createElement(
26
+ return h(
26
27
  "div",
27
28
  { style: { padding: "12px", border: "1px solid var(--dsw-alias-state-error-primary)", borderRadius: "8px", background: "var(--dsw-alias-bg-layer-2)", margin: "8px 0", fontSize: "13px" } },
28
- React.createElement("div", { style: { fontWeight: 600, color: "var(--dsw-alias-state-error-primary)", marginBottom: "4px" } }, "Subscriptions UI error"),
29
- React.createElement("div", { style: { color: "var(--dsw-alias-label-secondary)", fontSize: "12px", marginBottom: "8px" } }, String(this.state.error && this.state.error.message || this.state.error || "Unknown error")),
30
- React.createElement("button", {
29
+ h("div", { style: { fontWeight: 600, color: "var(--dsw-alias-state-error-primary)", marginBottom: "4px" } }, "Subscriptions UI error"),
30
+ h("div", { style: { color: "var(--dsw-alias-label-secondary)", fontSize: "12px", marginBottom: "8px" } }, String(this.state.error && this.state.error.message || this.state.error || "Unknown error")),
31
+ h("button", {
31
32
  className: "dsub-mini",
32
33
  onClick: () => this.setState({ hasError: false, error: null })
33
34
  }, "Retry")
@@ -39,168 +40,8 @@ window.__ModuleLoader__.load({
39
40
 
40
41
 
41
42
  const CSS =
42
- '.dsub-card{list-style:none;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;transition:border-color .16s,background .16s}' +
43
- '.dsub-card:hover{border-color:var(--dsw-alias-label-dimmed)}' +
44
- '.dsub-cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}' +
45
- '.dsub-header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}' +
46
- '.dsub-header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}' +
47
- '.dsub-headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}' +
48
- '.dsub-name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}' +
49
- '.dsub-description{color:var(--dsw-alias-label-secondary);font-size:13px}' +
50
- '.dsub-chev{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}' +
51
- '.dsub-chevOpen{transform:rotate(180deg)}' +
52
- '.dsub-body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:12px}' +
53
- '.dsub-block{margin-top:10px}' +
54
- '.dsub-group{margin-top:12px;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;padding:0 14px}' +
55
- '.dsub-group[open]{padding-bottom:6px}' +
56
- '.dsub-groupHead{cursor:pointer;font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);padding:10px 0;list-style:none}' +
57
- '.dsub-groupHead::-webkit-details-marker{display:none}' +
58
- '.dsub-row{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin-top:8px}' +
59
- '.dsub-grow{flex:1 1 180px;min-width:140px}' +
60
- '.dsub-helpBox{margin-top:8px;padding:12px 14px;border-radius:8px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);font-size:12px;line-height:1.6}' +
61
- '.dsub-helpHead{display:flex;align-items:center;justify-content:space-between;font-weight:600;margin-bottom:8px;color:var(--dsw-alias-brand-primary)}' +
62
- '.dsub-helpStep{margin-bottom:6px;color:var(--dsw-alias-label-primary)}' +
63
- '.dsub-btnActive{background:var(--dsw-alias-brand-primary);color:var(--dsw-alias-label-primary-foreground);border-color:var(--dsw-alias-brand-primary)}' +
64
- '.dsub-h{font-size:13.5px;font-weight:600;color:var(--dsw-alias-label-primary)}' +
65
- '.dsub-sub{font-size:12px;color:var(--dsw-alias-label-secondary)}' +
66
- '.dsub-dim{font-size:11.5px;color:var(--dsw-alias-label-tertiary)}' +
67
- '.dsub-mini{appearance:none;font:inherit;font-size:12px;cursor:pointer;border:1px solid var(--dsw-alias-border-l2);border-radius:6px;padding:3px 8px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);transition:all .15s}' +
68
- '.dsub-mini:hover{background:var(--dsw-alias-bg-layer-1);border-color:var(--dsw-alias-label-dimmed)}' +
69
- '.dsub-ok{font-size:12px;color:var(--dsw-alias-state-success-primary)}' +
70
- '.dsub-bad{font-size:12px;color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;word-break:break-word;max-width:100%}' +
71
- '.dsub-hint{overflow-wrap:anywhere;word-break:break-word;max-width:100%}' +
72
- '.dsub-btn{appearance:none;font:inherit;cursor:pointer;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:5px 12px;font-size:12.5px;font-weight:500;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);transition:all .15s}' +
73
- '.dsub-btn:hover{background:var(--dsw-alias-bg-layer-1);border-color:var(--dsw-alias-label-dimmed)}' +
74
- '.dsub-inp{height:30px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);border-radius:6px;padding:0 8px;font-size:12px;min-width:180px}' +
75
- '.dsub-inp:focus{outline:none;border-color:var(--dsw-alias-brand-primary)}' +
76
- '.dsub-box{border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:10px;margin-top:8px;background:var(--dsw-alias-bg-layer-2)}' +
77
- '.dsub-cooldown{display:inline-block;padding:2px 6px;border-radius:4px;background:var(--dsw-alias-state-warn-primary);color:var(--dsw-alias-bg-layer-1);font-size:11px;font-weight:600}' +
78
- '.dsub-bar{position:relative;height:6px;border-radius:3px;background:var(--dsw-alias-bg-layer-1);overflow:hidden;flex:1;min-width:80px}' +
79
- '.dsub-barFill{height:100%;border-radius:3px;background:var(--dsw-alias-state-success-primary);transition:width .2s}' +
80
- '.dsub-barWarn .dsub-barFill{background:var(--dsw-alias-state-warn-primary)}' +
81
- '.dsub-barFull .dsub-barFill{background:var(--dsw-alias-state-error-primary)}' +
82
- '.dsub-barRow{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--dsw-alias-label-secondary)}' +
83
- '.dsub-manual{display:flex;flex-direction:column;gap:6px;margin-top:4px;padding-top:10px;border-top:1px solid var(--dsw-alias-border-l2)}' +
84
- '.dsub-verify{font-size:12px;color:var(--dsw-alias-state-warn-primary)}' +
85
- '.dsub-verify a{color:var(--dsw-alias-brand-primary)}' +
86
- '.dsub-pill{display:inline-flex;align-items:center;gap:7px;height:28px;padding:0 11px;border:1px solid var(--dsw-alias-border-l2);border-radius:999px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font-size:12px;font-weight:600;cursor:pointer;box-shadow:0 1px 3px color-mix(in srgb, black 15%, transparent),inset 0 1px 0 color-mix(in srgb, white 6%, transparent);transition:all .16s ease;user-select:none}' +
87
- '.dsub-pill:hover{background:var(--dsw-alias-bg-layer-3);border-color:var(--dsw-alias-label-tertiary);transform:translateY(-1px);box-shadow:0 3px 8px color-mix(in srgb, black 25%, transparent),inset 0 1px 0 color-mix(in srgb, white 10%, transparent)}' +
88
- '.dsub-pill:active{transform:translateY(0)}' +
89
- '.dsub-pillTag{padding:1px 5px;border-radius:4px;font-size:10.5px;font-weight:700;letter-spacing:.02em;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary)}' +
90
- '.dsub-led{width:7px;height:7px;border-radius:50%;flex:none;transition:all .2s ease}' +
91
- '.dsub-ledOk{background:var(--dsw-alias-state-success-primary);box-shadow:0 0 6px color-mix(in srgb,var(--dsw-alias-state-success-primary) 70%,transparent)}' +
92
- '.dsub-ledWarn{background:var(--dsw-alias-state-warn-primary);box-shadow:0 0 6px color-mix(in srgb,var(--dsw-alias-state-warn-primary) 70%,transparent)}' +
93
- '.dsub-ledBad{background:var(--dsw-alias-state-error-primary);box-shadow:0 0 6px color-mix(in srgb,var(--dsw-alias-state-error-primary) 70%,transparent)}' +
94
- '.dsub-ledOff{background:var(--dsw-alias-label-tertiary)}' +
95
- '.dsub-toast-container{position:fixed;top:16px;right:16px;z-index:10030;display:flex;flex-direction:column;gap:8px;pointer-events:none}' +'.dsub-toast{pointer-events:auto;min-width:280px;max-width:400px;padding:10px 14px;border-radius:10px;background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);border:1px solid var(--dsw-alias-border-l1);box-shadow:0 8px 24px color-mix(in srgb,black 40%,transparent);display:flex;align-items:center;justify-content:space-between;gap:10px;font-size:12px;line-height:1.4;animation:dsubFadeIn .2s ease-out}' +'.dsub-toast-warn{border-color:var(--dsw-alias-state-warn-primary)}' +'.dsub-toast-bad{border-color:var(--dsw-alias-state-error-primary)}' +'.dsub-toast-ok{border-color:var(--dsw-alias-state-success-primary)}' +'.dsub-toast-close{background:none;border:none;color:var(--dsw-alias-label-tertiary);cursor:pointer;font-size:14px;padding:0 2px}' +'.dsub-toast-close:hover{color:var(--dsw-alias-label-primary)}' +
96
- '.dsub-modalWrap{position:fixed;inset:0;z-index:10020;display:grid;place-items:center;background:color-mix(in srgb, black 65%, transparent);backdrop-filter:blur(10px);animation:dsubFadeIn .16s ease-out}' +
97
- '.dsub-modal{width:min(520px,94vw);max-height:min(85vh,720px);overflow-y:auto;border:1px solid var(--dsw-alias-border-l1);border-radius:16px;background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);box-shadow:0 24px 64px color-mix(in srgb, black 60%, transparent),0 0 0 1px color-mix(in srgb, white 7%, transparent);padding:20px;animation:dsubScaleIn .18s cubic-bezier(.16,1,.3,1)}' +
98
- '@keyframes dsubFadeIn{from{opacity:0}to{opacity:1}}' +
99
- '@keyframes dsubScaleIn{from{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}' +
100
- '.dsub-modalHead{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-bottom:14px;border-bottom:1px solid var(--dsw-alias-border-l2)}' +
101
- '.dsub-modalTitleWrap{display:flex;align-items:center;gap:10px}' +
102
- '.dsub-modalIcon{width:30px;height:30px;border-radius:8px;background:var(--dsw-alias-bg-layer-1);display:grid;place-items:center;color:var(--dsw-alias-brand-primary);font-size:14px}' +
103
- '.dsub-modalBadge{font-size:11px;font-weight:600;padding:2px 7px;border-radius:10px;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary)}' +
104
- '.dsub-heroCard{margin-top:14px;padding:14px 16px;border-radius:12px;background:linear-gradient(135deg,var(--dsw-alias-bg-layer-2) 0%,var(--dsw-alias-bg-layer-3) 100%);border:1px solid var(--dsw-alias-border-l1);box-shadow:inset 0 1px 0 color-mix(in srgb, white 5%, transparent)}' +
105
- '.dsub-heroHead{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}' +
106
- '.dsub-heroTitle{font-size:14px;font-weight:700;display:flex;align-items:center;gap:6px}' +
107
- '.dsub-heroModel{font-size:11.5px;color:var(--dsw-alias-label-secondary);font-family:ui-monospace,monospace}' +
108
- '.dsub-select{appearance:none;height:30px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);border-radius:6px;padding:0 24px 0 8px;font-size:12px;cursor:pointer}' +
109
- '.dsub-details{margin-top:12px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:8px 12px;background:var(--dsw-alias-bg-layer-2)}' +
110
- '.dsub-summary{cursor:pointer;font-weight:600;font-size:12.5px;color:var(--dsw-alias-label-secondary);user-select:none}' +
111
- '.dsub-summary:hover{color:var(--dsw-alias-label-primary)}' +
112
- '.dsub-header-bar{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px;padding:8px 0 12px;margin-bottom:8px;border-bottom:1px solid var(--dsw-alias-border-l2)}' +
113
- '.dsub-badge{font-size:12px;padding:3px 10px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2);display:inline-flex;align-items:center;gap:5px;font-weight:500}' +
114
- '.dsub-badge-ok{border-color:var(--dsw-alias-state-success-primary);color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 10%,transparent)}' +
115
- '.dsub-badge-warn{border-color:var(--dsw-alias-state-warn-primary);color:var(--dsw-alias-state-warn-primary);background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 10%,transparent)}' +
116
- '.dsub-badge-bad{border-color:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent)}' +
117
- '.dsub-badge-neutral{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2)}' +
118
- '.dsub-section-card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;padding:14px 16px;display:flex;flex-direction:column;gap:10px;margin-top:12px}' +
119
- '.dsub-section-title{font-size:14.5px;font-weight:600;color:var(--dsw-alias-label-primary);display:flex;align-items:center;justify-content:space-between;gap:8px}' +
120
- '.dsub-section-desc{font-size:12px;color:var(--dsw-alias-label-secondary);margin-top:-4px;line-height:1.4}' +
121
- '.dsub-grid-2{display:grid;grid-template-columns:repeat(auto-fit, minmax(200px, 1fr));gap:10px}' +
122
- '.dsub-stat-box{padding:10px 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-2);display:flex;flex-direction:column;gap:3px}' +
123
- '.dsub-stat-val{font-size:16.5px;font-weight:700;color:var(--dsw-alias-label-primary)}' +
124
- '.dsub-stat-lbl{font-size:11.5px;color:var(--dsw-alias-label-secondary)}' +
125
- '.dsub-chart-wrap{display:flex;align-items:flex-end;gap:3px;height:52px;padding:6px 0;margin-top:8px;border-bottom:1px solid var(--dsw-alias-border-l3)}' +
126
- '.dsub-chart-bar{flex:1;background:var(--dsw-alias-brand-primary);border-radius:2px 2px 0 0;min-height:3px;transition:height .2s ease;opacity:0.85;cursor:pointer}' +
127
- '.dsub-chart-bar:hover{opacity:1;background:var(--dsw-alias-state-success-primary)}' +
128
- '.dsub-chart-labels{display:flex;justify-content:space-between;font-size:10px;color:var(--dsw-alias-label-secondary);margin-top:3px}' +
129
- '.dsub-alert-ok{padding:8px 12px;border-radius:8px;background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 10%,transparent);color:var(--dsw-alias-state-success-primary);font-size:12.5px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-success-primary) 25%,transparent)}' +
130
- '.dsub-alert-bad{padding:8px 12px;border-radius:8px;background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary);font-size:12.5px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary) 25%,transparent)}' +
131
- '.dsub-btn-primary{background:var(--dsw-alias-label-primary) !important;color:var(--dsw-alias-bg-layer-3) !important;border-color:transparent !important;font-weight:600}' +
132
- '.dsub-btn-primary:hover:not(:disabled){opacity:0.9}' +
133
- '.dsub-model-grid{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}' +
134
- '.dsub-model-chip{display:inline-flex;align-items:center;gap:6px;padding:3px 8px;border-radius:6px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);font-size:11.5px;color:var(--dsw-alias-label-primary)}' +
135
- '.dsub-model-chip code{font-family:ui-monospace,monospace;font-weight:600}' +
136
- '.dsub-model-tag{font-size:10px;padding:1px 4px;border-radius:3px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary);font-weight:600}' +
137
- '.dsub-trace-box{padding:8px 12px;border-radius:8px;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);margin-top:8px;font-size:12px}' +
138
- '.dsub-trace-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:4px 0;border-bottom:1px solid var(--dsw-alias-border-l3)}' +
139
- '.dsub-trace-row:last-child{border-bottom:none}' +
140
- '.dsub-model-status-available{color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 12%,transparent)}' +
141
- '.dsub-model-status-degraded{color:var(--dsw-alias-state-warn-primary);background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 12%,transparent)}' +
142
- '.dsub-model-status-quarantined{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 12%,transparent)}' +
143
- '.dsub-model-status-cooldown{color:var(--dsw-alias-state-business-primary);background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 12%,transparent)}' +
144
- '.dsub-model-status-exhausted{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 12%,transparent)}' +
145
- '.dsub-model-status-unconfigured{color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-layer-3)}' +
146
- '.dsub-heroBars{display:flex;flex-direction:column;gap:8px;margin-top:10px}' +
147
- '.dsub-barLabelRow{display:flex;justify-content:space-between;font-size:11.5px;color:var(--dsw-alias-label-secondary);margin-bottom:3px}' +
148
- '.dsub-barTrack{height:6px;border-radius:3px;background:var(--dsw-alias-bg-layer-1);overflow:hidden}' +
149
- '.dsub-barFillGrad{height:100%;border-radius:3px;transition:width .3s ease}' +
150
- '.dsub-panel-box{margin-top:10px;padding:12px 14px;border-radius:10px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);display:flex;flex-direction:column;gap:8px}' +
151
- '.dsub-panel-warn{border-color:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 40%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 5%,transparent)}' +
152
- '.dsub-panel-title{font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);display:flex;align-items:center;justify-content:space-between}' +
153
- '.dsub-panel-desc{font-size:12px;color:var(--dsw-alias-label-secondary);line-height:1.4}' +
154
- '.dsub-usage-grid{display:flex;flex-direction:column;gap:8px;margin-top:4px}' +
155
- '.dsub-usage-card{display:flex;flex-direction:column;gap:5px;padding:8px 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-1)}' +
156
- '.dsub-usage-head{display:flex;justify-content:space-between;align-items:center;font-size:12px;font-weight:500;color:var(--dsw-alias-label-primary)}' +
157
- '.dsub-usage-track{width:100%;height:8px;border-radius:999px;background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);overflow:hidden}' +
158
- '.dsub-usage-fill{height:100%;border-radius:999px;transition:width .3s ease}' +
159
- '.dsub-usage-meta{display:flex;justify-content:space-between;align-items:center;font-size:11px;color:var(--dsw-alias-label-secondary)}' +
160
- '.dsub-tag-ok{border-color:color-mix(in srgb,var(--dsw-alias-state-success-primary) 30%,transparent);color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 8%,transparent);padding:1px 7px;border-radius:999px;font-size:11px;font-weight:600;border-style:solid;border-width:1px}' +
161
- '.dsub-tag-warn{border-color:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 40%,transparent);color:var(--dsw-alias-state-warn-primary);background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 8%,transparent);padding:1px 7px;border-radius:999px;font-size:11px;font-weight:600;border-style:solid;border-width:1px}' +
162
- '.dsub-tag-bad{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 40%,transparent);color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 8%,transparent);padding:1px 7px;border-radius:999px;font-size:11px;font-weight:600;border-style:solid;border-width:1px}' +
163
- '.dsub-slot-meta-row{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-top:12px;padding-top:10px;border-top:1px solid var(--dsw-alias-border-l2);font-size:12px}' +
164
- '.dsub-ref-tag{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;color:var(--dsw-alias-label-secondary)}' +
165
- '.dsub-ref-tag code{padding:2px 6px;border-radius:4px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);font-family:ui-monospace,monospace;color:var(--dsw-alias-label-primary);font-size:11px}' +
166
- '.dsub-speed-tag{display:inline-flex;align-items:center;gap:4px;font-size:11.5px;color:var(--dsw-alias-brand-primary);background:color-mix(in srgb,var(--dsw-alias-brand-primary) 8%,transparent);padding:2px 8px;border-radius:6px;font-weight:500;border:1px solid color-mix(in srgb,var(--dsw-alias-brand-primary) 20%,transparent)}' +
167
- '.dsub-btn-danger{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 40%,transparent)!important;color:var(--dsw-alias-state-error-primary)!important}' +
168
- '.dsub-btn-danger:hover:not(:disabled){background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 12%,transparent)!important}' +
169
- '.dsub-poolTitle{margin-top:16px;margin-bottom:8px;font-size:11.5px;font-weight:700;color:var(--dsw-alias-label-secondary);text-transform:uppercase;letter-spacing:.05em}' +
170
- '.dsub-accountCard{display:flex;align-items:center;gap:12px;padding:10px 14px;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-alias-bg-layer-2);margin-top:6px;transition:border-color .15s,background .15s}' +
171
- '.dsub-accountCard:hover{background:var(--dsw-alias-bg-layer-3);border-color:var(--dsw-alias-label-tertiary)}' +
172
- '.dsub-brandBadge{width:32px;height:32px;border-radius:8px;display:grid;place-items:center;font-size:12px;font-weight:700;flex-shrink:0}' +
173
- '.dsub-brandCodex{background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 15%,transparent);color:var(--dsw-alias-state-success-primary);border:1px solid color-mix(in srgb,var(--dsw-alias-state-success-primary) 30%,transparent)}' +
174
- '.dsub-brandClaude{background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 15%,transparent);color:var(--dsw-alias-state-warn-primary);border:1px solid color-mix(in srgb,var(--dsw-alias-state-warn-primary) 30%,transparent)}' +
175
- '.dsub-brandGrok{background:color-mix(in srgb,var(--dsw-alias-state-business-primary, var(--dsw-alias-brand-primary)) 15%,transparent);color:var(--dsw-alias-state-business-primary, var(--dsw-alias-brand-primary));border:1px solid color-mix(in srgb,var(--dsw-alias-state-business-primary, var(--dsw-alias-brand-primary)) 30%,transparent)}' +
176
- '.dsub-brandAgy{background:color-mix(in srgb,var(--dsw-alias-brand-primary) 15%,transparent);color:var(--dsw-alias-brand-primary);border:1px solid color-mix(in srgb,var(--dsw-alias-brand-primary) 30%,transparent)}' +
177
- '.dsub-brandOllama{background:color-mix(in srgb,var(--dsw-alias-label-tertiary) 15%,transparent);color:var(--dsw-alias-label-secondary);border:1px solid color-mix(in srgb,var(--dsw-alias-label-tertiary) 30%,transparent)}' +
178
- '.dsub-brandKimi{background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 15%,transparent);color:var(--dsw-alias-state-warn-primary);border:1px solid color-mix(in srgb,var(--dsw-alias-state-warn-primary) 30%,transparent)}' +
179
- '.dsub-brandGlm{background:color-mix(in srgb,var(--dsw-alias-state-business-primary, var(--dsw-alias-brand-primary)) 15%,transparent);color:var(--dsw-alias-state-business-primary, var(--dsw-alias-brand-primary));border:1px solid color-mix(in srgb,var(--dsw-alias-state-business-primary, var(--dsw-alias-brand-primary)) 30%,transparent)}' +
180
- '.dsub-planBadge{display:inline-flex;align-items:center;padding:1px 6px;border-radius:4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:0.5px;background:color-mix(in srgb,var(--dsw-alias-brand-primary) 15%,transparent);color:var(--dsw-alias-brand-primary);border:1px solid color-mix(in srgb,var(--dsw-alias-brand-primary) 30%,transparent);margin-left:6px}' +
181
-
182
- '.dsub-accInfo{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}' +
183
- '.dsub-accNameRow{display:flex;align-items:center;justify-content:space-between;gap:8px}' +
184
- '.dsub-accName{font-size:13px;font-weight:600}' +
185
- '.dsub-accStatusTag{font-size:10.5px;font-weight:600;padding:1px 6px;border-radius:4px}' +
186
- '.dsub-statusOk{background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 15%,transparent);color:var(--dsw-alias-state-success-primary)}' +
187
- '.dsub-statusWarn{background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 15%,transparent);color:var(--dsw-alias-state-warn-primary)}' +
188
- '.dsub-statusBad{background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 15%,transparent);color:var(--dsw-alias-state-error-primary)}' +
189
- '.dsub-statusOff{background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-tertiary)}' +
190
- '.dsub-modalFoot{display:flex;align-items:center;justify-content:space-between;margin-top:16px;padding-top:12px;border-top:1px solid var(--dsw-alias-border-l2)}' +
191
- '.dsub-btnPrimary{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border-radius:8px;font-size:12px;font-weight:600;background:var(--dsw-alias-brand-primary);color:var(--dsw-alias-label-primary-foreground);border:0;cursor:pointer;transition:opacity .15s}' +
192
- '.dsub-btnPrimary:hover{opacity:.9}' +
193
- '.dsub-btnSec{display:inline-flex;align-items:center;gap:5px;padding:5px 10px;border-radius:7px;font-size:11.5px;font-weight:500;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;text-decoration:none;transition:all .15s}' +
194
- '.dsub-btnSec:hover{background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-tertiary)}' +
195
- '.dsub-cq{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--dsw-alias-label-secondary);padding:0 6px}' +
196
- '.dsub-cqBar{position:relative;width:40px;height:5px;border-radius:3px;background:var(--dsw-alias-bg-layer-1);overflow:hidden}' +
197
- '.dsub-cqBarFill{height:100%;border-radius:3px;background:var(--dsw-alias-state-success-primary)}' +
198
- '.dsub-cqBarWarn .dsub-cqBarFill{background:var(--dsw-alias-state-warn-primary)}' +
199
- '.dsub-cqBarFull .dsub-cqBarFill{background:var(--dsw-alias-state-error-primary)}' +
200
- '.dsub-cqB{font-variant-numeric:tabular-nums;font-weight:600;color:var(--dsw-alias-label-primary)}' +
201
- '.dsub-diag{font:11px/1.5 ui-monospace,SFMono-Regular,monospace;max-height:260px;overflow:auto;white-space:pre-wrap;word-break:break-word;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:10px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary)}'
202
-
203
- const cssId = 'dsh-subscriptions/settings.module.css'
43
+ ".dsub-card{list-style:none;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;transition:border-color .16s,background .16s}.dsub-card:hover{border-color:var(--dsw-alias-label-dimmed)}.dsub-cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.dsub-header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.dsub-header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.dsub-headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.dsub-name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.dsub-description{color:var(--dsw-alias-label-secondary);font-size:13px}.dsub-chev{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.dsub-chevOpen{transform:rotate(180deg)}.dsub-body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:12px}.dsub-block{margin-top:10px}.dsub-group{margin-top:12px;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;padding:0 14px}.dsub-group[open]{padding-bottom:6px}.dsub-groupHead{cursor:pointer;font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);padding:10px 0;list-style:none}.dsub-groupHead::-webkit-details-marker{display:none}.dsub-row{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin-top:8px}.dsub-grow{flex:1 1 180px;min-width:140px}.dsub-helpBox{margin-top:8px;padding:12px 14px;border-radius:8px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);font-size:12px;line-height:1.6}.dsub-helpHead{display:flex;align-items:center;justify-content:space-between;font-weight:600;margin-bottom:8px;color:var(--dsw-alias-brand-primary)}.dsub-helpStep{margin-bottom:6px;color:var(--dsw-alias-label-primary)}.dsub-btnActive{background:var(--dsw-alias-brand-primary);color:var(--dsw-alias-label-primary-foreground);border-color:var(--dsw-alias-brand-primary)}.dsub-h{font-size:13.5px;font-weight:600;color:var(--dsw-alias-label-primary)}.dsub-sub{font-size:12px;color:var(--dsw-alias-label-secondary)}.dsub-dim{font-size:11.5px;color:var(--dsw-alias-label-tertiary)}.dsub-mini{appearance:none;font:inherit;font-size:12px;cursor:pointer;border:1px solid var(--dsw-alias-border-l2);border-radius:6px;padding:3px 8px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);transition:all .15s}.dsub-mini:hover{background:var(--dsw-alias-bg-layer-1);border-color:var(--dsw-alias-label-dimmed)}.dsub-ok{font-size:12px;color:var(--dsw-alias-state-success-primary)}.dsub-bad{font-size:12px;color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;word-break:break-word;max-width:100%}.dsub-hint{overflow-wrap:anywhere;word-break:break-word;max-width:100%}.dsub-btn{appearance:none;font:inherit;cursor:pointer;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:5px 12px;font-size:12.5px;font-weight:500;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);transition:all .15s}.dsub-btn:hover{background:var(--dsw-alias-bg-layer-1);border-color:var(--dsw-alias-label-dimmed)}.dsub-inp{height:30px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);border-radius:6px;padding:0 8px;font-size:12px;min-width:180px}.dsub-inp:focus{outline:none;border-color:var(--dsw-alias-brand-primary)}.dsub-box{border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:10px;margin-top:8px;background:var(--dsw-alias-bg-layer-2)}.dsub-cooldown{display:inline-block;padding:2px 6px;border-radius:4px;background:var(--dsw-alias-state-warn-primary);color:var(--dsw-alias-bg-layer-1);font-size:11px;font-weight:600}.dsub-bar{position:relative;height:6px;border-radius:3px;background:var(--dsw-alias-bg-layer-1);overflow:hidden;flex:1;min-width:80px}.dsub-barFill{height:100%;border-radius:3px;background:var(--dsw-alias-state-success-primary);transition:width .2s}.dsub-barWarn .dsub-barFill{background:var(--dsw-alias-state-warn-primary)}.dsub-barFull .dsub-barFill{background:var(--dsw-alias-state-error-primary)}.dsub-barRow{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--dsw-alias-label-secondary)}.dsub-manual{display:flex;flex-direction:column;gap:6px;margin-top:4px;padding-top:10px;border-top:1px solid var(--dsw-alias-border-l2)}.dsub-verify{font-size:12px;color:var(--dsw-alias-state-warn-primary)}.dsub-verify a{color:var(--dsw-alias-brand-primary)}.dsub-pill{display:inline-flex;align-items:center;gap:7px;height:28px;padding:0 11px;border:1px solid var(--dsw-alias-border-l2);border-radius:999px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font-size:12px;font-weight:600;cursor:pointer;box-shadow:0 1px 3px color-mix(in srgb,black 15%,transparent),inset 0 1px 0 color-mix(in srgb,white 6%,transparent);transition:all .16s ease;user-select:none}.dsub-pill:hover{background:var(--dsw-alias-bg-layer-3);border-color:var(--dsw-alias-label-tertiary);transform:translateY(-1px);box-shadow:0 3px 8px color-mix(in srgb,black 25%,transparent),inset 0 1px 0 color-mix(in srgb,white 10%,transparent)}.dsub-pill:active{transform:translateY(0)}.dsub-pillTag{padding:1px 5px;border-radius:4px;font-size:10.5px;font-weight:700;letter-spacing:.02em;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary)}.dsub-led{width:7px;height:7px;border-radius:50%;flex:none;transition:all .2s ease}.dsub-ledOk{background:var(--dsw-alias-state-success-primary);box-shadow:0 0 6px color-mix(in srgb,var(--dsw-alias-state-success-primary) 70%,transparent)}.dsub-ledWarn{background:var(--dsw-alias-state-warn-primary);box-shadow:0 0 6px color-mix(in srgb,var(--dsw-alias-state-warn-primary) 70%,transparent)}.dsub-ledBad{background:var(--dsw-alias-state-error-primary);box-shadow:0 0 6px color-mix(in srgb,var(--dsw-alias-state-error-primary) 70%,transparent)}.dsub-ledOff{background:var(--dsw-alias-label-tertiary)}.dsub-toast-container{position:fixed;top:16px;right:16px;z-index:10030;display:flex;flex-direction:column;gap:8px;pointer-events:none}.dsub-toast{pointer-events:auto;min-width:280px;max-width:400px;padding:10px 14px;border-radius:10px;background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);border:1px solid var(--dsw-alias-border-l1);box-shadow:0 8px 24px color-mix(in srgb,black 40%,transparent);display:flex;align-items:center;justify-content:space-between;gap:10px;font-size:12px;line-height:1.4;animation:dsubFadeIn .2s ease-out}.dsub-toast-warn{border-color:var(--dsw-alias-state-warn-primary)}.dsub-toast-bad{border-color:var(--dsw-alias-state-error-primary)}.dsub-toast-ok{border-color:var(--dsw-alias-state-success-primary)}.dsub-toast-close{background:none;border:none;color:var(--dsw-alias-label-tertiary);cursor:pointer;font-size:14px;padding:0 2px}.dsub-toast-close:hover{color:var(--dsw-alias-label-primary)}.dsub-modalWrap{position:fixed;inset:0;z-index:10020;display:grid;place-items:center;background:color-mix(in srgb,black 65%,transparent);backdrop-filter:blur(10px);animation:dsubFadeIn .16s ease-out}.dsub-modal{width:min(520px,94vw);max-height:min(85vh,720px);overflow-y:auto;border:1px solid var(--dsw-alias-border-l1);border-radius:16px;background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);box-shadow:0 24px 64px color-mix(in srgb,black 60%,transparent),0 0 0 1px color-mix(in srgb,white 7%,transparent);padding:20px;animation:dsubScaleIn .18s cubic-bezier(.16,1,.3,1)}@keyframes dsubFadeIn{from{opacity:0}to{opacity:1}}@keyframes dsubScaleIn{from{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}.dsub-modalHead{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-bottom:14px;border-bottom:1px solid var(--dsw-alias-border-l2)}.dsub-modalTitleWrap{display:flex;align-items:center;gap:10px}.dsub-modalIcon{width:30px;height:30px;border-radius:8px;background:var(--dsw-alias-bg-layer-1);display:grid;place-items:center;color:var(--dsw-alias-brand-primary);font-size:14px}.dsub-modalBadge{font-size:11px;font-weight:600;padding:2px 7px;border-radius:10px;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary)}.dsub-heroCard{margin-top:14px;padding:14px 16px;border-radius:12px;background:linear-gradient(135deg,var(--dsw-alias-bg-layer-2) 0%,var(--dsw-alias-bg-layer-3) 100%);border:1px solid var(--dsw-alias-border-l1);box-shadow:inset 0 1px 0 color-mix(in srgb,white 5%,transparent)}.dsub-heroHead{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}.dsub-heroTitle{font-size:14px;font-weight:700;display:flex;align-items:center;gap:6px}.dsub-heroModel{font-size:11.5px;color:var(--dsw-alias-label-secondary);font-family:ui-monospace,monospace}.dsub-select{appearance:none;height:30px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);border-radius:6px;padding:0 24px 0 8px;font-size:12px;cursor:pointer}.dsub-details{margin-top:12px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:8px 12px;background:var(--dsw-alias-bg-layer-2)}.dsub-summary{cursor:pointer;font-weight:600;font-size:12.5px;color:var(--dsw-alias-label-secondary);user-select:none}.dsub-summary:hover{color:var(--dsw-alias-label-primary)}.dsub-header-bar{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px;padding:8px 0 12px;margin-bottom:8px;border-bottom:1px solid var(--dsw-alias-border-l2)}.dsub-badge{font-size:12px;padding:3px 10px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2);display:inline-flex;align-items:center;gap:5px;font-weight:500}.dsub-badge-ok{border-color:var(--dsw-alias-state-success-primary);color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 10%,transparent)}.dsub-badge-warn{border-color:var(--dsw-alias-state-warn-primary);color:var(--dsw-alias-state-warn-primary);background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 10%,transparent)}.dsub-badge-bad{border-color:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent)}.dsub-badge-neutral{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2)}.dsub-section-card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;padding:14px 16px;display:flex;flex-direction:column;gap:10px;margin-top:12px}.dsub-section-title{font-size:14.5px;font-weight:600;color:var(--dsw-alias-label-primary);display:flex;align-items:center;justify-content:space-between;gap:8px}.dsub-section-desc{font-size:12px;color:var(--dsw-alias-label-secondary);margin-top:-4px;line-height:1.4}.dsub-grid-2{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px}.dsub-stat-box{padding:10px 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-2);display:flex;flex-direction:column;gap:3px}.dsub-stat-val{font-size:16.5px;font-weight:700;color:var(--dsw-alias-label-primary)}.dsub-stat-lbl{font-size:11.5px;color:var(--dsw-alias-label-secondary)}.dsub-chart-wrap{display:flex;align-items:flex-end;gap:3px;height:52px;padding:6px 0;margin-top:8px;border-bottom:1px solid var(--dsw-alias-border-l3)}.dsub-chart-bar{flex:1;background:var(--dsw-alias-brand-primary);border-radius:2px 2px 0 0;min-height:3px;transition:height .2s ease;opacity:0.85;cursor:pointer}.dsub-chart-bar:hover{opacity:1;background:var(--dsw-alias-state-success-primary)}.dsub-chart-labels{display:flex;justify-content:space-between;font-size:10px;color:var(--dsw-alias-label-secondary);margin-top:3px}.dsub-alert-ok{padding:8px 12px;border-radius:8px;background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 10%,transparent);color:var(--dsw-alias-state-success-primary);font-size:12.5px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-success-primary) 25%,transparent)}.dsub-alert-bad{padding:8px 12px;border-radius:8px;background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary);font-size:12.5px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary) 25%,transparent)}.dsub-btn-primary{background:var(--dsw-alias-label-primary) !important;color:var(--dsw-alias-bg-layer-3) !important;border-color:transparent !important;font-weight:600}.dsub-btn-primary:hover:not(:disabled){opacity:0.9}.dsub-model-grid{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}.dsub-model-chip{display:inline-flex;align-items:center;gap:6px;padding:3px 8px;border-radius:6px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);font-size:11.5px;color:var(--dsw-alias-label-primary)}.dsub-model-chip code{font-family:ui-monospace,monospace;font-weight:600}.dsub-model-tag{font-size:10px;padding:1px 4px;border-radius:3px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary);font-weight:600}.dsub-trace-box{padding:8px 12px;border-radius:8px;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);margin-top:8px;font-size:12px}.dsub-trace-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:4px 0;border-bottom:1px solid var(--dsw-alias-border-l3)}.dsub-trace-row:last-child{border-bottom:none}.dsub-model-status-available{color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 12%,transparent)}.dsub-model-status-degraded{color:var(--dsw-alias-state-warn-primary);background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 12%,transparent)}.dsub-model-status-quarantined{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 12%,transparent)}.dsub-model-status-cooldown{color:var(--dsw-alias-state-business-primary);background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 12%,transparent)}.dsub-model-status-exhausted{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 12%,transparent)}.dsub-model-status-unconfigured{color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-layer-3)}.dsub-heroBars{display:flex;flex-direction:column;gap:8px;margin-top:10px}.dsub-barLabelRow{display:flex;justify-content:space-between;font-size:11.5px;color:var(--dsw-alias-label-secondary);margin-bottom:3px}.dsub-barTrack{height:6px;border-radius:3px;background:var(--dsw-alias-bg-layer-1);overflow:hidden}.dsub-barFillGrad{height:100%;border-radius:3px;transition:width .3s ease}.dsub-panel-box{margin-top:10px;padding:12px 14px;border-radius:10px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);display:flex;flex-direction:column;gap:8px}.dsub-panel-warn{border-color:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 40%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 5%,transparent)}.dsub-panel-title{font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);display:flex;align-items:center;justify-content:space-between}.dsub-panel-desc{font-size:12px;color:var(--dsw-alias-label-secondary);line-height:1.4}.dsub-usage-grid{display:flex;flex-direction:column;gap:8px;margin-top:4px}.dsub-usage-card{display:flex;flex-direction:column;gap:5px;padding:8px 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-1)}.dsub-usage-head{display:flex;justify-content:space-between;align-items:center;font-size:12px;font-weight:500;color:var(--dsw-alias-label-primary)}.dsub-usage-track{width:100%;height:8px;border-radius:999px;background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);overflow:hidden}.dsub-usage-fill{height:100%;border-radius:999px;transition:width .3s ease}.dsub-usage-meta{display:flex;justify-content:space-between;align-items:center;font-size:11px;color:var(--dsw-alias-label-secondary)}.dsub-tag-ok{border-color:color-mix(in srgb,var(--dsw-alias-state-success-primary) 30%,transparent);color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 8%,transparent);padding:1px 7px;border-radius:999px;font-size:11px;font-weight:600;border-style:solid;border-width:1px}.dsub-tag-warn{border-color:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 40%,transparent);color:var(--dsw-alias-state-warn-primary);background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 8%,transparent);padding:1px 7px;border-radius:999px;font-size:11px;font-weight:600;border-style:solid;border-width:1px}.dsub-tag-bad{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 40%,transparent);color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 8%,transparent);padding:1px 7px;border-radius:999px;font-size:11px;font-weight:600;border-style:solid;border-width:1px}.dsub-slot-meta-row{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-top:12px;padding-top:10px;border-top:1px solid var(--dsw-alias-border-l2);font-size:12px}.dsub-ref-tag{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;color:var(--dsw-alias-label-secondary)}.dsub-ref-tag code{padding:2px 6px;border-radius:4px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);font-family:ui-monospace,monospace;color:var(--dsw-alias-label-primary);font-size:11px}.dsub-speed-tag{display:inline-flex;align-items:center;gap:4px;font-size:11.5px;color:var(--dsw-alias-brand-primary);background:color-mix(in srgb,var(--dsw-alias-brand-primary) 8%,transparent);padding:2px 8px;border-radius:6px;font-weight:500;border:1px solid color-mix(in srgb,var(--dsw-alias-brand-primary) 20%,transparent)}.dsub-btn-danger{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 40%,transparent)!important;color:var(--dsw-alias-state-error-primary)!important}.dsub-btn-danger:hover:not(:disabled){background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 12%,transparent)!important}.dsub-poolTitle{margin-top:16px;margin-bottom:8px;font-size:11.5px;font-weight:700;color:var(--dsw-alias-label-secondary);text-transform:uppercase;letter-spacing:.05em}.dsub-accountCard{display:flex;align-items:center;gap:12px;padding:10px 14px;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-alias-bg-layer-2);margin-top:6px;transition:border-color .15s,background .15s}.dsub-accountCard:hover{background:var(--dsw-alias-bg-layer-3);border-color:var(--dsw-alias-label-tertiary)}.dsub-brandBadge{width:32px;height:32px;border-radius:8px;display:grid;place-items:center;font-size:12px;font-weight:700;flex-shrink:0}.dsub-brandCodex{background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 15%,transparent);color:var(--dsw-alias-state-success-primary);border:1px solid color-mix(in srgb,var(--dsw-alias-state-success-primary) 30%,transparent)}.dsub-brandClaude{background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 15%,transparent);color:var(--dsw-alias-state-warn-primary);border:1px solid color-mix(in srgb,var(--dsw-alias-state-warn-primary) 30%,transparent)}.dsub-brandGrok{background:color-mix(in srgb,var(--dsw-alias-state-business-primary,var(--dsw-alias-brand-primary)) 15%,transparent);color:var(--dsw-alias-state-business-primary,var(--dsw-alias-brand-primary));border:1px solid color-mix(in srgb,var(--dsw-alias-state-business-primary,var(--dsw-alias-brand-primary)) 30%,transparent)}.dsub-brandAgy{background:color-mix(in srgb,var(--dsw-alias-brand-primary) 15%,transparent);color:var(--dsw-alias-brand-primary);border:1px solid color-mix(in srgb,var(--dsw-alias-brand-primary) 30%,transparent)}.dsub-brandOllama{background:color-mix(in srgb,var(--dsw-alias-label-tertiary) 15%,transparent);color:var(--dsw-alias-label-secondary);border:1px solid color-mix(in srgb,var(--dsw-alias-label-tertiary) 30%,transparent)}.dsub-brandKimi{background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 15%,transparent);color:var(--dsw-alias-state-warn-primary);border:1px solid color-mix(in srgb,var(--dsw-alias-state-warn-primary) 30%,transparent)}.dsub-brandGlm{background:color-mix(in srgb,var(--dsw-alias-state-business-primary,var(--dsw-alias-brand-primary)) 15%,transparent);color:var(--dsw-alias-state-business-primary,var(--dsw-alias-brand-primary));border:1px solid color-mix(in srgb,var(--dsw-alias-state-business-primary,var(--dsw-alias-brand-primary)) 30%,transparent)}.dsub-planBadge{display:inline-flex;align-items:center;padding:1px 6px;border-radius:4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:0.5px;background:color-mix(in srgb,var(--dsw-alias-brand-primary) 15%,transparent);color:var(--dsw-alias-brand-primary);border:1px solid color-mix(in srgb,var(--dsw-alias-brand-primary) 30%,transparent);margin-left:6px}.dsub-accInfo{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}.dsub-accNameRow{display:flex;align-items:center;justify-content:space-between;gap:8px}.dsub-accName{font-size:13px;font-weight:600}.dsub-accStatusTag{font-size:10.5px;font-weight:600;padding:1px 6px;border-radius:4px}.dsub-statusOk{background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 15%,transparent);color:var(--dsw-alias-state-success-primary)}.dsub-statusWarn{background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 15%,transparent);color:var(--dsw-alias-state-warn-primary)}.dsub-statusBad{background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 15%,transparent);color:var(--dsw-alias-state-error-primary)}.dsub-statusOff{background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-tertiary)}.dsub-modalFoot{display:flex;align-items:center;justify-content:space-between;margin-top:16px;padding-top:12px;border-top:1px solid var(--dsw-alias-border-l2)}.dsub-btnPrimary{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border-radius:8px;font-size:12px;font-weight:600;background:var(--dsw-alias-brand-primary);color:var(--dsw-alias-label-primary-foreground);border:0;cursor:pointer;transition:opacity .15s}.dsub-btnPrimary:hover{opacity:.9}.dsub-btnSec{display:inline-flex;align-items:center;gap:5px;padding:5px 10px;border-radius:7px;font-size:11.5px;font-weight:500;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;text-decoration:none;transition:all .15s}.dsub-btnSec:hover{background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-tertiary)}.dsub-cq{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--dsw-alias-label-secondary);padding:0 6px}.dsub-cqBar{position:relative;width:40px;height:5px;border-radius:3px;background:var(--dsw-alias-bg-layer-1);overflow:hidden}.dsub-cqBarFill{height:100%;border-radius:3px;background:var(--dsw-alias-state-success-primary)}.dsub-cqBarWarn .dsub-cqBarFill{background:var(--dsw-alias-state-warn-primary)}.dsub-cqBarFull .dsub-cqBarFill{background:var(--dsw-alias-state-error-primary)}.dsub-cqB{font-variant-numeric:tabular-nums;font-weight:600;color:var(--dsw-alias-label-primary)}.dsub-diag{font:11px/1.5 ui-monospace,SFMono-Regular,monospace;max-height:260px;overflow:auto;white-space:pre-wrap;word-break:break-word;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:10px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary)}";
44
+ const cssId = 'dsh-subscriptions/settings.module.css'
204
45
  if (typeof document !== 'undefined' && !document.querySelector('style[data-plugin-css="' + cssId + '"]')) {
205
46
  const tag = document.createElement('style')
206
47
  tag.textContent = CSS
@@ -210,155 +51,21 @@ const cssId = 'dsh-subscriptions/settings.module.css'
210
51
  document.head.appendChild(tag)
211
52
  }
212
53
 
213
- // Card strings live in the locale registry: a separate package translates
214
- // them without touching this plugin's code. English is the default,
215
- // and the fallback when no translation exists.
216
54
  const NS = 'dsh-subscriptions'
217
55
  // Plugins page row seat (DSH 0.1.6-alpha.2): key = '<package name>#<row id>'.
218
56
  const PKG = '@goodandready/dsh-subscriptions'
219
57
  const ROW_ID = 'dsh-subscriptions'
220
58
  const ROW_CONFIG_KEY = PKG + '#' + ROW_ID
221
59
 
222
- const INSTRUCTIONS = {
223
- codex: {
224
- title: "OpenAI / ChatGPT Codex",
225
- stepsEn: [
226
- "1. Log in via CLI on server: run \"codex login\" in terminal.",
227
- "2. Click \"๐Ÿ“ฅ From CLI\" to auto-import ~/.codex/auth.json.",
228
- "3. Or click \"Device Login\" above and enter the code at auth.openai.com.",
229
- ],
230
- stepsZh: [
231
- "1. ๅœจๆœๅŠกๅ™จไธŠ้€š่ฟ‡ CLI ็™ปๅฝ•๏ผšๅœจ็ปˆ็ซฏ่ฟ่กŒ \"codex login\"ใ€‚",
232
- "2. ็‚นๅ‡ป \"๐Ÿ“ฅ ไปŽ CLI ๅฏผๅ…ฅ\" ่‡ชๅŠจ่ฏปๅ– ~/.codex/auth.jsonใ€‚",
233
- "3. ๆˆ–่€…็‚นๅ‡ปไธŠๆ–น็š„ \"่ฎพๅค‡็ ็™ปๅฝ•\" (Device Login) ๅนถๅœจ auth.openai.com ่พ“ๅ…ฅไปฃ็ ใ€‚",
234
- ],
235
- link: "https://chatgpt.com",
236
- },
237
- claude: {
238
- title: "Claude Code",
239
- stepsEn: [
240
- "1. Run \"claude login\" in server console.",
241
- "2. Click \"๐Ÿ“ฅ From CLI\" โ€” plugin will import ~/.claude/credentials.json.",
242
- "3. Or paste your Session Token / API Key from Anthropic Console and click \"Save token\".",
243
- ],
244
- stepsZh: [
245
- "1. ๅœจๆœๅŠกๅ™จๆŽงๅˆถๅฐ่ฟ่กŒ \"claude login\"ใ€‚",
246
- "2. ็‚นๅ‡ป \"๐Ÿ“ฅ ไปŽ CLI ๅฏผๅ…ฅ\" โ€” ๆ’ไปถๅฐ†่‡ชๅŠจๅฏผๅ…ฅ ~/.claude/credentials.jsonใ€‚",
247
- "3. ๆˆ–่€…ไปŽ Anthropic ๆŽงๅˆถๅฐๅคๅˆถๆ‚จ็š„ Session Token ๆˆ– API Key ๅนถ็‚นๅ‡ป \"ไฟๅญ˜ไปค็‰Œ\"ใ€‚",
248
- ],
249
- link: "https://console.anthropic.com/settings/keys",
250
- },
251
- cursor: {
252
- title: "Cursor IDE",
253
- stepsEn: [
254
- "1. Auto CLI: if Cursor is used on server, click \"๐Ÿ“ฅ From CLI\" (reads from ~/.cursor/cli-config.json).",
255
- "2. Manual: open Cursor Settings (Connect button or link below), copy your session token or API key.",
256
- "3. Paste it into the input field and click \"Save token\".",
257
- ],
258
- stepsZh: [
259
- "1. CLI ่‡ชๅŠจๅฏผๅ…ฅ๏ผš่‹ฅๆœๅŠกๅ™จๅฎ‰่ฃ…ไบ† Cursor๏ผŒ็‚นๅ‡ป \"๐Ÿ“ฅ ไปŽ CLI ๅฏผๅ…ฅ\" (่ฏปๅ–่‡ช ~/.cursor/cli-config.json)ใ€‚",
260
- "2. ๆ‰‹ๅŠจๅฏผๅ…ฅ๏ผšๆ‰“ๅผ€ Cursor ่ฎพ็ฝฎ้กต้ข๏ผˆ็‚นๅ‡ป่ฟžๆŽฅๆˆ–ไธ‹ๆ–น้“พๆŽฅ๏ผ‰๏ผŒๅคๅˆถ WorkOS ไผš่ฏไปค็‰Œๆˆ– API ๅฏ†้’ฅใ€‚",
261
- "3. ๅฐ†ๅ…ถ็ฒ˜่ดดๅˆฐ่พ“ๅ…ฅๆก†ไธญๅนถ็‚นๅ‡ป \"ไฟๅญ˜ไปค็‰Œ\"ใ€‚",
262
- ],
263
- link: "https://cursor.com/settings",
264
- },
265
- antigravity: {
266
- title: "Google Antigravity / Gemini",
267
- stepsEn: [
268
- "1. Easiest way: click \"๐Ÿ“ฅ From CLI\" โ€” server already has active token in ~/.gemini/antigravity-cli/antigravity-oauth-token.",
269
- "2. Clicking \"๐Ÿ“ฅ From CLI\" instantly loads fresh credentials.",
270
- "3. Manual: paste session JSON or OAuth tokens and click \"Save token\".",
271
- "Note: \"Connect\" button requires custom Google client_id in plugin settings; use \"๐Ÿ“ฅ From CLI\" for seamless login!",
272
- ],
273
- stepsZh: [
274
- "1. ๆŽจ่ๆ–นๅผ๏ผš็‚นๅ‡ป \"๐Ÿ“ฅ ไปŽ CLI ๅฏผๅ…ฅ\" โ€” ๆœๅŠกๅ™จๅทฒไฟๅญ˜ ~/.gemini/antigravity-cli/antigravity-oauth-token ไผš่ฏใ€‚",
275
- "2. ็‚นๅ‡ป \"๐Ÿ“ฅ ไปŽ CLI ๅฏผๅ…ฅ\" ๅฏๅณๆ—ถๅŠ ่ฝฝๆœ€ๆ–ฐ็š„ๅ‡ญๆฎไธŽ refresh_tokenใ€‚",
276
- "3. ๆ‰‹ๅŠจ่พ“ๅ…ฅ๏ผšๅฐ†ไผš่ฏ JSON ๆˆ– OAuth access_token/refresh_token ็ฒ˜่ดด่‡ณ่พ“ๅ…ฅๆก†ๅนถไฟๅญ˜ใ€‚",
277
- "ๆณจ๏ผš\"่ฟžๆŽฅ\" ๆŒ‰้’ฎ้œ€่ฆ่‡ชๅฎšไน‰ Google OAuth Client ID๏ผŒๆŽจ่็›ดๆŽฅไฝฟ็”จ \"๐Ÿ“ฅ ไปŽ CLI ๅฏผๅ…ฅ\"๏ผ",
278
- ],
279
- link: "https://antigravity.google",
280
- },
281
- kimi: {
282
- title: "Moonshot Kimi",
283
- stepsEn: [
284
- "1. Open Moonshot developer console (link below or click Connect).",
285
- "2. Generate and copy your API Key (sk-...).",
286
- "3. Paste it into the input field and click \"Save token\".",
287
- "4. Or click \"๐Ÿ“ฅ From CLI\" if ~/.kimi-code is configured.",
288
- ],
289
- stepsZh: [
290
- "1. ๆ‰“ๅผ€ Moonshot ๅผ€ๅ‘่€…ๆŽงๅˆถๅฐ๏ผˆ็‚นๅ‡ปไธ‹ๆ–น้“พๆŽฅๆˆ–็‚นๅ‡ป่ฟžๆŽฅ๏ผ‰ใ€‚",
291
- "2. ๅˆ›ๅปบๅนถๅคๅˆถๆ‚จ็š„ API ๅฏ†้’ฅ (sk-...)ใ€‚",
292
- "3. ๅฐ†ๅฏ†้’ฅ็ฒ˜่ดดๅˆฐๆงฝไฝ่พ“ๅ…ฅๆก†ไธญๅนถ็‚นๅ‡ป \"ไฟๅญ˜ไปค็‰Œ\"ใ€‚",
293
- "4. ๅฆ‚ๆžœ้…็ฝฎไบ† Kimi Code CLI๏ผŒไนŸๅฏ็‚นๅ‡ป \"๐Ÿ“ฅ ไปŽ CLI ๅฏผๅ…ฅ\" (~/.kimi-code)ใ€‚",
294
- ],
295
- link: "https://platform.moonshot.cn/console/api-keys",
296
- },
297
- glm: {
298
- title: "Zhipu GLM (Z.AI)",
299
- stepsEn: [
300
- "1. Open Zhipu BigModel API Keys center (link below or click Connect).",
301
- "2. Copy your GLM API Key.",
302
- "3. Paste it into the input field and click \"Save token\".",
303
- "4. Or click \"๐Ÿ“ฅ From CLI\" if ZCode CLI is installed (~/.zcode).",
304
- ],
305
- stepsZh: [
306
- "1. ๆ‰“ๅผ€ๆ™บ่ฐฑ AI ๅผ€ๆ”พๅนณๅฐ๏ผˆ็‚นๅ‡ปไธ‹ๆ–น้“พๆŽฅๆˆ–็‚นๅ‡ป่ฟžๆŽฅ๏ผ‰ใ€‚",
307
- "2. ๅคๅˆถๆ‚จ็š„ GLM API ๅฏ†้’ฅใ€‚",
308
- "3. ็ฒ˜่ดดๅˆฐ่พ“ๅ…ฅๆก†ไธญๅนถ็‚นๅ‡ป \"ไฟๅญ˜ไปค็‰Œ\"ใ€‚",
309
- "4. ่‹ฅๅทฒๅฎ‰่ฃ… ZCode CLI (~/.zcode)๏ผŒ็‚นๅ‡ป \"๐Ÿ“ฅ ไปŽ CLI ๅฏผๅ…ฅ\" ๅณๅฏ่‡ชๅŠจๅฏผๅ…ฅใ€‚",
310
- ],
311
- link: "https://bigmodel.cn/usercenter/proj-mgmt/apikeys",
312
- },
313
- grok: {
314
- title: "xAI Grok",
315
- stepsEn: [
316
- "1. Click \"Device Login\" (or \"Connect\") on the slot card.",
317
- "2. A one-time code will appear on the card.",
318
- "3. Open https://accounts.x.ai/oauth2/device, enter the code, and approve access for your xAI account.",
319
- "4. The plugin automatically captures tokens and enables Grok models.",
320
- "5. Or click \"๐Ÿ“ฅ From CLI\" (~/.grok/auth.json) / paste an xAI API Key.",
321
- ],
322
- stepsZh: [
323
- "1. ็‚นๅ‡ปๅก็‰‡ไธŠ็š„ \"่ฎพๅค‡็ ็™ปๅฝ•\" (Device Login) ๆˆ– \"่ฟžๆŽฅ\"ใ€‚",
324
- "2. ็•Œ้ขๅฐ†ๅฑ•็คบไธ€ๆฌกๆ€ง่ฎพๅค‡ๆŽˆๆƒ็ ใ€‚",
325
- "3. ๆ‰“ๅผ€ https://accounts.x.ai/oauth2/device๏ผŒ่พ“ๅ…ฅไปฃ็ ๏ผŒๅนถไธบๆ‚จๆ‹ฅๆœ‰ Grok ่ฎข้˜…็š„ xAI ่ดฆๆˆทๆŽˆๆƒใ€‚",
326
- "4. ๆŽˆๆƒๆˆๅŠŸๅŽ๏ผŒๆ’ไปถไผš่‡ชๅŠจๆ•่Žทไผš่ฏๅนถๆฟ€ๆดป Grok ๅฎ˜ๆ–นๆจกๅž‹ใ€‚",
327
- "5. ๆˆ–็‚นๅ‡ป \"๐Ÿ“ฅ ไปŽ CLI ๅฏผๅ…ฅ\" (~/.grok/auth.json) / ็›ดๆŽฅ็ฒ˜่ดด xAI API ๅฏ†้’ฅใ€‚",
328
- ],
329
- link: "https://accounts.x.ai/oauth2/device",
330
- },
331
- kiro: {
332
- title: "AWS Kiro",
333
- stepsEn: [
334
- "1. Click \"๐Ÿ“ฅ From CLI\" to import from ~/.kiro/credentials.json.",
335
- "2. Or paste KIRO_API_KEY and click \"Save token\".",
336
- ],
337
- stepsZh: [
338
- "1. ็‚นๅ‡ป \"๐Ÿ“ฅ ไปŽ CLI ๅฏผๅ…ฅ\" ไปŽ ~/.kiro/credentials.json ๆˆ– ~/.aws/sso ๅฏผๅ…ฅๅ‡ญๆฎใ€‚",
339
- "2. ๆˆ–็›ดๆŽฅ็ฒ˜่ดด KIRO_API_KEY ๅนถ็‚นๅ‡ป \"ไฟๅญ˜ไปค็‰Œ\"ใ€‚",
340
- ],
341
- link: "https://aws.amazon.com",
342
- },
343
- copilot: {
344
- title: "GitHub Copilot",
345
- stepsEn: [
346
- "1. Click \"Device Login\" (or \"Connect\") on the slot card.",
347
- "2. A one-time code will appear on the card.",
348
- "3. Open https://github.com/login/device, enter the code, and approve access for your GitHub account with Copilot subscription.",
349
- "4. The plugin automatically captures tokens and enables Copilot models.",
350
- ],
351
- stepsZh: [
352
- "1. ็‚นๅ‡ปๅก็‰‡ไธŠ็š„ \"่ฎพๅค‡็ ็™ปๅฝ•\" (Device Login) ๆˆ– \"่ฟžๆŽฅ\"ใ€‚",
353
- "2. ็•Œ้ขๅฐ†ๅฑ•็คบไธ€ๆฌกๆ€ง่ฎพๅค‡ๆŽˆๆƒ็ ใ€‚",
354
- "3. ๅœจๆต่งˆๅ™จๆ‰“ๅผ€ https://github.com/login/device ่พ“ๅ…ฅไปฃ็ ๏ผŒๅนถไธบๆ‚จๆ‹ฅๆœ‰ Copilot ่ฎข้˜…็š„ GitHub ่ดฆๆˆทๆŽˆๆƒใ€‚",
355
- "4. ๆŽˆๆƒๆˆๅŠŸๅŽ๏ผŒๆ’ไปถไผš่‡ชๅŠจๆ•่Žทไผš่ฏๅนถๆฟ€ๆดป GitHub Copilot ๅฎ˜ๆ–นๆจกๅž‹ใ€‚",
356
- ],
357
- link: "https://github.com/login/device",
358
- },
359
- }
60
+ let INSTRUCTIONS = {};
360
61
 
361
62
  const en = {
63
+ "syncModels": "Sync Models",
64
+ "syncModelsTitle": "Discover and synchronize available models from vendor API",
65
+ "modelsSynced": "Models synchronized",
66
+ "doctorDiagnosis": "Doctor Verdict",
67
+ "recommendation": "Recommendation",
68
+ "pingTitle": "Measure network latency to provider API",
362
69
  "notConnected": "Not connected",
363
70
  "verifyAccount": "Verify account",
364
71
  "coolingDown": "Cooling down",
@@ -436,6 +143,13 @@ const cssId = 'dsh-subscriptions/settings.module.css'
436
143
  "cascadingFallbackHint": "Automatically route queries to alternative providers when all accounts of a primary provider are exhausted.",
437
144
  "cascadingFallbackOrder": "Fallback Provider Order",
438
145
  "cascadingFallbackOrderHint": "Sequence of alternative providers to try when primary accounts are exhausted.",
146
+ "rotationStrategy": "Account Balancing Strategy",
147
+ "rotationStrategyHint": "Method used to distribute requests among available accounts of a provider.",
148
+ "rotationRoundRobin": "Round-Robin (Balanced rotation)",
149
+ "rotationLeastLoaded": "Least-Loaded (Fair-share quota)",
150
+ "rotationPriority": "Priority (Sequential by index/weight)",
151
+ "softFailureSentinel": "Soft-Failure & Refusal Sentinel",
152
+ "softFailureSentinelHint": "Detects HTTP 200 capacity apologies and auto-cascades to the next healthy account before streaming.",
439
153
  "recentErrors": "Recent Runtime Errors",
440
154
  "recentErrorsDesc": "Last 20 runtime failures across model streams and providers (sanitized).",
441
155
  "recentErrorsClear": "Clear Log",
@@ -642,6 +356,12 @@ const cssId = 'dsh-subscriptions/settings.module.css'
642
356
  };
643
357
 
644
358
  const zh = {
359
+ "syncModels": "ๅŒๆญฅๆจกๅž‹",
360
+ "syncModelsTitle": "ไปŽๆœๅŠกๅ•† API ๅฎžๆ—ถๅ‘็ŽฐๅนถๅŒๆญฅๅฏ็”จๆจกๅž‹ๅˆ—่กจ",
361
+ "modelsSynced": "ๆจกๅž‹ๅทฒๅŒๆญฅ",
362
+ "doctorDiagnosis": "่ฏŠๆ–ญ็ป“่ฎบ",
363
+ "recommendation": "ไฟฎๅคๅปบ่ฎฎ",
364
+ "pingTitle": "ๆต‹่ฏ•ๅˆฐๆœๅŠกๅ•† API ็š„็ฝ‘็ปœๅพ€่ฟ”ๅปถ่ฟŸ",
645
365
  "notConnected": "ๆœช่ฟžๆŽฅ",
646
366
  "verifyAccount": "้œ€่ฆ้ชŒ่ฏ่ดฆๆˆท",
647
367
  "coolingDown": "ๅ†ทๅด็ญ‰ๅพ…ไธญ",
@@ -719,6 +439,13 @@ const cssId = 'dsh-subscriptions/settings.module.css'
719
439
  "cascadingFallbackHint": "ๅฝ“้ฆ–้€‰ๆœๅŠกๅ•†ๆ‰€ๆœ‰่ดฆๆˆท้…้ข่€—ๅฐฝๆˆ–้™ๆตๆ—ถ๏ผŒ่‡ชๅŠจๆ— ็ผ่ฝฌๆŽฅ่‡ณๅค‡้€‰ๆœๅŠกๅ•†ใ€‚",
720
440
  "cascadingFallbackOrder": "ๆ•…้šœ่ฝฌ็งปไพ›ๅบ”ๅ•†้กบๅบ",
721
441
  "cascadingFallbackOrderHint": "้ฆ–้€‰ๆœๅŠกๅ•†่€—ๅฐฝๆ—ถๆŒ‰ๆญค้กบๅบไพๆฌกๅฐ่ฏ•ๅค‡้€‰ๆœๅŠกๅ•†ใ€‚",
442
+ "rotationStrategy": "่ดฆๆˆท่ดŸ่ฝฝๅ‡่กก็ญ–็•ฅ",
443
+ "rotationStrategyHint": "ๅœจๅŒไธ€ๆœๅŠกๅ•†็š„ๅคšไธชๅฏ็”จ่ดฆๆˆทไน‹้—ดๅˆ†ๅ‘่ฏทๆฑ‚็š„ๆ–นๅผใ€‚",
444
+ "rotationRoundRobin": "่ฝฎ่ฏขๅ‡่กก๏ผˆๆ ‡ๅ‡†ไบคๆ›ฟ๏ผ‰",
445
+ "rotationLeastLoaded": "ๆœ€ๅฐ‘่ดŸ่ฝฝไผ˜ๅ…ˆ๏ผˆ้…้ขๅ…ฌๅนณๅ…ฑไบซ๏ผ‰",
446
+ "rotationPriority": "ไผ˜ๅ…ˆ็บง้กบๅบ๏ผˆๆŒ‰ๅบๅท/ๆƒ้‡้กบๅบ๏ผ‰",
447
+ "softFailureSentinel": "่ฝฏๆ€งๆ‹’็ปไธŽๅฎน้‡ๅ“จๅ…ต",
448
+ "softFailureSentinelHint": "่‡ชๅŠจ่ฏ†ๅˆซ HTTP 200 ็Šถๆ€ไธ‹็š„ๆœๅŠกๅ•†ๅฎน้‡้“ๆญ‰ๅนถๆ— ็ผ่ฝฌๆŽฅ่‡ณไธ‹ไธ€ไธชๆญฃๅธธ่ดฆๆˆทใ€‚",
722
449
  "recentErrors": "ๆœ€่ฟ‘่ฟ่กŒ้”™่ฏฏ่ฎฐๅฝ•",
723
450
  "recentErrorsDesc": "ๆœ€่ฟ‘ 20 ๆกๆตๅผไผ ่พ“ไธŽ API ่ฐƒ็”จๅคฑ่ดฅ่ฎฐๅฝ•๏ผˆๅทฒ่„ฑๆ•๏ผ‰ใ€‚",
724
451
  "recentErrorsClear": "ๆธ…็ฉบ่ฎฐๅฝ•",
@@ -963,7 +690,7 @@ const cssId = 'dsh-subscriptions/settings.module.css'
963
690
  } else if (provider === 'glm') {
964
691
  label = '150% Boost'
965
692
  }
966
- return label ? React.createElement('span', { className: 'dsub-planBadge' }, label) : null
693
+ return label ? h('span', { className: 'dsub-planBadge' }, label) : null
967
694
  }
968
695
 
969
696
  function formatRelativeReset(resetAt, lang, now) {
@@ -992,13 +719,13 @@ const cssId = 'dsh-subscriptions/settings.module.css'
992
719
  if (ms <= 0) return null
993
720
  const total = Math.floor(ms / 1000)
994
721
  if (total > 3600) {
995
- return React.createElement('span', { className: 'dsub-sub', style: { fontVariantNumeric: 'tabular-nums' } },
722
+ return h('span', { className: 'dsub-sub', style: { fontVariantNumeric: 'tabular-nums' } },
996
723
  t('resetLabel') + ' ' + formatRelativeReset(props.resetAt, t('lang'), now))
997
724
  }
998
725
  const m = Math.floor(total / 60)
999
726
  const sec = total % 60
1000
727
  const pad = (n) => String(n).padStart(2, '0')
1001
- return React.createElement('span', { className: 'dsub-sub', style: { fontVariantNumeric: 'tabular-nums' } },
728
+ return h('span', { className: 'dsub-sub', style: { fontVariantNumeric: 'tabular-nums' } },
1002
729
  t('resetLabel') + ' ' + pad(m) + ':' + pad(sec))
1003
730
  }
1004
731
 
@@ -1031,8 +758,8 @@ const cssId = 'dsh-subscriptions/settings.module.css'
1031
758
  ChevronIcon = null
1032
759
  }
1033
760
  function FallbackChevron(props) {
1034
- return React.createElement('svg', { className: props.className, width: 14, height: 14, viewBox: '0 0 14 14', fill: 'none' },
1035
- React.createElement('path', { d: 'M3.5 5.25L7 8.75l3.5-3.5', stroke: 'currentColor', 'stroke-width': 1.5, 'stroke-linecap': 'round', 'stroke-linejoin': 'round' }),
761
+ return h('svg', { className: props.className, width: 14, height: 14, viewBox: '0 0 14 14', fill: 'none' },
762
+ h('path', { d: 'M3.5 5.25L7 8.75l3.5-3.5', stroke: 'currentColor', 'stroke-width': 1.5, 'stroke-linecap': 'round', 'stroke-linejoin': 'round' }),
1036
763
  )
1037
764
  }
1038
765
  const Chevron = ChevronIcon || FallbackChevron
@@ -1295,6 +1022,45 @@ const cssId = 'dsh-subscriptions/settings.module.css'
1295
1022
  .catch(() => {})
1296
1023
  }
1297
1024
 
1025
+ const doPing = async (provider, index) => {
1026
+ try {
1027
+ const res = await fetch('/dsh-subscriptions/ping', {
1028
+ method: 'POST',
1029
+ headers: { 'Content-Type': 'application/json' },
1030
+ body: JSON.stringify({ provider, index }),
1031
+ })
1032
+ const d = await res.json()
1033
+ if (d && d.ok) {
1034
+ setAccounts((accs) => accs.map((a) => (a.provider === provider && a.index === index) ? Object.assign({}, a, { lastPingMs: d.latencyMs, latencyGrade: d.latencyGrade, lastDoctorVerdict: null }) : a))
1035
+ setInfo('๐Ÿ“ถ Ping: ' + d.latencyMs + 'ms (' + d.latencyGrade + ')')
1036
+ } else if (d && d.doctor) {
1037
+ setAccounts((accs) => accs.map((a) => (a.provider === provider && a.index === index) ? Object.assign({}, a, { lastPingMs: d.latencyMs, latencyGrade: d.latencyGrade, lastDoctorVerdict: d.doctor }) : a))
1038
+ setErr('๐Ÿฉบ ' + d.doctor.title)
1039
+ }
1040
+ } catch (e) {
1041
+ setErr(cleanErrorMessage(e.message || e))
1042
+ }
1043
+ }
1044
+
1045
+ const doSyncModels = async (provider, index) => {
1046
+ try {
1047
+ const res = await fetch('/dsh-subscriptions/accounts/sync-models', {
1048
+ method: 'POST',
1049
+ headers: { 'Content-Type': 'application/json' },
1050
+ body: JSON.stringify({ provider, index }),
1051
+ })
1052
+ const d = await res.json()
1053
+ if (d && d.ok) {
1054
+ setAccounts((accs) => accs.map((a) => (a.provider === provider && a.index === index) ? Object.assign({}, a, { availableModels: d.models }) : a))
1055
+ setInfo('โœ“ ' + (t('modelsSynced') || 'Models synced') + ': ' + d.count + ' models')
1056
+ } else {
1057
+ setErr('โœ— ' + ((d && d.doctor && d.doctor.title) || (d && d.error && d.error.message) || 'Sync failed'))
1058
+ }
1059
+ } catch (e) {
1060
+ setErr(cleanErrorMessage(e.message || e))
1061
+ }
1062
+ }
1063
+
1298
1064
  const runSmokeTest = async (provider, index) => {
1299
1065
  setSmoke({ testing: true, result: null })
1300
1066
  try {
@@ -1362,15 +1128,15 @@ const cssId = 'dsh-subscriptions/settings.module.css'
1362
1128
  // #81: settings snapshot status - never render phantom inputs before the
1363
1129
  // config snapshot arrives, and offer a retry when the store is unavailable.
1364
1130
  if (!draft) {
1365
- return React.createElement('div', { className: 'dsub-wrap' },
1366
- React.createElement('div', { className: 'dsub-row' },
1367
- React.createElement('span', { className: 'dsub-sub' }, err ? t('settingsUnavailable') : t('settingsLoading')),
1368
- err ? React.createElement('button', {
1131
+ return h('div', { className: 'dsub-wrap' },
1132
+ h('div', { className: 'dsub-row' },
1133
+ h('span', { className: 'dsub-sub' }, err ? t('settingsUnavailable') : t('settingsLoading')),
1134
+ err ? h('button', {
1369
1135
  type: 'button', className: 'dsub-mini',
1370
1136
  onClick: () => { setErr(''); reload().catch((e) => setErr(String(e && e.message || e))) },
1371
1137
  }, t('settingsRetry')) : null,
1372
1138
  ),
1373
- err ? React.createElement('div', { className: 'dsub-bad' }, err) : null,
1139
+ err ? h('div', { className: 'dsub-bad' }, err) : null,
1374
1140
  )
1375
1141
  }
1376
1142
 
@@ -1603,45 +1369,45 @@ const cssId = 'dsh-subscriptions/settings.module.css'
1603
1369
 
1604
1370
  const connectedCount = accounts.filter((a) => a.configured).length
1605
1371
 
1606
- return React.createElement('div', { className: 'dsub-wrap' },
1607
- React.createElement('div', { className: 'dsub-header-bar' },
1608
- React.createElement('div', { className: 'dsub-row', style: { marginTop: 0 } },
1609
- React.createElement('span', {
1372
+ return h('div', { className: 'dsub-wrap' },
1373
+ h('div', { className: 'dsub-header-bar' },
1374
+ h('div', { className: 'dsub-row', style: { marginTop: 0 } },
1375
+ h('span', {
1610
1376
  className: 'dsub-badge ' + (hostPing.ok ? 'dsub-badge-ok' : 'dsub-badge-bad')
1611
1377
  }, hostPing.ok
1612
1378
  ? (hostPing.latencyMs != null ? 'Host online (' + hostPing.latencyMs + ' ms)' : t('hostOnline'))
1613
1379
  : t('hostOffline')
1614
1380
  ),
1615
- React.createElement('span', {
1381
+ h('span', {
1616
1382
  className: 'dsub-badge ' + (connectedCount > 0 ? 'dsub-badge-ok' : 'dsub-badge-warn')
1617
1383
  }, connectedCount > 0
1618
1384
  ? (connectedCount + ' ' + t('subsLogged'))
1619
1385
  : t('subsNotLogged')
1620
1386
  ),
1621
- React.createElement('span', {
1387
+ h('span', {
1622
1388
  className: 'dsub-badge dsub-badge-neutral'
1623
1389
  }, 'Pool: ' + accounts.length + ' accounts'),
1624
1390
  updater.status && updater.status.updateAvailable
1625
- ? React.createElement('span', { className: 'dsub-badge dsub-badge-warn' },
1391
+ ? h('span', { className: 'dsub-badge dsub-badge-warn' },
1626
1392
  'โฌ† ' + t('updateAvailable') + ' (v' + (updater.status.latestVersion || '') + ')'
1627
1393
  )
1628
1394
  : (updater.status && updater.status.currentVersion
1629
- ? React.createElement('span', { className: 'dsub-badge dsub-badge-neutral' },
1395
+ ? h('span', { className: 'dsub-badge dsub-badge-neutral' },
1630
1396
  'v' + updater.status.currentVersion
1631
1397
  )
1632
1398
  : null
1633
1399
  ),
1634
1400
  ),
1635
- React.createElement('div', { className: 'dsub-row', style: { marginTop: 0, gap: '8px' } },
1401
+ h('div', { className: 'dsub-row', style: { marginTop: 0, gap: '8px' } },
1636
1402
  updater.status && updater.status.updateAvailable && updater.status.canAutoUpdate
1637
- ? React.createElement('button', {
1403
+ ? h('button', {
1638
1404
  type: 'button',
1639
1405
  className: 'dsub-mini dsub-btn-primary',
1640
1406
  disabled: updater.updating,
1641
1407
  onClick: () => performUpdate(),
1642
1408
  }, updater.updating ? t('updating') : (t('updateNow') + ' โ†’ v' + updater.status.latestVersion))
1643
1409
  : null,
1644
- React.createElement('button', {
1410
+ h('button', {
1645
1411
  type: 'button',
1646
1412
  className: 'dsub-mini',
1647
1413
  disabled: smoke.testing,
@@ -1649,69 +1415,69 @@ const cssId = 'dsh-subscriptions/settings.module.css'
1649
1415
  }, smoke.testing ? t('smokeTesting') : t('runSmoke')),
1650
1416
  ),
1651
1417
  ),
1652
- updater.message ? React.createElement('div', {
1418
+ updater.message ? h('div', {
1653
1419
  className: updater.message.includes(t('updateSuccessRestart')) ? 'dsub-alert-ok' : 'dsub-alert-bad',
1654
1420
  style: { marginBottom: '12px' }
1655
1421
  }, updater.message) : null,
1656
- smoke.result ? React.createElement('div', {
1422
+ smoke.result ? h('div', {
1657
1423
  className: smoke.result.ok ? 'dsub-alert-ok' : 'dsub-alert-bad',
1658
1424
  style: { marginBottom: '12px' }
1659
1425
  }, smoke.result.ok
1660
1426
  ? ('๐ŸŸข ' + t('smokeOk') + ': ' + (smoke.result.provider || 'Provider').toUpperCase() + ' ยท ' + (smoke.result.latencyMs != null ? smoke.result.latencyMs + ' ms' : 'OK') + (smoke.result.label ? ' (' + smoke.result.label + ')' : ''))
1661
1427
  : ('โŒ ' + t('smokeFail') + ': ' + (smoke.result.error && (smoke.result.error.message || smoke.result.error.code) || 'Unknown error'))
1662
1428
  ) : null,
1663
- telemetry && telemetry.totalRequests > 0 ? React.createElement('div', { className: 'dsub-grid-2', style: { marginBottom: '14px' } },
1664
- React.createElement('div', { className: 'dsub-stat-box' },
1665
- React.createElement('div', { className: 'dsub-stat-val' }, telemetry.successRequests + ' / ' + telemetry.totalRequests),
1666
- React.createElement('div', { className: 'dsub-stat-lbl' }, t('statsRequests')),
1429
+ telemetry && telemetry.totalRequests > 0 ? h('div', { className: 'dsub-grid-2', style: { marginBottom: '14px' } },
1430
+ h('div', { className: 'dsub-stat-box' },
1431
+ h('div', { className: 'dsub-stat-val' }, telemetry.successRequests + ' / ' + telemetry.totalRequests),
1432
+ h('div', { className: 'dsub-stat-lbl' }, t('statsRequests')),
1667
1433
  ),
1668
- React.createElement('div', { className: 'dsub-stat-box' },
1669
- React.createElement('div', { className: 'dsub-stat-val' }, (telemetry.avgLatencyMs || 0) + ' ms'),
1670
- React.createElement('div', { className: 'dsub-stat-lbl' }, t('statsLatency')),
1434
+ h('div', { className: 'dsub-stat-box' },
1435
+ h('div', { className: 'dsub-stat-val' }, (telemetry.avgLatencyMs || 0) + ' ms'),
1436
+ h('div', { className: 'dsub-stat-lbl' }, t('statsLatency')),
1671
1437
  ),
1672
- React.createElement('div', { className: 'dsub-stat-box' },
1673
- React.createElement('div', { className: 'dsub-stat-val' }, (telemetry.successRate || 100) + '%'),
1674
- React.createElement('div', { className: 'dsub-stat-lbl' }, t('statsSuccessRate')),
1438
+ h('div', { className: 'dsub-stat-box' },
1439
+ h('div', { className: 'dsub-stat-val' }, (telemetry.successRate || 100) + '%'),
1440
+ h('div', { className: 'dsub-stat-lbl' }, t('statsSuccessRate')),
1675
1441
  ),
1676
- React.createElement('div', { className: 'dsub-stat-box' },
1677
- React.createElement('div', { className: 'dsub-stat-val' }, (telemetry.cacheHitPercent || 0) + '%'),
1678
- React.createElement('div', { className: 'dsub-stat-lbl' }, t('cacheHitRate')),
1442
+ h('div', { className: 'dsub-stat-box' },
1443
+ h('div', { className: 'dsub-stat-val' }, (telemetry.cacheHitPercent || 0) + '%'),
1444
+ h('div', { className: 'dsub-stat-lbl' }, t('cacheHitRate')),
1679
1445
  ),
1680
- React.createElement('div', { className: 'dsub-stat-box' },
1681
- React.createElement('div', { className: 'dsub-stat-val' }, telemetry.lastRequestAt ? Math.round((Date.now() - telemetry.lastRequestAt) / 60000) + 'm ago' : 'โ€”'),
1682
- React.createElement('div', { className: 'dsub-stat-lbl' }, t('statsLastActivity')),
1446
+ h('div', { className: 'dsub-stat-box' },
1447
+ h('div', { className: 'dsub-stat-val' }, telemetry.lastRequestAt ? Math.round((Date.now() - telemetry.lastRequestAt) / 60000) + 'm ago' : 'โ€”'),
1448
+ h('div', { className: 'dsub-stat-lbl' }, t('statsLastActivity')),
1683
1449
  ),
1684
1450
  ) : null,
1685
- (analytics && (analytics.totalRequests > 0 || (analytics.hourly && analytics.hourly.some(function(b) { return b.requests > 0 })))) || (queueStats && (queueStats.totalActive > 0 || queueStats.totalQueued > 0)) ? React.createElement('details', { className: 'dsub-group', open: true, style: { marginBottom: '14px' } },
1686
- React.createElement('summary', { className: 'dsub-groupHead' }, '๐Ÿ“Š ' + t('analyticsTitle')),
1687
- React.createElement('div', { className: 'dsub-sub', style: { marginTop: '4px' } }, t('analyticsDesc')),
1688
- React.createElement('div', { className: 'dsub-grid-2', style: { marginTop: '10px' } },
1689
- React.createElement('div', { className: 'dsub-stat-box' },
1690
- React.createElement('div', { className: 'dsub-stat-val' }, ((analytics && analytics.cache && analytics.cache.cacheHitRate) || 0) + '%'),
1691
- React.createElement('div', { className: 'dsub-stat-lbl' }, t('cacheHitRate') + (analytics && analytics.cache ? ' (' + (analytics.cache.cacheReadTokens || 0).toLocaleString() + ' tok)' : '')),
1451
+ (analytics && (analytics.totalRequests > 0 || (analytics.hourly && analytics.hourly.some(function(b) { return b.requests > 0 })))) || (queueStats && (queueStats.totalActive > 0 || queueStats.totalQueued > 0)) ? h('details', { className: 'dsub-group', open: true, style: { marginBottom: '14px' } },
1452
+ h('summary', { className: 'dsub-groupHead' }, '๐Ÿ“Š ' + t('analyticsTitle')),
1453
+ h('div', { className: 'dsub-sub', style: { marginTop: '4px' } }, t('analyticsDesc')),
1454
+ h('div', { className: 'dsub-grid-2', style: { marginTop: '10px' } },
1455
+ h('div', { className: 'dsub-stat-box' },
1456
+ h('div', { className: 'dsub-stat-val' }, ((analytics && analytics.cache && analytics.cache.cacheHitRate) || 0) + '%'),
1457
+ h('div', { className: 'dsub-stat-lbl' }, t('cacheHitRate') + (analytics && analytics.cache ? ' (' + (analytics.cache.cacheReadTokens || 0).toLocaleString() + ' tok)' : '')),
1692
1458
  ),
1693
- React.createElement('div', { className: 'dsub-stat-box' },
1694
- React.createElement('div', { className: 'dsub-stat-val' }, (analytics && analytics.performance && analytics.performance.ttft && analytics.performance.ttft.avgMs != null ? analytics.performance.ttft.avgMs + ' ms' : 'โ€”')),
1695
- React.createElement('div', { className: 'dsub-stat-lbl' }, t('ttftMetric') + (analytics && analytics.performance && analytics.performance.ttft && analytics.performance.ttft.p95Ms != null ? ' ยท p95 ' + analytics.performance.ttft.p95Ms + ' ms' : '')),
1459
+ h('div', { className: 'dsub-stat-box' },
1460
+ h('div', { className: 'dsub-stat-val' }, (analytics && analytics.performance && analytics.performance.ttft && analytics.performance.ttft.avgMs != null ? analytics.performance.ttft.avgMs + ' ms' : 'โ€”')),
1461
+ h('div', { className: 'dsub-stat-lbl' }, t('ttftMetric') + (analytics && analytics.performance && analytics.performance.ttft && analytics.performance.ttft.p95Ms != null ? ' ยท p95 ' + analytics.performance.ttft.p95Ms + ' ms' : '')),
1696
1462
  ),
1697
- React.createElement('div', { className: 'dsub-stat-box' },
1698
- React.createElement('div', { className: 'dsub-stat-val' }, (analytics && analytics.performance && analytics.performance.tps && analytics.performance.tps.avg != null ? analytics.performance.tps.avg + ' tok/s' : 'โ€”')),
1699
- React.createElement('div', { className: 'dsub-stat-lbl' }, t('speedMetric') + (analytics && analytics.performance && analytics.performance.tps && analytics.performance.tps.p95 != null ? ' ยท p95 ' + analytics.performance.tps.p95 : '')),
1463
+ h('div', { className: 'dsub-stat-box' },
1464
+ h('div', { className: 'dsub-stat-val' }, (analytics && analytics.performance && analytics.performance.tps && analytics.performance.tps.avg != null ? analytics.performance.tps.avg + ' tok/s' : 'โ€”')),
1465
+ h('div', { className: 'dsub-stat-lbl' }, t('speedMetric') + (analytics && analytics.performance && analytics.performance.tps && analytics.performance.tps.p95 != null ? ' ยท p95 ' + analytics.performance.tps.p95 : '')),
1700
1466
  ),
1701
- React.createElement('div', { className: 'dsub-stat-box' },
1702
- React.createElement('div', { className: 'dsub-stat-val' }, (queueStats ? queueStats.totalActive : 0) + ' / ' + (queueStats ? queueStats.totalQueued : 0)),
1703
- React.createElement('div', { className: 'dsub-stat-lbl' }, t('queueActive') + ' / ' + t('queueWaiting') + (queueStats && queueStats.metrics && queueStats.metrics.totalOverflowed ? ' ยท ' + queueStats.metrics.totalOverflowed + ' ' + t('queueRejected') : '')),
1467
+ h('div', { className: 'dsub-stat-box' },
1468
+ h('div', { className: 'dsub-stat-val' }, (queueStats ? queueStats.totalActive : 0) + ' / ' + (queueStats ? queueStats.totalQueued : 0)),
1469
+ h('div', { className: 'dsub-stat-lbl' }, t('queueActive') + ' / ' + t('queueWaiting') + (queueStats && queueStats.metrics && queueStats.metrics.totalOverflowed ? ' ยท ' + queueStats.metrics.totalOverflowed + ' ' + t('queueRejected') : '')),
1704
1470
  ),
1705
1471
  ),
1706
1472
  analytics && Array.isArray(analytics.hourly) && analytics.hourly.length ? (function() {
1707
1473
  var maxReq = Math.max.apply(Math, [1].concat(analytics.hourly.map(function(b) { return b.requests || 0 })))
1708
- return React.createElement('div', { style: { marginTop: '12px' } },
1709
- React.createElement('div', { style: { fontSize: '11.5px', fontWeight: 600, color: 'var(--dsw-alias-label-secondary)' } }, t('activity24h')),
1710
- React.createElement('div', { className: 'dsub-chart-wrap' },
1474
+ return h('div', { style: { marginTop: '12px' } },
1475
+ h('div', { style: { fontSize: '11.5px', fontWeight: 600, color: 'var(--dsw-alias-label-secondary)' } }, t('activity24h')),
1476
+ h('div', { className: 'dsub-chart-wrap' },
1711
1477
  analytics.hourly.map(function(b, idx) {
1712
1478
  var pct = Math.max(4, Math.round(((b.requests || 0) / maxReq) * 100))
1713
1479
  var title = b.label + ': ' + b.requests + ' req (' + b.cacheReadTokens + ' cached tok, ' + b.errorCount + ' err)'
1714
- return React.createElement('div', {
1480
+ return h('div', {
1715
1481
  key: idx,
1716
1482
  className: 'dsub-chart-bar',
1717
1483
  style: {
@@ -1724,19 +1490,19 @@ const cssId = 'dsh-subscriptions/settings.module.css'
1724
1490
  })
1725
1491
  })
1726
1492
  ),
1727
- React.createElement('div', { className: 'dsub-chart-labels' },
1728
- React.createElement('span', null, '-24h'),
1729
- React.createElement('span', null, '-18h'),
1730
- React.createElement('span', null, '-12h'),
1731
- React.createElement('span', null, '-6h'),
1732
- React.createElement('span', null, 'Now'),
1493
+ h('div', { className: 'dsub-chart-labels' },
1494
+ h('span', null, '-24h'),
1495
+ h('span', null, '-18h'),
1496
+ h('span', null, '-12h'),
1497
+ h('span', null, '-6h'),
1498
+ h('span', null, 'Now'),
1733
1499
  ),
1734
1500
  )
1735
1501
  })() : null,
1736
- analytics && Array.isArray(analytics.forecast) && analytics.forecast.some(function(f) { return f.willExhaustBeforeReset || (f.burnRateTokensPerHour > 0 && f.hoursToExhaustion != null && f.hoursToExhaustion < 72) }) ? React.createElement('div', { style: { marginTop: '12px' } },
1737
- React.createElement('div', { style: { fontSize: '11.5px', fontWeight: 600, color: 'var(--dsw-alias-state-warn-primary)', marginBottom: '6px' } }, 'โš ๏ธ ' + t('forecastTitle')),
1502
+ analytics && Array.isArray(analytics.forecast) && analytics.forecast.some(function(f) { return f.willExhaustBeforeReset || (f.burnRateTokensPerHour > 0 && f.hoursToExhaustion != null && f.hoursToExhaustion < 72) }) ? h('div', { style: { marginTop: '12px' } },
1503
+ h('div', { style: { fontSize: '11.5px', fontWeight: 600, color: 'var(--dsw-alias-state-warn-primary)', marginBottom: '6px' } }, 'โš ๏ธ ' + t('forecastTitle')),
1738
1504
  analytics.forecast.filter(function(f) { return f.willExhaustBeforeReset || (f.burnRateTokensPerHour > 0 && f.hoursToExhaustion != null && f.hoursToExhaustion < 72) }).map(function(f, idx) {
1739
- return React.createElement('div', { key: idx, className: 'dsub-alert-bad', style: { marginBottom: '6px' } },
1505
+ return h('div', { key: idx, className: 'dsub-alert-bad', style: { marginBottom: '6px' } },
1740
1506
  (f.provider ? f.provider.toUpperCase() : 'LLM') + ' (' + (f.label || f.ref) + '): ' +
1741
1507
  (f.willExhaustBeforeReset ? t('forecastExhaustWarning') : (t('forecastRunway') + ': ~' + f.hoursToExhaustion + 'h')) +
1742
1508
  ' ยท ' + t('forecastBurnRate') + ': ' + f.burnRateTokensPerHour.toLocaleString() + ' tok/h'
@@ -1744,128 +1510,128 @@ const cssId = 'dsh-subscriptions/settings.module.css'
1744
1510
  })
1745
1511
  ) : null,
1746
1512
  ) : null,
1747
- telemetry && Array.isArray(telemetry.recentDecisions) && telemetry.recentDecisions.length ? React.createElement('details', { className: 'dsub-group', style: { marginBottom: '14px' } },
1748
- React.createElement('summary', { className: 'dsub-groupHead' }, '๐Ÿงญ ' + t('rotationDecisionsTitle')),
1749
- React.createElement('div', { className: 'dsub-sub', style: { marginTop: '4px' } }, t('rotationDecisionsDesc')),
1750
- React.createElement('div', { className: 'dsub-trace-box' },
1513
+ telemetry && Array.isArray(telemetry.recentDecisions) && telemetry.recentDecisions.length ? h('details', { className: 'dsub-group', style: { marginBottom: '14px' } },
1514
+ h('summary', { className: 'dsub-groupHead' }, '๐Ÿงญ ' + t('rotationDecisionsTitle')),
1515
+ h('div', { className: 'dsub-sub', style: { marginTop: '4px' } }, t('rotationDecisionsDesc')),
1516
+ h('div', { className: 'dsub-trace-box' },
1751
1517
  telemetry.recentDecisions.map((dec, idx) => {
1752
1518
  const reasonBadge = dec.cascaded ? ('๐Ÿ”€ ' + t('rotationCascaded')) : (dec.decisionReason === 'cache_pinned' ? ('๐Ÿ“Œ ' + t('cachePinnedBadge')) : (dec.decisionReason === 'session_pinned' ? '๐Ÿ“Œ Pinned' : ('โšก ' + dec.decisionReason)))
1753
- return React.createElement('div', { key: idx, className: 'dsub-trace-row' },
1754
- React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '6px' } },
1755
- dec.provider ? React.createElement('span', { className: 'dsub-brand dsub-brand-' + dec.provider, style: { fontSize: '9px', padding: '1px 4px' } }, dec.provider.toUpperCase()) : null,
1756
- React.createElement('span', { style: { fontWeight: 600 } }, dec.ref || 'โ€”'),
1757
- dec.model ? React.createElement('code', { style: { fontSize: '11px', opacity: 0.8 } }, dec.model) : null,
1519
+ return h('div', { key: idx, className: 'dsub-trace-row' },
1520
+ h('div', { style: { display: 'flex', alignItems: 'center', gap: '6px' } },
1521
+ dec.provider ? h('span', { className: 'dsub-brand dsub-brand-' + dec.provider, style: { fontSize: '9px', padding: '1px 4px' } }, dec.provider.toUpperCase()) : null,
1522
+ h('span', { style: { fontWeight: 600 } }, dec.ref || 'โ€”'),
1523
+ dec.model ? h('code', { style: { fontSize: '11px', opacity: 0.8 } }, dec.model) : null,
1758
1524
  ),
1759
- React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '8px' } },
1760
- React.createElement('span', { className: 'dsub-model-tag' }, reasonBadge),
1761
- React.createElement('span', { style: { fontSize: '10.5px', opacity: 0.6 } }, dec.attemptsCount > 1 ? (dec.attemptsCount + ' ' + t('rotationAttempts')) : ('1 ' + t('rotationAttempt'))),
1525
+ h('div', { style: { display: 'flex', alignItems: 'center', gap: '8px' } },
1526
+ h('span', { className: 'dsub-model-tag' }, reasonBadge),
1527
+ h('span', { style: { fontSize: '10.5px', opacity: 0.6 } }, dec.attemptsCount > 1 ? (dec.attemptsCount + ' ' + t('rotationAttempts')) : ('1 ' + t('rotationAttempt'))),
1762
1528
  ),
1763
1529
  )
1764
1530
  })
1765
1531
  ),
1766
1532
  ) : null,
1767
- accounts && accounts.length ? React.createElement('details', { className: 'dsub-group', open: true, style: { marginBottom: '14px' } },
1768
- React.createElement('summary', { className: 'dsub-groupHead' }, '๐Ÿ“Š ' + (t('healthMatrix') || 'Health Matrix & Quota Runway')),
1769
- React.createElement('div', { style: { padding: '8px 0', overflowX: 'auto' } },
1770
- React.createElement('table', { style: { width: '100%', fontSize: '12px', borderCollapse: 'collapse' } },
1771
- React.createElement('thead', null,
1772
- React.createElement('tr', { style: { borderBottom: '1px solid var(--dsw-alias-border-l2)', textAlign: 'left', opacity: 0.7 } },
1773
- React.createElement('th', { style: { padding: '6px' } }, t('healthAccount')),
1774
- React.createElement('th', { style: { padding: '6px' } }, t('healthScore')),
1775
- React.createElement('th', { style: { padding: '6px' } }, t('healthLatency')),
1776
- React.createElement('th', { style: { padding: '6px' } }, t('healthStatus')),
1777
- React.createElement('th', { style: { padding: '6px' } }, t('healthQuota')),
1533
+ accounts && accounts.length ? h('details', { className: 'dsub-group', open: true, style: { marginBottom: '14px' } },
1534
+ h('summary', { className: 'dsub-groupHead' }, '๐Ÿ“Š ' + (t('healthMatrix') || 'Health Matrix & Quota Runway')),
1535
+ h('div', { style: { padding: '8px 0', overflowX: 'auto' } },
1536
+ h('table', { style: { width: '100%', fontSize: '12px', borderCollapse: 'collapse' } },
1537
+ h('thead', null,
1538
+ h('tr', { style: { borderBottom: '1px solid var(--dsw-alias-border-l2)', textAlign: 'left', opacity: 0.7 } },
1539
+ h('th', { style: { padding: '6px' } }, t('healthAccount')),
1540
+ h('th', { style: { padding: '6px' } }, t('healthScore')),
1541
+ h('th', { style: { padding: '6px' } }, t('healthLatency')),
1542
+ h('th', { style: { padding: '6px' } }, t('healthStatus')),
1543
+ h('th', { style: { padding: '6px' } }, t('healthQuota')),
1778
1544
  ),
1779
1545
  ),
1780
- React.createElement('tbody', null,
1546
+ h('tbody', null,
1781
1547
  accounts.map((acc, idx) => {
1782
1548
  const sc = acc.healthScore != null ? acc.healthScore : 100
1783
1549
  const healthColor = sc >= 80 ? 'var(--dsw-alias-state-success-primary)' : (sc >= 50 ? 'var(--dsw-alias-state-warn-primary)' : 'var(--dsw-alias-state-error-primary)')
1784
1550
  const isQ = acc.status === 'quarantine' || (acc.quarantineUntil && Number(acc.quarantineUntil) > Date.now())
1785
1551
  const statusLabel = isQ ? ('โ›” ' + t('healthQuarantine')) : (acc.status === 'probing' ? ('๐ŸŸก ' + t('healthWarmup')) : (acc.configured ? ('๐ŸŸข ' + t('healthActive')) : ('โšช ' + t('healthIdle'))))
1786
1552
  const pct = acc.usagePercent != null ? Math.round(acc.usagePercent) : null
1787
- return React.createElement('tr', { key: (acc.ref || acc.provider + acc.index || idx), style: { borderBottom: '1px solid var(--dsw-alias-border-l3)' } },
1788
- React.createElement('td', { style: { padding: '6px', fontWeight: 600 } }, (acc.provider ? acc.provider.toUpperCase() : 'LLM') + ' #' + (acc.index || 1) + (acc.label ? ' (' + acc.label + ')' : '')),
1789
- React.createElement('td', { style: { padding: '6px', color: healthColor } }, sc + '%'),
1790
- React.createElement('td', { style: { padding: '6px' } }, acc.latencyMs ? acc.latencyMs + ' ms' : 'โ€”'),
1791
- React.createElement('td', { style: { padding: '6px' } }, statusLabel),
1792
- React.createElement('td', { style: { padding: '6px' } }, pct != null ? (pct + '% used') : 'โ€”'),
1553
+ return h('tr', { key: (acc.ref || acc.provider + acc.index || idx), style: { borderBottom: '1px solid var(--dsw-alias-border-l3)' } },
1554
+ h('td', { style: { padding: '6px', fontWeight: 600 } }, (acc.provider ? acc.provider.toUpperCase() : 'LLM') + ' #' + (acc.index || 1) + (acc.label ? ' (' + acc.label + ')' : '')),
1555
+ h('td', { style: { padding: '6px', color: healthColor } }, sc + '%'),
1556
+ h('td', { style: { padding: '6px' } }, acc.latencyMs ? acc.latencyMs + ' ms' : 'โ€”'),
1557
+ h('td', { style: { padding: '6px' } }, statusLabel),
1558
+ h('td', { style: { padding: '6px' } }, pct != null ? (pct + '% used') : 'โ€”'),
1793
1559
  )
1794
1560
  }),
1795
1561
  ),
1796
1562
  ),
1797
1563
  ),
1798
1564
  ) : null,
1799
- React.createElement('div', { className: 'dsub-block' },
1800
- React.createElement('div', { className: 'dsub-h' }, t('title')),
1801
- React.createElement('div', { className: 'dsub-sub' },
1565
+ h('div', { className: 'dsub-block' },
1566
+ h('div', { className: 'dsub-h' }, t('title')),
1567
+ h('div', { className: 'dsub-sub' },
1802
1568
  t('intro')),
1803
- React.createElement('details', { className: 'dsub-group', open: true },
1804
- React.createElement('summary', { className: 'dsub-groupHead' }, t('groupAuth')),
1805
- React.createElement('label', { className: 'dsub-row' },
1806
- React.createElement('input', {
1569
+ h('details', { className: 'dsub-group', open: true },
1570
+ h('summary', { className: 'dsub-groupHead' }, t('groupAuth')),
1571
+ h('label', { className: 'dsub-row' },
1572
+ h('input', {
1807
1573
  type: 'checkbox',
1808
1574
  checked: !!draft.useWebCallback,
1809
1575
  onChange: (e) => setDraft((d) => Object.assign({}, d, { useWebCallback: e.target.checked })),
1810
1576
  }),
1811
- React.createElement('span', null, t('useOrigin')),
1577
+ h('span', null, t('useOrigin')),
1812
1578
  ),
1813
- React.createElement('div', { className: 'dsub-sub' },
1579
+ h('div', { className: 'dsub-sub' },
1814
1580
  t('useOriginHint')),
1815
- React.createElement('label', { className: 'dsub-row' },
1816
- React.createElement('input', {
1581
+ h('label', { className: 'dsub-row' },
1582
+ h('input', {
1817
1583
  type: 'checkbox',
1818
1584
  checked: !!draft.autoLoopback,
1819
1585
  onChange: (e) => setDraft((d) => Object.assign({}, d, { autoLoopback: e.target.checked })),
1820
1586
  }),
1821
- React.createElement('span', null, t('autoLoopback')),
1587
+ h('span', null, t('autoLoopback')),
1822
1588
  ),
1823
- React.createElement('div', { className: 'dsub-sub' },
1589
+ h('div', { className: 'dsub-sub' },
1824
1590
  t('autoLoopbackHint')),
1825
1591
  ),
1826
- React.createElement('details', { className: 'dsub-group', open: true },
1827
- React.createElement('summary', { className: 'dsub-groupHead' }, t('groupPrivacy')),
1828
- React.createElement('label', { className: 'dsub-row' },
1829
- React.createElement('input', {
1592
+ h('details', { className: 'dsub-group', open: true },
1593
+ h('summary', { className: 'dsub-groupHead' }, t('groupPrivacy')),
1594
+ h('label', { className: 'dsub-row' },
1595
+ h('input', {
1830
1596
  type: 'checkbox',
1831
1597
  checked: !!draft.privacyMask,
1832
1598
  onChange: (e) => setDraft((d) => Object.assign({}, d, { privacyMask: e.target.checked })),
1833
1599
  }),
1834
- React.createElement('span', null, t('privacyMask')),
1600
+ h('span', null, t('privacyMask')),
1835
1601
  ),
1836
- React.createElement('div', { className: 'dsub-sub' },
1602
+ h('div', { className: 'dsub-sub' },
1837
1603
  t('privacyMaskHint')),
1838
- React.createElement('label', { className: 'dsub-row' },
1839
- React.createElement('input', {
1604
+ h('label', { className: 'dsub-row' },
1605
+ h('input', {
1840
1606
  type: 'checkbox',
1841
1607
  checked: !!draft.hideDeprecatedModels,
1842
1608
  onChange: (e) => setDraft((d) => Object.assign({}, d, { hideDeprecatedModels: e.target.checked })),
1843
1609
  }),
1844
- React.createElement('span', null, t('hideDeprecated')),
1610
+ h('span', null, t('hideDeprecated')),
1845
1611
  ),
1846
- React.createElement('div', { className: 'dsub-sub' },
1612
+ h('div', { className: 'dsub-sub' },
1847
1613
  t('hideDeprecatedHint')),
1848
1614
  ),
1849
- React.createElement('details', { className: 'dsub-group', open: true },
1850
- React.createElement('summary', { className: 'dsub-groupHead' }, t('groupRotation')),
1851
- React.createElement('div', { className: 'dsub-row' },
1852
- React.createElement('span', { className: 'dsub-h' }, t('composerQuota')),
1853
- React.createElement('select', {
1615
+ h('details', { className: 'dsub-group', open: true },
1616
+ h('summary', { className: 'dsub-groupHead' }, t('groupRotation')),
1617
+ h('div', { className: 'dsub-row' },
1618
+ h('span', { className: 'dsub-h' }, t('composerQuota')),
1619
+ h('select', {
1854
1620
  className: 'dsub-select',
1855
1621
  value: draft.composerQuota || 'percent',
1856
1622
  onChange: (e) => setDraft((d) => Object.assign({}, d, { composerQuota: e.target.value })),
1857
1623
  },
1858
- React.createElement('option', { value: 'off' }, t('composerQuotaOff')),
1859
- React.createElement('option', { value: 'percent' }, t('composerQuotaPercent')),
1860
- React.createElement('option', { value: 'bar' }, t('composerQuotaBar')),
1861
- React.createElement('option', { value: 'forecast' }, t('composerQuotaForecast')),
1624
+ h('option', { value: 'off' }, t('composerQuotaOff')),
1625
+ h('option', { value: 'percent' }, t('composerQuotaPercent')),
1626
+ h('option', { value: 'bar' }, t('composerQuotaBar')),
1627
+ h('option', { value: 'forecast' }, t('composerQuotaForecast')),
1862
1628
  ),
1863
1629
  ),
1864
- React.createElement('div', { className: 'dsub-sub' },
1630
+ h('div', { className: 'dsub-sub' },
1865
1631
  t('composerQuotaHint')),
1866
- React.createElement('div', { className: 'dsub-row' },
1867
- React.createElement('span', { className: 'dsub-h' }, t('expiryNotifyDays')),
1868
- React.createElement('input', {
1632
+ h('div', { className: 'dsub-row' },
1633
+ h('span', { className: 'dsub-h' }, t('expiryNotifyDays')),
1634
+ h('input', {
1869
1635
  type: 'number',
1870
1636
  className: 'dsub-inp',
1871
1637
  style: { width: '80px', minWidth: '80px' },
@@ -1875,23 +1641,23 @@ const cssId = 'dsh-subscriptions/settings.module.css'
1875
1641
  onChange: (e) => setDraft((d) => Object.assign({}, d, { expiryNotifyDays: Number(e.target.value) || 0 })),
1876
1642
  }),
1877
1643
  ),
1878
- React.createElement('div', { className: 'dsub-sub' },
1644
+ h('div', { className: 'dsub-sub' },
1879
1645
  t('expiryNotifyDaysHint')),
1880
1646
  ),
1881
- React.createElement('details', { className: 'dsub-group', open: true },
1882
- React.createElement('summary', { className: 'dsub-groupHead' }, '๐Ÿšฆ ' + t('groupQueue')),
1883
- React.createElement('label', { className: 'dsub-row' },
1884
- React.createElement('input', {
1647
+ h('details', { className: 'dsub-group', open: true },
1648
+ h('summary', { className: 'dsub-groupHead' }, '๐Ÿšฆ ' + t('groupQueue')),
1649
+ h('label', { className: 'dsub-row' },
1650
+ h('input', {
1885
1651
  type: 'checkbox',
1886
1652
  checked: draft.enableQueue !== false,
1887
1653
  onChange: function(e) { setDraft(function(d) { return Object.assign({}, d, { enableQueue: e.target.checked }) }) },
1888
1654
  }),
1889
- React.createElement('span', null, t('enableQueue')),
1655
+ h('span', null, t('enableQueue')),
1890
1656
  ),
1891
- React.createElement('div', { className: 'dsub-sub' }, t('enableQueueHint')),
1892
- React.createElement('div', { className: 'dsub-row' },
1893
- React.createElement('span', { className: 'dsub-h' }, t('accountMaxConcurrency')),
1894
- React.createElement('input', {
1657
+ h('div', { className: 'dsub-sub' }, t('enableQueueHint')),
1658
+ h('div', { className: 'dsub-row' },
1659
+ h('span', { className: 'dsub-h' }, t('accountMaxConcurrency')),
1660
+ h('input', {
1895
1661
  type: 'number',
1896
1662
  className: 'dsub-inp',
1897
1663
  style: { width: '80px', minWidth: '80px' },
@@ -1901,10 +1667,10 @@ const cssId = 'dsh-subscriptions/settings.module.css'
1901
1667
  onChange: function(e) { setDraft(function(d) { return Object.assign({}, d, { accountMaxConcurrency: Math.max(1, Number(e.target.value) || 2) }) }) },
1902
1668
  }),
1903
1669
  ),
1904
- React.createElement('div', { className: 'dsub-sub' }, t('accountMaxConcurrencyHint')),
1905
- React.createElement('div', { className: 'dsub-row' },
1906
- React.createElement('span', { className: 'dsub-h' }, t('maxQueueSize')),
1907
- React.createElement('input', {
1670
+ h('div', { className: 'dsub-sub' }, t('accountMaxConcurrencyHint')),
1671
+ h('div', { className: 'dsub-row' },
1672
+ h('span', { className: 'dsub-h' }, t('maxQueueSize')),
1673
+ h('input', {
1908
1674
  type: 'number',
1909
1675
  className: 'dsub-inp',
1910
1676
  style: { width: '80px', minWidth: '80px' },
@@ -1914,10 +1680,10 @@ const cssId = 'dsh-subscriptions/settings.module.css'
1914
1680
  onChange: function(e) { setDraft(function(d) { return Object.assign({}, d, { maxQueueSize: Math.max(1, Number(e.target.value) || 20) }) }) },
1915
1681
  }),
1916
1682
  ),
1917
- React.createElement('div', { className: 'dsub-sub' }, t('maxQueueSizeHint')),
1918
- React.createElement('div', { className: 'dsub-row' },
1919
- React.createElement('span', { className: 'dsub-h' }, t('queueTimeoutSec')),
1920
- React.createElement('input', {
1683
+ h('div', { className: 'dsub-sub' }, t('maxQueueSizeHint')),
1684
+ h('div', { className: 'dsub-row' },
1685
+ h('span', { className: 'dsub-h' }, t('queueTimeoutSec')),
1686
+ h('input', {
1921
1687
  type: 'number',
1922
1688
  className: 'dsub-inp',
1923
1689
  style: { width: '80px', minWidth: '80px' },
@@ -1927,52 +1693,52 @@ const cssId = 'dsh-subscriptions/settings.module.css'
1927
1693
  onChange: function(e) { setDraft(function(d) { return Object.assign({}, d, { queueTimeoutMs: Math.max(1, Number(e.target.value) || 30) * 1000 }) }) },
1928
1694
  }),
1929
1695
  ),
1930
- React.createElement('div', { className: 'dsub-sub' }, t('queueTimeoutSecHint')),
1696
+ h('div', { className: 'dsub-sub' }, t('queueTimeoutSecHint')),
1931
1697
  ),
1932
- React.createElement('details', { className: 'dsub-group', open: true },
1933
- React.createElement('summary', { className: 'dsub-groupHead' }, t('groupProvider')),
1934
- React.createElement('label', { className: 'dsub-row' },
1935
- React.createElement('input', {
1698
+ h('details', { className: 'dsub-group', open: true },
1699
+ h('summary', { className: 'dsub-groupHead' }, t('groupProvider')),
1700
+ h('label', { className: 'dsub-row' },
1701
+ h('input', {
1936
1702
  type: 'checkbox',
1937
1703
  checked: !!draft.codexFastMode,
1938
1704
  onChange: (e) => setDraft((d) => Object.assign({}, d, { codexFastMode: e.target.checked })),
1939
1705
  }),
1940
- React.createElement('span', null, t('codexFastMode')),
1706
+ h('span', null, t('codexFastMode')),
1941
1707
  ),
1942
- React.createElement('div', { className: 'dsub-sub' },
1708
+ h('div', { className: 'dsub-sub' },
1943
1709
  t('codexFastModeHint')),
1944
- React.createElement('div', { className: 'dsub-row' },
1945
- React.createElement('span', { className: 'dsub-h' }, t('codexVerbosity')),
1946
- React.createElement('select', {
1710
+ h('div', { className: 'dsub-row' },
1711
+ h('span', { className: 'dsub-h' }, t('codexVerbosity')),
1712
+ h('select', {
1947
1713
  className: 'dsub-select',
1948
1714
  value: draft.codexVerbosity || 'default',
1949
1715
  onChange: (e) => setDraft((d) => Object.assign({}, d, { codexVerbosity: e.target.value })),
1950
1716
  },
1951
- React.createElement('option', { value: 'default' }, t('codexVerbosityDefault')),
1952
- React.createElement('option', { value: 'low' }, t('codexVerbosityLow')),
1953
- React.createElement('option', { value: 'medium' }, t('codexVerbosityMedium')),
1954
- React.createElement('option', { value: 'high' }, t('codexVerbosityHigh')),
1717
+ h('option', { value: 'default' }, t('codexVerbosityDefault')),
1718
+ h('option', { value: 'low' }, t('codexVerbosityLow')),
1719
+ h('option', { value: 'medium' }, t('codexVerbosityMedium')),
1720
+ h('option', { value: 'high' }, t('codexVerbosityHigh')),
1955
1721
  ),
1956
1722
  ),
1957
- React.createElement('div', { className: 'dsub-sub' },
1723
+ h('div', { className: 'dsub-sub' },
1958
1724
  t('codexVerbosityHint')),
1959
- React.createElement('div', { className: 'dsub-row' },
1960
- React.createElement('span', { className: 'dsub-h' }, t('copilotMode')),
1961
- React.createElement('select', {
1725
+ h('div', { className: 'dsub-row' },
1726
+ h('span', { className: 'dsub-h' }, t('copilotMode')),
1727
+ h('select', {
1962
1728
  className: 'dsub-select',
1963
1729
  value: draft.copilotMode || 'auto',
1964
1730
  onChange: (e) => setDraft((d) => Object.assign({}, d, { copilotMode: e.target.value })),
1965
1731
  },
1966
- React.createElement('option', { value: 'auto' }, t('copilotModeAuto')),
1967
- React.createElement('option', { value: 'cli' }, t('copilotModeCli')),
1968
- React.createElement('option', { value: 'web' }, t('copilotModeWeb')),
1732
+ h('option', { value: 'auto' }, t('copilotModeAuto')),
1733
+ h('option', { value: 'cli' }, t('copilotModeCli')),
1734
+ h('option', { value: 'web' }, t('copilotModeWeb')),
1969
1735
  ),
1970
1736
  ),
1971
- React.createElement('div', { className: 'dsub-sub' },
1737
+ h('div', { className: 'dsub-sub' },
1972
1738
  t('copilotModeHint')),
1973
- React.createElement('div', { className: 'dsub-row' },
1974
- React.createElement('span', { className: 'dsub-h' }, t('copilotCliPath')),
1975
- React.createElement('input', {
1739
+ h('div', { className: 'dsub-row' },
1740
+ h('span', { className: 'dsub-h' }, t('copilotCliPath')),
1741
+ h('input', {
1976
1742
  className: 'dsub-input',
1977
1743
  type: 'text',
1978
1744
  value: draft.copilotCliPath || '',
@@ -1980,30 +1746,30 @@ const cssId = 'dsh-subscriptions/settings.module.css'
1980
1746
  onChange: (e) => setDraft((d) => Object.assign({}, d, { copilotCliPath: e.target.value })),
1981
1747
  }),
1982
1748
  ),
1983
- React.createElement('div', { className: 'dsub-sub' },
1749
+ h('div', { className: 'dsub-sub' },
1984
1750
  t('copilotCliPathHint')),
1985
1751
  ),
1986
- React.createElement('details', { className: 'dsub-group', open: true },
1987
- React.createElement('summary', { className: 'dsub-groupHead' }, t('groupFallback')),
1988
- React.createElement('label', { className: 'dsub-row' },
1989
- React.createElement('input', {
1752
+ h('details', { className: 'dsub-group', open: true },
1753
+ h('summary', { className: 'dsub-groupHead' }, t('groupFallback')),
1754
+ h('label', { className: 'dsub-row' },
1755
+ h('input', {
1990
1756
  type: 'checkbox',
1991
1757
  checked: !!draft.ollamaFallback,
1992
1758
  onChange: (e) => setDraft((d) => Object.assign({}, d, { ollamaFallback: e.target.checked })),
1993
1759
  }),
1994
- React.createElement('span', null, t('ollamaFallback')),
1760
+ h('span', null, t('ollamaFallback')),
1995
1761
  ),
1996
- React.createElement('div', { className: 'dsub-sub' },
1762
+ h('div', { className: 'dsub-sub' },
1997
1763
  t('ollamaFallbackHint')),
1998
- draft.ollamaFallback ? React.createElement('div', { className: 'dsub-row' },
1999
- React.createElement('input', {
1764
+ draft.ollamaFallback ? h('div', { className: 'dsub-row' },
1765
+ h('input', {
2000
1766
  type: 'text',
2001
1767
  className: 'dsub-inp dsub-grow',
2002
1768
  placeholder: 'http://localhost:11434',
2003
1769
  value: draft.ollamaBaseUrl || '',
2004
1770
  onChange: (e) => setDraft((d) => Object.assign({}, d, { ollamaBaseUrl: e.target.value })),
2005
1771
  }),
2006
- React.createElement('input', {
1772
+ h('input', {
2007
1773
  type: 'text',
2008
1774
  className: 'dsub-inp dsub-grow',
2009
1775
  placeholder: 'llama3:latest',
@@ -2012,10 +1778,10 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2012
1778
  }),
2013
1779
  ) : null,
2014
1780
  ),
2015
- React.createElement('details', { className: 'dsub-group' },
2016
- React.createElement('summary', { className: 'dsub-groupHead' }, '๐ŸŽฏ ' + t('modelsCatalogTitle')),
2017
- React.createElement('div', { className: 'dsub-sub', style: { marginTop: '4px' } }, t('modelsCatalogDesc')),
2018
- React.createElement('div', { className: 'dsub-model-grid' },
1781
+ h('details', { className: 'dsub-group' },
1782
+ h('summary', { className: 'dsub-groupHead' }, '๐ŸŽฏ ' + t('modelsCatalogTitle')),
1783
+ h('div', { className: 'dsub-sub', style: { marginTop: '4px' } }, t('modelsCatalogDesc')),
1784
+ h('div', { className: 'dsub-model-grid' },
2019
1785
  (Array.isArray(modelsCatalog) && modelsCatalog.length ? modelsCatalog : [
2020
1786
  { id: 'gpt-4o', contextLabel: '128k', capabilities: ['vision'], pool: { status: 'available' } },
2021
1787
  { id: 'o1 / o3-mini', contextLabel: '200k', capabilities: ['reasoning'], pool: { status: 'available' } },
@@ -2054,22 +1820,22 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2054
1820
  }
2055
1821
  }
2056
1822
 
2057
- return React.createElement('div', { key: (m.id || idx) + '_' + idx, className: 'dsub-model-chip' },
2058
- m.provider ? React.createElement('span', { className: 'dsub-brand dsub-brand-' + m.provider, style: { fontSize: '9px', padding: '1px 4px' } }, m.provider.toUpperCase()) : null,
2059
- React.createElement('code', null, m.name || m.id),
2060
- tags.length ? React.createElement('span', { className: 'dsub-model-tag' }, tags.join(' ยท ')) : null,
2061
- React.createElement('span', { className: 'dsub-model-tag ' + statusClass }, poolLabel),
1823
+ return h('div', { key: (m.id || idx) + '_' + idx, className: 'dsub-model-chip' },
1824
+ m.provider ? h('span', { className: 'dsub-brand dsub-brand-' + m.provider, style: { fontSize: '9px', padding: '1px 4px' } }, m.provider.toUpperCase()) : null,
1825
+ h('code', null, m.name || m.id),
1826
+ tags.length ? h('span', { className: 'dsub-model-tag' }, tags.join(' ยท ')) : null,
1827
+ h('span', { className: 'dsub-model-tag ' + statusClass }, poolLabel),
2062
1828
  )
2063
1829
  })
2064
1830
  ),
2065
1831
  ),
2066
- React.createElement('details', { className: 'dsub-group' },
2067
- React.createElement('summary', { className: 'dsub-groupHead' }, '๐Ÿง  ' + t('reasoningEffortTitle')),
2068
- React.createElement('div', { className: 'dsub-sub', style: { marginTop: '4px' } }, t('reasoningEffortDesc')),
2069
- React.createElement('div', { style: { display: 'flex', flexWrap: 'wrap', gap: '8px', marginTop: '10px' } },
1832
+ h('details', { className: 'dsub-group' },
1833
+ h('summary', { className: 'dsub-groupHead' }, '๐Ÿง  ' + t('reasoningEffortTitle')),
1834
+ h('div', { className: 'dsub-sub', style: { marginTop: '4px' } }, t('reasoningEffortDesc')),
1835
+ h('div', { style: { display: 'flex', flexWrap: 'wrap', gap: '8px', marginTop: '10px' } },
2070
1836
  ['off', 'low', 'medium', 'high', 'max'].map((lvl) => {
2071
1837
  const label = lvl === 'off' ? t('reasoningLevelOff') : (lvl.charAt(0).toUpperCase() + lvl.slice(1))
2072
- return React.createElement('span', {
1838
+ return h('span', {
2073
1839
  key: lvl,
2074
1840
  className: 'dsub-model-tag',
2075
1841
  style: { padding: '4px 10px', fontSize: '12px', cursor: 'default' }
@@ -2077,12 +1843,12 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2077
1843
  })
2078
1844
  )
2079
1845
  ),
2080
- React.createElement('details', { className: 'dsub-details' },
2081
- React.createElement('summary', { className: 'dsub-summary' }, t('advancedSettings')),
2082
- React.createElement('div', { className: 'dsub-block' },
2083
- React.createElement('div', { className: 'dsub-row' },
2084
- React.createElement('span', { className: 'dsub-h' }, t('cooldownMs')),
2085
- React.createElement('input', {
1846
+ h('details', { className: 'dsub-details' },
1847
+ h('summary', { className: 'dsub-summary' }, t('advancedSettings')),
1848
+ h('div', { className: 'dsub-block' },
1849
+ h('div', { className: 'dsub-row' },
1850
+ h('span', { className: 'dsub-h' }, t('cooldownMs')),
1851
+ h('input', {
2086
1852
  type: 'number',
2087
1853
  className: 'dsub-inp',
2088
1854
  style: { width: '80px', minWidth: '80px' },
@@ -2092,10 +1858,10 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2092
1858
  onChange: (e) => setDraft((d) => Object.assign({}, d, { cooldownMs: (Number(e.target.value) || 10) * 60000 })),
2093
1859
  }),
2094
1860
  ),
2095
- React.createElement('div', { className: 'dsub-sub' }, t('cooldownMsHint')),
2096
- React.createElement('div', { className: 'dsub-row' },
2097
- React.createElement('span', { className: 'dsub-h' }, t('probeIntervalMin')),
2098
- React.createElement('input', {
1861
+ h('div', { className: 'dsub-sub' }, t('cooldownMsHint')),
1862
+ h('div', { className: 'dsub-row' },
1863
+ h('span', { className: 'dsub-h' }, t('probeIntervalMin')),
1864
+ h('input', {
2099
1865
  type: 'number',
2100
1866
  className: 'dsub-inp',
2101
1867
  style: { width: '80px', minWidth: '80px' },
@@ -2105,34 +1871,34 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2105
1871
  onChange: (e) => setDraft((d) => Object.assign({}, d, { probeIntervalMin: Number(e.target.value) || 15 })),
2106
1872
  }),
2107
1873
  ),
2108
- React.createElement('div', { className: 'dsub-sub' }, t('probeIntervalMinHint')),
2109
- React.createElement('label', { className: 'dsub-row' },
2110
- React.createElement('input', {
1874
+ h('div', { className: 'dsub-sub' }, t('probeIntervalMinHint')),
1875
+ h('label', { className: 'dsub-row' },
1876
+ h('input', {
2111
1877
  type: 'checkbox',
2112
1878
  checked: draft.notifyLimits !== false,
2113
1879
  onChange: (e) => setDraft((d) => Object.assign({}, d, { notifyLimits: e.target.checked })),
2114
1880
  }),
2115
- React.createElement('span', null, t('notifyLimits')),
1881
+ h('span', null, t('notifyLimits')),
2116
1882
  ),
2117
- React.createElement('div', { className: 'dsub-sub' }, t('notifyLimitsHint')),
2118
- React.createElement('label', { className: 'dsub-row', style: { marginTop: 10 } },
2119
- React.createElement('input', {
1883
+ h('div', { className: 'dsub-sub' }, t('notifyLimitsHint')),
1884
+ h('label', { className: 'dsub-row', style: { marginTop: 10 } },
1885
+ h('input', {
2120
1886
  type: 'checkbox',
2121
1887
  checked: Boolean(draft.cascadingFallback),
2122
1888
  onChange: (e) => setDraft((d) => Object.assign({}, d, { cascadingFallback: e.target.checked })),
2123
1889
  }),
2124
- React.createElement('span', null, t('cascadingFallback')),
1890
+ h('span', null, t('cascadingFallback')),
2125
1891
  ),
2126
- React.createElement('div', { className: 'dsub-sub' }, t('cascadingFallbackHint')),
2127
- Boolean(draft.cascadingFallback) ? React.createElement('div', { style: { marginTop: 8, padding: '8px 12px', background: 'var(--dsw-alias-bg-layer-2)', borderRadius: 8 } },
2128
- React.createElement('div', { style: { fontSize: 12, fontWeight: 600, marginBottom: 4 } }, t('cascadingFallbackOrder')),
2129
- React.createElement('div', { className: 'dsub-sub', style: { marginBottom: 8 } }, t('cascadingFallbackOrderHint')),
2130
- React.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: 4 } },
1892
+ h('div', { className: 'dsub-sub' }, t('cascadingFallbackHint')),
1893
+ Boolean(draft.cascadingFallback) ? h('div', { style: { marginTop: 8, padding: '8px 12px', background: 'var(--dsw-alias-bg-layer-2)', borderRadius: 8 } },
1894
+ h('div', { style: { fontSize: 12, fontWeight: 600, marginBottom: 4 } }, t('cascadingFallbackOrder')),
1895
+ h('div', { className: 'dsub-sub', style: { marginBottom: 8 } }, t('cascadingFallbackOrderHint')),
1896
+ h('div', { style: { display: 'flex', flexDirection: 'column', gap: 4 } },
2131
1897
  (Array.isArray(draft.cascadingFallbackOrder) && draft.cascadingFallbackOrder.length ? draft.cascadingFallbackOrder : (providers.length ? providers : ['antigravity', 'claude', 'codex', 'grok', 'copilot', 'cursor'])).map((p, idx, arr) => {
2132
- return React.createElement('div', { key: p, style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '4px 8px', background: 'var(--dsw-alias-bg-layer-1)', borderRadius: 6, fontSize: 12 } },
2133
- React.createElement('span', null, (idx + 1) + '. ' + p.toUpperCase()),
2134
- React.createElement('div', { style: { display: 'flex', gap: 4 } },
2135
- idx > 0 ? React.createElement('button', {
1898
+ return h('div', { key: p, style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '4px 8px', background: 'var(--dsw-alias-bg-layer-1)', borderRadius: 6, fontSize: 12 } },
1899
+ h('span', null, (idx + 1) + '. ' + p.toUpperCase()),
1900
+ h('div', { style: { display: 'flex', gap: 4 } },
1901
+ idx > 0 ? h('button', {
2136
1902
  type: 'button', className: 'dsub-mini', style: { padding: '1px 6px', fontSize: 10 },
2137
1903
  onClick: () => {
2138
1904
  const next = arr.slice()
@@ -2142,7 +1908,7 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2142
1908
  setDraft((d) => Object.assign({}, d, { cascadingFallbackOrder: next }))
2143
1909
  }
2144
1910
  }, 'โ–ฒ') : null,
2145
- idx < arr.length - 1 ? React.createElement('button', {
1911
+ idx < arr.length - 1 ? h('button', {
2146
1912
  type: 'button', className: 'dsub-mini', style: { padding: '1px 6px', fontSize: 10 },
2147
1913
  onClick: () => {
2148
1914
  const next = arr.slice()
@@ -2158,35 +1924,62 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2158
1924
  )
2159
1925
  ) : null,
2160
1926
  ),
1927
+ h('div', { className: 'dsub-row', style: { marginTop: 12 } },
1928
+ h('label', { style: { display: 'flex', flexDirection: 'column', gap: 4 } },
1929
+ h('span', { style: { fontWeight: 600 } }, t('rotationStrategy')),
1930
+ h('span', { className: 'dsub-sub' }, t('rotationStrategyHint')),
1931
+ h('select', {
1932
+ className: 'dsub-select',
1933
+ value: draft.rotationStrategy || 'round-robin',
1934
+ onChange: (e) => setDraft((d) => Object.assign({}, d, { rotationStrategy: e.target.value })),
1935
+ style: { maxWidth: 320, marginTop: 4 }
1936
+ },
1937
+ h('option', { value: 'round-robin' }, t('rotationRoundRobin')),
1938
+ h('option', { value: 'least-loaded' }, t('rotationLeastLoaded')),
1939
+ h('option', { value: 'priority' }, t('rotationPriority')),
1940
+ ),
1941
+ ),
1942
+ ),
1943
+ h('div', { className: 'dsub-row', style: { marginTop: 12 } },
1944
+ h('label', { style: { display: 'flex', alignItems: 'center', gap: 8, cursor: 'pointer' } },
1945
+ h('input', {
1946
+ type: 'checkbox',
1947
+ checked: draft.enableSoftFailureSentinel !== false,
1948
+ onChange: (e) => setDraft((d) => Object.assign({}, d, { enableSoftFailureSentinel: e.target.checked })),
1949
+ }),
1950
+ h('span', null, t('softFailureSentinel')),
1951
+ ),
1952
+ h('div', { className: 'dsub-sub' }, t('softFailureSentinelHint')),
1953
+ ),
2161
1954
  ),
2162
1955
  ),
2163
- React.createElement('div', { className: 'dsub-block' },
2164
- React.createElement('div', { className: 'dsub-row' },
2165
- React.createElement('button', { type: 'button', className: 'dsub-mini', onClick: () => runWizard(null, null, null, false) }, '๐Ÿฉบ ' + t('wizardAll')),
2166
- React.createElement('button', { type: 'button', className: 'dsub-mini', onClick: genDiag }, t('diagGenerate')),
2167
- React.createElement('button', { type: 'button', className: 'dsub-mini', onClick: runAnalyzeSession }, analyzingCache ? 'โ€ฆ' : t('cacheAnalyze')),
2168
- React.createElement('button', { type: 'button', className: 'dsub-mini', onClick: () => { setBackupModal('export'); setBackupErr(''); setBackupInfo('') } }, '๐Ÿ”’ ' + t('backupExport')),
2169
- React.createElement('button', { type: 'button', className: 'dsub-mini', onClick: () => { setBackupModal('import'); setBackupErr(''); setBackupInfo('') } }, '๐Ÿ“ฅ ' + t('backupImport')),
2170
- React.createElement('a', { href: 'https://github.com/GooDAnDReaDY/dsh-subscriptions/issues', target: '_blank', rel: 'noopener noreferrer', className: 'dsub-mini' }, t('diagIssues')),
1956
+ h('div', { className: 'dsub-block' },
1957
+ h('div', { className: 'dsub-row' },
1958
+ h('button', { type: 'button', className: 'dsub-mini', onClick: () => runWizard(null, null, null, false) }, '๐Ÿฉบ ' + t('wizardAll')),
1959
+ h('button', { type: 'button', className: 'dsub-mini', onClick: genDiag }, t('diagGenerate')),
1960
+ h('button', { type: 'button', className: 'dsub-mini', onClick: runAnalyzeSession }, analyzingCache ? 'โ€ฆ' : t('cacheAnalyze')),
1961
+ h('button', { type: 'button', className: 'dsub-mini', onClick: () => { setBackupModal('export'); setBackupErr(''); setBackupInfo('') } }, '๐Ÿ”’ ' + t('backupExport')),
1962
+ h('button', { type: 'button', className: 'dsub-mini', onClick: () => { setBackupModal('import'); setBackupErr(''); setBackupInfo('') } }, '๐Ÿ“ฅ ' + t('backupImport')),
1963
+ h('a', { href: 'https://github.com/GooDAnDReaDY/dsh-subscriptions/issues', target: '_blank', rel: 'noopener noreferrer', className: 'dsub-mini' }, t('diagIssues')),
2171
1964
  ),
2172
- React.createElement('div', { className: 'dsub-sub' }, t('diagHint')),
2173
- sessionAnalysis ? React.createElement('div', { className: 'dsub-sub', style: { marginTop: '6px', fontWeight: 500 } },
1965
+ h('div', { className: 'dsub-sub' }, t('diagHint')),
1966
+ sessionAnalysis ? h('div', { className: 'dsub-sub', style: { marginTop: '6px', fontWeight: 500 } },
2174
1967
  t('cacheHitRate') + ': ' + sessionAnalysis.weightedCacheHitPercent + '% ยท ' +
2175
1968
  t('tokensSaved') + ': ' + sessionAnalysis.savedTokens + ' / ' + sessionAnalysis.totalTokens
2176
1969
  ) : null,
2177
- diag ? React.createElement('div', { className: 'dsub-row' },
2178
- React.createElement('button', {
1970
+ diag ? h('div', { className: 'dsub-row' },
1971
+ h('button', {
2179
1972
  type: 'button', className: 'dsub-mini',
2180
1973
  onClick: () => { try { navigator.clipboard.writeText(diag) } catch { /* clipboard write error */ } },
2181
1974
  }, t('diagCopy')),
2182
- React.createElement('pre', { className: 'dsub-diag' }, diag),
1975
+ h('pre', { className: 'dsub-diag' }, diag),
2183
1976
  ) : null,
2184
- React.createElement('details', { className: 'dsub-details', style: { marginTop: 12 } },
2185
- React.createElement('summary', { className: 'dsub-summary' }, 'โš ๏ธ ' + t('recentErrors')),
2186
- React.createElement('div', { className: 'dsub-block' },
2187
- React.createElement('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8 } },
2188
- React.createElement('span', { className: 'dsub-sub' }, t('recentErrorsDesc')),
2189
- React.createElement('button', {
1977
+ h('details', { className: 'dsub-details', style: { marginTop: 12 } },
1978
+ h('summary', { className: 'dsub-summary' }, 'โš ๏ธ ' + t('recentErrors')),
1979
+ h('div', { className: 'dsub-block' },
1980
+ h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8 } },
1981
+ h('span', { className: 'dsub-sub' }, t('recentErrorsDesc')),
1982
+ h('button', {
2190
1983
  type: 'button', className: 'dsub-mini',
2191
1984
  onClick: async () => {
2192
1985
  await fetch('/dsh-subscriptions/diagnostics/errors/clear', { method: 'POST' }).catch(() => {})
@@ -2195,79 +1988,79 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2195
1988
  }, t('recentErrorsClear'))
2196
1989
  ),
2197
1990
  (diagReport && Array.isArray(diagReport.recentErrors) && diagReport.recentErrors.length ? diagReport.recentErrors : []).length === 0
2198
- ? React.createElement('div', { className: 'dsub-dim', style: { padding: 8 } }, t('recentErrorsEmpty'))
2199
- : React.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: 6 } },
2200
- (diagReport.recentErrors || []).map((err, i) => React.createElement('div', {
1991
+ ? h('div', { className: 'dsub-dim', style: { padding: 8 } }, t('recentErrorsEmpty'))
1992
+ : h('div', { style: { display: 'flex', flexDirection: 'column', gap: 6 } },
1993
+ (diagReport.recentErrors || []).map((err, i) => h('div', {
2201
1994
  key: i,
2202
1995
  style: { padding: '6px 10px', background: 'var(--dsw-alias-bg-layer-2)', borderRadius: 6, fontSize: 11.5, borderLeft: '3px solid var(--dsw-alias-state-error-primary)' }
2203
1996
  },
2204
- React.createElement('div', { style: { display: 'flex', justifyContent: 'space-between', marginBottom: 2 } },
2205
- React.createElement('span', { style: { fontWeight: 600 } }, (err.provider || 'unknown').toUpperCase() + (err.model ? ' ยท ' + err.model : '')),
2206
- React.createElement('span', { className: 'dsub-dim' }, (err.ts || '').slice(11, 19))
1997
+ h('div', { style: { display: 'flex', justifyContent: 'space-between', marginBottom: 2 } },
1998
+ h('span', { style: { fontWeight: 600 } }, (err.provider || 'unknown').toUpperCase() + (err.model ? ' ยท ' + err.model : '')),
1999
+ h('span', { className: 'dsub-dim' }, (err.ts || '').slice(11, 19))
2207
2000
  ),
2208
- React.createElement('div', { style: { display: 'flex', gap: 6, alignItems: 'center' } },
2209
- err.code ? React.createElement('span', { className: 'dsub-pillTag', style: { background: 'color-mix(in srgb,var(--dsw-alias-state-error-primary) 15%,transparent)', color: 'var(--dsw-alias-state-error-primary)' } }, err.code) : null,
2210
- err.status ? React.createElement('span', { className: 'dsub-dim' }, 'HTTP ' + err.status) : null,
2211
- React.createElement('span', { style: { opacity: 0.9, wordBreak: 'break-word' } }, err.message)
2001
+ h('div', { style: { display: 'flex', gap: 6, alignItems: 'center' } },
2002
+ err.code ? h('span', { className: 'dsub-pillTag', style: { background: 'color-mix(in srgb,var(--dsw-alias-state-error-primary) 15%,transparent)', color: 'var(--dsw-alias-state-error-primary)' } }, err.code) : null,
2003
+ err.status ? h('span', { className: 'dsub-dim' }, 'HTTP ' + err.status) : null,
2004
+ h('span', { style: { opacity: 0.9, wordBreak: 'break-word' } }, err.message)
2212
2005
  )
2213
2006
  ))
2214
2007
  )
2215
2008
  )
2216
2009
  ),
2217
- wizardModal ? React.createElement('div', { className: 'dsub-modalWrap', onClick: (e) => { if (e.target === e.currentTarget) setWizardModal(null) } },
2218
- React.createElement('div', { className: 'dsub-modal' },
2219
- React.createElement('div', { className: 'dsub-modalHead' },
2220
- React.createElement('div', { className: 'dsub-modalTitleWrap' },
2221
- React.createElement('div', { className: 'dsub-modalIcon' }, '๐Ÿฉบ'),
2222
- React.createElement('div', null,
2223
- React.createElement('div', { style: { fontWeight: 700, fontSize: '15px' } }, t('wizardTitle')),
2224
- React.createElement('div', { style: { fontSize: '11.5px', opacity: 0.7 } },
2010
+ wizardModal ? h('div', { className: 'dsub-modalWrap', onClick: (e) => { if (e.target === e.currentTarget) setWizardModal(null) } },
2011
+ h('div', { className: 'dsub-modal' },
2012
+ h('div', { className: 'dsub-modalHead' },
2013
+ h('div', { className: 'dsub-modalTitleWrap' },
2014
+ h('div', { className: 'dsub-modalIcon' }, '๐Ÿฉบ'),
2015
+ h('div', null,
2016
+ h('div', { style: { fontWeight: 700, fontSize: '15px' } }, t('wizardTitle')),
2017
+ h('div', { style: { fontSize: '11.5px', opacity: 0.7 } },
2225
2018
  wizardModal.provider && wizardModal.provider !== 'all' ? (wizardModal.provider.toUpperCase() + ' #' + wizardModal.index + (wizardModal.ref ? ' (' + wizardModal.ref + ')' : '')) : t('wizardAll')
2226
2019
  ),
2227
2020
  ),
2228
2021
  ),
2229
- React.createElement('button', { type: 'button', className: 'dsub-mini', onClick: () => setWizardModal(null) }, 'โœ• ' + t('closeModal')),
2022
+ h('button', { type: 'button', className: 'dsub-mini', onClick: () => setWizardModal(null) }, 'โœ• ' + t('closeModal')),
2230
2023
  ),
2231
- React.createElement('div', { style: { marginTop: '14px' } },
2232
- React.createElement('label', { className: 'dsub-row', style: { marginBottom: '10px' } },
2233
- React.createElement('input', {
2024
+ h('div', { style: { marginTop: '14px' } },
2025
+ h('label', { className: 'dsub-row', style: { marginBottom: '10px' } },
2026
+ h('input', {
2234
2027
  type: 'checkbox',
2235
2028
  checked: !!wizardModal.includeNetwork,
2236
2029
  onChange: (e) => runWizard(wizardModal.provider === 'all' ? null : wizardModal.provider, wizardModal.index, wizardModal.ref, e.target.checked),
2237
2030
  }),
2238
- React.createElement('span', { style: { fontSize: '12px' } }, t('wizardIncludeNetwork')),
2031
+ h('span', { style: { fontSize: '12px' } }, t('wizardIncludeNetwork')),
2239
2032
  ),
2240
- wizardModal.loading ? React.createElement('div', { className: 'dsub-alert-ok', style: { marginBottom: '12px' } }, 'โณ ' + t('wizardRunning')) : null,
2241
- wizardModal.error ? React.createElement('div', { className: 'dsub-alert-bad', style: { marginBottom: '12px' } }, wizardModal.error) : null,
2242
- wizardModal.report ? React.createElement('div', null,
2243
- React.createElement('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '12px' } },
2244
- React.createElement('span', {
2033
+ wizardModal.loading ? h('div', { className: 'dsub-alert-ok', style: { marginBottom: '12px' } }, 'โณ ' + t('wizardRunning')) : null,
2034
+ wizardModal.error ? h('div', { className: 'dsub-alert-bad', style: { marginBottom: '12px' } }, wizardModal.error) : null,
2035
+ wizardModal.report ? h('div', null,
2036
+ h('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '12px' } },
2037
+ h('span', {
2245
2038
  className: 'dsub-badge ' + (wizardModal.report.overallStatus === 'healthy' ? 'dsub-badge-ok' : (wizardModal.report.overallStatus === 'degraded' ? 'dsub-badge-warn' : 'dsub-badge-bad'))
2246
2039
  }, (wizardModal.report.overallStatus === 'healthy' ? '๐ŸŸข ' + t('wizardHealthy') : (wizardModal.report.overallStatus === 'degraded' ? '๐ŸŸก ' + t('wizardDegraded') : '๐Ÿ”ด ' + t('wizardFailing')))),
2247
- React.createElement('span', { style: { fontSize: '11.5px', opacity: 0.7 } },
2040
+ h('span', { style: { fontSize: '11.5px', opacity: 0.7 } },
2248
2041
  wizardModal.report.summary.passed + ' passed ยท ' + wizardModal.report.summary.warnings + ' warn ยท ' + wizardModal.report.summary.failed + ' fail'
2249
2042
  ),
2250
2043
  ),
2251
- React.createElement('div', { className: 'dsub-trace-box', style: { marginBottom: '12px' } },
2044
+ h('div', { className: 'dsub-trace-box', style: { marginBottom: '12px' } },
2252
2045
  wizardModal.report.steps.map((st, idx) => {
2253
2046
  const icon = st.status === 'pass' ? 'โœ…' : (st.status === 'warn' ? 'โš ๏ธ' : (st.status === 'fail' ? 'โŒ' : 'โšช'))
2254
2047
  const color = st.status === 'pass' ? 'var(--dsw-alias-state-success-primary)' : (st.status === 'warn' ? 'var(--dsw-alias-state-warn-primary)' : (st.status === 'fail' ? 'var(--dsw-alias-state-error-primary)' : 'var(--dsw-alias-label-secondary)'))
2255
- return React.createElement('div', { key: idx, className: 'dsub-trace-row' },
2256
- React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '8px' } },
2257
- React.createElement('span', null, icon),
2258
- React.createElement('span', { style: { fontWeight: 600 } }, st.name),
2259
- st.latencyMs != null ? React.createElement('span', { style: { fontSize: '10px', opacity: 0.6 } }, st.latencyMs + 'ms') : null,
2048
+ return h('div', { key: idx, className: 'dsub-trace-row' },
2049
+ h('div', { style: { display: 'flex', alignItems: 'center', gap: '8px' } },
2050
+ h('span', null, icon),
2051
+ h('span', { style: { fontWeight: 600 } }, st.name),
2052
+ st.latencyMs != null ? h('span', { style: { fontSize: '10px', opacity: 0.6 } }, st.latencyMs + 'ms') : null,
2260
2053
  ),
2261
- React.createElement('span', { style: { fontSize: '11px', color: color } }, st.message),
2054
+ h('span', { style: { fontSize: '11px', color: color } }, st.message),
2262
2055
  )
2263
2056
  })
2264
2057
  ),
2265
- wizardModal.report.recommendations && wizardModal.report.recommendations.length ? React.createElement('div', { style: { marginBottom: '12px' } },
2266
- React.createElement('div', { style: { fontSize: '11.5px', fontWeight: 600, color: 'var(--dsw-alias-state-warn-primary)', marginBottom: '4px' } }, '๐Ÿ’ก ' + t('wizardRecommendations')),
2267
- wizardModal.report.recommendations.map((rec, rIdx) => React.createElement('div', { key: rIdx, className: 'dsub-alert-bad', style: { marginBottom: '4px', fontSize: '11.5px' } }, rec))
2058
+ wizardModal.report.recommendations && wizardModal.report.recommendations.length ? h('div', { style: { marginBottom: '12px' } },
2059
+ h('div', { style: { fontSize: '11.5px', fontWeight: 600, color: 'var(--dsw-alias-state-warn-primary)', marginBottom: '4px' } }, '๐Ÿ’ก ' + t('wizardRecommendations')),
2060
+ wizardModal.report.recommendations.map((rec, rIdx) => h('div', { key: rIdx, className: 'dsub-alert-bad', style: { marginBottom: '4px', fontSize: '11.5px' } }, rec))
2268
2061
  ) : null,
2269
- React.createElement('div', { style: { display: 'flex', justifyContent: 'flex-end', gap: '8px', marginTop: '10px' } },
2270
- React.createElement('button', {
2062
+ h('div', { style: { display: 'flex', justifyContent: 'flex-end', gap: '8px', marginTop: '10px' } },
2063
+ h('button', {
2271
2064
  type: 'button',
2272
2065
  className: 'dsub-mini',
2273
2066
  onClick: () => {
@@ -2280,60 +2073,60 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2280
2073
  ),
2281
2074
  ),
2282
2075
  ) : null,
2283
- backupModal ? React.createElement('div', { className: 'dsub-panel-box', style: { marginTop: '10px' } },
2284
- React.createElement('div', { className: 'dsub-panel-title' },
2285
- React.createElement('span', null, backupModal === 'export' ? ('๐Ÿ”’ ' + t('backupExportTitle')) : ('๐Ÿ“ฅ ' + t('backupImportTitle'))),
2286
- React.createElement('button', {
2076
+ backupModal ? h('div', { className: 'dsub-panel-box', style: { marginTop: '10px' } },
2077
+ h('div', { className: 'dsub-panel-title' },
2078
+ h('span', null, backupModal === 'export' ? ('๐Ÿ”’ ' + t('backupExportTitle')) : ('๐Ÿ“ฅ ' + t('backupImportTitle'))),
2079
+ h('button', {
2287
2080
  type: 'button',
2288
2081
  className: 'dsub-mini',
2289
2082
  onClick: () => { setBackupModal(null); setBackupPass(''); setBackupData(''); setBackupErr(''); setBackupInfo('') }
2290
2083
  }, 'โœ• ' + t('closeModal'))
2291
2084
  ),
2292
- React.createElement('div', { className: 'dsub-panel-desc' },
2085
+ h('div', { className: 'dsub-panel-desc' },
2293
2086
  backupModal === 'export' ? t('backupExportHint') : t('backupImportHint')
2294
2087
  ),
2295
- React.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: '8px', marginTop: '8px' } },
2296
- backupModal === 'import' ? React.createElement('textarea', {
2088
+ h('div', { style: { display: 'flex', flexDirection: 'column', gap: '8px', marginTop: '8px' } },
2089
+ backupModal === 'import' ? h('textarea', {
2297
2090
  className: 'dsub-diag',
2298
2091
  style: { width: '100%', height: '80px', fontFamily: 'monospace', fontSize: '11px' },
2299
2092
  placeholder: t('backupPayloadPlaceholder'),
2300
2093
  value: backupData,
2301
2094
  onChange: (e) => setBackupData(e.target.value),
2302
2095
  }) : null,
2303
- React.createElement('div', { className: 'dsub-row' },
2304
- React.createElement('input', {
2096
+ h('div', { className: 'dsub-row' },
2097
+ h('input', {
2305
2098
  type: 'password',
2306
2099
  className: 'dsub-grow',
2307
2100
  placeholder: t('backupPassphrase'),
2308
2101
  value: backupPass,
2309
2102
  onChange: (e) => setBackupPass(e.target.value),
2310
2103
  }),
2311
- backupModal === 'export' ? React.createElement('button', {
2104
+ backupModal === 'export' ? h('button', {
2312
2105
  type: 'button',
2313
2106
  className: 'dsub-mini',
2314
2107
  disabled: backupLoading || !backupPass || backupPass.length < 12,
2315
2108
  onClick: doExportBackup,
2316
- }, backupLoading ? 'โ€ฆ' : t('backupExportAction')) : React.createElement('button', {
2109
+ }, backupLoading ? 'โ€ฆ' : t('backupExportAction')) : h('button', {
2317
2110
  type: 'button',
2318
2111
  className: 'dsub-mini',
2319
2112
  disabled: backupLoading || !backupPass || !backupData,
2320
2113
  onClick: doImportBackup,
2321
2114
  }, backupLoading ? 'โ€ฆ' : t('backupImportAction'))
2322
2115
  ),
2323
- backupErr ? React.createElement('div', { className: 'dsub-bad' }, backupErr) : null,
2324
- backupInfo ? React.createElement('div', { className: 'dsub-ok' }, backupInfo) : null,
2325
- (backupModal === 'export' && backupData) ? React.createElement('div', { className: 'dsub-row' },
2326
- React.createElement('button', {
2116
+ backupErr ? h('div', { className: 'dsub-bad' }, backupErr) : null,
2117
+ backupInfo ? h('div', { className: 'dsub-ok' }, backupInfo) : null,
2118
+ (backupModal === 'export' && backupData) ? h('div', { className: 'dsub-row' },
2119
+ h('button', {
2327
2120
  type: 'button',
2328
2121
  className: 'dsub-mini',
2329
2122
  onClick: () => { try { navigator.clipboard.writeText(backupData) } catch { /* ignore */ } },
2330
2123
  }, t('diagCopy')),
2331
- React.createElement('button', {
2124
+ h('button', {
2332
2125
  type: 'button',
2333
2126
  className: 'dsub-mini',
2334
2127
  onClick: downloadBackupFile,
2335
2128
  }, t('backupDownload')),
2336
- React.createElement('pre', { className: 'dsub-diag', style: { maxHeight: '60px', overflow: 'hidden', textOverflow: 'ellipsis' } }, backupData)
2129
+ h('pre', { className: 'dsub-diag', style: { maxHeight: '60px', overflow: 'hidden', textOverflow: 'ellipsis' } }, backupData)
2337
2130
  ) : null
2338
2131
  )
2339
2132
  ) : null,
@@ -2342,15 +2135,15 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2342
2135
  const rows = slots
2343
2136
  .map((slot, i) => ({ slot: slot, i: i }))
2344
2137
  .filter((row) => row.slot.provider === prov.id)
2345
- return React.createElement('div', { className: 'dsub-block', key: prov.id },
2346
- React.createElement('div', { className: 'dsub-h' }, prov.name),
2138
+ return h('div', { className: 'dsub-block', key: prov.id },
2139
+ h('div', { className: 'dsub-h' }, prov.name),
2347
2140
  rows.map((row) => {
2348
2141
  const account = accountOf(row.slot.provider, row.slot.index)
2349
2142
  const key = row.slot.provider + ':' + row.slot.index
2350
2143
  const on = !!account.configured
2351
- return React.createElement('div', { className: 'dsub-card', key: key },
2352
- React.createElement('div', { className: 'dsub-row' },
2353
- React.createElement('input', {
2144
+ return h('div', { className: 'dsub-card', key: key },
2145
+ h('div', { className: 'dsub-row' },
2146
+ h('input', {
2354
2147
  className: 'dsub-grow',
2355
2148
  value: row.slot.label || '',
2356
2149
  placeholder: account.label || (t('accountLabel') + ' ' + row.slot.index),
@@ -2360,22 +2153,22 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2360
2153
  setSlots(next)
2361
2154
  },
2362
2155
  }),
2363
- React.createElement('span', { className: 'dsub-badge' + (account.validationUrl ? ' dsub-badge-warn' : (on ? ' dsub-badge-on' : '')) }, badgeFor(account, t)),
2156
+ h('span', { className: 'dsub-badge' + (account.validationUrl ? ' dsub-badge-warn' : (on ? ' dsub-badge-on' : '')) }, badgeFor(account, t)),
2364
2157
  normalizePlanBadge(row.slot.provider, account.plan || (account.quota && account.quota.plan)),
2365
- React.createElement('button', {
2158
+ h('button', {
2366
2159
  type: 'button', className: 'dsub-mini',
2367
2160
  onClick: () => connect(row.slot.provider, row.slot.index).catch((e) => setErr(cleanErrorMessage(e.message || e))),
2368
2161
  }, on ? t('reconnect') : t('connect')),
2369
- ((row.slot.provider === 'codex' || row.slot.provider === 'copilot' || row.slot.provider === 'grok') ? React.createElement('button', {
2162
+ ((row.slot.provider === 'codex' || row.slot.provider === 'copilot' || row.slot.provider === 'grok') ? h('button', {
2370
2163
  type: 'button', className: 'dsub-mini',
2371
2164
  onClick: () => deviceStartLogin(row.slot.provider, row.slot.index).catch((e) => setErr(cleanErrorMessage(e.message || e))),
2372
2165
  }, t('deviceLogin')) : null),
2373
- React.createElement('button', {
2166
+ h('button', {
2374
2167
  type: 'button', className: 'dsub-mini',
2375
2168
  disabled: !on,
2376
2169
  onClick: () => logout(row.slot.provider, row.slot.index).catch((e) => setErr(cleanErrorMessage(e.message || e))),
2377
2170
  }, t('disconnect')),
2378
- React.createElement('button', {
2171
+ h('button', {
2379
2172
  type: 'button', className: 'dsub-mini',
2380
2173
  disabled: checking[key],
2381
2174
  title: t('smokeDesc'),
@@ -2386,30 +2179,47 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2386
2179
  if (!r) return null;
2387
2180
  var cls = r.ok ? 'dsub-badge-ok' : 'dsub-badge-bad';
2388
2181
  var txt = r.ok ? ('โœ“ ' + (r.latencyMs != null ? r.latencyMs + 'ms' : 'OK')) : ('โœ— ' + ((r.error && (r.error.code || r.error.message)) || 'FAIL'));
2389
- return React.createElement('span', { className: 'dsub-badge ' + cls, style: { marginLeft: 4 }, title: r.ok ? t('testConnectionSuccess') : ((r.error && r.error.message) || 'fail') }, txt);
2182
+ return h('span', { className: 'dsub-badge ' + cls, style: { marginLeft: 4 }, title: r.ok ? t('testConnectionSuccess') : ((r.error && r.error.message) || 'fail') }, txt);
2390
2183
  })(),
2391
- React.createElement('button', {
2184
+ (account && account.lastPingMs != null ? (function(){
2185
+ var ms = account.lastPingMs;
2186
+ var grade = account.latencyGrade || (ms < 250 ? 'good' : (ms < 750 ? 'fair' : 'poor'));
2187
+ var cls = grade === 'good' ? 'dsub-badge-ok' : (grade === 'fair' ? 'dsub-badge-warn' : 'dsub-badge-bad');
2188
+ return h('span', {
2189
+ className: 'dsub-badge ' + cls,
2190
+ style: { marginLeft: 4, cursor: 'pointer' },
2191
+ title: 'Latency: ' + ms + 'ms (' + grade + '). Click to test.',
2192
+ onClick: () => doPing(row.slot.provider, row.slot.index),
2193
+ }, '๐Ÿ“ถ ' + ms + 'ms');
2194
+ })() : null),
2195
+ h('button', {
2196
+ type: 'button',
2197
+ className: 'dsub-mini',
2198
+ title: t('syncModelsTitle'),
2199
+ onClick: () => doSyncModels(row.slot.provider, row.slot.index),
2200
+ }, '๐Ÿ”„ ' + t('syncModels')),
2201
+ h('button', {
2392
2202
  type: 'button', className: 'dsub-mini',
2393
2203
  title: t('wizardTitle'),
2394
2204
  onClick: () => runWizard(row.slot.provider, row.slot.index, row.slot.ref, false),
2395
2205
  }, '๐Ÿฉบ ' + t('wizardButton')),
2396
2206
 
2397
- (account && account.quarantineUntil && Number(account.quarantineUntil) > Date.now() ? React.createElement(React.Fragment, null,
2398
- React.createElement('button', {
2207
+ (account && account.quarantineUntil && Number(account.quarantineUntil) > Date.now() ? h(React.Fragment, null,
2208
+ h('button', {
2399
2209
  type: 'button', className: 'dsub-mini', title: t('probeWarmupTitle'),
2400
2210
  disabled: checking[key],
2401
2211
  onClick: () => doProbeQuarantine(row.slot.provider, row.slot.index, false),
2402
2212
  }, checking[key] ? t('checking') : ('๐Ÿ”„ ' + t('probeWarmupNow'))),
2403
- React.createElement('button', {
2213
+ h('button', {
2404
2214
  type: 'button', className: 'dsub-mini', title: t('releaseQuarantineTitle'),
2405
2215
  disabled: checking[key],
2406
2216
  onClick: () => doProbeQuarantine(row.slot.provider, row.slot.index, true),
2407
2217
  }, ('โœ• ' + t('releaseQuarantine'))),
2408
- ) : (on ? React.createElement('button', {
2218
+ ) : (on ? h('button', {
2409
2219
  type: 'button', className: 'dsub-mini', title: t('quarantineParkTitle'),
2410
2220
  onClick: () => doParkQuarantine(row.slot.provider, row.slot.index, 3600000),
2411
2221
  }, ('โธ ' + t('quarantinePark'))) : null)),
2412
- React.createElement('button', {
2222
+ h('button', {
2413
2223
  type: 'button', className: 'dsub-mini', title: t('removeSlot'),
2414
2224
  onClick: () => {
2415
2225
  const slot = row.slot
@@ -2419,55 +2229,75 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2419
2229
  },
2420
2230
  }, '\u00d7'),
2421
2231
  ),
2422
- (account && account.quarantineUntil && Number(account.quarantineUntil) > Date.now()) ? React.createElement('div', { className: 'dsub-row', style: { marginTop: 4 } },
2423
- React.createElement('span', { className: 'dsub-sub', style: { color: 'var(--dsw-alias-state-error-primary)', fontVariantNumeric: 'tabular-nums' } },
2232
+ (account && account.quarantineUntil && Number(account.quarantineUntil) > Date.now()) ? h('div', { className: 'dsub-row', style: { marginTop: 4 } },
2233
+ h('span', { className: 'dsub-sub', style: { color: 'var(--dsw-alias-state-error-primary)', fontVariantNumeric: 'tabular-nums' } },
2424
2234
  'โ›” ' + (account.quarantineReason || 'QUARANTINE') + ' ยท ' + t('resetsIn') + ' ' + formatRelativeReset(account.quarantineUntil, t('lang'), Date.now())
2425
2235
  ),
2426
- ) : (account && account.quota && account.quota.resetAt && Number(account.quota.resetAt) > Date.now()) ? React.createElement('div', { className: 'dsub-row', style: { marginTop: 4 } },
2427
- React.createElement(ResetCountdown, { resetAt: account.quota.resetAt }),
2236
+ ) : (account && account.quota && account.quota.resetAt && Number(account.quota.resetAt) > Date.now()) ? h('div', { className: 'dsub-row', style: { marginTop: 4 } },
2237
+ h(ResetCountdown, { resetAt: account.quota.resetAt }),
2428
2238
  ) : null,
2429
- React.createElement('div', { className: 'dsub-manual' },
2430
- React.createElement('span', { className: 'dsub-sub' }, t('manualTitle')),
2431
- React.createElement('div', { className: 'dsub-row' },
2432
- React.createElement('input', {
2239
+ h('div', { className: 'dsub-manual' },
2240
+ h('span', { className: 'dsub-sub' }, t('manualTitle')),
2241
+ h('div', { className: 'dsub-row' },
2242
+ h('input', {
2433
2243
  className: 'dsub-grow',
2434
2244
  value: paste[key] || '',
2435
2245
  placeholder: t('pastePlaceholder'),
2436
2246
  onChange: (e) => setPaste((p) => Object.assign({}, p, { [key]: e.target.value })),
2437
2247
  }),
2438
- React.createElement('button', {
2248
+ h('button', {
2439
2249
  type: 'button', className: 'dsub-mini',
2440
2250
  onClick: () => complete(row.slot.provider, row.slot.index).catch((e) => setErr(cleanErrorMessage(e.message || e))),
2441
2251
  }, t('submitCode')),
2442
2252
  ),
2443
- React.createElement('div', { className: 'dsub-row', style: { justifyContent: 'space-between' } },
2444
- React.createElement('button', {
2253
+ h('div', { className: 'dsub-row', style: { justifyContent: 'space-between' } },
2254
+ h('button', {
2445
2255
  type: 'button',
2446
2256
  className: 'dsub-mini',
2447
2257
  title: t('importLocalCliTitle'),
2448
2258
  style: { display: 'inline-flex', alignItems: 'center', gap: 6, fontWeight: 600 },
2449
2259
  onClick: () => importLocalCli(row.slot.provider, row.slot.index).catch((e) => setErr(cleanErrorMessage(e.message || e))),
2450
2260
  }, t('importLocalCli')),
2451
- React.createElement('button', {
2261
+ h('button', {
2452
2262
  type: 'button',
2453
2263
  className: 'dsub-mini' + (openHelp[key] ? ' dsub-btnActive' : ''),
2454
2264
  title: t('howToGetTokenTitle'),
2455
2265
  onClick: (e) => { if (e) { e.preventDefault(); e.stopPropagation(); } setOpenHelp((h) => Object.assign({}, h, { [key]: !h[key] })); },
2456
2266
  }, t('howToGetToken')),
2457
2267
  ),
2458
- React.createElement('div', { className: 'dsub-row' },
2459
- React.createElement('input', {
2268
+ h('div', { className: 'dsub-row' },
2269
+ h('input', {
2460
2270
  className: 'dsub-grow',
2461
2271
  value: tokenDraft[key] || '',
2462
2272
  placeholder: t('importTokenPlace'),
2463
2273
  onChange: (e) => setTokenDraft((d) => Object.assign({}, d, { [key]: e.target.value })),
2464
2274
  }),
2465
- React.createElement('button', {
2275
+ h('button', {
2466
2276
  type: 'button', className: 'dsub-mini',
2467
2277
  title: t('importToken'),
2468
2278
  onClick: () => importToken(row.slot.provider, row.slot.index).catch((e) => setErr(cleanErrorMessage(e.message || e))),
2469
2279
  }, t('importToken')),
2470
2280
  ),
2281
+ (account && account.lastDoctorVerdict ? (function(){
2282
+ var doc = account.lastDoctorVerdict;
2283
+ return h('div', {
2284
+ className: 'dsub-helpBox',
2285
+ style: {
2286
+ marginTop: 6,
2287
+ padding: '8px 12px',
2288
+ borderLeft: '3px solid var(--dsw-alias-brand-primary)',
2289
+ background: 'var(--dsw-alias-bg-layer-2)',
2290
+ },
2291
+ },
2292
+ h('div', { style: { fontWeight: 600, color: 'var(--dsw-alias-label-primary)', display: 'flex', alignItems: 'center', gap: 6, marginBottom: 4 } },
2293
+ '๐Ÿฉบ ' + doc.title
2294
+ ),
2295
+ h('div', { style: { fontSize: 12, color: 'var(--dsw-alias-label-secondary)', marginBottom: 4 } }, doc.details),
2296
+ h('div', { style: { fontSize: 12, color: 'var(--dsw-alias-brand-primary)', fontWeight: 500 } },
2297
+ '๐Ÿ’ก ' + (t('recommendation') || 'Recommendation') + ': ' + doc.recommendation
2298
+ )
2299
+ );
2300
+ })() : null),
2471
2301
  (openHelp[key] ? (function renderInlineHelp(){
2472
2302
  const prov = row.slot.provider;
2473
2303
  const info = (typeof INSTRUCTIONS !== 'undefined' && INSTRUCTIONS[prov]) || {
@@ -2478,10 +2308,10 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2478
2308
  // Determine language safely from current locale (fallback to zh if Chinese or en)
2479
2309
  const isZh = t('instructionsTitle').indexOf('่Žทๅ–') >= 0 || t('close') === 'ๅ…ณ้—ญ';
2480
2310
  const steps = (isZh && info.stepsZh) ? info.stepsZh : (info.stepsEn || []);
2481
- return React.createElement('div', { className: 'dsub-helpBox' },
2482
- React.createElement('div', { className: 'dsub-helpHead' },
2483
- React.createElement('span', null, 'โ„น๏ธ ' + info.title + ' โ€” ' + t('instructionsTitle')),
2484
- React.createElement('button', {
2311
+ return h('div', { className: 'dsub-helpBox' },
2312
+ h('div', { className: 'dsub-helpHead' },
2313
+ h('span', null, 'โ„น๏ธ ' + info.title + ' โ€” ' + t('instructionsTitle')),
2314
+ h('button', {
2485
2315
  type: 'button', className: 'dsub-mini',
2486
2316
  style: { padding: '1px 6px', fontSize: 11 },
2487
2317
  onClick: (e) => {
@@ -2490,9 +2320,9 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2490
2320
  },
2491
2321
  }, 'โœ•')
2492
2322
  ),
2493
- steps.map((st, i) => React.createElement('div', { key: i, className: 'dsub-helpStep' }, st)),
2494
- info.link ? React.createElement('div', { style: { marginTop: 8 } },
2495
- React.createElement('a', {
2323
+ steps.map((st, i) => h('div', { key: i, className: 'dsub-helpStep' }, st)),
2324
+ info.link ? h('div', { style: { marginTop: 8 } },
2325
+ h('a', {
2496
2326
  href: info.link,
2497
2327
  target: '_blank',
2498
2328
  rel: 'noopener noreferrer',
@@ -2502,8 +2332,8 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2502
2332
  ) : null
2503
2333
  );
2504
2334
  })() : null),
2505
- React.createElement('div', { className: 'dsub-row' },
2506
- React.createElement('input', {
2335
+ h('div', { className: 'dsub-row' },
2336
+ h('input', {
2507
2337
  className: 'dsub-grow',
2508
2338
  value: row.slot.proxyUrl || '',
2509
2339
  placeholder: t('proxyPlaceholder'),
@@ -2513,7 +2343,7 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2513
2343
  setSlots(next)
2514
2344
  },
2515
2345
  }),
2516
- React.createElement('button', {
2346
+ h('button', {
2517
2347
  type: 'button', className: 'dsub-mini',
2518
2348
  disabled: checking['proxy:' + key],
2519
2349
  onClick: () => doProxyCheck(row.slot.provider, row.slot.index).catch((e) => setErr(cleanErrorMessage(e.message || e))),
@@ -2523,7 +2353,7 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2523
2353
  var r = proxyRes[key]
2524
2354
  if (!r) return null
2525
2355
  var txt = r.ok ? (t('proxyOk') + ' ' + r.latencyMs + 'ms' + (r.viaProxy ? '' : ' (direct)')) : (t('proxyFail') + ': ' + ((r.error && r.error.message) || ''))
2526
- return React.createElement('div', { className: r.ok ? 'dsub-ok' : 'dsub-bad' }, txt)
2356
+ return h('div', { className: r.ok ? 'dsub-ok' : 'dsub-bad' }, txt)
2527
2357
  })(),
2528
2358
  ),
2529
2359
  (function devicePanel(){
@@ -2531,18 +2361,18 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2531
2361
  if (!d) return null
2532
2362
  var txt = d.status === 'authorized' ? t('deviceAuthorized') : (d.status === 'expired' ? t('deviceExpired') : t('devicePending'))
2533
2363
  var cls = d.status === 'authorized' ? 'dsub-ok' : (d.status === 'expired' ? 'dsub-bad' : 'dsub-verify')
2534
- return React.createElement('div', { className: 'dsub-verify' },
2535
- React.createElement('div', { className: cls }, txt),
2536
- d.status === 'pending' ? React.createElement(React.Fragment, null,
2537
- React.createElement('div', { style: { fontSize: '2em', fontWeight: 700, letterSpacing: '0.15em', margin: '4px 0' } }, d.userCode),
2538
- React.createElement('div', { className: 'dsub-row' },
2539
- React.createElement('button', {
2364
+ return h('div', { className: 'dsub-verify' },
2365
+ h('div', { className: cls }, txt),
2366
+ d.status === 'pending' ? h(React.Fragment, null,
2367
+ h('div', { style: { fontSize: '2em', fontWeight: 700, letterSpacing: '0.15em', margin: '4px 0' } }, d.userCode),
2368
+ h('div', { className: 'dsub-row' },
2369
+ h('button', {
2540
2370
  type: 'button', className: 'dsub-mini',
2541
2371
  onClick: () => { try { navigator.clipboard.writeText(d.userCode) } catch { /* clipboard write error */ } },
2542
2372
  }, t('deviceCopy')),
2543
- React.createElement('a', { href: d.authUrl, target: '_blank', rel: 'noopener noreferrer', className: 'dsub-mini' }, t('verifyLink')),
2373
+ h('a', { href: d.authUrl, target: '_blank', rel: 'noopener noreferrer', className: 'dsub-mini' }, t('verifyLink')),
2544
2374
  ),
2545
- React.createElement('div', { className: 'dsub-sub' }, t('deviceHint')),
2375
+ h('div', { className: 'dsub-sub' }, t('deviceHint')),
2546
2376
  ) : null,
2547
2377
  )
2548
2378
  })(),
@@ -2557,63 +2387,63 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2557
2387
  return code
2558
2388
  }
2559
2389
  if (st.phase !== 'confirm') {
2560
- return React.createElement('div', { className: 'dsub-panel-box' },
2561
- React.createElement('div', { className: 'dsub-panel-title' },
2562
- React.createElement('span', null, 'โšก ' + t('resetCredits')),
2563
- React.createElement('button', {
2390
+ return h('div', { className: 'dsub-panel-box' },
2391
+ h('div', { className: 'dsub-panel-title' },
2392
+ h('span', null, 'โšก ' + t('resetCredits')),
2393
+ h('button', {
2564
2394
  type: 'button',
2565
2395
  className: 'dsub-mini',
2566
2396
  disabled: st.phase === 'loading',
2567
2397
  onClick: () => resetPrepare(row.slot.provider, row.slot.index, key).catch((e) => setErr(String(e && e.message || e))),
2568
2398
  }, st.phase === 'loading' ? 'โ€ฆ' : t('resetCreditsAction'))
2569
2399
  ),
2570
- React.createElement('div', { className: 'dsub-panel-desc' }, t('resetCreditsHint'))
2400
+ h('div', { className: 'dsub-panel-desc' }, t('resetCreditsHint'))
2571
2401
  )
2572
2402
  }
2573
2403
  var ready = now >= st.readyAt
2574
2404
  var secs = Math.max(0, Math.ceil((st.readyAt - now) / 1000))
2575
- return React.createElement('div', { className: 'dsub-panel-box dsub-panel-warn' },
2576
- React.createElement('div', { className: 'dsub-panel-title' },
2577
- React.createElement('span', null, 'โš ๏ธ ' + t('resetCredits')),
2578
- React.createElement('span', { className: 'dsub-tag-ok' }, t('resetAvailable') + ': ' + st.availableCount)
2405
+ return h('div', { className: 'dsub-panel-box dsub-panel-warn' },
2406
+ h('div', { className: 'dsub-panel-title' },
2407
+ h('span', null, 'โš ๏ธ ' + t('resetCredits')),
2408
+ h('span', { className: 'dsub-tag-ok' }, t('resetAvailable') + ': ' + st.availableCount)
2579
2409
  ),
2580
- st.creditExpiresAt ? React.createElement('div', { className: 'dsub-panel-desc' },
2410
+ st.creditExpiresAt ? h('div', { className: 'dsub-panel-desc' },
2581
2411
  t('resetExpires') + ': ' + new Date(st.creditExpiresAt).toLocaleString()
2582
2412
  ) : null,
2583
- React.createElement('label', { className: 'dsub-row', style: { cursor: 'pointer', margin: '4px 0' } },
2584
- React.createElement('input', {
2413
+ h('label', { className: 'dsub-row', style: { cursor: 'pointer', margin: '4px 0' } },
2414
+ h('input', {
2585
2415
  type: 'checkbox',
2586
2416
  checked: !!st.ack,
2587
2417
  onChange: (e) => setReset((m) => Object.assign({}, m, { [key]: Object.assign({}, st, { ack: e.target.checked }) })),
2588
2418
  }),
2589
- React.createElement('span', { style: { fontSize: '12px', fontWeight: 500 } }, t('resetAck')),
2419
+ h('span', { style: { fontSize: '12px', fontWeight: 500 } }, t('resetAck')),
2590
2420
  ),
2591
- React.createElement('div', { className: 'dsub-row', style: { gap: '8px' } },
2592
- React.createElement('button', {
2421
+ h('div', { className: 'dsub-row', style: { gap: '8px' } },
2422
+ h('button', {
2593
2423
  type: 'button',
2594
2424
  className: 'dsub-mini dsub-btn-danger',
2595
2425
  disabled: !st.ack || !ready || !!st.busy,
2596
2426
  onClick: () => resetConsume(key).catch((e) => setErr(String(e && e.message || e))),
2597
2427
  }, st.busy ? t('resetBusy') : (ready ? t('resetGo') : (t('resetWait') + ' ' + secs + 's'))),
2598
- !ready && !st.busy ? React.createElement('span', { className: 'dsub-sub' }, t('resetWait') + ' ' + secs + 's') : null,
2599
- st.ack && ready ? React.createElement('span', { className: 'dsub-ok', style: { fontSize: '12px', fontWeight: 600 } }, 'โœ“ ' + t('resetReady')) : null,
2600
- React.createElement('button', {
2428
+ !ready && !st.busy ? h('span', { className: 'dsub-sub' }, t('resetWait') + ' ' + secs + 's') : null,
2429
+ st.ack && ready ? h('span', { className: 'dsub-ok', style: { fontSize: '12px', fontWeight: 600 } }, 'โœ“ ' + t('resetReady')) : null,
2430
+ h('button', {
2601
2431
  type: 'button',
2602
2432
  className: 'dsub-mini',
2603
2433
  style: { marginLeft: 'auto' },
2604
2434
  onClick: () => setReset((m) => Object.assign({}, m, { [key]: { phase: 'idle' } })),
2605
2435
  }, t('cancel'))
2606
2436
  ),
2607
- st.result ? React.createElement('div', { className: 'dsub-ok', style: { fontWeight: 600 } }, resultText(st.result)) : null,
2608
- st.error ? React.createElement('div', { className: 'dsub-bad' }, st.error) : null,
2437
+ st.result ? h('div', { className: 'dsub-ok', style: { fontWeight: 600 } }, resultText(st.result)) : null,
2438
+ st.error ? h('div', { className: 'dsub-bad' }, st.error) : null,
2609
2439
  )
2610
2440
  })() : null),
2611
- account.accountNotice ? React.createElement('div', { className: 'dsub-verify' }, account.accountNotice) : null,
2612
- account.refreshError ? React.createElement('div', { className: 'dsub-bad' }, t('reconnectRequired') + ': ' + account.refreshError) : null,
2613
- (function(){ var r=checkRes[key]; if(!r) return null; var txt=r.ok ? ('ok ' + (r.email||'')) : ('fail ' + (r.error && r.error.message || '')); var cls=r.ok ? 'dsub-ok' : 'dsub-bad'; var q=r.quota; if(q && q.remaining!=null) txt += ' quota:'+q.remaining+(q.limit!=null?'/'+q.limit:''); return React.createElement('div', {className: cls}, txt) })(),
2614
- account.validationUrl ? React.createElement('div', { className: 'dsub-verify' },
2441
+ account.accountNotice ? h('div', { className: 'dsub-verify' }, account.accountNotice) : null,
2442
+ account.refreshError ? h('div', { className: 'dsub-bad' }, t('reconnectRequired') + ': ' + account.refreshError) : null,
2443
+ (function(){ var r=checkRes[key]; if(!r) return null; var txt=r.ok ? ('ok ' + (r.email||'')) : ('fail ' + (r.error && r.error.message || '')); var cls=r.ok ? 'dsub-ok' : 'dsub-bad'; var q=r.quota; if(q && q.remaining!=null) txt += ' quota:'+q.remaining+(q.limit!=null?'/'+q.limit:''); return h('div', {className: cls}, txt) })(),
2444
+ account.validationUrl ? h('div', { className: 'dsub-verify' },
2615
2445
  t('verifyPrefix'),
2616
- React.createElement('a', { href: account.validationUrl, target: '_blank', rel: 'noopener noreferrer' }, t('verifyLink')),
2446
+ h('a', { href: account.validationUrl, target: '_blank', rel: 'noopener noreferrer' }, t('verifyLink')),
2617
2447
  t('verifySuffix'),
2618
2448
  ) : null,
2619
2449
  (function usageLimitsBlock(){
@@ -2639,18 +2469,18 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2639
2469
  var p = Math.min(100, Math.max(0, Math.round(pct)))
2640
2470
  var tagCls = p >= 90 ? 'dsub-tag-bad' : (p >= 70 ? 'dsub-tag-warn' : 'dsub-tag-ok')
2641
2471
  var fillBg = p >= 90 ? 'var(--dsw-alias-state-error-primary)' : (p >= 70 ? 'var(--dsw-alias-state-warn-primary)' : 'var(--dsw-alias-state-success-primary)')
2642
- return React.createElement('div', { key: label, className: 'dsub-usage-card' },
2643
- React.createElement('div', { className: 'dsub-usage-head' },
2644
- React.createElement('span', null, label),
2645
- React.createElement('span', { className: tagCls }, p + '%')
2472
+ return h('div', { key: label, className: 'dsub-usage-card' },
2473
+ h('div', { className: 'dsub-usage-head' },
2474
+ h('span', null, label),
2475
+ h('span', { className: tagCls }, p + '%')
2646
2476
  ),
2647
- React.createElement('div', { className: 'dsub-usage-track' },
2648
- React.createElement('div', {
2477
+ h('div', { className: 'dsub-usage-track' },
2478
+ h('div', {
2649
2479
  className: 'dsub-usage-fill',
2650
2480
  style: { width: p + '%', background: fillBg }
2651
2481
  })
2652
2482
  ),
2653
- detail ? React.createElement('div', { className: 'dsub-usage-meta' }, detail) : null
2483
+ detail ? h('div', { className: 'dsub-usage-meta' }, detail) : null
2654
2484
  )
2655
2485
  }
2656
2486
 
@@ -2662,18 +2492,18 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2662
2492
  if (idx === 0 && account.requests && w.usedPercent < 100) {
2663
2493
  var rem = 100 - w.usedPercent
2664
2494
  var est = Math.floor(rem / (w.usedPercent / account.requests))
2665
- if (est > 0) extra = React.createElement('span', null, t('forecast') + ' ' + est)
2495
+ if (est > 0) extra = h('span', null, t('forecast') + ' ' + est)
2666
2496
  }
2667
- var resetElem = w.resetAt ? React.createElement(ResetCountdown, { key: 'reset-' + idx, resetAt: w.resetAt }) : null
2497
+ var resetElem = w.resetAt ? h(ResetCountdown, { key: 'reset-' + idx, resetAt: w.resetAt }) : null
2668
2498
  var extraContent = (resetElem && extra)
2669
- ? React.createElement('span', { className: 'dsub-row', style: { gap: '6px' } }, resetElem, extra)
2499
+ ? h('span', { className: 'dsub-row', style: { gap: '6px' } }, resetElem, extra)
2670
2500
  : (resetElem || extra)
2671
2501
  items.push(renderItem(windowLabel(w), w.usedPercent, extraContent))
2672
2502
  }
2673
2503
  })
2674
2504
  }
2675
2505
  if (hasQuota) {
2676
- items.push(renderItem(t('quota'), q.usedPercent, q.resetAt ? React.createElement(ResetCountdown, { key: 'reset', resetAt: q.resetAt }) : null))
2506
+ items.push(renderItem(t('quota'), q.usedPercent, q.resetAt ? h(ResetCountdown, { key: 'reset', resetAt: q.resetAt }) : null))
2677
2507
  } else if (hasUsagePct) {
2678
2508
  items.push(renderItem(t('quota'), account.usagePercent, null))
2679
2509
  }
@@ -2685,17 +2515,17 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2685
2515
  if (m >= 1) agoStr = m + 'm ' + (t('close') === 'ๅ…ณ้—ญ' ? 'ๅ‰' : 'ago')
2686
2516
  }
2687
2517
 
2688
- return React.createElement('div', { className: 'dsub-panel-box' },
2689
- React.createElement('div', { className: 'dsub-panel-title' },
2690
- React.createElement('span', null, '๐Ÿ“Š ' + t('usageLimitsTitle')),
2691
- agoStr ? React.createElement('span', { className: 'dsub-sub' }, agoStr) : null
2518
+ return h('div', { className: 'dsub-panel-box' },
2519
+ h('div', { className: 'dsub-panel-title' },
2520
+ h('span', null, '๐Ÿ“Š ' + t('usageLimitsTitle')),
2521
+ agoStr ? h('span', { className: 'dsub-sub' }, agoStr) : null
2692
2522
  ),
2693
- React.createElement('div', { className: 'dsub-usage-grid' }, items)
2523
+ h('div', { className: 'dsub-usage-grid' }, items)
2694
2524
  )
2695
2525
  })(),
2696
- ((account.paidTierName || account.ref || (telemetry && telemetry.accounts && telemetry.accounts[account.ref])) ? React.createElement('div', { className: 'dsub-slot-meta-row' },
2697
- account.paidTierName ? React.createElement('span', { className: 'dsub-sub' },
2698
- React.createElement('strong', null, t('plan') + ': '),
2526
+ ((account.paidTierName || account.ref || (telemetry && telemetry.accounts && telemetry.accounts[account.ref])) ? h('div', { className: 'dsub-slot-meta-row' },
2527
+ account.paidTierName ? h('span', { className: 'dsub-sub' },
2528
+ h('strong', null, t('plan') + ': '),
2699
2529
  account.paidTierName
2700
2530
  ) : null,
2701
2531
  (function(){
@@ -2707,31 +2537,31 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2707
2537
  if (accTelem.avgTps != null) parts.push(accTelem.avgTps + ' t/s')
2708
2538
  else if (accTelem.lastTps != null) parts.push(accTelem.lastTps + ' t/s')
2709
2539
  if (parts.length === 0) return null
2710
- return React.createElement('span', { className: 'dsub-speed-tag', title: t('speedMetricsHint') },
2540
+ return h('span', { className: 'dsub-speed-tag', title: t('speedMetricsHint') },
2711
2541
  'โšก ' + parts.join(' ยท ')
2712
2542
  )
2713
2543
  })(),
2714
- account.ref ? React.createElement('span', { className: 'dsub-ref-tag' },
2715
- React.createElement('span', null, t('storedAs')),
2716
- React.createElement('code', null, account.ref)
2544
+ account.ref ? h('span', { className: 'dsub-ref-tag' },
2545
+ h('span', null, t('storedAs')),
2546
+ h('code', null, account.ref)
2717
2547
  ) : null
2718
2548
  ) : null),
2719
2549
  )
2720
2550
  }),
2721
- React.createElement('button', {
2551
+ h('button', {
2722
2552
  type: 'button', className: 'dsub-mini',
2723
2553
  onClick: () => addSlot(prov.id),
2724
2554
  }, t('addAccount')),
2725
2555
  )
2726
2556
  }),
2727
- React.createElement('div', { className: 'dsub-foot' },
2728
- React.createElement('button', {
2557
+ h('div', { className: 'dsub-foot' },
2558
+ h('button', {
2729
2559
  type: 'button', className: 'dsub-save',
2730
2560
  onClick: () => save().catch((e) => setErr(cleanErrorMessage(e.message || e))),
2731
2561
  }, t('save')),
2732
- saved ? React.createElement('span', { className: 'dsub-ok' }, t('saved')) : null,
2733
- info ? React.createElement('span', { className: 'dsub-ok' }, info) : null,
2734
- err ? React.createElement('span', { className: 'dsub-bad' }, err) : null,
2562
+ saved ? h('span', { className: 'dsub-ok' }, t('saved')) : null,
2563
+ info ? h('span', { className: 'dsub-ok' }, info) : null,
2564
+ err ? h('span', { className: 'dsub-bad' }, err) : null,
2735
2565
  ),
2736
2566
  )
2737
2567
  }
@@ -2745,29 +2575,29 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2745
2575
  // Row seat (plugins.row.config): the host page draws title/icon/crumb and the
2746
2576
  // padding, so the summary is a one-liner and the page drops our card chrome.
2747
2577
  if (props && props.view === 'summary') {
2748
- return React.createElement('div', { className: 'dsub-description' }, cardT('cardIntro'))
2578
+ return h('div', { className: 'dsub-description' }, cardT('cardIntro'))
2749
2579
  }
2750
2580
  // Check host snapshot status (#408, #459): loading, unavailable, or error
2751
2581
  if (props && props.status === 'loading') {
2752
- return React.createElement(page ? 'div' : 'li', {
2582
+ return h(page ? 'div' : 'li', {
2753
2583
  className: page ? 'dsub-page' : 'dsub-card',
2754
2584
  },
2755
- React.createElement('div', { className: 'dsub-header', style: { cursor: 'default' } },
2756
- React.createElement('div', { className: 'dsub-headText' },
2757
- React.createElement('div', { className: 'dsub-name' }, cardT('title')),
2758
- React.createElement('div', { className: 'dsub-description' }, cardT('loading') || cardT('settingsLoading') || 'Loadingโ€ฆ'),
2585
+ h('div', { className: 'dsub-header', style: { cursor: 'default' } },
2586
+ h('div', { className: 'dsub-headText' },
2587
+ h('div', { className: 'dsub-name' }, cardT('title')),
2588
+ h('div', { className: 'dsub-description' }, cardT('loading') || cardT('settingsLoading') || 'Loadingโ€ฆ'),
2759
2589
  ),
2760
2590
  )
2761
2591
  )
2762
2592
  }
2763
2593
  if (props && props.status === 'unavailable') {
2764
- return React.createElement(page ? 'div' : 'li', {
2594
+ return h(page ? 'div' : 'li', {
2765
2595
  className: page ? 'dsub-page' : 'dsub-card',
2766
2596
  },
2767
- React.createElement('div', { className: 'dsub-header', style: { cursor: 'default' } },
2768
- React.createElement('div', { className: 'dsub-headText' },
2769
- React.createElement('div', { className: 'dsub-name' }, cardT('title')),
2770
- React.createElement('div', { className: 'dsub-description', style: { color: 'var(--dsw-alias-state-warn-primary)' } },
2597
+ h('div', { className: 'dsub-header', style: { cursor: 'default' } },
2598
+ h('div', { className: 'dsub-headText' },
2599
+ h('div', { className: 'dsub-name' }, cardT('title')),
2600
+ h('div', { className: 'dsub-description', style: { color: 'var(--dsw-alias-state-warn-primary)' } },
2771
2601
  cardT('unavailable') || cardT('settingsUnavailable') || 'Settings are unavailable',
2772
2602
  ),
2773
2603
  ),
@@ -2775,37 +2605,37 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2775
2605
  )
2776
2606
  }
2777
2607
  if (props && props.status === 'error') {
2778
- return React.createElement(page ? 'div' : 'li', {
2608
+ return h(page ? 'div' : 'li', {
2779
2609
  className: page ? 'dsub-page' : 'dsub-card',
2780
2610
  },
2781
- React.createElement('div', { className: 'dsub-header', style: { cursor: 'default' } },
2782
- React.createElement('div', { className: 'dsub-headText' },
2783
- React.createElement('div', { className: 'dsub-name' }, cardT('title')),
2784
- React.createElement('div', { className: 'dsub-description', style: { color: 'var(--dsw-alias-state-error-primary)' } },
2611
+ h('div', { className: 'dsub-header', style: { cursor: 'default' } },
2612
+ h('div', { className: 'dsub-headText' },
2613
+ h('div', { className: 'dsub-name' }, cardT('title')),
2614
+ h('div', { className: 'dsub-description', style: { color: 'var(--dsw-alias-state-error-primary)' } },
2785
2615
  (props.error && (props.error.message || String(props.error))) || cardT('error') || cardT('settingsError') || 'Settings error',
2786
2616
  ),
2787
2617
  ),
2788
2618
  )
2789
2619
  )
2790
2620
  }
2791
- return React.createElement(page ? 'div' : 'li', {
2621
+ return h(page ? 'div' : 'li', {
2792
2622
  className: page ? 'dsub-page' : 'dsub-card' + (open ? ' dsub-cardOpen' : ''),
2793
2623
  },
2794
- React.createElement('button', {
2624
+ h('button', {
2795
2625
  type: 'button',
2796
2626
  className: 'dsub-header',
2797
2627
  style: page ? { display: 'none' } : undefined,
2798
2628
  onClick: () => setOpen(!open),
2799
2629
  'aria-expanded': page ? true : open,
2800
2630
  },
2801
- React.createElement('div', { className: 'dsub-headText' },
2802
- React.createElement('div', { className: 'dsub-name' }, cardT('title')),
2803
- React.createElement('div', { className: 'dsub-description' }, cardT('cardIntro')),
2631
+ h('div', { className: 'dsub-headText' },
2632
+ h('div', { className: 'dsub-name' }, cardT('title')),
2633
+ h('div', { className: 'dsub-description' }, cardT('cardIntro')),
2804
2634
  ),
2805
- React.createElement(Chevron, { className: 'dsub-chev' + (open ? ' dsub-chevOpen' : '') }),
2635
+ h(Chevron, { className: 'dsub-chev' + (open ? ' dsub-chevOpen' : '') }),
2806
2636
  ),
2807
- (page || open) ? React.createElement('div', { className: 'dsub-body' },
2808
- React.createElement(ErrorBoundary, null, React.createElement(SubsSection, props)),
2637
+ (page || open) ? h('div', { className: 'dsub-body' },
2638
+ h(ErrorBoundary, null, h(SubsSection, props)),
2809
2639
  ) : null,
2810
2640
  )
2811
2641
  }
@@ -2983,21 +2813,21 @@ const cssId = 'dsh-subscriptions/settings.module.css'
2983
2813
  const cls = state.remaining <= 10 ? ' dsub-cqBarFull' : (state.remaining <= 30 ? ' dsub-cqBarWarn' : '')
2984
2814
  var value = null
2985
2815
  if (state.mode === 'percent') {
2986
- value = React.createElement('span', { className: 'dsub-cqB' }, Math.round(state.remaining) + '%')
2816
+ value = h('span', { className: 'dsub-cqB' }, Math.round(state.remaining) + '%')
2987
2817
  } else if (state.mode === 'bar') {
2988
- value = React.createElement('span', { className: 'dsub-cqBar' + cls },
2989
- React.createElement('span', { className: 'dsub-cqBarFill', style: { width: Math.min(100, Math.max(0, state.remaining)) + '%' } }))
2818
+ value = h('span', { className: 'dsub-cqBar' + cls },
2819
+ h('span', { className: 'dsub-cqBarFill', style: { width: Math.min(100, Math.max(0, state.remaining)) + '%' } }))
2990
2820
  } else if (state.mode === 'forecast') {
2991
2821
  var est = state.est
2992
- if (!est || est.status === 'calibrating') value = React.createElement('span', { className: 'dsub-cqB' }, t('fcCalibrating'))
2993
- else if (est.status === 'idle') value = React.createElement('span', { className: 'dsub-cqB' }, t('fcIdle'))
2822
+ if (!est || est.status === 'calibrating') value = h('span', { className: 'dsub-cqB' }, t('fcCalibrating'))
2823
+ else if (est.status === 'idle') value = h('span', { className: 'dsub-cqB' }, t('fcIdle'))
2994
2824
  else {
2995
2825
  var secs = est.runwaySeconds || 0
2996
2826
  var txt = secs >= 3600 ? ('~' + (Math.round((secs / 3600) * 10) / 10) + t('fcHours')) : ('~' + Math.max(1, Math.round(secs / 60)) + t('fcMinutes'))
2997
- value = React.createElement('span', { className: 'dsub-cqB' }, txt)
2827
+ value = h('span', { className: 'dsub-cqB' }, txt)
2998
2828
  }
2999
2829
  } else return null
3000
- return React.createElement('span', { className: 'dsub-cq', title: t('forecast') + ' ยท ' + state.active.provider }, value)
2830
+ return h('span', { className: 'dsub-cq', title: t('forecast') + ' ยท ' + state.active.provider }, value)
3001
2831
  }
3002
2832
 
3003
2833
  // #83: SUBS(N) pill in the session header with a pool health LED and
@@ -3214,23 +3044,23 @@ const cssId = 'dsh-subscriptions/settings.module.css'
3214
3044
  const primPct = primaryWin && primaryWin.usedPercent != null ? Math.round(primaryWin.usedPercent) : (a.usagePercent != null ? Math.round(a.usagePercent) : 0)
3215
3045
  const secPct = secWin && secWin.usedPercent != null ? Math.round(secWin.usedPercent) : null
3216
3046
 
3217
- return React.createElement('div', { className: 'dsub-heroCard' },
3218
- React.createElement('div', { className: 'dsub-heroHead' },
3219
- React.createElement('div', { className: 'dsub-heroTitle' },
3220
- React.createElement('span', { className: 'dsub-brandBadge ' + b.cls, style: { width: 24, height: 24, fontSize: 11 } }, b.icon),
3221
- React.createElement('span', null, (a.provider ? a.provider.toUpperCase() : 'LLM') + (a.index ? ' #' + a.index : '')),
3222
- a.fastMode ? React.createElement('span', { className: 'dsub-pillTag', style: { background: 'color-mix(in srgb,var(--dsw-alias-state-warn-primary) 15%,transparent)', color: 'var(--dsw-alias-state-warn-primary)' } }, 'โšก FAST 1.5x') : null,
3047
+ return h('div', { className: 'dsub-heroCard' },
3048
+ h('div', { className: 'dsub-heroHead' },
3049
+ h('div', { className: 'dsub-heroTitle' },
3050
+ h('span', { className: 'dsub-brandBadge ' + b.cls, style: { width: 24, height: 24, fontSize: 11 } }, b.icon),
3051
+ h('span', null, (a.provider ? a.provider.toUpperCase() : 'LLM') + (a.index ? ' #' + a.index : '')),
3052
+ a.fastMode ? h('span', { className: 'dsub-pillTag', style: { background: 'color-mix(in srgb,var(--dsw-alias-state-warn-primary) 15%,transparent)', color: 'var(--dsw-alias-state-warn-primary)' } }, 'โšก FAST 1.5x') : null,
3223
3053
  ),
3224
- React.createElement('span', { className: 'dsub-heroModel' }, a.model || 'active model'),
3054
+ h('span', { className: 'dsub-heroModel' }, a.model || 'active model'),
3225
3055
  ),
3226
- React.createElement('div', { className: 'dsub-heroBars' },
3227
- React.createElement('div', null,
3228
- React.createElement('div', { className: 'dsub-barLabelRow' },
3229
- React.createElement('span', { style: { fontWeight: 600 } }, ((primaryWin && primaryWin.label) ? primaryWin.label + ' window' : t('subs5hWindow')) + (primaryWin && primaryWin.resetAt ? ' (' + formatRelativeReset(primaryWin.resetAt, t('lang'), now) + ')' : '')),
3230
- React.createElement('span', { style: { fontVariantNumeric: 'tabular-nums', fontWeight: 600 } }, primPct + '% ' + t('subsUsed') + ' (' + (100 - primPct) + '% ' + t('subsFree') + ')'),
3056
+ h('div', { className: 'dsub-heroBars' },
3057
+ h('div', null,
3058
+ h('div', { className: 'dsub-barLabelRow' },
3059
+ h('span', { style: { fontWeight: 600 } }, ((primaryWin && primaryWin.label) ? primaryWin.label + ' window' : t('subs5hWindow')) + (primaryWin && primaryWin.resetAt ? ' (' + formatRelativeReset(primaryWin.resetAt, t('lang'), now) + ')' : '')),
3060
+ h('span', { style: { fontVariantNumeric: 'tabular-nums', fontWeight: 600 } }, primPct + '% ' + t('subsUsed') + ' (' + (100 - primPct) + '% ' + t('subsFree') + ')'),
3231
3061
  ),
3232
- React.createElement('div', { className: 'dsub-barTrack' },
3233
- React.createElement('div', {
3062
+ h('div', { className: 'dsub-barTrack' },
3063
+ h('div', {
3234
3064
  className: 'dsub-barFillGrad',
3235
3065
  style: {
3236
3066
  width: Math.min(100, Math.max(0, primPct)) + '%',
@@ -3239,13 +3069,13 @@ const cssId = 'dsh-subscriptions/settings.module.css'
3239
3069
  }),
3240
3070
  ),
3241
3071
  ),
3242
- secWin ? React.createElement('div', null,
3243
- React.createElement('div', { className: 'dsub-barLabelRow' },
3244
- React.createElement('span', null, ((secWin.label || '7d') + ' window') + (secWin && secWin.resetAt ? ' (' + formatRelativeReset(secWin.resetAt, t('lang'), now) + ')' : '')),
3245
- React.createElement('span', { style: { fontVariantNumeric: 'tabular-nums' } }, secPct + '%'),
3072
+ secWin ? h('div', null,
3073
+ h('div', { className: 'dsub-barLabelRow' },
3074
+ h('span', null, ((secWin.label || '7d') + ' window') + (secWin && secWin.resetAt ? ' (' + formatRelativeReset(secWin.resetAt, t('lang'), now) + ')' : '')),
3075
+ h('span', { style: { fontVariantNumeric: 'tabular-nums' } }, secPct + '%'),
3246
3076
  ),
3247
- React.createElement('div', { className: 'dsub-barTrack' },
3248
- React.createElement('div', {
3077
+ h('div', { className: 'dsub-barTrack' },
3078
+ h('div', {
3249
3079
  className: 'dsub-barFillGrad',
3250
3080
  style: {
3251
3081
  width: Math.min(100, Math.max(0, secPct)) + '%',
@@ -3304,19 +3134,19 @@ const cssId = 'dsh-subscriptions/settings.module.css'
3304
3134
  else { statusClass = 'dsub-statusOk'; statusText = (pct != null ? pct + '% ยท ' : '') + t('subsLogged') }
3305
3135
  }
3306
3136
 
3307
- return React.createElement('div', { className: 'dsub-accountCard', key: i },
3308
- React.createElement('div', { className: 'dsub-brandBadge ' + b.cls }, b.icon),
3309
- React.createElement('div', { className: 'dsub-accInfo' },
3310
- React.createElement('div', { className: 'dsub-accNameRow' },
3311
- React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 6 } },
3312
- React.createElement('span', { className: 'dsub-accName' }, a.provider.toUpperCase() + (a.index ? ' #' + a.index : '')),
3313
- isActiveThis ? React.createElement('span', { className: 'dsub-pillTag', style: { background: 'color-mix(in srgb,var(--dsw-alias-state-success-primary) 15%,transparent)', color: 'var(--dsw-alias-state-success-primary)' } }, 'ACTIVE') : null,
3314
- a.proxy ? React.createElement('span', { className: 'dsub-dim', title: a.proxy }, '๐ŸŒ proxy') : null,
3137
+ return h('div', { className: 'dsub-accountCard', key: i },
3138
+ h('div', { className: 'dsub-brandBadge ' + b.cls }, b.icon),
3139
+ h('div', { className: 'dsub-accInfo' },
3140
+ h('div', { className: 'dsub-accNameRow' },
3141
+ h('div', { style: { display: 'flex', alignItems: 'center', gap: 6 } },
3142
+ h('span', { className: 'dsub-accName' }, a.provider.toUpperCase() + (a.index ? ' #' + a.index : '')),
3143
+ isActiveThis ? h('span', { className: 'dsub-pillTag', style: { background: 'color-mix(in srgb,var(--dsw-alias-state-success-primary) 15%,transparent)', color: 'var(--dsw-alias-state-success-primary)' } }, 'ACTIVE') : null,
3144
+ a.proxy ? h('span', { className: 'dsub-dim', title: a.proxy }, '๐ŸŒ proxy') : null,
3315
3145
  ),
3316
- React.createElement('span', { className: 'dsub-accStatusTag ' + statusClass, role: 'status', 'aria-live': 'polite' }, statusText),
3146
+ h('span', { className: 'dsub-accStatusTag ' + statusClass, role: 'status', 'aria-live': 'polite' }, statusText),
3317
3147
  ),
3318
- (isLogged && pct != null) ? React.createElement('div', { className: 'dsub-barTrack', style: { marginTop: 4, height: 4 } },
3319
- React.createElement('div', {
3148
+ (isLogged && pct != null) ? h('div', { className: 'dsub-barTrack', style: { marginTop: 4, height: 4 } },
3149
+ h('div', {
3320
3150
  className: 'dsub-barFillGrad',
3321
3151
  style: {
3322
3152
  width: Math.min(100, Math.max(0, pct)) + '%',
@@ -3328,49 +3158,49 @@ const cssId = 'dsh-subscriptions/settings.module.css'
3328
3158
  )
3329
3159
  })
3330
3160
 
3331
- return React.createElement(React.Fragment, null,
3332
- toasts.length > 0 ? React.createElement('div', { className: 'dsub-toast-container' },
3333
- toasts.map((toast) => React.createElement('div', { className: 'dsub-toast ' + toast.cls, key: toast.id },
3334
- React.createElement('span', null, toast.message),
3335
- React.createElement('button', {
3161
+ return h(React.Fragment, null,
3162
+ toasts.length > 0 ? h('div', { className: 'dsub-toast-container' },
3163
+ toasts.map((toast) => h('div', { className: 'dsub-toast ' + toast.cls, key: toast.id },
3164
+ h('span', null, toast.message),
3165
+ h('button', {
3336
3166
  type: 'button',
3337
3167
  className: 'dsub-toast-close',
3338
3168
  onClick: () => dismissToast(toast.id),
3339
3169
  }, "\u00d7"),
3340
3170
  ))
3341
3171
  ) : null,
3342
- React.createElement('button', {
3172
+ h('button', {
3343
3173
  type: 'button',
3344
3174
  className: 'dsub-pill',
3345
3175
  'aria-expanded': state.open ? 'true' : 'false',
3346
3176
  title: t('subsPill') + ': ' + (n > 0 ? (n + ' ' + t('connected')) : t('notConnected')),
3347
3177
  onClick: () => setState((s) => Object.assign({}, s, { open: !s.open })),
3348
3178
  },
3349
- React.createElement('span', { className: 'dsub-led ' + led }),
3350
- React.createElement('span', null, pillText),
3351
- React.createElement('span', { style: { fontSize: 9, opacity: 0.6, marginLeft: 2 } }, 'โ–ผ'),
3179
+ h('span', { className: 'dsub-led ' + led }),
3180
+ h('span', null, pillText),
3181
+ h('span', { style: { fontSize: 9, opacity: 0.6, marginLeft: 2 } }, 'โ–ผ'),
3352
3182
  ),
3353
- state.open ? React.createElement('div', {
3183
+ state.open ? h('div', {
3354
3184
  className: 'dsub-modalWrap',
3355
3185
  onClick: (e) => { if (e.target === e.currentTarget) setState((s) => Object.assign({}, s, { open: false })) },
3356
3186
  },
3357
- React.createElement('div', { className: 'dsub-modal', role: 'dialog', 'aria-modal': 'true', 'aria-label': t('subsModalTitle') },
3358
- React.createElement('div', { className: 'dsub-modalHead' },
3359
- React.createElement('div', { className: 'dsub-modalTitleWrap' },
3360
- React.createElement('div', { className: 'dsub-modalIcon' }, 'โšก'),
3361
- React.createElement('div', null,
3362
- React.createElement('div', { style: { fontWeight: 700, fontSize: 15 } }, t('subsModalTitle')),
3363
- React.createElement('div', { className: 'dsub-dim' }, n + ' of ' + total + ' ' + t('connected')),
3187
+ h('div', { className: 'dsub-modal', role: 'dialog', 'aria-modal': 'true', 'aria-label': t('subsModalTitle') },
3188
+ h('div', { className: 'dsub-modalHead' },
3189
+ h('div', { className: 'dsub-modalTitleWrap' },
3190
+ h('div', { className: 'dsub-modalIcon' }, 'โšก'),
3191
+ h('div', null,
3192
+ h('div', { style: { fontWeight: 700, fontSize: 15 } }, t('subsModalTitle')),
3193
+ h('div', { className: 'dsub-dim' }, n + ' of ' + total + ' ' + t('connected')),
3364
3194
  ),
3365
3195
  ),
3366
- React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 6 } },
3367
- React.createElement('button', {
3196
+ h('div', { style: { display: 'flex', alignItems: 'center', gap: 6 } },
3197
+ h('button', {
3368
3198
  type: 'button',
3369
3199
  className: 'dsub-mini',
3370
3200
  title: t('subsRefresh'),
3371
3201
  onClick: () => pull(),
3372
3202
  }, state.loading ? 'โ€ฆ' : '๐Ÿ”„'),
3373
- React.createElement('button', {
3203
+ h('button', {
3374
3204
  type: 'button',
3375
3205
  className: 'dsub-mini',
3376
3206
  autoFocus: true,
@@ -3380,11 +3210,11 @@ const cssId = 'dsh-subscriptions/settings.module.css'
3380
3210
  ),
3381
3211
  ),
3382
3212
  renderActiveHero(),
3383
- React.createElement('div', { className: 'dsub-poolTitle' }, t('subsPoolTitle')),
3384
- rows.length ? rows : React.createElement('div', { className: 'dsub-sub', style: { padding: '12px 0' } }, t('subsNotLogged')),
3385
- React.createElement('div', { className: 'dsub-modalFoot' },
3386
- React.createElement('span', { className: 'dsub-dim' }, 'DSH Subscriptions'),
3387
- React.createElement('a', {
3213
+ h('div', { className: 'dsub-poolTitle' }, t('subsPoolTitle')),
3214
+ rows.length ? rows : h('div', { className: 'dsub-sub', style: { padding: '12px 0' } }, t('subsNotLogged')),
3215
+ h('div', { className: 'dsub-modalFoot' },
3216
+ h('span', { className: 'dsub-dim' }, 'DSH Subscriptions'),
3217
+ h('a', {
3388
3218
  className: 'dsub-btnSec',
3389
3219
  href: '#',
3390
3220
  onClick: (e) => {
@@ -3425,7 +3255,7 @@ const cssId = 'dsh-subscriptions/settings.module.css'
3425
3255
  order: 15,
3426
3256
  locale: NS,
3427
3257
  },
3428
- () => React.createElement(ErrorBoundary, null, React.createElement(SubsPill, { t, ctx })),
3258
+ () => h(ErrorBoundary, null, h(SubsPill, { t, ctx })),
3429
3259
  ),
3430
3260
  )
3431
3261
  }, 'dsh-subscriptions: subs pill')
@@ -3441,7 +3271,7 @@ const cssId = 'dsh-subscriptions/settings.module.css'
3441
3271
  order: 5,
3442
3272
  locale: NS,
3443
3273
  },
3444
- () => React.createElement(ErrorBoundary, null, React.createElement(ComposerQuota, { t })),
3274
+ () => h(ErrorBoundary, null, h(ComposerQuota, { t })),
3445
3275
  ),
3446
3276
  )
3447
3277
  }, 'dsh-subscriptions: composer quota')