create-shopnex 0.0.0-edge.08b1a76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,54 @@
1
+ # create-shopnex
2
+
3
+ Try ShopNex on your machine with one command. It starts the admin (with the API and hosted checkout) and the
4
+ storefront on an embedded database ([PGlite](https://pglite.dev)): no PostgreSQL, no Docker, no clone.
5
+
6
+ ```sh
7
+ npx create-shopnex
8
+ ```
9
+
10
+ The first run downloads ShopNex (one file, about 15 MB) into `~/.shopnex/app/<version>` and checks its SHA-256; later
11
+ runs start straight away. It prints where to open the shop and the admin. Ctrl+C stops everything.
12
+
13
+ ## Options
14
+
15
+ | Option | What it does |
16
+ | ----------------------- | ------------------------------------------------------------------------------------- |
17
+ | `--data <folder>` | Where the database lives. Default `~/.shopnex/data`: the same folder is the same shop |
18
+ | `--port <n>` | Admin, API and checkout. Default `3000` |
19
+ | `--storefront-port <n>` | Storefront. Default `4321` |
20
+ | `--no-open` | Do not open the browser |
21
+ | `--app <name>` | What to start. Only `shop` today; a picker appears once there is more than one |
22
+ | `--verbose` | Show the servers' output while they start (otherwise only if one fails) |
23
+ | `--dry-run` | Show what would run, and exit |
24
+
25
+ To start over, delete the data folder (and the `<data folder>.secret` file next to it).
26
+
27
+ ## Not for production
28
+
29
+ One process owns the data, so nothing else can open the folder, and the servers listen on `127.0.0.1` only. Use
30
+ Docker or PostgreSQL for a real shop. There is no tool yet to move the data from the embedded database to PostgreSQL.
31
+
32
+ ## Where the build comes from
33
+
34
+ Each release attaches `shopnex-v<version>-node.tgz` and its `.sha256` (`scripts/build-node-bundle.mjs`, run by the
35
+ release workflow). It holds the admin (bundled into a few files), the built storefront with its themes and the database
36
+ migrations: JavaScript and WebAssembly, so one file serves every OS and CPU. `create-shopnex` asks for the build of its
37
+ own version, so a version without a release says so. The checksum comes from the same place as the file: it catches a
38
+ damaged download, not a tampered release.
39
+
40
+ `SHOPNEX_SECRET` is generated once and kept in `<data folder>.secret` (readable by you only), so the same shop keeps its
41
+ sessions and stored keys. `SHOPNEX_BUNDLE_URL` downloads from somewhere else (a mirror; the `.sha256` sits next to it)
42
+ and `SHOPNEX_APP_DIR` changes where builds are unpacked.
43
+
44
+ **Edge:** `npx create-shopnex@edge` runs the latest build of `main` (`.github/workflows/edge.yaml` replaces the file of
45
+ the `edge` pre-release on every push). It downloads again only when `main` moved. It can be broken: use a release for
46
+ anything you want to keep.
47
+
48
+ ## Development
49
+
50
+ ```sh
51
+ pnpm --filter create-shopnex dev # runs src/main.ts (needs a release of this version, or SHOPNEX_BUNDLE_URL)
52
+ pnpm --filter create-shopnex test
53
+ pnpm build && pnpm --dir templates/storefront build && node scripts/build-node-bundle.mjs 0.14.0 /tmp/bundle
54
+ ```
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ // The compiled CLI (pnpm --filter create-shopnex build; it is built before the package is packed). From a checkout,
3
+ // `pnpm --filter create-shopnex dev -- <options>` runs the TypeScript directly.
4
+ try {
5
+ await import('../dist/main.mjs')
6
+ } catch (error) {
7
+ if (error?.code !== 'ERR_MODULE_NOT_FOUND' || !String(error.message).includes('dist/main.mjs')) throw error
8
+ console.error('create-shopnex is not built. Run: pnpm --filter create-shopnex build')
9
+ process.exitCode = 1
10
+ }
package/dist/main.mjs ADDED
@@ -0,0 +1,1177 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __esm = (fn, res, err) => function __init() {
8
+ if (err) throw err[0];
9
+ try {
10
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
11
+ } catch (e2) {
12
+ throw err = [e2], e2;
13
+ }
14
+ };
15
+ var __commonJS = (cb, mod) => function __require() {
16
+ try {
17
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
18
+ } catch (e2) {
19
+ throw mod = 0, e2;
20
+ }
21
+ };
22
+ var __copyProps = (to, from, except, desc) => {
23
+ if (from && typeof from === "object" || typeof from === "function") {
24
+ for (let key of __getOwnPropNames(from))
25
+ if (!__hasOwnProp.call(to, key) && key !== except)
26
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
27
+ }
28
+ return to;
29
+ };
30
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
31
+ // If the importer is in node compatibility mode or this is not an ESM
32
+ // file that has been converted to a CommonJS file using a Babel-
33
+ // compatible transform (i.e. "__esModule" has not been set), then set
34
+ // "default" to the CommonJS "module.exports" for node compatibility.
35
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
36
+ mod
37
+ ));
38
+
39
+ // <define:__PKG__>
40
+ var define_PKG_default;
41
+ var init_define_PKG = __esm({
42
+ "<define:__PKG__>"() {
43
+ define_PKG_default = { version: "0.0.0-edge.08b1a76", engines: { node: ">=22.22.0" } };
44
+ }
45
+ });
46
+
47
+ // ../../node_modules/.pnpm/sisteransi@1.0.5/node_modules/sisteransi/src/index.js
48
+ var require_src = __commonJS({
49
+ "../../node_modules/.pnpm/sisteransi@1.0.5/node_modules/sisteransi/src/index.js"(exports, module) {
50
+ "use strict";
51
+ init_define_PKG();
52
+ var ESC = "\x1B";
53
+ var CSI = `${ESC}[`;
54
+ var beep = "\x07";
55
+ var cursor = {
56
+ to(x3, y3) {
57
+ if (!y3) return `${CSI}${x3 + 1}G`;
58
+ return `${CSI}${y3 + 1};${x3 + 1}H`;
59
+ },
60
+ move(x3, y3) {
61
+ let ret = "";
62
+ if (x3 < 0) ret += `${CSI}${-x3}D`;
63
+ else if (x3 > 0) ret += `${CSI}${x3}C`;
64
+ if (y3 < 0) ret += `${CSI}${-y3}A`;
65
+ else if (y3 > 0) ret += `${CSI}${y3}B`;
66
+ return ret;
67
+ },
68
+ up: (count = 1) => `${CSI}${count}A`,
69
+ down: (count = 1) => `${CSI}${count}B`,
70
+ forward: (count = 1) => `${CSI}${count}C`,
71
+ backward: (count = 1) => `${CSI}${count}D`,
72
+ nextLine: (count = 1) => `${CSI}E`.repeat(count),
73
+ prevLine: (count = 1) => `${CSI}F`.repeat(count),
74
+ left: `${CSI}G`,
75
+ hide: `${CSI}?25l`,
76
+ show: `${CSI}?25h`,
77
+ save: `${ESC}7`,
78
+ restore: `${ESC}8`
79
+ };
80
+ var scroll = {
81
+ up: (count = 1) => `${CSI}S`.repeat(count),
82
+ down: (count = 1) => `${CSI}T`.repeat(count)
83
+ };
84
+ var erase = {
85
+ screen: `${CSI}2J`,
86
+ up: (count = 1) => `${CSI}1J`.repeat(count),
87
+ down: (count = 1) => `${CSI}J`.repeat(count),
88
+ line: `${CSI}2K`,
89
+ lineEnd: `${CSI}K`,
90
+ lineStart: `${CSI}1K`,
91
+ lines(count) {
92
+ let clear = "";
93
+ for (let i = 0; i < count; i++)
94
+ clear += this.line + (i < count - 1 ? cursor.up() : "");
95
+ if (count)
96
+ clear += cursor.left;
97
+ return clear;
98
+ }
99
+ };
100
+ module.exports = { cursor, scroll, erase, beep };
101
+ }
102
+ });
103
+
104
+ // ../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js
105
+ var require_picocolors = __commonJS({
106
+ "../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js"(exports, module) {
107
+ init_define_PKG();
108
+ var p = process || {};
109
+ var argv = p.argv || [];
110
+ var env = p.env || {};
111
+ var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
112
+ var formatter = (open, close, replace = open) => (input) => {
113
+ let string = "" + input, index = string.indexOf(close, open.length);
114
+ return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
115
+ };
116
+ var replaceClose = (string, close, replace, index) => {
117
+ let result = "", cursor = 0;
118
+ do {
119
+ result += string.substring(cursor, index) + replace;
120
+ cursor = index + close.length;
121
+ index = string.indexOf(close, cursor);
122
+ } while (~index);
123
+ return result + string.substring(cursor);
124
+ };
125
+ var createColors = (enabled = isColorSupported) => {
126
+ let f3 = enabled ? formatter : () => String;
127
+ return {
128
+ isColorSupported: enabled,
129
+ reset: f3("\x1B[0m", "\x1B[0m"),
130
+ bold: f3("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
131
+ dim: f3("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
132
+ italic: f3("\x1B[3m", "\x1B[23m"),
133
+ underline: f3("\x1B[4m", "\x1B[24m"),
134
+ inverse: f3("\x1B[7m", "\x1B[27m"),
135
+ hidden: f3("\x1B[8m", "\x1B[28m"),
136
+ strikethrough: f3("\x1B[9m", "\x1B[29m"),
137
+ black: f3("\x1B[30m", "\x1B[39m"),
138
+ red: f3("\x1B[31m", "\x1B[39m"),
139
+ green: f3("\x1B[32m", "\x1B[39m"),
140
+ yellow: f3("\x1B[33m", "\x1B[39m"),
141
+ blue: f3("\x1B[34m", "\x1B[39m"),
142
+ magenta: f3("\x1B[35m", "\x1B[39m"),
143
+ cyan: f3("\x1B[36m", "\x1B[39m"),
144
+ white: f3("\x1B[37m", "\x1B[39m"),
145
+ gray: f3("\x1B[90m", "\x1B[39m"),
146
+ bgBlack: f3("\x1B[40m", "\x1B[49m"),
147
+ bgRed: f3("\x1B[41m", "\x1B[49m"),
148
+ bgGreen: f3("\x1B[42m", "\x1B[49m"),
149
+ bgYellow: f3("\x1B[43m", "\x1B[49m"),
150
+ bgBlue: f3("\x1B[44m", "\x1B[49m"),
151
+ bgMagenta: f3("\x1B[45m", "\x1B[49m"),
152
+ bgCyan: f3("\x1B[46m", "\x1B[49m"),
153
+ bgWhite: f3("\x1B[47m", "\x1B[49m"),
154
+ blackBright: f3("\x1B[90m", "\x1B[39m"),
155
+ redBright: f3("\x1B[91m", "\x1B[39m"),
156
+ greenBright: f3("\x1B[92m", "\x1B[39m"),
157
+ yellowBright: f3("\x1B[93m", "\x1B[39m"),
158
+ blueBright: f3("\x1B[94m", "\x1B[39m"),
159
+ magentaBright: f3("\x1B[95m", "\x1B[39m"),
160
+ cyanBright: f3("\x1B[96m", "\x1B[39m"),
161
+ whiteBright: f3("\x1B[97m", "\x1B[39m"),
162
+ bgBlackBright: f3("\x1B[100m", "\x1B[49m"),
163
+ bgRedBright: f3("\x1B[101m", "\x1B[49m"),
164
+ bgGreenBright: f3("\x1B[102m", "\x1B[49m"),
165
+ bgYellowBright: f3("\x1B[103m", "\x1B[49m"),
166
+ bgBlueBright: f3("\x1B[104m", "\x1B[49m"),
167
+ bgMagentaBright: f3("\x1B[105m", "\x1B[49m"),
168
+ bgCyanBright: f3("\x1B[106m", "\x1B[49m"),
169
+ bgWhiteBright: f3("\x1B[107m", "\x1B[49m")
170
+ };
171
+ };
172
+ module.exports = createColors();
173
+ module.exports.createColors = createColors;
174
+ }
175
+ });
176
+
177
+ // src/main.ts
178
+ init_define_PKG();
179
+
180
+ // src/cli.ts
181
+ init_define_PKG();
182
+ import { readFileSync as readFileSync3 } from "node:fs";
183
+
184
+ // ../../node_modules/.pnpm/@clack+prompts@0.7.0/node_modules/@clack/prompts/dist/index.mjs
185
+ init_define_PKG();
186
+
187
+ // ../../node_modules/.pnpm/@clack+core@0.3.5/node_modules/@clack/core/dist/index.mjs
188
+ init_define_PKG();
189
+ var import_sisteransi = __toESM(require_src(), 1);
190
+ import { stdin as $, stdout as k } from "node:process";
191
+ import * as f from "node:readline";
192
+ import _ from "node:readline";
193
+ import { WriteStream as U } from "node:tty";
194
+ function q({ onlyFirst: e2 = false } = {}) {
195
+ const F = ["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|");
196
+ return new RegExp(F, e2 ? void 0 : "g");
197
+ }
198
+ var J = q();
199
+ function S(e2) {
200
+ if (typeof e2 != "string") throw new TypeError(`Expected a \`string\`, got \`${typeof e2}\``);
201
+ return e2.replace(J, "");
202
+ }
203
+ function T(e2) {
204
+ return e2 && e2.__esModule && Object.prototype.hasOwnProperty.call(e2, "default") ? e2.default : e2;
205
+ }
206
+ var j = { exports: {} };
207
+ (function(e2) {
208
+ var u = {};
209
+ e2.exports = u, u.eastAsianWidth = function(t) {
210
+ var s = t.charCodeAt(0), C2 = t.length == 2 ? t.charCodeAt(1) : 0, D = s;
211
+ return 55296 <= s && s <= 56319 && 56320 <= C2 && C2 <= 57343 && (s &= 1023, C2 &= 1023, D = s << 10 | C2, D += 65536), D == 12288 || 65281 <= D && D <= 65376 || 65504 <= D && D <= 65510 ? "F" : D == 8361 || 65377 <= D && D <= 65470 || 65474 <= D && D <= 65479 || 65482 <= D && D <= 65487 || 65490 <= D && D <= 65495 || 65498 <= D && D <= 65500 || 65512 <= D && D <= 65518 ? "H" : 4352 <= D && D <= 4447 || 4515 <= D && D <= 4519 || 4602 <= D && D <= 4607 || 9001 <= D && D <= 9002 || 11904 <= D && D <= 11929 || 11931 <= D && D <= 12019 || 12032 <= D && D <= 12245 || 12272 <= D && D <= 12283 || 12289 <= D && D <= 12350 || 12353 <= D && D <= 12438 || 12441 <= D && D <= 12543 || 12549 <= D && D <= 12589 || 12593 <= D && D <= 12686 || 12688 <= D && D <= 12730 || 12736 <= D && D <= 12771 || 12784 <= D && D <= 12830 || 12832 <= D && D <= 12871 || 12880 <= D && D <= 13054 || 13056 <= D && D <= 19903 || 19968 <= D && D <= 42124 || 42128 <= D && D <= 42182 || 43360 <= D && D <= 43388 || 44032 <= D && D <= 55203 || 55216 <= D && D <= 55238 || 55243 <= D && D <= 55291 || 63744 <= D && D <= 64255 || 65040 <= D && D <= 65049 || 65072 <= D && D <= 65106 || 65108 <= D && D <= 65126 || 65128 <= D && D <= 65131 || 110592 <= D && D <= 110593 || 127488 <= D && D <= 127490 || 127504 <= D && D <= 127546 || 127552 <= D && D <= 127560 || 127568 <= D && D <= 127569 || 131072 <= D && D <= 194367 || 177984 <= D && D <= 196605 || 196608 <= D && D <= 262141 ? "W" : 32 <= D && D <= 126 || 162 <= D && D <= 163 || 165 <= D && D <= 166 || D == 172 || D == 175 || 10214 <= D && D <= 10221 || 10629 <= D && D <= 10630 ? "Na" : D == 161 || D == 164 || 167 <= D && D <= 168 || D == 170 || 173 <= D && D <= 174 || 176 <= D && D <= 180 || 182 <= D && D <= 186 || 188 <= D && D <= 191 || D == 198 || D == 208 || 215 <= D && D <= 216 || 222 <= D && D <= 225 || D == 230 || 232 <= D && D <= 234 || 236 <= D && D <= 237 || D == 240 || 242 <= D && D <= 243 || 247 <= D && D <= 250 || D == 252 || D == 254 || D == 257 || D == 273 || D == 275 || D == 283 || 294 <= D && D <= 295 || D == 299 || 305 <= D && D <= 307 || D == 312 || 319 <= D && D <= 322 || D == 324 || 328 <= D && D <= 331 || D == 333 || 338 <= D && D <= 339 || 358 <= D && D <= 359 || D == 363 || D == 462 || D == 464 || D == 466 || D == 468 || D == 470 || D == 472 || D == 474 || D == 476 || D == 593 || D == 609 || D == 708 || D == 711 || 713 <= D && D <= 715 || D == 717 || D == 720 || 728 <= D && D <= 731 || D == 733 || D == 735 || 768 <= D && D <= 879 || 913 <= D && D <= 929 || 931 <= D && D <= 937 || 945 <= D && D <= 961 || 963 <= D && D <= 969 || D == 1025 || 1040 <= D && D <= 1103 || D == 1105 || D == 8208 || 8211 <= D && D <= 8214 || 8216 <= D && D <= 8217 || 8220 <= D && D <= 8221 || 8224 <= D && D <= 8226 || 8228 <= D && D <= 8231 || D == 8240 || 8242 <= D && D <= 8243 || D == 8245 || D == 8251 || D == 8254 || D == 8308 || D == 8319 || 8321 <= D && D <= 8324 || D == 8364 || D == 8451 || D == 8453 || D == 8457 || D == 8467 || D == 8470 || 8481 <= D && D <= 8482 || D == 8486 || D == 8491 || 8531 <= D && D <= 8532 || 8539 <= D && D <= 8542 || 8544 <= D && D <= 8555 || 8560 <= D && D <= 8569 || D == 8585 || 8592 <= D && D <= 8601 || 8632 <= D && D <= 8633 || D == 8658 || D == 8660 || D == 8679 || D == 8704 || 8706 <= D && D <= 8707 || 8711 <= D && D <= 8712 || D == 8715 || D == 8719 || D == 8721 || D == 8725 || D == 8730 || 8733 <= D && D <= 8736 || D == 8739 || D == 8741 || 8743 <= D && D <= 8748 || D == 8750 || 8756 <= D && D <= 8759 || 8764 <= D && D <= 8765 || D == 8776 || D == 8780 || D == 8786 || 8800 <= D && D <= 8801 || 8804 <= D && D <= 8807 || 8810 <= D && D <= 8811 || 8814 <= D && D <= 8815 || 8834 <= D && D <= 8835 || 8838 <= D && D <= 8839 || D == 8853 || D == 8857 || D == 8869 || D == 8895 || D == 8978 || 9312 <= D && D <= 9449 || 9451 <= D && D <= 9547 || 9552 <= D && D <= 9587 || 9600 <= D && D <= 9615 || 9618 <= D && D <= 9621 || 9632 <= D && D <= 9633 || 9635 <= D && D <= 9641 || 9650 <= D && D <= 9651 || 9654 <= D && D <= 9655 || 9660 <= D && D <= 9661 || 9664 <= D && D <= 9665 || 9670 <= D && D <= 9672 || D == 9675 || 9678 <= D && D <= 9681 || 9698 <= D && D <= 9701 || D == 9711 || 9733 <= D && D <= 9734 || D == 9737 || 9742 <= D && D <= 9743 || 9748 <= D && D <= 9749 || D == 9756 || D == 9758 || D == 9792 || D == 9794 || 9824 <= D && D <= 9825 || 9827 <= D && D <= 9829 || 9831 <= D && D <= 9834 || 9836 <= D && D <= 9837 || D == 9839 || 9886 <= D && D <= 9887 || 9918 <= D && D <= 9919 || 9924 <= D && D <= 9933 || 9935 <= D && D <= 9953 || D == 9955 || 9960 <= D && D <= 9983 || D == 10045 || D == 10071 || 10102 <= D && D <= 10111 || 11093 <= D && D <= 11097 || 12872 <= D && D <= 12879 || 57344 <= D && D <= 63743 || 65024 <= D && D <= 65039 || D == 65533 || 127232 <= D && D <= 127242 || 127248 <= D && D <= 127277 || 127280 <= D && D <= 127337 || 127344 <= D && D <= 127386 || 917760 <= D && D <= 917999 || 983040 <= D && D <= 1048573 || 1048576 <= D && D <= 1114109 ? "A" : "N";
212
+ }, u.characterLength = function(t) {
213
+ var s = this.eastAsianWidth(t);
214
+ return s == "F" || s == "W" || s == "A" ? 2 : 1;
215
+ };
216
+ function F(t) {
217
+ return t.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g) || [];
218
+ }
219
+ u.length = function(t) {
220
+ for (var s = F(t), C2 = 0, D = 0; D < s.length; D++) C2 = C2 + this.characterLength(s[D]);
221
+ return C2;
222
+ }, u.slice = function(t, s, C2) {
223
+ textLen = u.length(t), s = s || 0, C2 = C2 || 1, s < 0 && (s = textLen + s), C2 < 0 && (C2 = textLen + C2);
224
+ for (var D = "", i = 0, n = F(t), E2 = 0; E2 < n.length; E2++) {
225
+ var h2 = n[E2], o2 = u.length(h2);
226
+ if (i >= s - (o2 == 2 ? 1 : 0)) if (i + o2 <= C2) D += h2;
227
+ else break;
228
+ i += o2;
229
+ }
230
+ return D;
231
+ };
232
+ })(j);
233
+ var Q = j.exports;
234
+ var X = T(Q);
235
+ var DD = function() {
236
+ return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g;
237
+ };
238
+ var uD = T(DD);
239
+ function A(e2, u = {}) {
240
+ if (typeof e2 != "string" || e2.length === 0 || (u = { ambiguousIsNarrow: true, ...u }, e2 = S(e2), e2.length === 0)) return 0;
241
+ e2 = e2.replace(uD(), " ");
242
+ const F = u.ambiguousIsNarrow ? 1 : 2;
243
+ let t = 0;
244
+ for (const s of e2) {
245
+ const C2 = s.codePointAt(0);
246
+ if (C2 <= 31 || C2 >= 127 && C2 <= 159 || C2 >= 768 && C2 <= 879) continue;
247
+ switch (X.eastAsianWidth(s)) {
248
+ case "F":
249
+ case "W":
250
+ t += 2;
251
+ break;
252
+ case "A":
253
+ t += F;
254
+ break;
255
+ default:
256
+ t += 1;
257
+ }
258
+ }
259
+ return t;
260
+ }
261
+ var d = 10;
262
+ var M = (e2 = 0) => (u) => `\x1B[${u + e2}m`;
263
+ var P = (e2 = 0) => (u) => `\x1B[${38 + e2};5;${u}m`;
264
+ var W = (e2 = 0) => (u, F, t) => `\x1B[${38 + e2};2;${u};${F};${t}m`;
265
+ var r = { modifier: { reset: [0, 0], bold: [1, 22], dim: [2, 22], italic: [3, 23], underline: [4, 24], overline: [53, 55], inverse: [7, 27], hidden: [8, 28], strikethrough: [9, 29] }, color: { black: [30, 39], red: [31, 39], green: [32, 39], yellow: [33, 39], blue: [34, 39], magenta: [35, 39], cyan: [36, 39], white: [37, 39], blackBright: [90, 39], gray: [90, 39], grey: [90, 39], redBright: [91, 39], greenBright: [92, 39], yellowBright: [93, 39], blueBright: [94, 39], magentaBright: [95, 39], cyanBright: [96, 39], whiteBright: [97, 39] }, bgColor: { bgBlack: [40, 49], bgRed: [41, 49], bgGreen: [42, 49], bgYellow: [43, 49], bgBlue: [44, 49], bgMagenta: [45, 49], bgCyan: [46, 49], bgWhite: [47, 49], bgBlackBright: [100, 49], bgGray: [100, 49], bgGrey: [100, 49], bgRedBright: [101, 49], bgGreenBright: [102, 49], bgYellowBright: [103, 49], bgBlueBright: [104, 49], bgMagentaBright: [105, 49], bgCyanBright: [106, 49], bgWhiteBright: [107, 49] } };
266
+ Object.keys(r.modifier);
267
+ var FD = Object.keys(r.color);
268
+ var eD = Object.keys(r.bgColor);
269
+ [...FD, ...eD];
270
+ function tD() {
271
+ const e2 = /* @__PURE__ */ new Map();
272
+ for (const [u, F] of Object.entries(r)) {
273
+ for (const [t, s] of Object.entries(F)) r[t] = { open: `\x1B[${s[0]}m`, close: `\x1B[${s[1]}m` }, F[t] = r[t], e2.set(s[0], s[1]);
274
+ Object.defineProperty(r, u, { value: F, enumerable: false });
275
+ }
276
+ return Object.defineProperty(r, "codes", { value: e2, enumerable: false }), r.color.close = "\x1B[39m", r.bgColor.close = "\x1B[49m", r.color.ansi = M(), r.color.ansi256 = P(), r.color.ansi16m = W(), r.bgColor.ansi = M(d), r.bgColor.ansi256 = P(d), r.bgColor.ansi16m = W(d), Object.defineProperties(r, { rgbToAnsi256: { value: (u, F, t) => u === F && F === t ? u < 8 ? 16 : u > 248 ? 231 : Math.round((u - 8) / 247 * 24) + 232 : 16 + 36 * Math.round(u / 255 * 5) + 6 * Math.round(F / 255 * 5) + Math.round(t / 255 * 5), enumerable: false }, hexToRgb: { value: (u) => {
277
+ const F = /[a-f\d]{6}|[a-f\d]{3}/i.exec(u.toString(16));
278
+ if (!F) return [0, 0, 0];
279
+ let [t] = F;
280
+ t.length === 3 && (t = [...t].map((C2) => C2 + C2).join(""));
281
+ const s = Number.parseInt(t, 16);
282
+ return [s >> 16 & 255, s >> 8 & 255, s & 255];
283
+ }, enumerable: false }, hexToAnsi256: { value: (u) => r.rgbToAnsi256(...r.hexToRgb(u)), enumerable: false }, ansi256ToAnsi: { value: (u) => {
284
+ if (u < 8) return 30 + u;
285
+ if (u < 16) return 90 + (u - 8);
286
+ let F, t, s;
287
+ if (u >= 232) F = ((u - 232) * 10 + 8) / 255, t = F, s = F;
288
+ else {
289
+ u -= 16;
290
+ const i = u % 36;
291
+ F = Math.floor(u / 36) / 5, t = Math.floor(i / 6) / 5, s = i % 6 / 5;
292
+ }
293
+ const C2 = Math.max(F, t, s) * 2;
294
+ if (C2 === 0) return 30;
295
+ let D = 30 + (Math.round(s) << 2 | Math.round(t) << 1 | Math.round(F));
296
+ return C2 === 2 && (D += 60), D;
297
+ }, enumerable: false }, rgbToAnsi: { value: (u, F, t) => r.ansi256ToAnsi(r.rgbToAnsi256(u, F, t)), enumerable: false }, hexToAnsi: { value: (u) => r.ansi256ToAnsi(r.hexToAnsi256(u)), enumerable: false } }), r;
298
+ }
299
+ var sD = tD();
300
+ var g = /* @__PURE__ */ new Set(["\x1B", "\x9B"]);
301
+ var CD = 39;
302
+ var b = "\x07";
303
+ var O = "[";
304
+ var iD = "]";
305
+ var I = "m";
306
+ var w = `${iD}8;;`;
307
+ var N = (e2) => `${g.values().next().value}${O}${e2}${I}`;
308
+ var L = (e2) => `${g.values().next().value}${w}${e2}${b}`;
309
+ var rD = (e2) => e2.split(" ").map((u) => A(u));
310
+ var y = (e2, u, F) => {
311
+ const t = [...u];
312
+ let s = false, C2 = false, D = A(S(e2[e2.length - 1]));
313
+ for (const [i, n] of t.entries()) {
314
+ const E2 = A(n);
315
+ if (D + E2 <= F ? e2[e2.length - 1] += n : (e2.push(n), D = 0), g.has(n) && (s = true, C2 = t.slice(i + 1).join("").startsWith(w)), s) {
316
+ C2 ? n === b && (s = false, C2 = false) : n === I && (s = false);
317
+ continue;
318
+ }
319
+ D += E2, D === F && i < t.length - 1 && (e2.push(""), D = 0);
320
+ }
321
+ !D && e2[e2.length - 1].length > 0 && e2.length > 1 && (e2[e2.length - 2] += e2.pop());
322
+ };
323
+ var ED = (e2) => {
324
+ const u = e2.split(" ");
325
+ let F = u.length;
326
+ for (; F > 0 && !(A(u[F - 1]) > 0); ) F--;
327
+ return F === u.length ? e2 : u.slice(0, F).join(" ") + u.slice(F).join("");
328
+ };
329
+ var oD = (e2, u, F = {}) => {
330
+ if (F.trim !== false && e2.trim() === "") return "";
331
+ let t = "", s, C2;
332
+ const D = rD(e2);
333
+ let i = [""];
334
+ for (const [E2, h2] of e2.split(" ").entries()) {
335
+ F.trim !== false && (i[i.length - 1] = i[i.length - 1].trimStart());
336
+ let o2 = A(i[i.length - 1]);
337
+ if (E2 !== 0 && (o2 >= u && (F.wordWrap === false || F.trim === false) && (i.push(""), o2 = 0), (o2 > 0 || F.trim === false) && (i[i.length - 1] += " ", o2++)), F.hard && D[E2] > u) {
338
+ const B2 = u - o2, p = 1 + Math.floor((D[E2] - B2 - 1) / u);
339
+ Math.floor((D[E2] - 1) / u) < p && i.push(""), y(i, h2, u);
340
+ continue;
341
+ }
342
+ if (o2 + D[E2] > u && o2 > 0 && D[E2] > 0) {
343
+ if (F.wordWrap === false && o2 < u) {
344
+ y(i, h2, u);
345
+ continue;
346
+ }
347
+ i.push("");
348
+ }
349
+ if (o2 + D[E2] > u && F.wordWrap === false) {
350
+ y(i, h2, u);
351
+ continue;
352
+ }
353
+ i[i.length - 1] += h2;
354
+ }
355
+ F.trim !== false && (i = i.map((E2) => ED(E2)));
356
+ const n = [...i.join(`
357
+ `)];
358
+ for (const [E2, h2] of n.entries()) {
359
+ if (t += h2, g.has(h2)) {
360
+ const { groups: B2 } = new RegExp(`(?:\\${O}(?<code>\\d+)m|\\${w}(?<uri>.*)${b})`).exec(n.slice(E2).join("")) || { groups: {} };
361
+ if (B2.code !== void 0) {
362
+ const p = Number.parseFloat(B2.code);
363
+ s = p === CD ? void 0 : p;
364
+ } else B2.uri !== void 0 && (C2 = B2.uri.length === 0 ? void 0 : B2.uri);
365
+ }
366
+ const o2 = sD.codes.get(Number(s));
367
+ n[E2 + 1] === `
368
+ ` ? (C2 && (t += L("")), s && o2 && (t += N(o2))) : h2 === `
369
+ ` && (s && o2 && (t += N(s)), C2 && (t += L(C2)));
370
+ }
371
+ return t;
372
+ };
373
+ function R(e2, u, F) {
374
+ return String(e2).normalize().replace(/\r\n/g, `
375
+ `).split(`
376
+ `).map((t) => oD(t, u, F)).join(`
377
+ `);
378
+ }
379
+ var nD = Object.defineProperty;
380
+ var aD = (e2, u, F) => u in e2 ? nD(e2, u, { enumerable: true, configurable: true, writable: true, value: F }) : e2[u] = F;
381
+ var a = (e2, u, F) => (aD(e2, typeof u != "symbol" ? u + "" : u, F), F);
382
+ function hD(e2, u) {
383
+ if (e2 === u) return;
384
+ const F = e2.split(`
385
+ `), t = u.split(`
386
+ `), s = [];
387
+ for (let C2 = 0; C2 < Math.max(F.length, t.length); C2++) F[C2] !== t[C2] && s.push(C2);
388
+ return s;
389
+ }
390
+ var V = /* @__PURE__ */ Symbol("clack:cancel");
391
+ function lD(e2) {
392
+ return e2 === V;
393
+ }
394
+ function v(e2, u) {
395
+ e2.isTTY && e2.setRawMode(u);
396
+ }
397
+ var z = /* @__PURE__ */ new Map([["k", "up"], ["j", "down"], ["h", "left"], ["l", "right"]]);
398
+ var xD = /* @__PURE__ */ new Set(["up", "down", "left", "right", "space", "enter"]);
399
+ var x = class {
400
+ constructor({ render: u, input: F = $, output: t = k, ...s }, C2 = true) {
401
+ a(this, "input"), a(this, "output"), a(this, "rl"), a(this, "opts"), a(this, "_track", false), a(this, "_render"), a(this, "_cursor", 0), a(this, "state", "initial"), a(this, "value"), a(this, "error", ""), a(this, "subscribers", /* @__PURE__ */ new Map()), a(this, "_prevFrame", ""), this.opts = s, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = u.bind(this), this._track = C2, this.input = F, this.output = t;
402
+ }
403
+ prompt() {
404
+ const u = new U(0);
405
+ return u._write = (F, t, s) => {
406
+ this._track && (this.value = this.rl.line.replace(/\t/g, ""), this._cursor = this.rl.cursor, this.emit("value", this.value)), s();
407
+ }, this.input.pipe(u), this.rl = _.createInterface({ input: this.input, output: u, tabSize: 2, prompt: "", escapeCodeTimeout: 50 }), _.emitKeypressEvents(this.input, this.rl), this.rl.prompt(), this.opts.initialValue !== void 0 && this._track && this.rl.write(this.opts.initialValue), this.input.on("keypress", this.onKeypress), v(this.input, true), this.output.on("resize", this.render), this.render(), new Promise((F, t) => {
408
+ this.once("submit", () => {
409
+ this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), v(this.input, false), F(this.value);
410
+ }), this.once("cancel", () => {
411
+ this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), v(this.input, false), F(V);
412
+ });
413
+ });
414
+ }
415
+ on(u, F) {
416
+ const t = this.subscribers.get(u) ?? [];
417
+ t.push({ cb: F }), this.subscribers.set(u, t);
418
+ }
419
+ once(u, F) {
420
+ const t = this.subscribers.get(u) ?? [];
421
+ t.push({ cb: F, once: true }), this.subscribers.set(u, t);
422
+ }
423
+ emit(u, ...F) {
424
+ const t = this.subscribers.get(u) ?? [], s = [];
425
+ for (const C2 of t) C2.cb(...F), C2.once && s.push(() => t.splice(t.indexOf(C2), 1));
426
+ for (const C2 of s) C2();
427
+ }
428
+ unsubscribe() {
429
+ this.subscribers.clear();
430
+ }
431
+ onKeypress(u, F) {
432
+ if (this.state === "error" && (this.state = "active"), F?.name && !this._track && z.has(F.name) && this.emit("cursor", z.get(F.name)), F?.name && xD.has(F.name) && this.emit("cursor", F.name), u && (u.toLowerCase() === "y" || u.toLowerCase() === "n") && this.emit("confirm", u.toLowerCase() === "y"), u === " " && this.opts.placeholder && (this.value || (this.rl.write(this.opts.placeholder), this.emit("value", this.opts.placeholder))), u && this.emit("key", u.toLowerCase()), F?.name === "return") {
433
+ if (this.opts.validate) {
434
+ const t = this.opts.validate(this.value);
435
+ t && (this.error = t, this.state = "error", this.rl.write(this.value));
436
+ }
437
+ this.state !== "error" && (this.state = "submit");
438
+ }
439
+ u === "" && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
440
+ }
441
+ close() {
442
+ this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
443
+ `), v(this.input, false), this.rl.close(), this.emit(`${this.state}`, this.value), this.unsubscribe();
444
+ }
445
+ restoreCursor() {
446
+ const u = R(this._prevFrame, process.stdout.columns, { hard: true }).split(`
447
+ `).length - 1;
448
+ this.output.write(import_sisteransi.cursor.move(-999, u * -1));
449
+ }
450
+ render() {
451
+ const u = R(this._render(this) ?? "", process.stdout.columns, { hard: true });
452
+ if (u !== this._prevFrame) {
453
+ if (this.state === "initial") this.output.write(import_sisteransi.cursor.hide);
454
+ else {
455
+ const F = hD(this._prevFrame, u);
456
+ if (this.restoreCursor(), F && F?.length === 1) {
457
+ const t = F[0];
458
+ this.output.write(import_sisteransi.cursor.move(0, t)), this.output.write(import_sisteransi.erase.lines(1));
459
+ const s = u.split(`
460
+ `);
461
+ this.output.write(s[t]), this._prevFrame = u, this.output.write(import_sisteransi.cursor.move(0, s.length - t - 1));
462
+ return;
463
+ } else if (F && F?.length > 1) {
464
+ const t = F[0];
465
+ this.output.write(import_sisteransi.cursor.move(0, t)), this.output.write(import_sisteransi.erase.down());
466
+ const s = u.split(`
467
+ `).slice(t);
468
+ this.output.write(s.join(`
469
+ `)), this._prevFrame = u;
470
+ return;
471
+ }
472
+ this.output.write(import_sisteransi.erase.down());
473
+ }
474
+ this.output.write(u), this.state === "initial" && (this.state = "active"), this._prevFrame = u;
475
+ }
476
+ }
477
+ };
478
+ var wD = Object.defineProperty;
479
+ var yD = (e2, u, F) => u in e2 ? wD(e2, u, { enumerable: true, configurable: true, writable: true, value: F }) : e2[u] = F;
480
+ var Z = (e2, u, F) => (yD(e2, typeof u != "symbol" ? u + "" : u, F), F);
481
+ var $D = class extends x {
482
+ constructor(u) {
483
+ super(u, false), Z(this, "options"), Z(this, "cursor", 0), this.options = u.options, this.cursor = this.options.findIndex(({ value: F }) => F === u.initialValue), this.cursor === -1 && (this.cursor = 0), this.changeValue(), this.on("cursor", (F) => {
484
+ switch (F) {
485
+ case "left":
486
+ case "up":
487
+ this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
488
+ break;
489
+ case "down":
490
+ case "right":
491
+ this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
492
+ break;
493
+ }
494
+ this.changeValue();
495
+ });
496
+ }
497
+ get _value() {
498
+ return this.options[this.cursor];
499
+ }
500
+ changeValue() {
501
+ this.value = this._value.value;
502
+ }
503
+ };
504
+ var WD = globalThis.process.platform.startsWith("win");
505
+ function OD({ input: e2 = $, output: u = k, overwrite: F = true, hideCursor: t = true } = {}) {
506
+ const s = f.createInterface({ input: e2, output: u, prompt: "", tabSize: 1 });
507
+ f.emitKeypressEvents(e2, s), e2.isTTY && e2.setRawMode(true);
508
+ const C2 = (D, { name: i }) => {
509
+ if (String(D) === "") {
510
+ t && u.write(import_sisteransi.cursor.show), process.exit(0);
511
+ return;
512
+ }
513
+ if (!F) return;
514
+ let n = i === "return" ? 0 : -1, E2 = i === "return" ? -1 : 0;
515
+ f.moveCursor(u, n, E2, () => {
516
+ f.clearLine(u, 1, () => {
517
+ e2.once("keypress", C2);
518
+ });
519
+ });
520
+ };
521
+ return t && u.write(import_sisteransi.cursor.hide), e2.once("keypress", C2), () => {
522
+ e2.off("keypress", C2), t && u.write(import_sisteransi.cursor.show), e2.isTTY && !WD && e2.setRawMode(false), s.terminal = false, s.close();
523
+ };
524
+ }
525
+
526
+ // ../../node_modules/.pnpm/@clack+prompts@0.7.0/node_modules/@clack/prompts/dist/index.mjs
527
+ var import_picocolors = __toESM(require_picocolors(), 1);
528
+ var import_sisteransi2 = __toESM(require_src(), 1);
529
+ import h from "node:process";
530
+ function q2() {
531
+ return h.platform !== "win32" ? h.env.TERM !== "linux" : Boolean(h.env.CI) || Boolean(h.env.WT_SESSION) || Boolean(h.env.TERMINUS_SUBLIME) || h.env.ConEmuTask === "{cmd::Cmder}" || h.env.TERM_PROGRAM === "Terminus-Sublime" || h.env.TERM_PROGRAM === "vscode" || h.env.TERM === "xterm-256color" || h.env.TERM === "alacritty" || h.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
532
+ }
533
+ var _2 = q2();
534
+ var o = (r2, n) => _2 ? r2 : n;
535
+ var H = o("\u25C6", "*");
536
+ var I2 = o("\u25A0", "x");
537
+ var x2 = o("\u25B2", "x");
538
+ var S2 = o("\u25C7", "o");
539
+ var K = o("\u250C", "T");
540
+ var a2 = o("\u2502", "|");
541
+ var d2 = o("\u2514", "\u2014");
542
+ var b2 = o("\u25CF", ">");
543
+ var E = o("\u25CB", " ");
544
+ var C = o("\u25FB", "[\u2022]");
545
+ var w2 = o("\u25FC", "[+]");
546
+ var M2 = o("\u25FB", "[ ]");
547
+ var U2 = o("\u25AA", "\u2022");
548
+ var B = o("\u2500", "-");
549
+ var Z2 = o("\u256E", "+");
550
+ var z2 = o("\u251C", "+");
551
+ var X2 = o("\u256F", "+");
552
+ var J2 = o("\u25CF", "\u2022");
553
+ var Y = o("\u25C6", "*");
554
+ var Q2 = o("\u25B2", "!");
555
+ var ee = o("\u25A0", "x");
556
+ var y2 = (r2) => {
557
+ switch (r2) {
558
+ case "initial":
559
+ case "active":
560
+ return import_picocolors.default.cyan(H);
561
+ case "cancel":
562
+ return import_picocolors.default.red(I2);
563
+ case "error":
564
+ return import_picocolors.default.yellow(x2);
565
+ case "submit":
566
+ return import_picocolors.default.green(S2);
567
+ }
568
+ };
569
+ var ie = (r2) => {
570
+ const n = (t, s) => {
571
+ const c = t.label ?? String(t.value);
572
+ return s === "active" ? `${import_picocolors.default.green(b2)} ${c} ${t.hint ? import_picocolors.default.dim(`(${t.hint})`) : ""}` : s === "selected" ? `${import_picocolors.default.dim(c)}` : s === "cancelled" ? `${import_picocolors.default.strikethrough(import_picocolors.default.dim(c))}` : `${import_picocolors.default.dim(E)} ${import_picocolors.default.dim(c)}`;
573
+ };
574
+ let i = 0;
575
+ return new $D({ options: r2.options, initialValue: r2.initialValue, render() {
576
+ const t = `${import_picocolors.default.gray(a2)}
577
+ ${y2(this.state)} ${r2.message}
578
+ `;
579
+ switch (this.state) {
580
+ case "submit":
581
+ return `${t}${import_picocolors.default.gray(a2)} ${n(this.options[this.cursor], "selected")}`;
582
+ case "cancel":
583
+ return `${t}${import_picocolors.default.gray(a2)} ${n(this.options[this.cursor], "cancelled")}
584
+ ${import_picocolors.default.gray(a2)}`;
585
+ default: {
586
+ const s = r2.maxItems === void 0 ? 1 / 0 : Math.max(r2.maxItems, 5);
587
+ this.cursor >= i + s - 3 ? i = Math.max(Math.min(this.cursor - s + 3, this.options.length - s), 0) : this.cursor < i + 2 && (i = Math.max(this.cursor - 2, 0));
588
+ const c = s < this.options.length && i > 0, l2 = s < this.options.length && i + s < this.options.length;
589
+ return `${t}${import_picocolors.default.cyan(a2)} ${this.options.slice(i, i + s).map((u, m2, $2) => m2 === 0 && c ? import_picocolors.default.dim("...") : m2 === $2.length - 1 && l2 ? import_picocolors.default.dim("...") : n(u, m2 + i === this.cursor ? "active" : "inactive")).join(`
590
+ ${import_picocolors.default.cyan(a2)} `)}
591
+ ${import_picocolors.default.cyan(d2)}
592
+ `;
593
+ }
594
+ }
595
+ } }).prompt();
596
+ };
597
+ var R2 = (r2) => r2.replace(me(), "");
598
+ var le = (r2 = "", n = "") => {
599
+ const i = `
600
+ ${r2}
601
+ `.split(`
602
+ `), t = R2(n).length, s = Math.max(i.reduce((l2, u) => (u = R2(u), u.length > l2 ? u.length : l2), 0), t) + 2, c = i.map((l2) => `${import_picocolors.default.gray(a2)} ${import_picocolors.default.dim(l2)}${" ".repeat(s - R2(l2).length)}${import_picocolors.default.gray(a2)}`).join(`
603
+ `);
604
+ process.stdout.write(`${import_picocolors.default.gray(a2)}
605
+ ${import_picocolors.default.green(S2)} ${import_picocolors.default.reset(n)} ${import_picocolors.default.gray(B.repeat(Math.max(s - t - 1, 1)) + Z2)}
606
+ ${c}
607
+ ${import_picocolors.default.gray(z2 + B.repeat(s + 2) + X2)}
608
+ `);
609
+ };
610
+ var ue = (r2 = "") => {
611
+ process.stdout.write(`${import_picocolors.default.gray(d2)} ${import_picocolors.default.red(r2)}
612
+
613
+ `);
614
+ };
615
+ var oe = (r2 = "") => {
616
+ process.stdout.write(`${import_picocolors.default.gray(K)} ${r2}
617
+ `);
618
+ };
619
+ var $e = (r2 = "") => {
620
+ process.stdout.write(`${import_picocolors.default.gray(a2)}
621
+ ${import_picocolors.default.gray(d2)} ${r2}
622
+
623
+ `);
624
+ };
625
+ var f2 = { message: (r2 = "", { symbol: n = import_picocolors.default.gray(a2) } = {}) => {
626
+ const i = [`${import_picocolors.default.gray(a2)}`];
627
+ if (r2) {
628
+ const [t, ...s] = r2.split(`
629
+ `);
630
+ i.push(`${n} ${t}`, ...s.map((c) => `${import_picocolors.default.gray(a2)} ${c}`));
631
+ }
632
+ process.stdout.write(`${i.join(`
633
+ `)}
634
+ `);
635
+ }, info: (r2) => {
636
+ f2.message(r2, { symbol: import_picocolors.default.blue(J2) });
637
+ }, success: (r2) => {
638
+ f2.message(r2, { symbol: import_picocolors.default.green(Y) });
639
+ }, step: (r2) => {
640
+ f2.message(r2, { symbol: import_picocolors.default.green(S2) });
641
+ }, warn: (r2) => {
642
+ f2.message(r2, { symbol: import_picocolors.default.yellow(Q2) });
643
+ }, warning: (r2) => {
644
+ f2.warn(r2);
645
+ }, error: (r2) => {
646
+ f2.message(r2, { symbol: import_picocolors.default.red(ee) });
647
+ } };
648
+ var de = () => {
649
+ const r2 = _2 ? ["\u25D2", "\u25D0", "\u25D3", "\u25D1"] : ["\u2022", "o", "O", "0"], n = _2 ? 80 : 120;
650
+ let i, t, s = false, c = "";
651
+ const l2 = (v2 = "") => {
652
+ s = true, i = OD(), c = v2.replace(/\.+$/, ""), process.stdout.write(`${import_picocolors.default.gray(a2)}
653
+ `);
654
+ let g2 = 0, p = 0;
655
+ t = setInterval(() => {
656
+ const O2 = import_picocolors.default.magenta(r2[g2]), P2 = ".".repeat(Math.floor(p)).slice(0, 3);
657
+ process.stdout.write(import_sisteransi2.cursor.move(-999, 0)), process.stdout.write(import_sisteransi2.erase.down(1)), process.stdout.write(`${O2} ${c}${P2}`), g2 = g2 + 1 < r2.length ? g2 + 1 : 0, p = p < r2.length ? p + 0.125 : 0;
658
+ }, n);
659
+ }, u = (v2 = "", g2 = 0) => {
660
+ c = v2 ?? c, s = false, clearInterval(t);
661
+ const p = g2 === 0 ? import_picocolors.default.green(S2) : g2 === 1 ? import_picocolors.default.red(I2) : import_picocolors.default.red(x2);
662
+ process.stdout.write(import_sisteransi2.cursor.move(-999, 0)), process.stdout.write(import_sisteransi2.erase.down(1)), process.stdout.write(`${p} ${c}
663
+ `), i();
664
+ }, m2 = (v2 = "") => {
665
+ c = v2 ?? c;
666
+ }, $2 = (v2) => {
667
+ const g2 = v2 > 1 ? "Something went wrong" : "Canceled";
668
+ s && u(g2, v2);
669
+ };
670
+ return process.on("uncaughtExceptionMonitor", () => $2(2)), process.on("unhandledRejection", () => $2(2)), process.on("SIGINT", () => $2(1)), process.on("SIGTERM", () => $2(1)), process.on("exit", $2), { start: l2, stop: u, message: m2 };
671
+ };
672
+ function me() {
673
+ const r2 = ["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|");
674
+ return new RegExp(r2, "g");
675
+ }
676
+
677
+ // src/args.ts
678
+ init_define_PKG();
679
+ import { parseArgs } from "node:util";
680
+
681
+ // src/errors.ts
682
+ init_define_PKG();
683
+ var UsageError = class extends Error {
684
+ };
685
+ var UnavailableError = class extends Error {
686
+ };
687
+
688
+ // src/args.ts
689
+ var DEFAULT_PORT = 3e3;
690
+ var DEFAULT_STOREFRONT_PORT = 4321;
691
+ var options = {
692
+ data: { type: "string" },
693
+ port: { type: "string" },
694
+ "storefront-port": { type: "string" },
695
+ app: { type: "string" },
696
+ verbose: { type: "boolean" },
697
+ "no-open": { type: "boolean" },
698
+ "dry-run": { type: "boolean" },
699
+ help: { type: "boolean", short: "h" },
700
+ version: { type: "boolean", short: "v" }
701
+ };
702
+ function toPort(name, value, fallback) {
703
+ if (value === void 0) return fallback;
704
+ const port = Number(value);
705
+ if (!Number.isInteger(port) || port < 1 || port > 65535) {
706
+ throw new UsageError(`--${name} must be a port number (1-65535), got "${value}"`);
707
+ }
708
+ return port;
709
+ }
710
+ function parse(argv) {
711
+ let values;
712
+ try {
713
+ ;
714
+ ({ values } = parseArgs({ args: argv, options, allowPositionals: false }));
715
+ } catch (error) {
716
+ throw new UsageError(`${error.message}
717
+ Run create-shopnex --help for the options.`);
718
+ }
719
+ const port = toPort("port", values.port, DEFAULT_PORT);
720
+ const storefrontPort = toPort("storefront-port", values["storefront-port"], DEFAULT_STOREFRONT_PORT);
721
+ if (port === storefrontPort) throw new UsageError("--port and --storefront-port must be different");
722
+ return {
723
+ data: values.data,
724
+ port,
725
+ storefrontPort,
726
+ app: values.app,
727
+ verbose: Boolean(values.verbose),
728
+ open: !values["no-open"],
729
+ dryRun: Boolean(values["dry-run"]),
730
+ help: Boolean(values.help),
731
+ version: Boolean(values.version)
732
+ };
733
+ }
734
+
735
+ // src/apps.ts
736
+ init_define_PKG();
737
+
738
+ // src/plan.ts
739
+ init_define_PKG();
740
+ import { join as join2 } from "node:path";
741
+
742
+ // src/paths.ts
743
+ init_define_PKG();
744
+ import { randomBytes } from "node:crypto";
745
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
746
+ import { homedir } from "node:os";
747
+ import { dirname, join, resolve } from "node:path";
748
+ var defaultDataDir = () => join(homedir(), ".shopnex", "data");
749
+ function resolveDataDir(option) {
750
+ if (!option) return defaultDataDir();
751
+ const expanded = option === "~" ? homedir() : option.startsWith("~/") ? join(homedir(), option.slice(2)) : option;
752
+ return resolve(expanded);
753
+ }
754
+ var databaseUrl = (dataDir) => `pglite:${dataDir}`;
755
+ var appCacheDir = () => process.env.SHOPNEX_APP_DIR ?? join(homedir(), ".shopnex", "app");
756
+ function ensureSecret(dataDir) {
757
+ const file = `${dataDir}.secret`;
758
+ if (!existsSync(file)) {
759
+ mkdirSync(dirname(file), { recursive: true });
760
+ writeFileSync(file, randomBytes(32).toString("hex"), { mode: 384 });
761
+ }
762
+ return readFileSync(file, "utf8").trim();
763
+ }
764
+
765
+ // src/plan.ts
766
+ function planFromBundle(input) {
767
+ const { root, dataDir, port, storefrontPort, secret } = input;
768
+ const appUrl = `http://localhost:${port}`;
769
+ return {
770
+ appUrl,
771
+ storefrontUrl: `http://localhost:${storefrontPort}`,
772
+ processes: [
773
+ {
774
+ name: "admin",
775
+ cwd: join2(root, "admin"),
776
+ command: process.execPath,
777
+ args: ["server.mjs"],
778
+ env: {
779
+ NODE_ENV: "production",
780
+ HOST: "127.0.0.1",
781
+ PORT: String(port),
782
+ DATABASE_URL: databaseUrl(dataDir),
783
+ SHOPNEX_MIGRATIONS_DIR: join2(root, "migrations"),
784
+ SHOPNEX_SECRET: secret,
785
+ BETTER_AUTH_URL: appUrl,
786
+ APP_URL: appUrl,
787
+ // Where the admin finds the storefront (Themes, the theme editor) until a Storefront URL is saved in Settings
788
+ STOREFRONT_URL: `http://localhost:${storefrontPort}`
789
+ },
790
+ readyUrl: `http://127.0.0.1:${port}/api/v1/health`
791
+ },
792
+ {
793
+ name: "storefront",
794
+ cwd: join2(root, "storefront"),
795
+ command: process.execPath,
796
+ args: ["dist/server/entry.mjs"],
797
+ env: {
798
+ NODE_ENV: "production",
799
+ HOST: "127.0.0.1",
800
+ PORT: String(storefrontPort),
801
+ COMMERCE_PROVIDER: "shopnex",
802
+ SHOPNEX_URL: appUrl,
803
+ SHOPNEX_PUBLIC_URL: appUrl
804
+ },
805
+ readyUrl: `http://127.0.0.1:${storefrontPort}/`
806
+ }
807
+ ]
808
+ };
809
+ }
810
+
811
+ // src/apps.ts
812
+ var apps = [
813
+ {
814
+ name: "shop",
815
+ label: "Shop",
816
+ hint: "the admin with the API and checkout, and the storefront",
817
+ plan: planFromBundle
818
+ }
819
+ ];
820
+ async function pickApp(name, { interactive, list = apps }) {
821
+ if (name !== void 0) {
822
+ const found = list.find((app) => app.name === name);
823
+ if (!found) throw new UsageError(`Unknown app "${name}". Available: ${list.map((app) => app.name).join(", ")}.`);
824
+ return found;
825
+ }
826
+ const [first] = list;
827
+ if (!first) throw new UsageError("No apps are registered.");
828
+ if (list.length === 1 || !interactive) return first;
829
+ const answer = await ie({
830
+ message: "What do you want to start?",
831
+ options: list.map((app) => ({ value: app.name, label: app.label, hint: app.hint }))
832
+ });
833
+ if (lD(answer)) {
834
+ ue("Nothing was started.");
835
+ process.exit(0);
836
+ }
837
+ return list.find((app) => app.name === answer) ?? first;
838
+ }
839
+
840
+ // src/bundle.ts
841
+ init_define_PKG();
842
+ import { createHash } from "node:crypto";
843
+ import {
844
+ createWriteStream,
845
+ existsSync as existsSync2,
846
+ mkdirSync as mkdirSync2,
847
+ mkdtempSync,
848
+ readdirSync,
849
+ readFileSync as readFileSync2,
850
+ renameSync,
851
+ rmSync
852
+ } from "node:fs";
853
+ import { join as join3 } from "node:path";
854
+ import { spawnSync } from "node:child_process";
855
+ import { Readable, Transform } from "node:stream";
856
+ import { pipeline } from "node:stream/promises";
857
+ var isEdge = (version) => /-edge\./.test(version);
858
+ var bundleName = (version) => `shopnex-v${version}-node.tgz`;
859
+ var bundleUrl = (version) => process.env.SHOPNEX_BUNDLE_URL ?? (isEdge(version) ? "https://github.com/shopnex-ai/shopnex/releases/download/edge/shopnex-edge-node.tgz" : `https://github.com/shopnex-ai/shopnex/releases/download/v${version}/${bundleName(version)}`);
860
+ var bundleDir = (key) => join3(appCacheDir(), key);
861
+ var isInstalled = (key) => existsSync2(join3(bundleDir(key), "manifest.json"));
862
+ var installedEdges = () => existsSync2(appCacheDir()) ? readdirSync(appCacheDir()).filter((name) => /^edge-[0-9a-f]{12}$/.test(name)) : [];
863
+ async function get(url, what, version) {
864
+ let response;
865
+ try {
866
+ response = await fetch(url);
867
+ } catch (error) {
868
+ const reason = error.cause?.message ?? error.message;
869
+ throw new UnavailableError(`Could not download ${what} (${reason}).
870
+ Check your connection and try again.`);
871
+ }
872
+ if (response.status === 404) {
873
+ throw new UnavailableError(
874
+ `ShopNex ${version} has no packaged build to download (404 for ${url}).
875
+ Use a released version of create-shopnex.`
876
+ );
877
+ }
878
+ if (!response.ok) {
879
+ throw new UnavailableError(`Could not download ${what}: ${url} answered ${response.status}.`);
880
+ }
881
+ return response;
882
+ }
883
+ var parseChecksum = (text) => text.trim().split(/\s+/)[0]?.toLowerCase() ?? "";
884
+ async function download(response, file, onProgress) {
885
+ const hash = createHash("sha256");
886
+ let bytes = 0;
887
+ const measure = new Transform({
888
+ transform(chunk, _encoding, done) {
889
+ hash.update(chunk);
890
+ bytes += chunk.length;
891
+ onProgress(bytes);
892
+ done(null, chunk);
893
+ }
894
+ });
895
+ await pipeline(
896
+ Readable.fromWeb(response.body),
897
+ measure,
898
+ createWriteStream(file)
899
+ );
900
+ return hash.digest("hex");
901
+ }
902
+ async function resolveBundle({ version }) {
903
+ const edge = isEdge(version);
904
+ if (!edge && isInstalled(version)) return bundleDir(version);
905
+ mkdirSync2(appCacheDir(), { recursive: true });
906
+ const spinner = de();
907
+ const animate = Boolean(process.stdout.isTTY);
908
+ const say = (message) => animate ? spinner.message(message) : void 0;
909
+ const start = edge ? "Checking for a newer edge build" : `Downloading ShopNex ${version} (once, about 15 MB)`;
910
+ if (animate) spinner.start(start);
911
+ else f2.step(start);
912
+ let work;
913
+ try {
914
+ const url = bundleUrl(version);
915
+ const expected = parseChecksum(await (await get(`${url}.sha256`, "the checksum", version)).text());
916
+ if (!/^[0-9a-f]{64}$/.test(expected)) throw new UnavailableError(`${url}.sha256 does not hold a SHA-256 checksum.`);
917
+ const key = edge ? `edge-${expected.slice(0, 12)}` : version;
918
+ const dir = bundleDir(key);
919
+ if (isInstalled(key)) {
920
+ if (animate) spinner.stop("ShopNex edge is up to date");
921
+ return dir;
922
+ }
923
+ const label = edge ? "the latest edge build" : `ShopNex ${version}`;
924
+ say(`Downloading ${label}`);
925
+ work = mkdtempSync(join3(appCacheDir(), `${key}.tmp-`));
926
+ const file = join3(work, "bundle.tgz");
927
+ const actual = await download(
928
+ await get(url, "ShopNex", version),
929
+ file,
930
+ (bytes) => say(`Downloading ${label}: ${(bytes / 1e6).toFixed(1)} MB`)
931
+ );
932
+ if (actual !== expected) {
933
+ throw new UnavailableError(
934
+ `The download is damaged: its SHA-256 is ${actual}, expected ${expected}. Nothing was installed; try again.`
935
+ );
936
+ }
937
+ say("Unpacking");
938
+ const unpacked = join3(work, "app");
939
+ mkdirSync2(unpacked);
940
+ const tar = spawnSync("tar", ["-xzf", file, "-C", unpacked], { encoding: "utf8" });
941
+ if (tar.error || tar.status !== 0) {
942
+ throw new UnavailableError(`Could not unpack the download with tar: ${tar.error?.message ?? tar.stderr.trim()}`);
943
+ }
944
+ const manifestFile = join3(unpacked, "manifest.json");
945
+ const manifest = existsSync2(manifestFile) ? JSON.parse(readFileSync2(manifestFile, "utf8")) : void 0;
946
+ if (edge ? !manifest : manifest?.version !== version) {
947
+ throw new UnavailableError(
948
+ `The download is not ShopNex ${version} (its manifest says ${manifest?.version ?? "nothing"}).`
949
+ );
950
+ }
951
+ rmSync(dir, { recursive: true, force: true });
952
+ renameSync(unpacked, dir);
953
+ for (const old of installedEdges()) if (old !== key) rmSync(bundleDir(old), { recursive: true, force: true });
954
+ if (animate) spinner.stop(`${label} downloaded`);
955
+ else f2.success(`${label} downloaded`);
956
+ return dir;
957
+ } catch (error) {
958
+ if (animate) spinner.stop("Download failed", 1);
959
+ throw error;
960
+ } finally {
961
+ if (work) rmSync(work, { recursive: true, force: true });
962
+ }
963
+ }
964
+
965
+ // src/node-version.ts
966
+ init_define_PKG();
967
+ var atLeast = (version, minimum) => version.replace(/^v/, "").localeCompare(minimum, void 0, { numeric: true }) >= 0;
968
+ function assertNode(version, enginesRange) {
969
+ const minimum = enginesRange.replace(/^>=/, "");
970
+ if (!atLeast(version, minimum)) {
971
+ throw new UsageError(
972
+ `ShopNex needs Node ${minimum} or newer, this is ${version}. Install a newer Node (https://nodejs.org) and run it again.`
973
+ );
974
+ }
975
+ }
976
+
977
+ // src/theme.ts
978
+ init_define_PKG();
979
+ var import_picocolors2 = __toESM(require_picocolors(), 1);
980
+ var BRAND = [67, 192, 122];
981
+ var ON_BRAND = [6, 21, 12];
982
+ var truecolor = import_picocolors2.default.isColorSupported && /^(truecolor|24bit)$/i.test(process.env.COLORTERM ?? "");
983
+ var brand = (text) => truecolor ? `\x1B[38;2;${BRAND.join(";")}m${text}\x1B[39m` : import_picocolors2.default.green(text);
984
+ var brandBadge = (text) => truecolor ? `\x1B[48;2;${BRAND.join(";")}m\x1B[38;2;${ON_BRAND.join(";")}m${text}\x1B[39m\x1B[49m` : import_picocolors2.default.bgGreen(import_picocolors2.default.black(text));
985
+
986
+ // src/run.ts
987
+ init_define_PKG();
988
+ import { spawn } from "node:child_process";
989
+ import { connect } from "node:net";
990
+ var import_picocolors3 = __toESM(require_picocolors(), 1);
991
+ var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
992
+ function portInUse(port) {
993
+ const tryHost = (host) => new Promise((resolve2) => {
994
+ const socket = connect({ port, host });
995
+ socket.setTimeout(500);
996
+ socket.once("connect", () => (socket.destroy(), resolve2(true)));
997
+ socket.once("timeout", () => (socket.destroy(), resolve2(false)));
998
+ socket.once("error", () => resolve2(false));
999
+ });
1000
+ return Promise.all([tryHost("127.0.0.1"), tryHost("::1")]).then((used) => used.some(Boolean));
1001
+ }
1002
+ async function assertPortsFree(ports) {
1003
+ for (const { port, flag } of ports) {
1004
+ if (await portInUse(port)) {
1005
+ throw new UsageError(`Port ${port} is already in use. Stop what is using it, or pick another with ${flag}.`);
1006
+ }
1007
+ }
1008
+ }
1009
+ async function isUp(url) {
1010
+ try {
1011
+ return (await fetch(url, { redirect: "manual" })).status < 500;
1012
+ } catch {
1013
+ return false;
1014
+ }
1015
+ }
1016
+ function openBrowser(url) {
1017
+ const [command, args] = process.platform === "darwin" ? ["open", [url]] : process.platform === "win32" ? ["cmd", ["/c", "start", "", url]] : ["xdg-open", [url]];
1018
+ const child = spawn(command, args, { stdio: "ignore", detached: true });
1019
+ child.on("error", () => {
1020
+ });
1021
+ child.unref();
1022
+ }
1023
+ function runPlan(plan, { open, verbose }) {
1024
+ return new Promise((resolve2) => {
1025
+ const children = [];
1026
+ const tails = /* @__PURE__ */ new Map();
1027
+ let stopping = false;
1028
+ let ready = false;
1029
+ const spinner = de();
1030
+ const animate = Boolean(process.stdout.isTTY) && !verbose;
1031
+ if (animate) spinner.start("Starting ShopNex (the first start takes a minute)");
1032
+ else f2.step("Starting ShopNex");
1033
+ const stop = (code) => {
1034
+ if (stopping) return;
1035
+ stopping = true;
1036
+ for (const child of children) {
1037
+ try {
1038
+ if (child.pid) process.kill(-child.pid, "SIGTERM");
1039
+ } catch {
1040
+ }
1041
+ }
1042
+ setTimeout(() => resolve2(code), 300);
1043
+ };
1044
+ for (const [index, proc] of plan.processes.entries()) {
1045
+ const child = spawn(proc.command, proc.args, {
1046
+ cwd: proc.cwd,
1047
+ env: { ...process.env, ...proc.env },
1048
+ detached: true,
1049
+ stdio: ["ignore", "pipe", "pipe"]
1050
+ });
1051
+ children.push(child);
1052
+ const prefix = (index === 0 ? brand : import_picocolors3.default.magenta)(`[${proc.name}]`.padEnd(12));
1053
+ tails.set(proc.name, []);
1054
+ for (const stream of [child.stdout, child.stderr]) {
1055
+ let buffer = "";
1056
+ stream.on("data", (chunk) => {
1057
+ buffer += chunk;
1058
+ const lines = buffer.split("\n");
1059
+ buffer = lines.pop() ?? "";
1060
+ for (const line of lines) {
1061
+ if (verbose) console.log(`${prefix} ${line}`);
1062
+ const tail = tails.get(proc.name) ?? [];
1063
+ tail.push(line);
1064
+ if (tail.length > 40) tail.shift();
1065
+ tails.set(proc.name, tail);
1066
+ }
1067
+ });
1068
+ }
1069
+ child.on("error", (error) => {
1070
+ console.error(`Could not start ${proc.name}: ${error.message}`);
1071
+ stop(1);
1072
+ });
1073
+ child.on("exit", (code, signal) => {
1074
+ if (stopping) return;
1075
+ if (animate && !ready) spinner.stop(`${proc.name} stopped`, 1);
1076
+ console.error(`${proc.name} stopped (${signal ?? `exit ${code}`}).`);
1077
+ if (!verbose) for (const line of tails.get(proc.name) ?? []) console.error(import_picocolors3.default.dim(` ${line}`));
1078
+ stop(code || 1);
1079
+ });
1080
+ }
1081
+ process.on("SIGINT", () => stop(0));
1082
+ process.on("SIGTERM", () => stop(0));
1083
+ void (async () => {
1084
+ for (let i = 0; i < 180 && !stopping; i++) {
1085
+ if ((await Promise.all(plan.processes.map((proc) => isUp(proc.readyUrl)))).every(Boolean)) break;
1086
+ await sleep(1e3);
1087
+ }
1088
+ if (stopping) return;
1089
+ ready = true;
1090
+ if (animate) spinner.stop("ShopNex is running");
1091
+ le(
1092
+ [
1093
+ `${import_picocolors3.default.bold("Shop ")} ${brand(plan.storefrontUrl)}`,
1094
+ `${import_picocolors3.default.bold("Admin")} ${brand(`${plan.appUrl}/admin`)} (the first run opens the setup wizard)`
1095
+ ].join("\n"),
1096
+ "Open"
1097
+ );
1098
+ $e("Create the owner account right away. Ctrl+C stops everything.");
1099
+ if (open) openBrowser(`${plan.appUrl}/admin`);
1100
+ })();
1101
+ });
1102
+ }
1103
+
1104
+ // src/cli.ts
1105
+ var pkg = typeof define_PKG_default !== "undefined" ? define_PKG_default : JSON.parse(readFileSync3(new URL("../package.json", import.meta.url), "utf8"));
1106
+ var HELP = `create-shopnex ${pkg.version}: try ShopNex on this machine with one command.
1107
+
1108
+ Usage
1109
+ create-shopnex [options]
1110
+
1111
+ Starts the admin (with the API and checkout) and the storefront on an embedded database. Nothing else to install.
1112
+ This is for trying ShopNex out: one process owns the data. For a real shop use Docker or PostgreSQL.
1113
+
1114
+ Options
1115
+ --data <folder> where the database lives (default ~/.shopnex/data); the same folder is the same shop
1116
+ --port <n> admin, API and checkout (default 3000)
1117
+ --storefront-port <n> storefront (default 4321)
1118
+ --no-open do not open the browser
1119
+ --app <name> what to start (default shop; a picker appears once there is more than one)
1120
+ --verbose show the output of the servers while they start
1121
+ --dry-run show what would run and exit
1122
+ -h, --help this text
1123
+ -v, --version the version
1124
+ `;
1125
+ function describe({ dataDir, plan, source }) {
1126
+ return [
1127
+ `Source ${source}`,
1128
+ `Data ${dataDir}`,
1129
+ `Admin ${plan.appUrl}/admin`,
1130
+ `Storefront ${plan.storefrontUrl}`
1131
+ ].join("\n");
1132
+ }
1133
+ async function run(argv) {
1134
+ const options2 = parse(argv);
1135
+ if (options2.help) return void console.log(HELP);
1136
+ if (options2.version) return void console.log(pkg.version);
1137
+ assertNode(process.versions.node, pkg.engines.node);
1138
+ oe(brandBadge(` create-shopnex ${pkg.version} `));
1139
+ const dataDir = resolveDataDir(options2.data);
1140
+ const ports = [
1141
+ { port: options2.port, flag: "--port" },
1142
+ { port: options2.storefrontPort, flag: "--storefront-port" }
1143
+ ];
1144
+ if (!options2.dryRun) await assertPortsFree(ports);
1145
+ const root = options2.dryRun ? bundleDir(pkg.version) : await resolveBundle({ version: pkg.version });
1146
+ const source = isEdge(pkg.version) ? "ShopNex edge (the latest build from main, checked on every run)" : `ShopNex ${pkg.version} ${isInstalled(pkg.version) ? "(downloaded)" : "(downloaded on the first run)"}`;
1147
+ const app = await pickApp(options2.app, { interactive: Boolean(process.stdin.isTTY && process.stdout.isTTY) });
1148
+ const plan = app.plan({
1149
+ root,
1150
+ dataDir,
1151
+ port: options2.port,
1152
+ storefrontPort: options2.storefrontPort,
1153
+ secret: options2.dryRun ? "" : ensureSecret(dataDir)
1154
+ });
1155
+ le(describe({ dataDir, plan, source }), app.label);
1156
+ if (options2.dryRun) return $e("Dry run: nothing was started.");
1157
+ f2.warn("This is a trial database: it is not for production.");
1158
+ process.exitCode = await runPlan(plan, { open: options2.open, verbose: options2.verbose });
1159
+ }
1160
+ async function main(argv) {
1161
+ try {
1162
+ await run(argv);
1163
+ } catch (error) {
1164
+ if (error instanceof UsageError) {
1165
+ console.error(error.message);
1166
+ process.exitCode = 2;
1167
+ } else if (error instanceof UnavailableError) {
1168
+ console.error(error.message);
1169
+ process.exitCode = 1;
1170
+ } else {
1171
+ throw error;
1172
+ }
1173
+ }
1174
+ }
1175
+
1176
+ // src/main.ts
1177
+ await main(process.argv.slice(2));
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "create-shopnex",
3
+ "version": "0.0.0-edge.08b1a76",
4
+ "description": "Try ShopNex with one command: npx create-shopnex starts the admin and the storefront on an embedded database, nothing else to install",
5
+ "license": "MIT",
6
+ "homepage": "https://shopnex.ai",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/shopnex-ai/shopnex.git",
10
+ "directory": "packages/create-shopnex"
11
+ },
12
+ "keywords": [
13
+ "shopnex",
14
+ "ecommerce",
15
+ "create-shopnex",
16
+ "storefront"
17
+ ],
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "type": "module",
22
+ "bin": {
23
+ "create-shopnex": "./bin/create-shopnex.mjs"
24
+ },
25
+ "files": [
26
+ "bin",
27
+ "dist"
28
+ ],
29
+ "engines": {
30
+ "node": ">=22.22.0"
31
+ },
32
+ "scripts": {
33
+ "build": "node scripts/build.mjs",
34
+ "prepack": "node scripts/build.mjs",
35
+ "dev": "tsx src/main.ts",
36
+ "typecheck": "tsc",
37
+ "test": "tsx --test \"tests/**/*.test.ts\""
38
+ },
39
+ "devDependencies": {
40
+ "@clack/prompts": "^0.7.0",
41
+ "@types/node": "catalog:",
42
+ "esbuild": "0.28.2",
43
+ "picocolors": "^1.1.1",
44
+ "tsx": "^4.23.15"
45
+ }
46
+ }