diff --git a/.gitignore b/.gitignore
index 5d67442b54..ca50cf4952 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,6 +31,17 @@
/libgap*.dll*
/libgap*.so*
+# emscripten / wasm build outputs (etc/emscripten/build.sh and friends)
+/native-build/
+/extern/emscripten/
+/web-example/
+/packages.tar.gz
+/gap.html
+/gap.js
+/gap.wasm
+/gap.worker.js
+/gap-fs.json
+
/bin/gap*.sh
/bin/*-*/
# Compiling the `xgap` package creates the file `xgap.sh`
diff --git a/etc/emscripten/Dockerfile b/etc/emscripten/Dockerfile
new file mode 100644
index 0000000000..9025dbaaa3
--- /dev/null
+++ b/etc/emscripten/Dockerfile
@@ -0,0 +1,50 @@
+# Build environment for compiling GAP to WebAssembly via Emscripten.
+#
+# Pinned to emsdk 3.1.23 for reproducibility. Both pieces of the in-browser
+# REPL are sensitive to the exact toolchain version:
+#
+# - GASMAN, GAP's conservative garbage collector, scans the stack including
+# pointers held in wasm registers, reached via emscripten_scan_registers()
+# (see src/gasman.c). That path is now compiled correctly regardless of
+# version, so the GC itself is no longer the constraint.
+#
+# - The terminal uses xterm-pty, whose emscriptenHack() monkey-patches
+# emscripten's internal TTY device so GAP's tcsetattr() (turning off echo
+# and canonical mode) reaches the line discipline. That patch is tied to
+# emscripten's TTY internals: on 3.1.47 the ioctl no longer reaches
+# xterm-pty, echo stays on, and every typed line is echoed twice.
+#
+# 3.1.23 is the version where the pinned xterm-pty (0.9.4) works. Bump both
+# together and re-test the REPL -- including that typed input is not
+# double-echoed -- before changing this.
+
+FROM emscripten/emsdk:3.1.23
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ autoconf \
+ automake \
+ libtool \
+ make \
+ python3 \
+ ca-certificates \
+ curl \
+ bison \
+ byacc \
+ m4 \
+ && rm -rf /var/lib/apt/lists/*
+
+# Allow running as a non-root host UID without breaking the emscripten cache.
+RUN mkdir -p /emsdk/upstream/emscripten/cache \
+ && chmod -R 0777 /emsdk/upstream/emscripten/cache
+
+# Cache the GAP package distribution tarball so container runs don't
+# re-download it from GitHub each time. The URL pins to the "latest"
+# release on the PackageDistro side, so this snapshot drifts as upstream
+# tags new releases — rebuild the image (--no-cache) to refresh.
+ARG GAP_PACKAGES_URL=https://github.com/gap-system/PackageDistro/releases/download/latest/packages.tar.gz
+RUN curl --fail --location --silent --show-error \
+ --output /opt/gap-packages.tar.gz \
+ "$GAP_PACKAGES_URL" \
+ && chmod 0644 /opt/gap-packages.tar.gz
+
+WORKDIR /gap
diff --git a/etc/emscripten/README.md b/etc/emscripten/README.md
index 5946302efe..083de668b6 100644
--- a/etc/emscripten/README.md
+++ b/etc/emscripten/README.md
@@ -1,26 +1,127 @@
-Code to allow building gap to WASM using Emscripten.
+# GAP in the browser
-Files:
+Build GAP as a WebAssembly module and serve it as a self-contained website.
+The terminal interface uses [xterm-pty](https://github.com/mame/xterm-pty),
+so the resulting page behaves like a normal GAP REPL.
-- `build.sh`: Run as `etc/emscripten/build.sh` from a fresh copy of GAP.
+## Quick start
-- `web-template`: Uses 'xterm-pty' to create a "nice" interface to the Wasm GAP.
+From a fresh GAP checkout, with either Docker or Podman installed:
-- `build_startup_manifest.js`: Run it in the web root directory to build `startup_manifest.json` that contains resources to preload.
+```sh
+etc/emscripten/build-in-docker.sh
+cd web-example
+../etc/emscripten/serve.py
+```
+
+Then open . The first build takes 10–30 minutes; the
+docker image, the GAP package distribution, and the GMP/zlib builds are all
+cached for subsequent runs.
+
+To pick up newer GAP packages from upstream, force a fresh image build:
+
+```sh
+docker build --no-cache -t gap-emscripten-build:3.1.23 etc/emscripten/
+```
+
+On Apple Silicon (and other non-amd64 hosts), the build runs `linux/amd64`
+under emulation, since `emscripten/emsdk:3.1.23` is amd64-only on Docker
+Hub. `build-in-docker.sh` pins the platform explicitly so the layer cache
+holds across runs; set `BUILD_PLATFORM` to override.
+
+The output directory `web-example/` is fully self-contained — copy it to any
+static host (see "Hosting" below for the headers it needs).
+
+## Building without Docker
+
+If you already have emsdk 3.1.23 sourced in your shell, you can run the
+underlying build directly:
+
+```sh
+etc/emscripten/build.sh
+etc/emscripten/assemble-website.sh
+```
+
+emsdk 3.1.23 is the version we test against, paired with xterm-pty 0.9.4.
+GAP relies on ASYNCIFY together with GASMAN's conservative GC, which scans
+wasm registers via `emscripten_scan_registers()` (see `src/gasman.c`); and
+the terminal relies on xterm-pty's `emscriptenHack()` patching emscripten's
+TTY device so `tcsetattr()` reaches the line discipline. Both are sensitive
+to the toolchain version (a newer emsdk leaves `tcsetattr` unhonoured, so
+typed input is echoed twice), so re-test the REPL when changing emsdk.
-See 'run-web-demo.sh' as an example on how to set up a working website.
+## Hosting
-Note that this demo uses xterm-pty, a library which provides a terminal interface
-for emscripten-compiled programs. This uses a javascript feature called
-"SharedArrayBuffer", which requires some headers are returned by the server:
+The xterm-pty terminal uses `SharedArrayBuffer`, which browsers only allow
+when the page is served with these two headers:
```
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
```
-For more details, see for [this article](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer).
+`serve.py` is a 20-line stdlib-only Python server that adds them. For
+GitHub Pages and other static hosts that don't let you set headers,
+`web-template/coi-serviceworker.js` is included as a workaround (it
+re-fetches resources through a service worker that adds the headers).
+
+## Files
+
+| File | Role |
+| ---- | ---- |
+| `build-in-docker.sh` | One-stop entry point. Builds the image, runs `build.sh` inside, then `assemble-website.sh`. |
+| `Dockerfile` | Pinned `emscripten/emsdk:3.1.23` with autotools, python3, bison/byacc/m4, and a baked-in copy of the GAP package distribution tarball at `/opt/gap-packages.tar.gz`. |
+| `build.sh` | Configures and builds GMP, zlib, and GAP itself for wasm. |
+| `assemble-website.sh` | Copies the build outputs and data directories (`pkg`, `lib`, `grp`, …) into `web-example/`. |
+| `generate_gap_fs_json.py` | Reads file paths on stdin, writes `gap-fs.json` (the manifest of every file in the virtual FS). |
+| `startup_manifest.json` | List of files to fetch eagerly at startup, captured from a real GAP run. Anything not in this list is fetched lazily on first read. See "Updating the startup manifest" below for how to refresh it. |
+| `serve.py` | Local server that adds the COOP/COEP headers. |
+| `web-template/` | Static UI: `index.html`, the worker scripts, the FS init shim, and the COOP/COEP service worker for hosts where you can't set headers. |
+
+## Updating the startup manifest
+
+`startup_manifest.json` lists files (relative to the GAP root) that the FS
+init shim downloads up front instead of lazily. The current list was
+captured from a real GAP run reaching its prompt, so it includes both
+the core library bootstrap (`lib/init.g`, `lib/read*.g`, …) and any
+default-loaded packages. Entries that no longer exist in the build are
+silently ignored, so it is safe to leave stale entries in place; it is
+also safe to leave the list empty (every file becomes lazy).
+
+The manifest is a startup-time optimisation, not a correctness mechanism:
+a wrong list never breaks the build, it only makes startup slower (files
+GAP needs but the manifest omits get fetched lazily, one round-trip each)
+or wastes bandwidth (files in the manifest that GAP doesn't actually
+read are downloaded anyway). So it's worth refreshing when something
+changes the set of files read at startup — most importantly when the
+default loaded packages change, but also after large library reshuffles.
+
+To regenerate it after such changes:
+
+1. Build the website (`build-in-docker.sh`) and serve it (`serve.py`).
+2. **Empty the served manifest before capturing.** Replace
+ `web-example/startup_manifest.json` with `[]` (or delete it).
+ Otherwise the existing entries are eagerly pre-fetched at startup,
+ appear in `fetchedUrls`, and you'll just round-trip the old list.
+ Editing the served file is enough — no rebuild is needed.
+3. Open the page and wait for the GAP prompt to appear. Every file that
+ GAP actually reads now goes through the lazy `XHR` path and gets
+ captured.
+4. Open devtools and read the captured URLs from the page's JS console:
+ `window.fetchedUrls` is an array of every unique URL the worker
+ requested. Chrome/Firefox provide a `copy()` console helper:
+ `copy(JSON.stringify(fetchedUrls))` puts the JSON on your clipboard.
+5. Strip non-GAP-FS entries (`gap.js`, `gap.wasm`, `gap-fs.json`, the
+ xterm CDN URLs) and write the result to
+ `etc/emscripten/startup_manifest.json` (so it's checked in and gets
+ picked up by the next `assemble-website.sh`). A `jq` filter that
+ keeps just GAP filesystem paths:
+
+ ```sh
+ jq '[.[] | select(test("^(pkg|lib|grp|tst|doc|hpcgap|dev|benchmark)/"))]' \
+ fetched-urls.json > etc/emscripten/startup_manifest.json
+ ```
-The file "coi-serviceworker.js" works around this problem on Github pages. This won't
-work locally, so "server.rb" is a simple ruby script, which just starts a web-server
-which returns the required headers.
\ No newline at end of file
+The bookkeeping lives in `web-template/gap-fs.js` (wraps `fetch` and
+`XMLHttpRequest.open` to report URLs to the main thread) and
+`web-template/index.html` (accumulates them onto `window.fetchedUrls`).
diff --git a/etc/emscripten/assemble-website.sh b/etc/emscripten/assemble-website.sh
new file mode 100755
index 0000000000..12e6f6a83b
--- /dev/null
+++ b/etc/emscripten/assemble-website.sh
@@ -0,0 +1,64 @@
+#!/usr/bin/env bash
+#
+# Assemble a self-contained website from a completed wasm build.
+# Outputs ./web-example/ relative to the GAP source root.
+#
+# Run after etc/emscripten/build.sh (or have build-in-docker.sh call it).
+
+set -euo pipefail
+
+SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
+ROOT_DIR=$(cd "$SCRIPT_DIR/../.." && pwd)
+OUT_DIR="$ROOT_DIR/web-example"
+
+cd "$ROOT_DIR"
+
+for f in gap.js gap.wasm gap-fs.json; do
+ if [[ ! -f $f ]]; then
+ echo "Error: missing build output '$f'. Run etc/emscripten/build.sh first." >&2
+ exit 1
+ fi
+done
+
+# Always start from a clean output directory. Merging into a previous
+# web-example/ confuses cp when a tree has changed shape between runs
+# (e.g. pkg/X switching between a symlink and a real directory).
+rm -rf "$OUT_DIR"
+mkdir -p "$OUT_DIR"
+
+cp "$SCRIPT_DIR"/web-template/* "$OUT_DIR"/
+cp "$SCRIPT_DIR"/startup_manifest.json "$OUT_DIR"/
+cp gap.js gap.wasm gap-fs.json "$OUT_DIR"/
+# Emscripten only emits a separate gap.worker.js for pthread builds; this
+# single-threaded ASYNCIFY build doesn't use one (newer emscripten inlines
+# the worker regardless). Copy it only if it was produced.
+if [[ -f gap.worker.js ]]; then
+ cp gap.worker.js "$OUT_DIR"/
+fi
+cp LICENSE COPYRIGHT "$OUT_DIR"/
+
+# Data directories. These are referenced by gap-fs.json and either eagerly
+# loaded (if listed in startup_manifest.json) or lazily fetched on first
+# read by Emscripten's createLazyFile.
+#
+# -L dereferences symlinks so the output tree is self-contained (a setup
+# where pkg/X is a symlink into a separate checkout still works). Some
+# packages ship dangling symlinks as build artefacts (e.g. pkg/vole's
+# rust/target/*.dSYM); cp prints those and exits non-zero but still copies
+# everything else, so we don't let that abort the run. The assertion below
+# catches a genuinely incomplete copy.
+for d in pkg lib grp tst doc hpcgap dev benchmark; do
+ cp -RL "$d" "$OUT_DIR"/ 2>/dev/null || true
+done
+
+# pkg/log holds package test logs (.log/.err/.out) that are never read at
+# runtime; keep them out of the shipped site.
+rm -rf "$OUT_DIR/pkg/log"
+
+# The library bootstrap must be present, or GAP 404s during startup.
+if [[ ! -f "$OUT_DIR/lib/init.g" ]]; then
+ echo "Error: lib/init.g missing from $OUT_DIR after copy." >&2
+ exit 1
+fi
+
+echo "Assembled website at $OUT_DIR"
diff --git a/etc/emscripten/build-in-docker.sh b/etc/emscripten/build-in-docker.sh
new file mode 100755
index 0000000000..ac7a7aa604
--- /dev/null
+++ b/etc/emscripten/build-in-docker.sh
@@ -0,0 +1,80 @@
+#!/usr/bin/env bash
+#
+# One-stop shop: build GAP for the web inside a pinned container.
+#
+# Usage (run from the GAP source tree):
+# etc/emscripten/build-in-docker.sh
+#
+# Output: ./web-example/ with a self-contained website. Copy it anywhere
+# and serve with COOP/COEP headers (etc/emscripten/serve.py is one option).
+
+set -euo pipefail
+
+SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
+ROOT_DIR=$(cd "$SCRIPT_DIR/../.." && pwd)
+
+RUNTIME="${CONTAINER_RUNTIME:-}"
+if [[ -z "$RUNTIME" ]]; then
+ if command -v podman >/dev/null 2>&1; then
+ RUNTIME=podman
+ elif command -v docker >/dev/null 2>&1; then
+ RUNTIME=docker
+ else
+ echo "Error: neither podman nor docker found in PATH." >&2
+ echo "Install one, or set CONTAINER_RUNTIME explicitly." >&2
+ exit 1
+ fi
+fi
+
+IMAGE_TAG="gap-emscripten-build:3.1.23"
+
+# Pin the platform. emscripten/emsdk:3.1.23 is amd64-only on Docker Hub, so on
+# Apple Silicon (or any non-amd64 host) the runtime would otherwise renegotiate
+# the platform on every build -- that mismatch invalidates the FROM layer's
+# cache and cascades through the whole image, defeating the layer cache even
+# with --layers. Override with BUILD_PLATFORM if needed.
+PLATFORM="${BUILD_PLATFORM:-linux/amd64}"
+
+echo ">> Using container runtime: $RUNTIME (platform: $PLATFORM)"
+echo ">> Building image $IMAGE_TAG (cached after first run)"
+
+# --layers is the podman/buildah flag for "use the layer cache"; older
+# podman versions default it to false. Docker has caching on by default
+# and rejects the flag, so only pass it for podman.
+declare -a BUILD_ARGS=(--platform "$PLATFORM")
+if [[ "$RUNTIME" != "docker" ]]; then
+ BUILD_ARGS+=(--layers)
+fi
+"$RUNTIME" build "${BUILD_ARGS[@]}" -t "$IMAGE_TAG" -f "$SCRIPT_DIR/Dockerfile" "$SCRIPT_DIR"
+
+# Run as the host user where possible so build outputs are not root-owned.
+declare -a USER_ARGS=()
+if [[ "$RUNTIME" == "docker" ]]; then
+ USER_ARGS=(--user "$(id -u):$(id -g)" -e HOME=/tmp)
+else
+ # Rootless podman maps host UID to container root by default.
+ USER_ARGS=(--userns=keep-id)
+fi
+
+echo ">> Building GAP inside container"
+"$RUNTIME" run --platform "$PLATFORM" --rm \
+ -v "$ROOT_DIR:/gap" \
+ -w /gap \
+ "${USER_ARGS[@]}" \
+ "$IMAGE_TAG" \
+ bash etc/emscripten/build.sh
+
+echo ">> Assembling website"
+bash "$SCRIPT_DIR/assemble-website.sh"
+
+cat </dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)
-if ! command -v emmake &> /dev/null; then
- echo Please install, and source, emscripten
- echo This script was tested with version 3.1.23
- echo See https://emscripten.org/docs/getting_started/downloads.html for install instructions
+if ! command -v emmake >/dev/null 2>&1; then
+ echo "Please install and source emscripten." >&2
+ echo "This script is tested with emsdk 3.1.23." >&2
+ echo "See https://emscripten.org/docs/getting_started/downloads.html" >&2
exit 1
-fi;
+fi
# Build the configure script if this is a fresh git checkout
if [[ ! -f ./configure ]]; then
./autogen.sh
fi
-# First build a standard GAP install, for some files
-# we will need during building
+# First build a standard GAP install: we need ffgen and gap-nocomp on the
+# host to generate sources that the wasm build cannot run itself.
+#
+# We copy those generated sources (build/c_*.c, build/ffdata.*) into src/
+# further down, so the wasm build picks them up as overrides. GAP's
+# Makefile.rules, however, also treats src/c_oper1.c, src/ffdata.c etc. as
+# overrides during THIS native build -- so leftovers from a previous run
+# would stop the native build regenerating them in native-build/build/, and
+# the copy below would then fail. Remove any leftovers so the native build
+# regenerates them cleanly (keeps the script idempotent across re-runs).
+rm -f src/c_oper1.c src/c_type1.c src/ffdata.c src/ffdata.h
(
mkdir -p native-build
cd native-build
if [[ ! -f config.status ]]; then
../configure
fi
- make -j8
+ make -j"$JOBS"
)
AUX_BUILD=$PWD/extern/emscripten/build
AUX_PREFIX=$PWD/extern/emscripten/install
-mkdir -p "$AUX_BUILD"
-mkdir -p "$AUX_PREFIX"
+mkdir -p "$AUX_BUILD" "$AUX_PREFIX"
+# A 32-bit build is required by GAP's small-integer representation, so we
+# pin --build to i686-pc-linux-gnu. This may need revisiting if GAP ever
+# moves to a 64-bit-friendly small-integer encoding.
(
mkdir -p "$AUX_BUILD/gmp"
- cd "$AUX_BUILD/gmp" &&
+ cd "$AUX_BUILD/gmp"
if [[ ! -f config.status ]]; then
CC_FOR_BUILD=/usr/bin/gcc ABI=standard \
- emconfigure $BASEDIR/extern/gmp/configure \
- --build i686-pc-linux-gnu --host none \
- --disable-assembly --enable-cxx \
- --prefix=$AUX_PREFIX
- fi &&
- emmake make -j8 &&
+ emconfigure "$BASEDIR/extern/gmp/configure" \
+ --build i686-pc-linux-gnu --host none \
+ --disable-assembly --enable-cxx \
+ --prefix="$AUX_PREFIX"
+ fi
+ emmake make -j"$JOBS"
emmake make install
)
(
mkdir -p "$AUX_BUILD/zlib"
- cd "$AUX_BUILD/zlib" &&
+ cd "$AUX_BUILD/zlib"
if [[ ! -f Makefile ]]; then
- emconfigure $BASEDIR/extern/zlib/configure --prefix=$AUX_PREFIX
- fi;
- emmake make -j8 &&
+ # --static: skip the shared library. Newer emscripten's wasm-ld
+ # rejects linking zlib's .so test programs (examplesh) with
+ # "unknown file type: libz.so"; GAP only needs the static libz.a.
+ emconfigure "$BASEDIR/extern/zlib/configure" --static --prefix="$AUX_PREFIX"
+ fi
+ emmake make -j"$JOBS"
emmake make install
)
-# There are two problems with building GAP
-# 1) GAP builds some executables (ffgen and gap-nocomp), which it wants to
-# execute while building. We get these files from 'native-build'.
-# 2) 'configure' gets confused by some of the LDFLAGS we need, so we have to pass
-# them in to 'make'
+# Two quirks of building GAP under emscripten:
+# 1) GAP runs ffgen and gap-nocomp during the build. We copy the host-built
+# versions in from native-build/ further down.
+# 2) configure rejects some LDFLAGS we need at link time, so we pass them
+# only at make-time.
#
-# These options are:
-# -sASYNCIFY -- we don't care about ASYNC, but this forces the compiler to output
-# all variables onto the stack, which is required for GASMAN
-# Note we could use 'ALLOW_MEMORY_GROWTH', both we don't currently, we instead set
-# a big memory window.
-# -O2 : Some optimisation
-# EXEEXT=.html -- this is actually a GAP makefile option, it lets us make the
-# output 'gap.html', which makes emscripten output a html page we can load
-# --pre-js lazy_fs.js : Prepend lazy_fs.js that is generated for lazy loading
-
-# Run configure if we don't have a makefile, or someone configured this
-# GAP for standard building (emscripten builds will use 'emcc')
-if [[ ! -f GNUmakefile ]] || ! grep '/emcc' GNUmakefile > /dev/null; then
+# Link-time flags worth noting:
+# -sASYNCIFY forces variables onto the stack (required by GASMAN).
+# -O2 enables some optimisation.
+# EXEEXT=.html a GAP makefile knob that produces gap.html, the html
+# shim emscripten generates for loading the wasm module.
+
+if [[ ! -f GNUmakefile ]] || ! grep -q '/emcc' GNUmakefile; then
+ # Wipe any in-tree state from a prior native (or mismatched) build.
+ # Stale build/deps/*.d files reference build/ffdata.h, which under
+ # emcc would be regenerated by a non-executable JS shim; stale .o
+ # files have the wrong architecture. Configure regenerates build/.
+ rm -rf build ffgen
emconfigure ./configure ABI=32 \
- --with-gmp=$AUX_PREFIX \
- --with-zlib=$AUX_PREFIX \
- LDFLAGS="-s ASYNCIFY=1 -O2"
-fi;
+ --with-gmp="$AUX_PREFIX" \
+ --with-zlib="$AUX_PREFIX" \
+ LDFLAGS="-s ASYNCIFY=1 -O2"
+fi
-# Get full required packages
-emmake make bootstrap-pkg-full
+# Provide the GAP package distribution without re-downloading it on every
+# build. Preference order:
+# 1. An existing pkg/ directory.
+# 2. packages.tar.gz already on the host (carried in the source mount).
+# 3. The tarball baked into the docker image at /opt/gap-packages.tar.gz.
+# 4. As a last resort, GAP's own bootstrap-pkg-full target downloads it.
+# Skipping straight to tar avoids `bootstrap-pkg-full`, which calls
+# curl -L -O unconditionally and overwrites packages.tar.gz on every run.
+if [[ ! -d pkg ]]; then
+ if [[ ! -f packages.tar.gz && -f /opt/gap-packages.tar.gz ]]; then
+ cp /opt/gap-packages.tar.gz packages.tar.gz
+ fi
+ if [[ -f packages.tar.gz ]]; then
+ mkdir pkg
+ (cd pkg && tar xzf ../packages.tar.gz)
+ else
+ emmake make bootstrap-pkg-full
+ fi
+fi
-# Copy in files from native_build
+# Copy host-built generated sources into place
cp native-build/build/c_*.c native-build/build/ffdata.* src/
-# Dynamically find and append ALL required files to the JS array
-# The flag -type f is safe because the only symbolic link is 'tst/mockpkg/Makefile.gappkg',
-# which is safe to ignore
-find pkg lib grp tst doc hpcgap dev benchmark -type f | python3 etc/emscripten/generate_gap_fs_json.py
-
-if [ $? -ne 0 ]; then
- echo "Build aborted: generate_gap_fs_json.py failed."
- exit 1
-fi
+# Build the file list that will be served. -L follows symlinks so that
+# users' local development setups (e.g. replacing pkg/foo with a symlink
+# to a git checkout under git/foo) are picked up; -type f then drops any
+# symlinks themselves.
+find -L pkg lib grp tst doc hpcgap dev benchmark -type f ! -path 'pkg/log/*' \
+ | python3 etc/emscripten/generate_gap_fs_json.py
-# The EXEEXT is usually for windows, but here it lets us set GAP's extension,
-# which lets us produce a html page to run GAP in.
-emmake make -j8 LDFLAGS="-lidbfs.js -s ASYNCIFY=1 -sTOTAL_STACK=32mb -sASYNCIFY_STACK_SIZE=32000000 -sINITIAL_MEMORY=2048mb -O2" EXEEXT=".html"
+emmake make -j"$JOBS" \
+ LDFLAGS="-lidbfs.js -s ASYNCIFY=1 -sTOTAL_STACK=32mb -sASYNCIFY_STACK_SIZE=32000000 -sINITIAL_MEMORY=2048mb -O2" \
+ EXEEXT=".html"
diff --git a/etc/emscripten/build_startup_manifest.js b/etc/emscripten/build_startup_manifest.js
deleted file mode 100755
index edb8594b10..0000000000
--- a/etc/emscripten/build_startup_manifest.js
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/env node
-"use strict";
-
-const http = require('http');
-const fs = require('fs');
-const path = require('path');
-
-const PORT = 9999;
-const BASE_DIR = process.cwd();
-const LOG_FILE = path.join(BASE_DIR, 'startup_manifest.json');
-
-const requestedFiles = new Set();
-fs.writeFileSync(LOG_FILE, '[\n]');
-
-const server = http.createServer((req, res) => {
- let urlPath = req.url.split('?')[0];
- if (urlPath === '/') {
- urlPath = '/index.html';
- }
-
- let localDiskPath = urlPath;
- try {
- localDiskPath = decodeURIComponent(urlPath);
- } catch (e) {}
-
- const filePath = path.join(BASE_DIR, localDiskPath);
-
- fs.readFile(filePath, (err, data) => {
- if (err) {
- console.error(`[404] Ignored missing file: ${localDiskPath}`);
- res.writeHead(404);
- res.end(`404: File not found`);
- return;
- }
-
- const ignored = ['/favicon.ico', '/index.html', '/startup_manifest.json', 'coi-serviceworker.js', 'gap-worker.js', 'gap-fs.js', 'gap.js', 'gap.wasm', 'gap-fs.json'];
- if (!ignored.includes(localDiskPath)) {
- let manifestPath = localDiskPath.startsWith('/') ? localDiskPath.substring(1) : localDiskPath;
-
- if (!requestedFiles.has(manifestPath)) {
- requestedFiles.add(manifestPath);
-
- const manifest = Array.from(requestedFiles);
- fs.writeFileSync(LOG_FILE, JSON.stringify(manifest, null, 4));
-
- console.log(`[Loaded & Logged] ${manifestPath} (Total: ${requestedFiles.size})`);
- }
- }
-
- let contentType = 'application/octet-stream';
- if (urlPath.endsWith('.html')) contentType = 'text/html';
- else if (urlPath.endsWith('.js')) contentType = 'text/javascript';
- else if (urlPath.endsWith('.wasm')) contentType = 'application/wasm';
- else if (urlPath.endsWith('.css')) contentType = 'text/css';
-
- res.writeHead(200, {
- 'Content-Type': contentType,
- 'Cross-Origin-Opener-Policy': 'same-origin',
- 'Cross-Origin-Embedder-Policy': 'require-corp',
- 'Access-Control-Allow-Origin': '*'
- });
-
- res.end(data);
- });
-});
-
-server.listen(PORT, '0.0.0.0', () => {
- console.log(`\n Tracker running at http://localhost:${PORT}/`);
- console.log(`Serving files from: ${BASE_DIR}`);
- console.log(`Logging valid loaded files to: ${LOG_FILE}\n`);
-});
diff --git a/etc/emscripten/generate_gap_fs_json.py b/etc/emscripten/generate_gap_fs_json.py
index dbf5447bba..917f0a2a38 100755
--- a/etc/emscripten/generate_gap_fs_json.py
+++ b/etc/emscripten/generate_gap_fs_json.py
@@ -1,18 +1,11 @@
-import sys
-import json
-import os
-
-def main():
- paths = [line.strip() for line in sys.stdin if line.strip()]
+#!/usr/bin/env python3
+"""Read a list of file paths from stdin (one per line) and write them as a
+JSON array to gap-fs.json in the current directory."""
- try:
- with open('gap-fs.json', 'w', encoding='utf-8') as f:
- json.dump(paths, f, separators=(',', ':'))
-
- print(f"Successfully wrote {len(paths)} files to gap-fs.json", file=sys.stderr)
- except Exception as e:
- print(f"Failed to write gap-fs.json: {e}", file=sys.stderr)
- sys.exit(1)
+import json
+import sys
-if __name__ == "__main__":
- main()
+paths = [line.strip() for line in sys.stdin if line.strip()]
+with open("gap-fs.json", "w", encoding="utf-8") as f:
+ json.dump(paths, f, separators=(",", ":"))
+print(f"wrote {len(paths)} files to gap-fs.json", file=sys.stderr)
diff --git a/etc/emscripten/run-web-demo.sh b/etc/emscripten/run-web-demo.sh
deleted file mode 100755
index a82eb948a9..0000000000
--- a/etc/emscripten/run-web-demo.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/usr/bin/env bash
-
-set -eux
-
-echo This script assumes you have already run 'build.sh'
-
-mkdir -p web-example
-cp etc/emscripten/web-template/* web-example/
-cp gap.js gap.wasm gap.worker.js gap-fs.json web-example/
-
-cp -r pkg lib grp tst doc hpcgap dev benchmark web-example/
-cd web-example
-../etc/emscripten/server.rb
diff --git a/etc/emscripten/serve.py b/etc/emscripten/serve.py
new file mode 100755
index 0000000000..7d089f0c54
--- /dev/null
+++ b/etc/emscripten/serve.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python3
+"""Serve the current directory with the COOP/COEP headers required by
+xterm-pty's SharedArrayBuffer usage. Run from the assembled web-example/
+(or any directory containing the gap.* artifacts).
+
+ ./serve.py # listens on 8080
+ ./serve.py 9000 # listens on 9000
+"""
+
+from __future__ import annotations
+
+import http.server
+import socketserver
+import sys
+
+
+class CrossOriginIsolatedHandler(http.server.SimpleHTTPRequestHandler):
+ def end_headers(self):
+ self.send_header("Cross-Origin-Opener-Policy", "same-origin")
+ self.send_header("Cross-Origin-Embedder-Policy", "require-corp")
+ super().end_headers()
+
+
+def main() -> None:
+ port = int(sys.argv[1]) if len(sys.argv) > 1 else 8080
+ with socketserver.TCPServer(("", port), CrossOriginIsolatedHandler) as httpd:
+ print(f"Serving on http://localhost:{port}/ (Ctrl-C to stop)")
+ try:
+ httpd.serve_forever()
+ except KeyboardInterrupt:
+ print()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/etc/emscripten/server.rb b/etc/emscripten/server.rb
deleted file mode 100755
index 642c9ad167..0000000000
--- a/etc/emscripten/server.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/env ruby
-# Taken from https://github.com/mame/xterm-pty/
-
-require "webrick"
-
-class Server < WEBrick::HTTPServer
- def service(req, res)
- super
- res["Cross-Origin-Opener-Policy"] = "same-origin"
- res["Cross-Origin-Embedder-Policy"] = "require-corp"
- end
-end
-
-Server.new(Port: 8080, DocumentRoot: ".").start
-
diff --git a/etc/emscripten/startup_manifest.json b/etc/emscripten/startup_manifest.json
new file mode 100644
index 0000000000..3ab701c269
--- /dev/null
+++ b/etc/emscripten/startup_manifest.json
@@ -0,0 +1,1521 @@
+[
+ "lib/init.g",
+ "lib/kernel.g",
+ "lib/global.g",
+ "lib/system.g",
+ "lib/read1.g",
+ "lib/hpc/thread1.g",
+ "lib/filter.g",
+ "lib/oper.g",
+ "lib/oper1.g",
+ "lib/type.g",
+ "lib/type1.g",
+ "lib/methsel.g",
+ "lib/methsel2.g",
+ "lib/function.g",
+ "lib/cache.gd",
+ "lib/object.gd",
+ "lib/variable.g",
+ "lib/package.gd",
+ "lib/coll.gd",
+ "lib/list.gd",
+ "lib/wpobj.gd",
+ "lib/arith.gd",
+ "lib/ffe.gd",
+ "lib/domain.gd",
+ "lib/string.g",
+ "lib/cyclotom.g",
+ "lib/set.gd",
+ "lib/record.gd",
+ "lib/random.gd",
+ "lib/cache.gi",
+ "lib/coll.gi",
+ "lib/flag.g",
+ "lib/boolean.g",
+ "lib/ffe.g",
+ "lib/arith.gi",
+ "lib/list.g",
+ "lib/wpobj.g",
+ "lib/permutat.g",
+ "lib/trans.g",
+ "lib/pperm.g",
+ "lib/filter.gi",
+ "lib/object.gi",
+ "lib/listcoef.gd",
+ "lib/info.gd",
+ "lib/files.gd",
+ "lib/streams.gd",
+ "lib/record.gi",
+ "lib/matobj1.gd",
+ "lib/vecmat.gd",
+ "lib/vec8bit.gd",
+ "lib/mat8bit.gd",
+ "lib/global.gd",
+ "lib/info.gi",
+ "lib/global.gi",
+ "lib/options.gd",
+ "lib/options.gi",
+ "lib/attr.gd",
+ "lib/attr.gi",
+ "lib/string.gd",
+ "lib/userpref.g",
+ "lib/cmdledit.g",
+ "lib/cmdleditx.g",
+ "lib/objset.g",
+ "lib/float.gd",
+ "lib/macfloat.g",
+ "lib/hpc/tasks.g",
+ "lib/error.g",
+ "lib/session.g",
+ "lib/read2.g",
+ "lib/process.gd",
+ "lib/files.gi",
+ "lib/streams.gi",
+ "lib/process.gi",
+ "lib/read3.g",
+ "lib/type.gd",
+ "lib/tuples.gd",
+ "lib/rvecempt.gd",
+ "lib/extaset.gd",
+ "lib/extlset.gd",
+ "lib/extrset.gd",
+ "lib/extuset.gd",
+ "lib/dict.gd",
+ "lib/bitfields.gd",
+ "lib/mapping.gd",
+ "lib/mapphomo.gd",
+ "lib/relation.gd",
+ "lib/magma.gd",
+ "lib/mgmideal.gd",
+ "lib/mgmhom.gd",
+ "lib/mgmadj.gd",
+ "lib/mgmcong.gd",
+ "lib/semicong.gd",
+ "lib/semigrp.gd",
+ "lib/smgideal.gd",
+ "lib/monoid.gd",
+ "lib/grp.gd",
+ "lib/invsgp.gd",
+ "lib/addmagma.gd",
+ "lib/addcoset.gd",
+ "lib/semiring.gd",
+ "lib/ring.gd",
+ "lib/matrix.gd",
+ "lib/matint.gd",
+ "lib/matblock.gd",
+ "lib/ideal.gd",
+ "lib/module.gd",
+ "lib/basis.gd",
+ "lib/basismut.gd",
+ "lib/vspc.gd",
+ "lib/vspchom.gd",
+ "lib/zlattice.gd",
+ "lib/algebra.gd",
+ "lib/mgmring.gd",
+ "lib/algfp.gd",
+ "lib/alglie.gd",
+ "lib/algsc.gd",
+ "lib/alghom.gd",
+ "lib/liefam.gd",
+ "lib/algrep.gd",
+ "lib/lierep.gd",
+ "lib/integer.gd",
+ "lib/gaussian.gd",
+ "lib/numtheor.gd",
+ "lib/dlog.gd",
+ "lib/primality.gd",
+ "lib/contfrac.gd",
+ "lib/ringsc.gd",
+ "lib/ringhom.gd",
+ "lib/combinat.gd",
+ "lib/ratfun.gd",
+ "lib/fampred.g",
+ "lib/list.gi",
+ "lib/set.gi",
+ "lib/wpobj.gi",
+ "lib/random.gi",
+ "lib/field.gd",
+ "lib/zmodnz.gd",
+ "lib/zmodnze.gd",
+ "lib/cyclotom.gd",
+ "lib/fldabnum.gd",
+ "lib/padics.gd",
+ "lib/ringpoly.gd",
+ "lib/upoly.gd",
+ "lib/polyfinf.gd",
+ "lib/polyrat.gd",
+ "lib/polyconw.gd",
+ "lib/algfld.gd",
+ "lib/meataxe.gd",
+ "lib/unknown.gd",
+ "lib/word.gd",
+ "lib/wordass.gd",
+ "lib/matobj2.gd",
+ "lib/matobjplist.gd",
+ "lib/matobjnz.gd",
+ "lib/rws.gd",
+ "lib/rwspcclt.gd",
+ "lib/rwsgrp.gd",
+ "lib/rwspcgrp.gd",
+ "lib/groebner.gd",
+ "lib/pcgs.gd",
+ "lib/pcgsind.gd",
+ "lib/pcgspcg.gd",
+ "lib/pcgsmodu.gd",
+ "lib/pcgsperm.gd",
+ "lib/pcgsspec.gd",
+ "lib/grppc.gd",
+ "lib/grppcnrm.gd",
+ "lib/grptbl.gd",
+ "lib/grpperm.gd",
+ "lib/grpprmcs.gd",
+ "lib/stbcbckt.gd",
+ "lib/ghom.gd",
+ "lib/ghompcgs.gd",
+ "lib/gprd.gd",
+ "lib/ghomperm.gd",
+ "lib/gpprmsya.gd",
+ "lib/addgphom.gd",
+ "lib/grpnames.g",
+ "lib/grpnames.gd",
+ "lib/quotsys.gd",
+ "lib/pquot.gd",
+ "lib/oprt.gd",
+ "lib/partitio.gd",
+ "lib/stbc.gd",
+ "lib/clas.gd",
+ "lib/clashom.gd",
+ "lib/permdeco.gd",
+ "lib/csetgrp.gd",
+ "lib/factgrp.gd",
+ "lib/grpreps.gd",
+ "lib/grppcrep.gd",
+ "lib/onecohom.gd",
+ "lib/grppccom.gd",
+ "lib/twocohom.gd",
+ "lib/grppcext.gd",
+ "lib/grppcfp.gd",
+ "lib/randiso.gd",
+ "lib/schur.gd",
+ "lib/schursym.gd",
+ "lib/grplatt.gd",
+ "lib/oprtglat.gd",
+ "lib/grppclat.gd",
+ "lib/grppcaut.gd",
+ "lib/straight.gd",
+ "lib/memory.gd",
+ "lib/grpfp.gd",
+ "lib/grpfree.gd",
+ "lib/sgpres.gd",
+ "lib/tietze.gd",
+ "lib/ghomfp.gd",
+ "lib/dt.g",
+ "lib/integer.gi",
+ "lib/grpnice.gd",
+ "lib/morpheus.gd",
+ "lib/grpmat.gd",
+ "lib/fitfree.gd",
+ "lib/grpffmat.gd",
+ "lib/grpramat.gd",
+ "grp/basic.gd",
+ "grp/classic.gd",
+ "grp/conformal.gd",
+ "grp/perf.gd",
+ "grp/suzuki.gd",
+ "grp/ree.gd",
+ "grp/simple.gd",
+ "grp/imf.gd",
+ "grp/glzmodmz.gd",
+ "grp/clasmax.grp",
+ "lib/orders.gd",
+ "lib/trans.gd",
+ "lib/pperm.gd",
+ "lib/fastendo.gd",
+ "lib/fpsemi.gd",
+ "lib/fpmon.gd",
+ "lib/rwssmg.gd",
+ "lib/kbsemi.gd",
+ "lib/tcsemi.gd",
+ "lib/adjoin.gd",
+ "lib/semirel.gd",
+ "lib/semitran.gd",
+ "lib/reesmat.gd",
+ "lib/semiquo.gd",
+ "lib/semipperm.gd",
+ "lib/pager.gd",
+ "lib/helpbase.gd",
+ "lib/helpview.gd",
+ "lib/helpt2t.gd",
+ "lib/helpdef.gd",
+ "lib/ctbl.gd",
+ "lib/ctblfuns.gd",
+ "lib/ctblmaps.gd",
+ "lib/ctblauto.gd",
+ "lib/ctbllatt.gd",
+ "lib/ctblsymm.gd",
+ "lib/ctblsolv.gd",
+ "lib/ctblpope.gd",
+ "lib/ctblmoli.gd",
+ "lib/ctblmono.gd",
+ "lib/ctblgrp.gd",
+ "lib/tom.gd",
+ "lib/proto.gd",
+ "lib/gasman.gd",
+ "lib/memusage.gd",
+ "lib/read4.g",
+ "lib/profile.g",
+ "lib/newprofile.g",
+ "lib/methwhy.g",
+ "lib/pager.gi",
+ "lib/helpbase.gi",
+ "lib/helpview.gi",
+ "lib/helpt2t.gi",
+ "lib/helpdef.gi",
+ "lib/reread.g",
+ "lib/package.gi",
+ "lib/string.gi",
+ "lib/test.gd",
+ "lib/test.gi",
+ "lib/galois.gd",
+ "lib/galois.gi",
+ "lib/transatl.g",
+ "lib/obsolete.g",
+ "lib/obsolete.gd",
+ "lib/read.g",
+ "lib/read5.g",
+ "lib/type.gi",
+ "lib/rvecempt.gi",
+ "lib/ratfun1.gi",
+ "lib/matrix.gi",
+ "lib/matint.gi",
+ "lib/matblock.gi",
+ "lib/tuples.gi",
+ "lib/domain.gi",
+ "lib/mapping1.gi",
+ "lib/mapping.gi",
+ "lib/mapprep.gi",
+ "lib/mapphomo.gi",
+ "lib/relation.gi",
+ "lib/magma.gi",
+ "lib/mgmideal.gi",
+ "lib/mgmhom.gi",
+ "lib/mgmadj.gi",
+ "lib/mgmcong.gi",
+ "lib/semigrp.gi",
+ "lib/semicong.gi",
+ "lib/smgideal.gi",
+ "lib/monoid.gi",
+ "lib/grp.gi",
+ "lib/invsgp.gi",
+ "lib/addmagma.gi",
+ "lib/addcoset.gi",
+ "lib/ring.gi",
+ "lib/ideal.gi",
+ "lib/module.gi",
+ "lib/modfree.gi",
+ "lib/modulrow.gi",
+ "lib/modulmat.gi",
+ "lib/basis.gi",
+ "lib/basismut.gi",
+ "lib/vspc.gi",
+ "lib/vspcrow.gi",
+ "lib/vspcmat.gi",
+ "lib/vspchom.gi",
+ "lib/zlattice.gi",
+ "lib/mgmring.gi",
+ "lib/algebra.gi",
+ "lib/idealalg.gi",
+ "lib/alghom.gi",
+ "lib/algfp.gi",
+ "lib/alglie.gi",
+ "lib/algliess.gi",
+ "lib/algsc.gi",
+ "lib/algmat.gi",
+ "lib/liefam.gi",
+ "lib/algrep.gi",
+ "lib/lierep.gi",
+ "lib/numtheor.gi",
+ "lib/dlog.gi",
+ "lib/primality.gi",
+ "lib/contfrac.gi",
+ "lib/ringsc.gi",
+ "lib/ringhom.gi",
+ "lib/combinat.gi",
+ "lib/ratfun.gi",
+ "lib/ratfunul.gi",
+ "lib/ringpoly.gi",
+ "lib/upoly.gi",
+ "lib/upolyirr.gi",
+ "lib/polyfinf.gi",
+ "lib/polyrat.gi",
+ "lib/polyconw.gi",
+ "lib/listcoef.gi",
+ "lib/algfld.gi",
+ "lib/groebner.gi",
+ "lib/unknown.gi",
+ "lib/field.gi",
+ "lib/fieldfin.gi",
+ "lib/zmodnz.gi",
+ "lib/zmodnze.gi",
+ "lib/ffe.gi",
+ "lib/ffeconway.gi",
+ "lib/rational.gi",
+ "lib/gaussian.gi",
+ "lib/cyclotom.gi",
+ "lib/fldabnum.gi",
+ "lib/padics.gi",
+ "lib/matobj.gi",
+ "lib/matobjrowlist.gi",
+ "lib/vecmat.gi",
+ "lib/vec8bit.gi",
+ "lib/mat8bit.gi",
+ "lib/matobjplist.gi",
+ "lib/matobjnz.gi",
+ "lib/meataxe.gi",
+ "lib/meatauto.gi",
+ "lib/word.gi",
+ "lib/wordass.gi",
+ "lib/wordrep.gi",
+ "lib/wordlett.gi",
+ "lib/mgmfree.gi",
+ "lib/smgrpfre.gi",
+ "lib/monofree.gi",
+ "lib/grpfree.gi",
+ "lib/rws.gi",
+ "lib/rwspcclt.gi",
+ "lib/rwspcsng.gi",
+ "lib/rwspccoc.gi",
+ "lib/rwsgrp.gi",
+ "lib/rwspcgrp.gi",
+ "lib/rwsdt.gi",
+ "lib/nilpquot.gi",
+ "lib/pquot.gi",
+ "lib/pcgs.gi",
+ "lib/pcgsind.gi",
+ "lib/pcgsmodu.gi",
+ "lib/pcgspcg.gi",
+ "lib/pcgscomp.gi",
+ "lib/pcgsperm.gi",
+ "lib/pcgsnice.gi",
+ "lib/pcgsspec.gi",
+ "lib/grppc.gi",
+ "lib/grppcint.gi",
+ "lib/grppcprp.gi",
+ "lib/grppcatr.gi",
+ "lib/grppcnrm.gi",
+ "lib/bitfields.gi",
+ "lib/dict.gi",
+ "lib/dicthf.gi",
+ "lib/grptbl.gi",
+ "lib/ghom.gi",
+ "lib/ghompcgs.gi",
+ "lib/gprd.gi",
+ "lib/ghomperm.gi",
+ "lib/grpperm.gi",
+ "lib/gpprmsya.gi",
+ "lib/gprdperm.gi",
+ "lib/gprdpc.gi",
+ "lib/gprdmat.gi",
+ "lib/oprt.gi",
+ "lib/oprtperm.gi",
+ "lib/oprtpcgs.gi",
+ "lib/partitio.gi",
+ "lib/stbc.gi",
+ "lib/stbcbckt.gi",
+ "lib/stbcrand.gi",
+ "lib/clas.gi",
+ "lib/claspcgs.gi",
+ "lib/csetgrp.gi",
+ "lib/csetperm.gi",
+ "lib/csetpc.gi",
+ "lib/factgrp.gi",
+ "lib/grpreps.gi",
+ "lib/grppcrep.gi",
+ "lib/grpprmcs.gi",
+ "lib/grpnames.gi",
+ "lib/onecohom.gi",
+ "lib/grppccom.gi",
+ "lib/grpcompl.gi",
+ "lib/twocohom.gi",
+ "lib/grppcext.gi",
+ "lib/randiso.gi",
+ "lib/randiso2.gi",
+ "lib/grppcfp.gi",
+ "lib/schur.gi",
+ "lib/schursym.gi",
+ "lib/grpnice.gi",
+ "lib/fitfree.gi",
+ "lib/permdeco.gi",
+ "lib/clashom.gi",
+ "lib/clasperm.gi",
+ "lib/maxsub.gi",
+ "lib/norad.gi",
+ "lib/autsr.gi",
+ "lib/morpheus.gi",
+ "lib/grplatt.gi",
+ "lib/oprtglat.gi",
+ "lib/grppclat.gi",
+ "lib/grppcaut.gi",
+ "lib/grpmat.gi",
+ "lib/grpffmat.gi",
+ "lib/grpramat.gi",
+ "lib/grpfp.gi",
+ "lib/gpfpiso.gi",
+ "lib/sgpres.gi",
+ "lib/tietze.gi",
+ "lib/ghomfp.gi",
+ "lib/addgphom.gi",
+ "lib/trans.gi",
+ "lib/pperm.gi",
+ "lib/fastendo.gi",
+ "lib/fpsemi.gi",
+ "lib/fpmon.gi",
+ "lib/rwssmg.gi",
+ "lib/kbsemi.gi",
+ "lib/tcsemi.gi",
+ "lib/adjoin.gi",
+ "lib/semirel.gi",
+ "lib/semitran.gi",
+ "lib/reesmat.gi",
+ "lib/semiquo.gi",
+ "lib/semipperm.gi",
+ "lib/proto.gi",
+ "lib/orders.gi",
+ "lib/gasman.gi",
+ "lib/memusage.gi",
+ "lib/function.gi",
+ "lib/float.gi",
+ "lib/ieee754.g",
+ "lib/read6.g",
+ "grp/basicpcg.gi",
+ "grp/basicprm.gi",
+ "grp/basicmat.gi",
+ "grp/basicfp.gi",
+ "grp/perf.grp",
+ "grp/classic.gi",
+ "grp/conformal.gi",
+ "grp/suzuki.gi",
+ "grp/ree.gi",
+ "grp/simple.gi",
+ "grp/imf.grp",
+ "grp/imf.gi",
+ "grp/glzmodmz.gi",
+ "lib/read7.g",
+ "lib/ctbl.gi",
+ "lib/ctblfuns.gi",
+ "lib/ctblmaps.gi",
+ "lib/ctblauto.gi",
+ "lib/ctbllatt.gi",
+ "lib/ctblsymm.gi",
+ "lib/ctblsolv.gi",
+ "lib/ctblpope.gi",
+ "lib/ctblmoli.gi",
+ "lib/ctblmono.gi",
+ "lib/ctblgrp.gi",
+ "lib/ctblperm.gi",
+ "lib/ctblpc.gi",
+ "lib/tom.gi",
+ "lib/straight.gi",
+ "lib/memory.gi",
+ "lib/read8.g",
+ "lib/overload.g",
+ "lib/syntaxtree.gd",
+ "lib/syntaxtree.gi",
+ "lib/teaching.g",
+ "lib/teachm2.g",
+ "lib/operdebug.g",
+ "lib/colorprompt.g",
+ "pkg/4ti2interface/PackageInfo.g",
+ "pkg/ace/PackageInfo.g",
+ "pkg/aclib/PackageInfo.g",
+ "pkg/agt/PackageInfo.g",
+ "pkg/alco/PackageInfo.g",
+ "pkg/alnuth/PackageInfo.g",
+ "pkg/anupq/PackageInfo.g",
+ "pkg/atlasrep/PackageInfo.g",
+ "pkg/autodoc/PackageInfo.g",
+ "pkg/automata/PackageInfo.g",
+ "pkg/automgrp/PackageInfo.g",
+ "pkg/autpgrp/PackageInfo.g",
+ "pkg/browse/PackageInfo.g",
+ "pkg/cap/PackageInfo.g",
+ "pkg/caratinterface/PackageInfo.g",
+ "pkg/cddinterface/PackageInfo.g",
+ "pkg/circle/PackageInfo.g",
+ "pkg/classicalmaximals/PackageInfo.g",
+ "pkg/classicpres/PackageInfo.g",
+ "pkg/cohomolo/PackageInfo.g",
+ "pkg/congruence/PackageInfo.g",
+ "pkg/corefreesub/PackageInfo.g",
+ "pkg/corelg/PackageInfo.g",
+ "pkg/crime/PackageInfo.g",
+ "pkg/crisp/PackageInfo.g",
+ "pkg/crypting/PackageInfo.g",
+ "pkg/cryst/PackageInfo.g",
+ "pkg/crystcat/PackageInfo.g",
+ "pkg/ctbllib/PackageInfo.g",
+ "pkg/cubefree/PackageInfo.g",
+ "pkg/curlinterface/PackageInfo.g",
+ "pkg/cvec/PackageInfo.g",
+ "pkg/datastructures/PackageInfo.g",
+ "pkg/deepthought/PackageInfo.g",
+ "pkg/design/PackageInfo.g",
+ "pkg/difsets/PackageInfo.g",
+ "pkg/digraphs/PackageInfo.g",
+ "pkg/edim/PackageInfo.g",
+ "pkg/example/PackageInfo.g",
+ "pkg/examplesforhomalg/PackageInfo.g",
+ "pkg/factint/PackageInfo.g",
+ "pkg/ferret/PackageInfo.g",
+ "pkg/fga/PackageInfo.g",
+ "pkg/fining/PackageInfo.g",
+ "pkg/float/PackageInfo.g",
+ "pkg/format/PackageInfo.g",
+ "pkg/forms/PackageInfo.g",
+ "pkg/fplsa/PackageInfo.g",
+ "pkg/fr/PackageInfo.g",
+ "pkg/francy/PackageInfo.g",
+ "pkg/fwtree/PackageInfo.g",
+ "pkg/gapdoc/PackageInfo.g",
+ "pkg/gauss/PackageInfo.g",
+ "pkg/gaussforhomalg/PackageInfo.g",
+ "pkg/gbnp/PackageInfo.g",
+ "pkg/generalizedmorphismsforcap/PackageInfo.g",
+ "pkg/genss/PackageInfo.g",
+ "pkg/gradedmodules/PackageInfo.g",
+ "pkg/gradedringforhomalg/PackageInfo.g",
+ "pkg/grape/PackageInfo.g",
+ "pkg/groupoids/PackageInfo.g",
+ "pkg/grpconst/PackageInfo.g",
+ "pkg/guarana/PackageInfo.g",
+ "pkg/guava/PackageInfo.g",
+ "pkg/hap/PackageInfo.g",
+ "pkg/hapcryst/PackageInfo.g",
+ "pkg/hecke/PackageInfo.g",
+ "pkg/help/PackageInfo.g",
+ "pkg/homalg/PackageInfo.g",
+ "pkg/homalgtocas/PackageInfo.g",
+ "pkg/ibnp/PackageInfo.g",
+ "pkg/idrel/PackageInfo.g",
+ "pkg/images/PackageInfo.g",
+ "pkg/inducereduce/PackageInfo.g",
+ "pkg/intpic/PackageInfo.g",
+ "pkg/io/PackageInfo.g",
+ "pkg/io_forhomalg/PackageInfo.g",
+ "pkg/irredsol/PackageInfo.g",
+ "pkg/itc/PackageInfo.g",
+ "pkg/json/PackageInfo.g",
+ "pkg/jupyterkernel/PackageInfo.g",
+ "pkg/jupyterviz/PackageInfo.g",
+ "pkg/kan/PackageInfo.g",
+ "pkg/kbmag/PackageInfo.g",
+ "pkg/laguna/PackageInfo.g",
+ "pkg/liealgdb/PackageInfo.g",
+ "pkg/liepring/PackageInfo.g",
+ "pkg/liering/PackageInfo.g",
+ "pkg/linearalgebraforcap/PackageInfo.g",
+ "pkg/lins/PackageInfo.g",
+ "pkg/localizeringforhomalg/PackageInfo.g",
+ "pkg/localnr/PackageInfo.g",
+ "pkg/loops/PackageInfo.g",
+ "pkg/lpres/PackageInfo.g",
+ "pkg/majoranaalgebras/PackageInfo.g",
+ "pkg/mapclass/PackageInfo.g",
+ "pkg/matgrp/PackageInfo.g",
+ "pkg/matricesforhomalg/PackageInfo.g",
+ "pkg/modisom/PackageInfo.g",
+ "pkg/modulargroup/PackageInfo.g",
+ "pkg/modulepresentationsforcap/PackageInfo.g",
+ "pkg/modules/PackageInfo.g",
+ "pkg/monoidalcategories/PackageInfo.g",
+ "pkg/nconvex/PackageInfo.g",
+ "pkg/nilmat/PackageInfo.g",
+ "pkg/nock/PackageInfo.g",
+ "pkg/nofoma/PackageInfo.g",
+ "pkg/normalizinterface/PackageInfo.g",
+ "pkg/nq/PackageInfo.g",
+ "pkg/numericalsgps/PackageInfo.g",
+ "pkg/openmath/PackageInfo.g",
+ "pkg/orb/PackageInfo.g",
+ "pkg/origami/PackageInfo.g",
+ "pkg/packagemaker/PackageInfo.g",
+ "pkg/packagemanager/PackageInfo.g",
+ "pkg/patternclass/PackageInfo.g",
+ "pkg/permut/PackageInfo.g",
+ "pkg/polenta/PackageInfo.g",
+ "pkg/polycyclic/PackageInfo.g",
+ "pkg/polymaking/PackageInfo.g",
+ "pkg/primgrp/PackageInfo.g",
+ "pkg/profiling/PackageInfo.g",
+ "pkg/qdistrnd/PackageInfo.g",
+ "pkg/qpa/PackageInfo.g",
+ "pkg/quagroup/PackageInfo.g",
+ "pkg/radiroot/PackageInfo.g",
+ "pkg/rcwa/PackageInfo.g",
+ "pkg/rds/PackageInfo.g",
+ "pkg/recog/PackageInfo.g",
+ "pkg/repndecomp/PackageInfo.g",
+ "pkg/repsn/PackageInfo.g",
+ "pkg/resclasses/PackageInfo.g",
+ "pkg/ringsforhomalg/PackageInfo.g",
+ "pkg/sco/PackageInfo.g",
+ "pkg/scscp/PackageInfo.g",
+ "pkg/semigroups/PackageInfo.g",
+ "pkg/sglppow/PackageInfo.g",
+ "pkg/sgpviz/PackageInfo.g",
+ "pkg/simpcomp/PackageInfo.g",
+ "pkg/singular/PackageInfo.g",
+ "pkg/sl2reps/PackageInfo.g",
+ "pkg/sla/PackageInfo.g",
+ "pkg/smallantimagmas/PackageInfo.g",
+ "pkg/smallclassnr/PackageInfo.g",
+ "pkg/smallgrp/PackageInfo.g",
+ "pkg/smallsemi/PackageInfo.g",
+ "pkg/sonata/PackageInfo.g",
+ "pkg/sophus/PackageInfo.g",
+ "pkg/sotgrps/PackageInfo.g",
+ "pkg/spinsym/PackageInfo.g",
+ "pkg/standardff/PackageInfo.g",
+ "pkg/symbcompcc/PackageInfo.g",
+ "pkg/thelma/PackageInfo.g",
+ "pkg/tomlib/PackageInfo.g",
+ "pkg/toolsforhomalg/PackageInfo.g",
+ "pkg/toric/PackageInfo.g",
+ "pkg/transgrp/PackageInfo.g",
+ "pkg/twistedconjugacy/PackageInfo.g",
+ "pkg/typeset/PackageInfo.g",
+ "pkg/ugaly/PackageInfo.g",
+ "pkg/unipot/PackageInfo.g",
+ "pkg/unitlib/PackageInfo.g",
+ "pkg/utils/PackageInfo.g",
+ "pkg/uuid/PackageInfo.g",
+ "pkg/walrus/PackageInfo.g",
+ "pkg/wedderga/PackageInfo.g",
+ "pkg/wpe/PackageInfo.g",
+ "pkg/xgap/PackageInfo.g",
+ "pkg/xmod/PackageInfo.g",
+ "pkg/xmodalg/PackageInfo.g",
+ "pkg/yangbaxter/PackageInfo.g",
+ "pkg/zeromqinterface/PackageInfo.g",
+ "pkg/gapdoc/init.g",
+ "pkg/gapdoc/lib/UnicodeTools.gd",
+ "pkg/gapdoc/lib/PrintUtil.gd",
+ "pkg/gapdoc/lib/Text.gd",
+ "pkg/gapdoc/lib/ComposeXML.gd",
+ "pkg/gapdoc/lib/XMLParser.gd",
+ "pkg/gapdoc/lib/GAPDoc.gd",
+ "pkg/gapdoc/lib/BibTeX.gd",
+ "pkg/gapdoc/lib/BibXMLextTools.gd",
+ "pkg/gapdoc/lib/GAPDoc2LaTeX.gd",
+ "pkg/gapdoc/lib/GAPDoc2Text.gd",
+ "pkg/gapdoc/lib/GAPDoc2HTML.gd",
+ "pkg/gapdoc/lib/Make.g",
+ "pkg/gapdoc/lib/Examples.gd",
+ "pkg/gapdoc/read.g",
+ "pkg/gapdoc/lib/UnicodeTools.gi",
+ "pkg/gapdoc/lib/UnicodeTabs.g",
+ "pkg/gapdoc/lib/PrintUtil.gi",
+ "pkg/gapdoc/lib/Text.gi",
+ "pkg/gapdoc/lib/ComposeXML.gi",
+ "pkg/gapdoc/lib/XMLParser.gi",
+ "pkg/gapdoc/lib/gapdocdtdinfo.g",
+ "pkg/gapdoc/lib/GAPDoc.gi",
+ "pkg/gapdoc/lib/BibTeX.gi",
+ "pkg/gapdoc/lib/bibxmlextinfo.g",
+ "pkg/gapdoc/lib/BibXMLextTools.gi",
+ "pkg/gapdoc/lib/GAPDoc2LaTeX.gi",
+ "pkg/gapdoc/lib/latexhead.tex",
+ "pkg/gapdoc/lib/GAPDoc2Text.gi",
+ "pkg/gapdoc/lib/TextThemes.g",
+ "pkg/gapdoc/lib/GAPDoc2HTML.gi",
+ "pkg/gapdoc/lib/Examples.gi",
+ "pkg/gapdoc/lib/HelpBookHandler.g",
+ "pkg/primgrp/init.g",
+ "pkg/primgrp/lib/primitiv.gd",
+ "pkg/primgrp/lib/irredsol.gd",
+ "pkg/primgrp/read.g",
+ "pkg/primgrp/lib/primitiv.grp",
+ "pkg/primgrp/lib/primitiv.gi",
+ "pkg/primgrp/lib/irredsol.grp",
+ "pkg/primgrp/lib/irredsol.gi",
+ "pkg/primgrp/lib/cohorts.grp",
+ "pkg/smallgrp/init.g",
+ "pkg/smallgrp/gap/small.gd",
+ "pkg/smallgrp/read.g",
+ "pkg/smallgrp/gap/small.gi",
+ "pkg/smallgrp/gap/smlgp1.g",
+ "pkg/smallgrp/gap/idgrp1.g",
+ "pkg/smallgrp/gap/smlinfo.gi",
+ "pkg/smallgrp/small2/smlgp2.g.gz",
+ "pkg/smallgrp/small3/smlgp3.g.gz",
+ "pkg/smallgrp/small4/smlgp4.g.gz",
+ "pkg/smallgrp/small5/smlgp5.g.gz",
+ "pkg/smallgrp/small6/smlgp6.g.gz",
+ "pkg/smallgrp/small7/smlgp7.g.gz",
+ "pkg/smallgrp/small8/smlgp8.g.gz",
+ "pkg/smallgrp/small9/smlgp9.g.gz",
+ "pkg/smallgrp/small10/smlgp10.g.gz",
+ "pkg/smallgrp/small11/smlgp11.g.gz",
+ "pkg/smallgrp/id2/idgrp2.g.gz",
+ "pkg/smallgrp/id3/idgrp3.g.gz",
+ "pkg/smallgrp/id4/idgrp4.g.gz",
+ "pkg/smallgrp/id5/idgrp5.g.gz",
+ "pkg/smallgrp/id6/idgrp6.g.gz",
+ "pkg/smallgrp/id9/idgrp9.g.gz",
+ "pkg/smallgrp/id10/idgrp10.g.gz",
+ "pkg/transgrp/init.g",
+ "pkg/transgrp/lib/trans.gd",
+ "pkg/transgrp/read.g",
+ "pkg/transgrp/lib/trans.grp",
+ "pkg/transgrp/lib/trans.gi",
+ "pkg/autpgrp/init.g",
+ "pkg/autpgrp/gap/autos.gd",
+ "pkg/autpgrp/read.g",
+ "pkg/autpgrp/gap/general.gi",
+ "pkg/autpgrp/gap/autoops.gi",
+ "pkg/autpgrp/gap/matrix.gi",
+ "pkg/autpgrp/gap/nicestab.gi",
+ "pkg/autpgrp/gap/initmat.gi",
+ "pkg/autpgrp/gap/initperm.gi",
+ "pkg/autpgrp/gap/hybrstab.gi",
+ "pkg/autpgrp/gap/matrstab.gi",
+ "pkg/autpgrp/gap/orbstab.gi",
+ "pkg/autpgrp/gap/autos.gi",
+ "pkg/autpgrp/gap/pcpres.gi",
+ "pkg/autpgrp/gap/countcl.gi",
+ "pkg/alnuth/init.g",
+ "pkg/alnuth/gap/setup.gd",
+ "pkg/alnuth/gap/factors.gd",
+ "pkg/alnuth/gap/field.gd",
+ "pkg/polycyclic/init.g",
+ "pkg/polycyclic/gap/matrix/matrix.gd",
+ "pkg/polycyclic/gap/basic/infos.gd",
+ "pkg/polycyclic/gap/basic/collect.gd",
+ "pkg/polycyclic/gap/basic/pcpelms.gd",
+ "pkg/polycyclic/gap/basic/pcpgrps.gd",
+ "pkg/polycyclic/gap/basic/pcppcps.gd",
+ "pkg/polycyclic/gap/basic/grphoms.gd",
+ "pkg/polycyclic/gap/basic/basic.gd",
+ "pkg/polycyclic/gap/cohom/cohom.gd",
+ "pkg/polycyclic/gap/matrep/matrep.gd",
+ "pkg/polycyclic/gap/matrep/unitri.gd",
+ "pkg/polycyclic/gap/pcpgrp/pcpgrp.gd",
+ "pkg/polycyclic/gap/pcpgrp/torsion.gd",
+ "pkg/polycyclic/gap/exam/exam.gd",
+ "pkg/polycyclic/gap/obsolete.gd",
+ "pkg/alnuth/read.g",
+ "pkg/alnuth/gap/userpref.gi",
+ "pkg/alnuth/gap/setup.gi",
+ "pkg/alnuth/gap/pari.gi",
+ "pkg/alnuth/gap/factors.gi",
+ "pkg/alnuth/gap/matfield.gi",
+ "pkg/alnuth/gap/polfield.gi",
+ "pkg/alnuth/gap/field.gi",
+ "pkg/alnuth/gap/unithom.gi",
+ "pkg/alnuth/gap/matunits.gi",
+ "pkg/alnuth/gap/rels.gi",
+ "pkg/alnuth/gap/present.gi",
+ "pkg/alnuth/gap/isom.gi",
+ "pkg/alnuth/gap/rationals.gi",
+ "pkg/alnuth/exam/unimod.gi",
+ "pkg/alnuth/exam/rationals.gi",
+ "pkg/alnuth/exam/fields.gi",
+ "pkg/polycyclic/read.g",
+ "pkg/polycyclic/gap/matrix/rowbases.gi",
+ "pkg/polycyclic/gap/matrix/latbases.gi",
+ "pkg/polycyclic/gap/matrix/lattices.gi",
+ "pkg/polycyclic/gap/matrix/modules.gi",
+ "pkg/polycyclic/gap/matrix/triangle.gi",
+ "pkg/polycyclic/gap/matrix/hnf.gi",
+ "pkg/polycyclic/gap/basic/collect.gi",
+ "pkg/polycyclic/gap/basic/colftl.gi",
+ "pkg/polycyclic/gap/basic/colcom.gi",
+ "pkg/polycyclic/gap/basic/coldt.gi",
+ "pkg/polycyclic/gap/basic/colsave.gi",
+ "pkg/polycyclic/gap/basic/pcpelms.gi",
+ "pkg/polycyclic/gap/basic/pcppcps.gi",
+ "pkg/polycyclic/gap/basic/pcpgrps.gi",
+ "pkg/polycyclic/gap/basic/pcppara.gi",
+ "pkg/polycyclic/gap/basic/pcpexpo.gi",
+ "pkg/polycyclic/gap/basic/pcpsers.gi",
+ "pkg/polycyclic/gap/basic/grphoms.gi",
+ "pkg/polycyclic/gap/basic/pcpfact.gi",
+ "pkg/polycyclic/gap/basic/chngpcp.gi",
+ "pkg/polycyclic/gap/basic/convert.gi",
+ "pkg/polycyclic/gap/basic/orbstab.gi",
+ "pkg/polycyclic/gap/basic/construct.gi",
+ "pkg/polycyclic/gap/cohom/cohom.gi",
+ "pkg/polycyclic/gap/cohom/addgrp.gi",
+ "pkg/polycyclic/gap/cohom/general.gi",
+ "pkg/polycyclic/gap/cohom/solabel.gi",
+ "pkg/polycyclic/gap/cohom/solcohom.gi",
+ "pkg/polycyclic/gap/cohom/twocohom.gi",
+ "pkg/polycyclic/gap/cohom/intcohom.gi",
+ "pkg/polycyclic/gap/cohom/onecohom.gi",
+ "pkg/polycyclic/gap/cohom/grpext.gi",
+ "pkg/polycyclic/gap/cohom/grpcom.gi",
+ "pkg/polycyclic/gap/cohom/norcom.gi",
+ "pkg/polycyclic/gap/action/extend.gi",
+ "pkg/polycyclic/gap/action/basepcgs.gi",
+ "pkg/polycyclic/gap/action/freegens.gi",
+ "pkg/polycyclic/gap/action/dixon.gi",
+ "pkg/polycyclic/gap/action/kernels.gi",
+ "pkg/polycyclic/gap/action/orbstab.gi",
+ "pkg/polycyclic/gap/action/orbnorm.gi",
+ "pkg/polycyclic/gap/pcpgrp/general.gi",
+ "pkg/polycyclic/gap/pcpgrp/inters.gi",
+ "pkg/polycyclic/gap/pcpgrp/grpinva.gi",
+ "pkg/polycyclic/gap/pcpgrp/torsion.gi",
+ "pkg/polycyclic/gap/pcpgrp/maxsub.gi",
+ "pkg/polycyclic/gap/pcpgrp/findex.gi",
+ "pkg/polycyclic/gap/pcpgrp/nindex.gi",
+ "pkg/polycyclic/gap/pcpgrp/nilpot.gi",
+ "pkg/polycyclic/gap/pcpgrp/polyz.gi",
+ "pkg/polycyclic/gap/pcpgrp/pcpattr.gi",
+ "pkg/polycyclic/gap/pcpgrp/wreath.gi",
+ "pkg/polycyclic/gap/pcpgrp/fitting.gi",
+ "pkg/polycyclic/gap/pcpgrp/centcon.gi",
+ "pkg/polycyclic/gap/pcpgrp/normcon.gi",
+ "pkg/polycyclic/gap/pcpgrp/schur.gi",
+ "pkg/polycyclic/gap/pcpgrp/tensor.gi",
+ "pkg/polycyclic/gap/matrep/matrep.gi",
+ "pkg/polycyclic/gap/matrep/affine.gi",
+ "pkg/polycyclic/gap/matrep/unitri.gi",
+ "pkg/polycyclic/gap/exam/pcplib.gi",
+ "pkg/polycyclic/gap/exam/matlib.gi",
+ "pkg/polycyclic/gap/exam/nqlib.gi",
+ "pkg/polycyclic/gap/exam/generic.gi",
+ "pkg/polycyclic/gap/exam/bgnilp.gi",
+ "pkg/polycyclic/gap/exam/metacyc.gi",
+ "pkg/polycyclic/gap/exam/metagrp.gi",
+ "pkg/polycyclic/gap/cover/const/bas.gi",
+ "pkg/polycyclic/gap/cover/const/orb.gi",
+ "pkg/polycyclic/gap/cover/const/aut.gi",
+ "pkg/polycyclic/gap/cover/const/com.gi",
+ "pkg/polycyclic/gap/cover/const/cov.gi",
+ "pkg/crisp/init.g",
+ "pkg/crisp/lib/classes.gd",
+ "pkg/crisp/lib/grpclass.gd",
+ "pkg/crisp/lib/fitting.gd",
+ "pkg/crisp/lib/schunck.gd",
+ "pkg/crisp/lib/form.gd",
+ "pkg/crisp/lib/projector.gd",
+ "pkg/crisp/lib/injector.gd",
+ "pkg/crisp/lib/normpro.gd",
+ "pkg/crisp/lib/solveeq.gd",
+ "pkg/crisp/lib/compl.gd",
+ "pkg/crisp/lib/radical.gd",
+ "pkg/crisp/lib/residual.gd",
+ "pkg/crisp/lib/util.gd",
+ "pkg/crisp/lib/samples.gd",
+ "pkg/crisp/lib/socle.gd",
+ "pkg/crisp/read.g",
+ "pkg/crisp/lib/classes.gi",
+ "pkg/crisp/lib/grpclass.gi",
+ "pkg/crisp/lib/fitting.gi",
+ "pkg/crisp/lib/schunck.gi",
+ "pkg/crisp/lib/form.gi",
+ "pkg/crisp/lib/projector.gi",
+ "pkg/crisp/lib/injector.gi",
+ "pkg/crisp/lib/normpro.gi",
+ "pkg/crisp/lib/solveeq.gi",
+ "pkg/crisp/lib/compl.gi",
+ "pkg/crisp/lib/radical.gi",
+ "pkg/crisp/lib/residual.gi",
+ "pkg/crisp/lib/util.gi",
+ "pkg/crisp/lib/samples.gi",
+ "pkg/crisp/lib/socle.gi",
+ "pkg/factint/init.g",
+ "pkg/factint/lib/factint.gd",
+ "pkg/factint/read.g",
+ "pkg/factint/tables/3k2k.g",
+ "pkg/factint/tables/akbk.g",
+ "pkg/factint/tables/factorial.g",
+ "pkg/factint/tables/fibo.g",
+ "pkg/factint/tables/primorial.g",
+ "pkg/factint/lib/general.gi",
+ "pkg/factint/lib/pminus1.gi",
+ "pkg/factint/lib/pplus1.gi",
+ "pkg/factint/lib/ecm.gi",
+ "pkg/factint/lib/cfrac.gi",
+ "pkg/factint/lib/mpqs.gi",
+ "pkg/forms/init.g",
+ "pkg/forms/lib/forms.gd",
+ "pkg/forms/lib/recognition.gd",
+ "pkg/forms/lib/conformal.gd",
+ "pkg/forms/read.g",
+ "pkg/forms/lib/forms.gi",
+ "pkg/forms/lib/recognition.gi",
+ "pkg/forms/lib/classic.gi",
+ "pkg/forms/lib/recognition_new.gi",
+ "pkg/forms/lib/conformal.gi",
+ "pkg/orb/init.g",
+ "pkg/orb/gap/homwdata.gd",
+ "pkg/orb/gap/avltree.gd",
+ "pkg/orb/gap/hash.gd",
+ "pkg/orb/gap/cache.gd",
+ "pkg/orb/gap/orbits.gd",
+ "pkg/orb/gap/search.gd",
+ "pkg/orb/gap/bysuborbit.gd",
+ "pkg/orb/read.g",
+ "pkg/orb/gap/homwdata.gi",
+ "pkg/orb/gap/avltree.gi",
+ "pkg/orb/gap/hash.gi",
+ "pkg/orb/gap/cache.gi",
+ "pkg/orb/gap/orbits.gi",
+ "pkg/orb/gap/search.gi",
+ "pkg/orb/gap/bysuborbit.gi",
+ "pkg/utils/init.g",
+ "pkg/utils/lib/start.gd",
+ "pkg/utils/lib/files.gd",
+ "pkg/utils/lib/groups.gd",
+ "pkg/utils/lib/iterator.gd",
+ "pkg/utils/lib/latex.gd",
+ "pkg/utils/lib/lcset.gd",
+ "pkg/utils/lib/lists.gd",
+ "pkg/utils/lib/magma.gd",
+ "pkg/utils/lib/maps.gd",
+ "pkg/utils/lib/matrix.gd",
+ "pkg/utils/lib/number.gd",
+ "pkg/utils/lib/print.gd",
+ "pkg/utils/lib/record.gd",
+ "pkg/utils/lib/string.gd",
+ "pkg/utils/lib/gslp.gd",
+ "pkg/utils/lib/download.gd",
+ "pkg/utils/read.g",
+ "pkg/utils/lib/files.gi",
+ "pkg/utils/lib/groups.gi",
+ "pkg/utils/lib/iterator.gi",
+ "pkg/utils/lib/latex.gi",
+ "pkg/utils/lib/lcset.gi",
+ "pkg/utils/lib/lists.gi",
+ "pkg/utils/lib/magma.gi",
+ "pkg/utils/lib/maps.gi",
+ "pkg/utils/lib/matrix.gi",
+ "pkg/utils/lib/number.gi",
+ "pkg/utils/lib/print.gi",
+ "pkg/utils/lib/record.gi",
+ "pkg/utils/lib/string.gi",
+ "pkg/utils/lib/gslp.gi",
+ "pkg/utils/lib/download.gi",
+ "pkg/genss/init.g",
+ "pkg/genss/gap/genss.gd",
+ "pkg/genss/gap/setwise.gd",
+ "pkg/genss/read.g",
+ "pkg/genss/gap/genss.gi",
+ "pkg/genss/gap/setwise.gi",
+ "pkg/atlasrep/init.g",
+ "pkg/atlasrep/gap/userpref.g",
+ "pkg/atlasrep/gap/bbox.gd",
+ "pkg/atlasrep/gap/access.gd",
+ "pkg/atlasrep/gap/scanmtx.gd",
+ "pkg/atlasrep/gap/scanmtx.gi",
+ "pkg/atlasrep/gap/types.gd",
+ "pkg/atlasrep/gap/interfac.gd",
+ "pkg/atlasrep/gap/mindeg.gd",
+ "pkg/atlasrep/gap/utils.gd",
+ "pkg/ctbllib/init.g",
+ "pkg/ctbllib/gap4/ctadmin.gd",
+ "pkg/ctbllib/gap4/construc.gd",
+ "pkg/ctbllib/gap4/ctblothe.gd",
+ "pkg/ctbllib/dlnames/dlnames.gd",
+ "pkg/ctbllib/gap4/obsolete.gd",
+ "pkg/ctbllib/gap4/brdbattrX.gd",
+ "pkg/ctbllib/gap4/brdbattrX.gi",
+ "pkg/recog/init.g",
+ "pkg/recog/gap/base/hack.g",
+ "pkg/recog/gap/base/methods.gd",
+ "pkg/recog/gap/base/methsel.gd",
+ "pkg/recog/gap/base/recognition.gd",
+ "pkg/recog/gap/base/kernel.gd",
+ "pkg/recog/gap/base/projective.gd",
+ "pkg/recog/gap/matrix/ppd.gd",
+ "pkg/recog/gap/matrix/classical.gd",
+ "pkg/recog/gap/projective/almostsimple.gd",
+ "pkg/recog/gap/projective/findnormal.gd",
+ "pkg/recog/gap/projective/AnSnOnFDPM.gd",
+ "pkg/spinsym/init.g",
+ "pkg/spinsym/gap/mtx.gd",
+ "pkg/spinsym/gap/fus.gd",
+ "pkg/spinsym/gap/young.gd",
+ "pkg/standardff/init.g",
+ "pkg/standardff/lib/Util.gd",
+ "pkg/standardff/lib/IsIrred.gd",
+ "pkg/standardff/lib/StandardFF.gd",
+ "pkg/standardff/lib/StandardCyc.gd",
+ "pkg/tomlib/init.g",
+ "pkg/tomlib/gap/tmadmin.tmd",
+ "pkg/tomlib/gap/stdgen.gd",
+ "pkg/atlasrep/read.g",
+ "pkg/atlasrep/gap/bbox.gi",
+ "pkg/atlasrep/gap/access.gi",
+ "pkg/atlasrep/gap/types.gi",
+ "pkg/atlasrep/gap/interfac.gi",
+ "pkg/atlasrep/gap/mindeg.gi",
+ "pkg/atlasrep/gap/utlmrkup.g",
+ "pkg/atlasrep/gap/utils.gi",
+ "pkg/atlasrep/gap/test.g",
+ "pkg/atlasrep/gap/json.g",
+ "pkg/atlasrep/gap/obsolete.gd",
+ "pkg/atlasrep/gap/obsolete.gi",
+ "pkg/ctbllib/read.g",
+ "pkg/ctbllib/gap4/ctadmin.gi",
+ "pkg/ctbllib/gap4/ctprimar.g",
+ "pkg/ctbllib/data/firstnames.json",
+ "pkg/ctbllib/data/othernames.json",
+ "pkg/ctbllib/data/fusionsources.json",
+ "pkg/ctbllib/data/extinfo.json",
+ "pkg/ctbllib/data/ctgeneri.tbl",
+ "pkg/ctbllib/data/version",
+ "pkg/ctbllib/data/namerepl.json",
+ "pkg/ctbllib/gap4/construc.gi",
+ "pkg/ctbllib/gap4/ctblothe.gi",
+ "pkg/ctbllib/gap4/test.g",
+ "pkg/ctbllib/dlnames/dlnames.gi",
+ "pkg/ctbllib/gap4/ctbltoct.g",
+ "pkg/ctbllib/gap4/ctdbattr.g",
+ "pkg/ctbllib/gap4/od.g",
+ "pkg/ctbllib/data/odresults.json",
+ "pkg/ctbllib/gap4/atlasstr.g",
+ "pkg/ctbllib/gap4/atlasirr.g",
+ "pkg/recog/read.g",
+ "pkg/recog/gap/base/methods.gi",
+ "pkg/recog/gap/base/methsel.gi",
+ "pkg/recog/gap/base/recognition.gi",
+ "pkg/recog/gap/base/kernel.gi",
+ "pkg/recog/gap/base/projective.gi",
+ "pkg/recog/gap/utils.gi",
+ "pkg/recog/gap/generic/TrivialGroup.gi",
+ "pkg/recog/gap/generic/FewGensAbelian.gi",
+ "pkg/recog/gap/generic/KnownNilpotent.gi",
+ "pkg/recog/gap/perm/giant.gi",
+ "pkg/recog/gap/perm/largebase.gi",
+ "pkg/recog/gap/SnAnBB.gi",
+ "pkg/recog/gap/generic/SnAnUnknownDegree.gi",
+ "pkg/recog/gap/matrix/matimpr.gi",
+ "pkg/recog/gap/matrix/blocks.gi",
+ "pkg/recog/gap/matrix/ppd.gi",
+ "pkg/recog/gap/matrix/classical.gi",
+ "pkg/recog/gap/matrix/slconstr.gi",
+ "pkg/recog/gap/projective/findnormal.gi",
+ "pkg/recog/gap/projective/c6.gi",
+ "pkg/recog/gap/projective/tensor.gi",
+ "pkg/recog/gap/projective/c3c5.gi",
+ "pkg/recog/gap/projective/d247.gi",
+ "pkg/recog/gap/projective/almostsimple/threeelorders.gi",
+ "pkg/recog/gap/projective/almostsimple.gi",
+ "pkg/recog/gap/projective/almostsimple/lietype.gi",
+ "pkg/recog/gap/projective/almostsimple/hints.gi",
+ "pkg/recog/gap/projective/classicalnatural.gi",
+ "pkg/recog/gap/projective/sl2_natural.gi",
+ "pkg/recog/gap/projective/sl.gi",
+ "pkg/recog/gap/projective/AnSnOnFDPM.gi",
+ "pkg/recog/gap/perm.gi",
+ "pkg/recog/gap/matrix.gi",
+ "pkg/recog/gap/projective.gi",
+ "pkg/spinsym/read.g",
+ "pkg/spinsym/gap/mtx.gi",
+ "pkg/spinsym/gap/fus.gi",
+ "pkg/spinsym/gap/young.gi",
+ "pkg/standardff/read.g",
+ "pkg/standardff/lib/Util.gi",
+ "pkg/standardff/lib/IsIrred.gi",
+ "pkg/standardff/lib/StandardFF.gi",
+ "pkg/standardff/lib/StandardCyc.gi",
+ "pkg/standardff/lib/CANFACT.g",
+ "pkg/standardff/lib/TestFuncs.g",
+ "pkg/tomlib/read.g",
+ "pkg/tomlib/gap/tmstdrd.tom",
+ "pkg/tomlib/gap/tmadmin.tmi",
+ "pkg/tomlib/gap/stdgen.gi",
+ "pkg/atlasrep/gap/ctbllib_only.g",
+ "pkg/ctbllib/gap4/atlasrep_only.g",
+ "pkg/ctbllib/gap4/tomlib_only.g",
+ "pkg/ctbllib/data/tom_tbl.json",
+ "pkg/ctbllib/gap4/spinsym_only.g",
+ "pkg/ctbllib/data/grp_atlas.json",
+ "pkg/ctbllib/data/attr_nccl.json",
+ "pkg/ctbllib/data/grp_small.json",
+ "pkg/ctbllib/data/grp_tom.json",
+ "pkg/ctbllib/data/grp_trans.json",
+ "pkg/ctbllib/data/grp_prim.json",
+ "pkg/ctbllib/data/grp_perf.json",
+ "pkg/fga/init.g",
+ "pkg/fga/lib/util.gd",
+ "pkg/fga/lib/Iterated.gd",
+ "pkg/fga/lib/Autom.gd",
+ "pkg/fga/lib/FreeGrps.gd",
+ "pkg/fga/lib/ReprAct.gd",
+ "pkg/fga/lib/Normal.gd",
+ "pkg/fga/lib/ExtAutom.gd",
+ "pkg/fga/lib/Hom.gd",
+ "pkg/fga/lib/AutGrp.gd",
+ "pkg/fga/lib/Intsect.gd",
+ "pkg/fga/lib/Whitehd.gd",
+ "pkg/fga/read.g",
+ "pkg/fga/lib/util.gi",
+ "pkg/fga/lib/Iterated.gi",
+ "pkg/fga/lib/Autom.gi",
+ "pkg/fga/lib/FreeGrps.gi",
+ "pkg/fga/lib/ReprAct.gi",
+ "pkg/fga/lib/Normal.gi",
+ "pkg/fga/lib/Central.gi",
+ "pkg/fga/lib/Index.gi",
+ "pkg/fga/lib/ExtAutom.gi",
+ "pkg/fga/lib/Hom.gi",
+ "pkg/fga/lib/AutGrp.gi",
+ "pkg/fga/lib/Intsect.gi",
+ "pkg/fga/lib/ReprActT.gi",
+ "pkg/fga/lib/Whitehd.gi",
+ "pkg/irredsol/init.g",
+ "pkg/irredsol/lib/util.g",
+ "pkg/irredsol/lib/util.gd",
+ "pkg/irredsol/lib/matmeths.gd",
+ "pkg/irredsol/lib/loading.gd",
+ "pkg/irredsol/lib/loadfp.gd",
+ "pkg/irredsol/lib/access.gd",
+ "pkg/irredsol/lib/iterators.gd",
+ "pkg/irredsol/lib/recognize.gd",
+ "pkg/irredsol/lib/primitive.gd",
+ "pkg/irredsol/lib/recognizeprim.gd",
+ "pkg/irredsol/lib/obsolete.gd",
+ "pkg/irredsol/read.g",
+ "pkg/irredsol/lib/matmeths.gi",
+ "pkg/irredsol/lib/loading.gi",
+ "pkg/irredsol/lib/loadfp.gi",
+ "pkg/irredsol/lib/access.gi",
+ "pkg/irredsol/lib/iterators.gi",
+ "pkg/irredsol/lib/recognize.gi",
+ "pkg/irredsol/lib/primitive.gi",
+ "pkg/irredsol/lib/recognizeprim.gi",
+ "pkg/irredsol/lib/util.gi",
+ "pkg/irredsol/lib/obsolete.gi",
+ "pkg/sophus/init.g",
+ "pkg/sophus/gap/sophus.gd",
+ "pkg/sophus/read.g",
+ "pkg/sophus/gap/general.gi",
+ "pkg/sophus/gap/lienp.gi",
+ "pkg/sophus/gap/liesct.gi",
+ "pkg/sophus/gap/liecover.gi",
+ "pkg/sophus/gap/nicestab.gi",
+ "pkg/sophus/gap/lieautoops.gi",
+ "pkg/sophus/gap/initauts.gi",
+ "pkg/sophus/gap/lieautgrp.gi",
+ "pkg/sophus/gap/allowable.gi",
+ "pkg/sophus/gap/descendant.gi",
+ "pkg/sophus/gap/lieisom.gi",
+ "pkg/sophus/gap/io.gi",
+ "pkg/laguna/init.g",
+ "pkg/laguna/lib/laguna.gd",
+ "pkg/laguna/lib/laguna.g",
+ "pkg/laguna/read.g",
+ "pkg/laguna/lib/laguna.gi",
+ "pkg/autodoc/init.g",
+ "pkg/autodoc/gap/DocumentationTree.gd",
+ "pkg/autodoc/gap/Parser.gd",
+ "pkg/autodoc/gap/AutoDocMainFunction.gd",
+ "pkg/autodoc/gap/ToolFunctions.gd",
+ "pkg/autodoc/gap/Magic.gd",
+ "pkg/autodoc/gap/Markdown.gd",
+ "pkg/autodoc/read.g",
+ "pkg/autodoc/gap/ToolFunctions.gi",
+ "pkg/autodoc/gap/DocumentationTree.gi",
+ "pkg/autodoc/gap/Parser.gi",
+ "pkg/autodoc/gap/AutoDocMainFunction.gi",
+ "pkg/autodoc/gap/Magic.gi",
+ "pkg/autodoc/gap/Markdown.gi",
+ "pkg/packagemanager/init.g",
+ "pkg/packagemanager/gap/PackageManager.gd",
+ "pkg/packagemanager/gap/archive.gd",
+ "pkg/packagemanager/gap/compile.gd",
+ "pkg/packagemanager/gap/directories.gd",
+ "pkg/packagemanager/gap/distro.gd",
+ "pkg/packagemanager/gap/doc.gd",
+ "pkg/packagemanager/gap/download.gd",
+ "pkg/packagemanager/gap/git.gd",
+ "pkg/packagemanager/gap/hg.gd",
+ "pkg/packagemanager/gap/interactive.gd",
+ "pkg/packagemanager/gap/packageinfo.gd",
+ "pkg/packagemanager/read.g",
+ "pkg/packagemanager/gap/PackageManager.gi",
+ "pkg/packagemanager/gap/archive.gi",
+ "pkg/packagemanager/gap/compile.gi",
+ "pkg/packagemanager/gap/directories.gi",
+ "pkg/packagemanager/gap/distro.gi",
+ "pkg/packagemanager/gap/doc.gi",
+ "pkg/packagemanager/gap/download.gi",
+ "pkg/packagemanager/gap/git.gi",
+ "pkg/packagemanager/gap/hg.gi",
+ "pkg/packagemanager/gap/interactive.gi",
+ "pkg/packagemanager/gap/packageinfo.gi",
+ "pkg/radiroot/init.g",
+ "pkg/radiroot/lib/Radicals.gd",
+ "pkg/radiroot/lib/SplittField.gd",
+ "pkg/radiroot/lib/Manipulations.gd",
+ "pkg/radiroot/lib/Strings.gd",
+ "pkg/radiroot/lib/Maple.gd",
+ "pkg/radiroot/read.g",
+ "pkg/radiroot/lib/Radicals.gi",
+ "pkg/radiroot/lib/SplittField.gi",
+ "pkg/radiroot/lib/Manipulations.gi",
+ "pkg/radiroot/lib/Strings.gi",
+ "pkg/radiroot/lib/Maple.gi",
+ "pkg/aclib/init.g",
+ "pkg/aclib/gap/groups.gd",
+ "pkg/cryst/init.g",
+ "pkg/cryst/gap/common.gd",
+ "pkg/cryst/gap/cryst.gd",
+ "pkg/cryst/gap/hom.gd",
+ "pkg/cryst/gap/wyckoff.gd",
+ "pkg/cryst/gap/zass.gd",
+ "pkg/cryst/gap/max.gd",
+ "pkg/cryst/gap/color.gd",
+ "pkg/cryst/gap/equiv.gd",
+ "pkg/cryst/grp/spacegrp.gd",
+ "pkg/crystcat/init.g",
+ "pkg/crystcat/lib/crystcat.gd",
+ "pkg/polenta/init.g",
+ "pkg/polenta/lib/finite.gd",
+ "pkg/polenta/lib/info.gd",
+ "pkg/polenta/lib/basic.gd",
+ "pkg/polenta/exam/test.gd",
+ "pkg/polenta/lib/cpcs.gd",
+ "pkg/polenta/lib/present.gd",
+ "pkg/polenta/lib/solvable.gd",
+ "pkg/polenta/lib/series.gd",
+ "pkg/polenta/lib/subgroups.gd",
+ "pkg/polenta/lib/ispolyz.gd",
+ "pkg/aclib/read.g",
+ "pkg/aclib/gap/matgrp3.gi",
+ "pkg/aclib/gap/matgrp4.gi",
+ "pkg/aclib/gap/matgrp.gi",
+ "pkg/aclib/gap/pcpgrp3.gi",
+ "pkg/aclib/gap/pcpgrp4.gi",
+ "pkg/aclib/gap/pcpgrp.gi",
+ "pkg/aclib/gap/betti.gi",
+ "pkg/aclib/gap/union.gi",
+ "pkg/aclib/gap/extend.gi",
+ "pkg/aclib/gap/crystgrp.gi",
+ "pkg/cryst/read.g",
+ "pkg/cryst/gap/common.gi",
+ "pkg/cryst/gap/hom.gi",
+ "pkg/cryst/gap/cryst.gi",
+ "pkg/cryst/gap/cryst2.gi",
+ "pkg/cryst/gap/fpgrp.gi",
+ "pkg/cryst/gap/zass.gi",
+ "pkg/cryst/gap/max.gi",
+ "pkg/cryst/gap/wyckoff.gi",
+ "pkg/cryst/gap/color.gi",
+ "pkg/cryst/gap/noxgap.gi",
+ "pkg/cryst/gap/pcpgrp.gi",
+ "pkg/cryst/gap/orbstab.gi",
+ "pkg/cryst/gap/equiv.gi",
+ "pkg/cryst/grp/spacegrp.grp",
+ "pkg/cryst/grp/spacegrp.gi",
+ "pkg/crystcat/read.g",
+ "pkg/crystcat/grp/crystcat.grp",
+ "pkg/crystcat/lib/crystcat.gi",
+ "pkg/crystcat/lib/normalizer.gi",
+ "pkg/polenta/read.g",
+ "pkg/polenta/lib/finite.gi",
+ "pkg/polenta/lib/basic.gi",
+ "pkg/polenta/lib/unipo.gi",
+ "pkg/polenta/lib/series.gi",
+ "pkg/polenta/lib/semi.gi",
+ "pkg/polenta/lib/ispoly.gi",
+ "pkg/polenta/lib/cpcs.gi",
+ "pkg/polenta/lib/present.gi",
+ "pkg/polenta/lib/isom.gi",
+ "pkg/polenta/lib/solvable.gi",
+ "pkg/polenta/exam/exam.gi",
+ "pkg/polenta/exam/test.gi",
+ "pkg/polenta/lib/subgroups.gi",
+ "pkg/polenta/lib/ispolyz.gi",
+ "pkg/resclasses/init.g",
+ "pkg/resclasses/lib/general.gd",
+ "pkg/resclasses/lib/z_pi.gd",
+ "pkg/resclasses/lib/resclass.gd",
+ "pkg/resclasses/lib/fixedrep.gd",
+ "pkg/resclasses/read.g",
+ "pkg/resclasses/lib/general.gi",
+ "pkg/resclasses/lib/resclaux.g",
+ "pkg/resclasses/lib/z_pi.gi",
+ "pkg/resclasses/lib/resclass.gi",
+ "pkg/resclasses/lib/fixedrep.gi",
+ "lib/obsolete.gi",
+ "pkg/4ti2interface/doc/manual.six",
+ "pkg/ace/doc/manual.six",
+ "pkg/aclib/doc/manual.six",
+ "pkg/agt/doc/manual.six",
+ "pkg/alco/doc/manual.six",
+ "pkg/alnuth/doc/manual.six",
+ "pkg/anupq/doc/manual.six",
+ "pkg/atlasrep/doc/manual.six",
+ "pkg/autodoc/doc/manual.six",
+ "pkg/automata/doc/manual.six",
+ "pkg/automgrp/doc/manual.six",
+ "pkg/autpgrp/doc/manual.six",
+ "pkg/browse/doc/manual.six",
+ "pkg/cap/doc/manual.six",
+ "pkg/caratinterface/doc/manual.six",
+ "pkg/cddinterface/doc/manual.six",
+ "pkg/circle/doc/manual.six",
+ "pkg/classicalmaximals/doc/manual.six",
+ "pkg/classicpres/doc/manual.six",
+ "pkg/cohomolo/doc/manual.six",
+ "pkg/congruence/doc/manual.six",
+ "pkg/corefreesub/doc/manual.six",
+ "pkg/corelg/doc/manual.six",
+ "pkg/crime/doc/manual.six",
+ "pkg/crisp/doc/manual.six",
+ "pkg/crypting/doc/manual.six",
+ "pkg/cryst/doc/manual.six",
+ "pkg/crystcat/doc/manual.six",
+ "pkg/ctbllib/doc/manual.six",
+ "pkg/ctbllib/doc2/manual.six",
+ "pkg/cubefree/doc/manual.six",
+ "pkg/curlinterface/doc/manual.six",
+ "pkg/cvec/doc/manual.six",
+ "pkg/datastructures/doc/manual.six",
+ "pkg/deepthought/doc/manual.six",
+ "pkg/design/doc/manual.six",
+ "pkg/difsets/doc/manual.six",
+ "pkg/digraphs/doc/manual.six",
+ "pkg/edim/doc/manual.six",
+ "pkg/example/doc/manual.six",
+ "pkg/examplesforhomalg/doc/manual.six",
+ "pkg/factint/doc/manual.six",
+ "pkg/ferret/doc/manual.six",
+ "pkg/fga/doc/manual.six",
+ "pkg/fining/doc/manual.six",
+ "pkg/float/doc/manual.six",
+ "pkg/format/doc/manual.six",
+ "pkg/forms/doc/manual.six",
+ "pkg/fplsa/doc/manual.six",
+ "pkg/fr/doc/manual.six",
+ "pkg/francy/doc/manual.six",
+ "pkg/fwtree/doc/manual.six",
+ "pkg/gapdoc/doc/manual.six",
+ "pkg/gapdoc/example/manual.six",
+ "pkg/gauss/doc/manual.six",
+ "pkg/gaussforhomalg/doc/manual.six",
+ "pkg/gbnp/doc/manual.six",
+ "pkg/generalizedmorphismsforcap/doc/manual.six",
+ "pkg/genss/doc/manual.six",
+ "pkg/gradedmodules/doc/manual.six",
+ "pkg/gradedringforhomalg/doc/manual.six",
+ "pkg/grape/doc/manual.six",
+ "pkg/groupoids/doc/manual.six",
+ "pkg/grpconst/doc/manual.six",
+ "pkg/guarana/doc/manual.six",
+ "pkg/guava/doc/manual.six",
+ "pkg/hap/doc/manual.six",
+ "pkg/hapcryst/doc/manual.six",
+ "pkg/hecke/doc/manual.six",
+ "pkg/help/doc/manual.six",
+ "pkg/homalg/doc/manual.six",
+ "pkg/homalgtocas/doc/manual.six",
+ "pkg/ibnp/doc/manual.six",
+ "pkg/idrel/doc/manual.six",
+ "pkg/images/doc/manual.six",
+ "pkg/inducereduce/doc/manual.six",
+ "pkg/intpic/doc/manual.six",
+ "pkg/io/doc/manual.six",
+ "pkg/io_forhomalg/doc/manual.six",
+ "pkg/irredsol/doc/manual.six",
+ "pkg/itc/doc/manual.six",
+ "pkg/json/doc/manual.six",
+ "pkg/jupyterkernel/doc/manual.six",
+ "pkg/jupyterviz/doc/manual.six",
+ "pkg/kan/doc/manual.six",
+ "pkg/kbmag/doc/manual.six",
+ "pkg/laguna/doc/manual.six",
+ "pkg/liealgdb/doc/manual.six",
+ "pkg/liepring/doc/manual.six",
+ "pkg/liering/doc/manual.six",
+ "pkg/linearalgebraforcap/doc/manual.six",
+ "pkg/lins/doc/manual.six",
+ "pkg/localizeringforhomalg/doc/manual.six",
+ "pkg/localnr/doc/manual.six",
+ "pkg/loops/doc/manual.six",
+ "pkg/lpres/doc/manual.six",
+ "pkg/majoranaalgebras/doc/manual.six",
+ "pkg/mapclass/doc/manual.six",
+ "pkg/matgrp/doc/manual.six",
+ "pkg/matricesforhomalg/doc/manual.six",
+ "pkg/modisom/doc/manual.six",
+ "pkg/modulargroup/doc/manual.six",
+ "pkg/modulepresentationsforcap/doc/manual.six",
+ "pkg/modules/doc/manual.six",
+ "pkg/monoidalcategories/doc/manual.six",
+ "pkg/nconvex/doc/manual.six",
+ "pkg/nilmat/doc/manual.six",
+ "pkg/nock/doc/manual.six",
+ "pkg/nofoma/doc/manual.six",
+ "pkg/normalizinterface/doc/manual.six",
+ "pkg/nq/doc/manual.six",
+ "pkg/numericalsgps/doc/manual.six",
+ "pkg/openmath/doc/manual.six",
+ "pkg/orb/doc/manual.six",
+ "pkg/origami/doc/manual.six",
+ "pkg/packagemaker/doc/manual.six",
+ "pkg/packagemanager/doc/manual.six",
+ "pkg/patternclass/doc/manual.six",
+ "pkg/permut/doc/manual.six",
+ "pkg/polenta/doc/manual.six",
+ "pkg/polycyclic/doc/manual.six",
+ "pkg/polymaking/doc/manual.six",
+ "pkg/primgrp/doc/manual.six",
+ "pkg/profiling/doc/manual.six",
+ "pkg/qdistrnd/doc/manual.six",
+ "pkg/qpa/doc/manual.six",
+ "pkg/quagroup/doc/manual.six",
+ "pkg/radiroot/doc/manual.six",
+ "pkg/rcwa/doc/manual.six",
+ "pkg/rds/doc/manual.six",
+ "pkg/recog/doc/manual.six",
+ "pkg/repndecomp/doc/manual.six",
+ "pkg/repsn/doc/manual.six",
+ "pkg/resclasses/doc/manual.six",
+ "pkg/ringsforhomalg/doc/manual.six",
+ "pkg/sco/doc/manual.six",
+ "pkg/scscp/doc/manual.six",
+ "pkg/semigroups/doc/manual.six",
+ "pkg/sglppow/doc/manual.six",
+ "pkg/sgpviz/doc/manual.six",
+ "pkg/simpcomp/doc/manual.six",
+ "pkg/singular/doc/manual.six",
+ "pkg/sl2reps/doc/manual.six",
+ "pkg/sla/doc/manual.six",
+ "pkg/smallantimagmas/doc/manual.six",
+ "pkg/smallclassnr/doc/manual.six",
+ "pkg/smallgrp/doc/manual.six",
+ "pkg/smallsemi/doc/manual.six",
+ "pkg/sonata/doc/ref/manual.six",
+ "pkg/sonata/doc/tut/manual.six",
+ "pkg/sophus/doc/manual.six",
+ "pkg/sotgrps/doc/manual.six",
+ "pkg/spinsym/doc/manual.six",
+ "pkg/standardff/doc/manual.six",
+ "pkg/symbcompcc/doc/manual.six",
+ "pkg/thelma/doc/manual.six",
+ "pkg/tomlib/doc/manual.six",
+ "pkg/toolsforhomalg/doc/manual.six",
+ "pkg/toric/doc/manual.six",
+ "pkg/transgrp/doc/manual.six",
+ "pkg/twistedconjugacy/doc/manual.six",
+ "pkg/typeset/doc/manual.six",
+ "pkg/ugaly/doc/manual.six",
+ "pkg/unipot/doc/manual.six",
+ "pkg/unitlib/doc/manual.six",
+ "pkg/utils/doc/manual.six",
+ "pkg/uuid/doc/manual.six",
+ "pkg/walrus/doc/manual.six",
+ "pkg/wedderga/doc/manual.six",
+ "pkg/wpe/doc/manual.six",
+ "pkg/xgap/doc/manual.six",
+ "pkg/xmod/doc/manual.six",
+ "pkg/xmodalg/doc/manual.six",
+ "pkg/yangbaxter/doc/manual.six",
+ "pkg/zeromqinterface/doc/manual.six"
+]
diff --git a/etc/emscripten/web-template/gap-fs.js b/etc/emscripten/web-template/gap-fs.js
index f3a1467d42..ca8ea4f23d 100644
--- a/etc/emscripten/web-template/gap-fs.js
+++ b/etc/emscripten/web-template/gap-fs.js
@@ -1,3 +1,29 @@
+// Instrument fetch and XMLHttpRequest so the page can collect the list of
+// URLs the worker actually requests, for rebuilding startup_manifest.json
+// without scraping the browser network panel. Each unique URL is posted
+// to the main thread as { type: "gap-fetched", url: ... }.
+(function instrumentFetches() {
+ const seen = new Set();
+ const report = (raw) => {
+ if (typeof raw !== "string") return;
+ if (seen.has(raw)) return;
+ seen.add(raw);
+ self.postMessage({ type: "gap-fetched", url: raw });
+ };
+
+ const origFetch = self.fetch;
+ self.fetch = function(input, init) {
+ report(typeof input === "string" ? input : input && input.url);
+ return origFetch.apply(this, arguments);
+ };
+
+ const origOpen = XMLHttpRequest.prototype.open;
+ XMLHttpRequest.prototype.open = function(method, url) {
+ report(url);
+ return origOpen.apply(this, arguments);
+ };
+})();
+
self.Module = self.Module || {};
self.Module.preRun = self.Module.preRun || [];
@@ -43,8 +69,12 @@ self.Module.preRun.push(function() {
if (p.startsWith('/')) p = p.substring(1);
startupSet.add(p);
});
+ } else {
+ console.info("startup_manifest.json not present; falling back to fully lazy loading");
}
- } catch (e) {}
+ } catch (e) {
+ console.warn("Failed to load startup_manifest.json:", e);
+ }
var fetchPromises = fileList.map(async function(appPath) {
var fetchRelativePath = appPath.split('/').map(encodeURIComponent).join('/');
@@ -58,16 +88,15 @@ self.Module.preRun.push(function() {
FS.stat(idbfsPath);
FS.writeFile(finalAppPath, FS.readFile(idbfsPath));
} catch (e) {
- try {
- const response = await fetch(fetchPath);
- if (response.ok) {
- const buffer = await response.arrayBuffer();
- const data = new Uint8Array(buffer);
- FS.writeFile(finalAppPath, data);
- FS.writeFile(idbfsPath, data);
- needsSave = true;
- }
- } catch (fetchErr) {}
+ const response = await fetch(fetchPath);
+ if (!response.ok) {
+ throw new Error("Failed to fetch startup file " + fetchPath + ": " + response.status);
+ }
+ const buffer = await response.arrayBuffer();
+ const data = new Uint8Array(buffer);
+ FS.writeFile(finalAppPath, data);
+ FS.writeFile(idbfsPath, data);
+ needsSave = true;
}
} else {
var parts = appPath.split('/');
diff --git a/etc/emscripten/web-template/index.html b/etc/emscripten/web-template/index.html
index b51df45fb8..d5f1bec759 100755
--- a/etc/emscripten/web-template/index.html
+++ b/etc/emscripten/web-template/index.html
@@ -1,22 +1,185 @@
-
+
+
- gap-wasm
+
+
+ GAP in the browser
+
-
+
+
GAP in the browser
+
+ A WebAssembly build of GAP
+ running entirely in your browser — useful for trying things out
+ without installing. Not all packages work, working memory is
+ capped, and performance is reduced compared to a native build.
+ For real work, install GAP from
+ www.gap-system.org.
+
+
+
+
+ What is this? · Licensing
+
+ GAP is a system for
+ computational discrete algebra, with particular emphasis on
+ computational group theory. This page is a self-contained
+ WebAssembly build, served as a static site and run inside a
+ Web Worker; you interact with it through an
+ xterm-pty
+ terminal in the page below.
+
+
+ To get started, try 1+1;,
+ Factorial(20);, or SymmetricGroup(5);.
+ The full GAP
+ manuals apply, with two caveats: some packages won't load
+ (anything that needs a native compiler or system library), and
+ anything that wants the local filesystem won't work.
+
+
+ Files downloaded on first visit are cached in your browser's
+ IndexedDB, so subsequent visits start much faster. Clear the
+ site data to reset the cache.
+
+ Loading GAP… The first visit downloads several tens of megabytes;
+ subsequent visits are cached in your browser and load much faster.
+
+
+
+ This page needs SharedArrayBuffer, which is only
+ available when the page is served with the headers
+ Cross-Origin-Opener-Policy: same-origin and
+ Cross-Origin-Embedder-Policy: require-corp. The
+ bundled service worker handles this on hosts where you can't set
+ headers (e.g. GitHub Pages); for local hosting use
+ etc/emscripten/serve.py.
+
+
+
+
+
+
+
+
diff --git a/src/gasman.c b/src/gasman.c
index 6712ebec79..7a616d6eb6 100644
--- a/src/gasman.c
+++ b/src/gasman.c
@@ -129,7 +129,7 @@
#include
#include
-#ifdef EMSCRIPTEN
+#ifdef __EMSCRIPTEN__
#include
#endif
@@ -1957,7 +1957,7 @@ static NOINLINE void GenStackFuncBags(void)
DisableMarkBagValidation = 1;
#endif
-#ifdef EMSCRIPTEN
+#ifdef __EMSCRIPTEN__
emscripten_scan_stack(ScanRange);
emscripten_scan_registers(ScanRange);
// The standard scanning may not be required with