@poe-platform/safe-bash 0.1.511 → 0.1.513

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/safe-bash/chunks/{chunk-5HT35GTV.js → chunk-5MSOBYRG.js} +2 -2
  2. package/dist/safe-bash/chunks/{chunk-B637PJBS.js → chunk-5OCQTFXT.js} +1 -1
  3. package/dist/safe-bash/chunks/{chunk-B637PJBS.js.map → chunk-5OCQTFXT.js.map} +2 -2
  4. package/dist/safe-bash/chunks/{chunk-4OKU6JXB.js → chunk-NYHAKXQ7.js} +2 -2
  5. package/dist/safe-bash/commands/cmp.d.ts +3 -0
  6. package/dist/safe-bash/commands/cmp.d.ts.map +1 -0
  7. package/dist/safe-bash/commands/cmp.js +595 -0
  8. package/dist/safe-bash/commands/cmp.js.map +1 -0
  9. package/dist/safe-bash/commands/fmt.d.ts +3 -0
  10. package/dist/safe-bash/commands/fmt.d.ts.map +1 -0
  11. package/dist/safe-bash/commands/fmt.js +839 -0
  12. package/dist/safe-bash/commands/fmt.js.map +1 -0
  13. package/dist/safe-bash/commands/metadata/index.d.ts.map +1 -1
  14. package/dist/safe-bash/commands/metadata/index.js +2 -1
  15. package/dist/safe-bash/commands/metadata/index.js.map +1 -1
  16. package/dist/safe-bash/commands/numfmt.d.ts +3 -0
  17. package/dist/safe-bash/commands/numfmt.d.ts.map +1 -0
  18. package/dist/safe-bash/commands/numfmt.js +1180 -0
  19. package/dist/safe-bash/commands/numfmt.js.map +1 -0
  20. package/dist/safe-bash/commands/regex-execution/bounded-provider.d.ts +1 -1
  21. package/dist/safe-bash/commands/regex-execution/bounded-provider.d.ts.map +1 -1
  22. package/dist/safe-bash/commands/regex-execution/bounded-provider.js +7 -35
  23. package/dist/safe-bash/commands/regex-execution/bounded-provider.js.map +1 -1
  24. package/dist/safe-bash/commands/regex-execution/ere/matcher.d.ts +2 -0
  25. package/dist/safe-bash/commands/regex-execution/ere/matcher.d.ts.map +1 -1
  26. package/dist/safe-bash/commands/regex-execution/ere/matcher.js +55 -1
  27. package/dist/safe-bash/commands/regex-execution/ere/matcher.js.map +1 -1
  28. package/dist/safe-bash/commands/regex-execution/ere/syntax.js +1 -1
  29. package/dist/safe-bash/commands/regex-execution/ere/syntax.js.map +1 -1
  30. package/dist/safe-bash/commands/regex-execution/ere/types.d.ts +1 -0
  31. package/dist/safe-bash/commands/regex-execution/ere/types.d.ts.map +1 -1
  32. package/dist/safe-bash/commands/regex-execution/utf8.d.ts +3 -0
  33. package/dist/safe-bash/commands/regex-execution/utf8.d.ts.map +1 -0
  34. package/dist/safe-bash/commands/regex-execution/utf8.js +24 -0
  35. package/dist/safe-bash/commands/regex-execution/utf8.js.map +1 -0
  36. package/dist/safe-bash/commands/shuf.d.ts +3 -0
  37. package/dist/safe-bash/commands/shuf.d.ts.map +1 -0
  38. package/dist/safe-bash/commands/shuf.js +768 -0
  39. package/dist/safe-bash/commands/shuf.js.map +1 -0
  40. package/dist/safe-bash/commands/standard.d.ts.map +1 -1
  41. package/dist/safe-bash/commands/standard.js +5 -0
  42. package/dist/safe-bash/commands/standard.js.map +1 -1
  43. package/dist/safe-bash/commands/truncate.d.ts +4 -0
  44. package/dist/safe-bash/commands/truncate.d.ts.map +1 -0
  45. package/dist/safe-bash/commands/truncate.js +668 -0
  46. package/dist/safe-bash/commands/truncate.js.map +1 -0
  47. package/dist/safe-bash/commands/which/which.d.ts.map +1 -1
  48. package/dist/safe-bash/commands/which/which.js +1 -0
  49. package/dist/safe-bash/commands/which/which.js.map +1 -1
  50. package/dist/safe-bash/commands/xml/index.browser.js +2 -2
  51. package/dist/safe-bash/commands/yq/index.browser.js +2 -2
  52. package/dist/safe-bash/contracts/command.d.ts +11 -1
  53. package/dist/safe-bash/contracts/command.d.ts.map +1 -1
  54. package/dist/safe-bash/contracts/command.js.map +1 -1
  55. package/dist/safe-bash/contracts/filesystem.d.ts +1 -1
  56. package/dist/safe-bash/contracts/filesystem.d.ts.map +1 -1
  57. package/dist/safe-bash/core.browser.js +9481 -789
  58. package/dist/safe-bash/core.browser.js.map +4 -4
  59. package/dist/safe-bash/shell/input.d.ts +15 -4
  60. package/dist/safe-bash/shell/input.d.ts.map +1 -1
  61. package/dist/safe-bash/shell/input.js +211 -9
  62. package/dist/safe-bash/shell/input.js.map +1 -1
  63. package/dist/safe-bash/shell/runtime.d.ts.map +1 -1
  64. package/dist/safe-bash/shell/runtime.js +16 -4
  65. package/dist/safe-bash/shell/runtime.js.map +1 -1
  66. package/package.json +2 -2
  67. /package/dist/safe-bash/chunks/{chunk-5HT35GTV.js.map → chunk-5MSOBYRG.js.map} +0 -0
  68. /package/dist/safe-bash/chunks/{chunk-4OKU6JXB.js.map → chunk-NYHAKXQ7.js.map} +0 -0
