├── skt.wasm ├── dist ├── skt.wasm ├── tailwind.config.js ├── package.json ├── input.css ├── output.css ├── index.html ├── skt.html └── skt.js ├── skt-js-img.png ├── netlify.toml ├── tailwind.config.js ├── .github ├── dependabot.yml └── workflows │ └── build-tailwind.yml ├── package.json ├── .gitignore ├── README.md ├── .devcontainer ├── Dockerfile ├── devcontainer.json └── reinstall-cmake.sh ├── LICENSE ├── src └── input.css └── skt.html /skt.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drdarshan/skt-js/main/skt.wasm -------------------------------------------------------------------------------- /dist/skt.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drdarshan/skt-js/main/dist/skt.wasm -------------------------------------------------------------------------------- /skt-js-img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drdarshan/skt-js/main/skt-js-img.png -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | publish = "dist" 3 | 4 | # Redirect all requests to index.html for SPA routing 5 | [[redirects]] 6 | from = "/*" 7 | to = "/index.html" 8 | status = 200 9 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | './*.html', 5 | ], 6 | theme: { 7 | extend: {}, 8 | }, 9 | plugins: [], 10 | } 11 | -------------------------------------------------------------------------------- /dist/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | './*.html', 5 | ], 6 | theme: { 7 | extend: {}, 8 | }, 9 | plugins: [], 10 | } 11 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for more information: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | # https://containers.dev/guide/dependabot 6 | 7 | version: 2 8 | updates: 9 | - package-ecosystem: "devcontainers" 10 | directory: "/" 11 | schedule: 12 | interval: weekly 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "skt-js", 3 | "version": "1.0.0", 4 | "description": "Online SKT Pre-processor - Run the skt.c pre-processor from the LaTeX sanskrit package directly in your browser", 5 | "main": "skt.js", 6 | "scripts": { 7 | "build:css": "tailwindcss -i ./src/input.css -o ./dist/output.css", 8 | "watch:css": "tailwindcss -i ./src/input.css -o ./dist/output.css --watch", 9 | "build": "npm run build:css", 10 | "dev": "npm run watch:css" 11 | }, 12 | "keywords": ["sanskrit", "latex", "skt", "preprocessor"], 13 | "author": "drdarshan", 14 | "license": "MIT", 15 | "devDependencies": { 16 | "tailwindcss": "^3.3.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /dist/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "skt-js", 3 | "version": "1.0.0", 4 | "description": "Online SKT Pre-processor - Run the skt.c pre-processor from the LaTeX sanskrit package directly in your browser", 5 | "main": "skt.js", 6 | "scripts": { 7 | "build:css": "tailwindcss -i ./src/input.css -o ./dist/output.css", 8 | "watch:css": "tailwindcss -i ./src/input.css -o ./dist/output.css --watch", 9 | "build": "npm run build:css", 10 | "dev": "npm run watch:css" 11 | }, 12 | "keywords": ["sanskrit", "latex", "skt", "preprocessor"], 13 | "author": "drdarshan", 14 | "license": "MIT", 15 | "devDependencies": { 16 | "tailwindcss": "^3.3.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | 54 | # debug information files 55 | *.dwo 56 | 57 | # Node dependencies 58 | node_modules/ 59 | package-lock.json 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SKT-JS: Run `skt` Sanskrit pre-process on your browser! 2 | This repo provides a WASM compiled version with a thin web app for the `skt.c` pre-processing binary in the `sanskrit` LaTeX 2e package: https://ctan.org/tex-archive/language/sanskrit 3 | 4 | You can access a convenient, pre-built version of the pre-processor here: https://skt-js.netlify.app 5 | 6 | The web app is pretty minimal but is sufficient for most Sanskrit typesetting tasks using the `sanskrit` package. You can take the results and either download it to run LaTeX on the generated document or copy the contents to an online LaTeX environment like Overleaf. 7 | 8 | I am stil working on making aspects like error handling more robust but if you have any requests or feedback, please file an issue! 9 | 10 | ![Lokah Samasthah Sukhino Bhavantu](skt-js-img.png) 11 | -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/devcontainers/cpp:1-ubuntu-24.04 2 | 3 | ARG REINSTALL_CMAKE_VERSION_FROM_SOURCE="none" 4 | 5 | # Optionally install the cmake for vcpkg 6 | COPY ./reinstall-cmake.sh /tmp/ 7 | 8 | RUN if [ "${REINSTALL_CMAKE_VERSION_FROM_SOURCE}" != "none" ]; then \ 9 | chmod +x /tmp/reinstall-cmake.sh && /tmp/reinstall-cmake.sh ${REINSTALL_CMAKE_VERSION_FROM_SOURCE}; \ 10 | fi \ 11 | && rm -f /tmp/reinstall-cmake.sh 12 | 13 | # [Optional] Uncomment this section to install additional vcpkg ports. 14 | # RUN su vscode -c "${VCPKG_ROOT}/vcpkg install " 15 | 16 | # [Optional] Uncomment this section to install additional packages. 17 | # RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ 18 | # && apt-get -y install --no-install-recommends 19 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the 2 | // README at: https://github.com/devcontainers/templates/tree/main/src/cpp 3 | { 4 | "name": "C++", 5 | "build": { 6 | "dockerfile": "Dockerfile" 7 | }, 8 | "features": { 9 | "ghcr.io/ebaskoro/devcontainer-features/emscripten:1": {} 10 | } 11 | 12 | // Features to add to the dev container. More info: https://containers.dev/features. 13 | // "features": {}, 14 | 15 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 16 | // "forwardPorts": [], 17 | 18 | // Use 'postCreateCommand' to run commands after the container is created. 19 | // "postCreateCommand": "gcc -v", 20 | 21 | // Configure tool-specific properties. 22 | // "customizations": {}, 23 | 24 | // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. 25 | // "remoteUser": "root" 26 | } 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Sudarshan Raghunathan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /dist/input.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400;500&family=Inter:wght@100..900&display=swap'); 2 | 3 | @tailwind base; 4 | @tailwind components; 5 | @tailwind utilities; 6 | 7 | body { 8 | font-family: 'Inter', sans-serif; 9 | background-color: #f3f4f6; /* cool-gray-100 */ 10 | } 11 | 12 | /* Monospace font for code and editors */ 13 | textarea, .CodeMirror { 14 | font-family: 'Roboto Mono', monospace !important; 15 | font-size: 14px; 16 | line-height: 1.6; 17 | letter-spacing: 0.3px; 18 | } 19 | 20 | /* Custom scrollbar for a cleaner look in textareas */ 21 | textarea::-webkit-scrollbar { width: 6px; } 22 | textarea::-webkit-scrollbar-track { background: #f1f1f1; border-radius: 10px; } 23 | textarea::-webkit-scrollbar-thumb { background: #c1c1c1; border-radius: 10px; } 24 | textarea::-webkit-scrollbar-thumb:hover { background: #a1a1a1; } 25 | 26 | /* Placeholder styling */ 27 | textarea::placeholder { 28 | color: #9ca3af; 29 | } 30 | 31 | /* CodeMirror container constraints */ 32 | .CodeMirror { 33 | height: 100% !important; 34 | } 35 | 36 | .editor-container { 37 | display: flex; 38 | flex-direction: column; 39 | flex: 1; 40 | min-height: 0; 41 | overflow: hidden; 42 | } 43 | 44 | /* GitHub ribbon styling */ 45 | .github-ribbon { 46 | position: fixed; 47 | top: 0; 48 | right: 0; 49 | border: 0; 50 | z-index: 50; 51 | } 52 | -------------------------------------------------------------------------------- /src/input.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400;500&family=Inter:wght@100..900&display=swap'); 2 | 3 | @tailwind base; 4 | @tailwind components; 5 | @tailwind utilities; 6 | 7 | body { 8 | font-family: 'Inter', sans-serif; 9 | background-color: #f3f4f6; /* cool-gray-100 */ 10 | } 11 | 12 | /* Monospace font for code and editors */ 13 | textarea, .CodeMirror { 14 | font-family: 'Roboto Mono', monospace !important; 15 | font-size: 14px; 16 | line-height: 1.6; 17 | letter-spacing: 0.3px; 18 | } 19 | 20 | /* Custom scrollbar for a cleaner look in textareas */ 21 | textarea::-webkit-scrollbar { width: 6px; } 22 | textarea::-webkit-scrollbar-track { background: #f1f1f1; border-radius: 10px; } 23 | textarea::-webkit-scrollbar-thumb { background: #c1c1c1; border-radius: 10px; } 24 | textarea::-webkit-scrollbar-thumb:hover { background: #a1a1a1; } 25 | 26 | /* Placeholder styling */ 27 | textarea::placeholder { 28 | color: #9ca3af; 29 | } 30 | 31 | /* CodeMirror container constraints */ 32 | .CodeMirror { 33 | height: 100% !important; 34 | } 35 | 36 | .editor-container { 37 | display: flex; 38 | flex-direction: column; 39 | flex: 1; 40 | min-height: 0; 41 | overflow: hidden; 42 | } 43 | 44 | /* GitHub ribbon styling */ 45 | .github-ribbon { 46 | position: fixed; 47 | top: 0; 48 | right: 0; 49 | border: 0; 50 | z-index: 50; 51 | } 52 | -------------------------------------------------------------------------------- /.devcontainer/reinstall-cmake.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #------------------------------------------------------------------------------------------------------------- 3 | # Copyright (c) Microsoft Corporation. All rights reserved. 4 | # Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. 5 | #------------------------------------------------------------------------------------------------------------- 6 | # 7 | set -e 8 | 9 | CMAKE_VERSION=${1:-"none"} 10 | 11 | if [ "${CMAKE_VERSION}" = "none" ]; then 12 | echo "No CMake version specified, skipping CMake reinstallation" 13 | exit 0 14 | fi 15 | 16 | # Cleanup temporary directory and associated files when exiting the script. 17 | cleanup() { 18 | EXIT_CODE=$? 19 | set +e 20 | if [[ -n "${TMP_DIR}" ]]; then 21 | echo "Executing cleanup of tmp files" 22 | rm -Rf "${TMP_DIR}" 23 | fi 24 | exit $EXIT_CODE 25 | } 26 | trap cleanup EXIT 27 | 28 | 29 | echo "Installing CMake..." 30 | apt-get -y purge --auto-remove cmake 31 | mkdir -p /opt/cmake 32 | 33 | architecture=$(dpkg --print-architecture) 34 | case "${architecture}" in 35 | arm64) 36 | ARCH=aarch64 ;; 37 | amd64) 38 | ARCH=x86_64 ;; 39 | *) 40 | echo "Unsupported architecture ${architecture}." 41 | exit 1 42 | ;; 43 | esac 44 | 45 | CMAKE_BINARY_NAME="cmake-${CMAKE_VERSION}-linux-${ARCH}.sh" 46 | CMAKE_CHECKSUM_NAME="cmake-${CMAKE_VERSION}-SHA-256.txt" 47 | TMP_DIR=$(mktemp -d -t cmake-XXXXXXXXXX) 48 | 49 | echo "${TMP_DIR}" 50 | cd "${TMP_DIR}" 51 | 52 | curl -sSL "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/${CMAKE_BINARY_NAME}" -O 53 | curl -sSL "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/${CMAKE_CHECKSUM_NAME}" -O 54 | 55 | sha256sum -c --ignore-missing "${CMAKE_CHECKSUM_NAME}" 56 | sh "${TMP_DIR}/${CMAKE_BINARY_NAME}" --prefix=/opt/cmake --skip-license 57 | 58 | ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake 59 | ln -s /opt/cmake/bin/ctest /usr/local/bin/ctest 60 | -------------------------------------------------------------------------------- /.github/workflows/build-tailwind.yml: -------------------------------------------------------------------------------- 1 | name: Build and Deploy 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | permissions: 10 | contents: write 11 | pages: write 12 | id-token: write 13 | 14 | jobs: 15 | build: 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - uses: actions/checkout@v4 20 | with: 21 | token: ${{ secrets.GITHUB_TOKEN }} 22 | 23 | - name: Setup Node.js 24 | uses: actions/setup-node@v4 25 | with: 26 | node-version: '18' 27 | 28 | - name: Install npm dependencies 29 | run: npm install 30 | 31 | - name: Build Tailwind CSS 32 | run: npm run build:css 33 | 34 | - name: Setup Emscripten 35 | uses: mymindstorm/setup-emsdk@v12 36 | with: 37 | version: latest 38 | 39 | - name: Create dist directory 40 | run: mkdir -p dist 41 | 42 | - name: Compile WASM from skt.c 43 | run: | 44 | emcc skt.c -o dist/skt.js \ 45 | -s WASM=1 \ 46 | -s ALLOW_MEMORY_GROWTH=1 \ 47 | -s INVOKE_RUN=0 \ 48 | -s EXPORTED_RUNTIME_METHODS="['callMain','FS']" \ 49 | -O3 50 | 51 | - name: Copy artifacts to dist 52 | run: | 53 | # Copy skt.html and update CSS path for dist folder 54 | sed 's|href="dist/output.css"|href="output.css"|g' skt.html > dist/skt.html 55 | # Also create index.html pointing to skt.html 56 | cp dist/skt.html dist/index.html 57 | cp -r src/input.css dist/ 2>/dev/null || true 58 | [ -f package.json ] && cp package.json dist/ || true 59 | [ -f tailwind.config.js ] && cp tailwind.config.js dist/ || true 60 | 61 | - name: Commit and push if changed 62 | if: github.event_name == 'push' && github.ref == 'refs/heads/main' 63 | run: | 64 | git config --local user.email "action@github.com" 65 | git config --local user.name "GitHub Action" 66 | git add dist/ 67 | git diff --quiet && git diff --staged --quiet || (git commit -m "Build: Compile Tailwind CSS and WASM artifacts" && git push) 68 | 69 | - name: Upload artifact for GitHub Pages 70 | uses: actions/upload-pages-artifact@v3 71 | with: 72 | path: './dist' 73 | 74 | deploy: 75 | needs: build 76 | if: github.event_name == 'push' && github.ref == 'refs/heads/main' 77 | runs-on: ubuntu-latest 78 | environment: 79 | name: github-pages 80 | url: ${{ steps.deployment.outputs.page_url }} 81 | 82 | steps: 83 | - name: Deploy to GitHub Pages 84 | id: deployment 85 | uses: actions/deploy-pages@v4 86 | -------------------------------------------------------------------------------- /dist/output.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400;500&family=Inter:wght@100..900&display=swap'); 2 | 3 | *, ::before, ::after{ 4 | --tw-border-spacing-x: 0; 5 | --tw-border-spacing-y: 0; 6 | --tw-translate-x: 0; 7 | --tw-translate-y: 0; 8 | --tw-rotate: 0; 9 | --tw-skew-x: 0; 10 | --tw-skew-y: 0; 11 | --tw-scale-x: 1; 12 | --tw-scale-y: 1; 13 | --tw-pan-x: ; 14 | --tw-pan-y: ; 15 | --tw-pinch-zoom: ; 16 | --tw-scroll-snap-strictness: proximity; 17 | --tw-gradient-from-position: ; 18 | --tw-gradient-via-position: ; 19 | --tw-gradient-to-position: ; 20 | --tw-ordinal: ; 21 | --tw-slashed-zero: ; 22 | --tw-numeric-figure: ; 23 | --tw-numeric-spacing: ; 24 | --tw-numeric-fraction: ; 25 | --tw-ring-inset: ; 26 | --tw-ring-offset-width: 0px; 27 | --tw-ring-offset-color: #fff; 28 | --tw-ring-color: rgb(59 130 246 / 0.5); 29 | --tw-ring-offset-shadow: 0 0 #0000; 30 | --tw-ring-shadow: 0 0 #0000; 31 | --tw-shadow: 0 0 #0000; 32 | --tw-shadow-colored: 0 0 #0000; 33 | --tw-blur: ; 34 | --tw-brightness: ; 35 | --tw-contrast: ; 36 | --tw-grayscale: ; 37 | --tw-hue-rotate: ; 38 | --tw-invert: ; 39 | --tw-saturate: ; 40 | --tw-sepia: ; 41 | --tw-drop-shadow: ; 42 | --tw-backdrop-blur: ; 43 | --tw-backdrop-brightness: ; 44 | --tw-backdrop-contrast: ; 45 | --tw-backdrop-grayscale: ; 46 | --tw-backdrop-hue-rotate: ; 47 | --tw-backdrop-invert: ; 48 | --tw-backdrop-opacity: ; 49 | --tw-backdrop-saturate: ; 50 | --tw-backdrop-sepia: ; 51 | --tw-contain-size: ; 52 | --tw-contain-layout: ; 53 | --tw-contain-paint: ; 54 | --tw-contain-style: ; 55 | } 56 | 57 | ::backdrop{ 58 | --tw-border-spacing-x: 0; 59 | --tw-border-spacing-y: 0; 60 | --tw-translate-x: 0; 61 | --tw-translate-y: 0; 62 | --tw-rotate: 0; 63 | --tw-skew-x: 0; 64 | --tw-skew-y: 0; 65 | --tw-scale-x: 1; 66 | --tw-scale-y: 1; 67 | --tw-pan-x: ; 68 | --tw-pan-y: ; 69 | --tw-pinch-zoom: ; 70 | --tw-scroll-snap-strictness: proximity; 71 | --tw-gradient-from-position: ; 72 | --tw-gradient-via-position: ; 73 | --tw-gradient-to-position: ; 74 | --tw-ordinal: ; 75 | --tw-slashed-zero: ; 76 | --tw-numeric-figure: ; 77 | --tw-numeric-spacing: ; 78 | --tw-numeric-fraction: ; 79 | --tw-ring-inset: ; 80 | --tw-ring-offset-width: 0px; 81 | --tw-ring-offset-color: #fff; 82 | --tw-ring-color: rgb(59 130 246 / 0.5); 83 | --tw-ring-offset-shadow: 0 0 #0000; 84 | --tw-ring-shadow: 0 0 #0000; 85 | --tw-shadow: 0 0 #0000; 86 | --tw-shadow-colored: 0 0 #0000; 87 | --tw-blur: ; 88 | --tw-brightness: ; 89 | --tw-contrast: ; 90 | --tw-grayscale: ; 91 | --tw-hue-rotate: ; 92 | --tw-invert: ; 93 | --tw-saturate: ; 94 | --tw-sepia: ; 95 | --tw-drop-shadow: ; 96 | --tw-backdrop-blur: ; 97 | --tw-backdrop-brightness: ; 98 | --tw-backdrop-contrast: ; 99 | --tw-backdrop-grayscale: ; 100 | --tw-backdrop-hue-rotate: ; 101 | --tw-backdrop-invert: ; 102 | --tw-backdrop-opacity: ; 103 | --tw-backdrop-saturate: ; 104 | --tw-backdrop-sepia: ; 105 | --tw-contain-size: ; 106 | --tw-contain-layout: ; 107 | --tw-contain-paint: ; 108 | --tw-contain-style: ; 109 | } 110 | 111 | /* 112 | ! tailwindcss v3.4.18 | MIT License | https://tailwindcss.com 113 | */ 114 | 115 | /* 116 | 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) 117 | 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) 118 | */ 119 | 120 | *, 121 | ::before, 122 | ::after { 123 | box-sizing: border-box; 124 | /* 1 */ 125 | border-width: 0; 126 | /* 2 */ 127 | border-style: solid; 128 | /* 2 */ 129 | border-color: #e5e7eb; 130 | /* 2 */ 131 | } 132 | 133 | ::before, 134 | ::after { 135 | --tw-content: ''; 136 | } 137 | 138 | /* 139 | 1. Use a consistent sensible line-height in all browsers. 140 | 2. Prevent adjustments of font size after orientation changes in iOS. 141 | 3. Use a more readable tab size. 142 | 4. Use the user's configured `sans` font-family by default. 143 | 5. Use the user's configured `sans` font-feature-settings by default. 144 | 6. Use the user's configured `sans` font-variation-settings by default. 145 | 7. Disable tap highlights on iOS 146 | */ 147 | 148 | html, 149 | :host { 150 | line-height: 1.5; 151 | /* 1 */ 152 | -webkit-text-size-adjust: 100%; 153 | /* 2 */ 154 | -moz-tab-size: 4; 155 | /* 3 */ 156 | -o-tab-size: 4; 157 | tab-size: 4; 158 | /* 3 */ 159 | font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; 160 | /* 4 */ 161 | font-feature-settings: normal; 162 | /* 5 */ 163 | font-variation-settings: normal; 164 | /* 6 */ 165 | -webkit-tap-highlight-color: transparent; 166 | /* 7 */ 167 | } 168 | 169 | /* 170 | 1. Remove the margin in all browsers. 171 | 2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. 172 | */ 173 | 174 | body { 175 | margin: 0; 176 | /* 1 */ 177 | line-height: inherit; 178 | /* 2 */ 179 | } 180 | 181 | /* 182 | 1. Add the correct height in Firefox. 183 | 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) 184 | 3. Ensure horizontal rules are visible by default. 185 | */ 186 | 187 | hr { 188 | height: 0; 189 | /* 1 */ 190 | color: inherit; 191 | /* 2 */ 192 | border-top-width: 1px; 193 | /* 3 */ 194 | } 195 | 196 | /* 197 | Add the correct text decoration in Chrome, Edge, and Safari. 198 | */ 199 | 200 | abbr:where([title]) { 201 | -webkit-text-decoration: underline dotted; 202 | text-decoration: underline dotted; 203 | } 204 | 205 | /* 206 | Remove the default font size and weight for headings. 207 | */ 208 | 209 | h1, 210 | h2, 211 | h3, 212 | h4, 213 | h5, 214 | h6 { 215 | font-size: inherit; 216 | font-weight: inherit; 217 | } 218 | 219 | /* 220 | Reset links to optimize for opt-in styling instead of opt-out. 221 | */ 222 | 223 | a { 224 | color: inherit; 225 | text-decoration: inherit; 226 | } 227 | 228 | /* 229 | Add the correct font weight in Edge and Safari. 230 | */ 231 | 232 | b, 233 | strong { 234 | font-weight: bolder; 235 | } 236 | 237 | /* 238 | 1. Use the user's configured `mono` font-family by default. 239 | 2. Use the user's configured `mono` font-feature-settings by default. 240 | 3. Use the user's configured `mono` font-variation-settings by default. 241 | 4. Correct the odd `em` font sizing in all browsers. 242 | */ 243 | 244 | code, 245 | kbd, 246 | samp, 247 | pre { 248 | font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; 249 | /* 1 */ 250 | font-feature-settings: normal; 251 | /* 2 */ 252 | font-variation-settings: normal; 253 | /* 3 */ 254 | font-size: 1em; 255 | /* 4 */ 256 | } 257 | 258 | /* 259 | Add the correct font size in all browsers. 260 | */ 261 | 262 | small { 263 | font-size: 80%; 264 | } 265 | 266 | /* 267 | Prevent `sub` and `sup` elements from affecting the line height in all browsers. 268 | */ 269 | 270 | sub, 271 | sup { 272 | font-size: 75%; 273 | line-height: 0; 274 | position: relative; 275 | vertical-align: baseline; 276 | } 277 | 278 | sub { 279 | bottom: -0.25em; 280 | } 281 | 282 | sup { 283 | top: -0.5em; 284 | } 285 | 286 | /* 287 | 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) 288 | 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) 289 | 3. Remove gaps between table borders by default. 290 | */ 291 | 292 | table { 293 | text-indent: 0; 294 | /* 1 */ 295 | border-color: inherit; 296 | /* 2 */ 297 | border-collapse: collapse; 298 | /* 3 */ 299 | } 300 | 301 | /* 302 | 1. Change the font styles in all browsers. 303 | 2. Remove the margin in Firefox and Safari. 304 | 3. Remove default padding in all browsers. 305 | */ 306 | 307 | button, 308 | input, 309 | optgroup, 310 | select, 311 | textarea { 312 | font-family: inherit; 313 | /* 1 */ 314 | font-feature-settings: inherit; 315 | /* 1 */ 316 | font-variation-settings: inherit; 317 | /* 1 */ 318 | font-size: 100%; 319 | /* 1 */ 320 | font-weight: inherit; 321 | /* 1 */ 322 | line-height: inherit; 323 | /* 1 */ 324 | letter-spacing: inherit; 325 | /* 1 */ 326 | color: inherit; 327 | /* 1 */ 328 | margin: 0; 329 | /* 2 */ 330 | padding: 0; 331 | /* 3 */ 332 | } 333 | 334 | /* 335 | Remove the inheritance of text transform in Edge and Firefox. 336 | */ 337 | 338 | button, 339 | select { 340 | text-transform: none; 341 | } 342 | 343 | /* 344 | 1. Correct the inability to style clickable types in iOS and Safari. 345 | 2. Remove default button styles. 346 | */ 347 | 348 | button, 349 | input:where([type='button']), 350 | input:where([type='reset']), 351 | input:where([type='submit']) { 352 | -webkit-appearance: button; 353 | /* 1 */ 354 | background-color: transparent; 355 | /* 2 */ 356 | background-image: none; 357 | /* 2 */ 358 | } 359 | 360 | /* 361 | Use the modern Firefox focus style for all focusable elements. 362 | */ 363 | 364 | :-moz-focusring { 365 | outline: auto; 366 | } 367 | 368 | /* 369 | Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) 370 | */ 371 | 372 | :-moz-ui-invalid { 373 | box-shadow: none; 374 | } 375 | 376 | /* 377 | Add the correct vertical alignment in Chrome and Firefox. 378 | */ 379 | 380 | progress { 381 | vertical-align: baseline; 382 | } 383 | 384 | /* 385 | Correct the cursor style of increment and decrement buttons in Safari. 386 | */ 387 | 388 | ::-webkit-inner-spin-button, 389 | ::-webkit-outer-spin-button { 390 | height: auto; 391 | } 392 | 393 | /* 394 | 1. Correct the odd appearance in Chrome and Safari. 395 | 2. Correct the outline style in Safari. 396 | */ 397 | 398 | [type='search'] { 399 | -webkit-appearance: textfield; 400 | /* 1 */ 401 | outline-offset: -2px; 402 | /* 2 */ 403 | } 404 | 405 | /* 406 | Remove the inner padding in Chrome and Safari on macOS. 407 | */ 408 | 409 | ::-webkit-search-decoration { 410 | -webkit-appearance: none; 411 | } 412 | 413 | /* 414 | 1. Correct the inability to style clickable types in iOS and Safari. 415 | 2. Change font properties to `inherit` in Safari. 416 | */ 417 | 418 | ::-webkit-file-upload-button { 419 | -webkit-appearance: button; 420 | /* 1 */ 421 | font: inherit; 422 | /* 2 */ 423 | } 424 | 425 | /* 426 | Add the correct display in Chrome and Safari. 427 | */ 428 | 429 | summary { 430 | display: list-item; 431 | } 432 | 433 | /* 434 | Removes the default spacing and border for appropriate elements. 435 | */ 436 | 437 | blockquote, 438 | dl, 439 | dd, 440 | h1, 441 | h2, 442 | h3, 443 | h4, 444 | h5, 445 | h6, 446 | hr, 447 | figure, 448 | p, 449 | pre { 450 | margin: 0; 451 | } 452 | 453 | fieldset { 454 | margin: 0; 455 | padding: 0; 456 | } 457 | 458 | legend { 459 | padding: 0; 460 | } 461 | 462 | ol, 463 | ul, 464 | menu { 465 | list-style: none; 466 | margin: 0; 467 | padding: 0; 468 | } 469 | 470 | /* 471 | Reset default styling for dialogs. 472 | */ 473 | 474 | dialog { 475 | padding: 0; 476 | } 477 | 478 | /* 479 | Prevent resizing textareas horizontally by default. 480 | */ 481 | 482 | textarea { 483 | resize: vertical; 484 | } 485 | 486 | /* 487 | 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) 488 | 2. Set the default placeholder color to the user's configured gray 400 color. 489 | */ 490 | 491 | input::-moz-placeholder, textarea::-moz-placeholder { 492 | opacity: 1; 493 | /* 1 */ 494 | color: #9ca3af; 495 | /* 2 */ 496 | } 497 | 498 | input::placeholder, 499 | textarea::placeholder { 500 | opacity: 1; 501 | /* 1 */ 502 | color: #9ca3af; 503 | /* 2 */ 504 | } 505 | 506 | /* 507 | Set the default cursor for buttons. 508 | */ 509 | 510 | button, 511 | [role="button"] { 512 | cursor: pointer; 513 | } 514 | 515 | /* 516 | Make sure disabled buttons don't get the pointer cursor. 517 | */ 518 | 519 | :disabled { 520 | cursor: default; 521 | } 522 | 523 | /* 524 | 1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) 525 | 2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) 526 | This can trigger a poorly considered lint error in some tools but is included by design. 527 | */ 528 | 529 | img, 530 | svg, 531 | video, 532 | canvas, 533 | audio, 534 | iframe, 535 | embed, 536 | object { 537 | display: block; 538 | /* 1 */ 539 | vertical-align: middle; 540 | /* 2 */ 541 | } 542 | 543 | /* 544 | Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) 545 | */ 546 | 547 | img, 548 | video { 549 | max-width: 100%; 550 | height: auto; 551 | } 552 | 553 | /* Make elements with the HTML hidden attribute stay hidden by default */ 554 | 555 | [hidden]:where(:not([hidden="until-found"])) { 556 | display: none; 557 | } 558 | 559 | .container{ 560 | width: 100%; 561 | } 562 | 563 | @media (min-width: 640px){ 564 | .container{ 565 | max-width: 640px; 566 | } 567 | } 568 | 569 | @media (min-width: 768px){ 570 | .container{ 571 | max-width: 768px; 572 | } 573 | } 574 | 575 | @media (min-width: 1024px){ 576 | .container{ 577 | max-width: 1024px; 578 | } 579 | } 580 | 581 | @media (min-width: 1280px){ 582 | .container{ 583 | max-width: 1280px; 584 | } 585 | } 586 | 587 | @media (min-width: 1536px){ 588 | .container{ 589 | max-width: 1536px; 590 | } 591 | } 592 | 593 | .fixed{ 594 | position: fixed; 595 | } 596 | 597 | .start-1{ 598 | inset-inline-start: 0.25rem; 599 | } 600 | 601 | .mx-auto{ 602 | margin-left: auto; 603 | margin-right: auto; 604 | } 605 | 606 | .mb-2{ 607 | margin-bottom: 0.5rem; 608 | } 609 | 610 | .mb-3{ 611 | margin-bottom: 0.75rem; 612 | } 613 | 614 | .mb-4{ 615 | margin-bottom: 1rem; 616 | } 617 | 618 | .mt-2{ 619 | margin-top: 0.5rem; 620 | } 621 | 622 | .mt-4{ 623 | margin-top: 1rem; 624 | } 625 | 626 | .inline{ 627 | display: inline; 628 | } 629 | 630 | .flex{ 631 | display: flex; 632 | } 633 | 634 | .table{ 635 | display: table; 636 | } 637 | 638 | .grid{ 639 | display: grid; 640 | } 641 | 642 | .hidden{ 643 | display: none; 644 | } 645 | 646 | .h-4{ 647 | height: 1rem; 648 | } 649 | 650 | .h-5{ 651 | height: 1.25rem; 652 | } 653 | 654 | .h-full{ 655 | height: 100%; 656 | } 657 | 658 | .min-h-\[60vh\]{ 659 | min-height: 60vh; 660 | } 661 | 662 | .w-4{ 663 | width: 1rem; 664 | } 665 | 666 | .w-5{ 667 | width: 1.25rem; 668 | } 669 | 670 | .max-w-7xl{ 671 | max-width: 80rem; 672 | } 673 | 674 | .flex-1{ 675 | flex: 1 1 0%; 676 | } 677 | 678 | .flex-grow{ 679 | flex-grow: 1; 680 | } 681 | 682 | @keyframes pulse{ 683 | 50%{ 684 | opacity: .5; 685 | } 686 | } 687 | 688 | .animate-pulse{ 689 | animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; 690 | } 691 | 692 | @keyframes spin{ 693 | to{ 694 | transform: rotate(360deg); 695 | } 696 | } 697 | 698 | .animate-spin{ 699 | animation: spin 1s linear infinite; 700 | } 701 | 702 | .cursor-pointer{ 703 | cursor: pointer; 704 | } 705 | 706 | .grid-cols-1{ 707 | grid-template-columns: repeat(1, minmax(0, 1fr)); 708 | } 709 | 710 | .flex-row{ 711 | flex-direction: row; 712 | } 713 | 714 | .flex-col{ 715 | flex-direction: column; 716 | } 717 | 718 | .items-start{ 719 | align-items: flex-start; 720 | } 721 | 722 | .items-center{ 723 | align-items: center; 724 | } 725 | 726 | .justify-end{ 727 | justify-content: flex-end; 728 | } 729 | 730 | .justify-center{ 731 | justify-content: center; 732 | } 733 | 734 | .justify-between{ 735 | justify-content: space-between; 736 | } 737 | 738 | .gap-1{ 739 | gap: 0.25rem; 740 | } 741 | 742 | .gap-2{ 743 | gap: 0.5rem; 744 | } 745 | 746 | .gap-6{ 747 | gap: 1.5rem; 748 | } 749 | 750 | .space-x-3 > :not([hidden]) ~ :not([hidden]){ 751 | --tw-space-x-reverse: 0; 752 | margin-right: calc(0.75rem * var(--tw-space-x-reverse)); 753 | margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse))); 754 | } 755 | 756 | .space-y-3 > :not([hidden]) ~ :not([hidden]){ 757 | --tw-space-y-reverse: 0; 758 | margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse))); 759 | margin-bottom: calc(0.75rem * var(--tw-space-y-reverse)); 760 | } 761 | 762 | .overflow-hidden{ 763 | overflow: hidden; 764 | } 765 | 766 | .whitespace-nowrap{ 767 | white-space: nowrap; 768 | } 769 | 770 | .rounded-full{ 771 | border-radius: 9999px; 772 | } 773 | 774 | .rounded-lg{ 775 | border-radius: 0.5rem; 776 | } 777 | 778 | .rounded-xl{ 779 | border-radius: 0.75rem; 780 | } 781 | 782 | .border{ 783 | border-width: 1px; 784 | } 785 | 786 | .border-gray-300{ 787 | --tw-border-opacity: 1; 788 | border-color: rgb(209 213 219 / var(--tw-border-opacity, 1)); 789 | } 790 | 791 | .bg-blue-600{ 792 | --tw-bg-opacity: 1; 793 | background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1)); 794 | } 795 | 796 | .bg-gray-50{ 797 | --tw-bg-opacity: 1; 798 | background-color: rgb(249 250 251 / var(--tw-bg-opacity, 1)); 799 | } 800 | 801 | .bg-green-500{ 802 | --tw-bg-opacity: 1; 803 | background-color: rgb(34 197 94 / var(--tw-bg-opacity, 1)); 804 | } 805 | 806 | .bg-green-600{ 807 | --tw-bg-opacity: 1; 808 | background-color: rgb(22 163 74 / var(--tw-bg-opacity, 1)); 809 | } 810 | 811 | .bg-indigo-600{ 812 | --tw-bg-opacity: 1; 813 | background-color: rgb(79 70 229 / var(--tw-bg-opacity, 1)); 814 | } 815 | 816 | .bg-purple-600{ 817 | --tw-bg-opacity: 1; 818 | background-color: rgb(147 51 234 / var(--tw-bg-opacity, 1)); 819 | } 820 | 821 | .bg-red-500{ 822 | --tw-bg-opacity: 1; 823 | background-color: rgb(239 68 68 / var(--tw-bg-opacity, 1)); 824 | } 825 | 826 | .bg-white{ 827 | --tw-bg-opacity: 1; 828 | background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1)); 829 | } 830 | 831 | .bg-yellow-400{ 832 | --tw-bg-opacity: 1; 833 | background-color: rgb(250 204 21 / var(--tw-bg-opacity, 1)); 834 | } 835 | 836 | .p-4{ 837 | padding: 1rem; 838 | } 839 | 840 | .px-3{ 841 | padding-left: 0.75rem; 842 | padding-right: 0.75rem; 843 | } 844 | 845 | .py-2{ 846 | padding-top: 0.5rem; 847 | padding-bottom: 0.5rem; 848 | } 849 | 850 | .text-justify{ 851 | text-align: justify; 852 | } 853 | 854 | .text-3xl{ 855 | font-size: 1.875rem; 856 | line-height: 2.25rem; 857 | } 858 | 859 | .text-lg{ 860 | font-size: 1.125rem; 861 | line-height: 1.75rem; 862 | } 863 | 864 | .text-sm{ 865 | font-size: 0.875rem; 866 | line-height: 1.25rem; 867 | } 868 | 869 | .font-extrabold{ 870 | font-weight: 800; 871 | } 872 | 873 | .font-medium{ 874 | font-weight: 500; 875 | } 876 | 877 | .font-semibold{ 878 | font-weight: 600; 879 | } 880 | 881 | .text-blue-600{ 882 | --tw-text-opacity: 1; 883 | color: rgb(37 99 235 / var(--tw-text-opacity, 1)); 884 | } 885 | 886 | .text-gray-500{ 887 | --tw-text-opacity: 1; 888 | color: rgb(107 114 128 / var(--tw-text-opacity, 1)); 889 | } 890 | 891 | .text-gray-600{ 892 | --tw-text-opacity: 1; 893 | color: rgb(75 85 99 / var(--tw-text-opacity, 1)); 894 | } 895 | 896 | .text-gray-700{ 897 | --tw-text-opacity: 1; 898 | color: rgb(55 65 81 / var(--tw-text-opacity, 1)); 899 | } 900 | 901 | .text-gray-800{ 902 | --tw-text-opacity: 1; 903 | color: rgb(31 41 55 / var(--tw-text-opacity, 1)); 904 | } 905 | 906 | .text-green-600{ 907 | --tw-text-opacity: 1; 908 | color: rgb(22 163 74 / var(--tw-text-opacity, 1)); 909 | } 910 | 911 | .text-indigo-700{ 912 | --tw-text-opacity: 1; 913 | color: rgb(67 56 202 / var(--tw-text-opacity, 1)); 914 | } 915 | 916 | .text-white{ 917 | --tw-text-opacity: 1; 918 | color: rgb(255 255 255 / var(--tw-text-opacity, 1)); 919 | } 920 | 921 | .antialiased{ 922 | -webkit-font-smoothing: antialiased; 923 | -moz-osx-font-smoothing: grayscale; 924 | } 925 | 926 | .opacity-25{ 927 | opacity: 0.25; 928 | } 929 | 930 | .opacity-75{ 931 | opacity: 0.75; 932 | } 933 | 934 | .shadow-lg{ 935 | --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); 936 | --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); 937 | box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); 938 | } 939 | 940 | .filter{ 941 | filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); 942 | } 943 | 944 | .transition{ 945 | transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; 946 | transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; 947 | transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; 948 | transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); 949 | transition-duration: 150ms; 950 | } 951 | 952 | body { 953 | font-family: 'Inter', sans-serif; 954 | background-color: #f3f4f6; 955 | /* cool-gray-100 */ 956 | } 957 | 958 | /* Monospace font for code and editors */ 959 | 960 | textarea, .CodeMirror { 961 | font-family: 'Roboto Mono', monospace !important; 962 | font-size: 14px; 963 | line-height: 1.6; 964 | letter-spacing: 0.3px; 965 | } 966 | 967 | /* Custom scrollbar for a cleaner look in textareas */ 968 | 969 | textarea::-webkit-scrollbar { 970 | width: 6px; 971 | } 972 | 973 | textarea::-webkit-scrollbar-track { 974 | background: #f1f1f1; 975 | border-radius: 10px; 976 | } 977 | 978 | textarea::-webkit-scrollbar-thumb { 979 | background: #c1c1c1; 980 | border-radius: 10px; 981 | } 982 | 983 | textarea::-webkit-scrollbar-thumb:hover { 984 | background: #a1a1a1; 985 | } 986 | 987 | /* Placeholder styling */ 988 | 989 | textarea::-moz-placeholder { 990 | color: #9ca3af; 991 | } 992 | 993 | textarea::placeholder { 994 | color: #9ca3af; 995 | } 996 | 997 | /* CodeMirror container constraints */ 998 | 999 | .CodeMirror { 1000 | height: 100% !important; 1001 | } 1002 | 1003 | .editor-container { 1004 | display: flex; 1005 | flex-direction: column; 1006 | flex: 1; 1007 | min-height: 0; 1008 | overflow: hidden; 1009 | } 1010 | 1011 | /* GitHub ribbon styling */ 1012 | 1013 | .github-ribbon { 1014 | position: fixed; 1015 | top: 0; 1016 | right: 0; 1017 | border: 0; 1018 | z-index: 50; 1019 | } 1020 | 1021 | .hover\:bg-blue-700:hover{ 1022 | --tw-bg-opacity: 1; 1023 | background-color: rgb(29 78 216 / var(--tw-bg-opacity, 1)); 1024 | } 1025 | 1026 | .hover\:bg-green-700:hover{ 1027 | --tw-bg-opacity: 1; 1028 | background-color: rgb(21 128 61 / var(--tw-bg-opacity, 1)); 1029 | } 1030 | 1031 | .hover\:bg-indigo-700:hover{ 1032 | --tw-bg-opacity: 1; 1033 | background-color: rgb(67 56 202 / var(--tw-bg-opacity, 1)); 1034 | } 1035 | 1036 | .hover\:bg-purple-700:hover{ 1037 | --tw-bg-opacity: 1; 1038 | background-color: rgb(126 34 206 / var(--tw-bg-opacity, 1)); 1039 | } 1040 | 1041 | .hover\:text-blue-800:hover{ 1042 | --tw-text-opacity: 1; 1043 | color: rgb(30 64 175 / var(--tw-text-opacity, 1)); 1044 | } 1045 | 1046 | .hover\:text-gray-700:hover{ 1047 | --tw-text-opacity: 1; 1048 | color: rgb(55 65 81 / var(--tw-text-opacity, 1)); 1049 | } 1050 | 1051 | .hover\:underline:hover{ 1052 | text-decoration-line: underline; 1053 | } 1054 | 1055 | .disabled\:cursor-not-allowed:disabled{ 1056 | cursor: not-allowed; 1057 | } 1058 | 1059 | .disabled\:opacity-50:disabled{ 1060 | opacity: 0.5; 1061 | } 1062 | 1063 | @media (min-width: 640px){ 1064 | .sm\:flex-row{ 1065 | flex-direction: row; 1066 | } 1067 | 1068 | .sm\:items-center{ 1069 | align-items: center; 1070 | } 1071 | 1072 | .sm\:space-y-0 > :not([hidden]) ~ :not([hidden]){ 1073 | --tw-space-y-reverse: 0; 1074 | margin-top: calc(0px * calc(1 - var(--tw-space-y-reverse))); 1075 | margin-bottom: calc(0px * var(--tw-space-y-reverse)); 1076 | } 1077 | 1078 | .sm\:p-8{ 1079 | padding: 2rem; 1080 | } 1081 | 1082 | .sm\:text-4xl{ 1083 | font-size: 2.25rem; 1084 | line-height: 2.5rem; 1085 | } 1086 | } 1087 | 1088 | @media (min-width: 1024px){ 1089 | .lg\:grid-cols-2{ 1090 | grid-template-columns: repeat(2, minmax(0, 1fr)); 1091 | } 1092 | } 1093 | -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Online SKT Processor 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 60 | 61 | 62 | 63 | Fork me on GitHub 64 | 65 | 66 |
67 | 68 |
69 |

