@shopify/shop-minis-cli 0.0.185 → 0.0.187

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.
Files changed (31) hide show
  1. package/build/commands/dev/utils/interactive-terminal.js +2 -0
  2. package/build/commands/dev/utils/interactive-terminal.js.map +1 -1
  3. package/build/commands/submit/gcs.d.ts +3 -2
  4. package/build/commands/submit/gcs.js +25 -6
  5. package/build/commands/submit/gcs.js.map +1 -1
  6. package/build/commands/submit/submit.js +7 -1
  7. package/build/commands/submit/submit.js.map +1 -1
  8. package/build/commands/submit/tasks.d.ts +5 -3
  9. package/build/commands/submit/tasks.js +2 -1
  10. package/build/commands/submit/tasks.js.map +1 -1
  11. package/build/data/create-upload.d.ts +2 -1
  12. package/build/data/create-upload.js +1 -0
  13. package/build/data/create-upload.js.map +1 -1
  14. package/build/data/types/autogenerated/shop-minis-admin-api/gql.d.ts +2 -2
  15. package/build/data/types/autogenerated/shop-minis-admin-api/gql.js +1 -1
  16. package/build/data/types/autogenerated/shop-minis-admin-api/gql.js.map +1 -1
  17. package/build/data/types/autogenerated/shop-minis-admin-api/graphql.d.ts +5 -30
  18. package/build/data/types/autogenerated/shop-minis-admin-api/graphql.js +4 -0
  19. package/build/data/types/autogenerated/shop-minis-admin-api/graphql.js.map +1 -1
  20. package/build/dev-panel/asset-manifest.json +6 -6
  21. package/build/dev-panel/index.html +1 -1
  22. package/build/dev-panel/static/css/{main.94b1dbb1.css → main.d66fe13a.css} +2 -2
  23. package/build/dev-panel/static/css/main.d66fe13a.css.map +1 -0
  24. package/build/dev-panel/static/js/{main.917a564c.js → main.baf3846f.js} +3 -3
  25. package/build/dev-panel/static/js/{main.917a564c.js.map → main.baf3846f.js.map} +1 -1
  26. package/build/utils/allowed-dependencies.js +2 -0
  27. package/build/utils/allowed-dependencies.js.map +1 -1
  28. package/package.json +1 -1
  29. package/scripts/audit-dependencies.ts +412 -0
  30. package/build/dev-panel/static/css/main.94b1dbb1.css.map +0 -1
  31. /package/build/dev-panel/static/js/{main.917a564c.js.LICENSE.txt → main.baf3846f.js.LICENSE.txt} +0 -0
@@ -27,6 +27,8 @@ export const OPTIONAL_DEPENDENCIES = {
27
27
  ai: '5.0.29',
28
28
  '@ai-sdk/openai': '2.0.23',
29
29
  '@ai-sdk/react': '2.0.29',
30
+ '@tensorflow/tfjs': '4.22.0',
31
+ '@tensorflow-models/posenet': '2.2.2',
30
32
  };