@@ -0,0 +1,1180 @@
1
+ import { FsError, getCommandArguments, readBytes, writeBytes } from "../contracts/index.js";
2
+ import { createOutputOperation } from "../contracts/output.js";
3
+ import { shellValueByteLength } from "../contracts/value.js";
4
+ import { yieldTurn } from "../contracts/yield.js";
5
+ import { PublicDiagnostic, publicDiagnosticMessage } from "../diagnostics.js";
6
+ import { bufferLimit, encoder } from "./internal.js";
7
+ import { RecordBuffer } from "./record-buffer.js";
8
+ const glibc231PrintableRanges = [
9
+ 0x20, 0x7e, 0xa0, 0x377, 0x37a, 0x37f, 0x384, 0x38a, 0x38c, 0x38c, 0x38e, 0x3a1, 0x3a3, 0x52f, 0x531, 0x556,
10
+ 0x559, 0x55f, 0x561, 0x587, 0x589, 0x58a, 0x58d, 0x58f, 0x591, 0x5c7, 0x5d0, 0x5ea, 0x5f0, 0x5f4, 0x600, 0x61c,
11
+ 0x61e, 0x70d, 0x70f, 0x74a, 0x74d, 0x7b1, 0x7c0, 0x7fa, 0x800, 0x82d, 0x830, 0x83e, 0x840, 0x85b, 0x85e, 0x85e,
12
+ 0x8a0, 0x8b4, 0x8b6, 0x8bd, 0x8d4, 0x983, 0x985, 0x98c, 0x98f, 0x990, 0x993, 0x9a8, 0x9aa, 0x9b0, 0x9b2, 0x9b2,
13
+ 0x9b6, 0x9b9, 0x9bc, 0x9c4, 0x9c7, 0x9c8, 0x9cb, 0x9ce, 0x9d7, 0x9d7, 0x9dc, 0x9dd, 0x9df, 0x9e3, 0x9e6, 0x9fb,
14
+ 0xa01, 0xa03, 0xa05, 0xa0a, 0xa0f, 0xa10, 0xa13, 0xa28, 0xa2a, 0xa30, 0xa32, 0xa33, 0xa35, 0xa36, 0xa38, 0xa39,
15
+ 0xa3c, 0xa3c, 0xa3e, 0xa42, 0xa47, 0xa48, 0xa4b, 0xa4d, 0xa51, 0xa51, 0xa59, 0xa5c, 0xa5e, 0xa5e, 0xa66, 0xa75,
16
+ 0xa81, 0xa83, 0xa85, 0xa8d, 0xa8f, 0xa91, 0xa93, 0xaa8, 0xaaa, 0xab0, 0xab2, 0xab3, 0xab5, 0xab9, 0xabc, 0xac5,
17
+ 0xac7, 0xac9, 0xacb, 0xacd, 0xad0, 0xad0, 0xae0, 0xae3, 0xae6, 0xaf1, 0xaf9, 0xaf9, 0xb01, 0xb03, 0xb05, 0xb0c,
18
+ 0xb0f, 0xb10, 0xb13, 0xb28, 0xb2a, 0xb30, 0xb32, 0xb33, 0xb35, 0xb39, 0xb3c, 0xb44, 0xb47, 0xb48, 0xb4b, 0xb4d,
19
+ 0xb56, 0xb57, 0xb5c, 0xb5d, 0xb5f, 0xb63, 0xb66, 0xb77, 0xb82, 0xb83, 0xb85, 0xb8a, 0xb8e, 0xb90, 0xb92, 0xb95,
20
+ 0xb99, 0xb9a, 0xb9c, 0xb9c, 0xb9e, 0xb9f, 0xba3, 0xba4, 0xba8, 0xbaa, 0xbae, 0xbb9, 0xbbe, 0xbc2, 0xbc6, 0xbc8,
21
+ 0xbca, 0xbcd, 0xbd0, 0xbd0, 0xbd7, 0xbd7, 0xbe6, 0xbfa, 0xc00, 0xc03, 0xc05, 0xc0c, 0xc0e, 0xc10, 0xc12, 0xc28,
22
+ 0xc2a, 0xc39, 0xc3d, 0xc44, 0xc46, 0xc48, 0xc4a, 0xc4d, 0xc55, 0xc56, 0xc58, 0xc5a, 0xc60, 0xc63, 0xc66, 0xc6f,
23
+ 0xc78, 0xc83, 0xc85, 0xc8c, 0xc8e, 0xc90, 0xc92, 0xca8, 0xcaa, 0xcb3, 0xcb5, 0xcb9, 0xcbc, 0xcc4, 0xcc6, 0xcc8,
24
+ 0xcca, 0xccd, 0xcd5, 0xcd6, 0xcde, 0xcde, 0xce0, 0xce3, 0xce6, 0xcef, 0xcf1, 0xcf2, 0xd01, 0xd03, 0xd05, 0xd0c,
25
+ 0xd0e, 0xd10, 0xd12, 0xd3a, 0xd3d, 0xd44, 0xd46, 0xd48, 0xd4a, 0xd4f, 0xd54, 0xd63, 0xd66, 0xd7f, 0xd82, 0xd83,
26
+ 0xd85, 0xd96, 0xd9a, 0xdb1, 0xdb3, 0xdbb, 0xdbd, 0xdbd, 0xdc0, 0xdc6, 0xdca, 0xdca, 0xdcf, 0xdd4, 0xdd6, 0xdd6,
27
+ 0xdd8, 0xddf, 0xde6, 0xdef, 0xdf2, 0xdf4, 0xe01, 0xe3a, 0xe3f, 0xe5b, 0xe81, 0xe82, 0xe84, 0xe84, 0xe87, 0xe88,
28
+ 0xe8a, 0xe8a, 0xe8d, 0xe8d, 0xe94, 0xe97, 0xe99, 0xe9f, 0xea1, 0xea3, 0xea5, 0xea5, 0xea7, 0xea7, 0xeaa, 0xeab,
29
+ 0xead, 0xeb9, 0xebb, 0xebd, 0xec0, 0xec4, 0xec6, 0xec6, 0xec8, 0xecd, 0xed0, 0xed9, 0xedc, 0xedf, 0xf00, 0xf47,
30
+ 0xf49, 0xf6c, 0xf71, 0xf97, 0xf99, 0xfbc, 0xfbe, 0xfcc, 0xfce, 0xfda, 0x1000, 0x10c5, 0x10c7, 0x10c7, 0x10cd, 0x10cd,
31
+ 0x10d0, 0x1248, 0x124a, 0x124d, 0x1250, 0x1256, 0x1258, 0x1258, 0x125a, 0x125d, 0x1260, 0x1288, 0x128a, 0x128d, 0x1290, 0x12b0,
32
+ 0x12b2, 0x12b5, 0x12b8, 0x12be, 0x12c0, 0x12c0, 0x12c2, 0x12c5, 0x12c8, 0x12d6, 0x12d8, 0x1310, 0x1312, 0x1315, 0x1318, 0x135a,
33
+ 0x135d, 0x137c, 0x1380, 0x1399, 0x13a0, 0x13f5, 0x13f8, 0x13fd, 0x1400, 0x169c, 0x16a0, 0x16f8, 0x1700, 0x170c, 0x170e, 0x1714,
34
+ 0x1720, 0x1736, 0x1740, 0x1753, 0x1760, 0x176c, 0x176e, 0x1770, 0x1772, 0x1773, 0x1780, 0x17dd, 0x17e0, 0x17e9, 0x17f0, 0x17f9,
35
+ 0x1800, 0x180e, 0x1810, 0x1819, 0x1820, 0x1877, 0x1880, 0x18aa, 0x18b0, 0x18f5, 0x1900, 0x191e, 0x1920, 0x192b, 0x1930, 0x193b,
36
+ 0x1940, 0x1940, 0x1944, 0x196d, 0x1970, 0x1974, 0x1980, 0x19ab, 0x19b0, 0x19c9, 0x19d0, 0x19da, 0x19de, 0x1a1b, 0x1a1e, 0x1a5e,
37
+ 0x1a60, 0x1a7c, 0x1a7f, 0x1a89, 0x1a90, 0x1a99, 0x1aa0, 0x1aad, 0x1ab0, 0x1abe, 0x1b00, 0x1b4b, 0x1b50, 0x1b7c, 0x1b80, 0x1bf3,
38
+ 0x1bfc, 0x1c37, 0x1c3b, 0x1c49, 0x1c4d, 0x1c88, 0x1cc0, 0x1cc7, 0x1cd0, 0x1cf6, 0x1cf8, 0x1cf9, 0x1d00, 0x1df5, 0x1dfb, 0x1f15,
39
+ 0x1f18, 0x1f1d, 0x1f20, 0x1f45, 0x1f48, 0x1f4d, 0x1f50, 0x1f57, 0x1f59, 0x1f59, 0x1f5b, 0x1f5b, 0x1f5d, 0x1f5d, 0x1f5f, 0x1f7d,
40
+ 0x1f80, 0x1fb4, 0x1fb6, 0x1fc4, 0x1fc6, 0x1fd3, 0x1fd6, 0x1fdb, 0x1fdd, 0x1fef, 0x1ff2, 0x1ff4, 0x1ff6, 0x1ffe, 0x2000, 0x2027,
41
+ 0x202a, 0x2064, 0x2066, 0x2071, 0x2074, 0x208e, 0x2090, 0x209c, 0x20a0, 0x20be, 0x20d0, 0x20f0, 0x2100, 0x218b, 0x2190, 0x23fe,
42
+ 0x2400, 0x2426, 0x2440, 0x244a, 0x2460, 0x2b73, 0x2b76, 0x2b95, 0x2b98, 0x2bb9, 0x2bbd, 0x2bc8, 0x2bca, 0x2bd1, 0x2bec, 0x2bef,
43
+ 0x2c00, 0x2c2e, 0x2c30, 0x2c5e, 0x2c60, 0x2cf3, 0x2cf9, 0x2d25, 0x2d27, 0x2d27, 0x2d2d, 0x2d2d, 0x2d30, 0x2d67, 0x2d6f, 0x2d70,
44
+ 0x2d7f, 0x2d96, 0x2da0, 0x2da6, 0x2da8, 0x2dae, 0x2db0, 0x2db6, 0x2db8, 0x2dbe, 0x2dc0, 0x2dc6, 0x2dc8, 0x2dce, 0x2dd0, 0x2dd6,
45
+ 0x2dd8, 0x2dde, 0x2de0, 0x2e44, 0x2e80, 0x2e99, 0x2e9b, 0x2ef3, 0x2f00, 0x2fd5, 0x2ff0, 0x2ffb, 0x3000, 0x303f, 0x3041, 0x3096,
46
+ 0x3099, 0x30ff, 0x3105, 0x312d, 0x3131, 0x318e, 0x3190, 0x31ba, 0x31c0, 0x31e3, 0x31f0, 0x321e, 0x3220, 0x32fe, 0x3300, 0x4db5,
47
+ 0x4dc0, 0x9fd5, 0xa000, 0xa48c, 0xa490, 0xa4c6, 0xa4d0, 0xa62b, 0xa640, 0xa6f7, 0xa700, 0xa7ae, 0xa7b0, 0xa7b7, 0xa7f7, 0xa82b,
48
+ 0xa830, 0xa839, 0xa840, 0xa877, 0xa880, 0xa8c5, 0xa8ce, 0xa8d9, 0xa8e0, 0xa8fd, 0xa900, 0xa953, 0xa95f, 0xa97c, 0xa980, 0xa9cd,
49
+ 0xa9cf, 0xa9d9, 0xa9de, 0xa9fe, 0xaa00, 0xaa36, 0xaa40, 0xaa4d, 0xaa50, 0xaa59, 0xaa5c, 0xaac2, 0xaadb, 0xaaf6, 0xab01, 0xab06,
50
+ 0xab09, 0xab0e, 0xab11, 0xab16, 0xab20, 0xab26, 0xab28, 0xab2e, 0xab30, 0xab65, 0xab70, 0xabed, 0xabf0, 0xabf9, 0xac00, 0xd7a3,
51
+ 0xd7b0, 0xd7c6, 0xd7cb, 0xd7fb, 0xe000, 0xfa6d, 0xfa70, 0xfad9, 0xfb00, 0xfb06, 0xfb13, 0xfb17, 0xfb1d, 0xfb36, 0xfb38, 0xfb3c,
52
+ 0xfb3e, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfb46, 0xfbc1, 0xfbd3, 0xfd3f, 0xfd50, 0xfd8f, 0xfd92, 0xfdc7, 0xfdf0, 0xfdfd,
53
+ 0xfe00, 0xfe19, 0xfe20, 0xfe52, 0xfe54, 0xfe66, 0xfe68, 0xfe6b, 0xfe70, 0xfe74, 0xfe76, 0xfefc, 0xfeff, 0xfeff, 0xff01, 0xffbe,
54
+ 0xffc2, 0xffc7, 0xffca, 0xffcf, 0xffd2, 0xffd7, 0xffda, 0xffdc, 0xffe0, 0xffe6, 0xffe8, 0xffee, 0xfff9, 0xfffd, 0x10000, 0x1000b,
55
+ 0x1000d, 0x10026, 0x10028, 0x1003a, 0x1003c, 0x1003d, 0x1003f, 0x1004d, 0x10050, 0x1005d, 0x10080, 0x100fa, 0x10100, 0x10102, 0x10107, 0x10133,
56
+ 0x10137, 0x1018e, 0x10190, 0x1019b, 0x101a0, 0x101a0, 0x101d0, 0x101fd, 0x10280, 0x1029c, 0x102a0, 0x102d0, 0x102e0, 0x102fb, 0x10300, 0x10323,
57
+ 0x10330, 0x1034a, 0x10350, 0x1037a, 0x10380, 0x1039d, 0x1039f, 0x103c3, 0x103c8, 0x103d5, 0x10400, 0x1049d, 0x104a0, 0x104a9, 0x104b0, 0x104d3,
58
+ 0x104d8, 0x104fb, 0x10500, 0x10527, 0x10530, 0x10563, 0x1056f, 0x1056f, 0x10600, 0x10736, 0x10740, 0x10755, 0x10760, 0x10767, 0x10800, 0x10805,
59
+ 0x10808, 0x10808, 0x1080a, 0x10835, 0x10837, 0x10838, 0x1083c, 0x1083c, 0x1083f, 0x10855, 0x10857, 0x1089e, 0x108a7, 0x108af, 0x108e0, 0x108f2,
60
+ 0x108f4, 0x108f5, 0x108fb, 0x1091b, 0x1091f, 0x10939, 0x1093f, 0x1093f, 0x10980, 0x109b7, 0x109bc, 0x109cf, 0x109d2, 0x10a03, 0x10a05, 0x10a06,
61
+ 0x10a0c, 0x10a13, 0x10a15, 0x10a17, 0x10a19, 0x10a33, 0x10a38, 0x10a3a, 0x10a3f, 0x10a47, 0x10a50, 0x10a58, 0x10a60, 0x10a9f, 0x10ac0, 0x10ae6,
62
+ 0x10aeb, 0x10af6, 0x10b00, 0x10b35, 0x10b39, 0x10b55, 0x10b58, 0x10b72, 0x10b78, 0x10b91, 0x10b99, 0x10b9c, 0x10ba9, 0x10baf, 0x10c00, 0x10c48,
63
+ 0x10c80, 0x10cb2, 0x10cc0, 0x10cf2, 0x10cfa, 0x10cff, 0x10e60, 0x10e7e, 0x11000, 0x1104d, 0x11052, 0x1106f, 0x1107f, 0x110c1, 0x110d0, 0x110e8,
64
+ 0x110f0, 0x110f9, 0x11100, 0x11134, 0x11136, 0x11143, 0x11150, 0x11176, 0x11180, 0x111cd, 0x111d0, 0x111df, 0x111e1, 0x111f4, 0x11200, 0x11211,
65
+ 0x11213, 0x1123e, 0x11280, 0x11286, 0x11288, 0x11288, 0x1128a, 0x1128d, 0x1128f, 0x1129d, 0x1129f, 0x112a9, 0x112b0, 0x112ea, 0x112f0, 0x112f9,
66
+ 0x11300, 0x11303, 0x11305, 0x1130c, 0x1130f, 0x11310, 0x11313, 0x11328, 0x1132a, 0x11330, 0x11332, 0x11333, 0x11335, 0x11339, 0x1133c, 0x11344,
67
+ 0x11347, 0x11348, 0x1134b, 0x1134d, 0x11350, 0x11350, 0x11357, 0x11357, 0x1135d, 0x11363, 0x11366, 0x1136c, 0x11370, 0x11374, 0x11400, 0x11459,
68
+ 0x1145b, 0x1145b, 0x1145d, 0x1145d, 0x11480, 0x114c7, 0x114d0, 0x114d9, 0x11580, 0x115b5, 0x115b8, 0x115dd, 0x11600, 0x11644, 0x11650, 0x11659,
69
+ 0x11660, 0x1166c, 0x11680, 0x116b7, 0x116c0, 0x116c9, 0x11700, 0x11719, 0x1171d, 0x1172b, 0x11730, 0x1173f, 0x118a0, 0x118f2, 0x118ff, 0x118ff,
70
+ 0x11ac0, 0x11af8, 0x11c00, 0x11c08, 0x11c0a, 0x11c36, 0x11c38, 0x11c45, 0x11c50, 0x11c6c, 0x11c70, 0x11c8f, 0x11c92, 0x11ca7, 0x11ca9, 0x11cb6,
71
+ 0x12000, 0x12399, 0x12400, 0x1246e, 0x12470, 0x12474, 0x12480, 0x12543, 0x13000, 0x1342e, 0x14400, 0x14646, 0x16800, 0x16a38, 0x16a40, 0x16a5e,
72
+ 0x16a60, 0x16a69, 0x16a6e, 0x16a6f, 0x16ad0, 0x16aed, 0x16af0, 0x16af5, 0x16b00, 0x16b45, 0x16b50, 0x16b59, 0x16b5b, 0x16b61, 0x16b63, 0x16b77,
73
+ 0x16b7d, 0x16b8f, 0x16f00, 0x16f44, 0x16f50, 0x16f7e, 0x16f8f, 0x16f9f, 0x16fe0, 0x16fe0, 0x17000, 0x187ec, 0x18800, 0x18af2, 0x1b000, 0x1b001,
74
+ 0x1bc00, 0x1bc6a, 0x1bc70, 0x1bc7c, 0x1bc80, 0x1bc88, 0x1bc90, 0x1bc99, 0x1bc9c, 0x1bca3, 0x1d000, 0x1d0f5, 0x1d100, 0x1d126, 0x1d129, 0x1d1e8,
75
+ 0x1d200, 0x1d245, 0x1d300, 0x1d356, 0x1d360, 0x1d371, 0x1d400, 0x1d454, 0x1d456, 0x1d49c, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a2, 0x1d4a5, 0x1d4a6,
76
+ 0x1d4a9, 0x1d4ac, 0x1d4ae, 0x1d4b9, 0x1d4bb, 0x1d4bb, 0x1d4bd, 0x1d4c3, 0x1d4c5, 0x1d505, 0x1d507, 0x1d50a, 0x1d50d, 0x1d514, 0x1d516, 0x1d51c,
77
+ 0x1d51e, 0x1d539, 0x1d53b, 0x1d53e, 0x1d540, 0x1d544, 0x1d546, 0x1d546, 0x1d54a, 0x1d550, 0x1d552, 0x1d6a5, 0x1d6a8, 0x1d7cb, 0x1d7ce, 0x1da8b,
78
+ 0x1da9b, 0x1da9f, 0x1daa1, 0x1daaf, 0x1e000, 0x1e006, 0x1e008, 0x1e018, 0x1e01b, 0x1e021, 0x1e023, 0x1e024, 0x1e026, 0x1e02a, 0x1e800, 0x1e8c4,
79
+ 0x1e8c7, 0x1e8d6, 0x1e900, 0x1e94a, 0x1e950, 0x1e959, 0x1e95e, 0x1e95f, 0x1ee00, 0x1ee03, 0x1ee05, 0x1ee1f, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee24,
80
+ 0x1ee27, 0x1ee27, 0x1ee29, 0x1ee32, 0x1ee34, 0x1ee37, 0x1ee39, 0x1ee39, 0x1ee3b, 0x1ee3b, 0x1ee42, 0x1ee42, 0x1ee47, 0x1ee47, 0x1ee49, 0x1ee49,
81
+ 0x1ee4b, 0x1ee4b, 0x1ee4d, 0x1ee4f, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee54, 0x1ee57, 0x1ee57, 0x1ee59, 0x1ee59, 0x1ee5b, 0x1ee5b, 0x1ee5d, 0x1ee5d,
82
+ 0x1ee5f, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee64, 0x1ee67, 0x1ee6a, 0x1ee6c, 0x1ee72, 0x1ee74, 0x1ee77, 0x1ee79, 0x1ee7c, 0x1ee7e, 0x1ee7e,
83
+ 0x1ee80, 0x1ee89, 0x1ee8b, 0x1ee9b, 0x1eea1, 0x1eea3, 0x1eea5, 0x1eea9, 0x1eeab, 0x1eebb, 0x1eef0, 0x1eef1, 0x1f000, 0x1f02b, 0x1f030, 0x1f093,
84
+ 0x1f0a0, 0x1f0ae, 0x1f0b1, 0x1f0bf, 0x1f0c1, 0x1f0cf, 0x1f0d1, 0x1f0f5, 0x1f100, 0x1f10c, 0x1f110, 0x1f12e, 0x1f130, 0x1f16b, 0x1f170, 0x1f1ac,
85
+ 0x1f1e6, 0x1f202, 0x1f210, 0x1f23b, 0x1f240, 0x1f248, 0x1f250, 0x1f251, 0x1f300, 0x1f6d2, 0x1f6e0, 0x1f6ec, 0x1f6f0, 0x1f6f6, 0x1f700, 0x1f773,
86
+ 0x1f780, 0x1f7d4, 0x1f800, 0x1f80b, 0x1f810, 0x1f847, 0x1f850, 0x1f859, 0x1f860, 0x1f887, 0x1f890, 0x1f8ad, 0x1f910, 0x1f91e, 0x1f920, 0x1f927,
87
+ 0x1f930, 0x1f930, 0x1f933, 0x1f93e, 0x1f940, 0x1f94b, 0x1f950, 0x1f95e, 0x1f980, 0x1f991, 0x1f9c0, 0x1f9c0, 0x20000, 0x2a6d6, 0x2a700, 0x2b734,
88
+ 0x2b740, 0x2b81d, 0x2b820, 0x2cea1, 0x2f800, 0x2fa1d, 0xe0001, 0xe0001, 0xe0020, 0xe007f, 0xe0100, 0xe01ef, 0xf0000, 0xffffd, 0x100000, 0x10fffd,
89
+ ];
90
+ const helpText = [
91
+ "Usage: numfmt [OPTION]... [NUMBER]...",
92
+ "Reformat NUMBER(s), or the numbers from standard input if none are specified.",
93
+ "",
94
+ "Mandatory arguments to long options are mandatory for short options too.",
95
+ " --debug print warnings about invalid input",
96
+ " -d, --delimiter=X use X instead of whitespace for field delimiter",
97
+ " --field=FIELDS replace the numbers in these input fields (default=1)",
98
+ " see FIELDS below",
99
+ " --format=FORMAT use printf style floating-point FORMAT;",
100
+ " see FORMAT below for details",
101
+ " --from=UNIT auto-scale input numbers to UNITs; default is 'none';",
102
+ " see UNIT below",
103
+ " --from-unit=N specify the input unit size (instead of the default 1)",
104
+ " --grouping use locale-defined grouping of digits, e.g. 1,000,000",
105
+ " (which means it has no effect in the C/POSIX locale)",
106
+ " --header[=N] print (without converting) the first N header lines;",
107
+ " N defaults to 1 if not specified",
108
+ " --invalid=MODE failure mode for invalid numbers: MODE can be:",
109
+ " abort (default), fail, warn, ignore",
110
+ " --padding=N pad the output to N characters; positive N will",
111
+ " right-align; negative N will left-align;",
112
+ " padding is ignored if the output is wider than N;",
113
+ " the default is to automatically pad if a whitespace",
114
+ " is found",
115
+ " --round=METHOD use METHOD for rounding when scaling; METHOD can be:",
116
+ " up, down, from-zero (default), towards-zero, nearest",
117
+ " --suffix=SUFFIX add SUFFIX to output numbers, and accept optional",
118
+ " SUFFIX in input numbers",
119
+ " --to=UNIT auto-scale output numbers to UNITs; see UNIT below",
120
+ " --to-unit=N the output unit size (instead of the default 1)",
121
+ " -z, --zero-terminated line delimiter is NUL, not newline",
122
+ " --help display this help and exit",
123
+ " --version output version information and exit",
124
+ "",
125
+ "UNIT options:",
126
+ " none no auto-scaling is done; suffixes will trigger an error",
127
+ " auto accept optional single/two letter suffix:",
128
+ " 1K = 1000,",
129
+ " 1Ki = 1024,",
130
+ " 1M = 1000000,",
131
+ " 1Mi = 1048576,",
132
+ " si accept optional single letter suffix:",
133
+ " 1K = 1000,",
134
+ " 1M = 1000000,",
135
+ " ...",
136
+ " iec accept optional single letter suffix:",
137
+ " 1K = 1024,",
138
+ " 1M = 1048576,",
139
+ " ...",
140
+ " iec-i accept optional two-letter suffix:",
141
+ " 1Ki = 1024,",
142
+ " 1Mi = 1048576,",
143
+ " ...",
144
+ "",
145
+ "FIELDS supports cut(1) style field ranges:",
146
+ " N N'th field, counted from 1",
147
+ " N- from N'th field, to end of line",
148
+ " N-M from N'th to M'th field (inclusive)",
149
+ " -M from first to M'th field (inclusive)",
150
+ " - all fields",
151
+ "Multiple fields/ranges can be separated with commas",
152
+ "",
153
+ "FORMAT must be suitable for printing one floating-point argument '%f'.",
154
+ "Optional quote (%'f) will enable --grouping (if supported by current locale).",
155
+ "Optional width value (%10f) will pad output. Optional zero (%010f) width",
156
+ "will zero pad the number. Optional negative values (%-10f) will left align.",
157
+ "Optional precision (%.1f) will override the input determined precision.",
158
+ "",
159
+ "Exit status is 0 if all input numbers were successfully converted.",
160
+ "By default, numfmt will stop at the first conversion error with exit status 2.",
161
+ "With --invalid='fail' a warning is printed for each conversion error",
162
+ "and the exit status is 2. With --invalid='warn' each conversion error is",
163
+ "diagnosed, but the exit status is 0. With --invalid='ignore' conversion",
164
+ "errors are not diagnosed and the exit status is 0.",
165
+ "",
166
+ "Examples:",
167
+ " $ numfmt --to=si 1000",
168
+ " -> \"1.0K\"",
169
+ " $ numfmt --to=iec 2048",
170
+ " -> \"2.0K\"",
171
+ " $ numfmt --to=iec-i 4096",
172
+ " -> \"4.0Ki\"",
173
+ " $ echo 1K | numfmt --from=si",
174
+ " -> \"1000\"",
175
+ " $ echo 1K | numfmt --from=iec",
176
+ " -> \"1024\"",
177
+ " $ df -B1 | numfmt --header --field 2-4 --to=si",
178
+ " $ ls -l | numfmt --header --field 5 --to=iec",
179
+ " $ ls -lh | numfmt --header --field 5 --from=iec --padding=10",
180
+ " $ ls -lh | numfmt --header --field 5 --from=iec --format %10f",
181
+ "",
182
+ "GNU coreutils online help: <https://www.gnu.org/software/coreutils/>",
183
+ "Report numfmt translation bugs to <https://translationproject.org/team/>",
184
+ "Full documentation at: <https://www.gnu.org/software/coreutils/numfmt>",
185
+ "or available locally via: info '(coreutils) numfmt invocation'",
186
+ "",
187
+ ].join("\n");
188
+ const unsignedMaximum = (1n << 64n) - 1n;
189
+ const signedMaximum = (1n << 63n) - 1n;
190
+ const scales = ["none", "auto", "si", "iec", "iec-i"];
191
+ function binary(numerator, denominator = 1n, exponent = 0) {
192
+ if (!numerator)
193
+ return { coefficient: 0n, exponent: 0 };
194
+ const negative = numerator < 0n !== denominator < 0n;
195
+ numerator = numerator < 0n ? -numerator : numerator;
196
+ denominator = denominator < 0n ? -denominator : denominator;
197
+ let shift = numerator.toString(2).length - denominator.toString(2).length;
198
+ if (shift >= 0 ? numerator < denominator << BigInt(shift) : numerator << BigInt(-shift) < denominator)
199
+ shift--;
200
+ const target = Math.max(shift + exponent - 63, -16445);
201
+ const adjustment = exponent - target;
202
+ if (adjustment >= 0)
203
+ numerator <<= BigInt(adjustment);
204
+ else
205
+ denominator <<= BigInt(-adjustment);
206
+ let rounded = numerator / denominator;
207
+ const remainder = numerator % denominator;
208
+ if (remainder * 2n > denominator || remainder * 2n === denominator && rounded % 2n !== 0n)
209
+ rounded++;
210
+ if (target > 16320 || target === 16320 && rounded >= 1n << 64n)
211
+ return { coefficient: negative ? -1n : 1n, exponent: Infinity };
212
+ return { coefficient: negative ? -rounded : rounded, exponent: target, negativeZero: negative && rounded === 0n };
213
+ }
214
+ function add(left, right) {
215
+ const exponent = Math.min(left.exponent, right.exponent);
216
+ const result = binary((left.coefficient << BigInt(left.exponent - exponent)) + (right.coefficient << BigInt(right.exponent - exponent)), 1n, exponent);
217
+ if (!result.coefficient)
218
+ result.negativeZero = left.negativeZero === true && right.negativeZero === true;
219
+ return result;
220
+ }
221
+ function multiply(left, right) {
222
+ if (!left.coefficient || !right.coefficient)
223
+ return { coefficient: 0n, exponent: 0, negativeZero: (left.coefficient < 0n || left.negativeZero === true) !== (right.coefficient < 0n || right.negativeZero === true) };
224
+ return binary(left.coefficient * right.coefficient, 1n, left.exponent + right.exponent);
225
+ }
226
+ function divide(left, right) {
227
+ if (!left.coefficient || right.exponent === Infinity)
228
+ return { coefficient: 0n, exponent: 0, negativeZero: (left.coefficient < 0n || left.negativeZero === true) !== (right.coefficient < 0n || right.negativeZero === true) };
229
+ return binary(left.coefficient, right.coefficient, left.exponent - right.exponent);
230
+ }
231
+ function absolute(value) {
232
+ return { ...value, coefficient: value.coefficient < 0n ? -value.coefficient : value.coefficient, negativeZero: false };
233
+ }
234
+ function negate(value) {
235
+ return { ...value, coefficient: -value.coefficient, negativeZero: value.coefficient === 0n && !value.negativeZero };
236
+ }
237
+ function integer(value) {
238
+ const magnitude = value.coefficient < 0n ? -value.coefficient : value.coefficient;
239
+ const result = value.exponent >= 0 ? magnitude << BigInt(value.exponent) : magnitude >> BigInt(-value.exponent);
240
+ return value.coefficient < 0n ? -result : result;
241
+ }
242
+ function compare(left, right) {
243
+ const difference = add(left, { ...right, coefficient: -right.coefficient }).coefficient;
244
+ return difference < 0n ? -1 : difference > 0n ? 1 : 0;
245
+ }
246
+ function power(base, exponent) {
247
+ if (base === 10 && exponent > 4933)
248
+ return { coefficient: 1n, exponent: Infinity };
249
+ let result = binary(1n);
250
+ const factor = binary(BigInt(base));
251
+ for (let index = 0; index < exponent; index++) {
252
+ result = multiply(result, factor);
253
+ if (result.exponent === Infinity)
254
+ break;
255
+ }
256
+ return result;
257
+ }
258
+ function round(value, method) {
259
+ const maximum = binary(signedMaximum);
260
+ const multiple = integer(divide(value, maximum));
261
+ const high = multiply(maximum, binary(multiple));
262
+ const low = add(value, { ...high, coefficient: -high.coefficient });
263
+ let rounded = integer(low);
264
+ if (method === "nearest")
265
+ rounded = integer(add(low, binary(low.coefficient < 0n ? -1n : 1n, 2n)));
266
+ else if (compare(low, binary(rounded)) !== 0) {
267
+ if (method === "from-zero")
268
+ rounded += low.coefficient < 0n ? -1n : 1n;
269
+ else if (method === "up" && low.coefficient > 0n)
270
+ rounded++;
271
+ else if (method === "down" && low.coefficient < 0n)
272
+ rounded--;
273
+ }
274
+ return add(high, binary(rounded));
275
+ }
276
+ function decimalRounded(value, precision) {
277
+ let numerator = absolute(value).coefficient;
278
+ let denominator = 1n;
279
+ if (precision >= 0)
280
+ numerator *= 10n ** BigInt(precision);
281
+ else
282
+ denominator *= 10n ** BigInt(-precision);
283
+ if (value.exponent >= 0)
284
+ numerator <<= BigInt(value.exponent);
285
+ else
286
+ denominator <<= BigInt(-value.exponent);
287
+ let rounded = numerator / denominator;
288
+ const remainder = numerator % denominator;
289
+ if (remainder * 2n > denominator || remainder * 2n === denominator && rounded % 2n !== 0n)
290
+ rounded++;
291
+ return rounded;
292
+ }
293
+ function fixed(value, precision, grouped = false) {
294
+ const digits = decimalRounded(value, precision).toString().padStart(precision + 1, "0");
295
+ let integral = precision ? digits.slice(0, -precision) : digits;
296
+ if (grouped) {
297
+ const parts = [];
298
+ while (integral.length > 3) {
299
+ parts.unshift(integral.slice(-3));
300
+ integral = integral.slice(0, -3);
301
+ }
302
+ parts.unshift(integral);
303
+ integral = parts.join(",");
304
+ }
305
+ return (value.coefficient < 0n || value.negativeZero ? "-" : "") + integral + (precision ? `.${digits.slice(-precision)}` : "");
306
+ }
307
+ function general(value, uppercase = false) {
308
+ if (!value.coefficient)
309
+ return value.negativeZero ? "-0" : "0";
310
+ const magnitude = absolute(value);
311
+ let numerator = magnitude.coefficient;
312
+ let denominator = 1n;
313
+ if (value.exponent >= 0)
314
+ numerator <<= BigInt(value.exponent);
315
+ else
316
+ denominator <<= BigInt(-value.exponent);
317
+ let decimalExponent = numerator.toString().length - denominator.toString().length;
318
+ if (decimalExponent >= 0 ? numerator < denominator * 10n ** BigInt(decimalExponent) : numerator * 10n ** BigInt(-decimalExponent) < denominator)
319
+ decimalExponent--;
320
+ let significant = decimalRounded(magnitude, 5 - decimalExponent).toString();
321
+ if (significant.length > 6) {
322
+ decimalExponent++;
323
+ significant = decimalRounded(magnitude, 5 - decimalExponent).toString();
324
+ }
325
+ let text;
326
+ if (decimalExponent < -4 || decimalExponent >= 6) {
327
+ text = significant[0] + "." + significant.slice(1);
328
+ while (text.endsWith("0"))
329
+ text = text.slice(0, -1);
330
+ if (text.endsWith("."))
331
+ text = text.slice(0, -1);
332
+ text += `${uppercase ? "E" : "e"}${decimalExponent < 0 ? "-" : "+"}${Math.abs(decimalExponent).toString().padStart(2, "0")}`;
333
+ }
334
+ else {
335
+ text = fixed(magnitude, Math.max(0, 5 - decimalExponent));
336
+ if (text.includes(".")) {
337
+ while (text.endsWith("0"))
338
+ text = text.slice(0, -1);
339
+ if (text.endsWith("."))
340
+ text = text.slice(0, -1);
341
+ }
342
+ }
343
+ return (value.coefficient < 0n ? "-" : "") + text;
344
+ }
345
+ function blank(character) { return character === " " || character === "\t"; }
346
+ function digit(character) { return character !== undefined && character >= "0" && character <= "9"; }
347
+ function byteText(bytes) {
348
+ let text = "";
349
+ for (let offset = 0; offset < bytes.length; offset += 4096)
350
+ text += String.fromCharCode(...bytes.subarray(offset, offset + 4096));
351
+ return text;
352
+ }
353
+ function textBytes(text) {
354
+ const bytes = new Uint8Array(text.length);
355
+ for (let offset = 0; offset < text.length; offset++)
356
+ bytes[offset] = text.charCodeAt(offset);
357
+ return bytes;
358
+ }
359
+ function utf8Size(text) {
360
+ let bytes = 0;
361
+ for (const character of text) {
362
+ const point = character.codePointAt(0);
363
+ bytes += point < 0x80 ? 1 : point < 0x800 ? 2 : point < 0x10000 ? 3 : 4;
364
+ }
365
+ return bytes;
366
+ }
367
+ const utf8Decoder = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
368
+ function quote(text, unicode) {
369
+ const right = unicode ? "\xe2\x80\x99" : "'";
370
+ let result = unicode ? "\xe2\x80\x98" : "'";
371
+ const escapes = { "\x07": "\\a", "\b": "\\b", "\f": "\\f", "\n": "\\n", "\r": "\\r", "\t": "\\t", "\v": "\\v" };
372
+ for (let index = 0; index < text.length;) {
373
+ if (text.startsWith(right, index)) {
374
+ result += `\\${right}`;
375
+ index += right.length;
376
+ continue;
377
+ }
378
+ const character = text[index];
379
+ const code = character.charCodeAt(0);
380
+ if (character === "\\")
381
+ result += "\\\\";
382
+ else if (code >= 32 && code < 127)
383
+ result += character;
384
+ else if (unicode && code >= 194 && code <= 244) {
385
+ const width = code < 224 ? 2 : code < 240 ? 3 : 4;
386
+ const candidate = text.slice(index, index + width);
387
+ let decoded;
388
+ try {
389
+ decoded = utf8Decoder.decode(textBytes(candidate));
390
+ }
391
+ catch {
392
+ decoded = undefined;
393
+ }
394
+ const point = decoded?.codePointAt(0) ?? -1;
395
+ let low = 0;
396
+ let high = glibc231PrintableRanges.length / 2;
397
+ let printable = false;
398
+ while (low < high) {
399
+ const middle = Math.trunc((low + high) / 2);
400
+ if (point < glibc231PrintableRanges[middle * 2])
401
+ high = middle;
402
+ else if (point > glibc231PrintableRanges[middle * 2 + 1])
403
+ low = middle + 1;
404
+ else {
405
+ printable = true;
406
+ break;
407
+ }
408
+ }
409
+ if (decoded !== undefined && printable) {
410
+ result += candidate;
411
+ index += width;
412
+ continue;
413
+ }
414
+ result += `\\${code.toString(8).padStart(3, "0")}`;
415
+ }
416
+ else
417
+ result += escapes[character] ?? `\\${code.toString(8).padStart(3, "0")}`;
418
+ index++;
419
+ }
420
+ return result + right;
421
+ }
422
+ class NumfmtDiagnostic extends Error {
423
+ status;
424
+ help;
425
+ extra;
426
+ constructor(message, status = 1, help = false, extra = "") {
427
+ super(message);
428
+ this.status = status;
429
+ this.help = help;
430
+ this.extra = extra;
431
+ }
432
+ }
433
+ function decimal(text, offset = 0) {
434
+ const start = offset;
435
+ while (text[offset] === " " || (text.charCodeAt(offset) >= 9 && text.charCodeAt(offset) <= 13))
436
+ offset++;
437
+ const negative = text[offset] === "-";
438
+ if (negative || text[offset] === "+")
439
+ offset++;
440
+ const digits = offset;
441
+ let value = 0n;
442
+ while (digit(text[offset])) {
443
+ if (value <= unsignedMaximum)
444
+ value = value * 10n + BigInt(text.charCodeAt(offset) - 48);
445
+ offset++;
446
+ }
447
+ return { value: negative ? -value : value, end: offset === digits ? start : offset, found: offset !== digits, overflow: value > unsignedMaximum };
448
+ }
449
+ function fields(text, unicode) {
450
+ const result = [];
451
+ let initial = 1n;
452
+ let value = 0n;
453
+ let dash = false;
454
+ let left = false;
455
+ let right = false;
456
+ let digitsStart = 0;
457
+ for (let offset = 0;; offset++) {
458
+ const character = text[offset];
459
+ if (character === "-") {
460
+ if (dash)
461
+ throw new NumfmtDiagnostic("invalid field range", 1, true);
462
+ if (left && value === 0n)
463
+ throw new NumfmtDiagnostic("fields are numbered from 1", 1, true);
464
+ dash = true;
465
+ initial = left ? value : 1n;
466
+ value = 0n;
467
+ }
468
+ else if (character === undefined || character === "," || blank(character)) {
469
+ if (dash) {
470
+ if (right && value < initial)
471
+ throw new NumfmtDiagnostic("invalid decreasing range", 1, true);
472
+ result.push([initial, right ? value : unsignedMaximum]);
473
+ }
474
+ else {
475
+ if (!value)
476
+ throw new NumfmtDiagnostic("fields are numbered from 1", 1, true);
477
+ result.push([value, value]);
478
+ }
479
+ if (result.length > 4096)
480
+ throw new PublicDiagnostic("field range limit exceeded");
481
+ if (character === undefined)
482
+ break;
483
+ value = 0n;
484
+ dash = false;
485
+ left = false;
486
+ right = false;
487
+ }
488
+ else if (digit(character)) {
489
+ if (!digit(text[offset - 1]))
490
+ digitsStart = offset;
491
+ if (dash)
492
+ right = true;
493
+ else
494
+ left = true;
495
+ value = value * 10n + BigInt(character.charCodeAt(0) - 48);
496
+ if (value >= unsignedMaximum) {
497
+ let end = offset + 1;
498
+ while (digit(text[end]))
499
+ end++;
500
+ throw new NumfmtDiagnostic(`field number ${quote(text.slice(digitsStart, end), unicode)} is too large`, 1, true);
501
+ }
502
+ }
503
+ else
504
+ throw new NumfmtDiagnostic(`invalid field value ${quote(text.slice(offset), unicode)}`, 1, true);
505
+ }
506
+ result.sort(([left], [right]) => Number(BigInt.asIntN(32, left)) - Number(BigInt.asIntN(32, right)));
507
+ const merged = [];
508
+ for (const range of result) {
509
+ const previous = merged.at(-1);
510
+ if (previous && range[0] <= previous[1]) {
511
+ if (range[1] > previous[1])
512
+ previous[1] = range[1];
513
+ }
514
+ else
515
+ merged.push(range);
516
+ }
517
+ return merged;
518
+ }
519
+ function unit(text, unicode) {
520
+ const parsed = decimal(text);
521
+ let value = parsed.value;
522
+ let tail = text.slice(parsed.end);
523
+ if (!parsed.found && "KMGTPEZY".includes(text[0] ?? "\0")) {
524
+ value = 1n;
525
+ tail = text;
526
+ }
527
+ let valid = parsed.found || value === 1n;
528
+ if (tail) {
529
+ const power = "KMGTPEZY".indexOf(tail[0]) + 1;
530
+ valid &&= power > 0 && (tail.length === 1 || tail.length === 2 && tail[1] === "i");
531
+ if (valid)
532
+ value *= BigInt(tail.length === 2 ? 1024 : 1000) ** BigInt(power);
533
+ }
534
+ if (!valid || parsed.overflow || value <= 0n || value > unsignedMaximum)
535
+ throw new NumfmtDiagnostic(`invalid unit size: ${quote(text, unicode)}`);
536
+ return value;
537
+ }
538
+ function parse(context) {
539
+ const locale = context.env.LC_ALL || context.env.LC_MESSAGES || context.env.LANG || "C";
540
+ const numericLocale = context.env.LC_ALL || context.env.LC_NUMERIC || context.env.LANG || "C";
541
+ const settings = { from: "none", to: "none", fromUnit: 1n, toUnit: 1n, rounding: "from-zero", invalid: "abort", padding: 0n, left: false, zeroPadding: 0n, precision: undefined, grouping: false, delimiter: undefined, separator: "\n", suffix: "", header: 0n, fields: undefined, format: undefined, prefix: "", postfix: "", debug: false, developer: false, unicode: locale.toLowerCase().includes("utf"), thousands: numericLocale.toLowerCase().startsWith("en_us."), localeValid: ["c", "posix", "c.utf-8", "c.utf8", "en_us.utf8", "en_us.utf-8"].includes(locale.toLowerCase()), operands: [] };
542
+ if (context.args.length > 4096)
543
+ throw new PublicDiagnostic("argument limit exceeded");
544
+ let bytes = 0;
545
+ for (const argument of context.args) {
546
+ if (argument.length > 65536 - bytes)
547
+ throw new PublicDiagnostic("argument limit exceeded");
548
+ bytes += context.argumentValues === undefined ? utf8Size(argument) : argument.length;
549
+ if (bytes > 65536)
550
+ throw new PublicDiagnostic("argument limit exceeded");
551
+ }
552
+ const argumentsCarrier = getCommandArguments(context);
553
+ bytes = 0;
554
+ for (const value of argumentsCarrier.values) {
555
+ bytes += typeof value === "string" ? utf8Size(value) : shellValueByteLength(value);
556
+ if (bytes > 65536)
557
+ throw new PublicDiagnostic("argument limit exceeded");
558
+ }
559
+ const args = argumentsCarrier.values.map((value, index) => byteText(typeof value === "string" ? encoder.encode(value) : argumentsCarrier.bytes(index)));
560
+ const options = { from: 1, "from-unit": 1, to: 1, "to-unit": 1, round: 1, padding: 1, suffix: 1, grouping: 0, delimiter: 1, field: 1, debug: 0, "-debug": 0, header: 2, format: 1, invalid: 1, "zero-terminated": 0, help: 0, version: 0 };
561
+ const match = (name, value, choices) => {
562
+ const matches = choices.filter(choice => choice.startsWith(value));
563
+ if (choices.includes(value))
564
+ return value;
565
+ if (matches.length === 1)
566
+ return matches[0];
567
+ throw new NumfmtDiagnostic(`${matches.length ? "ambiguous" : "invalid"} argument ${quote(value, settings.unicode)} for ${quote(`--${name}`, settings.unicode)}`, 1, true, `Valid arguments are:\n${choices.map(choice => ` - ${quote(choice, settings.unicode)}\n`).join("")}`);
568
+ };
569
+ const apply = (name, value) => {
570
+ if (name === "from")
571
+ settings.from = match(name, value, scales);
572
+ else if (name === "to")
573
+ settings.to = match(name, value, scales.filter(scale => scale !== "auto"));
574
+ else if (name === "round")
575
+ settings.rounding = match(name, value, ["up", "down", "from-zero", "towards-zero", "nearest"]);
576
+ else if (name === "invalid")
577
+ settings.invalid = match(name, value, ["abort", "fail", "warn", "ignore"]);
578
+ else if (name === "from-unit")
579
+ settings.fromUnit = unit(value, settings.unicode);
580
+ else if (name === "to-unit")
581
+ settings.toUnit = unit(value, settings.unicode);
582
+ else if (name === "padding" || name === "header") {
583
+ const parsed = decimal(value ?? "1");
584
+ if (!parsed.found || parsed.end !== (value ?? "1").length || parsed.overflow || parsed.value === 0n || (name === "header" ? parsed.value < 0n : parsed.value > signedMaximum || parsed.value < -signedMaximum - 1n))
585
+ throw new NumfmtDiagnostic(`invalid ${name} value ${quote(value, settings.unicode)}`);
586
+ if (name === "header")
587
+ settings.header = parsed.value;
588
+ else {
589
+ if (parsed.value < 0n)
590
+ settings.left = true;
591
+ settings.padding = parsed.value < 0n ? -parsed.value : parsed.value;
592
+ }
593
+ }
594
+ else if (name === "delimiter") {
595
+ if (value.length > 1)
596
+ throw new NumfmtDiagnostic("the delimiter must be a single character");
597
+ settings.delimiter = value || "\0";
598
+ }
599
+ else if (name === "field") {
600
+ if (settings.fields)
601
+ throw new NumfmtDiagnostic("multiple field specifications");
602
+ settings.fields = fields(value, settings.unicode);
603
+ }
604
+ else if (name === "suffix")
605
+ settings.suffix = value;
606
+ else if (name === "format")
607
+ settings.format = value;
608
+ else if (name === "grouping")
609
+ settings.grouping = true;
610
+ else if (name === "debug" || name === "-debug") {
611
+ settings.debug = true;
612
+ if (name === "-debug")
613
+ settings.developer = true;
614
+ }
615
+ else if (name === "zero-terminated")
616
+ settings.separator = "\0";
617
+ else
618
+ settings.information = name;
619
+ };
620
+ let stopped = false;
621
+ for (let index = 0; index < args.length; index++) {
622
+ const argument = args[index];
623
+ if (stopped || argument === "-" || !argument.startsWith("-")) {
624
+ settings.operands.push(argument);
625
+ if (context.env.POSIXLY_CORRECT !== undefined)
626
+ stopped = true;
627
+ }
628
+ else if (argument === "--")
629
+ stopped = true;
630
+ else if (argument.startsWith("--")) {
631
+ const equals = argument.indexOf("=");
632
+ const name = argument.slice(2, equals < 0 ? undefined : equals);
633
+ const matches = Object.keys(options).filter(option => option.startsWith(name));
634
+ const selected = Object.hasOwn(options, name) ? name : matches.length === 1 ? matches[0] : undefined;
635
+ if (!selected)
636
+ throw new NumfmtDiagnostic(matches.length > 1 ? `option '${argument}' is ambiguous; possibilities: ${matches.map(option => `'--${option}'`).join(" ")}` : `unrecognized option '${argument}'`, 1, true);
637
+ if (!options[selected] && equals >= 0)
638
+ throw new NumfmtDiagnostic(`option '--${selected}' doesn't allow an argument`, 1, true);
639
+ const value = equals >= 0 ? argument.slice(equals + 1) : options[selected] === 1 ? args[++index] : undefined;
640
+ if (options[selected] === 1 && value === undefined)
641
+ throw new NumfmtDiagnostic(`option '--${selected}' requires an argument`, 1, true);
642
+ apply(selected, value);
643
+ }
644
+ else
645
+ for (let offset = 1; offset < argument.length; offset++) {
646
+ const option = argument[offset];
647
+ if (option === "z")
648
+ apply("zero-terminated");
649
+ else if (option === "d") {
650
+ const value = offset + 1 < argument.length ? argument.slice(offset + 1) : args[++index];
651
+ if (value === undefined)
652
+ throw new NumfmtDiagnostic("option requires an argument -- 'd'", 1, true);
653
+ apply("delimiter", value);
654
+ break;
655
+ }
656
+ else
657
+ throw new NumfmtDiagnostic(`invalid option -- '${option}'`, 1, true);
658
+ }
659
+ if (settings.information)
660
+ break;
661
+ }
662
+ return settings;
663
+ }
664
+ class Converter {
665
+ settings;
666
+ context;
667
+ output;
668
+ invalid = false;
669
+ autoPadding = false;
670
+ work = 0;
671
+ constructor(settings, context, output) {
672
+ this.settings = settings;
673
+ this.context = context;
674
+ this.output = output;
675
+ }
676
+ async tick(amount = 1) {
677
+ this.work += amount;
678
+ if (this.work > 16 * 1024 * 1024)
679
+ throw new PublicDiagnostic("numfmt work limit exceeded");
680
+ if (this.work % 256 < amount)
681
+ await yieldTurn(this.context.signal);
682
+ this.context.signal.throwIfAborted();
683
+ }
684
+ async warning(message) { await this.output.emit(`numfmt: ${message}\n`, true); }
685
+ async failure(message) {
686
+ this.invalid = true;
687
+ if (this.settings.invalid === "abort")
688
+ throw new NumfmtDiagnostic(message, 2);
689
+ if (this.settings.invalid !== "ignore")
690
+ await this.warning(message);
691
+ return false;
692
+ }
693
+ async initialize() {
694
+ const settings = this.settings;
695
+ if (settings.format !== undefined && settings.grouping)
696
+ throw new NumfmtDiagnostic("--grouping cannot be combined with --format");
697
+ if (settings.debug && !settings.localeValid)
698
+ await this.warning("failed to set locale");
699
+ if (settings.debug && settings.from === "none" && settings.to === "none" && !settings.grouping && !settings.padding && settings.format === undefined)
700
+ await this.warning("no conversion option specified");
701
+ if (settings.format !== undefined)
702
+ await this.parseFormat(settings.format);
703
+ if (settings.grouping) {
704
+ if (settings.to !== "none")
705
+ throw new NumfmtDiagnostic("grouping cannot be combined with --to");
706
+ if (settings.debug && !settings.thousands)
707
+ await this.warning("grouping has no effect in this locale");
708
+ }
709
+ this.autoPadding = !settings.padding && settings.delimiter === undefined;
710
+ if (settings.debug && settings.header && settings.operands.length)
711
+ await this.warning("--header ignored with command-line input");
712
+ }
713
+ async parseFormat(text) {
714
+ const settings = this.settings;
715
+ const quoted = quote(text, settings.unicode);
716
+ let offset = 0;
717
+ let prefix = 0;
718
+ while (!(text[offset] === "%" && text[offset + 1] !== "%")) {
719
+ if (text[offset] === undefined)
720
+ throw new NumfmtDiagnostic(`format ${quoted} has no % directive`);
721
+ offset += text[offset] === "%" ? 2 : 1;
722
+ prefix++;
723
+ }
724
+ offset++;
725
+ let zero = false;
726
+ while (true) {
727
+ if (text[offset] === " ")
728
+ offset++;
729
+ else if (text[offset] === "'") {
730
+ settings.grouping = true;
731
+ offset++;
732
+ }
733
+ else if (text[offset] === "0") {
734
+ zero = true;
735
+ offset++;
736
+ }
737
+ else
738
+ break;
739
+ }
740
+ const width = decimal(text, offset);
741
+ if (width.overflow || width.value > signedMaximum || width.value < -signedMaximum - 1n)
742
+ throw new NumfmtDiagnostic(`invalid format ${quoted} (width overflow)`);
743
+ if (width.found && width.value !== 0n) {
744
+ if (settings.debug && settings.padding && !(zero && width.value > 0n))
745
+ await this.warning("--format padding overriding --padding");
746
+ if (width.value < 0n) {
747
+ settings.padding = -width.value;
748
+ settings.left = true;
749
+ }
750
+ else if (zero)
751
+ settings.zeroPadding = width.value;
752
+ else
753
+ settings.padding = width.value;
754
+ }
755
+ offset = width.end;
756
+ if (text[offset] === undefined)
757
+ throw new NumfmtDiagnostic(`format ${quoted} ends in %`);
758
+ if (text[offset] === ".") {
759
+ offset++;
760
+ const precision = decimal(text, offset);
761
+ if (precision.overflow || precision.value > signedMaximum || precision.value < 0n || blank(text[offset]) || text[offset] === "+")
762
+ throw new NumfmtDiagnostic(`invalid precision in format ${quoted}`);
763
+ settings.precision = precision.value;
764
+ offset = precision.end;
765
+ }
766
+ if (text[offset] !== "f")
767
+ throw new NumfmtDiagnostic(`invalid format ${quoted}, directive must be %[0]['][-][N][.][N]f`);
768
+ const suffix = ++offset;
769
+ while (offset < text.length) {
770
+ if (text[offset] === "%" && text[offset + 1] !== "%")
771
+ throw new NumfmtDiagnostic(`format ${quoted} has too many % directives`);
772
+ offset += text[offset] === "%" ? 2 : 1;
773
+ }
774
+ settings.prefix = text.slice(0, prefix);
775
+ settings.postfix = text.slice(suffix);
776
+ if (settings.developer)
777
+ await this.output.emit(`format String:\n input: ${quoted}\n grouping: ${settings.grouping ? "yes" : "no"}\n padding width: ${settings.padding}\n alignment: ${settings.left ? "Left" : "Right"}\n prefix: ${quote(settings.prefix, settings.unicode)}\n suffix: ${quote(settings.postfix, settings.unicode)}\n`, true);
778
+ }
779
+ async number(text, backing, start) {
780
+ const settings = this.settings;
781
+ const quoted = quote(text, settings.unicode);
782
+ if (settings.developer)
783
+ await this.output.emit(`simple_strtod_human:\n input string: ${quoted}\n locale decimal-point: ${quote(".", settings.unicode)}\n MAX_UNSCALED_DIGITS: 18\n`, true);
784
+ let offset = 0;
785
+ let loss = false;
786
+ let error = "";
787
+ const integral = async () => {
788
+ const negative = text[offset] === "-";
789
+ if (negative)
790
+ offset++;
791
+ const start = offset;
792
+ let value = binary(0n);
793
+ let digits = 0;
794
+ while (digit(text[offset])) {
795
+ if (value.coefficient || text[offset] !== "0")
796
+ digits++;
797
+ if (digits > 18)
798
+ loss = true;
799
+ if (digits > 27) {
800
+ error = "overflow";
801
+ break;
802
+ }
803
+ value = add(multiply(value, binary(10n)), binary(BigInt(text.charCodeAt(offset) - 48)));
804
+ offset++;
805
+ await this.tick();
806
+ }
807
+ if (offset === start && text[offset] !== ".")
808
+ error = "number";
809
+ return { value: negative ? negate(value) : value, negative };
810
+ };
811
+ const main = await integral();
812
+ let value = main.value;
813
+ let precision = 0;
814
+ if (!error && text[offset] === ".") {
815
+ const start = ++offset;
816
+ const fraction = await integral();
817
+ precision = offset - start;
818
+ if (fraction.negative)
819
+ error = "number";
820
+ if (!error) {
821
+ const part = divide(fraction.value, power(10, precision));
822
+ value = add(value, main.negative ? negate(part) : part);
823
+ }
824
+ }
825
+ if (error)
826
+ return this.failure(error === "overflow" ? `value too large to be converted: ${quoted}` : `invalid number: ${quoted}`);
827
+ if (settings.developer)
828
+ await this.output.emit(` parsed numeric value: ${fixed(value, 6)}\n input precision = ${precision}\n`, true);
829
+ let exponent = 0;
830
+ let base = settings.from === "iec" || settings.from === "iec-i" ? 1024 : 1000;
831
+ if (offset < text.length) {
832
+ while (blank(text[offset]))
833
+ offset++;
834
+ const suffix = text[offset];
835
+ if (suffix !== undefined && !"KMGTPEZY".includes(suffix))
836
+ return this.failure(`invalid suffix in input: ${quoted}`);
837
+ if (settings.from === "none")
838
+ return this.failure(`rejecting suffix in input: ${quoted} (consider using --from)`);
839
+ exponent = suffix === undefined ? 0 : "KMGTPEZY".indexOf(suffix) + 1;
840
+ offset++;
841
+ if (settings.from === "auto" && backing[start + offset] === 105) {
842
+ base = 1024;
843
+ offset++;
844
+ if (settings.developer)
845
+ await this.output.emit(" Auto-scaling, found 'i', switching to base 1024\n", true);
846
+ }
847
+ precision = 0;
848
+ }
849
+ if (settings.from === "iec-i") {
850
+ if (backing[start + offset] !== 105)
851
+ return this.failure(`missing 'i' suffix in input: ${quoted} (e.g Ki/Mi/Gi)`);
852
+ offset++;
853
+ }
854
+ const multiplier = power(base, exponent);
855
+ value = multiply(value, multiplier);
856
+ if (settings.developer)
857
+ await this.output.emit(` suffix power=${base}^${exponent} = ${fixed(multiplier, 6)}\n returning value: ${fixed(value, 6)} (${general(value, true)})\n`, true);
858
+ let tail = text.slice(offset);
859
+ if (offset > text.length && backing[start + offset]) {
860
+ if (settings.invalid === "ignore")
861
+ return this.failure("");
862
+ const tailStart = start + offset;
863
+ let tailEnd = tailStart;
864
+ while (tailEnd < backing.length && backing[tailEnd]) {
865
+ tailEnd++;
866
+ if ((tailEnd - tailStart) % 4096 === 0)
867
+ await this.tick(4096);
868
+ }
869
+ await this.tick((tailEnd - tailStart) % 4096);
870
+ tail = byteText(backing.subarray(tailStart, tailEnd));
871
+ }
872
+ if (tail)
873
+ return this.failure(`invalid suffix in input ${quoted}: ${quote(tail, settings.unicode)}`);
874
+ if (loss && settings.debug)
875
+ await this.warning(`large input value ${quoted}: possible precision loss`);
876
+ if (settings.fromUnit !== 1n || settings.toUnit !== 1n)
877
+ value = divide(multiply(value, binary(settings.fromUnit)), binary(settings.toUnit));
878
+ return { value, precision };
879
+ }
880
+ async human(value, inputPrecision) {
881
+ const settings = this.settings;
882
+ const precision = settings.precision ?? BigInt(inputPrecision);
883
+ let decimalPower = 0;
884
+ let reduced = absolute(value);
885
+ while (compare(reduced, binary(10n)) >= 0) {
886
+ reduced = divide(reduced, binary(10n));
887
+ decimalPower++;
888
+ }
889
+ if (settings.to === "none" && BigInt(decimalPower) + precision > 18n)
890
+ return this.failure(precision ? `value/precision too large to be printed: '${general(value)}/${precision}' (consider using --to)` : `value too large to be printed: '${general(value)}' (consider using --to)`);
891
+ if (decimalPower > 26)
892
+ return this.failure(`value too large to be printed: '${general(value)}' (cannot handle values > 999Y)`);
893
+ if (settings.developer)
894
+ await this.output.emit("double_to_human:\n", true);
895
+ let rendered;
896
+ let powerIndex = 0;
897
+ let printedValue = value;
898
+ if (settings.to === "none") {
899
+ const factor = power(10, Number(precision));
900
+ printedValue = divide(round(multiply(value, factor), settings.rounding), factor);
901
+ rendered = fixed(printedValue, Number(precision), settings.grouping && settings.thousands);
902
+ if (settings.developer)
903
+ await this.output.emit(` no scaling, returning ${settings.grouping ? "(grouped) " : ""}value: ${rendered}\n`, true);
904
+ }
905
+ else {
906
+ const base = settings.to === "si" ? 1000 : 1024;
907
+ while (compare(absolute(printedValue), binary(BigInt(base))) >= 0) {
908
+ printedValue = divide(printedValue, binary(BigInt(base)));
909
+ powerIndex++;
910
+ }
911
+ if (settings.developer)
912
+ await this.output.emit(` scaled value to ${fixed(printedValue, 6)} * ${base} ^ ${powerIndex}\n`, true);
913
+ const adjustment = settings.precision === undefined ? compare(absolute(printedValue), binary(10n)) < 0 ? 1 : 0 : Number(settings.precision < BigInt(powerIndex * 3) ? settings.precision : BigInt(powerIndex * 3));
914
+ const factor = power(10, adjustment);
915
+ printedValue = divide(round(multiply(printedValue, factor), settings.rounding), factor);
916
+ if (compare(absolute(printedValue), binary(BigInt(base))) >= 0) {
917
+ printedValue = divide(printedValue, binary(BigInt(base)));
918
+ powerIndex++;
919
+ }
920
+ if (settings.developer)
921
+ await this.output.emit(` after rounding, value=${fixed(printedValue, 6)} * ${base} ^ ${powerIndex}\n`, true);
922
+ let outputPrecision = settings.precision === undefined ? (printedValue.coefficient !== 0n && compare(absolute(printedValue), binary(10n)) < 0 && powerIndex > 0 ? 1n : 0n) : BigInt.asIntN(32, settings.precision);
923
+ if (outputPrecision < 0n)
924
+ outputPrecision = 6n;
925
+ if (outputPrecision > 126n)
926
+ throw new NumfmtDiagnostic(`failed to prepare value '${fixed(printedValue, 6)}' for printing`);
927
+ rendered = fixed(printedValue, Number(outputPrecision));
928
+ }
929
+ if (settings.zeroPadding > 0n) {
930
+ if (settings.zeroPadding > 127n)
931
+ throw new NumfmtDiagnostic(`failed to prepare value '${fixed(printedValue, 6)}' for printing`);
932
+ const negative = rendered.startsWith("-");
933
+ rendered = (negative ? "-" : "") + (negative ? rendered.slice(1) : rendered).padStart(Number(settings.zeroPadding) - Number(negative), "0");
934
+ }
935
+ if (settings.to !== "none")
936
+ rendered += powerIndex ? "KMGTPEZY"[powerIndex - 1] ?? "(error)" : "";
937
+ if (rendered.length >= (settings.to === "none" ? 128 : 127))
938
+ throw new NumfmtDiagnostic(`failed to prepare value '${fixed(printedValue, 6)}' for printing`);
939
+ if (settings.to === "iec-i" && powerIndex)
940
+ rendered += "i";
941
+ if (settings.developer && settings.to !== "none")
942
+ await this.output.emit(` returning value: ${quote(rendered, settings.unicode)}\n`, true);
943
+ rendered += settings.suffix.slice(0, 127 - rendered.length);
944
+ if (settings.developer)
945
+ await this.output.emit(`formatting output:\n value: ${fixed(value, 6)}\n humanized: ${quote(rendered, settings.unicode)}\n`, true);
946
+ if (settings.padding > BigInt(rendered.length)) {
947
+ if (settings.padding > BigInt(this.output.remaining - settings.prefix.length - settings.postfix.length))
948
+ throw new PublicDiagnostic("numfmt output limit exceeded");
949
+ rendered = settings.left ? rendered.padEnd(Number(settings.padding)) : rendered.padStart(Number(settings.padding));
950
+ if (settings.developer)
951
+ await this.output.emit(` After padding: ${quote(rendered, settings.unicode)}\n`, true);
952
+ }
953
+ return rendered;
954
+ }
955
+ async line(line, newline, backing = textBytes(line + "\0")) {
956
+ const settings = this.settings;
957
+ const nul = line.indexOf("\0");
958
+ if (nul >= 0)
959
+ line = line.slice(0, nul);
960
+ let start = 0;
961
+ let field = 0n;
962
+ while (true) {
963
+ field++;
964
+ let end = start;
965
+ if (settings.delimiter !== undefined) {
966
+ while (end < line.length && line[end] !== settings.delimiter)
967
+ end++;
968
+ }
969
+ else {
970
+ while (blank(line[end]) || line[end] === "\n")
971
+ end++;
972
+ while (end < line.length && !blank(line[end]) && line[end] !== "\n")
973
+ end++;
974
+ }
975
+ backing[end] = 0;
976
+ let text = line.slice(start, end);
977
+ await this.tick((settings.fields?.length ?? 0) + 1);
978
+ if (settings.fields ? settings.fields.some(([low, high]) => low <= field && field <= high) : field === 1n) {
979
+ if (settings.suffix && text.length > settings.suffix.length) {
980
+ if (text.endsWith(settings.suffix)) {
981
+ text = text.slice(0, -settings.suffix.length);
982
+ backing[start + text.length] = 0;
983
+ if (settings.developer)
984
+ await this.output.emit(`trimming suffix ${quote(settings.suffix, settings.unicode)}\n`, true);
985
+ }
986
+ else if (settings.developer)
987
+ await this.output.emit("no valid suffix found\n", true);
988
+ }
989
+ let skipped = 0;
990
+ while (blank(text[skipped]))
991
+ skipped++;
992
+ if (this.autoPadding) {
993
+ settings.padding = skipped > 0 || field > 1n ? BigInt(text.length) : 0n;
994
+ if (settings.developer)
995
+ await this.output.emit(`setting Auto-Padding to ${settings.padding} characters\n`, true);
996
+ }
997
+ const parsed = await this.number(text.slice(skipped), backing, start + skipped);
998
+ const converted = parsed && await this.human(parsed.value, parsed.precision);
999
+ await this.output.emit(converted === false ? text : settings.prefix + converted + settings.postfix);
1000
+ }
1001
+ else
1002
+ await this.output.emit(text);
1003
+ if (end >= line.length)
1004
+ break;
1005
+ await this.output.emit(settings.delimiter ?? " ");
1006
+ start = end + 1;
1007
+ }
1008
+ if (newline)
1009
+ await this.output.emit(settings.separator);
1010
+ }
1011
+ }
1012
+ export function numfmtCommand() {
1013
+ return { name: "numfmt", filesystemRequirements: [{ id: "stdin", description: "Format operands or standard input", capabilities: [] }], async execute(context) {
1014
+ context.signal.throwIfAborted();
1015
+ const controller = new AbortController();
1016
+ const local = { ...context, signal: AbortSignal.any([context.signal, controller.signal]) };
1017
+ let iterator;
1018
+ let reader;
1019
+ let finished = false;
1020
+ let retirement;
1021
+ let closing;
1022
+ let stdout;
1023
+ let stderr;
1024
+ let outputBytes = 0;
1025
+ let errorBytes = 0;
1026
+ const outputLimit = new PublicDiagnostic("numfmt output limit exceeded");
1027
+ const output = {
1028
+ get remaining() { return bufferLimit - outputBytes; },
1029
+ async emit(text, error = false) {
1030
+ const total = error ? errorBytes : outputBytes;
1031
+ if (text.length > bufferLimit - total)
1032
+ throw outputLimit;
1033
+ if (error)
1034
+ errorBytes += text.length;
1035
+ else
1036
+ outputBytes += text.length;
1037
+ const destination = error ? stderr?.output ?? context.stderr : stdout?.output ?? context.stdout;
1038
+ for (let offset = 0; offset < text.length; offset += 65536)
1039
+ await writeBytes(destination, textBytes(text.slice(offset, offset + 65536)), local.signal);
1040
+ },
1041
+ };
1042
+ const retire = () => retirement ??= Promise.resolve().then(async () => { if (!finished)
1043
+ await iterator?.return?.(); });
1044
+ const close = () => {
1045
+ closing ??= Promise.resolve().then(async () => {
1046
+ controller.abort(new FsError("EPIPE", { message: "numfmt input closed" }));
1047
+ const results = await Promise.allSettled([retire(), reader?.return?.(), stdout?.close(), stderr?.close()]);
1048
+ for (const result of results)
1049
+ if (result.status === "rejected")
1050
+ throw result.reason;
1051
+ });
1052
+ return closing;
1053
+ };
1054
+ context.registerCleanup?.(close);
1055
+ let outcome;
1056
+ try {
1057
+ stdout = createOutputOperation(local, context.stdout);
1058
+ stderr = createOutputOperation(local, context.stderr);
1059
+ const settings = parse(context);
1060
+ const converter = new Converter(settings, local, output);
1061
+ if (settings.information) {
1062
+ await output.emit(settings.information === "version" ? "numfmt (virtual-bash)\n" : helpText);
1063
+ outcome = { exitCode: 0 };
1064
+ }
1065
+ else {
1066
+ await converter.initialize();
1067
+ if (settings.operands.length) {
1068
+ for (const operand of settings.operands)
1069
+ await converter.line(operand, true);
1070
+ }
1071
+ else {
1072
+ local.signal.throwIfAborted();
1073
+ iterator = context.stdin[Symbol.asyncIterator]();
1074
+ reader = readBytes({ [Symbol.asyncIterator]: () => ({ next: async () => { const result = await iterator.next(); if (result.done)
1075
+ finished = true; return result; }, return: async () => { await retire(); return { done: true, value: undefined }; } }) }, local.signal)[Symbol.asyncIterator]();
1076
+ const record = new RecordBuffer(1024 * 1024);
1077
+ let received = 0;
1078
+ let empty = 0;
1079
+ let readFailure;
1080
+ let backing = new Uint8Array(0);
1081
+ const process = async (bytes, terminated) => {
1082
+ const initialized = bytes.length + (terminated ? 2 : 1);
1083
+ if (backing.length < initialized)
1084
+ backing = new Uint8Array(initialized);
1085
+ backing.set(bytes);
1086
+ backing[bytes.length] = terminated ? settings.separator.charCodeAt(0) : 0;
1087
+ if (terminated)
1088
+ backing[bytes.length + 1] = 0;
1089
+ const line = byteText(bytes);
1090
+ if (settings.header) {
1091
+ settings.header--;
1092
+ const header = line + (terminated ? settings.separator : "");
1093
+ const nul = header.indexOf("\0");
1094
+ await output.emit(nul < 0 ? header : header.slice(0, nul));
1095
+ }
1096
+ else {
1097
+ backing[bytes.length] = 0;
1098
+ await converter.line(line, terminated, backing);
1099
+ }
1100
+ };
1101
+ while (true) {
1102
+ await converter.tick();
1103
+ let item;
1104
+ try {
1105
+ item = await reader.next();
1106
+ }
1107
+ catch (error) {
1108
+ local.signal.throwIfAborted();
1109
+ const messages = { EISDIR: "Is a directory", EIO: "Input/output error", EBADF: "Bad file descriptor", EACCES: "Permission denied", EFBIG: "File too large" };
1110
+ if (!(error instanceof FsError) || !messages[error.code])
1111
+ throw error;
1112
+ readFailure = messages[error.code];
1113
+ break;
1114
+ }
1115
+ if (item.done)
1116
+ break;
1117
+ if (item.value.length > bufferLimit - received)
1118
+ throw new PublicDiagnostic("byte command input limit exceeded");
1119
+ received += item.value.length;
1120
+ if (!item.value.length && ++empty > 4096)
1121
+ throw new PublicDiagnostic("empty input chunk limit exceeded");
1122
+ const chunk = new Uint8Array(item.value);
1123
+ let start = 0;
1124
+ for (let offset = 0; offset < chunk.length; offset++) {
1125
+ if (offset % 4096 === 0)
1126
+ await converter.tick();
1127
+ if (chunk[offset] === settings.separator.charCodeAt(0)) {
1128
+ if (offset - start > record.capacity - record.size)
1129
+ throw new PublicDiagnostic("line buffer limit exceeded");
1130
+ await process(record.finish(undefined, chunk, start, offset), true);
1131
+ start = offset + 1;
1132
+ }
1133
+ }
1134
+ if (chunk.length - start > record.capacity - record.size)
1135
+ throw new PublicDiagnostic("line buffer limit exceeded");
1136
+ record.append(chunk, start);
1137
+ }
1138
+ if (record.size)
1139
+ await process(record.finish(), false);
1140
+ if (readFailure)
1141
+ await converter.warning(`error reading input: ${readFailure}`);
1142
+ }
1143
+ if (settings.debug && converter.invalid)
1144
+ await converter.warning("failed to convert some of the input numbers");
1145
+ outcome = { exitCode: converter.invalid && settings.invalid === "fail" ? 2 : 0 };
1146
+ }
1147
+ }
1148
+ catch (error) {
1149
+ try {
1150
+ context.signal.throwIfAborted();
1151
+ if (error instanceof NumfmtDiagnostic) {
1152
+ const text = `numfmt: ${error.message}\n${error.extra}${error.help ? "Try 'numfmt --help' for more information.\n" : ""}`;
1153
+ await output.emit(text, true);
1154
+ outcome = { exitCode: error.status };
1155
+ }
1156
+ else if (error instanceof PublicDiagnostic) {
1157
+ await output.emit(byteText(encoder.encode(`${context.command}: ${publicDiagnosticMessage(error, context.onInternalError)}\n`)), true);
1158
+ outcome = { exitCode: 1 };
1159
+ }
1160
+ else
1161
+ outcome = { error };
1162
+ }
1163
+ catch (failure) {
1164
+ outcome = failure === outputLimit ? { exitCode: 1 } : { error: failure };
1165
+ }
1166
+ }
1167
+ try {
1168
+ await close();
1169
+ }
1170
+ catch (error) {
1171
+ if (!("error" in outcome))
1172
+ outcome = { error };
1173
+ }
1174
+ context.signal.throwIfAborted();
1175
+ if ("error" in outcome)
1176
+ throw outcome.error;
1177
+ return outcome;
1178
+ } };
1179
+ }
1180
+ //# sourceMappingURL=numfmt.js.map