@ai-ecoverse/slicc-kernel 1.152.2 → 1.154.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +28 -3
  2. package/dist/driver-worker.js +147 -10
  3. package/dist/driver-worker.js.map +4 -4
  4. package/dist/index.js +168 -14
  5. package/dist/index.js.map +4 -4
  6. package/dist/kernel-worker.js +844 -167
  7. package/dist/kernel-worker.js.map +4 -4
  8. package/dist/node-driver-worker.js +147 -10
  9. package/dist/node-driver-worker.js.map +4 -4
  10. package/dist/node-process-worker.js +81 -24
  11. package/dist/node-process-worker.js.map +3 -3
  12. package/dist/node.js +982 -182
  13. package/dist/node.js.map +4 -4
  14. package/dist/process-worker.js +81 -24
  15. package/dist/process-worker.js.map +3 -3
  16. package/dist/types/client/attach.d.ts +2 -0
  17. package/dist/types/client/protocol.d.ts +4 -0
  18. package/dist/types/client/serve-client.d.ts +2 -0
  19. package/dist/types/embedder-relay.d.ts +58 -0
  20. package/dist/types/index.d.ts +4 -0
  21. package/dist/types/kernel/embedder.d.ts +100 -0
  22. package/dist/types/kernel/fd-table.d.ts +3 -1
  23. package/dist/types/kernel/host.d.ts +8 -0
  24. package/dist/types/kernel/net/tls-client.d.ts +4 -1
  25. package/dist/types/kernel/net/tls-engine.d.ts +5 -2
  26. package/dist/types/kernel/net/tls-server.d.ts +2 -0
  27. package/dist/types/kernel/net/tls-uplink.d.ts +2 -0
  28. package/dist/types/kernel/process.d.ts +17 -0
  29. package/dist/types/kernel/socket-syscalls.d.ts +3 -0
  30. package/dist/types/launcher.d.ts +13 -0
  31. package/dist/types/node.d.ts +3 -0
  32. package/dist/types/process/js/js-net.d.ts +3 -0
  33. package/dist/types/process/kernel-streams.d.ts +2 -1
  34. package/dist/types/process/wasi/wasi-fds.d.ts +1 -0
  35. package/dist/types/serve.d.ts +3 -0
  36. package/package.json +4 -4