31
33
  export const ALLOWED_DEPENDENCIES = {
32
34
  ...REQUIRED_DEPENDENCIES,
@@ -1 +1 @@
1
- {"version":3,"file":"allowed-dependencies.js","sourceRoot":"","sources":["../../src/utils/allowed-dependencies.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,8DAA8D;AAC9D,mDAAmD;AAEnD,MAAM,CAAC,MAAM,qBAAqB,GAA2B;IAC3D,2BAA2B,EAAE,GAAG;IAChC,KAAK,EAAE,QAAQ;IACf,WAAW,EAAE,QAAQ;CACtB,CAAA;AAED,MAAM,CAAC,MAAM,qBAAqB,GAA2B;IAC3D,gBAAgB,EAAE,OAAO;IACzB,iBAAiB,EAAE,gBAAgB;IACnC,oBAAoB,EAAE,QAAQ;IAC9B,MAAM,EAAE,OAAO;IACf,eAAe,EAAE,OAAO;IACxB,SAAS,EAAE,OAAO;IAClB,KAAK,EAAE,SAAS;IAChB,MAAM,EAAE,SAAS;IACjB,cAAc,EAAE,SAAS;IACzB,MAAM,EAAE,SAAS;IACjB,UAAU,EAAE,OAAO;IACnB,cAAc,EAAE,OAAO;IACvB,kBAAkB,EAAE,OAAO;IAC3B,UAAU,EAAE,QAAQ;IACpB,IAAI,EAAE,OAAO;IACb,OAAO,EAAE,OAAO;IAChB,uBAAuB,EAAE,QAAQ;IACjC,EAAE,EAAE,QAAQ;IACZ,gBAAgB,EAAE,QAAQ;IAC1B,eAAe,EAAE,QAAQ;CAC1B,CAAA;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,GAAG,qBAAqB;IACxB,GAAG,qBAAqB;CACzB,CAAA"}
1
+ {"version":3,"file":"allowed-dependencies.js","sourceRoot":"","sources":["../../src/utils/allowed-dependencies.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,8DAA8D;AAC9D,mDAAmD;AAEnD,MAAM,CAAC,MAAM,qBAAqB,GAA2B;IAC3D,2BAA2B,EAAE,GAAG;IAChC,KAAK,EAAE,QAAQ;IACf,WAAW,EAAE,QAAQ;CACtB,CAAA;AAED,MAAM,CAAC,MAAM,qBAAqB,GAA2B;IAC3D,gBAAgB,EAAE,OAAO;IACzB,iBAAiB,EAAE,gBAAgB;IACnC,oBAAoB,EAAE,QAAQ;IAC9B,MAAM,EAAE,OAAO;IACf,eAAe,EAAE,OAAO;IACxB,SAAS,EAAE,OAAO;IAClB,KAAK,EAAE,SAAS;IAChB,MAAM,EAAE,SAAS;IACjB,cAAc,EAAE,SAAS;IACzB,MAAM,EAAE,SAAS;IACjB,UAAU,EAAE,OAAO;IACnB,cAAc,EAAE,OAAO;IACvB,kBAAkB,EAAE,OAAO;IAC3B,UAAU,EAAE,QAAQ;IACpB,IAAI,EAAE,OAAO;IACb,OAAO,EAAE,OAAO;IAChB,uBAAuB,EAAE,QAAQ;IACjC,EAAE,EAAE,QAAQ;IACZ,gBAAgB,EAAE,QAAQ;IAC1B,eAAe,EAAE,QAAQ;IACzB,kBAAkB,EAAE,QAAQ;IAC5B,4BAA4B,EAAE,OAAO;CACtC,CAAA;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,GAAG,qBAAqB;IACxB,GAAG,qBAAqB;CACzB,CAAA"}
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "access": "public",
5
5
  "@shopify:registry": "https://registry.npmjs.org/"
6
6
  },
7
- "version": "0.0.185",
7
+ "version": "0.0.187",
8
8
  "description": "Shop Minis CLI",
9
9
  "main": "build/index.js",
10
10
  "bin": {
@@ -0,0 +1,412 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Simple Dependency Audit Script
4
+ * Usage:
5
+ * npx tsx audit-dependencies.ts <package-name> [version] # Audit single package
6
+ * npx tsx audit-dependencies.ts # Audit new dependencies from git diff
7
+ */
8
+
9
+ import {exec} from 'child_process'
10
+ import {promisify} from 'util'
11
+
12
+ const execAsync = promisify(exec)
13
+
14
+ interface PackageInfo {
15
+ package: string
16
+ version: string
17
+ repository: string
18
+ dependenciesCount: number
19
+ publishDate: string
20
+ }
21
+
22
+ interface DependencyInfo {
23
+ name: string
24
+ version: string
25
+ }
26
+
27
+ class PackageAuditor {
28
+ private packageName: string
29
+ private version: string
30
+ private riskScore = 0
31
+ private riskFactors: string[] = []
32
+ private vulnerabilities: string[] = []
33
+
34
+ constructor(packageName: string, version = 'latest') {
35
+ this.packageName = packageName
36
+ this.version = version
37
+ }
38
+
39
+ private async fetchJson(url: string): Promise<any> {
40
+ try {
41
+ const {stdout} = await execAsync(`curl -s "${url}"`, {
42
+ maxBuffer: 1024 * 1024 * 10, // 10MB buffer for large NPM responses
43
+ })
44
+ return JSON.parse(stdout)
45
+ } catch (error) {
46
+ throw new Error(`Failed to fetch ${url}: ${error}`)
47
+ }
48
+ }
49
+
50
+ private async fetchPostJson(url: string, body: any): Promise<any> {
51
+ try {
52
+ const jsonBody = JSON.stringify(body)
53
+ const {stdout} = await execAsync(
54
+ `curl -s -X POST -H "Content-Type: application/json" -d '${jsonBody}' "${url}"`,
55
+ {maxBuffer: 1024 * 1024 * 10} // 10MB buffer for large responses
56
+ )
57
+ return JSON.parse(stdout)
58
+ } catch (error) {
59
+ throw new Error(`Failed to POST to ${url}: ${error}`)
60
+ }
61
+ }
62
+
63
+ private async fetchNpmData(): Promise<any> {
64
+ try {
65
+ // Use abbreviated NPM registry (much smaller, but has what we need)
66
+ const data = await this.fetchJson(
67
+ `https://registry.npmjs.org/${this.packageName}/latest`
68
+ )
69
+
70
+ // For non-latest versions, we need to get specific version
71
+ if (this.version !== 'latest') {
72
+ try {
73
+ const versionData = await this.fetchJson(
74
+ `https://registry.npmjs.org/${this.packageName}/${this.version}`
75
+ )
76
+ return {
77
+ 'dist-tags': {latest: data.version},
78
+ repository: versionData.repository || data.repository,
79
+ time: versionData.time || {},
80
+ versions: {[this.version]: versionData},
81
+ }
82
+ } catch {
83
+ // If specific version fetch fails, use latest data
84
+ return {
85
+ 'dist-tags': {latest: data.version},
86
+ repository: data.repository,
87
+ time: {},
88
+ versions: {[data.version]: data},
89
+ }
90
+ }
91
+ }
92
+
93
+ // For latest version, structure data consistently
94
+ return {
95
+ 'dist-tags': {latest: data.version},
96
+ repository: data.repository,
97
+ time: {[data.version]: data.time || 'unknown'},
98
+ versions: {[data.version]: data},
99
+ }
100
+ } catch (error) {
101
+ console.error(
102
+ `⚠️ Optimized fetch failed for ${this.packageName}, package may not exist`
103
+ )
104
+ throw error
105
+ }
106
+ }
107
+
108
+ private async fetchDownloads(): Promise<number> {
109
+ try {
110
+ const data = await this.fetchJson(
111
+ `https://api.npmjs.org/downloads/point/last-week/${this.packageName}`
112
+ )
113
+ return data.downloads || 0
114
+ } catch {
115
+ return 0
116
+ }
117
+ }
118
+
119
+ private extractPackageInfo(npmData: any): PackageInfo {
120
+ const latestVersion = npmData['dist-tags']?.latest || 'unknown'
121
+ const versionToUse =
122
+ this.version === 'latest' ? latestVersion : this.version
123
+
124
+ const repository = (
125
+ npmData.repository?.url ||
126
+ npmData.versions?.[latestVersion]?.repository?.url ||
127
+ 'none'
128
+ )
129
+ .replace(/^git\+/, '')
130
+ .replace(/\.git$/, '')
131
+
132
+ const dependenciesCount = Object.keys(
133
+ npmData.versions?.[versionToUse]?.dependencies || {}
134
+ ).length
135
+
136
+ const publishDate = npmData.time?.[versionToUse] || 'unknown'
137
+
138
+ if (this.version === 'latest') {
139
+ this.version = latestVersion
140
+ }
141
+
142
+ return {
143
+ package: this.packageName,
144
+ version: versionToUse,
145
+ repository,
146
+ dependenciesCount,
147
+ publishDate,
148
+ }
149
+ }
150
+
151
+ private async checkPublicVulnerabilities(): Promise<void> {
152
+ const vulnerabilities: string[] = []
153
+ let totalVulnCount = 0
154
+
155
+ // 1. Check NPM Security Advisories (official, reliable)
156
+ try {
157
+ const auditData = await this.fetchJson(
158
+ `https://registry.npmjs.org/-/npm/v1/security/advisories/search?text=${this.packageName}`
159
+ )
160
+
161
+ if (auditData.objects && auditData.objects.length > 0) {
162
+ auditData.objects.forEach((advisory: any) => {
163
+ if (advisory.package_name === this.packageName) {
164
+ totalVulnCount++
165
+ vulnerabilities.push(`NPM: ${advisory.title}`)
166
+ }
167
+ })
168
+ }
169
+ } catch {
170
+ // NPM audit API might not be available
171
+ }
172
+
173
+ // 2. Check OSV (Google-maintained, comprehensive)
174
+ try {
175
+ const osvData = await this.fetchPostJson(`https://api.osv.dev/v1/query`, {
176
+ package: {name: this.packageName, ecosystem: 'npm'},
177
+ })
178
+
179
+ if (osvData.vulns && osvData.vulns.length > 0) {
180
+ osvData.vulns.forEach((vuln: any) => {
181
+ totalVulnCount++
182
+ vulnerabilities.push(
183
+ `OSV: ${vuln.id} - ${vuln.summary || 'Vulnerability'}`
184
+ )
185
+ })
186
+ }
187
+ } catch {
188
+ // OSV might not have data for this package
189
+ }
190
+
191
+ // 3. Check Snyk (industry standard, but may require auth)
192
+ try {
193
+ const snykData = await this.fetchJson(
194
+ `https://api.snyk.io/v1/test/npm/${this.packageName}/${this.version}`
195
+ )
196
+
197
+ if (snykData.issues && snykData.issues.vulnerabilities) {
198
+ snykData.issues.vulnerabilities.forEach((vuln: any) => {
199
+ totalVulnCount++
200
+ vulnerabilities.push(`Snyk: ${vuln.title}`)
201
+ })
202
+ }
203
+ } catch {
204
+ // Snyk API might require auth or have rate limits - continue without it
205
+ }
206
+
207
+ // Calculate risk based on findings
208
+ if (totalVulnCount > 0) {
209
+ this.riskScore += Math.min(totalVulnCount * 5, 50)
210
+ this.riskFactors.push(`${totalVulnCount} security vulnerabilities found`)
211
+ this.vulnerabilities = vulnerabilities
212
+ }
213
+ }
214
+
215
+ private assessMaintenanceRisk(publishDate: string): void {
216
+ if (publishDate && publishDate !== 'unknown') {
217
+ const packageDate = new Date(publishDate).getTime()
218
+ const now = Date.now()
219
+ const daysSince = Math.floor((now - packageDate) / (1000 * 60 * 60 * 24))
220
+
221
+ if (daysSince > 365 * 2) {
222
+ this.riskScore += 25
223
+ this.riskFactors.push('Package >2 years old')
224
+ } else if (daysSince > 365) {
225
+ this.riskScore += 10
226
+ this.riskFactors.push('Package >1 year old')
227
+ }
228
+ }
229
+ }
230
+
231
+ private assessAdoptionRisk(downloads: number): void {
232
+ if (downloads < 1000) {
233
+ this.riskScore += 25
234
+ this.riskFactors.push('Low adoption (<1K downloads/week)')
235
+ } else if (downloads < 10000) {
236
+ this.riskScore += 10
237
+ this.riskFactors.push('Moderate adoption (<10K downloads/week)')
238
+ }
239
+ }
240
+
241
+ private getRiskLevel(): string {
242
+ if (this.riskScore <= 15) return '🟢 LOW'
243
+ if (this.riskScore <= 49) return '🟡 MEDIUM'
244
+ return '🔴 HIGH/CRITICAL'
245
+ }
246
+
247
+ private getDecision(): string {
248
+ if (this.riskScore <= 15) return '✅ APPROVE'
249
+ if (this.riskScore <= 49) return '⚠️ CONDITIONAL APPROVAL'
250
+ return '❌ REJECT'
251
+ }
252
+
253
+ private generateReport(packageInfo: PackageInfo, downloads: number): void {
254
+ const riskLevel = this.getRiskLevel()
255
+ const decision = this.getDecision()
256
+ const formattedDownloads = downloads.toLocaleString()
257
+
258
+ console.log(`
259
+ ### 📦 ${packageInfo.package}@${packageInfo.version}
260
+
261
+ **${riskLevel}** | **${decision}**
262
+
263
+ 📈 **Downloads:** ${formattedDownloads}/week
264
+ 🔗 **Dependencies:** ${packageInfo.dependenciesCount}
265
+ 📊 **Risk Score:** ${this.riskScore}/100
266
+
267
+ ${
268
+ this.riskFactors.length > 0
269
+ ? `⚠️ **Issues Found:**\n${this.riskFactors
270
+ .map(factor => ` - ${factor}`)
271
+ .join('\n')}`
272
+ : '✅ **No risk factors identified**'
273
+ }
274
+
275
+ ${
276
+ this.vulnerabilities.length > 0
277
+ ? `🚨 **Security Vulnerabilities (${
278
+ this.vulnerabilities.length
279
+ }):**\n${this.vulnerabilities
280
+ .slice(0, 3)
281
+ .map(vuln => ` - ${vuln}`)
282
+ .join('\n')}${
283
+ this.vulnerabilities.length > 3
284
+ ? `\n - ... and ${this.vulnerabilities.length - 3} more`
285
+ : ''
286
+ }`
287
+ : '🛡️ **Security:** No vulnerabilities found'
288
+ }
289
+
290
+ ---
291
+ `)
292
+ }
293
+
294
+ async audit(): Promise<void> {
295
+ try {
296
+ const npmData = await this.fetchNpmData()
297
+ const packageInfo = this.extractPackageInfo(npmData)
298
+ const downloads = await this.fetchDownloads()
299
+
300
+ await this.checkPublicVulnerabilities()
301
+ this.assessMaintenanceRisk(packageInfo.publishDate)
302
+ this.assessAdoptionRisk(downloads)
303
+
304
+ this.generateReport(packageInfo, downloads)
305
+ } catch (error) {
306
+ console.error(`❌ Audit failed: ${error}`)
307
+ process.exit(1)
308
+ }
309
+ }
310
+ }
311
+
312
+ // Simple git diff function
313
+ async function getAddedDependencies(): Promise<DependencyInfo[]> {
314
+ try {
315
+ const {stdout} = await execAsync(
316
+ `git diff HEAD~1 HEAD -- src/utils/allowed-dependencies.ts`,
317
+ {maxBuffer: 1024 * 1024}
318
+ )
319
+
320
+ const addedLines = stdout
321
+ .split('\n')
322
+ .filter(line => line.startsWith('+'))
323
+ .filter(line => !line.startsWith('+++'))
324
+ .filter(line => line.includes(':'))
325
+
326
+ const addedDependencies: DependencyInfo[] = []
327
+
328
+ for (const line of addedLines) {
329
+ const depRegex =
330
+ /\+.*(?:['"`]([^'"`]+)['"`]|([a-zA-Z0-9@_-]+))\s*:\s*['"`]([^'"`]+)['"`]/
331
+ const match = line.match(depRegex)
332
+
333
+ if (match) {
334
+ const packageName = match[1] || match[2]
335
+ const version = match[3]
336
+ addedDependencies.push({name: packageName, version})
337
+ }
338
+ }
339
+
340
+ return addedDependencies
341
+ } catch (error) {
342
+ console.error(`⚠️ Could not get git diff: ${error}`)
343
+ return []
344
+ }
345
+ }
346
+
347
+ // Simple audit of multiple dependencies
348
+ async function auditAddedDependencies(): Promise<void> {
349
+ try {
350
+ const depsToAudit = await getAddedDependencies()
351
+
352
+ if (depsToAudit.length === 0) {
353
+ console.log(
354
+ '## Dependency Audit Results\n✅ No new dependencies found - no audit needed.'
355
+ )
356
+ return
357
+ }
358
+
359
+ console.log(
360
+ `## Dependency Audit Results\n🔍 Audited ${depsToAudit.length} new ${
361
+ depsToAudit.length === 1 ? 'dependency' : 'dependencies'
362
+ }:\n`
363
+ )
364
+
365
+ for (const dep of depsToAudit) {
366
+ const auditor = new PackageAuditor(dep.name, dep.version)
367
+ await auditor.audit()
368
+ }
369
+ } catch (error) {
370
+ console.error(`❌ Audit failed: ${error}`)
371
+ process.exit(1)
372
+ }
373
+ }
374
+
375
+ // CLI interface
376
+ function showUsage(): void {
377
+ console.error('Usage:')
378
+ console.error(
379
+ ' npx tsx audit-dependencies.ts <package-name> [version] # Audit single package'
380
+ )
381
+ console.error(
382
+ ' npx tsx audit-dependencies.ts # Audit new dependencies in PR'
383
+ )
384
+ console.error('')
385
+ console.error('Examples:')
386
+ console.error(' npx tsx audit-dependencies.ts lodash')
387
+ console.error(' npx tsx audit-dependencies.ts react 18.2.0')
388
+ process.exit(1)
389
+ }
390
+
391
+ async function main(): Promise<void> {
392
+ const args = process.argv.slice(2)
393
+
394
+ if (args.length === 0) {
395
+ // Mode: Audit new dependencies from git diff
396
+ await auditAddedDependencies()
397
+ } else if (args[0] === '--help' || args[0] === '-h') {
398
+ showUsage()
399
+ } else {
400
+ // Mode: Audit single package
401
+ const packageName = args[0]
402
+ const version = args[1] || 'latest'
403
+ const auditor = new PackageAuditor(packageName, version)
404
+ await auditor.audit()
405
+ }
406
+ }
407
+
408
+ // Run main function if this is the main module
409
+ main().catch(error => {
410
+ console.error(`❌ Fatal error: ${error}`)
411
+ process.exit(1)
412
+ })
@@ -1 +0,0 @@
1
- {"version":3,"file":"static/css/main.94b1dbb1.css","mappings":"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","sources":["index.css","App.css","components/CopyUrl.css","components/QRCode.css"],"sourcesContent":[":root {\n /* Light colors */\n --light-backgrounds-regular: #fff;\n --light-backgrounds-secondary: #f4f4ed;\n --light-backgrounds-inverse: #0f1721;\n --light-foregrounds-regular: #0f1721;\n --light-foregrounds-regular-inverse: #fff;\n --light-foregrounds-primary: #5433eb;\n /* Dark colors */\n --dark-background-regular: #0f1721;\n --dark-background-secondary: #3f454d;\n --dark-backgrounds-inverse: #fff;\n --dark-foregrounds-regular: #fff;\n --dark-foregrounds-regular-inverse: #0f1721;\n --dark-foregrounds-primary: #9c83f8;\n}\n@font-face {\n font-family: 'GoodSans';\n src: local('GoodSans'),\n url('https://cdn.shopify.com/static/fonts/GoodSans-Bold.woff2')\n format('woff2');\n font-style: normal;\n font-weight: 700;\n font-display: swap;\n}\n\n@font-face {\n font-family: 'GoodSans';\n src: local('GoodSans'),\n url('https://cdn.shopify.com/static/fonts/GoodSans-Medium.woff2')\n format('woff2');\n font-style: normal;\n font-weight: 500;\n font-display: swap;\n}\n\n@font-face {\n font-family: 'GoodSans';\n src: local('GoodSans'),\n url('https://cdn.shopify.com/static/fonts/GoodSansText-Regular.woff')\n format('woff2');\n font-style: normal;\n font-weight: 400;\n font-display: swap;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml,\nbody {\n margin: 0;\n padding: 0;\n}\n\nhtml {\n font-family: 'GoodSans';\n font-size: 1em;\n}\n\nbody {\n background: var(--light-backgrounds-secondary);\n color: var(--light-foregrounds-regular);\n}\n\na {\n color: var(--light-foregrounds-regular);\n text-decoration: none;\n}\n\nbody::-webkit-scrollbar {\n width: 10px;\n}\n\nbody::-webkit-scrollbar-track {\n background: rgba(0, 0, 0, 0.1);\n}\n\nbody::-webkit-scrollbar-track:hover {\n background: rgba(0, 0, 0, 0.3);\n}\n\nbody::-webkit-scrollbar-thumb {\n background-color: rgba(0, 0, 0, 0.3);\n border-radius: 6px;\n border: 2px solid transparent;\n margin: 2px;\n background-clip: padding-box;\n}\n\nbody::-webkit-scrollbar-thumb:hover {\n background-color: rgba(0, 0, 0, 0.8);\n}\n\nh1 {\n font-size: 1em;\n font-weight: 500;\n}\n",".page {\n max-width: min(30em, 100%);\n display: flex;\n flex-direction: column;\n padding-left: 1em;\n padding-right: 1em;\n margin: auto;\n}\n\n.logo {\n margin-top: 2em;\n align-self: center;\n margin-bottom: 1em;\n}\n\n.link-label {\n margin-bottom: 0.4em;\n}\n\n.link {\n margin-top: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n display: block;\n font-style: normal;\n font-size: 13px;\n line-height: 118%;\n color: var(--light-foregrounds-regular);\n text-decoration: none;\n padding: 1rem 0 1rem 1rem;\n}\n\n.link a,\n.link a:active,\n.link a:visited {\n color: var(--light-foregrounds-primary);\n}\n\n.qr-and-params-container {\n margin-top: 1em;\n margin-bottom: 2em;\n display: flex;\n flex-direction: column;\n gap: 1em;\n word-wrap: break-word;\n align-items: stretch;\n}\n\n.qrcode-container {\n flex: 1;\n width: 100%;\n position: relative;\n}\n\n.params-container {\n flex: 1;\n width: 100%;\n}\n\n.param-row {\n display: flex;\n flex-direction: row;\n}\n\n.param-appendix {\n font-size: 13px;\n}\n\nb.param-appendix {\n font-family: 'Courier New', Courier, monospace;\n}\n\n.cursor-pointer {\n cursor: pointer;\n}\n\n.button {\n background-color: var(--light-backgrounds-inverse);\n color: var(--light-foregrounds-regular-inverse);\n border-radius: 100px;\n padding: 16px;\n min-width: 200px;\n border: none;\n text-decoration: none;\n font-size: 1rem;\n margin-top: 20px;\n}\n\n.button:hover {\n cursor: pointer;\n}\n\n.Main {\n display: flex;\n flex-direction: column;\n gap: 2rem;\n flex: 3;\n}\n\n.rail {\n display: flex;\n flex-direction: row;\n gap: 1rem;\n}\n\n.button-link {\n display: flex;\n flex-direction: row;\n align-items: flex-start;\n background: var(--light-backgrounds-inverse);\n color: var(--light-foregrounds-regular-inverse);\n border-radius: 40px;\n padding: 8px 16px;\n gap: 10px;\n box-sizing: border-box;\n text-decoration: none;\n font-size: 0.8125rem;\n font-family: 'GoodSans', system-ui, -apple-system, BlinkMacSystemFont,\n 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue',\n sans-serif;\n}\n\n.card {\n display: flex;\n flex-direction: column;\n background: var(--light-backgrounds-regular);\n border-radius: 1rem;\n overflow: hidden;\n}\n\n.card h3 {\n margin: 0;\n}\n\n.p-2 {\n padding: 2rem;\n}\n\n.icon-container {\n width: 4rem;\n height: 4rem;\n background-color: #eeeaff;\n border-radius: 0.5rem;\n display: flex;\n justify-content: center;\n align-items: center;\n margin-bottom: 1rem;\n}\n\n.deeplink-content {\n background: var(--light-backgrounds-regular);\n border-radius: 60px;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n margin-top: 1rem;\n position: relative;\n border: 1px solid #cbcbca;\n}\n\n.copy-deeplink {\n background: var(--light-backgrounds-inverse);\n border-radius: 0px 31px 31px 0px;\n padding: 1rem 1.5rem;\n float: left;\n}\n\n.copy-deeplink:hover {\n cursor: pointer;\n}\n\n.w-50 {\n width: 50%;\n}\n\n@media (prefers-color-scheme: dark) {\n body {\n background: var(--dark-background-regular);\n color: var(--dark-foregrounds-regular);\n }\n\n body::-webkit-scrollbar {\n width: 10px;\n }\n\n body::-webkit-scrollbar-track {\n background: rgba(255, 255, 255, 0.1);\n }\n\n body::-webkit-scrollbar-track:hover {\n background: rgba(255, 255, 255, 0.3);\n }\n\n body::-webkit-scrollbar-thumb {\n background-color: rgba(255, 255, 255, 0.3);\n border-radius: 6px;\n border: 2px solid transparent;\n margin: 2px;\n background-clip: padding-box;\n }\n\n body::-webkit-scrollbar-thumb:hover {\n background-color: rgba(255, 255, 255, 0.8);\n }\n\n a {\n color: var(--dark-foregrounds-regular);\n text-decoration: none;\n }\n\n .link {\n color: var(--dark-foregrounds-regular);\n }\n\n .link a,\n .link a:active,\n .link a:visited {\n color: var(--dark-foregrounds-primary);\n }\n\n .button,\n .button-link {\n background-color: var(--dark-backgrounds-inverse) !important;\n color: var(--dark-foregrounds-regular-inverse) !important;\n }\n\n .card {\n background-color: var(--dark-background-secondary);\n }\n\n .deeplink-content {\n background-color: var(--dark-background-secondary);\n border-color: var(--dark-background-secondary);\n color: var(--dark-foregrounds-regular);\n }\n}\n",".icon {\n color: var(--light-foregrounds-regular-inverse);\n display: flex;\n gap: 0.5rem\n}\n\n.icon-checkmark, .icon-copy span {\n font-size: 13px;\n }\n",".qr-code-container {\n margin: auto;\n}\n\n.qr-code {\n display: none;\n height: auto;\n margin: 0 auto;\n max-width: 1000px;\n width: 100%;\n padding: 15px;\n border-radius: 1em;\n background-color: #ffffff;\n}\n\n.qr-code.dark {\n background-color: #3F454D;\n}\n\n@media only screen and (min-width: 800px) {\n .open-mini {\n display: none;\n }\n .qr-code {\n display: flex;\n }\n .container {\n flex: 1;\n }\n}\n"],"names":[],"sourceRoot":""}