oc-codex-multi-auth 6.21.0 → 6.22.0
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/LICENSE +21 -21
- package/README.md +729 -571
- package/assets/icon.svg +7 -7
- package/assets/opencode-logo-ornate-dark.svg +18 -18
- package/assets/readme-hero.svg +31 -31
- package/config/README.md +177 -177
- package/config/minimal-opencode.json +14 -14
- package/config/opencode-legacy.json +1496 -1496
- package/config/opencode-modern.json +555 -555
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +291 -53
- package/dist/index.js.map +1 -1
- package/dist/lib/account-display.d.ts +46 -0
- package/dist/lib/account-display.d.ts.map +1 -1
- package/dist/lib/account-display.js +260 -0
- package/dist/lib/account-display.js.map +1 -1
- package/dist/lib/accounts.d.ts +4 -0
- package/dist/lib/accounts.d.ts.map +1 -1
- package/dist/lib/accounts.js +20 -15
- package/dist/lib/accounts.js.map +1 -1
- package/dist/lib/auth/login-runner.d.ts.map +1 -1
- package/dist/lib/auth/login-runner.js +79 -2
- package/dist/lib/auth/login-runner.js.map +1 -1
- package/dist/lib/auto-update-checker.d.ts +17 -1
- package/dist/lib/auto-update-checker.d.ts.map +1 -1
- package/dist/lib/auto-update-checker.js +49 -3
- package/dist/lib/auto-update-checker.js.map +1 -1
- package/dist/lib/cli.d.ts +1 -0
- package/dist/lib/cli.d.ts.map +1 -1
- package/dist/lib/cli.js +9 -3
- package/dist/lib/cli.js.map +1 -1
- package/dist/lib/codex-usage.d.ts +4 -3
- package/dist/lib/codex-usage.d.ts.map +1 -1
- package/dist/lib/codex-usage.js +13 -11
- package/dist/lib/codex-usage.js.map +1 -1
- package/dist/lib/config.d.ts +75 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +152 -1
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/context-overflow.js +10 -10
- package/dist/lib/desktop-notifications.js +6 -6
- package/dist/lib/oauth-success.js +202 -202
- package/dist/lib/plan-allotment.d.ts +72 -0
- package/dist/lib/plan-allotment.d.ts.map +1 -0
- package/dist/lib/plan-allotment.js +142 -0
- package/dist/lib/plan-allotment.js.map +1 -0
- package/dist/lib/plugin-origin.d.ts +77 -0
- package/dist/lib/plugin-origin.d.ts.map +1 -0
- package/dist/lib/plugin-origin.js +301 -0
- package/dist/lib/plugin-origin.js.map +1 -0
- package/dist/lib/prompts/codex-opencode-bridge.js +67 -67
- package/dist/lib/prompts/codex.js +75 -75
- package/dist/lib/quota-display.d.ts +40 -0
- package/dist/lib/quota-display.d.ts.map +1 -0
- package/dist/lib/quota-display.js +45 -0
- package/dist/lib/quota-display.js.map +1 -0
- package/dist/lib/quota-notifications.d.ts +2 -1
- package/dist/lib/quota-notifications.d.ts.map +1 -1
- package/dist/lib/quota-notifications.js +34 -14
- package/dist/lib/quota-notifications.js.map +1 -1
- package/dist/lib/quota-overview.d.ts +253 -0
- package/dist/lib/quota-overview.d.ts.map +1 -0
- package/dist/lib/quota-overview.js +707 -0
- package/dist/lib/quota-overview.js.map +1 -0
- package/dist/lib/request/retry-budget.d.ts +26 -0
- package/dist/lib/request/retry-budget.d.ts.map +1 -1
- package/dist/lib/request/retry-budget.js +43 -0
- package/dist/lib/request/retry-budget.js.map +1 -1
- package/dist/lib/schemas.d.ts +67 -0
- package/dist/lib/schemas.d.ts.map +1 -1
- package/dist/lib/schemas.js +53 -0
- package/dist/lib/schemas.js.map +1 -1
- package/dist/lib/storage/backup.d.ts +33 -0
- package/dist/lib/storage/backup.d.ts.map +1 -1
- package/dist/lib/storage/backup.js +43 -7
- package/dist/lib/storage/backup.js.map +1 -1
- package/dist/lib/storage/credential-snapshots.d.ts +78 -0
- package/dist/lib/storage/credential-snapshots.d.ts.map +1 -0
- package/dist/lib/storage/credential-snapshots.js +302 -0
- package/dist/lib/storage/credential-snapshots.js.map +1 -0
- package/dist/lib/storage/export-import.d.ts.map +1 -1
- package/dist/lib/storage/export-import.js +7 -0
- package/dist/lib/storage/export-import.js.map +1 -1
- package/dist/lib/storage/flagged.d.ts.map +1 -1
- package/dist/lib/storage/flagged.js +23 -1
- package/dist/lib/storage/flagged.js.map +1 -1
- package/dist/lib/storage/load-save.d.ts +4 -0
- package/dist/lib/storage/load-save.d.ts.map +1 -1
- package/dist/lib/storage/load-save.js +50 -0
- package/dist/lib/storage/load-save.js.map +1 -1
- package/dist/lib/storage/paths.d.ts +1 -0
- package/dist/lib/storage/paths.d.ts.map +1 -1
- package/dist/lib/storage/paths.js +1 -1
- package/dist/lib/storage/paths.js.map +1 -1
- package/dist/lib/storage/test-home-guard.d.ts +35 -0
- package/dist/lib/storage/test-home-guard.d.ts.map +1 -0
- package/dist/lib/storage/test-home-guard.js +59 -0
- package/dist/lib/storage/test-home-guard.js.map +1 -0
- package/dist/lib/tools/codex-dashboard.d.ts.map +1 -1
- package/dist/lib/tools/codex-dashboard.js +3 -2
- package/dist/lib/tools/codex-dashboard.js.map +1 -1
- package/dist/lib/tools/codex-doctor.d.ts.map +1 -1
- package/dist/lib/tools/codex-doctor.js +16 -0
- package/dist/lib/tools/codex-doctor.js.map +1 -1
- package/dist/lib/tools/codex-health.d.ts.map +1 -1
- package/dist/lib/tools/codex-health.js +10 -2
- package/dist/lib/tools/codex-health.js.map +1 -1
- package/dist/lib/tools/codex-label.d.ts.map +1 -1
- package/dist/lib/tools/codex-label.js +1 -0
- package/dist/lib/tools/codex-label.js.map +1 -1
- package/dist/lib/tools/codex-limits.d.ts.map +1 -1
- package/dist/lib/tools/codex-limits.js +13 -9
- package/dist/lib/tools/codex-limits.js.map +1 -1
- package/dist/lib/tools/codex-list.d.ts.map +1 -1
- package/dist/lib/tools/codex-list.js +28 -3
- package/dist/lib/tools/codex-list.js.map +1 -1
- package/dist/lib/tools/codex-note.d.ts.map +1 -1
- package/dist/lib/tools/codex-note.js +4 -1
- package/dist/lib/tools/codex-note.js.map +1 -1
- package/dist/lib/tools/codex-pool.d.ts.map +1 -1
- package/dist/lib/tools/codex-pool.js +6 -2
- package/dist/lib/tools/codex-pool.js.map +1 -1
- package/dist/lib/tools/codex-refresh.d.ts.map +1 -1
- package/dist/lib/tools/codex-refresh.js +4 -1
- package/dist/lib/tools/codex-refresh.js.map +1 -1
- package/dist/lib/tools/codex-remove.d.ts.map +1 -1
- package/dist/lib/tools/codex-remove.js +1 -0
- package/dist/lib/tools/codex-remove.js.map +1 -1
- package/dist/lib/tools/codex-reset.d.ts.map +1 -1
- package/dist/lib/tools/codex-reset.js +13 -7
- package/dist/lib/tools/codex-reset.js.map +1 -1
- package/dist/lib/tools/codex-status.d.ts.map +1 -1
- package/dist/lib/tools/codex-status.js +25 -2
- package/dist/lib/tools/codex-status.js.map +1 -1
- package/dist/lib/tools/codex-switch.d.ts.map +1 -1
- package/dist/lib/tools/codex-switch.js +1 -0
- package/dist/lib/tools/codex-switch.js.map +1 -1
- package/dist/lib/tools/codex-tag.d.ts.map +1 -1
- package/dist/lib/tools/codex-tag.js +4 -1
- package/dist/lib/tools/codex-tag.js.map +1 -1
- package/dist/lib/tools/codex-warm.d.ts.map +1 -1
- package/dist/lib/tools/codex-warm.js +1 -0
- package/dist/lib/tools/codex-warm.js.map +1 -1
- package/dist/lib/tools/index.d.ts +9 -0
- package/dist/lib/tools/index.d.ts.map +1 -1
- package/dist/lib/tools/index.js.map +1 -1
- package/dist/lib/tui-quota-cache.d.ts +35 -0
- package/dist/lib/tui-quota-cache.d.ts.map +1 -1
- package/dist/lib/tui-quota-cache.js +76 -11
- package/dist/lib/tui-quota-cache.js.map +1 -1
- package/dist/lib/tui-quota-overview.d.ts +55 -0
- package/dist/lib/tui-quota-overview.d.ts.map +1 -0
- package/dist/lib/tui-quota-overview.js +209 -0
- package/dist/lib/tui-quota-overview.js.map +1 -0
- package/dist/lib/tui-status.d.ts +55 -0
- package/dist/lib/tui-status.d.ts.map +1 -1
- package/dist/lib/tui-status.js +155 -14
- package/dist/lib/tui-status.js.map +1 -1
- package/dist/lib/ui/auth-menu.d.ts +2 -0
- package/dist/lib/ui/auth-menu.d.ts.map +1 -1
- package/dist/lib/ui/auth-menu.js +10 -6
- package/dist/lib/ui/auth-menu.js.map +1 -1
- package/dist/tui.d.ts +55 -0
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +511 -29
- package/dist/tui.js.map +1 -1
- package/package.json +155 -155
- package/scripts/audit-dev-allowlist.js +114 -114
- package/scripts/clean-dist.js +27 -27
- package/scripts/copy-oauth-success.js +47 -47
- package/scripts/install-oc-codex-multi-auth-core.js +2003 -1499
- package/scripts/install-oc-codex-multi-auth.js +37 -37
- package/scripts/test-all-models.sh +260 -260
- package/scripts/validate-model-map.sh +97 -97
|
@@ -1,206 +1,206 @@
|
|
|
1
1
|
export function renderOAuthSuccessHtml(styleNonce) {
|
|
2
|
-
return `<!doctype html>
|
|
3
|
-
<html lang="en">
|
|
4
|
-
<head>
|
|
5
|
-
<meta charset="utf-8">
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
7
|
-
<meta name="color-scheme" content="dark">
|
|
8
|
-
<title>OpenCode - Authentication complete</title>
|
|
9
|
-
<style nonce="${styleNonce}">
|
|
10
|
-
:root {
|
|
11
|
-
color-scheme: dark;
|
|
12
|
-
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
|
|
13
|
-
font-synthesis: none;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
* {
|
|
17
|
-
box-sizing: border-box;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
body {
|
|
21
|
-
min-width: 320px;
|
|
22
|
-
min-height: 100vh;
|
|
23
|
-
margin: 0;
|
|
24
|
-
display: grid;
|
|
25
|
-
place-items: center;
|
|
26
|
-
padding: 32px 20px;
|
|
27
|
-
background:
|
|
28
|
-
radial-gradient(circle at 50% 0%, rgba(42, 195, 126, 0.12), transparent 38rem),
|
|
29
|
-
#080b0a;
|
|
30
|
-
color: #f2f5f3;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
main {
|
|
34
|
-
width: min(100%, 540px);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
.brand {
|
|
38
|
-
display: flex;
|
|
39
|
-
margin: 0 0 24px 0;
|
|
40
|
-
justify-content: center;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
.brand svg {
|
|
44
|
-
height: 22px;
|
|
45
|
-
width: auto;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
.card {
|
|
49
|
-
position: relative;
|
|
50
|
-
overflow: hidden;
|
|
51
|
-
padding: 44px;
|
|
52
|
-
border: 1px solid #26312c;
|
|
53
|
-
border-radius: 20px;
|
|
54
|
-
background: linear-gradient(145deg, rgba(22, 28, 25, 0.98), rgba(13, 17, 15, 0.98));
|
|
55
|
-
box-shadow: 0 24px 80px rgba(0, 0, 0, 0.45);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
.card::before {
|
|
59
|
-
content: "";
|
|
60
|
-
position: absolute;
|
|
61
|
-
inset: 0 0 auto;
|
|
62
|
-
height: 1px;
|
|
63
|
-
background: linear-gradient(90deg, transparent, rgba(86, 224, 157, 0.7), transparent);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
.success-icon {
|
|
67
|
-
width: 58px;
|
|
68
|
-
height: 58px;
|
|
69
|
-
display: grid;
|
|
70
|
-
place-items: center;
|
|
71
|
-
margin-bottom: 28px;
|
|
72
|
-
border: 1px solid rgba(86, 224, 157, 0.45);
|
|
73
|
-
border-radius: 16px;
|
|
74
|
-
background: rgba(42, 195, 126, 0.1);
|
|
75
|
-
color: #56e09d;
|
|
76
|
-
box-shadow: inset 0 0 28px rgba(42, 195, 126, 0.08);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
.success-icon svg {
|
|
80
|
-
width: 28px;
|
|
81
|
-
height: 28px;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
h1 {
|
|
85
|
-
margin: 0;
|
|
86
|
-
font-family: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
87
|
-
font-size: clamp(28px, 6vw, 38px);
|
|
88
|
-
font-weight: 650;
|
|
89
|
-
letter-spacing: -0.035em;
|
|
90
|
-
line-height: 1.12;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
.lead {
|
|
94
|
-
margin: 16px 0 0;
|
|
95
|
-
color: #aeb8b3;
|
|
96
|
-
font-family: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
97
|
-
font-size: 17px;
|
|
98
|
-
line-height: 1.6;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
.status {
|
|
102
|
-
display: flex;
|
|
103
|
-
align-items: center;
|
|
104
|
-
gap: 12px;
|
|
105
|
-
margin-top: 30px;
|
|
106
|
-
padding: 15px 16px;
|
|
107
|
-
border: 1px solid #29362f;
|
|
108
|
-
border-radius: 12px;
|
|
109
|
-
background: #0b100d;
|
|
110
|
-
color: #c9d2cd;
|
|
111
|
-
font-size: 13px;
|
|
112
|
-
line-height: 1.5;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
.status-dot {
|
|
116
|
-
width: 8px;
|
|
117
|
-
height: 8px;
|
|
118
|
-
flex: 0 0 auto;
|
|
119
|
-
border-radius: 50%;
|
|
120
|
-
background: #56e09d;
|
|
121
|
-
box-shadow: 0 0 0 4px rgba(86, 224, 157, 0.1);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
.next-step {
|
|
125
|
-
margin: 24px 0 0;
|
|
126
|
-
color: #7f8c85;
|
|
127
|
-
font-size: 13px;
|
|
128
|
-
line-height: 1.6;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
.next-step strong {
|
|
132
|
-
color: #b9c3be;
|
|
133
|
-
font-weight: 600;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
@media (max-width: 520px) {
|
|
137
|
-
body {
|
|
138
|
-
padding: 24px 16px;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
.card {
|
|
142
|
-
padding: 32px 24px;
|
|
143
|
-
border-radius: 16px;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
.success-icon {
|
|
147
|
-
width: 52px;
|
|
148
|
-
height: 52px;
|
|
149
|
-
margin-bottom: 24px;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
@media (prefers-reduced-motion: reduce) {
|
|
154
|
-
*, *::before, *::after {
|
|
155
|
-
scroll-behavior: auto !important;
|
|
156
|
-
animation-duration: 0.01ms !important;
|
|
157
|
-
animation-iteration-count: 1 !important;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
</style>
|
|
161
|
-
</head>
|
|
162
|
-
<body>
|
|
163
|
-
<main>
|
|
164
|
-
<div class="brand" aria-label="OpenCode">
|
|
165
|
-
<svg width="234" height="42" viewBox="0 0 234 42" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
|
166
|
-
<path d="M18 30H6V18H18V30Z" fill="#4B4646"/>
|
|
167
|
-
<path d="M18 12H6V30H18V12ZM24 36H0V6H24V36Z" fill="#B7B1B1"/>
|
|
168
|
-
<path d="M48 30H36V18H48V30Z" fill="#4B4646"/>
|
|
169
|
-
<path d="M36 30H48V12H36V30ZM54 36H36V42H30V6H54V36Z" fill="#B7B1B1"/>
|
|
170
|
-
<path d="M84 24V30H66V24H84Z" fill="#4B4646"/>
|
|
171
|
-
<path d="M84 24H66V30H84V36H60V6H84V24ZM66 18H78V12H66V18Z" fill="#B7B1B1"/>
|
|
172
|
-
<path d="M108 36H96V18H108V36Z" fill="#4B4646"/>
|
|
173
|
-
<path d="M108 12H96V36H90V6H108V12ZM114 36H108V12H114V36Z" fill="#B7B1B1"/>
|
|
174
|
-
<path d="M144 30H126V18H144V30Z" fill="#4B4646"/>
|
|
175
|
-
<path d="M144 12H126V30H144V36H120V6H144V12Z" fill="#F1ECEC"/>
|
|
176
|
-
<path d="M168 30H156V18H168V30Z" fill="#4B4646"/>
|
|
177
|
-
<path d="M168 12H156V30H168V12ZM174 36H150V6H174V36Z" fill="#F1ECEC"/>
|
|
178
|
-
<path d="M198 30H186V18H198V30Z" fill="#4B4646"/>
|
|
179
|
-
<path d="M198 12H186V30H198V12ZM204 36H180V6H198V0H204V36Z" fill="#F1ECEC"/>
|
|
180
|
-
<path d="M234 24V30H216V24H234Z" fill="#4B4646"/>
|
|
181
|
-
<path d="M216 12V18H228V12H216ZM234 24H216V30H234V36H210V6H234V24Z" fill="#F1ECEC"/>
|
|
182
|
-
</svg>
|
|
183
|
-
</div>
|
|
184
|
-
|
|
185
|
-
<section class="card" aria-labelledby="success-title">
|
|
186
|
-
<div class="success-icon" aria-hidden="true">
|
|
187
|
-
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
188
|
-
<path d="M5 12.5 9.25 17 19 7" stroke="currentColor" stroke-width="2.25" stroke-linecap="round" stroke-linejoin="round"/>
|
|
189
|
-
</svg>
|
|
190
|
-
</div>
|
|
191
|
-
|
|
192
|
-
<h1 id="success-title">Authentication complete</h1>
|
|
193
|
-
<p class="lead">Your OpenAI account is connected securely and ready to use with OpenCode.</p>
|
|
194
|
-
|
|
195
|
-
<div class="status" role="status">
|
|
196
|
-
<span class="status-dot" aria-hidden="true"></span>
|
|
197
|
-
<span>Credentials encrypted and stored</span>
|
|
198
|
-
</div>
|
|
199
|
-
|
|
200
|
-
<p class="next-step"><strong>You can close this tab.</strong> Return to your terminal to continue.</p>
|
|
201
|
-
</section>
|
|
202
|
-
</main>
|
|
203
|
-
</body>
|
|
2
|
+
return `<!doctype html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
7
|
+
<meta name="color-scheme" content="dark">
|
|
8
|
+
<title>OpenCode - Authentication complete</title>
|
|
9
|
+
<style nonce="${styleNonce}">
|
|
10
|
+
:root {
|
|
11
|
+
color-scheme: dark;
|
|
12
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
|
|
13
|
+
font-synthesis: none;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
* {
|
|
17
|
+
box-sizing: border-box;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
body {
|
|
21
|
+
min-width: 320px;
|
|
22
|
+
min-height: 100vh;
|
|
23
|
+
margin: 0;
|
|
24
|
+
display: grid;
|
|
25
|
+
place-items: center;
|
|
26
|
+
padding: 32px 20px;
|
|
27
|
+
background:
|
|
28
|
+
radial-gradient(circle at 50% 0%, rgba(42, 195, 126, 0.12), transparent 38rem),
|
|
29
|
+
#080b0a;
|
|
30
|
+
color: #f2f5f3;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
main {
|
|
34
|
+
width: min(100%, 540px);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.brand {
|
|
38
|
+
display: flex;
|
|
39
|
+
margin: 0 0 24px 0;
|
|
40
|
+
justify-content: center;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.brand svg {
|
|
44
|
+
height: 22px;
|
|
45
|
+
width: auto;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.card {
|
|
49
|
+
position: relative;
|
|
50
|
+
overflow: hidden;
|
|
51
|
+
padding: 44px;
|
|
52
|
+
border: 1px solid #26312c;
|
|
53
|
+
border-radius: 20px;
|
|
54
|
+
background: linear-gradient(145deg, rgba(22, 28, 25, 0.98), rgba(13, 17, 15, 0.98));
|
|
55
|
+
box-shadow: 0 24px 80px rgba(0, 0, 0, 0.45);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.card::before {
|
|
59
|
+
content: "";
|
|
60
|
+
position: absolute;
|
|
61
|
+
inset: 0 0 auto;
|
|
62
|
+
height: 1px;
|
|
63
|
+
background: linear-gradient(90deg, transparent, rgba(86, 224, 157, 0.7), transparent);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.success-icon {
|
|
67
|
+
width: 58px;
|
|
68
|
+
height: 58px;
|
|
69
|
+
display: grid;
|
|
70
|
+
place-items: center;
|
|
71
|
+
margin-bottom: 28px;
|
|
72
|
+
border: 1px solid rgba(86, 224, 157, 0.45);
|
|
73
|
+
border-radius: 16px;
|
|
74
|
+
background: rgba(42, 195, 126, 0.1);
|
|
75
|
+
color: #56e09d;
|
|
76
|
+
box-shadow: inset 0 0 28px rgba(42, 195, 126, 0.08);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.success-icon svg {
|
|
80
|
+
width: 28px;
|
|
81
|
+
height: 28px;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
h1 {
|
|
85
|
+
margin: 0;
|
|
86
|
+
font-family: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
87
|
+
font-size: clamp(28px, 6vw, 38px);
|
|
88
|
+
font-weight: 650;
|
|
89
|
+
letter-spacing: -0.035em;
|
|
90
|
+
line-height: 1.12;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.lead {
|
|
94
|
+
margin: 16px 0 0;
|
|
95
|
+
color: #aeb8b3;
|
|
96
|
+
font-family: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
97
|
+
font-size: 17px;
|
|
98
|
+
line-height: 1.6;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.status {
|
|
102
|
+
display: flex;
|
|
103
|
+
align-items: center;
|
|
104
|
+
gap: 12px;
|
|
105
|
+
margin-top: 30px;
|
|
106
|
+
padding: 15px 16px;
|
|
107
|
+
border: 1px solid #29362f;
|
|
108
|
+
border-radius: 12px;
|
|
109
|
+
background: #0b100d;
|
|
110
|
+
color: #c9d2cd;
|
|
111
|
+
font-size: 13px;
|
|
112
|
+
line-height: 1.5;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.status-dot {
|
|
116
|
+
width: 8px;
|
|
117
|
+
height: 8px;
|
|
118
|
+
flex: 0 0 auto;
|
|
119
|
+
border-radius: 50%;
|
|
120
|
+
background: #56e09d;
|
|
121
|
+
box-shadow: 0 0 0 4px rgba(86, 224, 157, 0.1);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.next-step {
|
|
125
|
+
margin: 24px 0 0;
|
|
126
|
+
color: #7f8c85;
|
|
127
|
+
font-size: 13px;
|
|
128
|
+
line-height: 1.6;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.next-step strong {
|
|
132
|
+
color: #b9c3be;
|
|
133
|
+
font-weight: 600;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
@media (max-width: 520px) {
|
|
137
|
+
body {
|
|
138
|
+
padding: 24px 16px;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.card {
|
|
142
|
+
padding: 32px 24px;
|
|
143
|
+
border-radius: 16px;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.success-icon {
|
|
147
|
+
width: 52px;
|
|
148
|
+
height: 52px;
|
|
149
|
+
margin-bottom: 24px;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
@media (prefers-reduced-motion: reduce) {
|
|
154
|
+
*, *::before, *::after {
|
|
155
|
+
scroll-behavior: auto !important;
|
|
156
|
+
animation-duration: 0.01ms !important;
|
|
157
|
+
animation-iteration-count: 1 !important;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
</style>
|
|
161
|
+
</head>
|
|
162
|
+
<body>
|
|
163
|
+
<main>
|
|
164
|
+
<div class="brand" aria-label="OpenCode">
|
|
165
|
+
<svg width="234" height="42" viewBox="0 0 234 42" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
|
166
|
+
<path d="M18 30H6V18H18V30Z" fill="#4B4646"/>
|
|
167
|
+
<path d="M18 12H6V30H18V12ZM24 36H0V6H24V36Z" fill="#B7B1B1"/>
|
|
168
|
+
<path d="M48 30H36V18H48V30Z" fill="#4B4646"/>
|
|
169
|
+
<path d="M36 30H48V12H36V30ZM54 36H36V42H30V6H54V36Z" fill="#B7B1B1"/>
|
|
170
|
+
<path d="M84 24V30H66V24H84Z" fill="#4B4646"/>
|
|
171
|
+
<path d="M84 24H66V30H84V36H60V6H84V24ZM66 18H78V12H66V18Z" fill="#B7B1B1"/>
|
|
172
|
+
<path d="M108 36H96V18H108V36Z" fill="#4B4646"/>
|
|
173
|
+
<path d="M108 12H96V36H90V6H108V12ZM114 36H108V12H114V36Z" fill="#B7B1B1"/>
|
|
174
|
+
<path d="M144 30H126V18H144V30Z" fill="#4B4646"/>
|
|
175
|
+
<path d="M144 12H126V30H144V36H120V6H144V12Z" fill="#F1ECEC"/>
|
|
176
|
+
<path d="M168 30H156V18H168V30Z" fill="#4B4646"/>
|
|
177
|
+
<path d="M168 12H156V30H168V12ZM174 36H150V6H174V36Z" fill="#F1ECEC"/>
|
|
178
|
+
<path d="M198 30H186V18H198V30Z" fill="#4B4646"/>
|
|
179
|
+
<path d="M198 12H186V30H198V12ZM204 36H180V6H198V0H204V36Z" fill="#F1ECEC"/>
|
|
180
|
+
<path d="M234 24V30H216V24H234Z" fill="#4B4646"/>
|
|
181
|
+
<path d="M216 12V18H228V12H216ZM234 24H216V30H234V36H210V6H234V24Z" fill="#F1ECEC"/>
|
|
182
|
+
</svg>
|
|
183
|
+
</div>
|
|
184
|
+
|
|
185
|
+
<section class="card" aria-labelledby="success-title">
|
|
186
|
+
<div class="success-icon" aria-hidden="true">
|
|
187
|
+
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
188
|
+
<path d="M5 12.5 9.25 17 19 7" stroke="currentColor" stroke-width="2.25" stroke-linecap="round" stroke-linejoin="round"/>
|
|
189
|
+
</svg>
|
|
190
|
+
</div>
|
|
191
|
+
|
|
192
|
+
<h1 id="success-title">Authentication complete</h1>
|
|
193
|
+
<p class="lead">Your OpenAI account is connected securely and ready to use with OpenCode.</p>
|
|
194
|
+
|
|
195
|
+
<div class="status" role="status">
|
|
196
|
+
<span class="status-dot" aria-hidden="true"></span>
|
|
197
|
+
<span>Credentials encrypted and stored</span>
|
|
198
|
+
</div>
|
|
199
|
+
|
|
200
|
+
<p class="next-step"><strong>You can close this tab.</strong> Return to your terminal to continue.</p>
|
|
201
|
+
</section>
|
|
202
|
+
</main>
|
|
203
|
+
</body>
|
|
204
204
|
</html>`;
|
|
205
205
|
}
|
|
206
206
|
// Retained for the standalone HTML artifact generated by the package build.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How much Codex capacity one ChatGPT plan carries relative to another.
|
|
3
|
+
*
|
|
4
|
+
* A pool of accounts on different plans has no single "percent used": one
|
|
5
|
+
* Pro seat spent to 50% has given up far more capacity than a Business
|
|
6
|
+
* Standard seat spent to 50%, so averaging the two percentages unweighted
|
|
7
|
+
* reports a pool that does not exist. Every plan here therefore carries a
|
|
8
|
+
* {@link PlanAllotment.weight} - its allotment relative to a 1x seat - and the
|
|
9
|
+
* pool total is the weighted mean.
|
|
10
|
+
*
|
|
11
|
+
* The weights are OpenAI's own published per-seat ratios, taken from the
|
|
12
|
+
* plan's monthly price against the 1x Plus/Business Standard seat: Pro is
|
|
13
|
+
* $200 against $20, and is marketed as 20x. They describe the *subscription*,
|
|
14
|
+
* not a measured token allowance, which is the only ratio OpenAI states and
|
|
15
|
+
* the same one the seat is sold on.
|
|
16
|
+
*
|
|
17
|
+
* `plan_type` is what the `/wham/usage` endpoint and the `chatgpt_plan_type`
|
|
18
|
+
* access-token claim report. Two of its slugs are not derivable from their
|
|
19
|
+
* text - `team` is the slug still emitted for what OpenAI now calls Business,
|
|
20
|
+
* and `self_serve_business_prolite` is the premium Business seat rather than
|
|
21
|
+
* the personal Pro Lite tier that shares the `prolite` token - so both are
|
|
22
|
+
* matched explicitly below.
|
|
23
|
+
*
|
|
24
|
+
* This module is deliberately a leaf (no imports). The prompt status line
|
|
25
|
+
* depends on it, and naming a plan is a separate concern that already has an
|
|
26
|
+
* owner in `lib/auth/plan-tier.ts`; pulling that in here would drag JWT
|
|
27
|
+
* decoding into the TUI's render path for a number that needs none of it.
|
|
28
|
+
*/
|
|
29
|
+
export type PlanAllotment = {
|
|
30
|
+
/**
|
|
31
|
+
* Allotment relative to a 1x seat, or `undefined` when the plan states no
|
|
32
|
+
* ratio. `undefined` is not 1: a plan we cannot place must not be
|
|
33
|
+
* silently averaged as though it were the baseline.
|
|
34
|
+
*/
|
|
35
|
+
weight?: number;
|
|
36
|
+
/** Marketing badge for the same ratio, e.g. `5x`. */
|
|
37
|
+
multiplier?: string;
|
|
38
|
+
/** Per-seat monthly price in USD, as listed by OpenAI. */
|
|
39
|
+
monthlyUsd?: number;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Weight used for a plan that states no ratio, so one unplaceable account
|
|
43
|
+
* cannot remove every other account from the pool total. It is the baseline
|
|
44
|
+
* seat rather than a guess at something larger: under-weighting an unknown
|
|
45
|
+
* plan understates one account, while over-weighting it would let a plan we
|
|
46
|
+
* failed to recognize dominate the number the whole pool is judged by.
|
|
47
|
+
*/
|
|
48
|
+
export declare const DEFAULT_PLAN_WEIGHT = 1;
|
|
49
|
+
/**
|
|
50
|
+
* Reduce a `plan_type` to the form the matchers below expect.
|
|
51
|
+
*
|
|
52
|
+
* The admin roster spells a tier as one token (`chatgptteamplan`) while the
|
|
53
|
+
* usage endpoint reports the bare word (`team`), and the premium Business
|
|
54
|
+
* seat arrives underscored (`self_serve_business_prolite`). All three have to
|
|
55
|
+
* land on the same normalized text or one seat is weighted differently
|
|
56
|
+
* depending on which surface named it.
|
|
57
|
+
*/
|
|
58
|
+
export declare function normalizePlanSlug(value: string | null | undefined): string | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Resolve a `plan_type` to its allotment. An unrecognized plan returns an
|
|
61
|
+
* empty allotment rather than a guess, so callers can tell "1x" apart from
|
|
62
|
+
* "we do not know".
|
|
63
|
+
*/
|
|
64
|
+
export declare function describePlanAllotment(planType: string | null | undefined): PlanAllotment;
|
|
65
|
+
/**
|
|
66
|
+
* The weight to average an account by, falling back to
|
|
67
|
+
* {@link DEFAULT_PLAN_WEIGHT} for a plan that states no ratio.
|
|
68
|
+
*/
|
|
69
|
+
export declare function getPlanWeight(planType: string | null | undefined): number;
|
|
70
|
+
/** `5x`, or `undefined` when the plan states no ratio. */
|
|
71
|
+
export declare function formatPlanMultiplier(planType: string | null | undefined): string | undefined;
|
|
72
|
+
//# sourceMappingURL=plan-allotment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-allotment.d.ts","sourceRoot":"","sources":["../../lib/plan-allotment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,MAAM,MAAM,aAAa,GAAG;IAC3B;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAIF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAetF;AA6CD;;;;GAIG;AACH,wBAAgB,qBAAqB,CACpC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACjC,aAAa,CAkBf;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAEzE;AAED,0DAA0D;AAC1D,wBAAgB,oBAAoB,CACnC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACjC,MAAM,GAAG,SAAS,CAEpB"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How much Codex capacity one ChatGPT plan carries relative to another.
|
|
3
|
+
*
|
|
4
|
+
* A pool of accounts on different plans has no single "percent used": one
|
|
5
|
+
* Pro seat spent to 50% has given up far more capacity than a Business
|
|
6
|
+
* Standard seat spent to 50%, so averaging the two percentages unweighted
|
|
7
|
+
* reports a pool that does not exist. Every plan here therefore carries a
|
|
8
|
+
* {@link PlanAllotment.weight} - its allotment relative to a 1x seat - and the
|
|
9
|
+
* pool total is the weighted mean.
|
|
10
|
+
*
|
|
11
|
+
* The weights are OpenAI's own published per-seat ratios, taken from the
|
|
12
|
+
* plan's monthly price against the 1x Plus/Business Standard seat: Pro is
|
|
13
|
+
* $200 against $20, and is marketed as 20x. They describe the *subscription*,
|
|
14
|
+
* not a measured token allowance, which is the only ratio OpenAI states and
|
|
15
|
+
* the same one the seat is sold on.
|
|
16
|
+
*
|
|
17
|
+
* `plan_type` is what the `/wham/usage` endpoint and the `chatgpt_plan_type`
|
|
18
|
+
* access-token claim report. Two of its slugs are not derivable from their
|
|
19
|
+
* text - `team` is the slug still emitted for what OpenAI now calls Business,
|
|
20
|
+
* and `self_serve_business_prolite` is the premium Business seat rather than
|
|
21
|
+
* the personal Pro Lite tier that shares the `prolite` token - so both are
|
|
22
|
+
* matched explicitly below.
|
|
23
|
+
*
|
|
24
|
+
* This module is deliberately a leaf (no imports). The prompt status line
|
|
25
|
+
* depends on it, and naming a plan is a separate concern that already has an
|
|
26
|
+
* owner in `lib/auth/plan-tier.ts`; pulling that in here would drag JWT
|
|
27
|
+
* decoding into the TUI's render path for a number that needs none of it.
|
|
28
|
+
*/
|
|
29
|
+
const UNKNOWN_ALLOTMENT = {};
|
|
30
|
+
/**
|
|
31
|
+
* Weight used for a plan that states no ratio, so one unplaceable account
|
|
32
|
+
* cannot remove every other account from the pool total. It is the baseline
|
|
33
|
+
* seat rather than a guess at something larger: under-weighting an unknown
|
|
34
|
+
* plan understates one account, while over-weighting it would let a plan we
|
|
35
|
+
* failed to recognize dominate the number the whole pool is judged by.
|
|
36
|
+
*/
|
|
37
|
+
export const DEFAULT_PLAN_WEIGHT = 1;
|
|
38
|
+
/**
|
|
39
|
+
* Reduce a `plan_type` to the form the matchers below expect.
|
|
40
|
+
*
|
|
41
|
+
* The admin roster spells a tier as one token (`chatgptteamplan`) while the
|
|
42
|
+
* usage endpoint reports the bare word (`team`), and the premium Business
|
|
43
|
+
* seat arrives underscored (`self_serve_business_prolite`). All three have to
|
|
44
|
+
* land on the same normalized text or one seat is weighted differently
|
|
45
|
+
* depending on which surface named it.
|
|
46
|
+
*/
|
|
47
|
+
export function normalizePlanSlug(value) {
|
|
48
|
+
if (typeof value !== "string")
|
|
49
|
+
return undefined;
|
|
50
|
+
// Case is folded before anything else is stripped, so every pattern below
|
|
51
|
+
// can be written once in lower case. Stripping first would leave the
|
|
52
|
+
// trailing-`plan` rule matching `teamplan` but not `Team_Plan`, and the
|
|
53
|
+
// same seat would then weigh differently depending on which surface spelled
|
|
54
|
+
// it.
|
|
55
|
+
const normalized = value
|
|
56
|
+
.trim()
|
|
57
|
+
.toLowerCase()
|
|
58
|
+
.replace(/^chatgpt[\s_-]*/, "")
|
|
59
|
+
.replace(/[\s_-]+/g, " ")
|
|
60
|
+
.replace(/\s?plan$/, "")
|
|
61
|
+
.trim();
|
|
62
|
+
return normalized || undefined;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* A `business` seat's ratio, which depends on the qualifier beside it.
|
|
66
|
+
*
|
|
67
|
+
* `self_serve_business_prolite` normalizes to `self serve business prolite`,
|
|
68
|
+
* so `business` is matched as a whole word anywhere in the text rather than
|
|
69
|
+
* as a prefix. A bare `business` names the workspace rather than the seat,
|
|
70
|
+
* and the two seats inside it are 5x apart, so it states no ratio at all.
|
|
71
|
+
*/
|
|
72
|
+
function describeBusinessSeat(plan) {
|
|
73
|
+
if (!/(^| )business( |$)/.test(plan))
|
|
74
|
+
return undefined;
|
|
75
|
+
if (plan.includes("prolite") ||
|
|
76
|
+
plan.includes("pro lite") ||
|
|
77
|
+
plan.includes("premium")) {
|
|
78
|
+
return { weight: 5, multiplier: "5x", monthlyUsd: 125 };
|
|
79
|
+
}
|
|
80
|
+
if (plan.includes("standard")) {
|
|
81
|
+
return { weight: 1, multiplier: "1x", monthlyUsd: 25 };
|
|
82
|
+
}
|
|
83
|
+
return UNKNOWN_ALLOTMENT;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* The $100 Pro that predates the $200 one. Both report a `pro` family slug,
|
|
87
|
+
* and they are 4x apart, so the legacy spellings are matched before the
|
|
88
|
+
* current tier claims the bare word.
|
|
89
|
+
*/
|
|
90
|
+
function isLegacyProPlan(plan) {
|
|
91
|
+
return (plan === "pro 5x" ||
|
|
92
|
+
plan === "pro 100" ||
|
|
93
|
+
plan === "pro legacy" ||
|
|
94
|
+
plan === "legacy pro" ||
|
|
95
|
+
plan === "legacy pro 5x" ||
|
|
96
|
+
plan === "pro legacy 5x");
|
|
97
|
+
}
|
|
98
|
+
function isCurrentProPlan(plan) {
|
|
99
|
+
return plan === "pro" || plan === "pro 20x" || plan === "pro 200";
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Resolve a `plan_type` to its allotment. An unrecognized plan returns an
|
|
103
|
+
* empty allotment rather than a guess, so callers can tell "1x" apart from
|
|
104
|
+
* "we do not know".
|
|
105
|
+
*/
|
|
106
|
+
export function describePlanAllotment(planType) {
|
|
107
|
+
const plan = normalizePlanSlug(planType);
|
|
108
|
+
if (!plan)
|
|
109
|
+
return UNKNOWN_ALLOTMENT;
|
|
110
|
+
if (plan === "plus")
|
|
111
|
+
return { weight: 1, multiplier: "1x", monthlyUsd: 20 };
|
|
112
|
+
// `team` is the slug OpenAI still emits for Business; a qualified
|
|
113
|
+
// `team premium` / `team standard` is handled by the business matcher.
|
|
114
|
+
if (plan === "team")
|
|
115
|
+
return { weight: 1, multiplier: "1x", monthlyUsd: 25 };
|
|
116
|
+
const business = describeBusinessSeat(plan);
|
|
117
|
+
if (business)
|
|
118
|
+
return business;
|
|
119
|
+
if (isLegacyProPlan(plan))
|
|
120
|
+
return { weight: 5, multiplier: "5x", monthlyUsd: 100 };
|
|
121
|
+
if (isCurrentProPlan(plan))
|
|
122
|
+
return { weight: 20, multiplier: "20x", monthlyUsd: 200 };
|
|
123
|
+
if (plan === "prolite" || plan === "pro lite") {
|
|
124
|
+
return { weight: 5, multiplier: "5x", monthlyUsd: 100 };
|
|
125
|
+
}
|
|
126
|
+
// Go, Free and Enterprise all reach here. The first two carry no Codex
|
|
127
|
+
// allotment worth weighting, and Enterprise is negotiated per contract, so
|
|
128
|
+
// none of them states a ratio this code could apply.
|
|
129
|
+
return UNKNOWN_ALLOTMENT;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* The weight to average an account by, falling back to
|
|
133
|
+
* {@link DEFAULT_PLAN_WEIGHT} for a plan that states no ratio.
|
|
134
|
+
*/
|
|
135
|
+
export function getPlanWeight(planType) {
|
|
136
|
+
return describePlanAllotment(planType).weight ?? DEFAULT_PLAN_WEIGHT;
|
|
137
|
+
}
|
|
138
|
+
/** `5x`, or `undefined` when the plan states no ratio. */
|
|
139
|
+
export function formatPlanMultiplier(planType) {
|
|
140
|
+
return describePlanAllotment(planType).multiplier;
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=plan-allotment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-allotment.js","sourceRoot":"","sources":["../../lib/plan-allotment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAeH,MAAM,iBAAiB,GAAkB,EAAE,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAErC;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAgC;IACjE,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChD,0EAA0E;IAC1E,qEAAqE;IACrE,wEAAwE;IACxE,4EAA4E;IAC5E,MAAM;IACN,MAAM,UAAU,GAAG,KAAK;SACtB,IAAI,EAAE;SACN,WAAW,EAAE;SACb,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC;SAC9B,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;SACxB,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,IAAI,EAAE,CAAC;IACT,OAAO,UAAU,IAAI,SAAS,CAAC;AAChC,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,oBAAoB,CAAC,IAAY;IACzC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACvD,IACC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;QACxB,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;QACzB,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EACvB,CAAC;QACF,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC;IACzD,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IACxD,CAAC;IACD,OAAO,iBAAiB,CAAC;AAC1B,CAAC;AAED;;;;GAIG;AACH,SAAS,eAAe,CAAC,IAAY;IACpC,OAAO,CACN,IAAI,KAAK,QAAQ;QACjB,IAAI,KAAK,SAAS;QAClB,IAAI,KAAK,YAAY;QACrB,IAAI,KAAK,YAAY;QACrB,IAAI,KAAK,eAAe;QACxB,IAAI,KAAK,eAAe,CACxB,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAY;IACrC,OAAO,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,CAAC;AACnE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CACpC,QAAmC;IAEnC,MAAM,IAAI,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,IAAI;QAAE,OAAO,iBAAiB,CAAC;IACpC,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IAC5E,kEAAkE;IAClE,uEAAuE;IACvE,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IAC5E,MAAM,QAAQ,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,IAAI,eAAe,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC;IACnF,IAAI,gBAAgB,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC;IACtF,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/C,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC;IACzD,CAAC;IACD,uEAAuE;IACvE,2EAA2E;IAC3E,qDAAqD;IACrD,OAAO,iBAAiB,CAAC;AAC1B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,QAAmC;IAChE,OAAO,qBAAqB,CAAC,QAAQ,CAAC,CAAC,MAAM,IAAI,mBAAmB,CAAC;AACtE,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,oBAAoB,CACnC,QAAmC;IAEnC,OAAO,qBAAqB,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC;AACnD,CAAC"}
|