@@ -2424,6 +2424,7 @@ var init_js_kernel = __esm({
2424
2424
  "fd-write",
2425
2425
  "fd-close",
2426
2426
  "fd-open-clipboard",
2427
+ "fd-open-embedder",
2427
2428
  "net-ws-ready",
2428
2429
  "sock-tls",
2429
2430
  "sock-tls-upgrade",
@@ -2759,6 +2760,7 @@ function* lookup(abs) {
2759
2760
  if (DEVICES.includes(name2)) return { kind: "device" };
2760
2761
  if (name2 === "tty") return { kind: "tty" };
2761
2762
  if (name2 === "clipboard") return { kind: "clipboard" };
2763
+ if (name2 === "embedder") return { kind: "embedder" };
2762
2764
  if (name2 === "sealed") return { kind: "sealed" };
2763
2765
  const std = STDIO.indexOf(name2);
2764
2766
  if (std >= 0) return { kind: "link", target: `${SELF_FD}/${std}`, fd: std };
@@ -2815,7 +2817,8 @@ function* fdTarget(fd, path) {
2815
2817
  if (info.kind === "file") return (yield { op: "fd-vfs-stat", fd }).path;
2816
2818
  if (info.terminal) return info.terminal;
2817
2819
  if (info.meta && "device" in info.meta) return `/dev/${info.meta.device}`;
2818
- if (info.kind === "clipboard" || info.kind === "sealed") return `/dev/${info.kind}`;
2820
+ if (info.kind === "clipboard" || info.kind === "sealed" || info.kind === "embedder")
2821
+ return `/dev/${info.kind}`;
2819
2822
  return `${info.kind === "socket" ? "socket" : "pipe"}:[${fd}]`;
2820
2823
  }
2821
2824
  function devFdStat(fd) {
@@ -2832,6 +2835,7 @@ function* devStat(abs, follow3) {
2832
2835
  case "device":
2833
2836
  case "tty":
2834
2837
  case "clipboard":
2838
+ case "embedder":
2835
2839
  case "sealed":
2836
2840
  return nodeStat(CHAR | 438);
2837
2841
  case "terminal":
@@ -2877,7 +2881,18 @@ function* devReaddir(abs) {
2877
2881
  if (node.kind !== "dir") throw new JsCallError("ENOTDIR", abs);
2878
2882
  const names = yield { op: "fd-tty-names" };
2879
2883
  const ttys = names.filter((n) => /^\/dev\/tty\d+$/.test(n)).map((n) => n.slice(5));
2880
- return [...DEVICES, "clipboard", "sealed", "tty", "fd", "pts", "shm", ...STDIO, ...ttys].sort();
2884
+ return [
2885
+ ...DEVICES,
2886
+ "clipboard",
2887
+ "embedder",
2888
+ "sealed",
2889
+ "tty",
2890
+ "fd",
2891
+ "pts",
2892
+ "shm",
2893
+ ...STDIO,
2894
+ ...ttys
2895
+ ].sort();
2881
2896
  }
2882
2897
  function* aliasOf(fd, abs, o) {
2883
2898
  const info = yield* fdInfo(fd, abs);
@@ -2918,6 +2933,11 @@ function* opened(abs, o) {
2918
2933
  fd: yield { op: "fd-open-clipboard", flags: accessFlags(o) },
2919
2934
  file: false
2920
2935
  };
2936
+ case "embedder":
2937
+ return {
2938
+ fd: yield { op: "fd-open-embedder", flags: accessFlags(o) },
2939
+ file: false
2940
+ };
2921
2941
  case "sealed":
2922
2942
  return { fd: yield { op: "fd-open-sealed", flags: accessFlags(o) }, file: false };
2923
2943
  case "terminal": {
@@ -3109,6 +3129,7 @@ var init_js_dev = __esm({
3109
3129
  "device",
3110
3130
  "tty",
3111
3131
  "clipboard",
3132
+ "embedder",
3112
3133
  "sealed"
3113
3134
  ]);
3114
3135
  }
@@ -3384,7 +3405,7 @@ function deviceOf(path) {
3384
3405
  }
3385
3406
  function namedDevice(path) {
3386
3407
  if (deviceOf(path) || stdioAlias(path) !== void 0) return true;
3387
- return path === SEALED_PATH || path === CLIPBOARD_PATH || path === "/dev/tty";
3408
+ return NAMED_PATHS.has(path);
3388
3409
  }
3389
3410
  function within(path, root) {
3390
3411
  return path === root || path.startsWith(root === "/" ? "/" : `${root}/`);
@@ -3457,7 +3478,7 @@ function promoteRequest(fd, f, handed) {
3457
3478
  ...f.buffer.handle !== void 0 && f.ino !== void 0 ? { ino: f.ino } : {}
3458
3479
  };
3459
3480
  }
3460
- var SYNTHETIC_DIRS, O_NONBLOCK, O_WRONLY2, O_RDWR2, O_APPEND2, SEALED_PATH, CLIPBOARD_PATH, WasiFds, GEN2;
3481
+ var SYNTHETIC_DIRS, O_NONBLOCK, O_WRONLY2, O_RDWR2, O_APPEND2, SEALED_PATH, CLIPBOARD_PATH, EMBEDDER_PATH, NAMED_PATHS, WasiFds, GEN2;
3461
3482
  var init_wasi_fds = __esm({
3462
3483
  "src/process/wasi/wasi-fds.ts"() {
3463
3484
  "use strict";
@@ -3474,6 +3495,13 @@ var init_wasi_fds = __esm({
3474
3495
  O_APPEND2 = 1024;
3475
3496
  SEALED_PATH = "/dev/sealed";
3476
3497
  CLIPBOARD_PATH = "/dev/clipboard";
3498
+ EMBEDDER_PATH = "/dev/embedder";
3499
+ NAMED_PATHS = /* @__PURE__ */ new Set([
3500
+ SEALED_PATH,
3501
+ CLIPBOARD_PATH,
3502
+ EMBEDDER_PATH,
3503
+ "/dev/tty"
3504
+ ]);
3477
3505
  WasiFds = class {
3478
3506
  table = /* @__PURE__ */ new Map();
3479
3507
  buffers = /* @__PURE__ */ new Map();
@@ -4086,7 +4114,7 @@ var init_wasi_fds = __esm({
4086
4114
  return joined2.split("/").includes("..") ? physical(this.fs, joined2) : normalize(joined2);
4087
4115
  }
4088
4116
  openKernelDevice(path, oflags, fdflags, rights) {
4089
- const { openSealed, openClipboard, openTty } = this.kernel.sys;
4117
+ const { openSealed, openClipboard, openEmbedder, openTty } = this.kernel.sys;
4090
4118
  const nonblock = (fdflags & FDFLAGS.NONBLOCK) !== 0;
4091
4119
  let fd;
4092
4120
  let kind;
@@ -4096,6 +4124,9 @@ var init_wasi_fds = __esm({
4096
4124
  } else if (path === CLIPBOARD_PATH && openClipboard) {
4097
4125
  fd = this.openCharDevice(openClipboard, oflags, rights);
4098
4126
  kind = "clipboard";
4127
+ } else if (path === EMBEDDER_PATH && openEmbedder) {
4128
+ fd = this.openCharDevice(openEmbedder, oflags, rights);
4129
+ kind = "embedder";
4099
4130
  } else if (path === "/dev/tty" || /^\/dev\/tty\d+$/.test(path)) {
4100
4131
  const exclusive = (oflags & OFLAGS.CREAT) !== 0 && (oflags & OFLAGS.EXCL) !== 0;
4101
4132
  try {
@@ -5346,6 +5377,7 @@ function kernelFiletype(kind) {
5346
5377
  case "tty":
5347
5378
  case "sealed":
5348
5379
  case "clipboard":
5380
+ case "embedder":
5349
5381
  return { filetype: FILETYPE.CHARACTER_DEVICE, seeks: false };
5350
5382
  case "device":
5351
5383
  return { filetype: FILETYPE.CHARACTER_DEVICE, seeks: true };
@@ -6423,7 +6455,7 @@ var init_wasi_host = __esm({
6423
6455
  return gone2 ? { ...out, nlink: 0n } : out;
6424
6456
  }
6425
6457
  synthetic(path) {
6426
- return deviceOf(path) !== void 0 || path === SEALED_PATH && !!this.o.kernel.sys.openSealed || path === CLIPBOARD_PATH && !!this.o.kernel.sys.openClipboard;
6458
+ return deviceOf(path) !== void 0 || path === SEALED_PATH && !!this.o.kernel.sys.openSealed || path === CLIPBOARD_PATH && !!this.o.kernel.sys.openClipboard || path === EMBEDDER_PATH && !!this.o.kernel.sys.openEmbedder;
6427
6459
  }
6428
6460
  linkedDev(path, follow3) {
6429
6461
  if (!follow3) return void 0;
@@ -7213,7 +7245,7 @@ var KERNEL_VERSION, OS_RELEASE;
7213
7245
  var init_version = __esm({
7214
7246
  "src/version.ts"() {
7215
7247
  "use strict";
7216
- KERNEL_VERSION = true ? "1.152.2" : "0.0.0-dev";
7248
+ KERNEL_VERSION = true ? "1.154.0" : "0.0.0-dev";
7217
7249
  OS_RELEASE = "6.0.0-slicc";
7218
7250
  }
7219
7251
  });
@@ -8056,7 +8088,8 @@ function serveRequest(tls) {
8056
8088
  ...tls.requestCert ? { requestCert: true } : {},
8057
8089
  ...tls.rejectUnauthorized === false ? { rejectUnauthorized: false } : {},
8058
8090
  ...tls.alpn ? { alpn: [...tls.alpn] } : {},
8059
- ...tls.handshakeTimeout !== void 0 ? { handshakeTimeout: tls.handshakeTimeout } : {}
8091
+ ...tls.handshakeTimeout !== void 0 ? { handshakeTimeout: tls.handshakeTimeout } : {},
8092
+ ...tls.keylog === true ? { keylog: true } : {}
8060
8093
  };
8061
8094
  }
8062
8095
  function servedOf(r) {
@@ -8066,9 +8099,13 @@ function servedOf(r) {
8066
8099
  path: "kernel",
8067
8100
  ...authorizationError ? { authorizationError } : {},
8068
8101
  peerCertificates: Object.freeze(r.peerCertificates.map(fromBase642)),
8069
- cipher: Object.freeze({ ...r.cipher })
8102
+ cipher: Object.freeze({ ...r.cipher }),
8103
+ ...keylogOf(r.keylog)
8070
8104
  });
8071
8105
  }
8106
+ function keylogOf(lines) {
8107
+ return lines ? { keylog: Object.freeze([...lines]) } : {};
8108
+ }
8072
8109
  function clientCert(tls, what = "connect") {
8073
8110
  if (tls.pfx !== void 0) {
8074
8111
  throw new JsCallError("ENOTSUP", what, "pfx is not supported: pass cert and key");
@@ -8089,6 +8126,7 @@ function tlsRequest(tls) {
8089
8126
  ...tls.rejectUnauthorized === false ? { insecure: true } : {},
8090
8127
  ...tls.sni === false ? { sni: false } : {},
8091
8128
  ...tls.checkHostname === false ? { checkHostname: false } : {},
8129
+ ...tls.keylog === true ? { keylog: true } : {},
8092
8130
  ...clientCert(tls)
8093
8131
  };
8094
8132
  }
@@ -8125,7 +8163,8 @@ function sessionOf(r) {
8125
8163
  ...r.authorizationError ? { authorizationError: r.authorizationError } : {},
8126
8164
  servername: r.servername,
8127
8165
  peerCertificates: Object.freeze((r.peerCertificates ?? []).map(fromBase642)),
8128
- ...controlsOf(r)
8166
+ ...controlsOf(r),
8167
+ ...keylogOf(r.keylog)
8129
8168
  });
8130
8169
  }
8131
8170
  function withAlert(err) {
@@ -12843,7 +12882,7 @@ function sealedStat(minor = 250) {
12843
12882
  const now = /* @__PURE__ */ new Date();
12844
12883
  return {
12845
12884
  dev: 22,
12846
- ino: minor === 251 ? 2 : 1,
12885
+ ino: DEVICE_INO[minor],
12847
12886
  mode: 8630,
12848
12887
  nlink: 1,
12849
12888
  uid: 0,
@@ -12867,7 +12906,7 @@ function datesOf(real) {
12867
12906
  dates[key] = new Date(value2);
12868
12907
  return dates;
12869
12908
  }
12870
- var POLLIN, POLLOUT, POLLERR, POLLHUP, POLLRDNORM, POLLWRNORM, TCSETSF, O_NONBLOCK2, SOCKET_MODE, PTY_PATH, TTY_PATH, PTS_MAJOR, TTY_NAME, SEALED_PATH2, STRERROR, CLIPBOARD_PATH2, O_CREAT2, O_EXCL2, O_NOCTTY, O_TRUNC3, O_DIRECTORY, KILLED_BY_SIGPIPE, ProcessExit, SyscallError, KernelStreams;
12909
+ var POLLIN, POLLOUT, POLLERR, POLLHUP, POLLRDNORM, POLLWRNORM, TCSETSF, O_NONBLOCK2, SOCKET_MODE, PTY_PATH, TTY_PATH, PTS_MAJOR, TTY_NAME, SEALED_PATH2, STRERROR, CLIPBOARD_PATH2, EMBEDDER_PATH2, DEVICE_INO, O_CREAT2, O_EXCL2, O_NOCTTY, O_TRUNC3, O_DIRECTORY, KILLED_BY_SIGPIPE, ProcessExit, SyscallError, KernelStreams;
12871
12910
  var init_kernel_streams = __esm({
12872
12911
  "src/process/kernel-streams.ts"() {
12873
12912
  "use strict";
@@ -12897,6 +12936,8 @@ var init_kernel_streams = __esm({
12897
12936
  EINTR: "Interrupted system call"
12898
12937
  };
12899
12938
  CLIPBOARD_PATH2 = "/dev/clipboard";
12939
+ EMBEDDER_PATH2 = "/dev/embedder";
12940
+ DEVICE_INO = { 250: 1, 251: 2, 252: 3 };
12900
12941
  O_CREAT2 = 64;
12901
12942
  O_EXCL2 = 128;
12902
12943
  O_NOCTTY = 256;
@@ -12979,7 +13020,7 @@ var init_kernel_streams = __esm({
12979
13020
  stream.stream_ops = { ...stream.stream_ops, getattr: () => this.Fs.stat?.(name2) ?? {} };
12980
13021
  }
12981
13022
  nameDevice(stream, kind) {
12982
- this.nameStream(stream, kind === "sealed" ? SEALED_PATH2 : CLIPBOARD_PATH2);
13023
+ this.nameStream(stream, `/dev/${kind}`);
12983
13024
  }
12984
13025
  listSealed() {
12985
13026
  const fs = this.Fs;
@@ -12987,7 +13028,8 @@ var init_kernel_streams = __esm({
12987
13028
  if (!analyzePath || !mkdev || !makedev) return;
12988
13029
  const nodes = [
12989
13030
  [SEALED_PATH2, 250, this.sys.openSealed],
12990
- [CLIPBOARD_PATH2, 251, this.sys.openClipboard]
13031
+ [CLIPBOARD_PATH2, 251, this.sys.openClipboard],
13032
+ [EMBEDDER_PATH2, 252, this.sys.openEmbedder]
12991
13033
  ];
12992
13034
  for (const [path, minor, opener] of nodes) {
12993
13035
  if (!opener) continue;
@@ -13017,6 +13059,7 @@ var init_kernel_streams = __esm({
13017
13059
  this.attach(stream, kfd, terminal);
13018
13060
  this.nameStream(stream, path);
13019
13061
  if (path === CLIPBOARD_PATH2) this.reportClose(kfd);
13062
+ if (path === EMBEDDER_PATH2) this.reportClose(kfd);
13020
13063
  }
13021
13064
  reporting = /* @__PURE__ */ new Set();
13022
13065
  reportClose(kfd) {
@@ -13304,10 +13347,11 @@ var init_kernel_streams = __esm({
13304
13347
  return this.vessel(open, kfd, { path, flags, mode }, false);
13305
13348
  }
13306
13349
  openClipboard(open, path, flags, mode) {
13307
- const { openClipboard } = this.sys;
13308
- if (path !== CLIPBOARD_PATH2 || !openClipboard) return void 0;
13350
+ const clipboard = path === CLIPBOARD_PATH2;
13351
+ const opener = clipboard ? this.sys.openClipboard : this.sys.openEmbedder;
13352
+ if (!clipboard && path !== EMBEDDER_PATH2 || !opener) return void 0;
13309
13353
  if (flags & O_DIRECTORY) throw new this.Fs.ErrnoError(wasiErrno("ENOTDIR"));
13310
- const kfd = this.call(() => openClipboard.call(this.sys, flags & 3));
13354
+ const kfd = this.call(() => opener.call(this.sys, flags & 3));
13311
13355
  try {
13312
13356
  const stream = this.vessel(open, kfd, { path, flags, mode }, false);
13313
13357
  this.reportClose(kfd);
@@ -13343,6 +13387,7 @@ var init_kernel_streams = __esm({
13343
13387
  fs[name2] = (path, ...rest2) => {
13344
13388
  if (path === SEALED_PATH2 && this.sys.openSealed) return sealedStat();
13345
13389
  if (path === CLIPBOARD_PATH2 && this.sys.openClipboard) return sealedStat(251);
13390
+ if (path === EMBEDDER_PATH2 && this.sys.openEmbedder) return sealedStat(252);
13346
13391
  const owned = this.ownedTty(path);
13347
13392
  if (owned && isPtyPath(path)) return this.owned(path, ptyStat(path));
13348
13393
  if (!isPtyPath(path))
@@ -13636,8 +13681,7 @@ function placeholder(Fs, streams2, entry) {
13636
13681
  const access = entry.flags ?? O_RDWR4;
13637
13682
  if (entry.kind === "socket") return streams2.socketStream(access);
13638
13683
  if (entry.kind === "tty") return Fs.open("/dev/tty", O_RDWR4);
13639
- if (entry.kind === "stream" || entry.kind === "clipboard" || entry.kind === "sealed")
13640
- return Fs.open("/dev/null", access);
13684
+ if (entry.kind === "stream" || DEVICE_KINDS.has(entry.kind)) return Fs.open("/dev/null", access);
13641
13685
  Fs.mkdirTree(PLACEHOLDER_DIR);
13642
13686
  return Fs.open(`${PLACEHOLDER_DIR}/${entry.fd}`, access | O_CREAT3);
13643
13687
  }
@@ -13661,8 +13705,9 @@ function placeKernelStream(Fs, streams2, entry) {
13661
13705
  streams2.sizeFromKernel(stream, entry.kernel);
13662
13706
  } else if (entry.kind === "socket") streams2.attachSocket(stream, entry.kernel);
13663
13707
  else streams2.attach(stream, entry.kernel, entry.kind === "tty");
13664
- if (entry.kind === "clipboard") streams2.reportClose(entry.kernel);
13665
- if (entry.kind === "sealed" || entry.kind === "clipboard") streams2.nameDevice(stream, entry.kind);
13708
+ if (entry.kind === "clipboard" || entry.kind === "embedder") streams2.reportClose(entry.kernel);
13709
+ if (DEVICE_KINDS.has(entry.kind))
13710
+ streams2.nameDevice(stream, entry.kind);
13666
13711
  if (entry.kind === "tty") streams2.nameTerminal(stream);
13667
13712
  if (entry.kind === "stream") {
13668
13713
  asFifo(stream, streams2, entry.desc !== void 0 ? `d${entry.desc}` : `k${entry.kernel}`);
@@ -13689,7 +13734,7 @@ function restoreForkedStreams(Fs, streams2, table) {
13689
13734
  }
13690
13735
  }
13691
13736
  }
13692
- var O_RDWR4, O_ACCMODE4, O_CREAT3, O_EXCL3, O_TRUNC4, PLACEHOLDER_DIR, NAMED_DEVICES, ACCESS, DEVICES2, FIFO_MODE, nextStreamIno, streamInos;
13737
+ var O_RDWR4, O_ACCMODE4, O_CREAT3, O_EXCL3, O_TRUNC4, PLACEHOLDER_DIR, NAMED_DEVICES, DEVICE_KINDS, ACCESS, DEVICES2, FIFO_MODE, nextStreamIno, streamInos;
13693
13738
  var init_process_fork = __esm({
13694
13739
  "src/process/process-fork.ts"() {
13695
13740
  "use strict";
@@ -13702,8 +13747,10 @@ var init_process_fork = __esm({
13702
13747
  PLACEHOLDER_DIR = "/dev/slicc-fd";
13703
13748
  NAMED_DEVICES = {
13704
13749
  "/dev/sealed": "sealed",
13705
- "/dev/clipboard": "clipboard"
13750
+ "/dev/clipboard": "clipboard",
13751
+ "/dev/embedder": "embedder"
13706
13752
  };
13753
+ DEVICE_KINDS = /* @__PURE__ */ new Set(["sealed", "clipboard", "embedder"]);
13707
13754
  ACCESS = { 0: "read", 1: "write" };
13708
13755
  DEVICES2 = {
13709
13756
  "/dev/null": "null",
@@ -14489,6 +14536,9 @@ function kernelSys(transport) {
14489
14536
  clipboardAbort(fd) {
14490
14537
  call2({ op: "fd-clipboard-abort", fd }, "fd-clipboard-abort");
14491
14538
  },
14539
+ openEmbedder(flags) {
14540
+ return json2(call2({ op: "fd-open-embedder", flags }, "fd-open-embedder"));
14541
+ },
14492
14542
  ptyNumbers() {
14493
14543
  return json2(call2({ op: "pty-list" }, "pty-list"));
14494
14544
  },
@@ -14984,7 +15034,14 @@ var init_process_runtime = __esm({
14984
15034
  O_ACCMODE5 = 3;
14985
15035
  O_DIRECTORY2 = 65536;
14986
15036
  accessMode = (access) => access === "read" ? O_RDONLY2 : access === "write" ? O_WRONLY6 : O_RDWR6;
14987
- PLACED = /* @__PURE__ */ new Set(["stream", "file", "socket", "clipboard", "sealed"]);
15037
+ PLACED = /* @__PURE__ */ new Set([
15038
+ "stream",
15039
+ "file",
15040
+ "socket",
15041
+ "clipboard",
15042
+ "embedder",
15043
+ "sealed"
15044
+ ]);
14988
15045
  GLUE_TRAILER = [
14989
15046
  "if (typeof ENV !== 'undefined') Object.assign(ENV, Module.sliccEnv);",
14990
15047
  "if (typeof thisProgram !== 'undefined' && Module.thisProgram === '') thisProgram = '';",