@ecmaos/kernel 0.6.3 → 0.6.5

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.
@@ -280,9 +280,9 @@ function arrayify$6(input) {
280
280
  }
281
281
  }
282
282
  __name(arrayify$6, "arrayify$6");
283
- const csi$5 = "\x1B[";
284
- const ansi$6 = {};
285
- ansi$6.style = {
283
+ const csi$6 = "\x1B[";
284
+ const ansi$7 = {};
285
+ ansi$7.style = {
286
286
  reset: "\x1B[0m",
287
287
  bold: "\x1B[1m",
288
288
  italic: "\x1B[3m",
@@ -330,29 +330,29 @@ ansi$6.style = {
330
330
  "bg-brightCyan": "\x1B[106m",
331
331
  "bg-brightWhite": "\x1B[107m"
332
332
  };
333
- ansi$6.rgb = function(r, g2, b) {
333
+ ansi$7.rgb = function(r, g2, b) {
334
334
  return `\x1B[38;2;${r};${g2};${b}m`;
335
335
  };
336
- ansi$6.bgRgb = function(r, g2, b) {
336
+ ansi$7.bgRgb = function(r, g2, b) {
337
337
  return `\x1B[48;2;${r};${g2};${b}m`;
338
338
  };
339
- ansi$6.styles = function(styles2) {
339
+ ansi$7.styles = function(styles2) {
340
340
  styles2 = arrayify$6(styles2);
341
341
  return styles2.map(function(effect) {
342
342
  const rgbMatches = effect.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
343
343
  const bgRgbMatches = effect.match(/bg-rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
344
344
  if (bgRgbMatches) {
345
345
  const [full, r, g2, b] = bgRgbMatches;
346
- return ansi$6.bgRgb(r, g2, b);
346
+ return ansi$7.bgRgb(r, g2, b);
347
347
  } else if (rgbMatches) {
348
348
  const [full, r, g2, b] = rgbMatches;
349
- return ansi$6.rgb(r, g2, b);
349
+ return ansi$7.rgb(r, g2, b);
350
350
  } else {
351
- return ansi$6.style[effect];
351
+ return ansi$7.style[effect];
352
352
  }
353
353
  }).join("");
354
354
  };
355
- ansi$6.format = function(str, styleArray) {
355
+ ansi$7.format = function(str, styleArray) {
356
356
  const re2 = /\[([\w\s-\(\),]+)\]{([^]*?)}/;
357
357
  let matches;
358
358
  str = String(str);
@@ -360,18 +360,18 @@ ansi$6.format = function(str, styleArray) {
360
360
  while (matches = str.match(re2)) {
361
361
  const inlineStyles = matches[1].split(/\s+/);
362
362
  const inlineString = matches[2];
363
- str = str.replace(matches[0], ansi$6.format(inlineString, inlineStyles));
363
+ str = str.replace(matches[0], ansi$7.format(inlineString, inlineStyles));
364
364
  }
365
- return styleArray && styleArray.length ? ansi$6.styles(styleArray) + str + ansi$6.style.reset : str;
365
+ return styleArray && styleArray.length ? ansi$7.styles(styleArray) + str + ansi$7.style.reset : str;
366
366
  };
367
- ansi$6.cursor = {
367
+ ansi$7.cursor = {
368
368
  /**
369
369
  * Moves the cursor `lines` cells up. If the cursor is already at the edge of the screen, this has no effect
370
370
  * @param [lines=1] {number}
371
371
  * @return {string}
372
372
  */
373
373
  up: /* @__PURE__ */ __name(function(lines) {
374
- return csi$5 + (lines || 1) + "A";
374
+ return csi$6 + (lines || 1) + "A";
375
375
  }, "up"),
376
376
  /**
377
377
  * Moves the cursor `lines` cells down. If the cursor is already at the edge of the screen, this has no effect
@@ -379,7 +379,7 @@ ansi$6.cursor = {
379
379
  * @return {string}
380
380
  */
381
381
  down: /* @__PURE__ */ __name(function(lines) {
382
- return csi$5 + (lines || 1) + "B";
382
+ return csi$6 + (lines || 1) + "B";
383
383
  }, "down"),
384
384
  /**
385
385
  * Moves the cursor `lines` cells forward. If the cursor is already at the edge of the screen, this has no effect
@@ -387,7 +387,7 @@ ansi$6.cursor = {
387
387
  * @return {string}
388
388
  */
389
389
  forward: /* @__PURE__ */ __name(function(lines) {
390
- return csi$5 + (lines || 1) + "C";
390
+ return csi$6 + (lines || 1) + "C";
391
391
  }, "forward"),
392
392
  /**
393
393
  * Moves the cursor `lines` cells back. If the cursor is already at the edge of the screen, this has no effect
@@ -395,7 +395,7 @@ ansi$6.cursor = {
395
395
  * @return {string}
396
396
  */
397
397
  back: /* @__PURE__ */ __name(function(lines) {
398
- return csi$5 + (lines || 1) + "D";
398
+ return csi$6 + (lines || 1) + "D";
399
399
  }, "back"),
400
400
  /**
401
401
  * Moves cursor to beginning of the line n lines down.
@@ -403,7 +403,7 @@ ansi$6.cursor = {
403
403
  * @return {string}
404
404
  */
405
405
  nextLine: /* @__PURE__ */ __name(function(lines) {
406
- return csi$5 + (lines || 1) + "E";
406
+ return csi$6 + (lines || 1) + "E";
407
407
  }, "nextLine"),
408
408
  /**
409
409
  * Moves cursor to beginning of the line n lines up.
@@ -411,7 +411,7 @@ ansi$6.cursor = {
411
411
  * @return {string}
412
412
  */
413
413
  previousLine: /* @__PURE__ */ __name(function(lines) {
414
- return csi$5 + (lines || 1) + "F";
414
+ return csi$6 + (lines || 1) + "F";
415
415
  }, "previousLine"),
416
416
  /**
417
417
  * Moves the cursor to column n.
@@ -419,7 +419,7 @@ ansi$6.cursor = {
419
419
  * @return {string}
420
420
  */
421
421
  horizontalAbsolute: /* @__PURE__ */ __name(function(n) {
422
- return csi$5 + n + "G";
422
+ return csi$6 + n + "G";
423
423
  }, "horizontalAbsolute"),
424
424
  /**
425
425
  * Moves the cursor to row n, column m. The values are 1-based, and default to 1 (top left corner) if omitted.
@@ -428,25 +428,25 @@ ansi$6.cursor = {
428
428
  * @return {string}
429
429
  */
430
430
  position: /* @__PURE__ */ __name(function(n, m) {
431
- return csi$5 + (n || 1) + ";" + (m || 1) + "H";
431
+ return csi$6 + (n || 1) + ";" + (m || 1) + "H";
432
432
  }, "position"),
433
433
  /**
434
434
  * Hides the cursor
435
435
  */
436
- hide: csi$5 + "?25l",
436
+ hide: csi$6 + "?25l",
437
437
  /**
438
438
  * Shows the cursor
439
439
  */
440
- show: csi$5 + "?25h"
440
+ show: csi$6 + "?25h"
441
441
  };
442
- ansi$6.erase = {
442
+ ansi$7.erase = {
443
443
  /**
444
444
  * Clears part of the screen. If n is 0 (or missing), clear from cursor to end of screen. If n is 1, clear from cursor to beginning of the screen. If n is 2, clear entire screen.
445
445
  * @param n {number}
446
446
  * @return {string}
447
447
  */
448
448
  display: /* @__PURE__ */ __name(function(n) {
449
- return csi$5 + (n || 0) + "J";
449
+ return csi$6 + (n || 0) + "J";
450
450
  }, "display"),
451
451
  /**
452
452
  * Erases part of the line. If n is zero (or missing), clear from cursor to the end of the line. If n is one, clear from cursor to beginning of the line. If n is two, clear entire line. Cursor position does not change.
@@ -454,7 +454,7 @@ ansi$6.erase = {
454
454
  * @return {string}
455
455
  */
456
456
  inLine: /* @__PURE__ */ __name(function(n) {
457
- return csi$5 + (n || 0) + "K";
457
+ return csi$6 + (n || 0) + "K";
458
458
  }, "inLine")
459
459
  };
460
460
  const ANSI_BACKGROUND_OFFSET$1 = 10;
@@ -4974,15 +4974,15 @@ const warn = _shortcut$1(Level.WARN);
4974
4974
  const notice = _shortcut$1(Level.NOTICE);
4975
4975
  const info = _shortcut$1(Level.INFO);
4976
4976
  const debug = _shortcut$1(Level.DEBUG);
4977
- function ansi$5(text, format2) {
4977
+ function ansi$6(text, format2) {
4978
4978
  return `\x1B[${format2}m${text}\x1B[0m`;
4979
4979
  }
4980
- __name(ansi$5, "ansi$5");
4980
+ __name(ansi$6, "ansi$6");
4981
4981
  function _prettyMs(entry, style) {
4982
4982
  const text = "[" + (entry.elapsedMs / 1e3).toFixed(3).padStart(10) + "] ";
4983
4983
  switch (style) {
4984
4984
  case "ansi":
4985
- return [ansi$5(text, "2;37")];
4985
+ return [ansi$6(text, "2;37")];
4986
4986
  case "css":
4987
4987
  return ["%c" + text, "opacity: 0.8; color: white;"];
4988
4988
  default:
@@ -25369,39 +25369,101 @@ const _Auth = class _Auth {
25369
25369
  // Create a new credential
25370
25370
  create: /* @__PURE__ */ __name(async (options) => {
25371
25371
  try {
25372
- return await navigator.credentials.create({ publicKey: options });
25372
+ if (!this.passkey.isSupported()) {
25373
+ throw new Error("WebAuthn is not supported in this browser");
25374
+ }
25375
+ if (!window.isSecureContext) {
25376
+ throw new Error("WebAuthn requires a secure context (HTTPS or localhost)");
25377
+ }
25378
+ const credential = await navigator.credentials.create({ publicKey: options });
25379
+ if (!credential || !(credential instanceof PublicKeyCredential)) {
25380
+ throw new Error("Failed to create credential");
25381
+ }
25382
+ return credential;
25373
25383
  } catch (error) {
25374
- console.error("Error creating credential:", error);
25375
- return null;
25384
+ if (error instanceof Error) {
25385
+ if (error.name === "NotAllowedError") {
25386
+ throw new Error("User cancelled or denied the operation");
25387
+ } else if (error.name === "InvalidStateError") {
25388
+ throw new Error("Credential already exists or operation is invalid");
25389
+ } else if (error.name === "NotSupportedError") {
25390
+ throw new Error("The operation is not supported");
25391
+ } else if (error.name === "SecurityError") {
25392
+ throw new Error("Security error: operation not allowed");
25393
+ }
25394
+ throw error;
25395
+ }
25396
+ throw new Error(`Error creating credential: ${String(error)}`);
25376
25397
  }
25377
25398
  }, "create"),
25378
25399
  // Get an existing credential
25379
25400
  get: /* @__PURE__ */ __name(async (options) => {
25380
25401
  try {
25381
- return await navigator.credentials.get({ publicKey: options });
25402
+ if (!this.passkey.isSupported()) {
25403
+ throw new Error("WebAuthn is not supported in this browser");
25404
+ }
25405
+ if (!window.isSecureContext) {
25406
+ throw new Error("WebAuthn requires a secure context (HTTPS or localhost)");
25407
+ }
25408
+ const credential = await navigator.credentials.get({ publicKey: options });
25409
+ if (!credential || !(credential instanceof PublicKeyCredential)) {
25410
+ return null;
25411
+ }
25412
+ return credential;
25382
25413
  } catch (error) {
25383
- console.error("Error getting credential:", error);
25384
- return null;
25414
+ if (error instanceof Error) {
25415
+ if (error.name === "NotAllowedError") {
25416
+ throw new Error("User cancelled or denied the operation");
25417
+ } else if (error.name === "InvalidStateError") {
25418
+ throw new Error("No matching credential found");
25419
+ } else if (error.name === "NotSupportedError") {
25420
+ throw new Error("The operation is not supported");
25421
+ } else if (error.name === "SecurityError") {
25422
+ throw new Error("Security error: operation not allowed");
25423
+ }
25424
+ throw error;
25425
+ }
25426
+ throw new Error(`Error getting credential: ${String(error)}`);
25385
25427
  }
25386
25428
  }, "get"),
25387
25429
  // Check if WebAuthn is supported in the current browser
25388
25430
  isSupported: /* @__PURE__ */ __name(() => {
25389
- return !!window.PublicKeyCredential;
25431
+ return !!window.PublicKeyCredential && !!navigator.credentials;
25390
25432
  }, "isSupported"),
25391
- // Register a new credential
25392
- register: /* @__PURE__ */ __name(async (credential) => {
25393
- await navigator.credentials.store(credential);
25394
- }, "register"),
25395
- // Full test of passkey functionality
25396
- fullTest: /* @__PURE__ */ __name(async () => {
25397
- const credential = await this.passkey.create({
25398
- challenge: new Uint8Array(32),
25399
- rp: { name: "Example RP" },
25400
- user: { id: new Uint8Array(16), name: "example@example.com", displayName: "Example User" },
25401
- pubKeyCredParams: [{ type: "public-key", alg: -7 }]
25402
- });
25403
- console.log(credential);
25404
- }, "fullTest")
25433
+ // Verify a passkey signature
25434
+ verify: /* @__PURE__ */ __name(async (credential, challenge, publicKey) => {
25435
+ try {
25436
+ const response = credential.response;
25437
+ const signature = response.signature;
25438
+ const clientDataJSON = response.clientDataJSON;
25439
+ const authenticatorData = response.authenticatorData;
25440
+ const clientData = JSON.parse(new TextDecoder().decode(clientDataJSON));
25441
+ const receivedChallenge = Uint8Array.from(atob(clientData.challenge), (c) => c.charCodeAt(0));
25442
+ const expectedChallenge = challenge;
25443
+ if (receivedChallenge.length !== expectedChallenge.length) {
25444
+ return false;
25445
+ }
25446
+ for (let i = 0; i < expectedChallenge.length; i++) {
25447
+ if (receivedChallenge[i] !== expectedChallenge[i]) {
25448
+ return false;
25449
+ }
25450
+ }
25451
+ const clientDataHash = await crypto.subtle.digest("SHA-256", clientDataJSON);
25452
+ const signedData = new Uint8Array(authenticatorData.byteLength + clientDataHash.byteLength);
25453
+ signedData.set(new Uint8Array(authenticatorData), 0);
25454
+ signedData.set(new Uint8Array(clientDataHash), authenticatorData.byteLength);
25455
+ const isValid2 = await crypto.subtle.verify(
25456
+ { name: "ECDSA", hash: "SHA-256" },
25457
+ publicKey,
25458
+ signature,
25459
+ signedData
25460
+ );
25461
+ return isValid2;
25462
+ } catch (error) {
25463
+ console.error("Error verifying passkey:", error);
25464
+ return false;
25465
+ }
25466
+ }, "verify")
25405
25467
  });
25406
25468
  __publicField(this, "password", {
25407
25469
  create: /* @__PURE__ */ __name(async (options) => {
@@ -25667,9 +25729,9 @@ function arrayify$5(input) {
25667
25729
  }
25668
25730
  }
25669
25731
  __name(arrayify$5, "arrayify$5");
25670
- const csi$4 = "\x1B[";
25671
- const ansi$4 = {};
25672
- ansi$4.style = {
25732
+ const csi$5 = "\x1B[";
25733
+ const ansi$5 = {};
25734
+ ansi$5.style = {
25673
25735
  reset: "\x1B[0m",
25674
25736
  bold: "\x1B[1m",
25675
25737
  italic: "\x1B[3m",
@@ -25717,29 +25779,29 @@ ansi$4.style = {
25717
25779
  "bg-brightCyan": "\x1B[106m",
25718
25780
  "bg-brightWhite": "\x1B[107m"
25719
25781
  };
25720
- ansi$4.rgb = function(r, g2, b) {
25782
+ ansi$5.rgb = function(r, g2, b) {
25721
25783
  return `\x1B[38;2;${r};${g2};${b}m`;
25722
25784
  };
25723
- ansi$4.bgRgb = function(r, g2, b) {
25785
+ ansi$5.bgRgb = function(r, g2, b) {
25724
25786
  return `\x1B[48;2;${r};${g2};${b}m`;
25725
25787
  };
25726
- ansi$4.styles = function(styles2) {
25788
+ ansi$5.styles = function(styles2) {
25727
25789
  styles2 = arrayify$5(styles2);
25728
25790
  return styles2.map(function(effect) {
25729
25791
  const rgbMatches = effect.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
25730
25792
  const bgRgbMatches = effect.match(/bg-rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
25731
25793
  if (bgRgbMatches) {
25732
25794
  const [full, r, g2, b] = bgRgbMatches;
25733
- return ansi$4.bgRgb(r, g2, b);
25795
+ return ansi$5.bgRgb(r, g2, b);
25734
25796
  } else if (rgbMatches) {
25735
25797
  const [full, r, g2, b] = rgbMatches;
25736
- return ansi$4.rgb(r, g2, b);
25798
+ return ansi$5.rgb(r, g2, b);
25737
25799
  } else {
25738
- return ansi$4.style[effect];
25800
+ return ansi$5.style[effect];
25739
25801
  }
25740
25802
  }).join("");
25741
25803
  };
25742
- ansi$4.format = function(str, styleArray) {
25804
+ ansi$5.format = function(str, styleArray) {
25743
25805
  const re2 = /\[([\w\s-\(\),]+)\]{([^]*?)}/;
25744
25806
  let matches;
25745
25807
  str = String(str);
@@ -25747,18 +25809,18 @@ ansi$4.format = function(str, styleArray) {
25747
25809
  while (matches = str.match(re2)) {
25748
25810
  const inlineStyles = matches[1].split(/\s+/);
25749
25811
  const inlineString = matches[2];
25750
- str = str.replace(matches[0], ansi$4.format(inlineString, inlineStyles));
25812
+ str = str.replace(matches[0], ansi$5.format(inlineString, inlineStyles));
25751
25813
  }
25752
- return styleArray && styleArray.length ? ansi$4.styles(styleArray) + str + ansi$4.style.reset : str;
25814
+ return styleArray && styleArray.length ? ansi$5.styles(styleArray) + str + ansi$5.style.reset : str;
25753
25815
  };
25754
- ansi$4.cursor = {
25816
+ ansi$5.cursor = {
25755
25817
  /**
25756
25818
  * Moves the cursor `lines` cells up. If the cursor is already at the edge of the screen, this has no effect
25757
25819
  * @param [lines=1] {number}
25758
25820
  * @return {string}
25759
25821
  */
25760
25822
  up: /* @__PURE__ */ __name(function(lines) {
25761
- return csi$4 + (lines || 1) + "A";
25823
+ return csi$5 + (lines || 1) + "A";
25762
25824
  }, "up"),
25763
25825
  /**
25764
25826
  * Moves the cursor `lines` cells down. If the cursor is already at the edge of the screen, this has no effect
@@ -25766,7 +25828,7 @@ ansi$4.cursor = {
25766
25828
  * @return {string}
25767
25829
  */
25768
25830
  down: /* @__PURE__ */ __name(function(lines) {
25769
- return csi$4 + (lines || 1) + "B";
25831
+ return csi$5 + (lines || 1) + "B";
25770
25832
  }, "down"),
25771
25833
  /**
25772
25834
  * Moves the cursor `lines` cells forward. If the cursor is already at the edge of the screen, this has no effect
@@ -25774,7 +25836,7 @@ ansi$4.cursor = {
25774
25836
  * @return {string}
25775
25837
  */
25776
25838
  forward: /* @__PURE__ */ __name(function(lines) {
25777
- return csi$4 + (lines || 1) + "C";
25839
+ return csi$5 + (lines || 1) + "C";
25778
25840
  }, "forward"),
25779
25841
  /**
25780
25842
  * Moves the cursor `lines` cells back. If the cursor is already at the edge of the screen, this has no effect
@@ -25782,7 +25844,7 @@ ansi$4.cursor = {
25782
25844
  * @return {string}
25783
25845
  */
25784
25846
  back: /* @__PURE__ */ __name(function(lines) {
25785
- return csi$4 + (lines || 1) + "D";
25847
+ return csi$5 + (lines || 1) + "D";
25786
25848
  }, "back"),
25787
25849
  /**
25788
25850
  * Moves cursor to beginning of the line n lines down.
@@ -25790,7 +25852,7 @@ ansi$4.cursor = {
25790
25852
  * @return {string}
25791
25853
  */
25792
25854
  nextLine: /* @__PURE__ */ __name(function(lines) {
25793
- return csi$4 + (lines || 1) + "E";
25855
+ return csi$5 + (lines || 1) + "E";
25794
25856
  }, "nextLine"),
25795
25857
  /**
25796
25858
  * Moves cursor to beginning of the line n lines up.
@@ -25798,7 +25860,7 @@ ansi$4.cursor = {
25798
25860
  * @return {string}
25799
25861
  */
25800
25862
  previousLine: /* @__PURE__ */ __name(function(lines) {
25801
- return csi$4 + (lines || 1) + "F";
25863
+ return csi$5 + (lines || 1) + "F";
25802
25864
  }, "previousLine"),
25803
25865
  /**
25804
25866
  * Moves the cursor to column n.
@@ -25806,7 +25868,7 @@ ansi$4.cursor = {
25806
25868
  * @return {string}
25807
25869
  */
25808
25870
  horizontalAbsolute: /* @__PURE__ */ __name(function(n) {
25809
- return csi$4 + n + "G";
25871
+ return csi$5 + n + "G";
25810
25872
  }, "horizontalAbsolute"),
25811
25873
  /**
25812
25874
  * Moves the cursor to row n, column m. The values are 1-based, and default to 1 (top left corner) if omitted.
@@ -25815,25 +25877,25 @@ ansi$4.cursor = {
25815
25877
  * @return {string}
25816
25878
  */
25817
25879
  position: /* @__PURE__ */ __name(function(n, m) {
25818
- return csi$4 + (n || 1) + ";" + (m || 1) + "H";
25880
+ return csi$5 + (n || 1) + ";" + (m || 1) + "H";
25819
25881
  }, "position"),
25820
25882
  /**
25821
25883
  * Hides the cursor
25822
25884
  */
25823
- hide: csi$4 + "?25l",
25885
+ hide: csi$5 + "?25l",
25824
25886
  /**
25825
25887
  * Shows the cursor
25826
25888
  */
25827
- show: csi$4 + "?25h"
25889
+ show: csi$5 + "?25h"
25828
25890
  };
25829
- ansi$4.erase = {
25891
+ ansi$5.erase = {
25830
25892
  /**
25831
25893
  * Clears part of the screen. If n is 0 (or missing), clear from cursor to end of screen. If n is 1, clear from cursor to beginning of the screen. If n is 2, clear entire screen.
25832
25894
  * @param n {number}
25833
25895
  * @return {string}
25834
25896
  */
25835
25897
  display: /* @__PURE__ */ __name(function(n) {
25836
- return csi$4 + (n || 0) + "J";
25898
+ return csi$5 + (n || 0) + "J";
25837
25899
  }, "display"),
25838
25900
  /**
25839
25901
  * Erases part of the line. If n is zero (or missing), clear from cursor to the end of the line. If n is one, clear from cursor to beginning of the line. If n is two, clear entire line. Cursor position does not change.
@@ -25841,7 +25903,7 @@ ansi$4.erase = {
25841
25903
  * @return {string}
25842
25904
  */
25843
25905
  inLine: /* @__PURE__ */ __name(function(n) {
25844
- return csi$4 + (n || 0) + "K";
25906
+ return csi$5 + (n || 0) + "K";
25845
25907
  }, "inLine")
25846
25908
  };
25847
25909
  const pkg$b = {
@@ -25874,11 +25936,11 @@ Commands:
25874
25936
  try {
25875
25937
  switch (args[0]) {
25876
25938
  case "status":
25877
- terminal.writeln(`${ansi$4.style.bold}🔋 Battery Status:${ansi$4.style.reset}
25878
- 🔌 Charging: ${battery.charging ? ansi$4.style.green + "Yes" : ansi$4.style.red + "No"}${ansi$4.style.reset}
25879
- ⏱️ Charging Time: ${battery.chargingTime === Infinity ? ansi$4.style.gray + "N/A" : ansi$4.style.cyan + battery.chargingTime}${ansi$4.style.reset}
25880
- ⌛ Discharging Time: ${battery.dischargingTime === Infinity ? ansi$4.style.gray + "N/A" : ansi$4.style.cyan + battery.dischargingTime}${ansi$4.style.reset}
25881
- 📊 Level: ${ansi$4.style[battery.level > 0.5 ? "green" : battery.level > 0.2 ? "yellow" : "red"]}${(battery.level * 100).toFixed(1)}%${ansi$4.style.reset}`);
25939
+ terminal.writeln(`${ansi$5.style.bold}🔋 Battery Status:${ansi$5.style.reset}
25940
+ 🔌 Charging: ${battery.charging ? ansi$5.style.green + "Yes" : ansi$5.style.red + "No"}${ansi$5.style.reset}
25941
+ ⏱️ Charging Time: ${battery.chargingTime === Infinity ? ansi$5.style.gray + "N/A" : ansi$5.style.cyan + battery.chargingTime}${ansi$5.style.reset}
25942
+ ⌛ Discharging Time: ${battery.dischargingTime === Infinity ? ansi$5.style.gray + "N/A" : ansi$5.style.cyan + battery.dischargingTime}${ansi$5.style.reset}
25943
+ 📊 Level: ${ansi$5.style[battery.level > 0.5 ? "green" : battery.level > 0.2 ? "yellow" : "red"]}${(battery.level * 100).toFixed(1)}%${ansi$5.style.reset}`);
25882
25944
  break;
25883
25945
  case "charging":
25884
25946
  terminal.writeln(`${battery.charging}`);
@@ -26236,9 +26298,9 @@ function arrayify$4(input) {
26236
26298
  }
26237
26299
  }
26238
26300
  __name(arrayify$4, "arrayify$4");
26239
- const csi$3 = "\x1B[";
26240
- const ansi$3 = {};
26241
- ansi$3.style = {
26301
+ const csi$4 = "\x1B[";
26302
+ const ansi$4 = {};
26303
+ ansi$4.style = {
26242
26304
  reset: "\x1B[0m",
26243
26305
  bold: "\x1B[1m",
26244
26306
  italic: "\x1B[3m",
@@ -26286,29 +26348,29 @@ ansi$3.style = {
26286
26348
  "bg-brightCyan": "\x1B[106m",
26287
26349
  "bg-brightWhite": "\x1B[107m"
26288
26350
  };
26289
- ansi$3.rgb = function(r, g2, b) {
26351
+ ansi$4.rgb = function(r, g2, b) {
26290
26352
  return `\x1B[38;2;${r};${g2};${b}m`;
26291
26353
  };
26292
- ansi$3.bgRgb = function(r, g2, b) {
26354
+ ansi$4.bgRgb = function(r, g2, b) {
26293
26355
  return `\x1B[48;2;${r};${g2};${b}m`;
26294
26356
  };
26295
- ansi$3.styles = function(styles2) {
26357
+ ansi$4.styles = function(styles2) {
26296
26358
  styles2 = arrayify$4(styles2);
26297
26359
  return styles2.map(function(effect) {
26298
26360
  const rgbMatches = effect.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
26299
26361
  const bgRgbMatches = effect.match(/bg-rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
26300
26362
  if (bgRgbMatches) {
26301
26363
  const [full, r, g2, b] = bgRgbMatches;
26302
- return ansi$3.bgRgb(r, g2, b);
26364
+ return ansi$4.bgRgb(r, g2, b);
26303
26365
  } else if (rgbMatches) {
26304
26366
  const [full, r, g2, b] = rgbMatches;
26305
- return ansi$3.rgb(r, g2, b);
26367
+ return ansi$4.rgb(r, g2, b);
26306
26368
  } else {
26307
- return ansi$3.style[effect];
26369
+ return ansi$4.style[effect];
26308
26370
  }
26309
26371
  }).join("");
26310
26372
  };
26311
- ansi$3.format = function(str, styleArray) {
26373
+ ansi$4.format = function(str, styleArray) {
26312
26374
  const re2 = /\[([\w\s-\(\),]+)\]{([^]*?)}/;
26313
26375
  let matches;
26314
26376
  str = String(str);
@@ -26316,18 +26378,18 @@ ansi$3.format = function(str, styleArray) {
26316
26378
  while (matches = str.match(re2)) {
26317
26379
  const inlineStyles = matches[1].split(/\s+/);
26318
26380
  const inlineString = matches[2];
26319
- str = str.replace(matches[0], ansi$3.format(inlineString, inlineStyles));
26381
+ str = str.replace(matches[0], ansi$4.format(inlineString, inlineStyles));
26320
26382
  }
26321
- return styleArray && styleArray.length ? ansi$3.styles(styleArray) + str + ansi$3.style.reset : str;
26383
+ return styleArray && styleArray.length ? ansi$4.styles(styleArray) + str + ansi$4.style.reset : str;
26322
26384
  };
26323
- ansi$3.cursor = {
26385
+ ansi$4.cursor = {
26324
26386
  /**
26325
26387
  * Moves the cursor `lines` cells up. If the cursor is already at the edge of the screen, this has no effect
26326
26388
  * @param [lines=1] {number}
26327
26389
  * @return {string}
26328
26390
  */
26329
26391
  up: /* @__PURE__ */ __name(function(lines) {
26330
- return csi$3 + (lines || 1) + "A";
26392
+ return csi$4 + (lines || 1) + "A";
26331
26393
  }, "up"),
26332
26394
  /**
26333
26395
  * Moves the cursor `lines` cells down. If the cursor is already at the edge of the screen, this has no effect
@@ -26335,7 +26397,7 @@ ansi$3.cursor = {
26335
26397
  * @return {string}
26336
26398
  */
26337
26399
  down: /* @__PURE__ */ __name(function(lines) {
26338
- return csi$3 + (lines || 1) + "B";
26400
+ return csi$4 + (lines || 1) + "B";
26339
26401
  }, "down"),
26340
26402
  /**
26341
26403
  * Moves the cursor `lines` cells forward. If the cursor is already at the edge of the screen, this has no effect
@@ -26343,7 +26405,7 @@ ansi$3.cursor = {
26343
26405
  * @return {string}
26344
26406
  */
26345
26407
  forward: /* @__PURE__ */ __name(function(lines) {
26346
- return csi$3 + (lines || 1) + "C";
26408
+ return csi$4 + (lines || 1) + "C";
26347
26409
  }, "forward"),
26348
26410
  /**
26349
26411
  * Moves the cursor `lines` cells back. If the cursor is already at the edge of the screen, this has no effect
@@ -26351,7 +26413,7 @@ ansi$3.cursor = {
26351
26413
  * @return {string}
26352
26414
  */
26353
26415
  back: /* @__PURE__ */ __name(function(lines) {
26354
- return csi$3 + (lines || 1) + "D";
26416
+ return csi$4 + (lines || 1) + "D";
26355
26417
  }, "back"),
26356
26418
  /**
26357
26419
  * Moves cursor to beginning of the line n lines down.
@@ -26359,7 +26421,7 @@ ansi$3.cursor = {
26359
26421
  * @return {string}
26360
26422
  */
26361
26423
  nextLine: /* @__PURE__ */ __name(function(lines) {
26362
- return csi$3 + (lines || 1) + "E";
26424
+ return csi$4 + (lines || 1) + "E";
26363
26425
  }, "nextLine"),
26364
26426
  /**
26365
26427
  * Moves cursor to beginning of the line n lines up.
@@ -26367,7 +26429,7 @@ ansi$3.cursor = {
26367
26429
  * @return {string}
26368
26430
  */
26369
26431
  previousLine: /* @__PURE__ */ __name(function(lines) {
26370
- return csi$3 + (lines || 1) + "F";
26432
+ return csi$4 + (lines || 1) + "F";
26371
26433
  }, "previousLine"),
26372
26434
  /**
26373
26435
  * Moves the cursor to column n.
@@ -26375,7 +26437,7 @@ ansi$3.cursor = {
26375
26437
  * @return {string}
26376
26438
  */
26377
26439
  horizontalAbsolute: /* @__PURE__ */ __name(function(n) {
26378
- return csi$3 + n + "G";
26440
+ return csi$4 + n + "G";
26379
26441
  }, "horizontalAbsolute"),
26380
26442
  /**
26381
26443
  * Moves the cursor to row n, column m. The values are 1-based, and default to 1 (top left corner) if omitted.
@@ -26384,25 +26446,25 @@ ansi$3.cursor = {
26384
26446
  * @return {string}
26385
26447
  */
26386
26448
  position: /* @__PURE__ */ __name(function(n, m) {
26387
- return csi$3 + (n || 1) + ";" + (m || 1) + "H";
26449
+ return csi$4 + (n || 1) + ";" + (m || 1) + "H";
26388
26450
  }, "position"),
26389
26451
  /**
26390
26452
  * Hides the cursor
26391
26453
  */
26392
- hide: csi$3 + "?25l",
26454
+ hide: csi$4 + "?25l",
26393
26455
  /**
26394
26456
  * Shows the cursor
26395
26457
  */
26396
- show: csi$3 + "?25h"
26458
+ show: csi$4 + "?25h"
26397
26459
  };
26398
- ansi$3.erase = {
26460
+ ansi$4.erase = {
26399
26461
  /**
26400
26462
  * Clears part of the screen. If n is 0 (or missing), clear from cursor to end of screen. If n is 1, clear from cursor to beginning of the screen. If n is 2, clear entire screen.
26401
26463
  * @param n {number}
26402
26464
  * @return {string}
26403
26465
  */
26404
26466
  display: /* @__PURE__ */ __name(function(n) {
26405
- return csi$3 + (n || 0) + "J";
26467
+ return csi$4 + (n || 0) + "J";
26406
26468
  }, "display"),
26407
26469
  /**
26408
26470
  * Erases part of the line. If n is zero (or missing), clear from cursor to the end of the line. If n is one, clear from cursor to beginning of the line. If n is two, clear entire line. Cursor position does not change.
@@ -26410,7 +26472,7 @@ ansi$3.erase = {
26410
26472
  * @return {string}
26411
26473
  */
26412
26474
  inLine: /* @__PURE__ */ __name(function(n) {
26413
- return csi$3 + (n || 0) + "K";
26475
+ return csi$4 + (n || 0) + "K";
26414
26476
  }, "inLine")
26415
26477
  };
26416
26478
  const pkg$9 = {
@@ -26445,16 +26507,16 @@ Commands:
26445
26507
  terminal.writeln("No gamepads connected");
26446
26508
  break;
26447
26509
  }
26448
- terminal.writeln(`${ansi$3.style.bold}🎮 Connected Gamepads:${ansi$3.style.reset}`);
26510
+ terminal.writeln(`${ansi$4.style.bold}🎮 Connected Gamepads:${ansi$4.style.reset}`);
26449
26511
  connectedPads.forEach((gamepad2) => {
26450
26512
  if (!gamepad2)
26451
26513
  return;
26452
26514
  terminal.writeln(`
26453
- 🎮 Index: ${ansi$3.style.cyan}${gamepad2.index}${ansi$3.style.reset}
26454
- 📝 ID: ${ansi$3.style.cyan}${gamepad2.id}${ansi$3.style.reset}
26455
- 🔌 Connected: ${ansi$3.style.cyan}${gamepad2.connected}${ansi$3.style.reset}
26456
- 🎯 Buttons: ${ansi$3.style.cyan}${gamepad2.buttons.length}${ansi$3.style.reset}
26457
- 📊 Axes: ${ansi$3.style.cyan}${gamepad2.axes.length}${ansi$3.style.reset}`);
26515
+ 🎮 Index: ${ansi$4.style.cyan}${gamepad2.index}${ansi$4.style.reset}
26516
+ 📝 ID: ${ansi$4.style.cyan}${gamepad2.id}${ansi$4.style.reset}
26517
+ 🔌 Connected: ${ansi$4.style.cyan}${gamepad2.connected}${ansi$4.style.reset}
26518
+ 🎯 Buttons: ${ansi$4.style.cyan}${gamepad2.buttons.length}${ansi$4.style.reset}
26519
+ 📊 Axes: ${ansi$4.style.cyan}${gamepad2.axes.length}${ansi$4.style.reset}`);
26458
26520
  });
26459
26521
  break;
26460
26522
  case "info":
@@ -26469,7 +26531,7 @@ Commands:
26469
26531
  terminal.writeln(`No gamepad found at index ${index}`);
26470
26532
  return 1;
26471
26533
  }
26472
- terminal.writeln(`${ansi$3.style.bold}Gamepad Information:${ansi$3.style.reset}
26534
+ terminal.writeln(`${ansi$4.style.bold}Gamepad Information:${ansi$4.style.reset}
26473
26535
  Index: ${gamepad.index}
26474
26536
  ID: ${gamepad.id}
26475
26537
  Connected: ${gamepad.connected}
@@ -26529,9 +26591,9 @@ function arrayify$3(input) {
26529
26591
  }
26530
26592
  }
26531
26593
  __name(arrayify$3, "arrayify$3");
26532
- const csi$2 = "\x1B[";
26533
- const ansi$2 = {};
26534
- ansi$2.style = {
26594
+ const csi$3 = "\x1B[";
26595
+ const ansi$3 = {};
26596
+ ansi$3.style = {
26535
26597
  reset: "\x1B[0m",
26536
26598
  bold: "\x1B[1m",
26537
26599
  italic: "\x1B[3m",
@@ -26579,29 +26641,29 @@ ansi$2.style = {
26579
26641
  "bg-brightCyan": "\x1B[106m",
26580
26642
  "bg-brightWhite": "\x1B[107m"
26581
26643
  };
26582
- ansi$2.rgb = function(r, g2, b) {
26644
+ ansi$3.rgb = function(r, g2, b) {
26583
26645
  return `\x1B[38;2;${r};${g2};${b}m`;
26584
26646
  };
26585
- ansi$2.bgRgb = function(r, g2, b) {
26647
+ ansi$3.bgRgb = function(r, g2, b) {
26586
26648
  return `\x1B[48;2;${r};${g2};${b}m`;
26587
26649
  };
26588
- ansi$2.styles = function(styles2) {
26650
+ ansi$3.styles = function(styles2) {
26589
26651
  styles2 = arrayify$3(styles2);
26590
26652
  return styles2.map(function(effect) {
26591
26653
  const rgbMatches = effect.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
26592
26654
  const bgRgbMatches = effect.match(/bg-rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
26593
26655
  if (bgRgbMatches) {
26594
26656
  const [full, r, g2, b] = bgRgbMatches;
26595
- return ansi$2.bgRgb(r, g2, b);
26657
+ return ansi$3.bgRgb(r, g2, b);
26596
26658
  } else if (rgbMatches) {
26597
26659
  const [full, r, g2, b] = rgbMatches;
26598
- return ansi$2.rgb(r, g2, b);
26660
+ return ansi$3.rgb(r, g2, b);
26599
26661
  } else {
26600
- return ansi$2.style[effect];
26662
+ return ansi$3.style[effect];
26601
26663
  }
26602
26664
  }).join("");
26603
26665
  };
26604
- ansi$2.format = function(str, styleArray) {
26666
+ ansi$3.format = function(str, styleArray) {
26605
26667
  const re2 = /\[([\w\s-\(\),]+)\]{([^]*?)}/;
26606
26668
  let matches;
26607
26669
  str = String(str);
@@ -26609,18 +26671,18 @@ ansi$2.format = function(str, styleArray) {
26609
26671
  while (matches = str.match(re2)) {
26610
26672
  const inlineStyles = matches[1].split(/\s+/);
26611
26673
  const inlineString = matches[2];
26612
- str = str.replace(matches[0], ansi$2.format(inlineString, inlineStyles));
26674
+ str = str.replace(matches[0], ansi$3.format(inlineString, inlineStyles));
26613
26675
  }
26614
- return styleArray && styleArray.length ? ansi$2.styles(styleArray) + str + ansi$2.style.reset : str;
26676
+ return styleArray && styleArray.length ? ansi$3.styles(styleArray) + str + ansi$3.style.reset : str;
26615
26677
  };
26616
- ansi$2.cursor = {
26678
+ ansi$3.cursor = {
26617
26679
  /**
26618
26680
  * Moves the cursor `lines` cells up. If the cursor is already at the edge of the screen, this has no effect
26619
26681
  * @param [lines=1] {number}
26620
26682
  * @return {string}
26621
26683
  */
26622
26684
  up: /* @__PURE__ */ __name(function(lines) {
26623
- return csi$2 + (lines || 1) + "A";
26685
+ return csi$3 + (lines || 1) + "A";
26624
26686
  }, "up"),
26625
26687
  /**
26626
26688
  * Moves the cursor `lines` cells down. If the cursor is already at the edge of the screen, this has no effect
@@ -26628,7 +26690,7 @@ ansi$2.cursor = {
26628
26690
  * @return {string}
26629
26691
  */
26630
26692
  down: /* @__PURE__ */ __name(function(lines) {
26631
- return csi$2 + (lines || 1) + "B";
26693
+ return csi$3 + (lines || 1) + "B";
26632
26694
  }, "down"),
26633
26695
  /**
26634
26696
  * Moves the cursor `lines` cells forward. If the cursor is already at the edge of the screen, this has no effect
@@ -26636,7 +26698,7 @@ ansi$2.cursor = {
26636
26698
  * @return {string}
26637
26699
  */
26638
26700
  forward: /* @__PURE__ */ __name(function(lines) {
26639
- return csi$2 + (lines || 1) + "C";
26701
+ return csi$3 + (lines || 1) + "C";
26640
26702
  }, "forward"),
26641
26703
  /**
26642
26704
  * Moves the cursor `lines` cells back. If the cursor is already at the edge of the screen, this has no effect
@@ -26644,7 +26706,7 @@ ansi$2.cursor = {
26644
26706
  * @return {string}
26645
26707
  */
26646
26708
  back: /* @__PURE__ */ __name(function(lines) {
26647
- return csi$2 + (lines || 1) + "D";
26709
+ return csi$3 + (lines || 1) + "D";
26648
26710
  }, "back"),
26649
26711
  /**
26650
26712
  * Moves cursor to beginning of the line n lines down.
@@ -26652,7 +26714,7 @@ ansi$2.cursor = {
26652
26714
  * @return {string}
26653
26715
  */
26654
26716
  nextLine: /* @__PURE__ */ __name(function(lines) {
26655
- return csi$2 + (lines || 1) + "E";
26717
+ return csi$3 + (lines || 1) + "E";
26656
26718
  }, "nextLine"),
26657
26719
  /**
26658
26720
  * Moves cursor to beginning of the line n lines up.
@@ -26660,7 +26722,7 @@ ansi$2.cursor = {
26660
26722
  * @return {string}
26661
26723
  */
26662
26724
  previousLine: /* @__PURE__ */ __name(function(lines) {
26663
- return csi$2 + (lines || 1) + "F";
26725
+ return csi$3 + (lines || 1) + "F";
26664
26726
  }, "previousLine"),
26665
26727
  /**
26666
26728
  * Moves the cursor to column n.
@@ -26668,7 +26730,7 @@ ansi$2.cursor = {
26668
26730
  * @return {string}
26669
26731
  */
26670
26732
  horizontalAbsolute: /* @__PURE__ */ __name(function(n) {
26671
- return csi$2 + n + "G";
26733
+ return csi$3 + n + "G";
26672
26734
  }, "horizontalAbsolute"),
26673
26735
  /**
26674
26736
  * Moves the cursor to row n, column m. The values are 1-based, and default to 1 (top left corner) if omitted.
@@ -26677,25 +26739,25 @@ ansi$2.cursor = {
26677
26739
  * @return {string}
26678
26740
  */
26679
26741
  position: /* @__PURE__ */ __name(function(n, m) {
26680
- return csi$2 + (n || 1) + ";" + (m || 1) + "H";
26742
+ return csi$3 + (n || 1) + ";" + (m || 1) + "H";
26681
26743
  }, "position"),
26682
26744
  /**
26683
26745
  * Hides the cursor
26684
26746
  */
26685
- hide: csi$2 + "?25l",
26747
+ hide: csi$3 + "?25l",
26686
26748
  /**
26687
26749
  * Shows the cursor
26688
26750
  */
26689
- show: csi$2 + "?25h"
26751
+ show: csi$3 + "?25h"
26690
26752
  };
26691
- ansi$2.erase = {
26753
+ ansi$3.erase = {
26692
26754
  /**
26693
26755
  * Clears part of the screen. If n is 0 (or missing), clear from cursor to end of screen. If n is 1, clear from cursor to beginning of the screen. If n is 2, clear entire screen.
26694
26756
  * @param n {number}
26695
26757
  * @return {string}
26696
26758
  */
26697
26759
  display: /* @__PURE__ */ __name(function(n) {
26698
- return csi$2 + (n || 0) + "J";
26760
+ return csi$3 + (n || 0) + "J";
26699
26761
  }, "display"),
26700
26762
  /**
26701
26763
  * Erases part of the line. If n is zero (or missing), clear from cursor to the end of the line. If n is one, clear from cursor to beginning of the line. If n is two, clear entire line. Cursor position does not change.
@@ -26703,7 +26765,7 @@ ansi$2.erase = {
26703
26765
  * @return {string}
26704
26766
  */
26705
26767
  inLine: /* @__PURE__ */ __name(function(n) {
26706
- return csi$2 + (n || 0) + "K";
26768
+ return csi$3 + (n || 0) + "K";
26707
26769
  }, "inLine")
26708
26770
  };
26709
26771
  const pkg$8 = {
@@ -26736,14 +26798,14 @@ Commands:
26736
26798
  const position = await new Promise((resolve2, reject) => {
26737
26799
  navigator.geolocation.getCurrentPosition(resolve2, reject);
26738
26800
  });
26739
- terminal.writeln(`${ansi$2.style.bold}📍 Current Position:${ansi$2.style.reset}
26740
- 🌍 Latitude: ${ansi$2.style.cyan}${position.coords.latitude}${ansi$2.style.reset}
26741
- 🌍 Longitude: ${ansi$2.style.cyan}${position.coords.longitude}${ansi$2.style.reset}
26742
- 📏 Accuracy: ${ansi$2.style.cyan}${position.coords.accuracy}m${ansi$2.style.reset}
26743
- 🏔️ Altitude: ${position.coords.altitude ? ansi$2.style.cyan + position.coords.altitude + "m" : ansi$2.style.gray + "N/A"}${ansi$2.style.reset}
26744
- 🎯 Altitude Accuracy: ${position.coords.altitudeAccuracy ? ansi$2.style.cyan + position.coords.altitudeAccuracy + "m" : ansi$2.style.gray + "N/A"}${ansi$2.style.reset}
26745
- 🧭 Heading: ${position.coords.heading ? ansi$2.style.cyan + position.coords.heading + "°" : ansi$2.style.gray + "N/A"}${ansi$2.style.reset}
26746
- 🚀 Speed: ${position.coords.speed ? ansi$2.style.cyan + position.coords.speed + "m/s" : ansi$2.style.gray + "N/A"}${ansi$2.style.reset}`);
26801
+ terminal.writeln(`${ansi$3.style.bold}📍 Current Position:${ansi$3.style.reset}
26802
+ 🌍 Latitude: ${ansi$3.style.cyan}${position.coords.latitude}${ansi$3.style.reset}
26803
+ 🌍 Longitude: ${ansi$3.style.cyan}${position.coords.longitude}${ansi$3.style.reset}
26804
+ 📏 Accuracy: ${ansi$3.style.cyan}${position.coords.accuracy}m${ansi$3.style.reset}
26805
+ 🏔️ Altitude: ${position.coords.altitude ? ansi$3.style.cyan + position.coords.altitude + "m" : ansi$3.style.gray + "N/A"}${ansi$3.style.reset}
26806
+ 🎯 Altitude Accuracy: ${position.coords.altitudeAccuracy ? ansi$3.style.cyan + position.coords.altitudeAccuracy + "m" : ansi$3.style.gray + "N/A"}${ansi$3.style.reset}
26807
+ 🧭 Heading: ${position.coords.heading ? ansi$3.style.cyan + position.coords.heading + "°" : ansi$3.style.gray + "N/A"}${ansi$3.style.reset}
26808
+ 🚀 Speed: ${position.coords.speed ? ansi$3.style.cyan + position.coords.speed + "m/s" : ansi$3.style.gray + "N/A"}${ansi$3.style.reset}`);
26747
26809
  break;
26748
26810
  case "watch":
26749
26811
  const watchId = navigator.geolocation.watchPosition(
@@ -27009,9 +27071,9 @@ function arrayify$2(input) {
27009
27071
  }
27010
27072
  }
27011
27073
  __name(arrayify$2, "arrayify$2");
27012
- const csi$1 = "\x1B[";
27013
- const ansi$1 = {};
27014
- ansi$1.style = {
27074
+ const csi$2 = "\x1B[";
27075
+ const ansi$2 = {};
27076
+ ansi$2.style = {
27015
27077
  reset: "\x1B[0m",
27016
27078
  bold: "\x1B[1m",
27017
27079
  italic: "\x1B[3m",
@@ -27059,29 +27121,29 @@ ansi$1.style = {
27059
27121
  "bg-brightCyan": "\x1B[106m",
27060
27122
  "bg-brightWhite": "\x1B[107m"
27061
27123
  };
27062
- ansi$1.rgb = function(r, g2, b) {
27124
+ ansi$2.rgb = function(r, g2, b) {
27063
27125
  return `\x1B[38;2;${r};${g2};${b}m`;
27064
27126
  };
27065
- ansi$1.bgRgb = function(r, g2, b) {
27127
+ ansi$2.bgRgb = function(r, g2, b) {
27066
27128
  return `\x1B[48;2;${r};${g2};${b}m`;
27067
27129
  };
27068
- ansi$1.styles = function(styles2) {
27130
+ ansi$2.styles = function(styles2) {
27069
27131
  styles2 = arrayify$2(styles2);
27070
27132
  return styles2.map(function(effect) {
27071
27133
  const rgbMatches = effect.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
27072
27134
  const bgRgbMatches = effect.match(/bg-rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
27073
27135
  if (bgRgbMatches) {
27074
27136
  const [full, r, g2, b] = bgRgbMatches;
27075
- return ansi$1.bgRgb(r, g2, b);
27137
+ return ansi$2.bgRgb(r, g2, b);
27076
27138
  } else if (rgbMatches) {
27077
27139
  const [full, r, g2, b] = rgbMatches;
27078
- return ansi$1.rgb(r, g2, b);
27140
+ return ansi$2.rgb(r, g2, b);
27079
27141
  } else {
27080
- return ansi$1.style[effect];
27142
+ return ansi$2.style[effect];
27081
27143
  }
27082
27144
  }).join("");
27083
27145
  };
27084
- ansi$1.format = function(str, styleArray) {
27146
+ ansi$2.format = function(str, styleArray) {
27085
27147
  const re2 = /\[([\w\s-\(\),]+)\]{([^]*?)}/;
27086
27148
  let matches;
27087
27149
  str = String(str);
@@ -27089,18 +27151,18 @@ ansi$1.format = function(str, styleArray) {
27089
27151
  while (matches = str.match(re2)) {
27090
27152
  const inlineStyles = matches[1].split(/\s+/);
27091
27153
  const inlineString = matches[2];
27092
- str = str.replace(matches[0], ansi$1.format(inlineString, inlineStyles));
27154
+ str = str.replace(matches[0], ansi$2.format(inlineString, inlineStyles));
27093
27155
  }
27094
- return styleArray && styleArray.length ? ansi$1.styles(styleArray) + str + ansi$1.style.reset : str;
27156
+ return styleArray && styleArray.length ? ansi$2.styles(styleArray) + str + ansi$2.style.reset : str;
27095
27157
  };
27096
- ansi$1.cursor = {
27158
+ ansi$2.cursor = {
27097
27159
  /**
27098
27160
  * Moves the cursor `lines` cells up. If the cursor is already at the edge of the screen, this has no effect
27099
27161
  * @param [lines=1] {number}
27100
27162
  * @return {string}
27101
27163
  */
27102
27164
  up: /* @__PURE__ */ __name(function(lines) {
27103
- return csi$1 + (lines || 1) + "A";
27165
+ return csi$2 + (lines || 1) + "A";
27104
27166
  }, "up"),
27105
27167
  /**
27106
27168
  * Moves the cursor `lines` cells down. If the cursor is already at the edge of the screen, this has no effect
@@ -27108,7 +27170,7 @@ ansi$1.cursor = {
27108
27170
  * @return {string}
27109
27171
  */
27110
27172
  down: /* @__PURE__ */ __name(function(lines) {
27111
- return csi$1 + (lines || 1) + "B";
27173
+ return csi$2 + (lines || 1) + "B";
27112
27174
  }, "down"),
27113
27175
  /**
27114
27176
  * Moves the cursor `lines` cells forward. If the cursor is already at the edge of the screen, this has no effect
@@ -27116,7 +27178,7 @@ ansi$1.cursor = {
27116
27178
  * @return {string}
27117
27179
  */
27118
27180
  forward: /* @__PURE__ */ __name(function(lines) {
27119
- return csi$1 + (lines || 1) + "C";
27181
+ return csi$2 + (lines || 1) + "C";
27120
27182
  }, "forward"),
27121
27183
  /**
27122
27184
  * Moves the cursor `lines` cells back. If the cursor is already at the edge of the screen, this has no effect
@@ -27124,7 +27186,7 @@ ansi$1.cursor = {
27124
27186
  * @return {string}
27125
27187
  */
27126
27188
  back: /* @__PURE__ */ __name(function(lines) {
27127
- return csi$1 + (lines || 1) + "D";
27189
+ return csi$2 + (lines || 1) + "D";
27128
27190
  }, "back"),
27129
27191
  /**
27130
27192
  * Moves cursor to beginning of the line n lines down.
@@ -27132,7 +27194,7 @@ ansi$1.cursor = {
27132
27194
  * @return {string}
27133
27195
  */
27134
27196
  nextLine: /* @__PURE__ */ __name(function(lines) {
27135
- return csi$1 + (lines || 1) + "E";
27197
+ return csi$2 + (lines || 1) + "E";
27136
27198
  }, "nextLine"),
27137
27199
  /**
27138
27200
  * Moves cursor to beginning of the line n lines up.
@@ -27140,7 +27202,7 @@ ansi$1.cursor = {
27140
27202
  * @return {string}
27141
27203
  */
27142
27204
  previousLine: /* @__PURE__ */ __name(function(lines) {
27143
- return csi$1 + (lines || 1) + "F";
27205
+ return csi$2 + (lines || 1) + "F";
27144
27206
  }, "previousLine"),
27145
27207
  /**
27146
27208
  * Moves the cursor to column n.
@@ -27148,7 +27210,7 @@ ansi$1.cursor = {
27148
27210
  * @return {string}
27149
27211
  */
27150
27212
  horizontalAbsolute: /* @__PURE__ */ __name(function(n) {
27151
- return csi$1 + n + "G";
27213
+ return csi$2 + n + "G";
27152
27214
  }, "horizontalAbsolute"),
27153
27215
  /**
27154
27216
  * Moves the cursor to row n, column m. The values are 1-based, and default to 1 (top left corner) if omitted.
@@ -27157,25 +27219,25 @@ ansi$1.cursor = {
27157
27219
  * @return {string}
27158
27220
  */
27159
27221
  position: /* @__PURE__ */ __name(function(n, m) {
27160
- return csi$1 + (n || 1) + ";" + (m || 1) + "H";
27222
+ return csi$2 + (n || 1) + ";" + (m || 1) + "H";
27161
27223
  }, "position"),
27162
27224
  /**
27163
27225
  * Hides the cursor
27164
27226
  */
27165
- hide: csi$1 + "?25l",
27227
+ hide: csi$2 + "?25l",
27166
27228
  /**
27167
27229
  * Shows the cursor
27168
27230
  */
27169
- show: csi$1 + "?25h"
27231
+ show: csi$2 + "?25h"
27170
27232
  };
27171
- ansi$1.erase = {
27233
+ ansi$2.erase = {
27172
27234
  /**
27173
27235
  * Clears part of the screen. If n is 0 (or missing), clear from cursor to end of screen. If n is 1, clear from cursor to beginning of the screen. If n is 2, clear entire screen.
27174
27236
  * @param n {number}
27175
27237
  * @return {string}
27176
27238
  */
27177
27239
  display: /* @__PURE__ */ __name(function(n) {
27178
- return csi$1 + (n || 0) + "J";
27240
+ return csi$2 + (n || 0) + "J";
27179
27241
  }, "display"),
27180
27242
  /**
27181
27243
  * Erases part of the line. If n is zero (or missing), clear from cursor to the end of the line. If n is one, clear from cursor to beginning of the line. If n is two, clear entire line. Cursor position does not change.
@@ -27183,7 +27245,7 @@ ansi$1.erase = {
27183
27245
  * @return {string}
27184
27246
  */
27185
27247
  inLine: /* @__PURE__ */ __name(function(n) {
27186
- return csi$1 + (n || 0) + "K";
27248
+ return csi$2 + (n || 0) + "K";
27187
27249
  }, "inLine")
27188
27250
  };
27189
27251
  const pkg$6 = {
@@ -27223,13 +27285,13 @@ Commands:
27223
27285
  terminal.writeln("No HID devices connected");
27224
27286
  break;
27225
27287
  }
27226
- terminal.writeln(`${ansi$1.style.bold}🎮 Connected HID Devices:${ansi$1.style.reset}`);
27288
+ terminal.writeln(`${ansi$2.style.bold}🎮 Connected HID Devices:${ansi$2.style.reset}`);
27227
27289
  uniqueDevices.forEach((device2) => {
27228
27290
  terminal.writeln(`
27229
- 📱 Device ID: ${ansi$1.style.cyan}${device2.productId}${ansi$1.style.reset}
27230
- 📝 Name: ${ansi$1.style.cyan}${device2.productName}${ansi$1.style.reset}
27231
- 🏢 Manufacturer: ${ansi$1.style.cyan}${device2.vendorId}${ansi$1.style.reset}
27232
- 🔌 Connected: ${ansi$1.style.cyan}${device2.opened ? "Yes" : "No"}${ansi$1.style.reset}`);
27291
+ 📱 Device ID: ${ansi$2.style.cyan}${device2.productId}${ansi$2.style.reset}
27292
+ 📝 Name: ${ansi$2.style.cyan}${device2.productName}${ansi$2.style.reset}
27293
+ 🏢 Manufacturer: ${ansi$2.style.cyan}${device2.vendorId}${ansi$2.style.reset}
27294
+ 🔌 Connected: ${ansi$2.style.cyan}${device2.opened ? "Yes" : "No"}${ansi$2.style.reset}`);
27233
27295
  });
27234
27296
  break;
27235
27297
  case "request":
@@ -27286,7 +27348,7 @@ Commands:
27286
27348
  terminal.writeln(`Device with ID ${args[1]} not found`);
27287
27349
  return 1;
27288
27350
  }
27289
- terminal.writeln(`${ansi$1.style.bold}Device Information:${ansi$1.style.reset}
27351
+ terminal.writeln(`${ansi$2.style.bold}Device Information:${ansi$2.style.reset}
27290
27352
  Product ID: ${targetDevice.productId}
27291
27353
  Vendor ID: ${targetDevice.vendorId}
27292
27354
  Product Name: ${targetDevice.productName}
@@ -27627,9 +27689,9 @@ function arrayify$1(input) {
27627
27689
  }
27628
27690
  }
27629
27691
  __name(arrayify$1, "arrayify$1");
27630
- const csi = "\x1B[";
27631
- const ansi = {};
27632
- ansi.style = {
27692
+ const csi$1 = "\x1B[";
27693
+ const ansi$1 = {};
27694
+ ansi$1.style = {
27633
27695
  reset: "\x1B[0m",
27634
27696
  bold: "\x1B[1m",
27635
27697
  italic: "\x1B[3m",
@@ -27677,29 +27739,29 @@ ansi.style = {
27677
27739
  "bg-brightCyan": "\x1B[106m",
27678
27740
  "bg-brightWhite": "\x1B[107m"
27679
27741
  };
27680
- ansi.rgb = function(r, g2, b) {
27742
+ ansi$1.rgb = function(r, g2, b) {
27681
27743
  return `\x1B[38;2;${r};${g2};${b}m`;
27682
27744
  };
27683
- ansi.bgRgb = function(r, g2, b) {
27745
+ ansi$1.bgRgb = function(r, g2, b) {
27684
27746
  return `\x1B[48;2;${r};${g2};${b}m`;
27685
27747
  };
27686
- ansi.styles = function(styles2) {
27748
+ ansi$1.styles = function(styles2) {
27687
27749
  styles2 = arrayify$1(styles2);
27688
27750
  return styles2.map(function(effect) {
27689
27751
  const rgbMatches = effect.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
27690
27752
  const bgRgbMatches = effect.match(/bg-rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
27691
27753
  if (bgRgbMatches) {
27692
27754
  const [full, r, g2, b] = bgRgbMatches;
27693
- return ansi.bgRgb(r, g2, b);
27755
+ return ansi$1.bgRgb(r, g2, b);
27694
27756
  } else if (rgbMatches) {
27695
27757
  const [full, r, g2, b] = rgbMatches;
27696
- return ansi.rgb(r, g2, b);
27758
+ return ansi$1.rgb(r, g2, b);
27697
27759
  } else {
27698
- return ansi.style[effect];
27760
+ return ansi$1.style[effect];
27699
27761
  }
27700
27762
  }).join("");
27701
27763
  };
27702
- ansi.format = function(str, styleArray) {
27764
+ ansi$1.format = function(str, styleArray) {
27703
27765
  const re2 = /\[([\w\s-\(\),]+)\]{([^]*?)}/;
27704
27766
  let matches;
27705
27767
  str = String(str);
@@ -27707,18 +27769,18 @@ ansi.format = function(str, styleArray) {
27707
27769
  while (matches = str.match(re2)) {
27708
27770
  const inlineStyles = matches[1].split(/\s+/);
27709
27771
  const inlineString = matches[2];
27710
- str = str.replace(matches[0], ansi.format(inlineString, inlineStyles));
27772
+ str = str.replace(matches[0], ansi$1.format(inlineString, inlineStyles));
27711
27773
  }
27712
- return styleArray && styleArray.length ? ansi.styles(styleArray) + str + ansi.style.reset : str;
27774
+ return styleArray && styleArray.length ? ansi$1.styles(styleArray) + str + ansi$1.style.reset : str;
27713
27775
  };
27714
- ansi.cursor = {
27776
+ ansi$1.cursor = {
27715
27777
  /**
27716
27778
  * Moves the cursor `lines` cells up. If the cursor is already at the edge of the screen, this has no effect
27717
27779
  * @param [lines=1] {number}
27718
27780
  * @return {string}
27719
27781
  */
27720
27782
  up: /* @__PURE__ */ __name(function(lines) {
27721
- return csi + (lines || 1) + "A";
27783
+ return csi$1 + (lines || 1) + "A";
27722
27784
  }, "up"),
27723
27785
  /**
27724
27786
  * Moves the cursor `lines` cells down. If the cursor is already at the edge of the screen, this has no effect
@@ -27726,7 +27788,7 @@ ansi.cursor = {
27726
27788
  * @return {string}
27727
27789
  */
27728
27790
  down: /* @__PURE__ */ __name(function(lines) {
27729
- return csi + (lines || 1) + "B";
27791
+ return csi$1 + (lines || 1) + "B";
27730
27792
  }, "down"),
27731
27793
  /**
27732
27794
  * Moves the cursor `lines` cells forward. If the cursor is already at the edge of the screen, this has no effect
@@ -27734,7 +27796,7 @@ ansi.cursor = {
27734
27796
  * @return {string}
27735
27797
  */
27736
27798
  forward: /* @__PURE__ */ __name(function(lines) {
27737
- return csi + (lines || 1) + "C";
27799
+ return csi$1 + (lines || 1) + "C";
27738
27800
  }, "forward"),
27739
27801
  /**
27740
27802
  * Moves the cursor `lines` cells back. If the cursor is already at the edge of the screen, this has no effect
@@ -27742,7 +27804,7 @@ ansi.cursor = {
27742
27804
  * @return {string}
27743
27805
  */
27744
27806
  back: /* @__PURE__ */ __name(function(lines) {
27745
- return csi + (lines || 1) + "D";
27807
+ return csi$1 + (lines || 1) + "D";
27746
27808
  }, "back"),
27747
27809
  /**
27748
27810
  * Moves cursor to beginning of the line n lines down.
@@ -27750,7 +27812,7 @@ ansi.cursor = {
27750
27812
  * @return {string}
27751
27813
  */
27752
27814
  nextLine: /* @__PURE__ */ __name(function(lines) {
27753
- return csi + (lines || 1) + "E";
27815
+ return csi$1 + (lines || 1) + "E";
27754
27816
  }, "nextLine"),
27755
27817
  /**
27756
27818
  * Moves cursor to beginning of the line n lines up.
@@ -27758,7 +27820,7 @@ ansi.cursor = {
27758
27820
  * @return {string}
27759
27821
  */
27760
27822
  previousLine: /* @__PURE__ */ __name(function(lines) {
27761
- return csi + (lines || 1) + "F";
27823
+ return csi$1 + (lines || 1) + "F";
27762
27824
  }, "previousLine"),
27763
27825
  /**
27764
27826
  * Moves the cursor to column n.
@@ -27766,7 +27828,7 @@ ansi.cursor = {
27766
27828
  * @return {string}
27767
27829
  */
27768
27830
  horizontalAbsolute: /* @__PURE__ */ __name(function(n) {
27769
- return csi + n + "G";
27831
+ return csi$1 + n + "G";
27770
27832
  }, "horizontalAbsolute"),
27771
27833
  /**
27772
27834
  * Moves the cursor to row n, column m. The values are 1-based, and default to 1 (top left corner) if omitted.
@@ -27775,25 +27837,25 @@ ansi.cursor = {
27775
27837
  * @return {string}
27776
27838
  */
27777
27839
  position: /* @__PURE__ */ __name(function(n, m) {
27778
- return csi + (n || 1) + ";" + (m || 1) + "H";
27840
+ return csi$1 + (n || 1) + ";" + (m || 1) + "H";
27779
27841
  }, "position"),
27780
27842
  /**
27781
27843
  * Hides the cursor
27782
27844
  */
27783
- hide: csi + "?25l",
27845
+ hide: csi$1 + "?25l",
27784
27846
  /**
27785
27847
  * Shows the cursor
27786
27848
  */
27787
- show: csi + "?25h"
27849
+ show: csi$1 + "?25h"
27788
27850
  };
27789
- ansi.erase = {
27851
+ ansi$1.erase = {
27790
27852
  /**
27791
27853
  * Clears part of the screen. If n is 0 (or missing), clear from cursor to end of screen. If n is 1, clear from cursor to beginning of the screen. If n is 2, clear entire screen.
27792
27854
  * @param n {number}
27793
27855
  * @return {string}
27794
27856
  */
27795
27857
  display: /* @__PURE__ */ __name(function(n) {
27796
- return csi + (n || 0) + "J";
27858
+ return csi$1 + (n || 0) + "J";
27797
27859
  }, "display"),
27798
27860
  /**
27799
27861
  * Erases part of the line. If n is zero (or missing), clear from cursor to the end of the line. If n is one, clear from cursor to beginning of the line. If n is two, clear entire line. Cursor position does not change.
@@ -27801,7 +27863,7 @@ ansi.erase = {
27801
27863
  * @return {string}
27802
27864
  */
27803
27865
  inLine: /* @__PURE__ */ __name(function(n) {
27804
- return csi + (n || 0) + "K";
27866
+ return csi$1 + (n || 0) + "K";
27805
27867
  }, "inLine")
27806
27868
  };
27807
27869
  const pkg$3 = {
@@ -27833,7 +27895,7 @@ Commands:
27833
27895
  if ("Gyroscope" in globalThis) sensors.push("gyroscope");
27834
27896
  if ("LinearAccelerationSensor" in globalThis) sensors.push("linear");
27835
27897
  if ("AbsoluteOrientationSensor" in globalThis) sensors.push("orientation");
27836
- terminal.writeln(`${ansi.style.bold}📱 Available Sensors:${ansi.style.reset}`);
27898
+ terminal.writeln(`${ansi$1.style.bold}📱 Available Sensors:${ansi$1.style.reset}`);
27837
27899
  sensors.forEach((sensor2) => terminal.writeln(` - ${sensor2}`));
27838
27900
  break;
27839
27901
  case "read":
@@ -28060,27 +28122,27 @@ function displaySensorData(sensor, sensorType, terminal) {
28060
28122
  switch (sensorType) {
28061
28123
  case "accelerometer":
28062
28124
  case "linear":
28063
- terminal.writeln(`${ansi.style.bold}📊 ${sensorType.charAt(0).toUpperCase() + sensorType.slice(1)} Reading:${ansi.style.reset}
28064
- 🕒 Time: ${ansi.style.cyan}${timestamp}${ansi.style.reset}
28065
- X: ${ansi.style.cyan}${sensor.x.toFixed(2)}${ansi.style.reset} m/s²
28066
- Y: ${ansi.style.cyan}${sensor.y.toFixed(2)}${ansi.style.reset} m/s²
28067
- Z: ${ansi.style.cyan}${sensor.z.toFixed(2)}${ansi.style.reset} m/s²`);
28125
+ terminal.writeln(`${ansi$1.style.bold}📊 ${sensorType.charAt(0).toUpperCase() + sensorType.slice(1)} Reading:${ansi$1.style.reset}
28126
+ 🕒 Time: ${ansi$1.style.cyan}${timestamp}${ansi$1.style.reset}
28127
+ X: ${ansi$1.style.cyan}${sensor.x.toFixed(2)}${ansi$1.style.reset} m/s²
28128
+ Y: ${ansi$1.style.cyan}${sensor.y.toFixed(2)}${ansi$1.style.reset} m/s²
28129
+ Z: ${ansi$1.style.cyan}${sensor.z.toFixed(2)}${ansi$1.style.reset} m/s²`);
28068
28130
  break;
28069
28131
  case "gyroscope":
28070
- terminal.writeln(`${ansi.style.bold}📊 Gyroscope Reading:${ansi.style.reset}
28071
- 🕒 Time: ${ansi.style.cyan}${timestamp}${ansi.style.reset}
28072
- X: ${ansi.style.cyan}${sensor.x.toFixed(2)}${ansi.style.reset} rad/s
28073
- Y: ${ansi.style.cyan}${sensor.y.toFixed(2)}${ansi.style.reset} rad/s
28074
- Z: ${ansi.style.cyan}${sensor.z.toFixed(2)}${ansi.style.reset} rad/s`);
28132
+ terminal.writeln(`${ansi$1.style.bold}📊 Gyroscope Reading:${ansi$1.style.reset}
28133
+ 🕒 Time: ${ansi$1.style.cyan}${timestamp}${ansi$1.style.reset}
28134
+ X: ${ansi$1.style.cyan}${sensor.x.toFixed(2)}${ansi$1.style.reset} rad/s
28135
+ Y: ${ansi$1.style.cyan}${sensor.y.toFixed(2)}${ansi$1.style.reset} rad/s
28136
+ Z: ${ansi$1.style.cyan}${sensor.z.toFixed(2)}${ansi$1.style.reset} rad/s`);
28075
28137
  break;
28076
28138
  case "orientation":
28077
- terminal.writeln(`${ansi.style.bold}📊 Orientation Reading:${ansi.style.reset}
28078
- 🕒 Time: ${ansi.style.cyan}${timestamp}${ansi.style.reset}
28139
+ terminal.writeln(`${ansi$1.style.bold}📊 Orientation Reading:${ansi$1.style.reset}
28140
+ 🕒 Time: ${ansi$1.style.cyan}${timestamp}${ansi$1.style.reset}
28079
28141
  Quaternion:
28080
- X: ${ansi.style.cyan}${sensor.quaternion[0].toFixed(3)}${ansi.style.reset}
28081
- Y: ${ansi.style.cyan}${sensor.quaternion[1].toFixed(3)}${ansi.style.reset}
28082
- Z: ${ansi.style.cyan}${sensor.quaternion[2].toFixed(3)}${ansi.style.reset}
28083
- W: ${ansi.style.cyan}${sensor.quaternion[3].toFixed(3)}${ansi.style.reset}`);
28142
+ X: ${ansi$1.style.cyan}${sensor.quaternion[0].toFixed(3)}${ansi$1.style.reset}
28143
+ Y: ${ansi$1.style.cyan}${sensor.quaternion[1].toFixed(3)}${ansi$1.style.reset}
28144
+ Z: ${ansi$1.style.cyan}${sensor.quaternion[2].toFixed(3)}${ansi$1.style.reset}
28145
+ W: ${ansi$1.style.cyan}${sensor.quaternion[3].toFixed(3)}${ansi$1.style.reset}`);
28084
28146
  break;
28085
28147
  }
28086
28148
  }
@@ -28559,7 +28621,7 @@ const _Dom = class _Dom {
28559
28621
  }
28560
28622
  async topbar(show) {
28561
28623
  if (!this._topbar) return;
28562
- const { default: topbar } = await import("./topbar.min-BbHcCmce.js").then((n) => n.t);
28624
+ const { default: topbar } = await import("./topbar.min-D7kPyIYf.js").then((n) => n.t);
28563
28625
  this._topbarShow = show ?? !this._topbarShow;
28564
28626
  if (this._topbarShow) topbar.show();
28565
28627
  else topbar.hide();
@@ -59629,7 +59691,7 @@ const _TerminalCommand = class _TerminalCommand {
59629
59691
  };
59630
59692
  __name(_TerminalCommand, "TerminalCommand");
59631
59693
  let TerminalCommand = _TerminalCommand;
59632
- function createCommand$d(kernel, shell, terminal) {
59694
+ function createCommand$i(kernel, shell, terminal) {
59633
59695
  return new TerminalCommand({
59634
59696
  command: "cat",
59635
59697
  description: "Concatenate files and print on the standard output",
@@ -59713,8 +59775,8 @@ function createCommand$d(kernel, shell, terminal) {
59713
59775
  }, "run")
59714
59776
  });
59715
59777
  }
59716
- __name(createCommand$d, "createCommand$d");
59717
- function createCommand$c(kernel, shell, terminal) {
59778
+ __name(createCommand$i, "createCommand$i");
59779
+ function createCommand$h(kernel, shell, terminal) {
59718
59780
  return new TerminalCommand({
59719
59781
  command: "cd",
59720
59782
  description: "Change the shell working directory",
@@ -59735,8 +59797,8 @@ function createCommand$c(kernel, shell, terminal) {
59735
59797
  }, "run")
59736
59798
  });
59737
59799
  }
59738
- __name(createCommand$c, "createCommand$c");
59739
- function createCommand$b(kernel, shell, terminal) {
59800
+ __name(createCommand$h, "createCommand$h");
59801
+ function createCommand$g(kernel, shell, terminal) {
59740
59802
  return new TerminalCommand({
59741
59803
  command: "chmod",
59742
59804
  description: "Change file mode bits",
@@ -59762,8 +59824,8 @@ function createCommand$b(kernel, shell, terminal) {
59762
59824
  }, "run")
59763
59825
  });
59764
59826
  }
59765
- __name(createCommand$b, "createCommand$b");
59766
- function createCommand$a(kernel, shell, terminal) {
59827
+ __name(createCommand$g, "createCommand$g");
59828
+ function createCommand$f(kernel, shell, terminal) {
59767
59829
  return new TerminalCommand({
59768
59830
  command: "cp",
59769
59831
  description: "Copy files",
@@ -59785,8 +59847,8 @@ function createCommand$a(kernel, shell, terminal) {
59785
59847
  }, "run")
59786
59848
  });
59787
59849
  }
59788
- __name(createCommand$a, "createCommand$a");
59789
- function createCommand$9(kernel, shell, terminal) {
59850
+ __name(createCommand$f, "createCommand$f");
59851
+ function createCommand$e(kernel, shell, terminal) {
59790
59852
  return new TerminalCommand({
59791
59853
  command: "echo",
59792
59854
  description: "Print arguments to the standard output",
@@ -59814,8 +59876,8 @@ function createCommand$9(kernel, shell, terminal) {
59814
59876
  }, "run")
59815
59877
  });
59816
59878
  }
59817
- __name(createCommand$9, "createCommand$9");
59818
- function createCommand$8(kernel, shell, terminal) {
59879
+ __name(createCommand$e, "createCommand$e");
59880
+ function createCommand$d(kernel, shell, terminal) {
59819
59881
  return new TerminalCommand({
59820
59882
  command: "ln",
59821
59883
  description: "Create links between files",
@@ -59907,7 +59969,7 @@ function createCommand$8(kernel, shell, terminal) {
59907
59969
  }, "run")
59908
59970
  });
59909
59971
  }
59910
- __name(createCommand$8, "createCommand$8");
59972
+ __name(createCommand$d, "createCommand$d");
59911
59973
  var humanFormat$2 = { exports: {} };
59912
59974
  var humanFormat$1 = humanFormat$2.exports;
59913
59975
  var hasRequiredHumanFormat;
@@ -60188,7 +60250,7 @@ function requireHumanFormat() {
60188
60250
  __name(requireHumanFormat, "requireHumanFormat");
60189
60251
  var humanFormatExports = requireHumanFormat();
60190
60252
  const humanFormat = /* @__PURE__ */ getDefaultExportFromCjs(humanFormatExports);
60191
- function createCommand$7(kernel, shell, terminal) {
60253
+ function createCommand$c(kernel, shell, terminal) {
60192
60254
  return new TerminalCommand({
60193
60255
  command: "ls",
60194
60256
  description: "List directory contents",
@@ -60353,8 +60415,8 @@ function createCommand$7(kernel, shell, terminal) {
60353
60415
  }, "run")
60354
60416
  });
60355
60417
  }
60356
- __name(createCommand$7, "createCommand$7");
60357
- function createCommand$6(kernel, shell, terminal) {
60418
+ __name(createCommand$c, "createCommand$c");
60419
+ function createCommand$b(kernel, shell, terminal) {
60358
60420
  return new TerminalCommand({
60359
60421
  command: "mkdir",
60360
60422
  description: "Create a directory",
@@ -60373,8 +60435,8 @@ function createCommand$6(kernel, shell, terminal) {
60373
60435
  }, "run")
60374
60436
  });
60375
60437
  }
60376
- __name(createCommand$6, "createCommand$6");
60377
- function createCommand$5(kernel, shell, terminal) {
60438
+ __name(createCommand$b, "createCommand$b");
60439
+ function createCommand$a(kernel, shell, terminal) {
60378
60440
  return new TerminalCommand({
60379
60441
  command: "mv",
60380
60442
  description: "Move or rename files",
@@ -60413,8 +60475,8 @@ function createCommand$5(kernel, shell, terminal) {
60413
60475
  }, "run")
60414
60476
  });
60415
60477
  }
60416
- __name(createCommand$5, "createCommand$5");
60417
- function createCommand$4(kernel, shell, terminal) {
60478
+ __name(createCommand$a, "createCommand$a");
60479
+ function createCommand$9(kernel, shell, terminal) {
60418
60480
  return new TerminalCommand({
60419
60481
  command: "pwd",
60420
60482
  description: "Print the shell working directory",
@@ -60430,8 +60492,8 @@ function createCommand$4(kernel, shell, terminal) {
60430
60492
  }, "run")
60431
60493
  });
60432
60494
  }
60433
- __name(createCommand$4, "createCommand$4");
60434
- function createCommand$3(kernel, shell, terminal) {
60495
+ __name(createCommand$9, "createCommand$9");
60496
+ function createCommand$8(kernel, shell, terminal) {
60435
60497
  return new TerminalCommand({
60436
60498
  command: "rm",
60437
60499
  description: "Remove files or directories",
@@ -60451,8 +60513,8 @@ function createCommand$3(kernel, shell, terminal) {
60451
60513
  }, "run")
60452
60514
  });
60453
60515
  }
60454
- __name(createCommand$3, "createCommand$3");
60455
- function createCommand$2(kernel, shell, terminal) {
60516
+ __name(createCommand$8, "createCommand$8");
60517
+ function createCommand$7(kernel, shell, terminal) {
60456
60518
  return new TerminalCommand({
60457
60519
  command: "rmdir",
60458
60520
  description: "Remove a directory",
@@ -60471,7 +60533,7 @@ function createCommand$2(kernel, shell, terminal) {
60471
60533
  }, "run")
60472
60534
  });
60473
60535
  }
60474
- __name(createCommand$2, "createCommand$2");
60536
+ __name(createCommand$7, "createCommand$7");
60475
60537
  const MAX_32_BITS = 4294967295;
60476
60538
  const MAX_16_BITS = 65535;
60477
60539
  const MAX_8_BITS = 255;
@@ -65266,7 +65328,7 @@ const table = {
65266
65328
  return mimeTypes;
65267
65329
  })();
65268
65330
  t(configure);
65269
- function createCommand$1(kernel, shell, terminal) {
65331
+ function createCommand$6(kernel, shell, terminal) {
65270
65332
  return new TerminalCommand({
65271
65333
  command: "stat",
65272
65334
  description: "Display information about a file or directory",
@@ -65296,8 +65358,8 @@ function createCommand$1(kernel, shell, terminal) {
65296
65358
  }, "run")
65297
65359
  });
65298
65360
  }
65299
- __name(createCommand$1, "createCommand$1");
65300
- function createCommand(kernel, shell, terminal) {
65361
+ __name(createCommand$6, "createCommand$6");
65362
+ function createCommand$5(kernel, shell, terminal) {
65301
65363
  return new TerminalCommand({
65302
65364
  command: "touch",
65303
65365
  description: "Create an empty file",
@@ -65316,23 +65378,1052 @@ function createCommand(kernel, shell, terminal) {
65316
65378
  }, "run")
65317
65379
  });
65318
65380
  }
65381
+ __name(createCommand$5, "createCommand$5");
65382
+ function createCommand$4(kernel, shell, terminal) {
65383
+ return new TerminalCommand({
65384
+ command: "hex",
65385
+ description: "Display file contents in hexadecimal format",
65386
+ kernel,
65387
+ shell,
65388
+ terminal,
65389
+ options: [
65390
+ { name: "help", type: Boolean, description: kernel.i18n.t("Display help") },
65391
+ { name: "path", type: String, typeLabel: "{underline path}", defaultOption: true, description: "The path to the file to display" }
65392
+ ],
65393
+ run: /* @__PURE__ */ __name(async (argv, process2) => {
65394
+ const filePath = argv.path;
65395
+ if (!filePath) {
65396
+ await writelnStderr(process2, terminal, "Usage: hex <file>");
65397
+ return 1;
65398
+ }
65399
+ const fullPath = path$1.resolve(shell.cwd, filePath);
65400
+ try {
65401
+ const exists2 = await shell.context.fs.promises.exists(fullPath);
65402
+ if (!exists2) {
65403
+ await writelnStderr(process2, terminal, `hex: ${filePath}: No such file or directory`);
65404
+ return 1;
65405
+ }
65406
+ const stats = await shell.context.fs.promises.stat(fullPath);
65407
+ if (stats.isDirectory()) {
65408
+ await writelnStderr(process2, terminal, `hex: ${filePath}: Is a directory`);
65409
+ return 1;
65410
+ }
65411
+ const data = await shell.context.fs.promises.readFile(fullPath);
65412
+ const bytesPerLine = 16;
65413
+ for (let offset = 0; offset < data.length; offset += bytesPerLine) {
65414
+ const lineBytes = data.slice(offset, offset + bytesPerLine);
65415
+ const offsetHex = offset.toString(16).padStart(8, "0");
65416
+ const hexGroups = [];
65417
+ const asciiChars = [];
65418
+ for (let i = 0; i < bytesPerLine; i++) {
65419
+ if (i < lineBytes.length) {
65420
+ const byte = lineBytes[i];
65421
+ if (byte === void 0) continue;
65422
+ const hex = byte.toString(16).padStart(2, "0");
65423
+ if (i % 2 === 0) {
65424
+ hexGroups.push(hex);
65425
+ } else {
65426
+ hexGroups[hexGroups.length - 1] += hex;
65427
+ }
65428
+ if (byte >= 32 && byte <= 126) {
65429
+ asciiChars.push(String.fromCharCode(byte));
65430
+ } else {
65431
+ asciiChars.push(".");
65432
+ }
65433
+ } else {
65434
+ if (i % 2 === 0) {
65435
+ hexGroups.push(" ");
65436
+ } else {
65437
+ hexGroups[hexGroups.length - 1] += " ";
65438
+ }
65439
+ asciiChars.push(" ");
65440
+ }
65441
+ }
65442
+ const hexString = hexGroups.join(" ").padEnd(47, " ");
65443
+ const asciiString = asciiChars.join("");
65444
+ await writelnStdout(process2, terminal, `${offsetHex}: ${hexString} ${asciiString}`);
65445
+ }
65446
+ return 0;
65447
+ } catch (error) {
65448
+ await writelnStderr(process2, terminal, `hex: ${filePath}: ${error instanceof Error ? error.message : "Unknown error"}`);
65449
+ return 1;
65450
+ }
65451
+ }, "run")
65452
+ });
65453
+ }
65454
+ __name(createCommand$4, "createCommand$4");
65455
+ const csi = "\x1B[";
65456
+ const ansi = {};
65457
+ ansi.style = {
65458
+ reset: "\x1B[0m",
65459
+ bold: "\x1B[1m",
65460
+ italic: "\x1B[3m",
65461
+ underline: "\x1B[4m",
65462
+ fontDefault: "\x1B[10m",
65463
+ font2: "\x1B[11m",
65464
+ font3: "\x1B[12m",
65465
+ font4: "\x1B[13m",
65466
+ font5: "\x1B[14m",
65467
+ font6: "\x1B[15m",
65468
+ imageNegative: "\x1B[7m",
65469
+ imagePositive: "\x1B[27m",
65470
+ black: "\x1B[30m",
65471
+ red: "\x1B[31m",
65472
+ green: "\x1B[32m",
65473
+ yellow: "\x1B[33m",
65474
+ blue: "\x1B[34m",
65475
+ magenta: "\x1B[35m",
65476
+ cyan: "\x1B[36m",
65477
+ white: "\x1B[37m",
65478
+ grey: "\x1B[90m",
65479
+ gray: "\x1B[90m",
65480
+ brightRed: "\x1B[91m",
65481
+ brightGreen: "\x1B[92m",
65482
+ brightYellow: "\x1B[93m",
65483
+ brightBlue: "\x1B[94m",
65484
+ brightMagenta: "\x1B[95m",
65485
+ brightCyan: "\x1B[96m",
65486
+ brightWhite: "\x1B[97m",
65487
+ "bg-black": "\x1B[40m",
65488
+ "bg-red": "\x1B[41m",
65489
+ "bg-green": "\x1B[42m",
65490
+ "bg-yellow": "\x1B[43m",
65491
+ "bg-blue": "\x1B[44m",
65492
+ "bg-magenta": "\x1B[45m",
65493
+ "bg-cyan": "\x1B[46m",
65494
+ "bg-white": "\x1B[47m",
65495
+ "bg-grey": "\x1B[100m",
65496
+ "bg-gray": "\x1B[100m",
65497
+ "bg-brightRed": "\x1B[101m",
65498
+ "bg-brightGreen": "\x1B[102m",
65499
+ "bg-brightYellow": "\x1B[103m",
65500
+ "bg-brightBlue": "\x1B[104m",
65501
+ "bg-brightMagenta": "\x1B[105m",
65502
+ "bg-brightCyan": "\x1B[106m",
65503
+ "bg-brightWhite": "\x1B[107m"
65504
+ };
65505
+ ansi.rgb = function(r, g2, b) {
65506
+ return `\x1B[38;2;${r};${g2};${b}m`;
65507
+ };
65508
+ ansi.bgRgb = function(r, g2, b) {
65509
+ return `\x1B[48;2;${r};${g2};${b}m`;
65510
+ };
65511
+ ansi.styles = function(styles2) {
65512
+ styles2 = arrayify(styles2);
65513
+ return styles2.map(function(effect) {
65514
+ const rgbMatches = effect.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
65515
+ const bgRgbMatches = effect.match(/bg-rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
65516
+ if (bgRgbMatches) {
65517
+ const [full, r, g2, b] = bgRgbMatches;
65518
+ return ansi.bgRgb(r, g2, b);
65519
+ } else if (rgbMatches) {
65520
+ const [full, r, g2, b] = rgbMatches;
65521
+ return ansi.rgb(r, g2, b);
65522
+ } else {
65523
+ return ansi.style[effect];
65524
+ }
65525
+ }).join("");
65526
+ };
65527
+ ansi.format = function(str, styleArray) {
65528
+ const re2 = /\[([\w\s-\(\),]+)\]{([^]*?)}/;
65529
+ let matches;
65530
+ str = String(str);
65531
+ if (!str) return "";
65532
+ while (matches = str.match(re2)) {
65533
+ const inlineStyles = matches[1].split(/\s+/);
65534
+ const inlineString = matches[2];
65535
+ str = str.replace(matches[0], ansi.format(inlineString, inlineStyles));
65536
+ }
65537
+ return styleArray && styleArray.length ? ansi.styles(styleArray) + str + ansi.style.reset : str;
65538
+ };
65539
+ ansi.cursor = {
65540
+ /**
65541
+ * Moves the cursor `lines` cells up. If the cursor is already at the edge of the screen, this has no effect
65542
+ * @param [lines=1] {number}
65543
+ * @return {string}
65544
+ */
65545
+ up: /* @__PURE__ */ __name(function(lines) {
65546
+ return csi + (lines || 1) + "A";
65547
+ }, "up"),
65548
+ /**
65549
+ * Moves the cursor `lines` cells down. If the cursor is already at the edge of the screen, this has no effect
65550
+ * @param [lines=1] {number}
65551
+ * @return {string}
65552
+ */
65553
+ down: /* @__PURE__ */ __name(function(lines) {
65554
+ return csi + (lines || 1) + "B";
65555
+ }, "down"),
65556
+ /**
65557
+ * Moves the cursor `lines` cells forward. If the cursor is already at the edge of the screen, this has no effect
65558
+ * @param [lines=1] {number}
65559
+ * @return {string}
65560
+ */
65561
+ forward: /* @__PURE__ */ __name(function(lines) {
65562
+ return csi + (lines || 1) + "C";
65563
+ }, "forward"),
65564
+ /**
65565
+ * Moves the cursor `lines` cells back. If the cursor is already at the edge of the screen, this has no effect
65566
+ * @param [lines=1] {number}
65567
+ * @return {string}
65568
+ */
65569
+ back: /* @__PURE__ */ __name(function(lines) {
65570
+ return csi + (lines || 1) + "D";
65571
+ }, "back"),
65572
+ /**
65573
+ * Moves cursor to beginning of the line n lines down.
65574
+ * @param [lines=1] {number}
65575
+ * @return {string}
65576
+ */
65577
+ nextLine: /* @__PURE__ */ __name(function(lines) {
65578
+ return csi + (lines || 1) + "E";
65579
+ }, "nextLine"),
65580
+ /**
65581
+ * Moves cursor to beginning of the line n lines up.
65582
+ * @param [lines=1] {number}
65583
+ * @return {string}
65584
+ */
65585
+ previousLine: /* @__PURE__ */ __name(function(lines) {
65586
+ return csi + (lines || 1) + "F";
65587
+ }, "previousLine"),
65588
+ /**
65589
+ * Moves the cursor to column n.
65590
+ * @param n {number} - column number
65591
+ * @return {string}
65592
+ */
65593
+ horizontalAbsolute: /* @__PURE__ */ __name(function(n) {
65594
+ return csi + n + "G";
65595
+ }, "horizontalAbsolute"),
65596
+ /**
65597
+ * Moves the cursor to row n, column m. The values are 1-based, and default to 1 (top left corner) if omitted.
65598
+ * @param n {number} - row number
65599
+ * @param m {number} - column number
65600
+ * @return {string}
65601
+ */
65602
+ position: /* @__PURE__ */ __name(function(n, m) {
65603
+ return csi + (n || 1) + ";" + (m || 1) + "H";
65604
+ }, "position"),
65605
+ /**
65606
+ * Hides the cursor
65607
+ */
65608
+ hide: csi + "?25l",
65609
+ /**
65610
+ * Shows the cursor
65611
+ */
65612
+ show: csi + "?25h"
65613
+ };
65614
+ ansi.erase = {
65615
+ /**
65616
+ * Clears part of the screen. If n is 0 (or missing), clear from cursor to end of screen. If n is 1, clear from cursor to beginning of the screen. If n is 2, clear entire screen.
65617
+ * @param n {number}
65618
+ * @return {string}
65619
+ */
65620
+ display: /* @__PURE__ */ __name(function(n) {
65621
+ return csi + (n || 0) + "J";
65622
+ }, "display"),
65623
+ /**
65624
+ * Erases part of the line. If n is zero (or missing), clear from cursor to the end of the line. If n is one, clear from cursor to beginning of the line. If n is two, clear entire line. Cursor position does not change.
65625
+ * @param n {number}
65626
+ * @return {string}
65627
+ */
65628
+ inLine: /* @__PURE__ */ __name(function(n) {
65629
+ return csi + (n || 0) + "K";
65630
+ }, "inLine")
65631
+ };
65632
+ function createCommand$3(kernel, shell, terminal) {
65633
+ return new TerminalCommand({
65634
+ command: "less",
65635
+ description: "View file contents interactively",
65636
+ kernel,
65637
+ shell,
65638
+ terminal,
65639
+ options: [
65640
+ { name: "help", type: Boolean, description: kernel.i18n.t("Display help") },
65641
+ { name: "path", type: String, typeLabel: "{underline path}", defaultOption: true, description: "The path to the file to view" }
65642
+ ],
65643
+ run: /* @__PURE__ */ __name(async (argv, process2) => {
65644
+ if (!process2) return 1;
65645
+ let lines = [];
65646
+ let currentLine = 0;
65647
+ let keyListener = null;
65648
+ let linesRendered = 0;
65649
+ try {
65650
+ if (argv.path) {
65651
+ const filePath = argv.path;
65652
+ const expandedPath = shell.expandTilde(filePath);
65653
+ const fullPath = path$1.resolve(shell.cwd, expandedPath);
65654
+ const exists2 = await shell.context.fs.promises.exists(fullPath);
65655
+ if (!exists2) {
65656
+ await writelnStderr(process2, terminal, `less: ${filePath}: No such file or directory`);
65657
+ return 1;
65658
+ }
65659
+ const stats = await shell.context.fs.promises.stat(fullPath);
65660
+ if (stats.isDirectory()) {
65661
+ await writelnStderr(process2, terminal, `less: ${filePath}: Is a directory`);
65662
+ return 1;
65663
+ }
65664
+ const content = await shell.context.fs.promises.readFile(fullPath, "utf-8");
65665
+ lines = content.split("\n");
65666
+ } else {
65667
+ if (!process2.stdin) {
65668
+ await writelnStderr(process2, terminal, "less: No input provided");
65669
+ return 1;
65670
+ }
65671
+ const reader = process2.stdin.getReader();
65672
+ const decoder2 = new TextDecoder();
65673
+ const chunks = [];
65674
+ try {
65675
+ while (true) {
65676
+ const { done, value } = await reader.read();
65677
+ if (done) break;
65678
+ chunks.push(decoder2.decode(value, { stream: true }));
65679
+ }
65680
+ chunks.push(decoder2.decode(new Uint8Array(), { stream: false }));
65681
+ } finally {
65682
+ reader.releaseLock();
65683
+ }
65684
+ const content = chunks.join("");
65685
+ lines = content.split("\n");
65686
+ }
65687
+ if (lines.length === 0) {
65688
+ return 0;
65689
+ }
65690
+ terminal.unlisten();
65691
+ terminal.write("\n");
65692
+ terminal.write(ansi.cursor.hide);
65693
+ const rows = terminal.rows;
65694
+ const displayRows = rows - 1;
65695
+ const render = /* @__PURE__ */ __name(() => {
65696
+ const maxLine = Math.max(0, lines.length - displayRows);
65697
+ if (currentLine > maxLine) {
65698
+ currentLine = maxLine;
65699
+ }
65700
+ if (currentLine < 0) {
65701
+ currentLine = 0;
65702
+ }
65703
+ if (linesRendered > 0) {
65704
+ terminal.write(ansi.cursor.up(linesRendered));
65705
+ }
65706
+ const endLine = Math.min(currentLine + displayRows, lines.length);
65707
+ linesRendered = 0;
65708
+ for (let i = currentLine; i < endLine; i++) {
65709
+ terminal.write(ansi.erase.inLine(2));
65710
+ const line3 = lines[i] || "";
65711
+ terminal.write(line3);
65712
+ linesRendered++;
65713
+ if (i < endLine - 1) {
65714
+ terminal.write("\n");
65715
+ }
65716
+ }
65717
+ for (let i = endLine - currentLine; i < displayRows; i++) {
65718
+ terminal.write("\n");
65719
+ terminal.write(ansi.erase.inLine(2));
65720
+ linesRendered++;
65721
+ }
65722
+ const percentage = lines.length > 0 ? Math.round(endLine / lines.length * 100) : 100;
65723
+ const statusLine = `-- ${currentLine + 1}-${endLine} / ${lines.length} (${percentage}%)`;
65724
+ terminal.write("\n");
65725
+ terminal.write(ansi.erase.inLine(2));
65726
+ terminal.write(statusLine);
65727
+ linesRendered++;
65728
+ }, "render");
65729
+ render();
65730
+ await new Promise((resolve2) => {
65731
+ keyListener = terminal.onKey(async ({ domEvent }) => {
65732
+ const keyName = domEvent.key;
65733
+ switch (keyName) {
65734
+ case "q":
65735
+ case "Q":
65736
+ case "Escape":
65737
+ if (keyListener) {
65738
+ keyListener.dispose();
65739
+ keyListener = null;
65740
+ }
65741
+ terminal.write(ansi.cursor.show);
65742
+ terminal.write("\n");
65743
+ terminal.listen();
65744
+ resolve2();
65745
+ return;
65746
+ case "ArrowUp":
65747
+ if (currentLine > 0) {
65748
+ currentLine--;
65749
+ render();
65750
+ }
65751
+ break;
65752
+ case "ArrowDown":
65753
+ case "Enter":
65754
+ currentLine++;
65755
+ render();
65756
+ break;
65757
+ case "PageDown":
65758
+ case " ":
65759
+ currentLine = Math.min(currentLine + displayRows, Math.max(0, lines.length - displayRows));
65760
+ render();
65761
+ break;
65762
+ case "PageUp":
65763
+ case "b":
65764
+ case "B":
65765
+ currentLine = Math.max(0, currentLine - displayRows);
65766
+ render();
65767
+ break;
65768
+ case "Home":
65769
+ case "g":
65770
+ currentLine = 0;
65771
+ render();
65772
+ break;
65773
+ case "End":
65774
+ case "G":
65775
+ currentLine = Math.max(0, lines.length - displayRows);
65776
+ render();
65777
+ break;
65778
+ }
65779
+ });
65780
+ });
65781
+ return 0;
65782
+ } catch (error) {
65783
+ if (keyListener) {
65784
+ keyListener.dispose();
65785
+ }
65786
+ terminal.write(ansi.cursor.show);
65787
+ terminal.write("\n");
65788
+ terminal.listen();
65789
+ await writelnStderr(process2, terminal, `less: ${error instanceof Error ? error.message : "Unknown error"}`);
65790
+ return 1;
65791
+ }
65792
+ }, "run")
65793
+ });
65794
+ }
65795
+ __name(createCommand$3, "createCommand$3");
65796
+ function createCommand$2(kernel, shell, terminal) {
65797
+ return new TerminalCommand({
65798
+ command: "passkey",
65799
+ description: "Manage passkey credentials for WebAuthn authentication",
65800
+ kernel,
65801
+ shell,
65802
+ terminal,
65803
+ options: [
65804
+ { name: "help", type: Boolean, description: kernel.i18n.t("Display help") },
65805
+ { name: "subcommand", type: String, defaultOption: true, description: "Subcommand: register, list, remove, remove-all" },
65806
+ { name: "name", type: String, description: "Name/description for the passkey (used with register)" },
65807
+ { name: "id", type: String, description: "Passkey ID to remove (used with remove)" }
65808
+ ],
65809
+ run: /* @__PURE__ */ __name(async (argv, process2) => {
65810
+ if (!process2) return 1;
65811
+ const currentUid = shell.credentials.uid;
65812
+ const user2 = kernel.users.get(currentUid);
65813
+ if (!user2) {
65814
+ await writelnStderr(process2, terminal, chalk$1.red("Error: Current user not found"));
65815
+ return 1;
65816
+ }
65817
+ const subcommand = argv.subcommand?.toLowerCase();
65818
+ if (!subcommand || subcommand === "help" || argv.help) {
65819
+ await writelnStdout(process2, terminal, "Usage: passkey <subcommand> [options]");
65820
+ await writelnStdout(process2, terminal, "");
65821
+ await writelnStdout(process2, terminal, "Subcommands:");
65822
+ await writelnStdout(process2, terminal, " register [--name <name>] Register a new passkey");
65823
+ await writelnStdout(process2, terminal, " list List all registered passkeys");
65824
+ await writelnStdout(process2, terminal, " remove --id <id> Remove a specific passkey");
65825
+ await writelnStdout(process2, terminal, " remove-all Remove all passkeys");
65826
+ return 0;
65827
+ }
65828
+ try {
65829
+ switch (subcommand) {
65830
+ case "register": {
65831
+ if (!kernel.auth.passkey.isSupported()) {
65832
+ await writelnStderr(process2, terminal, chalk$1.red("Error: WebAuthn is not supported in this browser"));
65833
+ return 1;
65834
+ }
65835
+ const name = argv.name || void 0;
65836
+ const username = user2.username;
65837
+ const userId = new TextEncoder().encode(username);
65838
+ const challenge = crypto.getRandomValues(new Uint8Array(32));
65839
+ const rpId = globalThis.location.hostname || "localhost";
65840
+ const createOptions = {
65841
+ challenge,
65842
+ rp: {
65843
+ name: kernel.name || "ecmaOS",
65844
+ id: rpId
65845
+ },
65846
+ user: {
65847
+ id: userId,
65848
+ name: username,
65849
+ displayName: username
65850
+ },
65851
+ pubKeyCredParams: [
65852
+ { type: "public-key", alg: -7 },
65853
+ { type: "public-key", alg: -257 }
65854
+ ],
65855
+ authenticatorSelection: {
65856
+ userVerification: "preferred"
65857
+ },
65858
+ timeout: 6e4
65859
+ };
65860
+ await writelnStdout(process2, terminal, chalk$1.yellow("Please interact with your authenticator to register a passkey..."));
65861
+ const credential = await kernel.auth.passkey.create(createOptions);
65862
+ if (!credential || !(credential instanceof PublicKeyCredential)) {
65863
+ await writelnStderr(process2, terminal, chalk$1.red("Error: Failed to create passkey. Registration cancelled or failed."));
65864
+ return 1;
65865
+ }
65866
+ const publicKeyCredential = credential;
65867
+ const response = publicKeyCredential.response;
65868
+ const credentialId = btoa(String.fromCharCode(...new Uint8Array(publicKeyCredential.rawId)));
65869
+ let publicKeyArray;
65870
+ try {
65871
+ if (typeof response.getPublicKey === "function") {
65872
+ try {
65873
+ const publicKeyCrypto = response.getPublicKey();
65874
+ if (publicKeyCrypto && publicKeyCrypto instanceof CryptoKey) {
65875
+ const publicKeyJwk = await crypto.subtle.exportKey("jwk", publicKeyCrypto);
65876
+ publicKeyArray = new TextEncoder().encode(JSON.stringify(publicKeyJwk));
65877
+ } else {
65878
+ throw new Error("getPublicKey() did not return a valid CryptoKey");
65879
+ }
65880
+ } catch (exportError) {
65881
+ await writelnStderr(process2, terminal, chalk$1.yellow(`Warning: Could not extract public key via getPublicKey(): ${exportError instanceof Error ? exportError.message : String(exportError)}. Using attestationObject instead.`));
65882
+ const attestationObject = response.attestationObject;
65883
+ publicKeyArray = new Uint8Array(attestationObject);
65884
+ }
65885
+ } else {
65886
+ const attestationObject = response.attestationObject;
65887
+ publicKeyArray = new Uint8Array(attestationObject);
65888
+ }
65889
+ } catch (error) {
65890
+ await writelnStderr(process2, terminal, chalk$1.red(`Error processing credential data: ${error instanceof Error ? error.message : String(error)}`));
65891
+ return 1;
65892
+ }
65893
+ const passkey = {
65894
+ id: crypto.randomUUID(),
65895
+ credentialId,
65896
+ publicKey: publicKeyArray,
65897
+ createdAt: Date.now(),
65898
+ name
65899
+ };
65900
+ await kernel.users.addPasskey(currentUid, passkey);
65901
+ await writelnStdout(process2, terminal, chalk$1.green(`Passkey registered successfully${name ? `: ${name}` : ""}`));
65902
+ await writelnStdout(process2, terminal, `Passkey ID: ${passkey.id}`);
65903
+ return 0;
65904
+ }
65905
+ case "list": {
65906
+ const passkeys = await kernel.users.getPasskeys(currentUid);
65907
+ if (passkeys.length === 0) {
65908
+ await writelnStdout(process2, terminal, "No passkeys registered for this user.");
65909
+ return 0;
65910
+ }
65911
+ await writelnStdout(process2, terminal, `Registered passkeys (${passkeys.length}):`);
65912
+ await writelnStdout(process2, terminal, "");
65913
+ for (const pk of passkeys) {
65914
+ const createdDate = new Date(pk.createdAt).toLocaleString();
65915
+ const lastUsedDate = pk.lastUsed ? new Date(pk.lastUsed).toLocaleString() : "Never";
65916
+ await writelnStdout(process2, terminal, ` ID: ${pk.id}`);
65917
+ if (pk.name) {
65918
+ await writelnStdout(process2, terminal, ` Name: ${pk.name}`);
65919
+ }
65920
+ await writelnStdout(process2, terminal, ` Created: ${createdDate}`);
65921
+ await writelnStdout(process2, terminal, ` Last used: ${lastUsedDate}`);
65922
+ await writelnStdout(process2, terminal, "");
65923
+ }
65924
+ return 0;
65925
+ }
65926
+ case "remove": {
65927
+ const id = argv.id;
65928
+ if (!id) {
65929
+ await writelnStderr(process2, terminal, chalk$1.red("Error: --id is required for remove command"));
65930
+ await writelnStdout(process2, terminal, "Usage: passkey remove --id <id>");
65931
+ return 1;
65932
+ }
65933
+ const passkeys = await kernel.users.getPasskeys(currentUid);
65934
+ const passkey = passkeys.find((pk) => pk.id === id);
65935
+ if (!passkey) {
65936
+ await writelnStderr(process2, terminal, chalk$1.red(`Error: Passkey with ID ${id} not found`));
65937
+ return 1;
65938
+ }
65939
+ await kernel.users.removePasskey(currentUid, id);
65940
+ await writelnStdout(process2, terminal, chalk$1.green(`Passkey removed successfully${passkey.name ? `: ${passkey.name}` : ""}`));
65941
+ return 0;
65942
+ }
65943
+ case "remove-all": {
65944
+ const passkeys = await kernel.users.getPasskeys(currentUid);
65945
+ if (passkeys.length === 0) {
65946
+ await writelnStdout(process2, terminal, "No passkeys to remove.");
65947
+ return 0;
65948
+ }
65949
+ await kernel.users.savePasskeys(currentUid, []);
65950
+ const passkeysPath = `${user2.home}/.passkeys`;
65951
+ try {
65952
+ await kernel.filesystem.fs.unlink(passkeysPath);
65953
+ } catch {
65954
+ }
65955
+ await writelnStdout(process2, terminal, chalk$1.green(`Removed ${passkeys.length} passkey(s)`));
65956
+ return 0;
65957
+ }
65958
+ default:
65959
+ await writelnStderr(process2, terminal, chalk$1.red(`Error: Unknown subcommand: ${subcommand}`));
65960
+ await writelnStdout(process2, terminal, 'Run "passkey help" for usage information');
65961
+ return 1;
65962
+ }
65963
+ } catch (error) {
65964
+ await writelnStderr(process2, terminal, chalk$1.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
65965
+ return 1;
65966
+ }
65967
+ }, "run")
65968
+ });
65969
+ }
65970
+ __name(createCommand$2, "createCommand$2");
65971
+ function parseSedExpression(expr) {
65972
+ expr = expr.trim();
65973
+ const substituteMatch = expr.match(/^(\d+)?(,(\d+|\$))?s\/(.+?)\/(.*?)\/([gip]*\d*)$/);
65974
+ if (substituteMatch) {
65975
+ const [, startLine, , endLine, pattern2, replacement, flags] = substituteMatch;
65976
+ const address = startLine ? {
65977
+ type: endLine ? "range" : "line",
65978
+ start: parseInt(startLine, 10),
65979
+ ...endLine && { end: endLine === "$" ? Infinity : parseInt(endLine, 10) }
65980
+ } : void 0;
65981
+ return {
65982
+ type: "substitute",
65983
+ pattern: pattern2,
65984
+ replacement: replacement || "",
65985
+ flags: flags || "",
65986
+ address
65987
+ };
65988
+ }
65989
+ const simpleSubstituteMatch = expr.match(/^s\/(.+?)\/(.*?)\/([gip]*\d*)$/);
65990
+ if (simpleSubstituteMatch) {
65991
+ const [, pattern2, replacement, flags] = simpleSubstituteMatch;
65992
+ return {
65993
+ type: "substitute",
65994
+ pattern: pattern2,
65995
+ replacement: replacement || "",
65996
+ flags: flags || ""
65997
+ };
65998
+ }
65999
+ const deleteMatch = expr.match(/^(\d+)?(,(\d+|\$))?d$/);
66000
+ if (deleteMatch) {
66001
+ const [, startLine, , endLine] = deleteMatch;
66002
+ const address = startLine ? {
66003
+ type: endLine ? "range" : "line",
66004
+ start: parseInt(startLine, 10),
66005
+ ...endLine && { end: endLine === "$" ? Infinity : parseInt(endLine, 10) }
66006
+ } : void 0;
66007
+ return {
66008
+ type: "delete",
66009
+ address
66010
+ };
66011
+ }
66012
+ const patternDeleteMatch = expr.match(/^\/(.+?)\/d$/);
66013
+ if (patternDeleteMatch) {
66014
+ return {
66015
+ type: "delete",
66016
+ address: {
66017
+ type: "pattern",
66018
+ start: patternDeleteMatch[1]
66019
+ }
66020
+ };
66021
+ }
66022
+ const printMatch = expr.match(/^\/(.+?)\/p$/);
66023
+ if (printMatch) {
66024
+ return {
66025
+ type: "print",
66026
+ address: {
66027
+ type: "pattern",
66028
+ start: printMatch[1]
66029
+ }
66030
+ };
66031
+ }
66032
+ return null;
66033
+ }
66034
+ __name(parseSedExpression, "parseSedExpression");
66035
+ function applySedCommand(line3, lineNum, totalLines, command) {
66036
+ if (command.type === "substitute") {
66037
+ if (!command.pattern || command.replacement === void 0) {
66038
+ return { result: line3, shouldPrint: false };
66039
+ }
66040
+ let shouldApply = true;
66041
+ if (command.address) {
66042
+ switch (command.address.type) {
66043
+ case "line":
66044
+ shouldApply = lineNum === command.address.start;
66045
+ break;
66046
+ case "range":
66047
+ const end = command.address.end === Infinity ? totalLines : command.address.end;
66048
+ shouldApply = lineNum >= command.address.start && lineNum <= end;
66049
+ break;
66050
+ case "pattern":
66051
+ try {
66052
+ const regex = new RegExp(command.address.start);
66053
+ shouldApply = regex.test(line3);
66054
+ } catch {
66055
+ return { result: line3, shouldPrint: false };
66056
+ }
66057
+ break;
66058
+ }
66059
+ }
66060
+ if (!shouldApply) {
66061
+ return { result: line3, shouldPrint: false };
66062
+ }
66063
+ const flags = command.flags || "";
66064
+ const global2 = flags.includes("g");
66065
+ const caseInsensitive = flags.includes("i");
66066
+ const nthMatch = flags.match(/^\d+$/) ? parseInt(flags, 10) : null;
66067
+ try {
66068
+ let regexFlags = global2 ? "g" : "";
66069
+ if (caseInsensitive) regexFlags += "i";
66070
+ if (nthMatch) {
66071
+ let count = 0;
66072
+ const regex2 = new RegExp(command.pattern, caseInsensitive ? "gi" : "g");
66073
+ const result2 = line3.replace(regex2, (match) => {
66074
+ count++;
66075
+ if (count === nthMatch) {
66076
+ return command.replacement || match;
66077
+ }
66078
+ return match;
66079
+ });
66080
+ return { result: result2, shouldPrint: false };
66081
+ }
66082
+ const regex = new RegExp(command.pattern, regexFlags || void 0);
66083
+ const result = line3.replace(regex, command.replacement);
66084
+ return { result, shouldPrint: false };
66085
+ } catch {
66086
+ return { result: line3, shouldPrint: false };
66087
+ }
66088
+ }
66089
+ if (command.type === "delete") {
66090
+ if (command.address) {
66091
+ switch (command.address.type) {
66092
+ case "line":
66093
+ if (lineNum === command.address.start) {
66094
+ return { result: null, shouldPrint: false };
66095
+ }
66096
+ break;
66097
+ case "range":
66098
+ const end = command.address.end === Infinity ? totalLines : command.address.end;
66099
+ if (lineNum >= command.address.start && lineNum <= end) {
66100
+ return { result: null, shouldPrint: false };
66101
+ }
66102
+ break;
66103
+ case "pattern":
66104
+ try {
66105
+ const regex = new RegExp(command.address.start);
66106
+ if (regex.test(line3)) {
66107
+ return { result: null, shouldPrint: false };
66108
+ }
66109
+ } catch {
66110
+ return { result: line3, shouldPrint: false };
66111
+ }
66112
+ break;
66113
+ }
66114
+ }
66115
+ return { result: line3, shouldPrint: false };
66116
+ }
66117
+ if (command.type === "print") {
66118
+ if (command.address && command.address.type === "pattern") {
66119
+ try {
66120
+ const regex = new RegExp(command.address.start);
66121
+ if (regex.test(line3)) {
66122
+ return { result: line3, shouldPrint: true };
66123
+ }
66124
+ } catch {
66125
+ return { result: line3, shouldPrint: false };
66126
+ }
66127
+ }
66128
+ return { result: line3, shouldPrint: false };
66129
+ }
66130
+ return { result: line3, shouldPrint: false };
66131
+ }
66132
+ __name(applySedCommand, "applySedCommand");
66133
+ function createCommand$1(kernel, shell, terminal) {
66134
+ return new TerminalCommand({
66135
+ command: "sed",
66136
+ description: "Stream editor for filtering and transforming text",
66137
+ kernel,
66138
+ shell,
66139
+ terminal,
66140
+ options: [
66141
+ { name: "help", type: Boolean, description: kernel.i18n.t("Display help") },
66142
+ { name: "expression", type: String, alias: "e", multiple: true, description: "Add the script to the commands to be executed" },
66143
+ { name: "file", type: String, alias: "f", description: "Add the contents of script-file to the commands to be executed" },
66144
+ { name: "inplace", type: String, alias: "i", description: "Edit files in place (makes backup if extension supplied)" },
66145
+ { name: "quiet", type: Boolean, alias: "q", description: "Suppress normal output" },
66146
+ { name: "path", type: String, typeLabel: "{underline path}", defaultOption: true, multiple: true, description: "Expression or input file(s)" }
66147
+ ],
66148
+ run: /* @__PURE__ */ __name(async (argv, process2) => {
66149
+ if (!process2) return 1;
66150
+ let expressions = argv.expression || [];
66151
+ let files = argv.path || [];
66152
+ const inplace = argv.inplace;
66153
+ const quiet = argv.quiet || false;
66154
+ const isSedExpression = /* @__PURE__ */ __name((arg) => {
66155
+ if (!arg) return false;
66156
+ const trimmed = arg.trim();
66157
+ return trimmed.startsWith("s/") || trimmed.startsWith("/") || /^\d+[sd]/.test(trimmed) || /^\d+,\d*[sd]/.test(trimmed) || /^\d+s\//.test(trimmed) || /^\d+,\d*s\//.test(trimmed);
66158
+ }, "isSedExpression");
66159
+ const potentialExpressions = [];
66160
+ const potentialFiles = [];
66161
+ for (const arg of files) {
66162
+ if (isSedExpression(arg)) {
66163
+ potentialExpressions.push(arg);
66164
+ } else {
66165
+ potentialFiles.push(arg);
66166
+ }
66167
+ }
66168
+ if (potentialExpressions.length > 0) {
66169
+ expressions = [...expressions, ...potentialExpressions];
66170
+ files = potentialFiles;
66171
+ }
66172
+ if (expressions.length === 0 && !argv.file) {
66173
+ await writelnStderr(process2, terminal, "sed: No expression provided");
66174
+ return 1;
66175
+ }
66176
+ const commands = [];
66177
+ if (argv.file) {
66178
+ const scriptPath = path$1.resolve(shell.cwd, argv.file);
66179
+ const exists2 = await shell.context.fs.promises.exists(scriptPath);
66180
+ if (!exists2) {
66181
+ await writelnStderr(process2, terminal, `sed: ${argv.file}: No such file or directory`);
66182
+ return 1;
66183
+ }
66184
+ const scriptContent = await shell.context.fs.promises.readFile(scriptPath, "utf-8");
66185
+ const scriptLines = scriptContent.split("\n").filter((line3) => line3.trim() && !line3.trim().startsWith("#"));
66186
+ for (const line3 of scriptLines) {
66187
+ const cmd = parseSedExpression(line3.trim());
66188
+ if (cmd) commands.push(cmd);
66189
+ }
66190
+ }
66191
+ for (const expr of expressions) {
66192
+ const cmd = parseSedExpression(expr);
66193
+ if (cmd) {
66194
+ commands.push(cmd);
66195
+ } else {
66196
+ await writelnStderr(process2, terminal, `sed: Invalid expression: ${expr}`);
66197
+ return 1;
66198
+ }
66199
+ }
66200
+ if (commands.length === 0) {
66201
+ await writelnStderr(process2, terminal, "sed: No valid commands found");
66202
+ return 1;
66203
+ }
66204
+ const writer = process2.stdout.getWriter();
66205
+ try {
66206
+ const processFile = /* @__PURE__ */ __name(async (filePath) => {
66207
+ const exists2 = await shell.context.fs.promises.exists(filePath);
66208
+ if (!exists2) {
66209
+ await writelnStderr(process2, terminal, `sed: ${filePath}: No such file or directory`);
66210
+ return [];
66211
+ }
66212
+ const stats = await shell.context.fs.promises.stat(filePath);
66213
+ if (stats.isDirectory()) {
66214
+ await writelnStderr(process2, terminal, `sed: ${filePath}: Is a directory`);
66215
+ return [];
66216
+ }
66217
+ const content = await shell.context.fs.promises.readFile(filePath, "utf-8");
66218
+ return content.split("\n");
66219
+ }, "processFile");
66220
+ let inputLines = [];
66221
+ if (files.length > 0) {
66222
+ for (const file of files) {
66223
+ const expandedPath = shell.expandTilde(file);
66224
+ const fullPath = path$1.resolve(shell.cwd, expandedPath);
66225
+ const lines = await processFile(fullPath);
66226
+ inputLines.push(...lines);
66227
+ if (lines.length > 0 && inputLines.length > lines.length) {
66228
+ inputLines.push("");
66229
+ }
66230
+ }
66231
+ } else {
66232
+ if (!process2.stdin) {
66233
+ await writelnStderr(process2, terminal, "sed: No input provided");
66234
+ return 1;
66235
+ }
66236
+ const reader = process2.stdin.getReader();
66237
+ const decoder2 = new TextDecoder();
66238
+ const chunks = [];
66239
+ try {
66240
+ while (true) {
66241
+ const { done, value } = await reader.read();
66242
+ if (done) break;
66243
+ chunks.push(decoder2.decode(value, { stream: true }));
66244
+ }
66245
+ chunks.push(decoder2.decode(new Uint8Array(), { stream: false }));
66246
+ } finally {
66247
+ reader.releaseLock();
66248
+ }
66249
+ const content = chunks.join("");
66250
+ inputLines = content.split("\n");
66251
+ }
66252
+ const outputLines = [];
66253
+ const totalLines = inputLines.length;
66254
+ for (let i = 0; i < inputLines.length; i++) {
66255
+ let line3 = inputLines[i] || "";
66256
+ let lineNum = i + 1;
66257
+ let shouldPrint = false;
66258
+ for (const command of commands) {
66259
+ const { result, shouldPrint: print } = applySedCommand(line3, lineNum, totalLines, command);
66260
+ if (result === null) {
66261
+ line3 = null;
66262
+ break;
66263
+ }
66264
+ line3 = result;
66265
+ if (print) {
66266
+ shouldPrint = true;
66267
+ }
66268
+ }
66269
+ if (line3 !== null) {
66270
+ outputLines.push(line3);
66271
+ if (shouldPrint && !quiet) {
66272
+ outputLines.push(line3);
66273
+ }
66274
+ }
66275
+ }
66276
+ const output2 = outputLines.join("\n");
66277
+ if (inplace !== void 0 && files.length > 0) {
66278
+ for (const file of files) {
66279
+ const expandedPath = shell.expandTilde(file);
66280
+ const fullPath = path$1.resolve(shell.cwd, expandedPath);
66281
+ const fileLines = await processFile(fullPath);
66282
+ if (fileLines.length === 0) continue;
66283
+ const fileOutputLines = [];
66284
+ const fileTotalLines = fileLines.length;
66285
+ for (let i = 0; i < fileLines.length; i++) {
66286
+ let line3 = fileLines[i] || "";
66287
+ let lineNum = i + 1;
66288
+ let shouldPrint = false;
66289
+ for (const command of commands) {
66290
+ const { result, shouldPrint: print } = applySedCommand(line3, lineNum, fileTotalLines, command);
66291
+ if (result === null) {
66292
+ line3 = null;
66293
+ break;
66294
+ }
66295
+ line3 = result;
66296
+ if (print) {
66297
+ shouldPrint = true;
66298
+ }
66299
+ }
66300
+ if (line3 !== null) {
66301
+ fileOutputLines.push(line3);
66302
+ if (shouldPrint && !quiet) {
66303
+ fileOutputLines.push(line3);
66304
+ }
66305
+ }
66306
+ }
66307
+ const fileOutput = fileOutputLines.join("\n");
66308
+ if (inplace) {
66309
+ const backupPath = `${fullPath}${inplace}`;
66310
+ const originalContent = await shell.context.fs.promises.readFile(fullPath, "utf-8");
66311
+ await shell.context.fs.promises.writeFile(backupPath, originalContent);
66312
+ }
66313
+ await shell.context.fs.promises.writeFile(fullPath, fileOutput);
66314
+ }
66315
+ } else {
66316
+ await writer.write(new TextEncoder().encode(output2));
66317
+ }
66318
+ return 0;
66319
+ } catch (error) {
66320
+ await writelnStderr(process2, terminal, `sed: ${error instanceof Error ? error.message : "Unknown error"}`);
66321
+ return 1;
66322
+ } finally {
66323
+ writer.releaseLock();
66324
+ }
66325
+ }, "run")
66326
+ });
66327
+ }
66328
+ __name(createCommand$1, "createCommand$1");
66329
+ function createCommand(kernel, shell, terminal) {
66330
+ return new TerminalCommand({
66331
+ command: "tee",
66332
+ description: "Read from standard input and write to standard output and files",
66333
+ kernel,
66334
+ shell,
66335
+ terminal,
66336
+ options: [
66337
+ { name: "help", type: Boolean, description: kernel.i18n.t("Display help") },
66338
+ { name: "append", type: Boolean, alias: "a", description: "Append to the given files, do not overwrite" },
66339
+ { name: "ignore-interrupts", type: Boolean, alias: "i", description: "Ignore interrupt signals" },
66340
+ { name: "path", type: String, typeLabel: "{underline path}", defaultOption: true, multiple: true, description: "File(s) to write to" }
66341
+ ],
66342
+ run: /* @__PURE__ */ __name(async (argv, process2) => {
66343
+ if (!process2) return 1;
66344
+ if (!process2.stdin) {
66345
+ await writelnStderr(process2, terminal, "tee: No input provided");
66346
+ return 1;
66347
+ }
66348
+ const files = argv.path || [];
66349
+ const append2 = argv.append || false;
66350
+ const ignoreInterrupts = argv["ignore-interrupts"] || false;
66351
+ const writer = process2.stdout.getWriter();
66352
+ try {
66353
+ const filePaths = [];
66354
+ for (const file of files) {
66355
+ const expandedPath = shell.expandTilde(file);
66356
+ const fullPath = path$1.resolve(shell.cwd, expandedPath);
66357
+ if (!append2) {
66358
+ try {
66359
+ await shell.context.fs.promises.writeFile(fullPath, "");
66360
+ } catch (error) {
66361
+ await writelnStderr(process2, terminal, `tee: ${file}: ${error instanceof Error ? error.message : "Unknown error"}`);
66362
+ return 1;
66363
+ }
66364
+ }
66365
+ filePaths.push({ path: file, fullPath });
66366
+ }
66367
+ const reader = process2.stdin.getReader();
66368
+ let interrupted = false;
66369
+ const interruptHandler = /* @__PURE__ */ __name(() => {
66370
+ interrupted = true;
66371
+ }, "interruptHandler");
66372
+ if (!ignoreInterrupts) {
66373
+ kernel.terminal.events.on(TerminalEvents.INTERRUPT, interruptHandler);
66374
+ }
66375
+ try {
66376
+ while (true) {
66377
+ if (interrupted) break;
66378
+ const { done, value } = await reader.read();
66379
+ if (done) break;
66380
+ await writer.write(value);
66381
+ for (const fileInfo of filePaths) {
66382
+ try {
66383
+ await shell.context.fs.promises.appendFile(fileInfo.fullPath, value);
66384
+ } catch (error) {
66385
+ await writelnStderr(process2, terminal, `tee: ${fileInfo.path}: ${error instanceof Error ? error.message : "Write error"}`);
66386
+ }
66387
+ }
66388
+ }
66389
+ } finally {
66390
+ reader.releaseLock();
66391
+ if (!ignoreInterrupts) {
66392
+ kernel.terminal.events.off(TerminalEvents.INTERRUPT, interruptHandler);
66393
+ }
66394
+ }
66395
+ return 0;
66396
+ } catch (error) {
66397
+ await writelnStderr(process2, terminal, `tee: ${error instanceof Error ? error.message : "Unknown error"}`);
66398
+ return 1;
66399
+ } finally {
66400
+ writer.releaseLock();
66401
+ }
66402
+ }, "run")
66403
+ });
66404
+ }
65319
66405
  __name(createCommand, "createCommand");
65320
66406
  function createAllCommands(kernel, shell, terminal) {
65321
66407
  return {
65322
- cat: createCommand$d(kernel, shell, terminal),
65323
- cd: createCommand$c(kernel, shell, terminal),
65324
- chmod: createCommand$b(kernel, shell, terminal),
65325
- cp: createCommand$a(kernel, shell, terminal),
65326
- echo: createCommand$9(kernel, shell, terminal),
65327
- ln: createCommand$8(kernel, shell, terminal),
65328
- ls: createCommand$7(kernel, shell, terminal),
65329
- mkdir: createCommand$6(kernel, shell, terminal),
65330
- mv: createCommand$5(kernel, shell, terminal),
65331
- pwd: createCommand$4(kernel, shell, terminal),
65332
- rm: createCommand$3(kernel, shell, terminal),
65333
- rmdir: createCommand$2(kernel, shell, terminal),
65334
- stat: createCommand$1(kernel, shell, terminal),
65335
- touch: createCommand(kernel, shell, terminal)
66408
+ cat: createCommand$i(kernel, shell, terminal),
66409
+ cd: createCommand$h(kernel, shell, terminal),
66410
+ chmod: createCommand$g(kernel, shell, terminal),
66411
+ cp: createCommand$f(kernel, shell, terminal),
66412
+ echo: createCommand$e(kernel, shell, terminal),
66413
+ ln: createCommand$d(kernel, shell, terminal),
66414
+ ls: createCommand$c(kernel, shell, terminal),
66415
+ mkdir: createCommand$b(kernel, shell, terminal),
66416
+ mv: createCommand$a(kernel, shell, terminal),
66417
+ pwd: createCommand$9(kernel, shell, terminal),
66418
+ rm: createCommand$8(kernel, shell, terminal),
66419
+ rmdir: createCommand$7(kernel, shell, terminal),
66420
+ stat: createCommand$6(kernel, shell, terminal),
66421
+ touch: createCommand$5(kernel, shell, terminal),
66422
+ hex: createCommand$4(kernel, shell, terminal),
66423
+ less: createCommand$3(kernel, shell, terminal),
66424
+ passkey: createCommand$2(kernel, shell, terminal),
66425
+ sed: createCommand$1(kernel, shell, terminal),
66426
+ tee: createCommand(kernel, shell, terminal)
65336
66427
  };
65337
66428
  }
65338
66429
  __name(createAllCommands, "createAllCommands");
@@ -65436,7 +66527,7 @@ const TerminalCommands = /* @__PURE__ */ __name((kernel, shell, terminal) => {
65436
66527
  { name: "reinstall", type: Boolean, description: "Reinstall the package if it is already installed" }
65437
66528
  ],
65438
66529
  run: /* @__PURE__ */ __name(async (argv) => {
65439
- const { default: install } = await import("./install-7ncBAQu_.js");
66530
+ const { default: install } = await import("./install-CNseKaMB.js");
65440
66531
  return await install({ kernel, shell, terminal, args: [argv.package, argv.registry, argv.reinstall] });
65441
66532
  }, "run")
65442
66533
  }),
@@ -65451,7 +66542,7 @@ const TerminalCommands = /* @__PURE__ */ __name((kernel, shell, terminal) => {
65451
66542
  { name: "package", type: String, typeLabel: "{underline package}", defaultOption: true, description: "The package name and optional version (e.g. package@1.0.0). If no version is specified, all versions will be uninstalled." }
65452
66543
  ],
65453
66544
  run: /* @__PURE__ */ __name(async (argv) => {
65454
- const { default: uninstall } = await import("./uninstall-RZVWBlfX.js");
66545
+ const { default: uninstall } = await import("./uninstall-CamF7_kP.js");
65455
66546
  return await uninstall({ kernel, shell, terminal, args: [argv.package] });
65456
66547
  }, "run")
65457
66548
  }),
@@ -66003,7 +67094,7 @@ const snake = /* @__PURE__ */ __name(({ kernel, terminal }) => {
66003
67094
  const gameBoard = Array(height).fill(null).map(() => Array(width).fill(" "));
66004
67095
  snake2.forEach((segment) => gameBoard[segment.y][segment.x] = segment.y === snake2[0].y && segment.x === snake2[0].x ? chalk$2.yellow("█") : chalk$2.gray("█"));
66005
67096
  gameBoard[food.y][food.x] = chalk$2.green("●");
66006
- terminal.write(ansi$6.erase.display(2) + ansi$6.cursor.position(2, 1));
67097
+ terminal.write(ansi$7.erase.display(2) + ansi$7.cursor.position(2, 1));
66007
67098
  terminal.writeln(chalk$2.blue("┌" + "─".repeat(width) + "┐"));
66008
67099
  gameBoard.forEach((row) => terminal.writeln(chalk$2.blue("│" + row.join("") + "│")));
66009
67100
  terminal.writeln(chalk$2.blue(`└${"─".repeat(width)}┘`));
@@ -66023,7 +67114,7 @@ const snake = /* @__PURE__ */ __name(({ kernel, terminal }) => {
66023
67114
  } else snake2.pop();
66024
67115
  return;
66025
67116
  }, "moveSnake");
66026
- terminal.write(ansi$6.cursor.hide);
67117
+ terminal.write(ansi$7.cursor.hide);
66027
67118
  terminal.unlisten();
66028
67119
  renderGame();
66029
67120
  const keyListener = terminal.onKey(({ domEvent }) => {
@@ -66063,7 +67154,7 @@ const snake = /* @__PURE__ */ __name(({ kernel, terminal }) => {
66063
67154
  terminal.listen();
66064
67155
  clearInterval(gameLoop);
66065
67156
  terminal.writeln("Game Over!");
66066
- terminal.write(ansi$6.cursor.show + terminal.prompt());
67157
+ terminal.write(ansi$7.cursor.show + terminal.prompt());
66067
67158
  return;
66068
67159
  }
66069
67160
  if (!gameStarted) return;
@@ -66465,7 +67556,7 @@ const _Terminal = class _Terminal extends xtermExports.Terminal {
66465
67556
  if (!options.kernel) throw new Error("Terminal requires a kernel");
66466
67557
  super({ ...DefaultTerminalOptions, ...options });
66467
67558
  __publicField(this, "_addons", /* @__PURE__ */ new Map());
66468
- __publicField(this, "_ansi", ansi$6);
67559
+ __publicField(this, "_ansi", ansi$7);
66469
67560
  __publicField(this, "_cmd", "");
66470
67561
  __publicField(this, "_commands");
66471
67562
  __publicField(this, "_cursorPosition", 0);
@@ -66704,18 +67795,18 @@ const _Terminal = class _Terminal extends xtermExports.Terminal {
66704
67795
  resolve2(input);
66705
67796
  break;
66706
67797
  case "ArrowLeft":
66707
- this.write(ansi$6.cursor.back());
67798
+ this.write(ansi$7.cursor.back());
66708
67799
  cursor--;
66709
67800
  break;
66710
67801
  case "ArrowRight":
66711
- this.write(ansi$6.cursor.forward());
67802
+ this.write(ansi$7.cursor.forward());
66712
67803
  cursor++;
66713
67804
  break;
66714
67805
  case "Home":
66715
- this.write(ansi$6.cursor.horizontalAbsolute(0));
67806
+ this.write(ansi$7.cursor.horizontalAbsolute(0));
66716
67807
  break;
66717
67808
  case "End":
66718
- this.write(ansi$6.cursor.horizontalAbsolute(input.length));
67809
+ this.write(ansi$7.cursor.horizontalAbsolute(input.length));
66719
67810
  break;
66720
67811
  case "Escape":
66721
67812
  disposable.dispose();
@@ -66724,7 +67815,7 @@ const _Terminal = class _Terminal extends xtermExports.Terminal {
66724
67815
  case "Backspace":
66725
67816
  if (cursor > 0) {
66726
67817
  input = input.slice(0, cursor - 1) + input.slice(cursor);
66727
- this.write(ansi$6.cursor.horizontalAbsolute(0) + ansi$6.erase.inLine(2) + ":" + input);
67818
+ this.write(ansi$7.cursor.horizontalAbsolute(0) + ansi$7.erase.inLine(2) + ":" + input);
66728
67819
  cursor--;
66729
67820
  } else this.write("\x07");
66730
67821
  break;
@@ -66736,7 +67827,7 @@ const _Terminal = class _Terminal extends xtermExports.Terminal {
66736
67827
  const charCode = domEvent.key.charCodeAt(0);
66737
67828
  if (charCode >= 32 && charCode <= 126) {
66738
67829
  input = input.slice(0, cursor) + domEvent.key + input.slice(cursor);
66739
- if (!hide) this.write(ansi$6.cursor.horizontalAbsolute(0) + ansi$6.erase.inLine(2) + prompt + input);
67830
+ if (!hide) this.write(ansi$7.cursor.horizontalAbsolute(0) + ansi$7.erase.inLine(2) + prompt + input);
66740
67831
  cursor++;
66741
67832
  }
66742
67833
  }
@@ -66905,7 +67996,7 @@ const _Terminal = class _Terminal extends xtermExports.Terminal {
66905
67996
  case "v":
66906
67997
  return this.paste();
66907
67998
  case "Escape":
66908
- return this.write(ansi$6.erase.display(2) + ansi$6.cursor.position() + this.prompt());
67999
+ return this.write(ansi$7.erase.display(2) + ansi$7.cursor.position() + this.prompt());
66909
68000
  }
66910
68001
  }
66911
68002
  switch (keyName) {
@@ -66947,7 +68038,7 @@ const _Terminal = class _Terminal extends xtermExports.Terminal {
66947
68038
  }
66948
68039
  this._cmd = "";
66949
68040
  this._cursorPosition = 0;
66950
- this.write(ansi$6.erase.inLine(2) + this.prompt());
68041
+ this.write(ansi$7.erase.inLine(2) + this.prompt());
66951
68042
  break;
66952
68043
  case "Backspace":
66953
68044
  if (this._cursorPosition > 0) {
@@ -66961,7 +68052,7 @@ const _Terminal = class _Terminal extends xtermExports.Terminal {
66961
68052
  case "Delete":
66962
68053
  if (this._cursorPosition < this._cmd.length) {
66963
68054
  this._cmd = this._cmd.slice(0, this._cursorPosition) + this._cmd.slice(this._cursorPosition + 1);
66964
- this.write(ansi$6.erase.inLine(2) + ansi$6.cursor.horizontalAbsolute(0));
68055
+ this.write(ansi$7.erase.inLine(2) + ansi$7.cursor.horizontalAbsolute(0));
66965
68056
  if (this._multiLineMode) {
66966
68057
  const parts = this._cmd.split("#");
66967
68058
  if (parts.length > 1) {
@@ -67040,11 +68131,11 @@ const _Terminal = class _Terminal extends xtermExports.Terminal {
67040
68131
  break;
67041
68132
  case "Home":
67042
68133
  this._cursorPosition = 0;
67043
- this.write(ansi$6.cursor.horizontalAbsolute(this.prompt().replace(/\x1b\[[0-9;]*[a-zA-Z]/g, "").length + 1));
68134
+ this.write(ansi$7.cursor.horizontalAbsolute(this.prompt().replace(/\x1b\[[0-9;]*[a-zA-Z]/g, "").length + 1));
67044
68135
  break;
67045
68136
  case "End":
67046
68137
  this._cursorPosition = this._cmd.length + 1;
67047
- this.write(ansi$6.cursor.horizontalAbsolute(this.prompt().replace(/\x1b\[[0-9;]*[a-zA-Z]/g, "").length + this._cmd.length + 1));
68138
+ this.write(ansi$7.cursor.horizontalAbsolute(this.prompt().replace(/\x1b\[[0-9;]*[a-zA-Z]/g, "").length + this._cmd.length + 1));
67048
68139
  break;
67049
68140
  case "Tab": {
67050
68141
  domEvent.preventDefault();
@@ -67063,7 +68154,7 @@ const _Terminal = class _Terminal extends xtermExports.Terminal {
67063
68154
  await this._shell.execute(`ls ${expandedPath}`);
67064
68155
  this.write(this.prompt() + this._cmd);
67065
68156
  } else if (matches.length > 0) {
67066
- this.write("\r" + ansi$6.erase.inLine());
68157
+ this.write("\r" + ansi$7.erase.inLine());
67067
68158
  this._tabCompletionIndex = (this._tabCompletionIndex + 1) % matches.length;
67068
68159
  const newCmd = matches[this._tabCompletionIndex] || "";
67069
68160
  this._cmd = newCmd;
@@ -67082,7 +68173,7 @@ const _Terminal = class _Terminal extends xtermExports.Terminal {
67082
68173
  if (key.length === 1) {
67083
68174
  this._cmd = this._cmd.slice(0, this._cursorPosition) + key + this._cmd.slice(this._cursorPosition);
67084
68175
  this._cursorPosition++;
67085
- this.write(ansi$6.erase.inLine(2) + ansi$6.cursor.horizontalAbsolute(0));
68176
+ this.write(ansi$7.erase.inLine(2) + ansi$7.cursor.horizontalAbsolute(0));
67086
68177
  if (this._multiLineMode) {
67087
68178
  const parts = this._cmd.split("#");
67088
68179
  if (parts.length > 1) {
@@ -67157,7 +68248,7 @@ const _Terminal = class _Terminal extends xtermExports.Terminal {
67157
68248
  const currentLine = this._cmd;
67158
68249
  this._cmd = "";
67159
68250
  this._cursorPosition = 0;
67160
- this.write("\r" + ansi$6.erase.inLine(2));
68251
+ this.write("\r" + ansi$7.erase.inLine(2));
67161
68252
  return currentLine;
67162
68253
  }
67163
68254
  restoreCommand(cmd) {
@@ -67254,7 +68345,7 @@ const _Spinner = class _Spinner {
67254
68345
  }
67255
68346
  start() {
67256
68347
  let index = 0;
67257
- this.terminal.write(ansi$6.cursor.hide);
68348
+ this.terminal.write(ansi$7.cursor.hide);
67258
68349
  const interval = setInterval(() => {
67259
68350
  const currentFrame = this.frames[index];
67260
68351
  const fullText = `${this.prefix ? this.prefix + " " : ""}${currentFrame}${this.suffix ? " " + this.suffix : ""}`;
@@ -67272,7 +68363,7 @@ const _Spinner = class _Spinner {
67272
68363
  }
67273
68364
  stop() {
67274
68365
  clearInterval(this.loop);
67275
- this.terminal.write(ansi$6.cursor.show);
68366
+ this.terminal.write(ansi$7.cursor.show);
67276
68367
  }
67277
68368
  };
67278
68369
  __name(_Spinner, "Spinner");
@@ -71304,10 +72395,27 @@ const _Users = class _Users {
71304
72395
  /**
71305
72396
  * Login a user
71306
72397
  */
71307
- async login(username, password) {
72398
+ async login(username, password, passkeyCredential) {
71308
72399
  const user2 = Array.from(this._users.values()).find((u) => u.username === username);
71309
- const hashedPassword = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(password.trim()));
71310
- if (!user2 || user2.password !== Array.from(new Uint8Array(hashedPassword)).map((b) => b.toString(16).padStart(2, "0")).join("")) throw new Error("Invalid username or password");
72400
+ if (!user2) throw new Error("Invalid username or password");
72401
+ if (passkeyCredential) {
72402
+ const passkeys = await this.getPasskeys(user2.uid);
72403
+ const credential = passkeyCredential;
72404
+ const credentialId = btoa(String.fromCharCode(...new Uint8Array(credential.rawId)));
72405
+ const matchingPasskey = passkeys.find((pk) => pk.credentialId === credentialId);
72406
+ if (!matchingPasskey) {
72407
+ throw new Error("Passkey not found for this user");
72408
+ }
72409
+ matchingPasskey.lastUsed = Date.now();
72410
+ await this.savePasskeys(user2.uid, passkeys);
72411
+ } else if (password) {
72412
+ const hashedPassword = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(password.trim()));
72413
+ if (user2.password !== Array.from(new Uint8Array(hashedPassword)).map((b) => b.toString(16).padStart(2, "0")).join("")) {
72414
+ throw new Error("Invalid username or password");
72415
+ }
72416
+ } else {
72417
+ throw new Error("Password or passkey required");
72418
+ }
71311
72419
  const cred = createCredentials({
71312
72420
  uid: user2.uid,
71313
72421
  gid: user2.gid,
@@ -71351,6 +72459,77 @@ const _Users = class _Users {
71351
72459
  throw new Error(`User with UID ${uid} not found`);
71352
72460
  }
71353
72461
  }
72462
+ /**
72463
+ * Get all passkeys for a user
72464
+ */
72465
+ async getPasskeys(uid) {
72466
+ const user2 = this._users.get(uid);
72467
+ if (!user2) return [];
72468
+ const passkeysPath = `${user2.home}/.passkeys`;
72469
+ try {
72470
+ const exists2 = await this._options.kernel.filesystem.fs.exists(passkeysPath);
72471
+ if (!exists2) return [];
72472
+ const content = await this._options.kernel.filesystem.fs.readFile(passkeysPath, "utf-8");
72473
+ const parsed = JSON.parse(content);
72474
+ return parsed.map((pk) => {
72475
+ const publicKeyArray = JSON.parse(pk.publicKey);
72476
+ return {
72477
+ ...pk,
72478
+ publicKey: new Uint8Array(publicKeyArray)
72479
+ };
72480
+ });
72481
+ } catch (error) {
72482
+ this._options.kernel.log.warn(`Failed to read passkeys for user ${uid}: ${error}`);
72483
+ return [];
72484
+ }
72485
+ }
72486
+ /**
72487
+ * Save passkeys for a user
72488
+ */
72489
+ async savePasskeys(uid, passkeys) {
72490
+ const user2 = this._users.get(uid);
72491
+ if (!user2) throw new Error(`User with UID ${uid} not found`);
72492
+ const passkeysPath = `${user2.home}/.passkeys`;
72493
+ const serialized = passkeys.map((pk) => {
72494
+ const publicKeyArray = pk.publicKey instanceof ArrayBuffer ? Array.from(new Uint8Array(pk.publicKey)) : Array.from(pk.publicKey);
72495
+ return {
72496
+ ...pk,
72497
+ publicKey: JSON.stringify(publicKeyArray)
72498
+ };
72499
+ });
72500
+ await this._options.kernel.filesystem.fs.writeFile(
72501
+ passkeysPath,
72502
+ JSON.stringify(serialized, null, 2),
72503
+ { encoding: "utf-8", mode: 384 }
72504
+ );
72505
+ try {
72506
+ await this._options.kernel.filesystem.fs.chown(passkeysPath, uid, user2.gid);
72507
+ } catch {
72508
+ }
72509
+ }
72510
+ /**
72511
+ * Add a passkey to a user's collection
72512
+ */
72513
+ async addPasskey(uid, passkey) {
72514
+ const existing = await this.getPasskeys(uid);
72515
+ existing.push(passkey);
72516
+ await this.savePasskeys(uid, existing);
72517
+ }
72518
+ /**
72519
+ * Remove a passkey by ID
72520
+ */
72521
+ async removePasskey(uid, passkeyId) {
72522
+ const existing = await this.getPasskeys(uid);
72523
+ const filtered = existing.filter((pk) => pk.id !== passkeyId);
72524
+ await this.savePasskeys(uid, filtered);
72525
+ }
72526
+ /**
72527
+ * Check if a user has any registered passkeys
72528
+ */
72529
+ async hasPasskeys(uid) {
72530
+ const passkeys = await this.getPasskeys(uid);
72531
+ return passkeys.length > 0;
72532
+ }
71354
72533
  };
71355
72534
  __name(_Users, "Users");
71356
72535
  let Users = _Users;
@@ -72715,10 +73894,10 @@ const _Workers = class _Workers {
72715
73894
  };
72716
73895
  __name(_Workers, "Workers");
72717
73896
  let Workers = _Workers;
72718
- const __vite_import_meta_env__ = { "AUTHOR": { "name": "Jay Mathis", "email": "code@mathis.network", "url": "https://github.com/mathiscode" }, "BASE_URL": "/", "DESCRIPTION": "ecmaOS: Micro-kernel and framework for web technologies", "DEV": false, "HOMEPAGE": "https://ecmaos.sh", "KNOWN_ISSUES": ["It's best to stick to Chromium-based browsers for the most features", "Keyboard is broken on mobile; ecmaOS is not mobile-friendly at this time", "Don't expect any sort of POSIX compliance at this stage", "Most commands/devices are very basic implementations, not complete reproductions", "stdin/stdout/stderr streams and redirection can be wonky and don't work everywhere, but are coming along", "CTRL-C will return you to a prompt, but doesn't currently interrupt a process", "Lots of unfinished work; watch your step"], "MODE": "production", "NAME": "@ecmaos/kernel", "PROD": true, "REPOSITORY": "https://github.com/ecmaos/ecmaos", "SSR": false, "TIPS": ["If it ever fails to boot, check your logs or try clearing all data", "You can run some devices that offer a CLI - e.g. '/dev/battery --help'", "Use the 'install' command to install packages - e.g. 'install @ecmaos-apps/news'", "You can install any NPM package - e.g. 'install jquery'", "Use the 'news' command to see the latest news about ecmaOS", "Type 'ls /bin' to see all built-in commands", "Type 'ls /usr/bin' to see all installed commands", "You can set your environment variables in ~/.env (try setting PROMPT to a PS1-like format)", "Try 'fetch /xkcd-os.sixel'"], "VERSION": "0.6.3", "VITE_APP_SHOW_DEFAULT_LOGIN": "true", "VITE_BOOT_DISABLE_ISSUES": "true", "VITE_BOOT_DISABLE_LOGO_CONSOLE": "false", "VITE_BOOT_DISABLE_LOGO_FIGLET": "false", "VITE_BOOT_DISABLE_TIPS": "false", "VITE_INITFS": "/initfs.tar.gz", "VITE_KERNEL_INTERVALS_PROC": "1000", "VITE_KERNEL_MODULES": "@ecmaos-modules/boilerplate@0.1.0", "VITE_METAL_SOCKET": "ws://localhost:30445/socket", "VITE_PORT": "30443", "VITE_RECOMMENDED_APPS": "@ecmaos-apps/code,@ecmaos-apps/webamp,@ecmaos-apps/news", "XTERM_VERSION": "5.5.0", "ZENFS_VERSION": "2.4.2" };
73897
+ const __vite_import_meta_env__ = { "AUTHOR": { "name": "Jay Mathis", "email": "code@mathis.network", "url": "https://github.com/mathiscode" }, "BASE_URL": "/", "DESCRIPTION": "ecmaOS: Micro-kernel and framework for web technologies", "DEV": false, "HOMEPAGE": "https://ecmaos.sh", "KNOWN_ISSUES": ["It's best to stick to Chromium-based browsers for the most features", "Keyboard is broken on mobile; ecmaOS is not mobile-friendly at this time", "Don't expect any sort of POSIX compliance at this stage", "Most commands/devices are very basic implementations, not complete reproductions", "stdin/stdout/stderr streams and redirection can be wonky and don't work everywhere, but are coming along", "CTRL-C will return you to a prompt, but doesn't currently interrupt a process", "Lots of unfinished work; watch your step"], "MODE": "production", "NAME": "@ecmaos/kernel", "PROD": true, "REPOSITORY": "https://github.com/ecmaos/ecmaos", "SSR": false, "TIPS": ["If it ever fails to boot, check your logs, try clearing all data, try incognito mode, or try another browser", "You can run some devices that offer a CLI - e.g. '/dev/battery --help'", "Use the 'install' command to install packages - e.g. 'install @ecmaos-apps/news'", "You can install any NPM package - e.g. 'install jquery'", "Use the 'news' command to see the latest news about ecmaOS", "Type 'ls /bin' to see all built-in commands", "Type 'ls /usr/bin' to see all installed commands", "You can set your environment variables in ~/.env (try setting PROMPT to a PS1-like format)", "You can register and login with a passkey: 'passkey register' and 'passkey list'", "Try 'fetch /xkcd-os.sixel'"], "VERSION": "0.6.5", "VITE_APP_SHOW_DEFAULT_LOGIN": "true", "VITE_BOOT_DISABLE_ISSUES": "true", "VITE_BOOT_DISABLE_LOGO_CONSOLE": "false", "VITE_BOOT_DISABLE_LOGO_FIGLET": "false", "VITE_BOOT_DISABLE_TIPS": "false", "VITE_INITFS": "/initfs.tar.gz", "VITE_KERNEL_INTERVALS_PROC": "1000", "VITE_KERNEL_MODULES": "@ecmaos-modules/boilerplate@0.1.0", "VITE_METAL_SOCKET": "ws://localhost:30445/socket", "VITE_PORT": "30443", "VITE_RECOMMENDED_APPS": "@ecmaos-apps/code,@ecmaos-apps/edit,@ecmaos-apps/ai,@ecmaos-apps/webamp,@ecmaos-apps/news", "XTERM_VERSION": "5.5.0", "ZENFS_VERSION": "2.4.2" };
72719
73898
  var define_import_meta_env_AUTHOR_default = { name: "Jay Mathis", email: "code@mathis.network", url: "https://github.com/mathiscode" };
72720
73899
  var define_import_meta_env_KNOWN_ISSUES_default = ["It's best to stick to Chromium-based browsers for the most features", "Keyboard is broken on mobile; ecmaOS is not mobile-friendly at this time", "Don't expect any sort of POSIX compliance at this stage", "Most commands/devices are very basic implementations, not complete reproductions", "stdin/stdout/stderr streams and redirection can be wonky and don't work everywhere, but are coming along", "CTRL-C will return you to a prompt, but doesn't currently interrupt a process", "Lots of unfinished work; watch your step"];
72721
- var define_import_meta_env_TIPS_default = ["If it ever fails to boot, check your logs or try clearing all data", "You can run some devices that offer a CLI - e.g. '/dev/battery --help'", "Use the 'install' command to install packages - e.g. 'install @ecmaos-apps/news'", "You can install any NPM package - e.g. 'install jquery'", "Use the 'news' command to see the latest news about ecmaOS", "Type 'ls /bin' to see all built-in commands", "Type 'ls /usr/bin' to see all installed commands", "You can set your environment variables in ~/.env (try setting PROMPT to a PS1-like format)", "Try 'fetch /xkcd-os.sixel'"];
73900
+ var define_import_meta_env_TIPS_default = ["If it ever fails to boot, check your logs, try clearing all data, try incognito mode, or try another browser", "You can run some devices that offer a CLI - e.g. '/dev/battery --help'", "Use the 'install' command to install packages - e.g. 'install @ecmaos-apps/news'", "You can install any NPM package - e.g. 'install jquery'", "Use the 'news' command to see the latest news about ecmaOS", "Type 'ls /bin' to see all built-in commands", "Type 'ls /usr/bin' to see all installed commands", "You can set your environment variables in ~/.env (try setting PROMPT to a PS1-like format)", "You can register and login with a passkey: 'passkey register' and 'passkey list'", "Try 'fetch /xkcd-os.sixel'"];
72722
73901
  const DefaultKernelOptions = {
72723
73902
  devices: DefaultDevices,
72724
73903
  dom: DefaultDomOptions,
@@ -72760,7 +73939,7 @@ const _Kernel = class _Kernel {
72760
73939
  /** Name of the kernel */
72761
73940
  __publicField(this, "name", "@ecmaos/kernel");
72762
73941
  /** Version string of the kernel */
72763
- __publicField(this, "version", "0.6.3");
73942
+ __publicField(this, "version", "0.6.5");
72764
73943
  /** Authentication and authorization service */
72765
73944
  __publicField(this, "auth");
72766
73945
  /** BIOS module providing low-level functionality */
@@ -72918,7 +74097,7 @@ const _Kernel = class _Kernel {
72918
74097
  ];
72919
74098
  this.terminal.writeln(chalk$2.red.bold(`🐉 ${t2("kernel.experimental", "EXPERIMENTAL")} 🐉`));
72920
74099
  this.terminal.writeln(
72921
- `${this.terminal.createSpecialLink("https://ecmaos.sh", "@ecmaos/kernel")}@${"0.6.3"}` + chalk$2.cyan(` [${dependencyLinks.map((link2) => link2.link).join(", ")}]`)
74100
+ `${this.terminal.createSpecialLink("https://ecmaos.sh", "@ecmaos/kernel")}@${"0.6.5"}` + chalk$2.cyan(` [${dependencyLinks.map((link2) => link2.link).join(", ")}]`)
72922
74101
  );
72923
74102
  this.terminal.writeln(`${t2("kernel.madeBy", "Made with ❤️ by Jay Mathis")} ${this.terminal.createSpecialLink(
72924
74103
  define_import_meta_env_AUTHOR_default?.url || "https://github.com/mathiscode",
@@ -72935,14 +74114,14 @@ const _Kernel = class _Kernel {
72935
74114
  if (logoFiglet && true) {
72936
74115
  console.log(`%c${logoFiglet}`, "color: green");
72937
74116
  console.log(`%c${"https://github.com/ecmaos/ecmaos"}`, "color: blue; text-decoration: underline; font-size: 16px");
72938
- this.log.info(`${"@ecmaos/kernel"} v${"0.6.3"}`);
74117
+ this.log.info(`${"@ecmaos/kernel"} v${"0.6.5"}`);
72939
74118
  }
72940
74119
  if (Notification?.permission === "default") Notification.requestPermission();
72941
74120
  if (Notification?.permission === "denied") this.log.warn(t2("kernel.permissionNotificationDenied", "Notification permission denied"));
72942
74121
  this.intervals.set("title-blink", () => {
72943
74122
  globalThis.document.title = globalThis.document.title.includes("_") ? "ecmaos# " : "ecmaos# _";
72944
74123
  }, 600);
72945
- this.toast.success(`${"@ecmaos/kernel"} v${"0.6.3"}`);
74124
+ this.toast.success(`${"@ecmaos/kernel"} v${"0.6.5"}`);
72946
74125
  }
72947
74126
  await this.configure({ devices: this.options.devices || DefaultDevices, filesystem: Filesystem.options() });
72948
74127
  const requiredPaths = [
@@ -73103,20 +74282,62 @@ const _Kernel = class _Kernel {
73103
74282
  const icon = isSecure ? "🔒" : "🔓";
73104
74283
  this.terminal.writeln(`${icon} ${protocolStr}//${hostname}${port}`);
73105
74284
  const username = await this.terminal.readline(`👤 ${this.i18n.t("Username")}: `);
73106
- const password = await this.terminal.readline(`🔑 ${this.i18n.t("Password")}: `, true);
73107
- const { user: user22, cred } = await this.users.login(username, password);
73108
- this.shell.credentials = cred;
73109
- this.shell.context = bindContext({ root: "/", pwd: "/", credentials: cred });
74285
+ const user22 = Array.from(this.users.all.values()).find((u) => u.username === username);
74286
+ let loginSuccess = false;
74287
+ let userCred = null;
74288
+ if (user22) {
74289
+ const passkeys = await this.users.getPasskeys(user22.uid);
74290
+ if (passkeys.length > 0 && this.auth.passkey.isSupported()) {
74291
+ try {
74292
+ const challenge = crypto.getRandomValues(new Uint8Array(32));
74293
+ const rpId = globalThis.location.hostname || "localhost";
74294
+ const allowCredentials = passkeys.map((pk) => {
74295
+ const credentialIdBytes = Uint8Array.from(atob(pk.credentialId), (c) => c.charCodeAt(0));
74296
+ return {
74297
+ id: credentialIdBytes.buffer,
74298
+ type: "public-key",
74299
+ transports: ["usb", "nfc", "ble", "internal"]
74300
+ };
74301
+ });
74302
+ const requestOptions = {
74303
+ challenge,
74304
+ allowCredentials,
74305
+ rpId,
74306
+ userVerification: "preferred",
74307
+ timeout: 6e4
74308
+ };
74309
+ this.terminal.writeln(chalk$2.yellow("🔐 Please use your passkey to authenticate..."));
74310
+ const credential = await this.auth.passkey.get(requestOptions);
74311
+ if (credential && credential instanceof PublicKeyCredential) {
74312
+ userCred = await this.users.login(username, void 0, credential);
74313
+ loginSuccess = true;
74314
+ } else {
74315
+ this.terminal.writeln(chalk$2.yellow("Passkey authentication cancelled or failed. Falling back to password..."));
74316
+ }
74317
+ } catch (err2) {
74318
+ this.terminal.writeln(chalk$2.yellow(`Passkey authentication error: ${err2.message}. Falling back to password...`));
74319
+ }
74320
+ }
74321
+ }
74322
+ if (!loginSuccess) {
74323
+ const password = await this.terminal.readline(`🔑 ${this.i18n.t("Password")}: `, true);
74324
+ userCred = await this.users.login(username, password);
74325
+ }
74326
+ if (!userCred) {
74327
+ throw new Error("Login failed");
74328
+ }
74329
+ this.shell.credentials = userCred.cred;
74330
+ this.shell.context = bindContext({ root: "/", pwd: "/", credentials: userCred.cred });
73110
74331
  await this.shell.loadEnvFile();
73111
- this.shell.env.set("UID", user22.uid.toString());
73112
- this.shell.env.set("GID", user22.gid.toString());
73113
- this.shell.env.set("SUID", cred.suid.toString());
73114
- this.shell.env.set("SGID", cred.sgid.toString());
73115
- this.shell.env.set("EUID", cred.euid.toString());
73116
- this.shell.env.set("EGID", cred.egid.toString());
73117
- this.shell.env.set("SHELL", user22.shell || "ecmaos");
73118
- this.shell.env.set("HOME", user22.home || "/root");
73119
- this.shell.env.set("USER", user22.username);
74332
+ this.shell.env.set("UID", userCred.user.uid.toString());
74333
+ this.shell.env.set("GID", userCred.user.gid.toString());
74334
+ this.shell.env.set("SUID", userCred.cred.suid.toString());
74335
+ this.shell.env.set("SGID", userCred.cred.sgid.toString());
74336
+ this.shell.env.set("EUID", userCred.cred.euid.toString());
74337
+ this.shell.env.set("EGID", userCred.cred.egid.toString());
74338
+ this.shell.env.set("SHELL", userCred.user.shell || "ecmaos");
74339
+ this.shell.env.set("HOME", userCred.user.home || "/root");
74340
+ this.shell.env.set("USER", userCred.user.username);
73120
74341
  process$1.env = Object.fromEntries(this.shell.env);
73121
74342
  break;
73122
74343
  } catch (err2) {
@@ -73174,7 +74395,7 @@ const _Kernel = class _Kernel {
73174
74395
  this._state = KernelState.RUNNING;
73175
74396
  this.setupDebugGlobals();
73176
74397
  if (!this.storage.local.getItem("ecmaos:first-boot")) {
73177
- const recommendedApps = "@ecmaos-apps/code,@ecmaos-apps/webamp,@ecmaos-apps/news";
74398
+ const recommendedApps = "@ecmaos-apps/code,@ecmaos-apps/edit,@ecmaos-apps/ai,@ecmaos-apps/webamp,@ecmaos-apps/news";
73178
74399
  if (recommendedApps) {
73179
74400
  const apps = recommendedApps.split(",");
73180
74401
  this.terminal.writeln("\n" + chalk$2.yellow.bold(this.i18n.t("kernel.recommendedApps", "Recommended apps:")));
@@ -73187,7 +74408,7 @@ const _Kernel = class _Kernel {
73187
74408
  }
73188
74409
  this.storage.local.setItem("ecmaos:first-boot", Date.now().toString());
73189
74410
  }
73190
- this.terminal.write(ansi$6.erase.inLine(2) + this.terminal.prompt());
74411
+ this.terminal.write(ansi$7.erase.inLine(2) + this.terminal.prompt());
73191
74412
  this.terminal.focus();
73192
74413
  this.terminal.listen();
73193
74414
  } catch (error) {
@@ -73646,7 +74867,7 @@ const _Kernel = class _Kernel {
73646
74867
  memory: "?",
73647
74868
  platform: navigator.userAgentData?.platform || navigator?.platform || navigator.userAgent,
73648
74869
  querystring: location.search,
73649
- version: `${"@ecmaos/kernel"} ${"0.6.3"}`,
74870
+ version: `${"@ecmaos/kernel"} ${"0.6.5"}`,
73650
74871
  language: navigator.language,
73651
74872
  host: location.host,
73652
74873
  userAgent: navigator.userAgent,
@@ -73823,4 +75044,4 @@ export {
73823
75044
  path$1 as p,
73824
75045
  semver as s
73825
75046
  };
73826
- //# sourceMappingURL=kernel-DEdzF9cH.js.map
75047
+ //# sourceMappingURL=kernel-C_Xvcpox.js.map