@wix/himalaya-cli 0.1053.0 → 0.1054.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +423 -311
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/headless-loop.md +4 -1
- package/guides/wix-business-context.md +7 -0
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -2182,6 +2182,282 @@ var init_widget_identity = __esm({
|
|
|
2182
2182
|
}
|
|
2183
2183
|
});
|
|
2184
2184
|
|
|
2185
|
+
// ../../core/admin-web/src/utils/qr.ts
|
|
2186
|
+
function rawDataModules(ver) {
|
|
2187
|
+
let result = (16 * ver + 128) * ver + 64;
|
|
2188
|
+
if (ver >= 2) {
|
|
2189
|
+
const numAlign = Math.floor(ver / 7) + 2;
|
|
2190
|
+
result -= (25 * numAlign - 10) * numAlign - 55;
|
|
2191
|
+
if (ver >= 7) result -= 36;
|
|
2192
|
+
}
|
|
2193
|
+
return result;
|
|
2194
|
+
}
|
|
2195
|
+
function byteCapacity(ver) {
|
|
2196
|
+
const lenBits = ver < 10 ? 8 : 16;
|
|
2197
|
+
return dataCodewords(ver) - Math.ceil((4 + lenBits) / 8);
|
|
2198
|
+
}
|
|
2199
|
+
function fitVersion(len) {
|
|
2200
|
+
for (let v = 1; v <= QR_MAX_VERSION; v++) if (byteCapacity(v) >= len) return v;
|
|
2201
|
+
return void 0;
|
|
2202
|
+
}
|
|
2203
|
+
function rsDivisor(degree) {
|
|
2204
|
+
const result = new Array(degree).fill(0);
|
|
2205
|
+
result[degree - 1] = 1;
|
|
2206
|
+
let root = 1;
|
|
2207
|
+
for (let i = 0; i < degree; i++) {
|
|
2208
|
+
for (let j = 0; j < degree; j++) {
|
|
2209
|
+
result[j] = gfMul(result[j], root);
|
|
2210
|
+
if (j + 1 < degree) result[j] ^= result[j + 1];
|
|
2211
|
+
}
|
|
2212
|
+
root = gfMul(root, 2);
|
|
2213
|
+
}
|
|
2214
|
+
return result;
|
|
2215
|
+
}
|
|
2216
|
+
function rsRemainder(data, degree) {
|
|
2217
|
+
const divisor = rsDivisor(degree);
|
|
2218
|
+
const res = new Array(degree).fill(0);
|
|
2219
|
+
for (const b of data) {
|
|
2220
|
+
const factor = b ^ res.shift();
|
|
2221
|
+
res.push(0);
|
|
2222
|
+
for (let i = 0; i < degree; i++) res[i] ^= gfMul(divisor[i], factor);
|
|
2223
|
+
}
|
|
2224
|
+
return res;
|
|
2225
|
+
}
|
|
2226
|
+
function encodeData(bytes2, ver) {
|
|
2227
|
+
const bits = [];
|
|
2228
|
+
const push = (val, len) => {
|
|
2229
|
+
for (let i = len - 1; i >= 0; i--) bits.push(val >>> i & 1);
|
|
2230
|
+
};
|
|
2231
|
+
push(4, 4);
|
|
2232
|
+
push(bytes2.length, ver < 10 ? 8 : 16);
|
|
2233
|
+
for (const b of bytes2) push(b, 8);
|
|
2234
|
+
const capacityBits = dataCodewords(ver) * 8;
|
|
2235
|
+
push(0, Math.min(4, capacityBits - bits.length));
|
|
2236
|
+
while (bits.length % 8 !== 0) bits.push(0);
|
|
2237
|
+
const out = [];
|
|
2238
|
+
for (let i = 0; i < bits.length; i += 8) {
|
|
2239
|
+
let byte2 = 0;
|
|
2240
|
+
for (let j = 0; j < 8; j++) byte2 = byte2 << 1 | bits[i + j];
|
|
2241
|
+
out.push(byte2);
|
|
2242
|
+
}
|
|
2243
|
+
for (let pad2 = 236; out.length < dataCodewords(ver); pad2 ^= 236 ^ 17) out.push(pad2);
|
|
2244
|
+
return out;
|
|
2245
|
+
}
|
|
2246
|
+
function interleave(data, ver) {
|
|
2247
|
+
const numBlocks = NUM_BLOCKS_L[ver];
|
|
2248
|
+
const eccLen = ECC_PER_BLOCK_L[ver];
|
|
2249
|
+
const shortLen = Math.floor(totalCodewords(ver) / numBlocks) - eccLen;
|
|
2250
|
+
const numShort = numBlocks - totalCodewords(ver) % numBlocks;
|
|
2251
|
+
const blocks = [];
|
|
2252
|
+
const eccs = [];
|
|
2253
|
+
let off = 0;
|
|
2254
|
+
for (let i = 0; i < numBlocks; i++) {
|
|
2255
|
+
const len = shortLen + (i < numShort ? 0 : 1);
|
|
2256
|
+
const blk = data.slice(off, off + len);
|
|
2257
|
+
off += len;
|
|
2258
|
+
blocks.push(blk);
|
|
2259
|
+
eccs.push(rsRemainder(blk, eccLen));
|
|
2260
|
+
}
|
|
2261
|
+
const out = [];
|
|
2262
|
+
for (let i = 0; i < shortLen + 1; i++) {
|
|
2263
|
+
for (let b = 0; b < numBlocks; b++) {
|
|
2264
|
+
const v = blocks[b][i];
|
|
2265
|
+
if (v !== void 0) out.push(v);
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2268
|
+
for (let i = 0; i < eccLen; i++) for (let b = 0; b < numBlocks; b++) out.push(eccs[b][i]);
|
|
2269
|
+
return out;
|
|
2270
|
+
}
|
|
2271
|
+
function alignmentPositions(ver) {
|
|
2272
|
+
if (ver === 1) return [];
|
|
2273
|
+
const num3 = Math.floor(ver / 7) + 2;
|
|
2274
|
+
const size = ver * 4 + 17;
|
|
2275
|
+
const step = Math.ceil((ver * 4 + 4) / (num3 * 2 - 2)) * 2;
|
|
2276
|
+
const res = [6];
|
|
2277
|
+
for (let pos = size - 7; res.length < num3; pos -= step) res.splice(1, 0, pos);
|
|
2278
|
+
return res;
|
|
2279
|
+
}
|
|
2280
|
+
function bchFormat(data) {
|
|
2281
|
+
let rem = data;
|
|
2282
|
+
for (let i = 0; i < 10; i++) rem = rem << 1 ^ (rem >>> 9) * 1335;
|
|
2283
|
+
return (data << 10 | rem) ^ 21522;
|
|
2284
|
+
}
|
|
2285
|
+
function bchVersion(ver) {
|
|
2286
|
+
let rem = ver;
|
|
2287
|
+
for (let i = 0; i < 12; i++) rem = rem << 1 ^ (rem >>> 11) * 7973;
|
|
2288
|
+
return ver << 12 | rem;
|
|
2289
|
+
}
|
|
2290
|
+
function penalty(m, size) {
|
|
2291
|
+
let score = 0;
|
|
2292
|
+
const run2 = (get) => {
|
|
2293
|
+
for (let i = 0; i < size; i++) {
|
|
2294
|
+
let last = get(i, 0), len = 1;
|
|
2295
|
+
for (let j = 1; j < size; j++) {
|
|
2296
|
+
const cur = get(i, j);
|
|
2297
|
+
if (cur === last) {
|
|
2298
|
+
len++;
|
|
2299
|
+
if (len === 5) score += 3;
|
|
2300
|
+
else if (len > 5) score++;
|
|
2301
|
+
} else {
|
|
2302
|
+
last = cur;
|
|
2303
|
+
len = 1;
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
};
|
|
2308
|
+
run2((i, j) => m[i][j]);
|
|
2309
|
+
run2((i, j) => m[j][i]);
|
|
2310
|
+
for (let y = 0; y < size - 1; y++)
|
|
2311
|
+
for (let x = 0; x < size - 1; x++) {
|
|
2312
|
+
const c = m[y][x];
|
|
2313
|
+
if (c === m[y][x + 1] && c === m[y + 1][x] && c === m[y + 1][x + 1]) score += 3;
|
|
2314
|
+
}
|
|
2315
|
+
let dark = 0;
|
|
2316
|
+
for (const row of m) for (const c of row) if (c) dark++;
|
|
2317
|
+
const total = size * size;
|
|
2318
|
+
score += Math.floor(Math.abs(dark * 20 - total * 10) / total) * 10;
|
|
2319
|
+
return score;
|
|
2320
|
+
}
|
|
2321
|
+
function encodeQr(text5) {
|
|
2322
|
+
const bytes2 = [...new TextEncoder().encode(text5)];
|
|
2323
|
+
const version2 = fitVersion(bytes2.length);
|
|
2324
|
+
if (!version2) {
|
|
2325
|
+
throw new RangeError(`QR payload too long: ${bytes2.length} bytes exceeds version ${QR_MAX_VERSION} at EC level L`);
|
|
2326
|
+
}
|
|
2327
|
+
const codewords = interleave(encodeData(bytes2, version2), version2);
|
|
2328
|
+
const size = version2 * 4 + 17;
|
|
2329
|
+
const modules = Array.from({ length: size }, () => new Array(size).fill(false));
|
|
2330
|
+
const reserved = Array.from({ length: size }, () => new Array(size).fill(false));
|
|
2331
|
+
const set = (x, y, dark) => {
|
|
2332
|
+
modules[y][x] = dark;
|
|
2333
|
+
reserved[y][x] = true;
|
|
2334
|
+
};
|
|
2335
|
+
const finder = (cx, cy) => {
|
|
2336
|
+
for (let dy = -4; dy <= 4; dy++)
|
|
2337
|
+
for (let dx = -4; dx <= 4; dx++) {
|
|
2338
|
+
const x = cx + dx, y = cy + dy;
|
|
2339
|
+
if (x < 0 || y < 0 || x >= size || y >= size) continue;
|
|
2340
|
+
const d = Math.max(Math.abs(dx), Math.abs(dy));
|
|
2341
|
+
set(x, y, d !== 2 && d !== 4);
|
|
2342
|
+
}
|
|
2343
|
+
};
|
|
2344
|
+
finder(3, 3);
|
|
2345
|
+
finder(size - 4, 3);
|
|
2346
|
+
finder(3, size - 4);
|
|
2347
|
+
for (let i = 8; i < size - 8; i++) {
|
|
2348
|
+
set(i, 6, i % 2 === 0);
|
|
2349
|
+
set(6, i, i % 2 === 0);
|
|
2350
|
+
}
|
|
2351
|
+
for (const ay of alignmentPositions(version2))
|
|
2352
|
+
for (const ax of alignmentPositions(version2)) {
|
|
2353
|
+
if (ax === 6 && ay === 6 || ax === 6 && ay === size - 7 || ax === size - 7 && ay === 6) continue;
|
|
2354
|
+
for (let dy = -2; dy <= 2; dy++)
|
|
2355
|
+
for (let dx = -2; dx <= 2; dx++) set(ax + dx, ay + dy, Math.max(Math.abs(dx), Math.abs(dy)) !== 1);
|
|
2356
|
+
}
|
|
2357
|
+
for (let i = 0; i < 9; i++) {
|
|
2358
|
+
reserved[i][8] = true;
|
|
2359
|
+
reserved[8][i] = true;
|
|
2360
|
+
}
|
|
2361
|
+
for (let i = 0; i < 8; i++) {
|
|
2362
|
+
reserved[size - 1 - i][8] = true;
|
|
2363
|
+
reserved[8][size - 1 - i] = true;
|
|
2364
|
+
}
|
|
2365
|
+
set(8, size - 8, true);
|
|
2366
|
+
if (version2 >= 7)
|
|
2367
|
+
for (let i = 0; i < 18; i++) {
|
|
2368
|
+
const a = size - 11 + i % 3, b = Math.floor(i / 3);
|
|
2369
|
+
reserved[a][b] = true;
|
|
2370
|
+
reserved[b][a] = true;
|
|
2371
|
+
}
|
|
2372
|
+
let bit = 0;
|
|
2373
|
+
const totalBits = codewords.length * 8;
|
|
2374
|
+
for (let right = size - 1; right >= 1; right -= 2) {
|
|
2375
|
+
if (right === 6) right = 5;
|
|
2376
|
+
for (let vert = 0; vert < size; vert++) {
|
|
2377
|
+
for (let j = 0; j < 2; j++) {
|
|
2378
|
+
const x = right - j;
|
|
2379
|
+
const upward = (right + 1 & 2) === 0;
|
|
2380
|
+
const y = upward ? size - 1 - vert : vert;
|
|
2381
|
+
if (reserved[y][x]) continue;
|
|
2382
|
+
modules[y][x] = bit < totalBits ? (codewords[bit >>> 3] >>> 7 - (bit & 7) & 1) === 1 : false;
|
|
2383
|
+
bit++;
|
|
2384
|
+
}
|
|
2385
|
+
}
|
|
2386
|
+
}
|
|
2387
|
+
let best = null, bestMask = 0, bestScore = Infinity;
|
|
2388
|
+
for (let mask = 0; mask < 8; mask++) {
|
|
2389
|
+
const cand = modules.map((row) => [...row]);
|
|
2390
|
+
for (let y = 0; y < size; y++)
|
|
2391
|
+
for (let x = 0; x < size; x++) if (!reserved[y][x] && MASKS[mask](x, y)) cand[y][x] = !cand[y][x];
|
|
2392
|
+
applyFormat(cand, size, mask);
|
|
2393
|
+
if (version2 >= 7) applyVersion(cand, size, version2);
|
|
2394
|
+
const s = penalty(cand, size);
|
|
2395
|
+
if (s < bestScore) {
|
|
2396
|
+
bestScore = s;
|
|
2397
|
+
best = cand;
|
|
2398
|
+
bestMask = mask;
|
|
2399
|
+
}
|
|
2400
|
+
}
|
|
2401
|
+
return { size, version: version2, mask: bestMask, modules: best };
|
|
2402
|
+
}
|
|
2403
|
+
function applyFormat(m, size, mask) {
|
|
2404
|
+
const bits = bchFormat(1 << 3 | mask);
|
|
2405
|
+
const on3 = (i) => (bits >>> i & 1) === 1;
|
|
2406
|
+
const put = (x, y, dark) => {
|
|
2407
|
+
m[y][x] = dark;
|
|
2408
|
+
};
|
|
2409
|
+
for (let i = 0; i <= 5; i++) put(8, i, on3(i));
|
|
2410
|
+
put(8, 7, on3(6));
|
|
2411
|
+
put(8, 8, on3(7));
|
|
2412
|
+
put(7, 8, on3(8));
|
|
2413
|
+
for (let i = 9; i < 15; i++) put(14 - i, 8, on3(i));
|
|
2414
|
+
for (let i = 0; i < 8; i++) put(size - 1 - i, 8, on3(i));
|
|
2415
|
+
for (let i = 8; i < 15; i++) put(8, size - 15 + i, on3(i));
|
|
2416
|
+
put(8, size - 8, true);
|
|
2417
|
+
}
|
|
2418
|
+
function applyVersion(m, size, version2) {
|
|
2419
|
+
const bits = bchVersion(version2);
|
|
2420
|
+
for (let i = 0; i < 18; i++) {
|
|
2421
|
+
const on3 = (bits >>> i & 1) === 1;
|
|
2422
|
+
const a = size - 11 + i % 3, b = Math.floor(i / 3);
|
|
2423
|
+
m[a][b] = on3;
|
|
2424
|
+
m[b][a] = on3;
|
|
2425
|
+
}
|
|
2426
|
+
}
|
|
2427
|
+
var ECC_PER_BLOCK_L, NUM_BLOCKS_L, QR_MAX_VERSION, totalCodewords, dataCodewords, EXP, LOG, gfMul, MASKS;
|
|
2428
|
+
var init_qr = __esm({
|
|
2429
|
+
"../../core/admin-web/src/utils/qr.ts"() {
|
|
2430
|
+
ECC_PER_BLOCK_L = [0, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28];
|
|
2431
|
+
NUM_BLOCKS_L = [0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8];
|
|
2432
|
+
QR_MAX_VERSION = 20;
|
|
2433
|
+
totalCodewords = (ver) => Math.floor(rawDataModules(ver) / 8);
|
|
2434
|
+
dataCodewords = (ver) => totalCodewords(ver) - ECC_PER_BLOCK_L[ver] * NUM_BLOCKS_L[ver];
|
|
2435
|
+
EXP = new Uint8Array(512);
|
|
2436
|
+
LOG = new Uint8Array(256);
|
|
2437
|
+
(() => {
|
|
2438
|
+
let x = 1;
|
|
2439
|
+
for (let i = 0; i < 255; i++) {
|
|
2440
|
+
EXP[i] = x;
|
|
2441
|
+
LOG[x] = i;
|
|
2442
|
+
x <<= 1;
|
|
2443
|
+
if (x & 256) x ^= 285;
|
|
2444
|
+
}
|
|
2445
|
+
for (let i = 255; i < 512; i++) EXP[i] = EXP[i - 255];
|
|
2446
|
+
})();
|
|
2447
|
+
gfMul = (a, b) => a === 0 || b === 0 ? 0 : EXP[LOG[a] + LOG[b]];
|
|
2448
|
+
MASKS = [
|
|
2449
|
+
(x, y) => (x + y) % 2 === 0,
|
|
2450
|
+
(_x, y) => y % 2 === 0,
|
|
2451
|
+
(x) => x % 3 === 0,
|
|
2452
|
+
(x, y) => (x + y) % 3 === 0,
|
|
2453
|
+
(x, y) => (Math.floor(y / 2) + Math.floor(x / 3)) % 2 === 0,
|
|
2454
|
+
(x, y) => x * y % 2 + x * y % 3 === 0,
|
|
2455
|
+
(x, y) => (x * y % 2 + x * y % 3) % 2 === 0,
|
|
2456
|
+
(x, y) => ((x + y) % 2 + x * y % 3) % 2 === 0
|
|
2457
|
+
];
|
|
2458
|
+
}
|
|
2459
|
+
});
|
|
2460
|
+
|
|
2185
2461
|
// ../../core/dev-server/src/wix-placeholders.ts
|
|
2186
2462
|
var PLACEHOLDER_CLIENT_ID;
|
|
2187
2463
|
var init_wix_placeholders = __esm({
|
|
@@ -11363,6 +11639,7 @@ function resolveIdiom(tokens, ctx = {}) {
|
|
|
11363
11639
|
var IDIOM_CONTEXTS, UNSAFE_KEYS;
|
|
11364
11640
|
var init_idiom = __esm({
|
|
11365
11641
|
"../../core/ts/src/idiom.ts"() {
|
|
11642
|
+
"use strict";
|
|
11366
11643
|
IDIOM_CONTEXTS = {
|
|
11367
11644
|
ios: { native: ["ios"] },
|
|
11368
11645
|
android: { native: ["material"] },
|
|
@@ -21757,7 +22034,6 @@ function shouldRevealError(args) {
|
|
|
21757
22034
|
var EMAIL_RE, URL_HOST_RE, INTEGER_RE, NUMBER_RE;
|
|
21758
22035
|
var init_validation = __esm({
|
|
21759
22036
|
"../../core/ts/src/validation.ts"() {
|
|
21760
|
-
"use strict";
|
|
21761
22037
|
EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
|
|
21762
22038
|
URL_HOST_RE = /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(:[0-9]+)?$/;
|
|
21763
22039
|
INTEGER_RE = /^[+-]?[0-9]+$/;
|
|
@@ -25358,7 +25634,6 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
|
|
|
25358
25634
|
var WORKER_SUBTREE_CEILINGS, ID_PART, ACTION_ID;
|
|
25359
25635
|
var init_worker_subtree = __esm({
|
|
25360
25636
|
"../../core/ts/src/worker-subtree.ts"() {
|
|
25361
|
-
"use strict";
|
|
25362
25637
|
init_worker_subtree_safe_types_generated();
|
|
25363
25638
|
WORKER_SUBTREE_CEILINGS = Object.freeze({
|
|
25364
25639
|
maxEncodedBytes: 65536,
|
|
@@ -26899,7 +27174,8 @@ function renderNodeInner(node, ctx) {
|
|
|
26899
27174
|
extra.role = "button";
|
|
26900
27175
|
if (typeof el.type !== "string") extra[SYNTHETIC_TAP_ROLE] = true;
|
|
26901
27176
|
}
|
|
26902
|
-
|
|
27177
|
+
const defaultedTabIndex = extra.tabIndex == null || extra.tabIndex === -1 && extra[SYNTHETIC_TABINDEX] === true;
|
|
27178
|
+
if (defaultedTabIndex) {
|
|
26903
27179
|
extra.tabIndex = 0;
|
|
26904
27180
|
if (typeof el.type !== "string") extra[SYNTHETIC_TABINDEX] = true;
|
|
26905
27181
|
}
|
|
@@ -41178,6 +41454,11 @@ h2{font-size:12px;font-weight:600;color:var(--muted);text-transform:uppercase;le
|
|
|
41178
41454
|
.phone img,.phone iframe{width:100%;height:100%;object-fit:cover;object-position:top;border:0;display:block;cursor:zoom-in}
|
|
41179
41455
|
.phone.vpf{position:relative}.phone iframe.vp{position:absolute;top:0;left:0;width:390px;height:844px;transform-origin:0 0;transform:scale(var(--k,.72));cursor:auto}
|
|
41180
41456
|
.cap{text-align:center;color:var(--muted);font-size:12px;margin-top:8px}
|
|
41457
|
+
.lan{text-align:center;margin-top:12px;padding:12px;border:1px solid var(--line);border-radius:12px}
|
|
41458
|
+
.lan svg{display:block;margin:8px auto;border-radius:6px}
|
|
41459
|
+
.lant{font-weight:600}
|
|
41460
|
+
.lanu{font-size:12px;word-break:break-all}
|
|
41461
|
+
.lanh{color:var(--muted);font-size:12px;margin-top:4px}
|
|
41181
41462
|
.film{display:flex;gap:6px;overflow-x:auto;margin-top:12px;padding-bottom:4px}.film img{width:48px;aspect-ratio:390/844;object-fit:cover;object-position:top;border-radius:8px;border:1px solid var(--line);cursor:zoom-in}
|
|
41182
41463
|
.chips{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:16px}.chip{font-size:12px;padding:5px 10px;border-radius:999px;background:var(--card);border:1px solid var(--line);color:var(--muted)}
|
|
41183
41464
|
.chip.ok{background:var(--okbg);color:var(--ok);border-color:transparent}.chip.warn{background:var(--warnbg);color:var(--warn);border-color:transparent}.chip.bad{background:var(--badbg);color:var(--bad);border-color:transparent}
|
|
@@ -41246,6 +41527,14 @@ h2{font-size:12px;font-weight:600;color:var(--muted);text-transform:uppercase;le
|
|
|
41246
41527
|
var cur=null, lastSeen=Date.now();
|
|
41247
41528
|
function $(id){return document.getElementById(id)}
|
|
41248
41529
|
function el(tag,cls,txt){var e=document.createElement(tag);if(cls)e.className=cls;if(txt!=null)e.textContent=txt;return e}
|
|
41530
|
+
/* #3250 \u2014 a --lan run's way onto the owner's phone. The QR arrives as rows of 1/0 modules and is drawn
|
|
41531
|
+
as ONE path of unit squares: built with DOM calls, so nothing in the URL can become markup. */
|
|
41532
|
+
function lanCard(lan){var d=el("div","lan");d.appendChild(el("div","lant","Open on your phone"));
|
|
41533
|
+
if(lan.qr){var ns="http://www.w3.org/2000/svg",n=lan.qr.length,q=4,sz=n+2*q,svg=document.createElementNS(ns,"svg");svg.setAttribute("viewBox","0 0 "+sz+" "+sz);svg.setAttribute("width","148");svg.setAttribute("height","148");svg.setAttribute("role","img");svg.setAttribute("aria-label","QR code for "+lan.url);
|
|
41534
|
+
var bg=document.createElementNS(ns,"rect");bg.setAttribute("width",String(sz));bg.setAttribute("height",String(sz));bg.setAttribute("fill","#fff");svg.appendChild(bg);
|
|
41535
|
+
var p="";for(var y=0;y<n;y++)for(var x=0;x<n;x++)if(lan.qr[y].charAt(x)==="1")p+="M"+(x+q)+" "+(y+q)+"h1v1h-1z";
|
|
41536
|
+
var path=document.createElementNS(ns,"path");path.setAttribute("d",p);path.setAttribute("fill","#000");svg.appendChild(path);d.appendChild(svg)}
|
|
41537
|
+
d.appendChild(el("div","lanu",lan.url));d.appendChild(el("div","lanh","On the same Wi-Fi as this computer. It opens as the real app, full screen."));return d}
|
|
41249
41538
|
function clear(e){while(e.firstChild)e.removeChild(e.firstChild)}
|
|
41250
41539
|
function nowMs(){return asOf||Date.now()}
|
|
41251
41540
|
function ago(ts){var s=Math.max(0,Math.round((nowMs()-Date.parse(ts))/1000));if(s<60)return s+"s ago";var m=Math.round(s/60);if(m<60)return m+" min ago";return Math.round(m/60)+" h ago"}
|
|
@@ -41273,7 +41562,7 @@ function render(s){
|
|
|
41273
41562
|
if(pip){paintStrip(s)}else{
|
|
41274
41563
|
var kept=s.live?focus.querySelector("iframe"):null;if(kept&&(kept.getAttribute("src")!==s.live.url||kept.getAttribute("data-run")!==s.live.runId))kept=null;
|
|
41275
41564
|
if(kept){while(focus.lastChild&&focus.lastChild!==kept.parentNode)focus.removeChild(focus.lastChild)}else clear(focus);
|
|
41276
|
-
if(s.live){$("focuslbl").textContent="Live preview";if(!kept){var f=el("div","phone vpf");var fr=document.createElement("iframe");fr.className="vp";fr.setAttribute("width","390");fr.setAttribute("height","844");fr.setAttribute("data-run",s.live.runId);fr.src=s.live.url;fr.title="Live preview";f.appendChild(fr);focus.appendChild(f)}fit();if(s.live.buildError){var be=el("div","chip bad",null);be.style.display="block";be.style.marginTop="8px";be.textContent="Last edit did not build, still showing the last good version: "+s.live.buildError;focus.appendChild(be)}focus.appendChild(el("div","cap",(s.live.watching?"Repaints as the app is edited \xB7 ":"The build this run started with; himi run --watch repaints on every edit \xB7 ")+s.live.url))}
|
|
41565
|
+
if(s.live){$("focuslbl").textContent="Live preview";if(!kept){var f=el("div","phone vpf");var fr=document.createElement("iframe");fr.className="vp";fr.setAttribute("width","390");fr.setAttribute("height","844");fr.setAttribute("data-run",s.live.runId);fr.src=s.live.url;fr.title="Live preview";f.appendChild(fr);focus.appendChild(f)}fit();if(s.live.buildError){var be=el("div","chip bad",null);be.style.display="block";be.style.marginTop="8px";be.textContent="Last edit did not build, still showing the last good version: "+s.live.buildError;focus.appendChild(be)}focus.appendChild(el("div","cap",(s.live.watching?"Repaints as the app is edited \xB7 ":"The build this run started with; himi run --watch repaints on every edit \xB7 ")+s.live.url));if(s.live.lan)focus.appendChild(lanCard(s.live.lan))}
|
|
41277
41566
|
else if(s.focus&&s.focus.frames.length){var fl=s.focus.frames;$("focuslbl").textContent="Latest \xB7 "+s.focus.id;var p=el("div","phone");p.appendChild(img(fl[fl.length-1].img));focus.appendChild(p);focus.appendChild(el("div","cap",fl.length+(fl.length===1?" version":" versions")+" so far"))}
|
|
41278
41567
|
else{$("focuslbl").textContent="Latest";focus.appendChild(el("div","empty","The first render appears here."))}
|
|
41279
41568
|
if(s.focus&&s.focus.frames.length>1)s.focus.frames.forEach(function(fm){film.appendChild(img(fm.img))});}}
|
|
@@ -41784,12 +42073,30 @@ function liveRun(dir) {
|
|
|
41784
42073
|
screens: (Array.isArray(build2.screens) ? build2.screens : []).filter((x) => typeof x === "string").slice(0, 20),
|
|
41785
42074
|
tokens: build2.tokens === true,
|
|
41786
42075
|
config: build2.config === true
|
|
41787
|
-
} : null
|
|
42076
|
+
} : null,
|
|
42077
|
+
lan: lanOf(rec?.lanUrl)
|
|
41788
42078
|
};
|
|
41789
42079
|
} catch {
|
|
41790
42080
|
return null;
|
|
41791
42081
|
}
|
|
41792
42082
|
}
|
|
42083
|
+
function lanOf(value) {
|
|
42084
|
+
const raw = text(value);
|
|
42085
|
+
if (!raw) return null;
|
|
42086
|
+
let url;
|
|
42087
|
+
try {
|
|
42088
|
+
const u = new URL(raw);
|
|
42089
|
+
if (u.protocol !== "http:" && u.protocol !== "https:") return null;
|
|
42090
|
+
url = u.href;
|
|
42091
|
+
} catch {
|
|
42092
|
+
return null;
|
|
42093
|
+
}
|
|
42094
|
+
try {
|
|
42095
|
+
return { url, qr: encodeQr(url).modules.map((row) => row.map((m) => m ? "1" : "0").join("")) };
|
|
42096
|
+
} catch {
|
|
42097
|
+
return { url, qr: null };
|
|
42098
|
+
}
|
|
42099
|
+
}
|
|
41793
42100
|
function focusScreen(memory) {
|
|
41794
42101
|
const present = Object.entries(memory.shots).filter(([, s]) => s.present);
|
|
41795
42102
|
if (!present.length) return null;
|
|
@@ -41916,6 +42223,7 @@ var STUDIO_DIR, STUDIO_PAGE, STATE_FILE, MEMORY_FILE, VALIDATE_RECORD, PUSH_RECO
|
|
|
41916
42223
|
var init_studio = __esm({
|
|
41917
42224
|
"src/studio.ts"() {
|
|
41918
42225
|
init_studio_page();
|
|
42226
|
+
init_qr();
|
|
41919
42227
|
init_studio_timeline();
|
|
41920
42228
|
init_progress();
|
|
41921
42229
|
init_studio_page();
|
|
@@ -51325,21 +51633,21 @@ var init_preview_assets_generated = __esm({
|
|
|
51325
51633
|
"../../packages/serve/src/preview-assets.generated.ts"() {
|
|
51326
51634
|
init_preview_assets_format();
|
|
51327
51635
|
PREVIEW_ASSET_MANIFEST = [
|
|
51328
|
-
{ key: "assets/index-
|
|
51329
|
-
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset:
|
|
51330
|
-
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset:
|
|
51331
|
-
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset:
|
|
51332
|
-
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
51333
|
-
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset:
|
|
51334
|
-
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset:
|
|
51335
|
-
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
51336
|
-
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset:
|
|
51337
|
-
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
51338
|
-
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset:
|
|
51339
|
-
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset:
|
|
51340
|
-
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
51341
|
-
{ key: "index.html", contentType: "text/html; charset=utf-8", offset:
|
|
51342
|
-
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset:
|
|
51636
|
+
{ key: "assets/index-D1gUsTY3.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 1056804, sha256: "26589af001475b3ae732fdc5abd94d43c0b48f9d946b9fe6a2f27db0c7ba71a7" },
|
|
51637
|
+
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset: 1056812, length: 4610, sha256: "994062dd7af4186a739de55dd9e151c63b6301f8e2cbafc608d35c2e87da0cd2" },
|
|
51638
|
+
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset: 1061422, length: 488584, sha256: "d7598e12c5dbef095ff8272cfc55da0250bd07fbdecbac8a530b9b277872a134" },
|
|
51639
|
+
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 1550006, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
|
|
51640
|
+
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 1640930, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
|
|
51641
|
+
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 1731914, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
|
|
51642
|
+
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 1822894, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
|
|
51643
|
+
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 1913766, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
|
|
51644
|
+
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 2004746, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
|
|
51645
|
+
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 2113382, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
|
|
51646
|
+
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 2222466, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
|
|
51647
|
+
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 2331514, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
|
|
51648
|
+
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 2439214, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
|
|
51649
|
+
{ key: "index.html", contentType: "text/html; charset=utf-8", offset: 2527322, length: 4947, sha256: "207153af042e0e1a166f74fcd50bd1052e9000b05e7bc7283c0514848af6bd31" },
|
|
51650
|
+
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 2532269, length: 17209, sha256: "dffc9718e2faa63ae2cc919e0a842f585ed565aaaa7c53778e90379442c731b6" }
|
|
51343
51651
|
];
|
|
51344
51652
|
}
|
|
51345
51653
|
});
|
|
@@ -51348,6 +51656,8 @@ var init_preview_assets_generated = __esm({
|
|
|
51348
51656
|
var run_exports = {};
|
|
51349
51657
|
__export(run_exports, {
|
|
51350
51658
|
NO_SPA_MESSAGE: () => NO_SPA_MESSAGE,
|
|
51659
|
+
lanAddress: () => lanAddress,
|
|
51660
|
+
lanFlagConflict: () => lanFlagConflict,
|
|
51351
51661
|
loadPreviewAssets: () => loadPreviewAssets,
|
|
51352
51662
|
makePackageRunHandler: () => makePackageRunHandler,
|
|
51353
51663
|
packageUrl: () => packageUrl,
|
|
@@ -51356,7 +51666,7 @@ __export(run_exports, {
|
|
|
51356
51666
|
withoutProdServe: () => withoutProdServe
|
|
51357
51667
|
});
|
|
51358
51668
|
import { cpSync as cpSync2, existsSync as existsSync55, mkdirSync as mkdirSync26, mkdtempSync as mkdtempSync3, readFileSync as readFileSync61, rmSync as rmSync12, statSync as statSync13 } from "node:fs";
|
|
51359
|
-
import { tmpdir as tmpdir4 } from "node:os";
|
|
51669
|
+
import { networkInterfaces as osNetworkInterfaces, tmpdir as tmpdir4 } from "node:os";
|
|
51360
51670
|
import { dirname as dirname29, join as join54 } from "node:path";
|
|
51361
51671
|
import { fileURLToPath as fileURLToPath22 } from "node:url";
|
|
51362
51672
|
function makePackageRunHandler(opts) {
|
|
@@ -51460,10 +51770,37 @@ function packageUrl(origin, app, opts = {}) {
|
|
|
51460
51770
|
const query = opts.surface ? `?surface=${encodeURIComponent(opts.surface)}` : "";
|
|
51461
51771
|
return `${origin.replace(/\/$/, "")}${path2}${query}`;
|
|
51462
51772
|
}
|
|
51773
|
+
function isPrivateLan(address) {
|
|
51774
|
+
const [a, b] = address.split(".").map(Number);
|
|
51775
|
+
return a === 10 || a === 172 && b >= 16 && b <= 31 || a === 192 && b === 168;
|
|
51776
|
+
}
|
|
51777
|
+
function lanAddress(ifaces = osNetworkInterfaces()) {
|
|
51778
|
+
const found = [];
|
|
51779
|
+
for (const [name, list] of Object.entries(ifaces)) {
|
|
51780
|
+
if (UNREACHABLE_IFACE.test(name)) continue;
|
|
51781
|
+
for (const i of list ?? []) {
|
|
51782
|
+
const v4 = i.family === "IPv4" || i.family === 4;
|
|
51783
|
+
if (v4 && !i.internal && isPrivateLan(i.address)) found.push({ name, address: i.address });
|
|
51784
|
+
}
|
|
51785
|
+
}
|
|
51786
|
+
return (found.find((f) => LIKELY_LAN_IFACE.test(f.name)) ?? found[0])?.address ?? null;
|
|
51787
|
+
}
|
|
51788
|
+
function lanFlagConflict(f) {
|
|
51789
|
+
if (!f.lan) return null;
|
|
51790
|
+
if (f.browser) return { error: "--lan cannot be combined with --browser: that preview runs inside a desktop tab, with no server a phone could open. Drop --browser." };
|
|
51791
|
+
if (f.spa) return { error: "--lan cannot be combined with --spa: the hosted page would read the preview from loopback, which on a phone is the phone itself. Drop --spa." };
|
|
51792
|
+
return null;
|
|
51793
|
+
}
|
|
51463
51794
|
function openBrowser(url) {
|
|
51464
51795
|
openUrl(url);
|
|
51465
51796
|
}
|
|
51466
51797
|
async function runPackage(source, opts = {}) {
|
|
51798
|
+
const conflict = lanFlagConflict(opts);
|
|
51799
|
+
if (conflict) throw new Error(conflict.error);
|
|
51800
|
+
const lanHost = opts.lan ? lanAddress((opts.networkInterfaces ?? osNetworkInterfaces)()) : null;
|
|
51801
|
+
if (opts.lan && !lanHost) {
|
|
51802
|
+
throw new Error("himi run --lan found no LAN address to share: connect this machine to the same Wi-Fi as the phone (a VPN tunnel does not count), or drop --lan");
|
|
51803
|
+
}
|
|
51467
51804
|
const resolved2 = await resolvePackage(source, opts.workDir);
|
|
51468
51805
|
const assets = opts.assets ?? (opts.spa ? /* @__PURE__ */ new Map() : await loadPreviewAssets());
|
|
51469
51806
|
if (!opts.spa && assets.size === 0) {
|
|
@@ -51481,16 +51818,38 @@ async function runPackage(source, opts = {}) {
|
|
|
51481
51818
|
});
|
|
51482
51819
|
const extra = opts.extraRoutes;
|
|
51483
51820
|
const handler = extra ? (request) => extra(request) ?? plane(request) : plane;
|
|
51484
|
-
const
|
|
51485
|
-
|
|
51486
|
-
|
|
51487
|
-
|
|
51488
|
-
|
|
51489
|
-
const addr = server.address();
|
|
51490
|
-
resolvePort(typeof addr === "object" && addr ? addr.port : opts.port ?? 0);
|
|
51821
|
+
const listen = (srv, port2, host2) => new Promise((resolveListen, reject) => {
|
|
51822
|
+
srv.once("error", reject);
|
|
51823
|
+
srv.listen(port2, host2, () => {
|
|
51824
|
+
const addr = srv.address();
|
|
51825
|
+
resolveListen(typeof addr === "object" && addr ? { port: addr.port, address: addr.address } : { port: port2, address: host2 });
|
|
51491
51826
|
});
|
|
51492
51827
|
});
|
|
51828
|
+
const closeServer = (srv) => new Promise((done) => {
|
|
51829
|
+
srv.closeAllConnections?.();
|
|
51830
|
+
srv.close(() => done());
|
|
51831
|
+
});
|
|
51832
|
+
const host = opts.host ?? "127.0.0.1";
|
|
51833
|
+
const server = nodeAdapter(handler);
|
|
51834
|
+
const first = await listen(server, opts.port ?? 0, host);
|
|
51835
|
+
const port = first.port;
|
|
51836
|
+
const bound = [first.address];
|
|
51837
|
+
const servers = [server];
|
|
51838
|
+
if (lanHost) {
|
|
51839
|
+
const lanServer = nodeAdapter(handler);
|
|
51840
|
+
let lanBound;
|
|
51841
|
+
try {
|
|
51842
|
+
lanBound = (await listen(lanServer, port, lanHost)).address;
|
|
51843
|
+
} catch (e) {
|
|
51844
|
+
await closeServer(server);
|
|
51845
|
+
if (resolved2.temp) rmSync12(resolved2.temp, { recursive: true, force: true });
|
|
51846
|
+
throw new Error(`himi run --lan could not listen on ${lanHost}:${port} (${e.message}); drop --lan, or pass --port for a free one`);
|
|
51847
|
+
}
|
|
51848
|
+
bound.push(lanBound);
|
|
51849
|
+
servers.push(lanServer);
|
|
51850
|
+
}
|
|
51493
51851
|
const origin = `http://${host}:${port}`;
|
|
51852
|
+
const lanUrl = lanHost ? packageUrl(`http://${lanHost}:${port}`, resolved2.app, opts) : void 0;
|
|
51494
51853
|
const url = opts.spa ? `${packageUrl(opts.spa, resolved2.app, opts)}${opts.surface ? "&" : "?"}api=${encodeURIComponent(origin)}` : packageUrl(origin, resolved2.app, opts);
|
|
51495
51854
|
if (opts.open) openBrowser(url);
|
|
51496
51855
|
return {
|
|
@@ -51500,17 +51859,16 @@ async function runPackage(source, opts = {}) {
|
|
|
51500
51859
|
url,
|
|
51501
51860
|
releaseRoot: resolved2.releaseRoot,
|
|
51502
51861
|
origin,
|
|
51862
|
+
bound,
|
|
51863
|
+
...lanUrl ? { lanUrl } : {},
|
|
51503
51864
|
warnings: resolved2.warnings,
|
|
51504
|
-
close:
|
|
51505
|
-
|
|
51506
|
-
|
|
51507
|
-
|
|
51508
|
-
done();
|
|
51509
|
-
});
|
|
51510
|
-
})
|
|
51865
|
+
close: async () => {
|
|
51866
|
+
await Promise.all(servers.map(closeServer));
|
|
51867
|
+
if (resolved2.temp) rmSync12(resolved2.temp, { recursive: true, force: true });
|
|
51868
|
+
}
|
|
51511
51869
|
};
|
|
51512
51870
|
}
|
|
51513
|
-
var NO_SPA_MESSAGE;
|
|
51871
|
+
var NO_SPA_MESSAGE, UNREACHABLE_IFACE, LIKELY_LAN_IFACE;
|
|
51514
51872
|
var init_run = __esm({
|
|
51515
51873
|
"src/run.ts"() {
|
|
51516
51874
|
init_open_url();
|
|
@@ -51522,6 +51880,8 @@ var init_run = __esm({
|
|
|
51522
51880
|
init_himi_package();
|
|
51523
51881
|
init_himi_package();
|
|
51524
51882
|
NO_SPA_MESSAGE = "the web-host SPA is not embedded in this build \u2014 run `node packages/serve/scripts/embed-preview-assets.mjs` (in a monorepo checkout), or pass --spa <url> to use a hosted preview host instead";
|
|
51883
|
+
UNREACHABLE_IFACE = /^(utun|tun|tap|ppp|ipsec|wg|gif|stf|bridge|vmnet|vboxnet|virbr|docker|br-|veth|awdl|llw|anpi|tailscale|zt|zerotier|nordlynx)|vpn/i;
|
|
51884
|
+
LIKELY_LAN_IFACE = /^(en|eth|wlan|wl|wifi)/i;
|
|
51525
51885
|
}
|
|
51526
51886
|
});
|
|
51527
51887
|
|
|
@@ -64427,278 +64787,8 @@ function verifyAttestation(attestation, contentDir2, descriptors, expectedApp, r
|
|
|
64427
64787
|
return { ok: errors.length === 0, errors };
|
|
64428
64788
|
}
|
|
64429
64789
|
|
|
64430
|
-
// ../../core/admin-web/src/utils/qr.ts
|
|
64431
|
-
var ECC_PER_BLOCK_L = [0, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28];
|
|
64432
|
-
var NUM_BLOCKS_L = [0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8];
|
|
64433
|
-
var QR_MAX_VERSION = 20;
|
|
64434
|
-
function rawDataModules(ver) {
|
|
64435
|
-
let result = (16 * ver + 128) * ver + 64;
|
|
64436
|
-
if (ver >= 2) {
|
|
64437
|
-
const numAlign = Math.floor(ver / 7) + 2;
|
|
64438
|
-
result -= (25 * numAlign - 10) * numAlign - 55;
|
|
64439
|
-
if (ver >= 7) result -= 36;
|
|
64440
|
-
}
|
|
64441
|
-
return result;
|
|
64442
|
-
}
|
|
64443
|
-
var totalCodewords = (ver) => Math.floor(rawDataModules(ver) / 8);
|
|
64444
|
-
var dataCodewords = (ver) => totalCodewords(ver) - ECC_PER_BLOCK_L[ver] * NUM_BLOCKS_L[ver];
|
|
64445
|
-
function byteCapacity(ver) {
|
|
64446
|
-
const lenBits = ver < 10 ? 8 : 16;
|
|
64447
|
-
return dataCodewords(ver) - Math.ceil((4 + lenBits) / 8);
|
|
64448
|
-
}
|
|
64449
|
-
function fitVersion(len) {
|
|
64450
|
-
for (let v = 1; v <= QR_MAX_VERSION; v++) if (byteCapacity(v) >= len) return v;
|
|
64451
|
-
return void 0;
|
|
64452
|
-
}
|
|
64453
|
-
var EXP = new Uint8Array(512);
|
|
64454
|
-
var LOG = new Uint8Array(256);
|
|
64455
|
-
(() => {
|
|
64456
|
-
let x = 1;
|
|
64457
|
-
for (let i = 0; i < 255; i++) {
|
|
64458
|
-
EXP[i] = x;
|
|
64459
|
-
LOG[x] = i;
|
|
64460
|
-
x <<= 1;
|
|
64461
|
-
if (x & 256) x ^= 285;
|
|
64462
|
-
}
|
|
64463
|
-
for (let i = 255; i < 512; i++) EXP[i] = EXP[i - 255];
|
|
64464
|
-
})();
|
|
64465
|
-
var gfMul = (a, b) => a === 0 || b === 0 ? 0 : EXP[LOG[a] + LOG[b]];
|
|
64466
|
-
function rsDivisor(degree) {
|
|
64467
|
-
const result = new Array(degree).fill(0);
|
|
64468
|
-
result[degree - 1] = 1;
|
|
64469
|
-
let root = 1;
|
|
64470
|
-
for (let i = 0; i < degree; i++) {
|
|
64471
|
-
for (let j = 0; j < degree; j++) {
|
|
64472
|
-
result[j] = gfMul(result[j], root);
|
|
64473
|
-
if (j + 1 < degree) result[j] ^= result[j + 1];
|
|
64474
|
-
}
|
|
64475
|
-
root = gfMul(root, 2);
|
|
64476
|
-
}
|
|
64477
|
-
return result;
|
|
64478
|
-
}
|
|
64479
|
-
function rsRemainder(data, degree) {
|
|
64480
|
-
const divisor = rsDivisor(degree);
|
|
64481
|
-
const res = new Array(degree).fill(0);
|
|
64482
|
-
for (const b of data) {
|
|
64483
|
-
const factor = b ^ res.shift();
|
|
64484
|
-
res.push(0);
|
|
64485
|
-
for (let i = 0; i < degree; i++) res[i] ^= gfMul(divisor[i], factor);
|
|
64486
|
-
}
|
|
64487
|
-
return res;
|
|
64488
|
-
}
|
|
64489
|
-
function encodeData(bytes2, ver) {
|
|
64490
|
-
const bits = [];
|
|
64491
|
-
const push = (val, len) => {
|
|
64492
|
-
for (let i = len - 1; i >= 0; i--) bits.push(val >>> i & 1);
|
|
64493
|
-
};
|
|
64494
|
-
push(4, 4);
|
|
64495
|
-
push(bytes2.length, ver < 10 ? 8 : 16);
|
|
64496
|
-
for (const b of bytes2) push(b, 8);
|
|
64497
|
-
const capacityBits = dataCodewords(ver) * 8;
|
|
64498
|
-
push(0, Math.min(4, capacityBits - bits.length));
|
|
64499
|
-
while (bits.length % 8 !== 0) bits.push(0);
|
|
64500
|
-
const out = [];
|
|
64501
|
-
for (let i = 0; i < bits.length; i += 8) {
|
|
64502
|
-
let byte2 = 0;
|
|
64503
|
-
for (let j = 0; j < 8; j++) byte2 = byte2 << 1 | bits[i + j];
|
|
64504
|
-
out.push(byte2);
|
|
64505
|
-
}
|
|
64506
|
-
for (let pad2 = 236; out.length < dataCodewords(ver); pad2 ^= 236 ^ 17) out.push(pad2);
|
|
64507
|
-
return out;
|
|
64508
|
-
}
|
|
64509
|
-
function interleave(data, ver) {
|
|
64510
|
-
const numBlocks = NUM_BLOCKS_L[ver];
|
|
64511
|
-
const eccLen = ECC_PER_BLOCK_L[ver];
|
|
64512
|
-
const shortLen = Math.floor(totalCodewords(ver) / numBlocks) - eccLen;
|
|
64513
|
-
const numShort = numBlocks - totalCodewords(ver) % numBlocks;
|
|
64514
|
-
const blocks = [];
|
|
64515
|
-
const eccs = [];
|
|
64516
|
-
let off = 0;
|
|
64517
|
-
for (let i = 0; i < numBlocks; i++) {
|
|
64518
|
-
const len = shortLen + (i < numShort ? 0 : 1);
|
|
64519
|
-
const blk = data.slice(off, off + len);
|
|
64520
|
-
off += len;
|
|
64521
|
-
blocks.push(blk);
|
|
64522
|
-
eccs.push(rsRemainder(blk, eccLen));
|
|
64523
|
-
}
|
|
64524
|
-
const out = [];
|
|
64525
|
-
for (let i = 0; i < shortLen + 1; i++) {
|
|
64526
|
-
for (let b = 0; b < numBlocks; b++) {
|
|
64527
|
-
const v = blocks[b][i];
|
|
64528
|
-
if (v !== void 0) out.push(v);
|
|
64529
|
-
}
|
|
64530
|
-
}
|
|
64531
|
-
for (let i = 0; i < eccLen; i++) for (let b = 0; b < numBlocks; b++) out.push(eccs[b][i]);
|
|
64532
|
-
return out;
|
|
64533
|
-
}
|
|
64534
|
-
function alignmentPositions(ver) {
|
|
64535
|
-
if (ver === 1) return [];
|
|
64536
|
-
const num3 = Math.floor(ver / 7) + 2;
|
|
64537
|
-
const size = ver * 4 + 17;
|
|
64538
|
-
const step = Math.ceil((ver * 4 + 4) / (num3 * 2 - 2)) * 2;
|
|
64539
|
-
const res = [6];
|
|
64540
|
-
for (let pos = size - 7; res.length < num3; pos -= step) res.splice(1, 0, pos);
|
|
64541
|
-
return res;
|
|
64542
|
-
}
|
|
64543
|
-
var MASKS = [
|
|
64544
|
-
(x, y) => (x + y) % 2 === 0,
|
|
64545
|
-
(_x, y) => y % 2 === 0,
|
|
64546
|
-
(x) => x % 3 === 0,
|
|
64547
|
-
(x, y) => (x + y) % 3 === 0,
|
|
64548
|
-
(x, y) => (Math.floor(y / 2) + Math.floor(x / 3)) % 2 === 0,
|
|
64549
|
-
(x, y) => x * y % 2 + x * y % 3 === 0,
|
|
64550
|
-
(x, y) => (x * y % 2 + x * y % 3) % 2 === 0,
|
|
64551
|
-
(x, y) => ((x + y) % 2 + x * y % 3) % 2 === 0
|
|
64552
|
-
];
|
|
64553
|
-
function bchFormat(data) {
|
|
64554
|
-
let rem = data;
|
|
64555
|
-
for (let i = 0; i < 10; i++) rem = rem << 1 ^ (rem >>> 9) * 1335;
|
|
64556
|
-
return (data << 10 | rem) ^ 21522;
|
|
64557
|
-
}
|
|
64558
|
-
function bchVersion(ver) {
|
|
64559
|
-
let rem = ver;
|
|
64560
|
-
for (let i = 0; i < 12; i++) rem = rem << 1 ^ (rem >>> 11) * 7973;
|
|
64561
|
-
return ver << 12 | rem;
|
|
64562
|
-
}
|
|
64563
|
-
function penalty(m, size) {
|
|
64564
|
-
let score = 0;
|
|
64565
|
-
const run2 = (get) => {
|
|
64566
|
-
for (let i = 0; i < size; i++) {
|
|
64567
|
-
let last = get(i, 0), len = 1;
|
|
64568
|
-
for (let j = 1; j < size; j++) {
|
|
64569
|
-
const cur = get(i, j);
|
|
64570
|
-
if (cur === last) {
|
|
64571
|
-
len++;
|
|
64572
|
-
if (len === 5) score += 3;
|
|
64573
|
-
else if (len > 5) score++;
|
|
64574
|
-
} else {
|
|
64575
|
-
last = cur;
|
|
64576
|
-
len = 1;
|
|
64577
|
-
}
|
|
64578
|
-
}
|
|
64579
|
-
}
|
|
64580
|
-
};
|
|
64581
|
-
run2((i, j) => m[i][j]);
|
|
64582
|
-
run2((i, j) => m[j][i]);
|
|
64583
|
-
for (let y = 0; y < size - 1; y++)
|
|
64584
|
-
for (let x = 0; x < size - 1; x++) {
|
|
64585
|
-
const c = m[y][x];
|
|
64586
|
-
if (c === m[y][x + 1] && c === m[y + 1][x] && c === m[y + 1][x + 1]) score += 3;
|
|
64587
|
-
}
|
|
64588
|
-
let dark = 0;
|
|
64589
|
-
for (const row of m) for (const c of row) if (c) dark++;
|
|
64590
|
-
const total = size * size;
|
|
64591
|
-
score += Math.floor(Math.abs(dark * 20 - total * 10) / total) * 10;
|
|
64592
|
-
return score;
|
|
64593
|
-
}
|
|
64594
|
-
function encodeQr(text5) {
|
|
64595
|
-
const bytes2 = [...new TextEncoder().encode(text5)];
|
|
64596
|
-
const version2 = fitVersion(bytes2.length);
|
|
64597
|
-
if (!version2) {
|
|
64598
|
-
throw new RangeError(`QR payload too long: ${bytes2.length} bytes exceeds version ${QR_MAX_VERSION} at EC level L`);
|
|
64599
|
-
}
|
|
64600
|
-
const codewords = interleave(encodeData(bytes2, version2), version2);
|
|
64601
|
-
const size = version2 * 4 + 17;
|
|
64602
|
-
const modules = Array.from({ length: size }, () => new Array(size).fill(false));
|
|
64603
|
-
const reserved = Array.from({ length: size }, () => new Array(size).fill(false));
|
|
64604
|
-
const set = (x, y, dark) => {
|
|
64605
|
-
modules[y][x] = dark;
|
|
64606
|
-
reserved[y][x] = true;
|
|
64607
|
-
};
|
|
64608
|
-
const finder = (cx, cy) => {
|
|
64609
|
-
for (let dy = -4; dy <= 4; dy++)
|
|
64610
|
-
for (let dx = -4; dx <= 4; dx++) {
|
|
64611
|
-
const x = cx + dx, y = cy + dy;
|
|
64612
|
-
if (x < 0 || y < 0 || x >= size || y >= size) continue;
|
|
64613
|
-
const d = Math.max(Math.abs(dx), Math.abs(dy));
|
|
64614
|
-
set(x, y, d !== 2 && d !== 4);
|
|
64615
|
-
}
|
|
64616
|
-
};
|
|
64617
|
-
finder(3, 3);
|
|
64618
|
-
finder(size - 4, 3);
|
|
64619
|
-
finder(3, size - 4);
|
|
64620
|
-
for (let i = 8; i < size - 8; i++) {
|
|
64621
|
-
set(i, 6, i % 2 === 0);
|
|
64622
|
-
set(6, i, i % 2 === 0);
|
|
64623
|
-
}
|
|
64624
|
-
for (const ay of alignmentPositions(version2))
|
|
64625
|
-
for (const ax of alignmentPositions(version2)) {
|
|
64626
|
-
if (ax === 6 && ay === 6 || ax === 6 && ay === size - 7 || ax === size - 7 && ay === 6) continue;
|
|
64627
|
-
for (let dy = -2; dy <= 2; dy++)
|
|
64628
|
-
for (let dx = -2; dx <= 2; dx++) set(ax + dx, ay + dy, Math.max(Math.abs(dx), Math.abs(dy)) !== 1);
|
|
64629
|
-
}
|
|
64630
|
-
for (let i = 0; i < 9; i++) {
|
|
64631
|
-
reserved[i][8] = true;
|
|
64632
|
-
reserved[8][i] = true;
|
|
64633
|
-
}
|
|
64634
|
-
for (let i = 0; i < 8; i++) {
|
|
64635
|
-
reserved[size - 1 - i][8] = true;
|
|
64636
|
-
reserved[8][size - 1 - i] = true;
|
|
64637
|
-
}
|
|
64638
|
-
set(8, size - 8, true);
|
|
64639
|
-
if (version2 >= 7)
|
|
64640
|
-
for (let i = 0; i < 18; i++) {
|
|
64641
|
-
const a = size - 11 + i % 3, b = Math.floor(i / 3);
|
|
64642
|
-
reserved[a][b] = true;
|
|
64643
|
-
reserved[b][a] = true;
|
|
64644
|
-
}
|
|
64645
|
-
let bit = 0;
|
|
64646
|
-
const totalBits = codewords.length * 8;
|
|
64647
|
-
for (let right = size - 1; right >= 1; right -= 2) {
|
|
64648
|
-
if (right === 6) right = 5;
|
|
64649
|
-
for (let vert = 0; vert < size; vert++) {
|
|
64650
|
-
for (let j = 0; j < 2; j++) {
|
|
64651
|
-
const x = right - j;
|
|
64652
|
-
const upward = (right + 1 & 2) === 0;
|
|
64653
|
-
const y = upward ? size - 1 - vert : vert;
|
|
64654
|
-
if (reserved[y][x]) continue;
|
|
64655
|
-
modules[y][x] = bit < totalBits ? (codewords[bit >>> 3] >>> 7 - (bit & 7) & 1) === 1 : false;
|
|
64656
|
-
bit++;
|
|
64657
|
-
}
|
|
64658
|
-
}
|
|
64659
|
-
}
|
|
64660
|
-
let best = null, bestMask = 0, bestScore = Infinity;
|
|
64661
|
-
for (let mask = 0; mask < 8; mask++) {
|
|
64662
|
-
const cand = modules.map((row) => [...row]);
|
|
64663
|
-
for (let y = 0; y < size; y++)
|
|
64664
|
-
for (let x = 0; x < size; x++) if (!reserved[y][x] && MASKS[mask](x, y)) cand[y][x] = !cand[y][x];
|
|
64665
|
-
applyFormat(cand, size, mask);
|
|
64666
|
-
if (version2 >= 7) applyVersion(cand, size, version2);
|
|
64667
|
-
const s = penalty(cand, size);
|
|
64668
|
-
if (s < bestScore) {
|
|
64669
|
-
bestScore = s;
|
|
64670
|
-
best = cand;
|
|
64671
|
-
bestMask = mask;
|
|
64672
|
-
}
|
|
64673
|
-
}
|
|
64674
|
-
return { size, version: version2, mask: bestMask, modules: best };
|
|
64675
|
-
}
|
|
64676
|
-
function applyFormat(m, size, mask) {
|
|
64677
|
-
const bits = bchFormat(1 << 3 | mask);
|
|
64678
|
-
const on3 = (i) => (bits >>> i & 1) === 1;
|
|
64679
|
-
const put = (x, y, dark) => {
|
|
64680
|
-
m[y][x] = dark;
|
|
64681
|
-
};
|
|
64682
|
-
for (let i = 0; i <= 5; i++) put(8, i, on3(i));
|
|
64683
|
-
put(8, 7, on3(6));
|
|
64684
|
-
put(8, 8, on3(7));
|
|
64685
|
-
put(7, 8, on3(8));
|
|
64686
|
-
for (let i = 9; i < 15; i++) put(14 - i, 8, on3(i));
|
|
64687
|
-
for (let i = 0; i < 8; i++) put(size - 1 - i, 8, on3(i));
|
|
64688
|
-
for (let i = 8; i < 15; i++) put(8, size - 15 + i, on3(i));
|
|
64689
|
-
put(8, size - 8, true);
|
|
64690
|
-
}
|
|
64691
|
-
function applyVersion(m, size, version2) {
|
|
64692
|
-
const bits = bchVersion(version2);
|
|
64693
|
-
for (let i = 0; i < 18; i++) {
|
|
64694
|
-
const on3 = (bits >>> i & 1) === 1;
|
|
64695
|
-
const a = size - 11 + i % 3, b = Math.floor(i / 3);
|
|
64696
|
-
m[a][b] = on3;
|
|
64697
|
-
m[b][a] = on3;
|
|
64698
|
-
}
|
|
64699
|
-
}
|
|
64700
|
-
|
|
64701
64790
|
// ../../core/admin-web/src/utils/qr-terminal.ts
|
|
64791
|
+
init_qr();
|
|
64702
64792
|
function qrTerminal(text5, opts = {}) {
|
|
64703
64793
|
const { modules, size } = encodeQr(text5);
|
|
64704
64794
|
const quietZone = opts.quietZone ?? 4;
|
|
@@ -66085,6 +66175,7 @@ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
|
66085
66175
|
"force",
|
|
66086
66176
|
"replace",
|
|
66087
66177
|
"watch",
|
|
66178
|
+
"lan",
|
|
66088
66179
|
"no-claim",
|
|
66089
66180
|
"new",
|
|
66090
66181
|
"dev",
|
|
@@ -66503,7 +66594,7 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
|
|
|
66503
66594
|
file is not the plane's per-release archive.
|
|
66504
66595
|
himi share --file <package.himi> [--expires-at <ISO>] | revoke --app <app> <shareId>
|
|
66505
66596
|
publish a content-addressed package link for a released app
|
|
66506
|
-
himi run [<package.himi|dir|url>] [--browser] [--watch] [--port <n>] [--chrome preview|app] [--screen <id>] [--surface <id>] [--no-open]
|
|
66597
|
+
himi run [<package.himi|dir|url>] [--browser] [--watch] [--lan] [--port <n>] [--chrome preview|app] [--screen <id>] [--surface <id>] [--no-open]
|
|
66507
66598
|
serve a package on localhost + open it in a browser. No serve
|
|
66508
66599
|
plane, no dev-server. With no argument it packs the current
|
|
66509
66600
|
content package first \u2014 edit, run, look at it.
|
|
@@ -66511,6 +66602,9 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
|
|
|
66511
66602
|
(a failed build keeps the last good preview). The build board
|
|
66512
66603
|
is served beside it at /__himi/studio/ with the preview framed
|
|
66513
66604
|
in it. Blocks until Ctrl-C.
|
|
66605
|
+
--lan also serves it to the local network and prints a QR:
|
|
66606
|
+
a phone on the same Wi-Fi opens it as the real app, full
|
|
66607
|
+
screen. Read-only, but anyone on that network can open it.
|
|
66514
66608
|
himi flags list|set|ramp|rm [<key>] [--app <a>]
|
|
66515
66609
|
read/change operational flags (RFC 0013); writes report
|
|
66516
66610
|
servedNow from the device door, never just ok
|
|
@@ -66857,7 +66951,7 @@ var COMMANDS = [
|
|
|
66857
66951
|
{ name: "import", summary: "turn a `himi pack --dev` package back into an EDITABLE content package \u2014 the file counterpart of `himi pull`, needing no serve plane, no account and no network. Refuses an invalid package before trusting its source (the content hash is recomputed over every entry on open, so the archive is provably the one that was packed), and refuses a RELEASE package by naming the absence \u2014 it carries built output and no source \u2014 rather than reporting a missing file. `--name` re-substitutes the app identity through the same machinery `himi init --template` and `himi pull --name` use, so the restored tree is a NEW app rather than a second copy of the same one, and a name that also appears inside a screen id (`feed` in `feed_home`) is left alone. A non-empty destination needs `--force` and a merge NAMES what it kept (`left: [...]`), the same contract `himi pull --force` has; a shape clash is refused whole before anything is written. There is no `--replace`: a file you were handed is not the plane's per-release archive.", required: "<package.himi> [--out <dir>] [--name <new>] [--force]" },
|
|
66858
66952
|
{ name: "pull", summary: "restore an app's SOURCE from the serve plane into an editable content package \u2014 the other half of `himi push`, which archives the content package on every publish. Owner or editor only: a viewer may download the RUNNING app (`/v1/owner/package`), not the codebase it was built from. A PAST release is restorable, not only the live one \u2014 the archive is content-addressed per release, so it has none of the live-single-slot problem that makes `himi pack` current-release-only. Two limits: pruning keeps the current release plus the newest ~20 ledger entries, and a release id identifies OTA content rather than source, so a source-only change republishes under the same id and replaces that id's archive. A release published before source archiving shipped, or pushed with `--no-source`, answers `app_source_not_found` and says to push again. `--name` re-substitutes the app identity through the same machinery `himi init --template` uses, so the restored tree is a NEW app rather than a second copy of the same one, and a name that also appears inside a screen id (`feed` in `feed_home`) is left alone. A NON-EMPTY destination is refused unless you say which you mean: `--force` merges and reports \u2014 it writes the archive over what is there, keeps files the release does not carry, and NAMES every one of them as `left: [...]` so a tree that matches no release is never silent (#2437); `--replace` restores exactly what was archived, removing those files first (`removed: [...]`) and implying `--force`. `--replace` refuses a directory holding no `himalaya.content.json`, so a mistyped `--out` cannot clear an unrelated tree, and the only paths it can remove are the ones a push would have archived \u2014 `.git/`, `node_modules/`, `dist/`, `.env*` and key material are out of its reach by construction.", required: "<app> [--release <id>] [--out <dir>] [--name <new>] [--force|--replace] [--target <t>]" },
|
|
66859
66953
|
{ name: "share", summary: "publish or revoke a content-addressed `.himi` share link. The package must be a validated archive for an already-published release; the resulting https URL is safe to QR, copy, or open in Himi Player.", required: "--file <package.himi> [--expires-at <ISO>] | revoke --app <app> <shareId>" },
|
|
66860
|
-
{ name: "run", summary: "serve a .himi package on localhost and open it in a browser \u2014 no serve plane, no dev-server, no setup. Given no argument it builds the current content package first, so `himi run` is the inner loop: edit, run, look at it. The SPA and /v1 are served from ONE origin because Tier-5 bundle fetches on web are same-origin-only. --chrome preview frames the app in a device chassis; --chrome app serves it as a plain web app. Blocks until Ctrl-C, like any dev server. --browser runs the whole plane INSIDE the tab (service worker + in-memory store) so no app code executes in this process or on any pod. --watch keeps the preview LIVE: every save in the content package rebuilds it and repaints the open tab with only what changed (the dev-server's hot-reload events); a build that fails keeps the last good preview on screen and says why. Any `himi run` of a content package (plain, --watch or --browser) frames its preview on the build board (`himi studio`) while it serves, and all but --browser also serve that board at /__himi/studio/ on the preview's own origin.", required: "[<package.himi|dir|url>] [--browser] [--watch] [--content <dir>] [--port <n>] [--chrome preview|app] [--screen <id>] [--surface <id>] [--no-open] [--spa <url>]" },
|
|
66954
|
+
{ name: "run", summary: "serve a .himi package on localhost and open it in a browser \u2014 no serve plane, no dev-server, no setup. Given no argument it builds the current content package first, so `himi run` is the inner loop: edit, run, look at it. The SPA and /v1 are served from ONE origin because Tier-5 bundle fetches on web are same-origin-only. --chrome preview frames the app in a device chassis; --chrome app serves it as a plain web app. Blocks until Ctrl-C, like any dev server. --browser runs the whole plane INSIDE the tab (service worker + in-memory store) so no app code executes in this process or on any pod. --lan also serves it to the local network and prints a QR, so a phone on the same Wi-Fi opens it as the real app, full screen. --watch keeps the preview LIVE: every save in the content package rebuilds it and repaints the open tab with only what changed (the dev-server's hot-reload events); a build that fails keeps the last good preview on screen and says why. Any `himi run` of a content package (plain, --watch or --browser) frames its preview on the build board (`himi studio`) while it serves, and all but --browser also serve that board at /__himi/studio/ on the preview's own origin.", required: "[<package.himi|dir|url>] [--browser] [--watch] [--lan] [--content <dir>] [--port <n>] [--chrome preview|app] [--screen <id>] [--surface <id>] [--no-open] [--spa <url>]" },
|
|
66861
66955
|
{ name: "preview", summary: "print the shareable web URL + himi:// deep link + agent /v1/preview JSON URLs for an app+release; --surface frames the web preview as any catalog surface (?surface=)", required: "--app --release [--screen] [--surface]" },
|
|
66862
66956
|
{ name: "surfaces", summary: "the surface catalog vs this app's envelope (platforms.json): targeted surfaces, the opt-in key for the rest, per-surface preview links with --app --release, and which widget families the package produces with --measure-widgets (which runs its built bundles)", required: "[--content <dir>] [--app --release] [--measure-widgets]" },
|
|
66863
66957
|
{ name: "context", summary: "fetch the agent preview envelope (GET /v1/preview/a/<app>) \u2014 ok/issues/screens/links; exit 1 if ok:false", required: "--app --release [--screen] [--include telemetry]" },
|
|
@@ -71430,7 +71524,13 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
71430
71524
|
// ---- himi run — serve a package on localhost and open it in a browser ----
|
|
71431
71525
|
// Blocks until interrupted, like any dev server.
|
|
71432
71526
|
case "run": {
|
|
71433
|
-
const { runPackage: runPackage2 } = await Promise.resolve().then(() => (init_run(), run_exports));
|
|
71527
|
+
const { runPackage: runPackage2, lanFlagConflict: lanFlagConflict2 } = await Promise.resolve().then(() => (init_run(), run_exports));
|
|
71528
|
+
const spaFlag = flags.spa;
|
|
71529
|
+
const lanConflict = lanFlagConflict2({ lan: flags.lan === true, browser: flags.browser === true, spa: typeof spaFlag === "string" || Array.isArray(spaFlag) ? String(spaFlag) : void 0 });
|
|
71530
|
+
if (lanConflict) {
|
|
71531
|
+
io.error(JSON.stringify({ ok: false, ...lanConflict }));
|
|
71532
|
+
return 2;
|
|
71533
|
+
}
|
|
71434
71534
|
let source = pos[1];
|
|
71435
71535
|
let temp = null;
|
|
71436
71536
|
const watch2 = flags.watch === true;
|
|
@@ -71486,7 +71586,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
71486
71586
|
let startedAt = "";
|
|
71487
71587
|
const record2 = (served2, build2) => {
|
|
71488
71588
|
try {
|
|
71489
|
-
if (recordKit?.writeRunRecord(dir, { url: served2.url, port: served2.port, pid: process.pid, startedAt, watching: watch2, build: build2 })) recorded = true;
|
|
71589
|
+
if (recordKit?.writeRunRecord(dir, { url: served2.url, port: served2.port, ...served2.lanUrl ? { lanUrl: served2.lanUrl } : {}, pid: process.pid, startedAt, watching: watch2, build: build2 })) recorded = true;
|
|
71490
71590
|
return null;
|
|
71491
71591
|
} catch (e) {
|
|
71492
71592
|
return e.message;
|
|
@@ -71535,6 +71635,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
71535
71635
|
surface: str6(flags.surface),
|
|
71536
71636
|
spa: str6(flags.spa),
|
|
71537
71637
|
open: flags["no-open"] !== true,
|
|
71638
|
+
lan: flags.lan === true,
|
|
71538
71639
|
// The build board on the preview's own origin, for any run of this content package.
|
|
71539
71640
|
...recordKit ? { extraRoutes: (request) => recordKit.boardFile(dir, new URL(request.url).pathname) } : {},
|
|
71540
71641
|
// `liveWix` only with --watch: that is the "click around while you work" window, and a
|
|
@@ -71607,12 +71708,23 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
71607
71708
|
await running.close();
|
|
71608
71709
|
throw e;
|
|
71609
71710
|
}
|
|
71711
|
+
if (running.lanUrl) {
|
|
71712
|
+
io.error(`himi run --lan: anyone on this network can open this preview (read-only) at ${running.lanUrl}`);
|
|
71713
|
+
io.error("Scan it with your phone, on the same Wi-Fi:");
|
|
71714
|
+
try {
|
|
71715
|
+
const qr = qrTerminal(running.lanUrl);
|
|
71716
|
+
io.error(qr.cols <= 60 ? qr.text : ` QR omitted (terminal width ${qr.cols} exceeds 60 columns)`);
|
|
71717
|
+
} catch {
|
|
71718
|
+
io.error(" QR omitted (link is too long)");
|
|
71719
|
+
}
|
|
71720
|
+
}
|
|
71610
71721
|
print({
|
|
71611
71722
|
ok: true,
|
|
71612
71723
|
app: running.app,
|
|
71613
71724
|
releaseId: running.releaseId,
|
|
71614
71725
|
url: running.url,
|
|
71615
71726
|
port: running.port,
|
|
71727
|
+
...running.lanUrl ? { lan: { url: running.lanUrl } } : {},
|
|
71616
71728
|
...watch2 ? { watching: dir } : {},
|
|
71617
71729
|
...recordKit && boardOpen(dir) ? { board: `${running.origin}/__himi/studio/` } : {},
|
|
71618
71730
|
...running.warnings.length ? { warnings: running.warnings } : {},
|
|
Binary file
|
package/guides/headless-loop.md
CHANGED
|
@@ -101,7 +101,10 @@ fills, and a published draft or the handover is celebrated once. The tab title c
|
|
|
101
101
|
("(5/8) salon"), and the owner can switch on Sound and desktop notices from the board itself — both
|
|
102
102
|
start off, so never promise them either. The board can also rewind the whole build — drag its timeline or
|
|
103
103
|
press Replay for a thirty-second making-of, checks included — pop the live phone out into an
|
|
104
|
-
always-on-top window, and show the owner their website next to their app the moment the brand lands.
|
|
104
|
+
always-on-top window, and show the owner their website next to their app the moment the brand lands.
|
|
105
|
+
To put the preview on the owner's phone, run `himi run --watch --lan` instead: it prints a QR (and
|
|
106
|
+
the board shows one) that a phone on the same Wi-Fi opens as the real app, full screen, repainting as
|
|
107
|
+
you edit. Say that anyone on that network can open it; it is read-only. `himi test` writes one PNG per
|
|
105
108
|
screen to `.himi/shots/` on every run, so take the new screens from there instead of rendering each
|
|
106
109
|
one again; a bare `--png` on `himi render` writes `.himi/shots/<id>.png`. `himi progress` copies each image into `.himi/history/`
|
|
107
110
|
as it was when you journaled it, so a later render cannot change what the record says the owner saw;
|
|
@@ -145,6 +145,13 @@ Same collector, three doors:
|
|
|
145
145
|
| `POST /v1/site/analyze` (BO-only) | JSON book + overlays + media URLs (no PNG bodies) |
|
|
146
146
|
| MCP `himi_site_analyze` | Same JSON via `structuredContent` |
|
|
147
147
|
|
|
148
|
+
`clientId` is optional on the HTTP and MCP doors too, as `--client-id` is on the CLI: a body of
|
|
149
|
+
`{ "siteUrl": "https://…" }` alone is the URL-only pass — vertical probes `skipped`, no `wix` block
|
|
150
|
+
in `provisioningOverlay`, and the response carries `urlOnly: true` plus a `note` saying the catalog
|
|
151
|
+
counts and the binding need a `clientId`. `"apply": true` without a `clientId` is refused with
|
|
152
|
+
`400 apply_needs_client_id`, the HTTP twin of `--apply` exiting 2. The door stays BO-only, and
|
|
153
|
+
`siteUrl` is judged by the same public-host guard whether or not a client id is sent.
|
|
154
|
+
|
|
148
155
|
The plane has no headless browser (`look.unavailable: no_browser_on_plane`). Owner token is a **request field**, never spawned via `wix token` on the guest. Blobs in the book are **URLs** (Media Manager / wixstatic), not S3 and not base64.
|
|
149
156
|
|
|
150
157
|
`--apply` writes `appearance.homeLayout` + `navigation.navKind` plus identity/colors. It never silently overwrites committed Amit1 `apps/himi-branded-lite/provisioning.json`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1054.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "himi — the Himalaya authoring CLI. Build a Tier-5 content package on your own machine, push it to the production serve as a draft, preview it on web + Himi Player, and read worker logs back — the remote dev loop. Wraps @himalaya/serve-cli for transport.",
|
|
6
6
|
"keywords": [
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
"artifactId": "himalaya-cli"
|
|
66
66
|
}
|
|
67
67
|
},
|
|
68
|
-
"falconPackageHash": "
|
|
68
|
+
"falconPackageHash": "045caa3e88a506e031fb787279f23cc802f48565167f69eb533939ab"
|
|
69
69
|
}
|