Online SKT Pre-processor

70 |

Run the skt.c pre-processor from the LaTeX sanskrit package directly in your browser.

71 |
72 | 73 | 74 |
75 | 76 | 77 |
78 | 79 | 80 | 81 |
82 | 89 | 92 | 93 | 100 |
101 | 102 | 103 |
104 | 109 |
110 | 111 |
112 |
113 | 114 | 115 |
116 | 117 | 118 | 119 |
120 | 126 |
127 | 128 | 129 |
130 | 135 |
136 | 137 | 138 |
139 |
140 |
141 | 142 | 143 |
144 |
145 |
146 | Status: Waiting for WASM module... 147 |
148 |
149 |
150 | 151 | 571 | 572 | 580 | 581 | 582 | -------------------------------------------------------------------------------- /dist/skt.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Online SKT Processor 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 60 | 61 | 62 | 63 | Fork me on GitHub 64 | 65 | 66 |
67 | 68 |
69 |

Online SKT Pre-processor

70 |

Run the skt.c pre-processor from the LaTeX sanskrit package directly in your browser.

71 |
72 | 73 | 74 |
75 | 76 | 77 |
78 | 79 | 80 | 81 |
82 | 89 | 92 | 93 | 100 |
101 | 102 | 103 |
104 | 109 |
110 | 111 |
112 |
113 | 114 | 115 |
116 | 117 | 118 | 119 |
120 | 126 |
127 | 128 | 129 |
130 | 135 |
136 | 137 | 138 |
139 |
140 |
141 | 142 | 143 |
144 |
145 |
146 | Status: Waiting for WASM module... 147 |
148 |
149 |
150 | 151 | 571 | 572 | 580 | 581 | 582 | -------------------------------------------------------------------------------- /skt.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Online SKT Processor 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 60 | 61 | 62 | 63 | Fork me on GitHub 64 | 65 | 66 |
67 | 68 |
69 |

Online SKT Pre-processor

70 |

Run the skt.c pre-processor from the LaTeX sanskrit package directly in your browser.

71 |
72 | 73 | 74 |
75 | 76 | 77 |
78 | 79 | 80 | 81 |
82 | 89 | 92 | 93 | 100 |
101 | 102 | 103 |
104 | 109 |
110 | 111 |
112 |
113 | 114 | 115 |
116 | 117 | 118 | 119 |
120 | 126 |
127 | 128 | 129 |
130 | 135 |
136 | 137 | 138 |
139 |
140 |
141 | 142 | 143 |
144 |
145 |
146 | Status: Waiting for WASM module... 147 |
148 |
149 |
150 | 151 | 571 | 572 | 580 | 581 | 582 | -------------------------------------------------------------------------------- /dist/skt.js: -------------------------------------------------------------------------------- 1 | var Module=typeof Module!="undefined"?Module:{};var ENVIRONMENT_IS_WEB=!!globalThis.window;var ENVIRONMENT_IS_WORKER=!!globalThis.WorkerGlobalScope;var ENVIRONMENT_IS_NODE=globalThis.process?.versions?.node&&globalThis.process?.type!="renderer";var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var _scriptName=globalThis.document?.currentScript?.src;if(typeof __filename!="undefined"){_scriptName=__filename}else if(ENVIRONMENT_IS_WORKER){_scriptName=self.location.href}var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_NODE){var fs=require("fs");scriptDirectory=__dirname+"/";readBinary=filename=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename);return ret};readAsync=async(filename,binary=true)=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename,binary?undefined:"utf8");return ret};if(process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}arguments_=process.argv.slice(2);if(typeof module!="undefined"){module["exports"]=Module}quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){try{scriptDirectory=new URL(".",_scriptName).href}catch{}{if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=async url=>{if(isFileURI(url)){return new Promise((resolve,reject)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){resolve(xhr.response);return}reject(xhr.status)};xhr.onerror=reject;xhr.send(null)})}var response=await fetch(url,{credentials:"same-origin"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+" : "+response.url)}}}else{}var out=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var EXITSTATUS;var isFileURI=filename=>filename.startsWith("file://");var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var HEAP64,HEAPU64;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAP16=new Int16Array(b);HEAPU8=new Uint8Array(b);HEAPU16=new Uint16Array(b);HEAP32=new Int32Array(b);HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);HEAPU64=new BigUint64Array(b)}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;if(!Module["noFSInit"]&&!FS.initialized)FS.init();TTY.init();wasmExports["k"]();FS.ignorePermissions=false}function preMain(){}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(onPostRuns)}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);throw e}var wasmBinaryFile;function findWasmBinary(){return locateFile("skt.wasm")}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}async function getWasmBinary(binaryFile){if(!wasmBinary){try{var response=await readAsync(binaryFile);return new Uint8Array(response)}catch{}}return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){if(!binary&&!isFileURI(binaryFile)&&!ENVIRONMENT_IS_NODE){try{var response=fetch(binaryFile,{credentials:"same-origin"});var instantiationResult=await WebAssembly.instantiateStreaming(response,imports);return instantiationResult}catch(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation")}}return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){var imports={a:wasmImports};return imports}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;assignWasmExports(wasmExports);updateMemoryViews();removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){return new Promise((resolve,reject)=>{Module["instantiateWasm"](info,(inst,mod)=>{resolve(receiveInstance(inst,mod))})})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);var runDependencies=0;var dependenciesFulfilled=null;var removeRunDependency=id=>{runDependencies--;Module["monitorRunDependencies"]?.(runDependencies);if(runDependencies==0){if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}};var addRunDependency=id=>{runDependencies++;Module["monitorRunDependencies"]?.(runDependencies)};var noExitRuntime=true;var syscallGetVarargI=()=>{var ret=HEAP32[+SYSCALLS.varargs>>2];SYSCALLS.varargs+=4;return ret};var syscallGetVarargP=syscallGetVarargI;var PATH={isAbs:path=>path.charAt(0)==="/",splitPath:filename=>{var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:(parts,allowAboveRoot)=>{var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:path=>{var isAbsolute=PATH.isAbs(path),trailingSlash=path.slice(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(p=>!!p),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:path=>{var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.slice(0,-1)}return root+dir},basename:path=>path&&path.match(/([^\/]+|\/)\/*$/)[1],join:(...paths)=>PATH.normalize(paths.join("/")),join2:(l,r)=>PATH.normalize(l+"/"+r)};var initRandomFill=()=>{if(ENVIRONMENT_IS_NODE){var nodeCrypto=require("crypto");return view=>nodeCrypto.randomFillSync(view)}return view=>crypto.getRandomValues(view)};var randomFill=view=>{(randomFill=initRandomFill())(view)};var PATH_FS={resolve:(...args)=>{var resolvedPath="",resolvedAbsolute=false;for(var i=args.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?args[i]:FS.cwd();if(typeof path!="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=PATH.isAbs(path)}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(p=>!!p),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:(from,to)=>{from=PATH_FS.resolve(from).slice(1);to=PATH_FS.resolve(to).slice(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i{var maxIdx=idx+maxBytesToRead;if(ignoreNul)return maxIdx;while(heapOrArray[idx]&&!(idx>=maxIdx))++idx;return idx};var UTF8ArrayToString=(heapOrArray,idx=0,maxBytesToRead,ignoreNul)=>{var endPtr=findStringEnd(heapOrArray,idx,maxBytesToRead,ignoreNul);if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var FS_stdin_getChar_buffer=[];var lengthBytesUTF8=str=>{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63;i++}}heap[outIdx]=0;return outIdx-startIdx};var intArrayFromString=(stringy,dontAddNull,length)=>{var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array};var FS_stdin_getChar=()=>{if(!FS_stdin_getChar_buffer.length){var result=null;if(ENVIRONMENT_IS_NODE){var BUFSIZE=256;var buf=Buffer.alloc(BUFSIZE);var bytesRead=0;var fd=process.stdin.fd;try{bytesRead=fs.readSync(fd,buf,0,BUFSIZE)}catch(e){if(e.toString().includes("EOF"))bytesRead=0;else throw e}if(bytesRead>0){result=buf.slice(0,bytesRead).toString("utf-8")}}else if(globalThis.window?.prompt){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else{}if(!result){return null}FS_stdin_getChar_buffer=intArrayFromString(result,true)}return FS_stdin_getChar_buffer.shift()};var TTY={ttys:[],init(){},shutdown(){},register(dev,ops){TTY.ttys[dev]={input:[],output:[],ops};FS.registerDevice(dev,TTY.stream_ops)},stream_ops:{open(stream){var tty=TTY.ttys[stream.node.rdev];if(!tty){throw new FS.ErrnoError(43)}stream.tty=tty;stream.seekable=false},close(stream){stream.tty.ops.fsync(stream.tty)},fsync(stream){stream.tty.ops.fsync(stream.tty)},read(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.get_char){throw new FS.ErrnoError(60)}var bytesRead=0;for(var i=0;i0){out(UTF8ArrayToString(tty.output));tty.output=[]}},ioctl_tcgets(tty){return{c_iflag:25856,c_oflag:5,c_cflag:191,c_lflag:35387,c_cc:[3,28,127,21,4,0,1,0,17,19,26,0,18,15,23,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}},ioctl_tcsets(tty,optional_actions,data){return 0},ioctl_tiocgwinsz(tty){return[24,80]}},default_tty1_ops:{put_char(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output));tty.output=[]}else{if(val!=0)tty.output.push(val)}},fsync(tty){if(tty.output?.length>0){err(UTF8ArrayToString(tty.output));tty.output=[]}}}};var mmapAlloc=size=>{abort()};var MEMFS={ops_table:null,mount(mount){return MEMFS.createNode(null,"/",16895,0)},createNode(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}MEMFS.ops_table||={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}};var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.atime=node.mtime=node.ctime=Date.now();if(parent){parent.contents[name]=node;parent.atime=parent.mtime=parent.ctime=node.atime}return node},getFileDataAsTypedArray(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0)},resizeFileStorage(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0}else{var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize}},node_ops:{getattr(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.atime);attr.mtime=new Date(node.mtime);attr.ctime=new Date(node.ctime);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr(node,attr){for(const key of["mode","atime","mtime","ctime"]){if(attr[key]!=null){node[key]=attr[key]}}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup(parent,name){if(!MEMFS.doesNotExistError){MEMFS.doesNotExistError=new FS.ErrnoError(44);MEMFS.doesNotExistError.stack=""}throw MEMFS.doesNotExistError},mknod(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename(old_node,new_dir,new_name){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){if(FS.isDir(old_node.mode)){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}FS.hashRemoveNode(new_node)}delete old_node.parent.contents[old_node.name];new_dir.contents[new_name]=old_node;old_node.name=new_name;new_dir.ctime=new_dir.mtime=old_node.parent.ctime=old_node.parent.mtime=Date.now()},unlink(parent,name){delete parent.contents[name];parent.ctime=parent.mtime=Date.now()},rmdir(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name];parent.ctime=parent.mtime=Date.now()},readdir(node){return[".","..",...Object.keys(node.contents)]},symlink(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length{var flagModes={r:0,"r+":2,w:512|64|1,"w+":512|64|2,a:1024|64|1,"a+":1024|64|2};var flags=flagModes[str];if(typeof flags=="undefined"){throw new Error(`Unknown file open mode: ${str}`)}return flags};var FS_getMode=(canRead,canWrite)=>{var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode};var asyncLoad=async url=>{var arrayBuffer=await readAsync(url);return new Uint8Array(arrayBuffer)};var FS_createDataFile=(...args)=>FS.createDataFile(...args);var getUniqueRunDependency=id=>id;var preloadPlugins=[];var FS_handledByPreloadPlugin=async(byteArray,fullname)=>{if(typeof Browser!="undefined")Browser.init();for(var plugin of preloadPlugins){if(plugin["canHandle"](fullname)){return plugin["handle"](byteArray,fullname)}}return byteArray};var FS_preloadFile=async(parent,name,url,canRead,canWrite,dontCreateFile,canOwn,preFinish)=>{var fullname=name?PATH_FS.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency(`cp ${fullname}`);addRunDependency(dep);try{var byteArray=url;if(typeof url=="string"){byteArray=await asyncLoad(url)}byteArray=await FS_handledByPreloadPlugin(byteArray,fullname);preFinish?.();if(!dontCreateFile){FS_createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}}finally{removeRunDependency(dep)}};var FS_createPreloadedFile=(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish)=>{FS_preloadFile(parent,name,url,canRead,canWrite,dontCreateFile,canOwn,preFinish).then(onload).catch(onerror)};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,filesystems:null,syncFSRequests:0,readFiles:{},ErrnoError:class{name="ErrnoError";constructor(errno){this.errno=errno}},FSStream:class{shared={};get object(){return this.node}set object(val){this.node=val}get isRead(){return(this.flags&2097155)!==1}get isWrite(){return(this.flags&2097155)!==0}get isAppend(){return this.flags&1024}get flags(){return this.shared.flags}set flags(val){this.shared.flags=val}get position(){return this.shared.position}set position(val){this.shared.position=val}},FSNode:class{node_ops={};stream_ops={};readMode=292|73;writeMode=146;mounted=null;constructor(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.rdev=rdev;this.atime=this.mtime=this.ctime=Date.now()}get read(){return(this.mode&this.readMode)===this.readMode}set read(val){val?this.mode|=this.readMode:this.mode&=~this.readMode}get write(){return(this.mode&this.writeMode)===this.writeMode}set write(val){val?this.mode|=this.writeMode:this.mode&=~this.writeMode}get isFolder(){return FS.isDir(this.mode)}get isDevice(){return FS.isChrdev(this.mode)}},lookupPath(path,opts={}){if(!path){throw new FS.ErrnoError(44)}opts.follow_mount??=true;if(!PATH.isAbs(path)){path=FS.cwd()+"/"+path}linkloop:for(var nlinks=0;nlinks<40;nlinks++){var parts=path.split("/").filter(p=>!!p);var current=FS.root;var current_path="/";for(var i=0;i>>0)%FS.nameTable.length},hashAddNode(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode(parent,name,mode,rdev){var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode(node){FS.hashRemoveNode(node)},isRoot(node){return node===node.parent},isMountpoint(node){return!!node.mounted},isFile(mode){return(mode&61440)===32768},isDir(mode){return(mode&61440)===16384},isLink(mode){return(mode&61440)===40960},isChrdev(mode){return(mode&61440)===8192},isBlkdev(mode){return(mode&61440)===24576},isFIFO(mode){return(mode&61440)===4096},isSocket(mode){return(mode&49152)===49152},flagsToPermissionString(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions(node,perms){if(FS.ignorePermissions){return 0}if(perms.includes("r")&&!(node.mode&292)){return 2}else if(perms.includes("w")&&!(node.mode&146)){return 2}else if(perms.includes("x")&&!(node.mode&73)){return 2}return 0},mayLookup(dir){if(!FS.isDir(dir.mode))return 54;var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate(dir,name){if(!FS.isDir(dir.mode)){return 54}try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&(512|64)){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},checkOpExists(op,err){if(!op){throw new FS.ErrnoError(err)}return op},MAX_OPEN_FDS:4096,nextfd(){for(var fd=0;fd<=FS.MAX_OPEN_FDS;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStreamChecked(fd){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}return stream},getStream:fd=>FS.streams[fd],createStream(stream,fd=-1){stream=Object.assign(new FS.FSStream,stream);if(fd==-1){fd=FS.nextfd()}stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream(fd){FS.streams[fd]=null},dupStream(origStream,fd=-1){var stream=FS.createStream(origStream,fd);stream.stream_ops?.dup?.(stream);return stream},doSetAttr(stream,node,attr){var setattr=stream?.stream_ops.setattr;var arg=setattr?stream:node;setattr??=node.node_ops.setattr;FS.checkOpExists(setattr,63);setattr(arg,attr)},chrdev_stream_ops:{open(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;stream.stream_ops.open?.(stream)},llseek(){throw new FS.ErrnoError(70)}},major:dev=>dev>>8,minor:dev=>dev&255,makedev:(ma,mi)=>ma<<8|mi,registerDevice(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:dev=>FS.devices[dev],getMounts(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push(...m.mounts)}return mounts},syncfs(populate,callback){if(typeof populate=="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`)}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}for(var mount of mounts){if(mount.type.syncfs){mount.type.syncfs(mount,populate,done)}else{done(null)}}},mount(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type,opts,mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);for(var[hash,current]of Object.entries(FS.nameTable)){while(current){var next=current.name_next;if(mounts.includes(current.mount)){FS.destroyNode(current)}current=next}}node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup(parent,name){return parent.node_ops.lookup(parent,name)},mknod(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name){throw new FS.ErrnoError(28)}if(name==="."||name===".."){throw new FS.ErrnoError(20)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},statfs(path){return FS.statfsNode(FS.lookupPath(path,{follow:true}).node)},statfsStream(stream){return FS.statfsNode(stream.node)},statfsNode(node){var rtn={bsize:4096,frsize:4096,blocks:1e6,bfree:5e5,bavail:5e5,files:FS.nextInode,ffree:FS.nextInode-1,fsid:42,flags:2,namelen:255};if(node.node_ops.statfs){Object.assign(rtn,node.node_ops.statfs(node.mount.opts.root))}return rtn},create(path,mode=438){mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir(path,mode=511){mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree(path,mode){var dirs=path.split("/");var d="";for(var dir of dirs){if(!dir)continue;if(d||PATH.isAbs(path))d+="/";d+=dir;try{FS.mkdir(d,mode)}catch(e){if(e.errno!=20)throw e}}},mkdev(path,mode,dev){if(typeof dev=="undefined"){dev=mode;mode=438}mode|=8192;return FS.mknod(path,mode,dev)},symlink(oldpath,newpath){if(!PATH_FS.resolve(oldpath)){throw new FS.ErrnoError(44)}var lookup=FS.lookupPath(newpath,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var newname=PATH.basename(newpath);var errCode=FS.mayCreate(parent,newname);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.symlink){throw new FS.ErrnoError(63)}return parent.node_ops.symlink(parent,newname,oldpath)},rename(old_path,new_path){var old_dirname=PATH.dirname(old_path);var new_dirname=PATH.dirname(new_path);var old_name=PATH.basename(old_path);var new_name=PATH.basename(new_path);var lookup,old_dir,new_dir;lookup=FS.lookupPath(old_path,{parent:true});old_dir=lookup.node;lookup=FS.lookupPath(new_path,{parent:true});new_dir=lookup.node;if(!old_dir||!new_dir)throw new FS.ErrnoError(44);if(old_dir.mount!==new_dir.mount){throw new FS.ErrnoError(75)}var old_node=FS.lookupNode(old_dir,old_name);var relative=PATH_FS.relative(old_path,new_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(28)}relative=PATH_FS.relative(new_path,old_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(55)}var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(old_node===new_node){return}var isdir=FS.isDir(old_node.mode);var errCode=FS.mayDelete(old_dir,old_name,isdir);if(errCode){throw new FS.ErrnoError(errCode)}errCode=new_node?FS.mayDelete(new_dir,new_name,isdir):FS.mayCreate(new_dir,new_name);if(errCode){throw new FS.ErrnoError(errCode)}if(!old_dir.node_ops.rename){throw new FS.ErrnoError(63)}if(FS.isMountpoint(old_node)||new_node&&FS.isMountpoint(new_node)){throw new FS.ErrnoError(10)}if(new_dir!==old_dir){errCode=FS.nodePermissions(old_dir,"w");if(errCode){throw new FS.ErrnoError(errCode)}}FS.hashRemoveNode(old_node);try{old_dir.node_ops.rename(old_node,new_dir,new_name);old_node.parent=new_dir}catch(e){throw e}finally{FS.hashAddNode(old_node)}},rmdir(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,true);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.rmdir){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.rmdir(parent,name);FS.destroyNode(node)},readdir(path){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;var readdir=FS.checkOpExists(node.node_ops.readdir,54);return readdir(node)},unlink(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,false);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.unlink){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.unlink(parent,name);FS.destroyNode(node)},readlink(path){var lookup=FS.lookupPath(path);var link=lookup.node;if(!link){throw new FS.ErrnoError(44)}if(!link.node_ops.readlink){throw new FS.ErrnoError(28)}return link.node_ops.readlink(link)},stat(path,dontFollow){var lookup=FS.lookupPath(path,{follow:!dontFollow});var node=lookup.node;var getattr=FS.checkOpExists(node.node_ops.getattr,63);return getattr(node)},fstat(fd){var stream=FS.getStreamChecked(fd);var node=stream.node;var getattr=stream.stream_ops.getattr;var arg=getattr?stream:node;getattr??=node.node_ops.getattr;FS.checkOpExists(getattr,63);return getattr(arg)},lstat(path){return FS.stat(path,true)},doChmod(stream,node,mode,dontFollow){FS.doSetAttr(stream,node,{mode:mode&4095|node.mode&~4095,ctime:Date.now(),dontFollow})},chmod(path,mode,dontFollow){var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}FS.doChmod(null,node,mode,dontFollow)},lchmod(path,mode){FS.chmod(path,mode,true)},fchmod(fd,mode){var stream=FS.getStreamChecked(fd);FS.doChmod(stream,stream.node,mode,false)},doChown(stream,node,dontFollow){FS.doSetAttr(stream,node,{timestamp:Date.now(),dontFollow})},chown(path,uid,gid,dontFollow){var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}FS.doChown(null,node,dontFollow)},lchown(path,uid,gid){FS.chown(path,uid,gid,true)},fchown(fd,uid,gid){var stream=FS.getStreamChecked(fd);FS.doChown(stream,stream.node,false)},doTruncate(stream,node,len){if(FS.isDir(node.mode)){throw new FS.ErrnoError(31)}if(!FS.isFile(node.mode)){throw new FS.ErrnoError(28)}var errCode=FS.nodePermissions(node,"w");if(errCode){throw new FS.ErrnoError(errCode)}FS.doSetAttr(stream,node,{size:len,timestamp:Date.now()})},truncate(path,len){if(len<0){throw new FS.ErrnoError(28)}var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:true});node=lookup.node}else{node=path}FS.doTruncate(null,node,len)},ftruncate(fd,len){var stream=FS.getStreamChecked(fd);if(len<0||(stream.flags&2097155)===0){throw new FS.ErrnoError(28)}FS.doTruncate(stream,stream.node,len)},utime(path,atime,mtime){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;var setattr=FS.checkOpExists(node.node_ops.setattr,63);setattr(node,{atime,mtime})},open(path,flags,mode=438){if(path===""){throw new FS.ErrnoError(44)}flags=typeof flags=="string"?FS_modeStringToFlags(flags):flags;if(flags&64){mode=mode&4095|32768}else{mode=0}var node;var isDirPath;if(typeof path=="object"){node=path}else{isDirPath=path.endsWith("/");var lookup=FS.lookupPath(path,{follow:!(flags&131072),noent_okay:true});node=lookup.node;path=lookup.path}var created=false;if(flags&64){if(node){if(flags&128){throw new FS.ErrnoError(20)}}else if(isDirPath){throw new FS.ErrnoError(31)}else{node=FS.mknod(path,mode|511,0);created=true}}if(!node){throw new FS.ErrnoError(44)}if(FS.isChrdev(node.mode)){flags&=~512}if(flags&65536&&!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}if(!created){var errCode=FS.mayOpen(node,flags);if(errCode){throw new FS.ErrnoError(errCode)}}if(flags&512&&!created){FS.truncate(node,0)}flags&=~(128|512|131072);var stream=FS.createStream({node,path:FS.getPath(node),flags,seekable:true,position:0,stream_ops:node.stream_ops,ungotten:[],error:false});if(stream.stream_ops.open){stream.stream_ops.open(stream)}if(created){FS.chmod(node,mode&511)}if(Module["logReadFiles"]&&!(flags&1)){if(!(path in FS.readFiles)){FS.readFiles[path]=1}}return stream},close(stream){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(stream.getdents)stream.getdents=null;try{if(stream.stream_ops.close){stream.stream_ops.close(stream)}}catch(e){throw e}finally{FS.closeStream(stream.fd)}stream.fd=null},isClosed(stream){return stream.fd===null},llseek(stream,offset,whence){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(!stream.seekable||!stream.stream_ops.llseek){throw new FS.ErrnoError(70)}if(whence!=0&&whence!=1&&whence!=2){throw new FS.ErrnoError(28)}stream.position=stream.stream_ops.llseek(stream,offset,whence);stream.ungotten=[];return stream.position},read(stream,buffer,offset,length,position){if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.read){throw new FS.ErrnoError(28)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesRead=stream.stream_ops.read(stream,buffer,offset,length,position);if(!seeking)stream.position+=bytesRead;return bytesRead},write(stream,buffer,offset,length,position,canOwn){if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.write){throw new FS.ErrnoError(28)}if(stream.seekable&&stream.flags&1024){FS.llseek(stream,0,2)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesWritten=stream.stream_ops.write(stream,buffer,offset,length,position,canOwn);if(!seeking)stream.position+=bytesWritten;return bytesWritten},mmap(stream,length,position,prot,flags){if((prot&2)!==0&&(flags&2)===0&&(stream.flags&2097155)!==2){throw new FS.ErrnoError(2)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(2)}if(!stream.stream_ops.mmap){throw new FS.ErrnoError(43)}if(!length){throw new FS.ErrnoError(28)}return stream.stream_ops.mmap(stream,length,position,prot,flags)},msync(stream,buffer,offset,length,mmapFlags){if(!stream.stream_ops.msync){return 0}return stream.stream_ops.msync(stream,buffer,offset,length,mmapFlags)},ioctl(stream,cmd,arg){if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(59)}return stream.stream_ops.ioctl(stream,cmd,arg)},readFile(path,opts={}){opts.flags=opts.flags||0;opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){abort(`Invalid encoding type "${opts.encoding}"`)}var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){buf=UTF8ArrayToString(buf)}FS.close(stream);return buf},writeFile(path,data,opts={}){opts.flags=opts.flags||577;var stream=FS.open(path,opts.flags,opts.mode);if(typeof data=="string"){data=new Uint8Array(intArrayFromString(data,true))}if(ArrayBuffer.isView(data)){FS.write(stream,data,0,data.byteLength,undefined,opts.canOwn)}else{abort("Unsupported data type")}FS.close(stream)},cwd:()=>FS.currentPath,chdir(path){var lookup=FS.lookupPath(path,{follow:true});if(lookup.node===null){throw new FS.ErrnoError(44)}if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(54)}var errCode=FS.nodePermissions(lookup.node,"x");if(errCode){throw new FS.ErrnoError(errCode)}FS.currentPath=lookup.path},createDefaultDirectories(){FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")},createDefaultDevices(){FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:()=>0,write:(stream,buffer,offset,length,pos)=>length,llseek:()=>0});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var randomBuffer=new Uint8Array(1024),randomLeft=0;var randomByte=()=>{if(randomLeft===0){randomFill(randomBuffer);randomLeft=randomBuffer.byteLength}return randomBuffer[--randomLeft]};FS.createDevice("/dev","random",randomByte);FS.createDevice("/dev","urandom",randomByte);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")},createSpecialDirectories(){FS.mkdir("/proc");var proc_self=FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount(){var node=FS.createNode(proc_self,"fd",16895,73);node.stream_ops={llseek:MEMFS.stream_ops.llseek};node.node_ops={lookup(parent,name){var fd=+name;var stream=FS.getStreamChecked(fd);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:()=>stream.path},id:fd+1};ret.parent=ret;return ret},readdir(){return Array.from(FS.streams.entries()).filter(([k,v])=>v).map(([k,v])=>k.toString())}};return node}},{},"/proc/self/fd")},createStandardStreams(input,output,error){if(input){FS.createDevice("/dev","stdin",input)}else{FS.symlink("/dev/tty","/dev/stdin")}if(output){FS.createDevice("/dev","stdout",null,output)}else{FS.symlink("/dev/tty","/dev/stdout")}if(error){FS.createDevice("/dev","stderr",null,error)}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin",0);var stdout=FS.open("/dev/stdout",1);var stderr=FS.open("/dev/stderr",1)},staticInit(){FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={MEMFS}},init(input,output,error){FS.initialized=true;input??=Module["stdin"];output??=Module["stdout"];error??=Module["stderr"];FS.createStandardStreams(input,output,error)},quit(){FS.initialized=false;for(var stream of FS.streams){if(stream){FS.close(stream)}}},findObject(path,dontResolveLastLink){var ret=FS.analyzePath(path,dontResolveLastLink);if(!ret.exists){return null}return ret.object},analyzePath(path,dontResolveLastLink){try{var lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});path=lookup.path}catch(e){}var ret={isRoot:false,exists:false,error:0,name:null,path:null,object:null,parentExists:false,parentPath:null,parentObject:null};try{var lookup=FS.lookupPath(path,{parent:true});ret.parentExists=true;ret.parentPath=lookup.path;ret.parentObject=lookup.node;ret.name=PATH.basename(path);lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});ret.exists=true;ret.path=lookup.path;ret.object=lookup.node;ret.name=lookup.node.name;ret.isRoot=lookup.path==="/"}catch(e){ret.error=e.errno}return ret},createPath(parent,path,canRead,canWrite){parent=typeof parent=="string"?parent:FS.getPath(parent);var parts=path.split("/").reverse();while(parts.length){var part=parts.pop();if(!part)continue;var current=PATH.join2(parent,part);try{FS.mkdir(current)}catch(e){if(e.errno!=20)throw e}parent=current}return current},createFile(parent,name,properties,canRead,canWrite){var path=PATH.join2(typeof parent=="string"?parent:FS.getPath(parent),name);var mode=FS_getMode(canRead,canWrite);return FS.create(path,mode)},createDataFile(parent,name,data,canRead,canWrite,canOwn){var path=name;if(parent){parent=typeof parent=="string"?parent:FS.getPath(parent);path=name?PATH.join2(parent,name):parent}var mode=FS_getMode(canRead,canWrite);var node=FS.create(path,mode);if(data){if(typeof data=="string"){var arr=new Array(data.length);for(var i=0,len=data.length;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]}setDataGetter(getter){this.getter=getter}cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))abort("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=(from,to)=>{if(from>to)abort("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)abort("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))abort("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}return intArrayFromString(xhr.responseText||"",true)};var lazyArray=this;lazyArray.setDataGetter(chunkNum=>{var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]=="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]=="undefined")abort("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true}get length(){if(!this.lengthKnown){this.cacheLength()}return this._length}get chunkSize(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}if(globalThis.XMLHttpRequest){if(!ENVIRONMENT_IS_WORKER)abort("Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc");var lazyArray=new LazyUint8Array;var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};for(const[key,fn]of Object.entries(node.stream_ops)){stream_ops[key]=(...args)=>{FS.forceLoadFile(node);return fn(...args)}}function writeChunks(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i{FS.forceLoadFile(node);return writeChunks(stream,buffer,offset,length,position)};stream_ops.mmap=(stream,length,position,prot,flags)=>{FS.forceLoadFile(node);var ptr=mmapAlloc(length);if(!ptr){throw new FS.ErrnoError(48)}writeChunks(stream,HEAP8,ptr,length,position);return{ptr,allocated:true}};node.stream_ops=stream_ops;return node}};var UTF8ToString=(ptr,maxBytesToRead,ignoreNul)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead,ignoreNul):"";var SYSCALLS={DEFAULT_POLLMASK:5,calculateAt(dirfd,path,allowEmpty){if(PATH.isAbs(path)){return path}var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=SYSCALLS.getStreamFromFD(dirfd);dir=dirstream.path}if(path.length==0){if(!allowEmpty){throw new FS.ErrnoError(44)}return dir}return dir+"/"+path},writeStat(buf,stat){HEAPU32[buf>>2]=stat.dev;HEAPU32[buf+4>>2]=stat.mode;HEAPU32[buf+8>>2]=stat.nlink;HEAPU32[buf+12>>2]=stat.uid;HEAPU32[buf+16>>2]=stat.gid;HEAPU32[buf+20>>2]=stat.rdev;HEAP64[buf+24>>3]=BigInt(stat.size);HEAP32[buf+32>>2]=4096;HEAP32[buf+36>>2]=stat.blocks;var atime=stat.atime.getTime();var mtime=stat.mtime.getTime();var ctime=stat.ctime.getTime();HEAP64[buf+40>>3]=BigInt(Math.floor(atime/1e3));HEAPU32[buf+48>>2]=atime%1e3*1e3*1e3;HEAP64[buf+56>>3]=BigInt(Math.floor(mtime/1e3));HEAPU32[buf+64>>2]=mtime%1e3*1e3*1e3;HEAP64[buf+72>>3]=BigInt(Math.floor(ctime/1e3));HEAPU32[buf+80>>2]=ctime%1e3*1e3*1e3;HEAP64[buf+88>>3]=BigInt(stat.ino);return 0},writeStatFs(buf,stats){HEAPU32[buf+4>>2]=stats.bsize;HEAPU32[buf+60>>2]=stats.bsize;HEAP64[buf+8>>3]=BigInt(stats.blocks);HEAP64[buf+16>>3]=BigInt(stats.bfree);HEAP64[buf+24>>3]=BigInt(stats.bavail);HEAP64[buf+32>>3]=BigInt(stats.files);HEAP64[buf+40>>3]=BigInt(stats.ffree);HEAPU32[buf+48>>2]=stats.fsid;HEAPU32[buf+64>>2]=stats.flags;HEAPU32[buf+56>>2]=stats.namelen},doMsync(addr,stream,len,flags,offset){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}if(flags&2){return 0}var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},getStreamFromFD(fd){var stream=FS.getStreamChecked(fd);return stream},varargs:undefined,getStr(ptr){var ret=UTF8ToString(ptr);return ret}};function ___syscall_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=syscallGetVarargI();if(arg<0){return-28}while(FS.streams[arg]){arg++}var newStream;newStream=FS.dupStream(stream,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=syscallGetVarargI();stream.flags|=arg;return 0}case 12:{var arg=syscallGetVarargP();var offset=0;HEAP16[arg+offset>>1]=2;return 0}case 13:case 14:return 0}return-28}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:{if(!stream.tty)return-59;return 0}case 21505:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcgets){var termios=stream.tty.ops.ioctl_tcgets(stream);var argp=syscallGetVarargP();HEAP32[argp>>2]=termios.c_iflag||0;HEAP32[argp+4>>2]=termios.c_oflag||0;HEAP32[argp+8>>2]=termios.c_cflag||0;HEAP32[argp+12>>2]=termios.c_lflag||0;for(var i=0;i<32;i++){HEAP8[argp+i+17]=termios.c_cc[i]||0}return 0}return 0}case 21510:case 21511:case 21512:{if(!stream.tty)return-59;return 0}case 21506:case 21507:case 21508:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcsets){var argp=syscallGetVarargP();var c_iflag=HEAP32[argp>>2];var c_oflag=HEAP32[argp+4>>2];var c_cflag=HEAP32[argp+8>>2];var c_lflag=HEAP32[argp+12>>2];var c_cc=[];for(var i=0;i<32;i++){c_cc.push(HEAP8[argp+i+17])}return stream.tty.ops.ioctl_tcsets(stream.tty,op,{c_iflag,c_oflag,c_cflag,c_lflag,c_cc})}return 0}case 21519:{if(!stream.tty)return-59;var argp=syscallGetVarargP();HEAP32[argp>>2]=0;return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21537:case 21531:{var argp=syscallGetVarargP();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tiocgwinsz){var winsize=stream.tty.ops.ioctl_tiocgwinsz(stream.tty);var argp=syscallGetVarargP();HEAP16[argp>>1]=winsize[0];HEAP16[argp+2>>1]=winsize[1]}return 0}case 21524:{if(!stream.tty)return-59;return 0}case 21515:{if(!stream.tty)return-59;return 0}default:return-28}}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_openat(dirfd,path,flags,varargs){SYSCALLS.varargs=varargs;try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);var mode=varargs?syscallGetVarargI():0;return FS.open(path,flags,mode).fd}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}var getHeapMax=()=>2147483648;var alignMemory=(size,alignment)=>Math.ceil(size/alignment)*alignment;var growMemory=size=>{var oldHeapSize=wasmMemory.buffer.byteLength;var pages=(size-oldHeapSize+65535)/65536|0;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignMemory(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false};var runtimeKeepaliveCounter=0;var keepRuntimeAlive=()=>noExitRuntime||runtimeKeepaliveCounter>0;var _proc_exit=code=>{EXITSTATUS=code;if(!keepRuntimeAlive()){Module["onExit"]?.(code);ABORT=true}quit_(code,new ExitStatus(code))};var exitJS=(status,implicit)=>{EXITSTATUS=status;_proc_exit(status)};var _exit=exitJS;function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doReadv=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var INT53_MAX=9007199254740992;var INT53_MIN=-9007199254740992;var bigintToI53Checked=num=>numINT53_MAX?NaN:Number(num);function _fd_seek(fd,offset,whence,newOffset){offset=bigintToI53Checked(offset);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);FS.llseek(stream,offset,whence);HEAP64[newOffset>>3]=BigInt(stream.position);if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doWritev=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var handleException=e=>{if(e instanceof ExitStatus||e=="unwind"){return EXITSTATUS}quit_(1,e)};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var stackAlloc=sz=>__emscripten_stack_alloc(sz);var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};FS.createPreloadedFile=FS_createPreloadedFile;FS.preloadFile=FS_preloadFile;FS.staticInit();{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["preloadPlugins"])preloadPlugins=Module["preloadPlugins"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].shift()()}}}Module["callMain"]=callMain;Module["FS"]=FS;var _main,__emscripten_stack_alloc,memory,__indirect_function_table,wasmMemory;function assignWasmExports(wasmExports){_main=Module["_main"]=wasmExports["l"];__emscripten_stack_alloc=wasmExports["m"];memory=wasmMemory=wasmExports["j"];__indirect_function_table=wasmExports["__indirect_function_table"]}var wasmImports={d:___syscall_fcntl64,h:___syscall_ioctl,i:___syscall_openat,e:_emscripten_resize_heap,a:_exit,b:_fd_close,g:_fd_read,f:_fd_seek,c:_fd_write};function callMain(args=[]){var entryFunction=_main;args.unshift(thisProgram);var argc=args.length;var argv=stackAlloc((argc+1)*4);var argv_ptr=argv;for(var arg of args){HEAPU32[argv_ptr>>2]=stringToUTF8OnStack(arg);argv_ptr+=4}HEAPU32[argv_ptr>>2]=0;try{var ret=entryFunction(argc,argv);exitJS(ret,true);return ret}catch(e){return handleException(e)}}function run(args=arguments_){if(runDependencies>0){dependenciesFulfilled=run;return}preRun();if(runDependencies>0){dependenciesFulfilled=run;return}function doRun(){Module["calledRun"]=true;if(ABORT)return;initRuntime();preMain();Module["onRuntimeInitialized"]?.();var noInitialRun=Module["noInitialRun"]||true;if(!noInitialRun)callMain(args);postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>Module["setStatus"](""),1);doRun()},1)}else{doRun()}}var wasmExports;createWasm();run(); 2 | --------------------------------------------------------------------------------