Repository: electron/fiddle Branch: main Commit: 5c625b0da70f Files: 370 Total size: 4.0 MB Directory structure: gitextract_zj1ox0h2/ ├── .eslintrc.js ├── .gitattributes ├── .github/ │ ├── CODEOWNERS │ ├── dependabot.yml │ └── workflows/ │ ├── add-to-project.yml │ ├── build.yml │ ├── check-download-links.yml │ ├── ci.yml │ ├── coveralls.yml │ ├── release.yml │ ├── semantic.yml │ └── test.yml ├── .gitignore ├── .husky/ │ ├── .gitignore │ └── pre-commit ├── .markdownlint.json ├── .nvmrc ├── .prettierrc.js ├── .stylelintrc ├── .yarn/ │ └── releases/ │ └── yarn-4.10.3.cjs ├── .yarnrc.yml ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── SECURITY.md ├── assets/ │ └── icons/ │ └── fiddle.icns ├── forge.config.ts ├── package.json ├── rtl-spec/ │ ├── components/ │ │ ├── commands-address-bar.spec.tsx │ │ ├── commands-bisect.spec.tsx │ │ ├── commands-publish-button.spec.tsx │ │ ├── commands-runner.spec.tsx │ │ ├── commands-version-chooser.spec.tsx │ │ ├── editor.spec.tsx │ │ ├── editors-non-ideal-state.spec.tsx │ │ ├── editors-toolbar-button.spec.tsx │ │ ├── editors.spec.tsx │ │ ├── history.spec.tsx │ │ ├── sidebar-file-tree.spec.tsx │ │ ├── tour-welcome.spec.tsx │ │ ├── tour.spec.tsx │ │ └── version-select.spec.tsx │ └── test-utils/ │ ├── renderClassComponentWithInstanceRef.ts │ └── versions.ts ├── src/ │ ├── ambient.d.ts │ ├── constants.ts │ ├── interfaces.ts │ ├── ipc-events.ts │ ├── less/ │ │ ├── blueprint.less │ │ ├── components/ │ │ │ ├── commands.less │ │ │ ├── dialogs.less │ │ │ ├── editors.less │ │ │ ├── history.less │ │ │ ├── mosaic.less │ │ │ ├── output.less │ │ │ ├── settings-electron.less │ │ │ ├── settings.less │ │ │ ├── show-me.less │ │ │ ├── sidebar.less │ │ │ ├── tour.less │ │ │ └── version-select.less │ │ ├── container.less │ │ ├── main.less │ │ ├── mosaic-vendor.less │ │ ├── root.less │ │ └── variables.less │ ├── main/ │ │ ├── about-panel.ts │ │ ├── command-line.ts │ │ ├── constants.ts │ │ ├── content.ts │ │ ├── context-menu.ts │ │ ├── devtools.ts │ │ ├── dialogs.ts │ │ ├── electron-types.ts │ │ ├── fiddle-core.ts │ │ ├── files.ts │ │ ├── first-run.ts │ │ ├── ipc.ts │ │ ├── main.ts │ │ ├── menu.ts │ │ ├── npm.ts │ │ ├── protocol.ts │ │ ├── sentry.ts │ │ ├── squirrel.ts │ │ ├── templates.ts │ │ ├── themes.ts │ │ ├── update.ts │ │ ├── utils/ │ │ │ ├── check-first-run.ts │ │ │ ├── devmode.ts │ │ │ ├── exec.ts │ │ │ ├── get-files.ts │ │ │ ├── get-project-name.ts │ │ │ ├── get-username.ts │ │ │ └── read-fiddle.ts │ │ ├── versions.ts │ │ └── windows.ts │ ├── preload/ │ │ └── preload.ts │ ├── renderer/ │ │ ├── app.tsx │ │ ├── bisect.ts │ │ ├── components/ │ │ │ ├── TestIdContainer.tsx │ │ │ ├── commands-action-button.tsx │ │ │ ├── commands-address-bar.tsx │ │ │ ├── commands-bisect.tsx │ │ │ ├── commands-runner.tsx │ │ │ ├── commands-version-chooser.tsx │ │ │ ├── commands.tsx │ │ │ ├── dialog-add-theme.tsx │ │ │ ├── dialog-add-version.tsx │ │ │ ├── dialog-bisect.tsx │ │ │ ├── dialog-generic.tsx │ │ │ ├── dialog-token.tsx │ │ │ ├── dialogs.tsx │ │ │ ├── editor.tsx │ │ │ ├── editors-non-ideal-state.tsx │ │ │ ├── editors-toolbar-button.tsx │ │ │ ├── editors.tsx │ │ │ ├── header.tsx │ │ │ ├── history-wrapper.tsx │ │ │ ├── history.tsx │ │ │ ├── output-editors-wrapper.tsx │ │ │ ├── output.tsx │ │ │ ├── outputs.tsx │ │ │ ├── settings-credits.tsx │ │ │ ├── settings-electron.tsx │ │ │ ├── settings-execution.tsx │ │ │ ├── settings-general-appearance.tsx │ │ │ ├── settings-general-block-accelerators.tsx │ │ │ ├── settings-general-console.tsx │ │ │ ├── settings-general-font.tsx │ │ │ ├── settings-general-gist.tsx │ │ │ ├── settings-general-github.tsx │ │ │ ├── settings-general-mirror.tsx │ │ │ ├── settings-general.tsx │ │ │ ├── settings.tsx │ │ │ ├── sidebar-file-tree.tsx │ │ │ ├── sidebar-package-manager.tsx │ │ │ ├── sidebar.tsx │ │ │ ├── tour-welcome.tsx │ │ │ ├── tour.tsx │ │ │ └── version-select.tsx │ │ ├── constants.ts │ │ ├── editor-mosaic.ts │ │ ├── electron-types.ts │ │ ├── file-manager.ts │ │ ├── main.tsx │ │ ├── mirror-constants.ts │ │ ├── npm-search.tsx │ │ ├── remote-loader.ts │ │ ├── runner.ts │ │ ├── sentry.ts │ │ ├── state.ts │ │ ├── task-runner.ts │ │ ├── themes.ts │ │ ├── transforms/ │ │ │ ├── dotfiles.ts │ │ │ └── forge.ts │ │ ├── utils/ │ │ │ ├── disable-download.ts │ │ │ ├── editor-utils.ts │ │ │ ├── electron-name.ts │ │ │ ├── get-package.ts │ │ │ ├── get-version-range.ts │ │ │ ├── highlight-text.tsx │ │ │ ├── js-path.ts │ │ │ ├── normalize-version.ts │ │ │ ├── octokit.ts │ │ │ ├── plural-maybe.ts │ │ │ ├── position-for-rect.ts │ │ │ ├── sort-versions.ts │ │ │ └── toggle-monaco.ts │ │ └── versions.ts │ ├── templates.ts │ ├── themes-defaults.ts │ └── utils/ │ ├── editor-utils.ts │ └── gist.ts ├── static/ │ ├── css/ │ │ └── .gitkeep │ ├── electron-quick-start/ │ │ ├── index.html │ │ ├── main.js │ │ ├── preload.js │ │ └── renderer.js │ ├── entitlements.plist │ ├── index.html │ └── show-me/ │ ├── app/ │ │ └── main.js │ ├── autoupdater/ │ │ └── main.js │ ├── browserview/ │ │ └── main.js │ ├── browserwindow/ │ │ ├── index.html │ │ └── main.js │ ├── clipboard/ │ │ ├── index.html │ │ ├── main.js │ │ ├── preload.js │ │ └── renderer.js │ ├── contenttracing/ │ │ └── main.js │ ├── cookies/ │ │ └── main.js │ ├── crashreporter/ │ │ ├── index.html │ │ ├── main.js │ │ └── preload.js │ ├── debugger/ │ │ ├── index.html │ │ └── main.js │ ├── desktopcapturer/ │ │ ├── index.html │ │ ├── main.js │ │ └── preload.js │ ├── dialog/ │ │ └── main.js │ ├── globalshortcut/ │ │ └── main.js │ ├── inapppurchase/ │ │ └── main.js │ ├── ipc/ │ │ ├── index.html │ │ ├── main.js │ │ └── preload.js │ ├── menu/ │ │ ├── index.html │ │ └── main.js │ ├── nativeimage/ │ │ └── main.js │ ├── net/ │ │ └── main.js │ ├── notification/ │ │ ├── index.html │ │ ├── main.js │ │ └── preload.js │ ├── powermonitor/ │ │ └── main.js │ ├── powersaveblocker/ │ │ └── main.js │ ├── screen/ │ │ ├── index.html │ │ ├── main.js │ │ └── preload.js │ ├── session/ │ │ └── main.js │ ├── shell/ │ │ ├── index.html │ │ ├── main.js │ │ └── preload.js │ ├── systempreferences/ │ │ └── main.js │ ├── touchbar/ │ │ ├── index.html │ │ └── main.js │ ├── tray/ │ │ └── main.js │ ├── utilityprocess/ │ │ ├── child.js │ │ └── main.js │ ├── webcontents/ │ │ ├── index.html │ │ └── main.js │ ├── webcontentsview/ │ │ └── main.js │ └── webframe/ │ ├── index.html │ ├── main.js │ └── preload.js ├── tests/ │ ├── fixtures/ │ │ └── node-types.json │ ├── globalSetup.ts │ ├── install-state-spec.ts │ ├── main/ │ │ ├── command-line-spec.ts │ │ ├── content-spec.ts │ │ ├── context-menu-spec.ts │ │ ├── devtools-spec.ts │ │ ├── dialogs-spec.ts │ │ ├── electron-types-spec.ts │ │ ├── fiddle-core-spec.ts │ │ ├── files-spec.ts │ │ ├── first-run-spec.ts │ │ ├── ipc-spec.ts │ │ ├── main-spec.ts │ │ ├── menu-spec.ts │ │ ├── npm-spec.ts │ │ ├── protocol-spec.ts │ │ ├── squirrel-spec.ts │ │ ├── templates-spec.ts │ │ ├── themes-spec.ts │ │ ├── update-spec.ts │ │ ├── utils/ │ │ │ ├── check-first-run-spec.ts │ │ │ ├── devmode-spec.ts │ │ │ ├── exec-spec.ts │ │ │ ├── get-project-name-spec.ts │ │ │ ├── get-username-spec.ts │ │ │ └── read-fiddle-spec.ts │ │ ├── versions-spec.ts │ │ └── windows-spec.ts │ ├── mocks/ │ │ ├── app.ts │ │ ├── bisector.ts │ │ ├── browser-window.ts │ │ ├── child-process.ts │ │ ├── editor-values.ts │ │ ├── electron-fiddle.ts │ │ ├── electron-types.ts │ │ ├── electron-versions.ts │ │ ├── electron.ts │ │ ├── fiddle-core.ts │ │ ├── file-manager.ts │ │ ├── mocks.ts │ │ ├── monaco.ts │ │ ├── npm-response-main.json │ │ ├── npm-response-nightlies.json │ │ ├── remote-loader.ts │ │ ├── runner.ts │ │ ├── state.ts │ │ ├── styles.ts │ │ ├── versions-mock.json │ │ └── web-contents.ts │ ├── preload/ │ │ └── preload-spec.ts │ ├── renderer/ │ │ ├── app-spec.tsx │ │ ├── bisect-spec.ts │ │ ├── components/ │ │ │ ├── __snapshots__/ │ │ │ │ ├── commands-spec.tsx.snap │ │ │ │ ├── dialog-add-theme-spec.tsx.snap │ │ │ │ ├── dialog-add-version-spec.tsx.snap │ │ │ │ ├── dialog-bisect-spec.tsx.snap │ │ │ │ ├── dialog-generic-spec.tsx.snap │ │ │ │ ├── dialog-token-spec.tsx.snap │ │ │ │ ├── header-spec.tsx.snap │ │ │ │ ├── settings-credits-spec.tsx.snap │ │ │ │ ├── settings-electron-spec.tsx.snap │ │ │ │ ├── settings-execution-spec.tsx.snap │ │ │ │ ├── settings-general-appearance-spec.tsx.snap │ │ │ │ ├── settings-general-block-accelerators-spec.tsx.snap │ │ │ │ ├── settings-general-console-spec.tsx.snap │ │ │ │ ├── settings-general-font-spec.tsx.snap │ │ │ │ ├── settings-general-gist-spec.tsx.snap │ │ │ │ ├── settings-general-github-spec.tsx.snap │ │ │ │ ├── settings-general-mirror-spec.tsx.snap │ │ │ │ ├── settings-general-spec.tsx.snap │ │ │ │ ├── settings-spec.tsx.snap │ │ │ │ └── sidebar-package-manager-spec.tsx.snap │ │ │ ├── commands-spec.tsx │ │ │ ├── dialog-add-theme-spec.tsx │ │ │ ├── dialog-add-version-spec.tsx │ │ │ ├── dialog-bisect-spec.tsx │ │ │ ├── dialog-generic-spec.tsx │ │ │ ├── dialog-token-spec.tsx │ │ │ ├── dialogs-spec.tsx │ │ │ ├── header-spec.tsx │ │ │ ├── output-spec.tsx │ │ │ ├── settings-credits-spec.tsx │ │ │ ├── settings-electron-spec.tsx │ │ │ ├── settings-execution-spec.tsx │ │ │ ├── settings-general-appearance-spec.tsx │ │ │ ├── settings-general-block-accelerators-spec.tsx │ │ │ ├── settings-general-console-spec.tsx │ │ │ ├── settings-general-font-spec.tsx │ │ │ ├── settings-general-gist-spec.tsx │ │ │ ├── settings-general-github-spec.tsx │ │ │ ├── settings-general-mirror-spec.tsx │ │ │ ├── settings-general-spec.tsx │ │ │ ├── settings-spec.tsx │ │ │ └── sidebar-package-manager-spec.tsx │ │ ├── editor-mosaic-spec.ts │ │ ├── electron-types-spec.ts │ │ ├── file-manager-spec.ts │ │ ├── npm-search-spec.ts │ │ ├── remote-loader-spec.ts │ │ ├── runner-spec.tsx │ │ ├── state-spec.ts │ │ ├── task-runner-spec.tsx │ │ ├── themes-spec.tsx │ │ ├── utils/ │ │ │ ├── disable-download-spec.ts │ │ │ ├── editor-utils-spec.ts │ │ │ ├── electron-name-spec.ts │ │ │ ├── get-package-spec.ts │ │ │ ├── get-version-range-spec.ts │ │ │ ├── highlight-text-spec.ts │ │ │ ├── js-path-spec.ts │ │ │ ├── normalize-version-spec.ts │ │ │ ├── plural-maybe-spec.ts │ │ │ ├── position-for-rect-spec.ts │ │ │ ├── sort-versions-spec.ts │ │ │ └── toggle-monaco-spec.ts │ │ └── versions-spec.ts │ ├── setup.ts │ ├── themes-defaults-spec.ts │ ├── transforms/ │ │ ├── dotfiles-spec.ts │ │ └── forge-spec.ts │ ├── utils/ │ │ ├── editor-utils-spec.ts │ │ └── gist-spec.ts │ └── utils.ts ├── tools/ │ ├── add-macos-cert.sh │ ├── certs/ │ │ ├── apple.cer │ │ ├── dac.cer │ │ └── requirements.txt │ ├── clean-webpack.ts │ ├── contributors.ts │ ├── fetch-releases.ts │ └── webpack/ │ ├── common/ │ │ ├── webpack.plugins.ts │ │ └── webpack.rules.ts │ ├── webpack.main.config.ts │ └── webpack.renderer.config.ts ├── tsconfig.json └── vitest.config.ts ================================================ FILE CONTENTS ================================================ ================================================ FILE: .eslintrc.js ================================================ const config = { parser: '@typescript-eslint/parser', // Specifies the ESLint parser parserOptions: { ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features sourceType: 'module', // Allows for the use of imports ecmaFeatures: { jsx: true, // Allows for the parsing of JSX }, }, settings: { react: { version: 'detect', // Tells eslint-plugin-react to automatically detect the version of React to use }, 'import/resolver': { // Allows eslint-plugin-import to detect resolved imports typescript: { project: './tsconfig.json' }, }, }, extends: [ 'plugin:react/recommended', // Uses the recommended rules from @eslint-plugin-react 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin 'plugin:import/recommended', // Used along with eslint-plugin-import to sort imports with recommended standards 'plugin:import/typescript', // To handle import order cases for typescript files 'prettier', ], plugins: ['import', 'eslint-plugin-tsdoc'], rules: { // Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs // e.g. "@typescript-eslint/explicit-function-return-type": "off", '@typescript-eslint/ban-ts-comment': 'off', '@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off', '@typescript-eslint/no-non-null-assertion': 'off', '@typescript-eslint/no-var-requires': 'off', '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }], 'sort-imports': [ 'error', { ignoreCase: false, ignoreDeclarationSort: true, // use eslint-plugin-import to handle this rule ignoreMemberSort: false, memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'], allowSeparatedGroups: true, }, ], 'import/no-named-as-default-member': 'off', 'import/namespace': 'off', 'import/order': [ 'error', { groups: [ 'builtin', // Built-in imports 'external', // External imports 'internal', // Absolute imports ['sibling', 'parent'], // Relative imports 'index', // index imports 'unknown', ], // Keep all the `react` imports at the top level pathGroups: [ { pattern: 'react', group: 'builtin', position: 'before' }, ], 'newlines-between': 'always', alphabetize: { // sort in ascending order order: 'asc', caseInsensitive: true, }, // Exclude `react` imports so that our custom pathGroups applies pathGroupsExcludedImportTypes: ['react'], }, ], 'tsdoc/syntax': 'error', }, overrides: [ { files: ['rtl-spec/**', 'tests/**'], rules: { 'tsdoc/syntax': 'off' } }, ], // the static folder is linted by standard ignorePatterns: ['/out', '/.webpack', '/coverage', '/static'], }; module.exports = config; ================================================ FILE: .gitattributes ================================================ * text=auto # Source code should always use LF as line ending *.d.ts text eol=lf *.js text eol=lf *.ts text eol=lf *.tsx text eol=lf ================================================ FILE: .github/CODEOWNERS ================================================ * @electron/wg-ecosystem @codebytere ================================================ FILE: .github/dependabot.yml ================================================ version: 2 updates: - package-ecosystem: "github-actions" directory: "/" schedule: interval: "daily" ================================================ FILE: .github/workflows/add-to-project.yml ================================================ name: Add to Ecosystem WG Project on: issues: types: - opened pull_request_target: types: - opened permissions: {} jobs: add-to-project: runs-on: ubuntu-latest steps: - name: Generate GitHub App token uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0 id: generate-token with: creds: ${{ secrets.ECOSYSTEM_ISSUE_TRIAGE_GH_APP_CREDS }} org: electron - name: Add to Project uses: dsanders11/project-actions/add-item@2134fe7cc71c58b7ae259c82a8e63c6058255678 # v1.7.0 with: field: Opened field-value: ${{ github.event.pull_request.created_at || github.event.issue.created_at }} project-number: 89 token: ${{ steps.generate-token.outputs.token }} ================================================ FILE: .github/workflows/build.yml ================================================ name: Build # Called from ci on: workflow_call: jobs: build: name: Build strategy: fail-fast: false matrix: os: - macos-15-intel - ubuntu-latest - windows-latest arch: - x64 include: - os: macos-latest arch: arm64 - os: ubuntu-24.04-arm arch: armv7l runs-on: '${{ matrix.os }}' steps: - run: git config --global core.autocrlf input - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Node.js uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version-file: .nvmrc cache: 'yarn' - name: Install dependencies run: yarn --immutable - run: yarn run contributors env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: yarn run electron-releases # Artifacts generated are unsigned - name: Run Forge makers run: yarn run make ================================================ FILE: .github/workflows/check-download-links.yml ================================================ name: Check Download Links 'on': workflow_dispatch: null schedule: - cron: 0 1 * * * permissions: {} jobs: check-download-links: name: Check Download Links runs-on: ubuntu-latest steps: - name: Install dependencies run: npm install hast-util-from-html@^2.0.1 hast-util-select@^6.0.2 - name: Check website download links uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd with: script: | const { fromHtml } = await import('${{ github.workspace }}/node_modules/hast-util-from-html/index.js'); const { selectAll } = await import('${{ github.workspace }}/node_modules/hast-util-select/index.js'); const tree = fromHtml(await fetch('https://www.electronjs.org/fiddle').then(resp => resp.text())); const links = selectAll('#downloads a[href^="https://github.com/electron/fiddle/releases/download/"]', tree); const statusCodes = new Map(); for (const { properties: { href } } of links) { const resp = await fetch(href, { method: 'HEAD' }); statusCodes.set(href, resp.status); } if (Array.from(statusCodes.values()).some(code => code === 404)) { process.exitCode = 1; core.summary.addHeading('🚨 Broken Download Links'); core.summary.addTable([ [ { data: 'Artifact', header: true }, { data: 'Status', header: true }, ], ...Array.from(statusCodes.entries()) .map(([href, code]) => [ `${href.split('/').pop()}`, `
${code === 404 ? '❌' : '✅'}
`, ]), ]); } else { core.summary.addRaw('🎉 No broken links'); } await core.summary.write(); ================================================ FILE: .github/workflows/ci.yml ================================================ name: CI on: pull_request: push: branches: - main permissions: contents: read jobs: test: permissions: contents: read uses: ./.github/workflows/test.yml build: permissions: contents: read uses: ./.github/workflows/build.yml gha-done: name: GitHub Actions Completed runs-on: ubuntu-latest needs: [test, build] if: always() && !contains(needs.*.result, 'failure') steps: - name: GitHub Actions Jobs Done run: | echo "All GitHub Actions Jobs are done" ================================================ FILE: .github/workflows/coveralls.yml ================================================ name: Coveralls on: push: branches: - main pull_request: permissions: read-all jobs: test: name: Check Coverage runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Node.js uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version: 22.x cache: yarn - name: Install run: yarn --immutable - run: yarn run contributors env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: yarn run electron-releases - name: test run: yarn test:ci - name: Coveralls uses: coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e # v2.3.7 with: github-token: ${{ secrets.GITHUB_TOKEN }} ================================================ FILE: .github/workflows/release.yml ================================================ name: Release on: push: tags: - 'v*' permissions: {} jobs: build: name: Build strategy: fail-fast: false matrix: os: - macos-15-intel - ubuntu-latest - windows-latest arch: - x64 include: - os: macos-latest-xlarge arch: arm64 - os: ubuntu-24.04-arm arch: armv7l - os: ubuntu-24.04-arm arch: arm64 - os: windows-latest arch: ia32 runs-on: "${{ matrix.os }}" permissions: actions: write contents: read environment: release steps: - run: git config --global core.autocrlf input - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Node.js uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version-file: .nvmrc - run: yarn install --immutable - run: yarn run contributors env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: yarn run electron-releases - name: Install dependencies (Linux) if: ${{ startsWith(matrix.os, 'ubuntu-') }} run: sudo apt-get update && sudo apt install rpm squashfs-tools - name: Load certificates (macOS) if: ${{ startsWith(matrix.os, 'macos-') }} env: MACOS_CERT_P12: ${{ secrets.MACOS_CERT_P12 }} MACOS_CERT_PASSWORD: ${{ secrets.MACOS_CERT_PASSWORD }} run: chmod +x tools/add-macos-cert.sh && . ./tools/add-macos-cert.sh - name: Signing Manager Setup (Windows) if: ${{ startsWith(matrix.os, 'windows-') }} uses: digicert/ssm-code-signing@1d820463733701cf1484c7eb5d7d24a15ca2c454 # v1.2.1 - name: Write authentication cert to disk (Windows) if: ${{ startsWith(matrix.os, 'windows-') }} shell: bash env: SM_CLIENT_CERT_P12_BASE64: ${{ secrets.SM_CLIENT_CERT_P12_BASE64 }} run: | echo "$SM_CLIENT_CERT_P12_BASE64" | base64 --decode > /d/cert.p12 echo "SM_CLIENT_CERT_FILE=D:\\cert.p12" >> "$GITHUB_ENV" - name: Sync cert (Windows) if: ${{ startsWith(matrix.os, 'windows-') }} shell: cmd env: CERT_FINGERPRINT: ${{ secrets.CERT_FINGERPRINT }} KEYPAIR_ALIAS: ${{ secrets.KEYPAIR_ALIAS }} SM_API_KEY: ${{ secrets.SM_API_KEY }} SM_CLIENT_CERT_FILE: ${{ env.SM_CLIENT_CERT_FILE }} SM_CLIENT_CERT_PASSWORD: ${{ secrets.SM_CLIENT_CERT_PASSWORD }} SM_HOST: ${{ secrets.SM_HOST }} run: | smksp_registrar list smctl windows certsync --keypair-alias=%KEYPAIR_ALIAS% - name: Build (macOS) if: ${{ startsWith(matrix.os, 'macos-') }} env: APPLE_ID: ${{ secrets.APPLE_ID }} APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} run: yarn run publish --arch=${{ matrix.arch }} --dry-run - name: Build (Windows) if: ${{ startsWith(matrix.os, 'windows-') }} env: CERT_FINGERPRINT: ${{ secrets.CERT_FINGERPRINT }} KEYPAIR_ALIAS: ${{ secrets.KEYPAIR_ALIAS }} SM_API_KEY: ${{ secrets.SM_API_KEY }} SM_CLIENT_CERT_FILE: ${{ env.SM_CLIENT_CERT_FILE }} SM_CLIENT_CERT_PASSWORD: ${{ secrets.SM_CLIENT_CERT_PASSWORD }} SM_HOST: ${{ secrets.SM_HOST }} run: yarn run publish --arch=${{ matrix.arch }} --dry-run - name: Build (Linux) if: ${{ startsWith(matrix.os, 'ubuntu-') }} run: yarn run publish --arch=${{ matrix.arch }} --dry-run - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: build-artifacts-${{ matrix.os }}-${{ matrix.arch }} path: out - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: ${{ startsWith(matrix.os, 'ubuntu-') && matrix.arch == 'x64' }} with: name: webpack-source-maps path: .webpack include-hidden-files: true test: permissions: contents: read uses: ./.github/workflows/test.yml release: name: Release runs-on: ubuntu-latest needs: - build - test environment: release permissions: contents: read id-token: write steps: - run: git config --global core.autocrlf input - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Node.js uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version: '22.17.x' - run: yarn install --immutable - name: Download All Artifacts uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: out pattern: build-artifacts-* merge-multiple: true - name: Get GitHub app token id: secret-service uses: electron/secret-service-action@3476425e8b30555aac15b1b7096938e254b0e155 # v1.0.0 - name: Publish to GitHub env: GITHUB_TOKEN: ${{ fromJSON(steps.secret-service.outputs.secrets).GITHUB_TOKEN }} run: yarn run publish --from-dry-run notify-sentry-deploy: name: Notify Sentry Deploy runs-on: ubuntu-latest needs: release permissions: actions: read steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 persist-credentials: false - name: Download source maps artifact uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: webpack-source-maps path: .webpack - uses: getsentry/action-release@dab6548b3c03c4717878099e43782cf5be654289 # v3.5.0 env: SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_ORG: electronjs SENTRY_PROJECT: electron-fiddle with: environment: production release: Electron-Fiddle@${{ github.ref_name }} sourcemaps: ./.webpack/ url_prefix: '~/.webpack' ================================================ FILE: .github/workflows/semantic.yml ================================================ name: "Check Semantic Commit" on: pull_request: types: - opened - edited - synchronize permissions: contents: read jobs: main: permissions: pull-requests: read # for amannn/action-semantic-pull-request to analyze PRs statuses: write # for amannn/action-semantic-pull-request to mark status of analyzed PR name: Validate PR Title runs-on: ubuntu-latest steps: - name: semantic-pull-request uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: validateSingleCommit: false ================================================ FILE: .github/workflows/test.yml ================================================ # Called during ci and release name: Test on: workflow_call: jobs: test: name: Test strategy: fail-fast: false matrix: os: - macos-15-intel - ubuntu-latest - windows-latest arch: - x64 include: - os: macos-latest arch: arm64 - os: ubuntu-24.04-arm arch: armv7l runs-on: '${{ matrix.os }}' steps: - run: git config --global core.autocrlf input - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Node.js uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version-file: .nvmrc cache: 'yarn' - name: Install dependencies run: yarn --immutable - run: yarn run contributors env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: yarn run electron-releases - name: Lint and format run: yarn run lint && yarn run format - name: Test run: yarn tsc && yarn test:ci ================================================ FILE: .gitignore ================================================ .DS_Store .env .gclient_done **/.npmrc .tags* .vs/ .vscode/ *.log *.pyc *.sln *.swp *.VC.db *.VC.VC.opendb *.vcxproj *.vcxproj.filters *.vcxproj.user *.xcodeproj /.idea/ /external_binaries/ /out/ node_modules/ SHASUMS256.txt compile_commands.json .envrc .cache yarn-error.log *.p12 # Coverage coverage # Test report report.json # npm package /npm/dist /npm/path.txt # Electron Fiddle-Specific /static/contributors.json /static/css/root.css /static/releases.json # Webpack configurations .webpack # Yarn v4 .pnp.* .yarn/* !.yarn/patches !.yarn/plugins !.yarn/releases !.yarn/sdks !.yarn/versions ================================================ FILE: .husky/.gitignore ================================================ _ ================================================ FILE: .husky/pre-commit ================================================ yarn run lint-staged ================================================ FILE: .markdownlint.json ================================================ { "extends": "@electron/lint-roller/configs/markdownlint.json" } ================================================ FILE: .nvmrc ================================================ 22.17 ================================================ FILE: .prettierrc.js ================================================ module.exports = { trailingComma: "all", singleQuote: true, }; ================================================ FILE: .stylelintrc ================================================ { "extends": "stylelint-config-standard", "customSyntax": "postcss-less", "ignoreFiles": [ "./src/less/*-vendor.less" ], "rules": { "alpha-value-notation": null, "color-function-notation": null, "import-notation": "string" } } ================================================ FILE: .yarn/releases/yarn-4.10.3.cjs ================================================ #!/usr/bin/env node /* eslint-disable */ //prettier-ignore (()=>{var DGe=Object.create;var dU=Object.defineProperty;var PGe=Object.getOwnPropertyDescriptor;var bGe=Object.getOwnPropertyNames;var xGe=Object.getPrototypeOf,kGe=Object.prototype.hasOwnProperty;var Ie=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,r)=>(typeof require<"u"?require:e)[r]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var Ze=(t,e)=>()=>(t&&(e=t(t=0)),e);var _=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),Vt=(t,e)=>{for(var r in e)dU(t,r,{get:e[r],enumerable:!0})},QGe=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of bGe(e))!kGe.call(t,a)&&a!==r&&dU(t,a,{get:()=>e[a],enumerable:!(s=PGe(e,a))||s.enumerable});return t};var ut=(t,e,r)=>(r=t!=null?DGe(xGe(t)):{},QGe(e||!t||!t.__esModule?dU(r,"default",{value:t,enumerable:!0}):r,t));var fi={};Vt(fi,{SAFE_TIME:()=>HX,S_IFDIR:()=>Jb,S_IFLNK:()=>Kb,S_IFMT:()=>Mf,S_IFREG:()=>N2});var Mf,Jb,N2,Kb,HX,jX=Ze(()=>{Mf=61440,Jb=16384,N2=32768,Kb=40960,HX=456789e3});var or={};Vt(or,{EBADF:()=>Mo,EBUSY:()=>RGe,EEXIST:()=>MGe,EINVAL:()=>FGe,EISDIR:()=>LGe,ENOENT:()=>NGe,ENOSYS:()=>TGe,ENOTDIR:()=>OGe,ENOTEMPTY:()=>_Ge,EOPNOTSUPP:()=>HGe,EROFS:()=>UGe,ERR_DIR_CLOSED:()=>mU});function Cc(t,e){return Object.assign(new Error(`${t}: ${e}`),{code:t})}function RGe(t){return Cc("EBUSY",t)}function TGe(t,e){return Cc("ENOSYS",`${t}, ${e}`)}function FGe(t){return Cc("EINVAL",`invalid argument, ${t}`)}function Mo(t){return Cc("EBADF",`bad file descriptor, ${t}`)}function NGe(t){return Cc("ENOENT",`no such file or directory, ${t}`)}function OGe(t){return Cc("ENOTDIR",`not a directory, ${t}`)}function LGe(t){return Cc("EISDIR",`illegal operation on a directory, ${t}`)}function MGe(t){return Cc("EEXIST",`file already exists, ${t}`)}function UGe(t){return Cc("EROFS",`read-only filesystem, ${t}`)}function _Ge(t){return Cc("ENOTEMPTY",`directory not empty, ${t}`)}function HGe(t){return Cc("EOPNOTSUPP",`operation not supported, ${t}`)}function mU(){return Cc("ERR_DIR_CLOSED","Directory handle was closed")}var zb=Ze(()=>{});var $a={};Vt($a,{BigIntStatsEntry:()=>iE,DEFAULT_MODE:()=>IU,DirEntry:()=>yU,StatEntry:()=>nE,areStatsEqual:()=>CU,clearStats:()=>Zb,convertToBigIntStats:()=>GGe,makeDefaultStats:()=>GX,makeEmptyStats:()=>jGe});function GX(){return new nE}function jGe(){return Zb(GX())}function Zb(t){for(let e in t)if(Object.hasOwn(t,e)){let r=t[e];typeof r=="number"?t[e]=0:typeof r=="bigint"?t[e]=BigInt(0):EU.types.isDate(r)&&(t[e]=new Date(0))}return t}function GGe(t){let e=new iE;for(let r in t)if(Object.hasOwn(t,r)){let s=t[r];typeof s=="number"?e[r]=BigInt(s):EU.types.isDate(s)&&(e[r]=new Date(s))}return e.atimeNs=e.atimeMs*BigInt(1e6),e.mtimeNs=e.mtimeMs*BigInt(1e6),e.ctimeNs=e.ctimeMs*BigInt(1e6),e.birthtimeNs=e.birthtimeMs*BigInt(1e6),e}function CU(t,e){if(t.atimeMs!==e.atimeMs||t.birthtimeMs!==e.birthtimeMs||t.blksize!==e.blksize||t.blocks!==e.blocks||t.ctimeMs!==e.ctimeMs||t.dev!==e.dev||t.gid!==e.gid||t.ino!==e.ino||t.isBlockDevice()!==e.isBlockDevice()||t.isCharacterDevice()!==e.isCharacterDevice()||t.isDirectory()!==e.isDirectory()||t.isFIFO()!==e.isFIFO()||t.isFile()!==e.isFile()||t.isSocket()!==e.isSocket()||t.isSymbolicLink()!==e.isSymbolicLink()||t.mode!==e.mode||t.mtimeMs!==e.mtimeMs||t.nlink!==e.nlink||t.rdev!==e.rdev||t.size!==e.size||t.uid!==e.uid)return!1;let r=t,s=e;return!(r.atimeNs!==s.atimeNs||r.mtimeNs!==s.mtimeNs||r.ctimeNs!==s.ctimeNs||r.birthtimeNs!==s.birthtimeNs)}var EU,IU,yU,nE,iE,wU=Ze(()=>{EU=ut(Ie("util")),IU=33188,yU=class{constructor(){this.name="";this.path="";this.mode=0}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&61440)===16384}isFIFO(){return!1}isFile(){return(this.mode&61440)===32768}isSocket(){return!1}isSymbolicLink(){return(this.mode&61440)===40960}},nE=class{constructor(){this.uid=0;this.gid=0;this.size=0;this.blksize=0;this.atimeMs=0;this.mtimeMs=0;this.ctimeMs=0;this.birthtimeMs=0;this.atime=new Date(0);this.mtime=new Date(0);this.ctime=new Date(0);this.birthtime=new Date(0);this.dev=0;this.ino=0;this.mode=IU;this.nlink=1;this.rdev=0;this.blocks=1}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&61440)===16384}isFIFO(){return!1}isFile(){return(this.mode&61440)===32768}isSocket(){return!1}isSymbolicLink(){return(this.mode&61440)===40960}},iE=class{constructor(){this.uid=BigInt(0);this.gid=BigInt(0);this.size=BigInt(0);this.blksize=BigInt(0);this.atimeMs=BigInt(0);this.mtimeMs=BigInt(0);this.ctimeMs=BigInt(0);this.birthtimeMs=BigInt(0);this.atimeNs=BigInt(0);this.mtimeNs=BigInt(0);this.ctimeNs=BigInt(0);this.birthtimeNs=BigInt(0);this.atime=new Date(0);this.mtime=new Date(0);this.ctime=new Date(0);this.birthtime=new Date(0);this.dev=BigInt(0);this.ino=BigInt(0);this.mode=BigInt(IU);this.nlink=BigInt(1);this.rdev=BigInt(0);this.blocks=BigInt(1)}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&BigInt(61440))===BigInt(16384)}isFIFO(){return!1}isFile(){return(this.mode&BigInt(61440))===BigInt(32768)}isSocket(){return!1}isSymbolicLink(){return(this.mode&BigInt(61440))===BigInt(40960)}}});function JGe(t){let e,r;if(e=t.match(YGe))t=e[1];else if(r=t.match(VGe))t=`\\\\${r[1]?".\\":""}${r[2]}`;else return t;return t.replace(/\//g,"\\")}function KGe(t){t=t.replace(/\\/g,"/");let e,r;return(e=t.match(qGe))?t=`/${e[1]}`:(r=t.match(WGe))&&(t=`/unc/${r[1]?".dot/":""}${r[2]}`),t}function Xb(t,e){return t===fe?WX(e):BU(e)}var O2,vt,Er,fe,J,qX,qGe,WGe,YGe,VGe,BU,WX,el=Ze(()=>{O2=ut(Ie("path")),vt={root:"/",dot:".",parent:".."},Er={home:"~",nodeModules:"node_modules",manifest:"package.json",lockfile:"yarn.lock",virtual:"__virtual__",pnpJs:".pnp.js",pnpCjs:".pnp.cjs",pnpData:".pnp.data.json",pnpEsmLoader:".pnp.loader.mjs",rc:".yarnrc.yml",env:".env"},fe=Object.create(O2.default),J=Object.create(O2.default.posix);fe.cwd=()=>process.cwd();J.cwd=process.platform==="win32"?()=>BU(process.cwd()):process.cwd;process.platform==="win32"&&(J.resolve=(...t)=>t.length>0&&J.isAbsolute(t[0])?O2.default.posix.resolve(...t):O2.default.posix.resolve(J.cwd(),...t));qX=function(t,e,r){return e=t.normalize(e),r=t.normalize(r),e===r?".":(e.endsWith(t.sep)||(e=e+t.sep),r.startsWith(e)?r.slice(e.length):null)};fe.contains=(t,e)=>qX(fe,t,e);J.contains=(t,e)=>qX(J,t,e);qGe=/^([a-zA-Z]:.*)$/,WGe=/^\/\/(\.\/)?(.*)$/,YGe=/^\/([a-zA-Z]:.*)$/,VGe=/^\/unc\/(\.dot\/)?(.*)$/;BU=process.platform==="win32"?KGe:t=>t,WX=process.platform==="win32"?JGe:t=>t;fe.fromPortablePath=WX;fe.toPortablePath=BU});async function $b(t,e){let r="0123456789abcdef";await t.mkdirPromise(e.indexPath,{recursive:!0});let s=[];for(let a of r)for(let n of r)s.push(t.mkdirPromise(t.pathUtils.join(e.indexPath,`${a}${n}`),{recursive:!0}));return await Promise.all(s),e.indexPath}async function YX(t,e,r,s,a){let n=t.pathUtils.normalize(e),c=r.pathUtils.normalize(s),f=[],p=[],{atime:h,mtime:E}=a.stableTime?{atime:dd,mtime:dd}:await r.lstatPromise(c);await t.mkdirpPromise(t.pathUtils.dirname(e),{utimes:[h,E]}),await vU(f,p,t,n,r,c,{...a,didParentExist:!0});for(let C of f)await C();await Promise.all(p.map(C=>C()))}async function vU(t,e,r,s,a,n,c){let f=c.didParentExist?await VX(r,s):null,p=await a.lstatPromise(n),{atime:h,mtime:E}=c.stableTime?{atime:dd,mtime:dd}:p,C;switch(!0){case p.isDirectory():C=await ZGe(t,e,r,s,f,a,n,p,c);break;case p.isFile():C=await eqe(t,e,r,s,f,a,n,p,c);break;case p.isSymbolicLink():C=await tqe(t,e,r,s,f,a,n,p,c);break;default:throw new Error(`Unsupported file type (${p.mode})`)}return(c.linkStrategy?.type!=="HardlinkFromIndex"||!p.isFile())&&((C||f?.mtime?.getTime()!==E.getTime()||f?.atime?.getTime()!==h.getTime())&&(e.push(()=>r.lutimesPromise(s,h,E)),C=!0),(f===null||(f.mode&511)!==(p.mode&511))&&(e.push(()=>r.chmodPromise(s,p.mode&511)),C=!0)),C}async function VX(t,e){try{return await t.lstatPromise(e)}catch{return null}}async function ZGe(t,e,r,s,a,n,c,f,p){if(a!==null&&!a.isDirectory())if(p.overwrite)t.push(async()=>r.removePromise(s)),a=null;else return!1;let h=!1;a===null&&(t.push(async()=>{try{await r.mkdirPromise(s,{mode:f.mode})}catch(S){if(S.code!=="EEXIST")throw S}}),h=!0);let E=await n.readdirPromise(c),C=p.didParentExist&&!a?{...p,didParentExist:!1}:p;if(p.stableSort)for(let S of E.sort())await vU(t,e,r,r.pathUtils.join(s,S),n,n.pathUtils.join(c,S),C)&&(h=!0);else(await Promise.all(E.map(async b=>{await vU(t,e,r,r.pathUtils.join(s,b),n,n.pathUtils.join(c,b),C)}))).some(b=>b)&&(h=!0);return h}async function XGe(t,e,r,s,a,n,c,f,p,h){let E=await n.checksumFilePromise(c,{algorithm:"sha1"}),C=420,S=f.mode&511,b=`${E}${S!==C?S.toString(8):""}`,I=r.pathUtils.join(h.indexPath,E.slice(0,2),`${b}.dat`),T;(le=>(le[le.Lock=0]="Lock",le[le.Rename=1]="Rename"))(T||={});let N=1,U=await VX(r,I);if(a){let ie=U&&a.dev===U.dev&&a.ino===U.ino,ue=U?.mtimeMs!==zGe;if(ie&&ue&&h.autoRepair&&(N=0,U=null),!ie)if(p.overwrite)t.push(async()=>r.removePromise(s)),a=null;else return!1}let W=!U&&N===1?`${I}.${Math.floor(Math.random()*4294967296).toString(16).padStart(8,"0")}`:null,ee=!1;return t.push(async()=>{if(!U&&(N===0&&await r.lockPromise(I,async()=>{let ie=await n.readFilePromise(c);await r.writeFilePromise(I,ie)}),N===1&&W)){let ie=await n.readFilePromise(c);await r.writeFilePromise(W,ie);try{await r.linkPromise(W,I)}catch(ue){if(ue.code==="EEXIST")ee=!0,await r.unlinkPromise(W);else throw ue}}a||await r.linkPromise(I,s)}),e.push(async()=>{U||(await r.lutimesPromise(I,dd,dd),S!==C&&await r.chmodPromise(I,S)),W&&!ee&&await r.unlinkPromise(W)}),!1}async function $Ge(t,e,r,s,a,n,c,f,p){if(a!==null)if(p.overwrite)t.push(async()=>r.removePromise(s)),a=null;else return!1;return t.push(async()=>{let h=await n.readFilePromise(c);await r.writeFilePromise(s,h)}),!0}async function eqe(t,e,r,s,a,n,c,f,p){return p.linkStrategy?.type==="HardlinkFromIndex"?XGe(t,e,r,s,a,n,c,f,p,p.linkStrategy):$Ge(t,e,r,s,a,n,c,f,p)}async function tqe(t,e,r,s,a,n,c,f,p){if(a!==null)if(p.overwrite)t.push(async()=>r.removePromise(s)),a=null;else return!1;return t.push(async()=>{await r.symlinkPromise(Xb(r.pathUtils,await n.readlinkPromise(c)),s)}),!0}var dd,zGe,SU=Ze(()=>{el();dd=new Date(456789e3*1e3),zGe=dd.getTime()});function ex(t,e,r,s){let a=()=>{let n=r.shift();if(typeof n>"u")return null;let c=t.pathUtils.join(e,n);return Object.assign(t.statSync(c),{name:n,path:void 0})};return new L2(e,a,s)}var L2,JX=Ze(()=>{zb();L2=class{constructor(e,r,s={}){this.path=e;this.nextDirent=r;this.opts=s;this.closed=!1}throwIfClosed(){if(this.closed)throw mU()}async*[Symbol.asyncIterator](){try{let e;for(;(e=await this.read())!==null;)yield e}finally{await this.close()}}read(e){let r=this.readSync();return typeof e<"u"?e(null,r):Promise.resolve(r)}readSync(){return this.throwIfClosed(),this.nextDirent()}close(e){return this.closeSync(),typeof e<"u"?e(null):Promise.resolve()}closeSync(){this.throwIfClosed(),this.opts.onClose?.(),this.closed=!0}}});function KX(t,e){if(t!==e)throw new Error(`Invalid StatWatcher status: expected '${e}', got '${t}'`)}var zX,tx,ZX=Ze(()=>{zX=Ie("events");wU();tx=class t extends zX.EventEmitter{constructor(r,s,{bigint:a=!1}={}){super();this.status="ready";this.changeListeners=new Map;this.startTimeout=null;this.fakeFs=r,this.path=s,this.bigint=a,this.lastStats=this.stat()}static create(r,s,a){let n=new t(r,s,a);return n.start(),n}start(){KX(this.status,"ready"),this.status="running",this.startTimeout=setTimeout(()=>{this.startTimeout=null,this.fakeFs.existsSync(this.path)||this.emit("change",this.lastStats,this.lastStats)},3)}stop(){KX(this.status,"running"),this.status="stopped",this.startTimeout!==null&&(clearTimeout(this.startTimeout),this.startTimeout=null),this.emit("stop")}stat(){try{return this.fakeFs.statSync(this.path,{bigint:this.bigint})}catch{let r=this.bigint?new iE:new nE;return Zb(r)}}makeInterval(r){let s=setInterval(()=>{let a=this.stat(),n=this.lastStats;CU(a,n)||(this.lastStats=a,this.emit("change",a,n))},r.interval);return r.persistent?s:s.unref()}registerChangeListener(r,s){this.addListener("change",r),this.changeListeners.set(r,this.makeInterval(s))}unregisterChangeListener(r){this.removeListener("change",r);let s=this.changeListeners.get(r);typeof s<"u"&&clearInterval(s),this.changeListeners.delete(r)}unregisterAllChangeListeners(){for(let r of this.changeListeners.keys())this.unregisterChangeListener(r)}hasChangeListeners(){return this.changeListeners.size>0}ref(){for(let r of this.changeListeners.values())r.ref();return this}unref(){for(let r of this.changeListeners.values())r.unref();return this}}});function sE(t,e,r,s){let a,n,c,f;switch(typeof r){case"function":a=!1,n=!0,c=5007,f=r;break;default:({bigint:a=!1,persistent:n=!0,interval:c=5007}=r),f=s;break}let p=rx.get(t);typeof p>"u"&&rx.set(t,p=new Map);let h=p.get(e);return typeof h>"u"&&(h=tx.create(t,e,{bigint:a}),p.set(e,h)),h.registerChangeListener(f,{persistent:n,interval:c}),h}function md(t,e,r){let s=rx.get(t);if(typeof s>"u")return;let a=s.get(e);typeof a>"u"||(typeof r>"u"?a.unregisterAllChangeListeners():a.unregisterChangeListener(r),a.hasChangeListeners()||(a.stop(),s.delete(e)))}function yd(t){let e=rx.get(t);if(!(typeof e>"u"))for(let r of e.keys())md(t,r)}var rx,DU=Ze(()=>{ZX();rx=new WeakMap});function rqe(t){let e=t.match(/\r?\n/g);if(e===null)return $X.EOL;let r=e.filter(a=>a===`\r `).length,s=e.length-r;return r>s?`\r `:` `}function Ed(t,e){return e.replace(/\r?\n/g,rqe(t))}var XX,$X,mp,Uf,Id=Ze(()=>{XX=Ie("crypto"),$X=Ie("os");SU();el();mp=class{constructor(e){this.pathUtils=e}async*genTraversePromise(e,{stableSort:r=!1}={}){let s=[e];for(;s.length>0;){let a=s.shift();if((await this.lstatPromise(a)).isDirectory()){let c=await this.readdirPromise(a);if(r)for(let f of c.sort())s.push(this.pathUtils.join(a,f));else throw new Error("Not supported")}else yield a}}async checksumFilePromise(e,{algorithm:r="sha512"}={}){let s=await this.openPromise(e,"r");try{let n=Buffer.allocUnsafeSlow(65536),c=(0,XX.createHash)(r),f=0;for(;(f=await this.readPromise(s,n,0,65536))!==0;)c.update(f===65536?n:n.slice(0,f));return c.digest("hex")}finally{await this.closePromise(s)}}async removePromise(e,{recursive:r=!0,maxRetries:s=5}={}){let a;try{a=await this.lstatPromise(e)}catch(n){if(n.code==="ENOENT")return;throw n}if(a.isDirectory()){if(r){let n=await this.readdirPromise(e);await Promise.all(n.map(c=>this.removePromise(this.pathUtils.resolve(e,c))))}for(let n=0;n<=s;n++)try{await this.rmdirPromise(e);break}catch(c){if(c.code!=="EBUSY"&&c.code!=="ENOTEMPTY")throw c;n1024,C&&(t.dump&&W2===t.dump.charCodeAt(0)?S+="?":S+="? "),S+=t.dump,C&&(S+=$U(t,e)),Rd(t,e+1,E,!0,C)&&(t.dump&&W2===t.dump.charCodeAt(0)?S+=":":S+=": ",S+=t.dump,a+=S));t.tag=n,t.dump=a||"{}"}function Yte(t,e,r){var s,a,n,c,f,p;for(a=r?t.explicitTypes:t.implicitTypes,n=0,c=a.length;n {var n,c;if(Object.getPrototypeOf(s).toString()==="[object Set]")if(typeof a?.coercions<"u"){if(typeof a?.coercion>"u")return mr(a,"Unbound coercion result");let f=[...s],p=[...s];if(!r(p,Object.assign(Object.assign({},a),{coercion:void 0})))return!1;let h=()=>p.some((E,C)=>E!==f[C])?new Set(p):s;return a.coercions.push([(n=a.p)!==null&&n!==void 0?n:".",Z2(a.coercion,s,h)]),!0}else{let f=!0;for(let p of s)if(f=t(p,Object.assign({},a))&&f,!f&&a?.errors==null)break;return f}if(typeof a?.coercions<"u"){if(typeof a?.coercion>"u")return mr(a,"Unbound coercion result");let f={value:s};return r(s,Object.assign(Object.assign({},a),{coercion:Wf(f,"value")}))?(a.coercions.push([(c=a.p)!==null&&c!==void 0?c:".",Z2(a.coercion,s,()=>new Set(f.value))]),!0):!1}return mr(a,`Expected a set (got ${ti(s)})`)}})}function NWe(t,e){let r=Rx(Tx([t,e])),s=Fx(e,{keys:t});return Wr({test:(a,n)=>{var c,f,p;if(Object.getPrototypeOf(a).toString()==="[object Map]")if(typeof n?.coercions<"u"){if(typeof n?.coercion>"u")return mr(n,"Unbound coercion result");let h=[...a],E=[...a];if(!r(E,Object.assign(Object.assign({},n),{coercion:void 0})))return!1;let C=()=>E.some((S,b)=>S[0]!==h[b][0]||S[1]!==h[b][1])?new Map(E):a;return n.coercions.push([(c=n.p)!==null&&c!==void 0?c:".",Z2(n.coercion,a,C)]),!0}else{let h=!0;for(let[E,C]of a)if(h=t(E,Object.assign({},n))&&h,!h&&n?.errors==null||(h=e(C,Object.assign(Object.assign({},n),{p:s0(n,E)}))&&h,!h&&n?.errors==null))break;return h}if(typeof n?.coercions<"u"){if(typeof n?.coercion>"u")return mr(n,"Unbound coercion result");let h={value:a};return Array.isArray(a)?r(a,Object.assign(Object.assign({},n),{coercion:void 0}))?(n.coercions.push([(f=n.p)!==null&&f!==void 0?f:".",Z2(n.coercion,a,()=>new Map(h.value))]),!0):!1:s(a,Object.assign(Object.assign({},n),{coercion:Wf(h,"value")}))?(n.coercions.push([(p=n.p)!==null&&p!==void 0?p:".",Z2(n.coercion,a,()=>new Map(Object.entries(h.value)))]),!0):!1}return mr(n,`Expected a map (got ${ti(a)})`)}})}function Tx(t,{delimiter:e}={}){let r=Rre(t.length);return Wr({test:(s,a)=>{var n;if(typeof s=="string"&&typeof e<"u"&&typeof a?.coercions<"u"){if(typeof a?.coercion>"u")return mr(a,"Unbound coercion result");s=s.split(e),a.coercions.push([(n=a.p)!==null&&n!==void 0?n:".",a.coercion.bind(null,s)])}if(!Array.isArray(s))return mr(a,`Expected a tuple (got ${ti(s)})`);let c=r(s,Object.assign({},a));for(let f=0,p=s.length;f {var n;if(Array.isArray(s)&&typeof a?.coercions<"u")return typeof a?.coercion>"u"?mr(a,"Unbound coercion result"):r(s,Object.assign(Object.assign({},a),{coercion:void 0}))?(s=Object.fromEntries(s),a.coercions.push([(n=a.p)!==null&&n!==void 0?n:".",a.coercion.bind(null,s)]),!0):!1;if(typeof s!="object"||s===null)return mr(a,`Expected an object (got ${ti(s)})`);let c=Object.keys(s),f=!0;for(let p=0,h=c.length;p `:`[${b}]`)}s.push(...this.arity.leading.map(c=>`<${c}>`)),this.arity.extra===Hl?s.push("..."):s.push(...this.arity.extra.map(c=>`[${c}]`)),s.push(...this.arity.trailing.map(c=>`<${c}>`))}return{usage:s.join(" "),options:a}}compile(){if(typeof this.context>"u")throw new Error("Assertion failed: No context attached");let e=Fre(),r=En.InitialNode,s=this.usage().usage,a=this.options.filter(f=>f.required).map(f=>f.nameSet);r=Ou(e,_l()),Ia(e,En.InitialNode,ei.StartOfInput,r,["setCandidateState",{candidateUsage:s,requiredOptions:a}]);let n=this.arity.proxy?"always":"isNotOptionLike",c=this.paths.length>0?this.paths:[[]];for(let f of c){let p=r;if(f.length>0){let S=Ou(e,_l());BE(e,p,S),this.registerOptions(e,S),p=S}for(let S=0;S >/2":{type_args:!1,type_result:!1,fn:function(w,P,y){return w>>P}},"/\\/2":{type_args:!1,type_result:!1,fn:function(w,P,y){return w&P}},"\\//2":{type_args:!1,type_result:!1,fn:function(w,P,y){return w|P}},"xor/2":{type_args:!1,type_result:!1,fn:function(w,P,y){return w^P}},"rem/2":{type_args:!1,type_result:!1,fn:function(w,P,y){return P?w%P:x.error.evaluation("zero_division",y.__call_indicator)}},"mod/2":{type_args:!1,type_result:!1,fn:function(w,P,y){return P?w-parseInt(w/P)*P:x.error.evaluation("zero_division",y.__call_indicator)}},"max/2":{type_args:null,type_result:null,fn:function(w,P,y){return Math.max(w,P)}},"min/2":{type_args:null,type_result:null,fn:function(w,P,y){return Math.min(w,P)}}}},directive:{"dynamic/1":function(w,P){var y=P.args[0];if(x.type.is_variable(y))w.throw_error(x.error.instantiation(P.indicator));else if(!x.type.is_compound(y)||y.indicator!=="//2")w.throw_error(x.error.type("predicate_indicator",y,P.indicator));else if(x.type.is_variable(y.args[0])||x.type.is_variable(y.args[1]))w.throw_error(x.error.instantiation(P.indicator));else if(!x.type.is_atom(y.args[0]))w.throw_error(x.error.type("atom",y.args[0],P.indicator));else if(!x.type.is_integer(y.args[1]))w.throw_error(x.error.type("integer",y.args[1],P.indicator));else{var F=P.args[0].args[0].id+"/"+P.args[0].args[1].value;w.session.public_predicates[F]=!0,w.session.rules[F]||(w.session.rules[F]=[])}},"multifile/1":function(w,P){var y=P.args[0];x.type.is_variable(y)?w.throw_error(x.error.instantiation(P.indicator)):!x.type.is_compound(y)||y.indicator!=="//2"?w.throw_error(x.error.type("predicate_indicator",y,P.indicator)):x.type.is_variable(y.args[0])||x.type.is_variable(y.args[1])?w.throw_error(x.error.instantiation(P.indicator)):x.type.is_atom(y.args[0])?x.type.is_integer(y.args[1])?w.session.multifile_predicates[P.args[0].args[0].id+"/"+P.args[0].args[1].value]=!0:w.throw_error(x.error.type("integer",y.args[1],P.indicator)):w.throw_error(x.error.type("atom",y.args[0],P.indicator))},"set_prolog_flag/2":function(w,P){var y=P.args[0],F=P.args[1];x.type.is_variable(y)||x.type.is_variable(F)?w.throw_error(x.error.instantiation(P.indicator)):x.type.is_atom(y)?x.type.is_flag(y)?x.type.is_value_flag(y,F)?x.type.is_modifiable_flag(y)?w.session.flag[y.id]=F:w.throw_error(x.error.permission("modify","flag",y)):w.throw_error(x.error.domain("flag_value",new j("+",[y,F]),P.indicator)):w.throw_error(x.error.domain("prolog_flag",y,P.indicator)):w.throw_error(x.error.type("atom",y,P.indicator))},"use_module/1":function(w,P){var y=P.args[0];if(x.type.is_variable(y))w.throw_error(x.error.instantiation(P.indicator));else if(!x.type.is_term(y))w.throw_error(x.error.type("term",y,P.indicator));else if(x.type.is_module(y)){var F=y.args[0].id;e(w.session.modules,F)===-1&&w.session.modules.push(F)}},"char_conversion/2":function(w,P){var y=P.args[0],F=P.args[1];x.type.is_variable(y)||x.type.is_variable(F)?w.throw_error(x.error.instantiation(P.indicator)):x.type.is_character(y)?x.type.is_character(F)?y.id===F.id?delete w.session.__char_conversion[y.id]:w.session.__char_conversion[y.id]=F.id:w.throw_error(x.error.type("character",F,P.indicator)):w.throw_error(x.error.type("character",y,P.indicator))},"op/3":function(w,P){var y=P.args[0],F=P.args[1],z=P.args[2];if(x.type.is_variable(y)||x.type.is_variable(F)||x.type.is_variable(z))w.throw_error(x.error.instantiation(P.indicator));else if(!x.type.is_integer(y))w.throw_error(x.error.type("integer",y,P.indicator));else if(!x.type.is_atom(F))w.throw_error(x.error.type("atom",F,P.indicator));else if(!x.type.is_atom(z))w.throw_error(x.error.type("atom",z,P.indicator));else if(y.value<0||y.value>1200)w.throw_error(x.error.domain("operator_priority",y,P.indicator));else if(z.id===",")w.throw_error(x.error.permission("modify","operator",z,P.indicator));else if(z.id==="|"&&(y.value<1001||F.id.length!==3))w.throw_error(x.error.permission("modify","operator",z,P.indicator));else if(["fy","fx","yf","xf","xfx","yfx","xfy"].indexOf(F.id)===-1)w.throw_error(x.error.domain("operator_specifier",F,P.indicator));else{var Z={prefix:null,infix:null,postfix:null};for(var $ in w.session.__operators)if(w.session.__operators.hasOwnProperty($)){var oe=w.session.__operators[$][z.id];oe&&(e(oe,"fx")!==-1&&(Z.prefix={priority:$,type:"fx"}),e(oe,"fy")!==-1&&(Z.prefix={priority:$,type:"fy"}),e(oe,"xf")!==-1&&(Z.postfix={priority:$,type:"xf"}),e(oe,"yf")!==-1&&(Z.postfix={priority:$,type:"yf"}),e(oe,"xfx")!==-1&&(Z.infix={priority:$,type:"xfx"}),e(oe,"xfy")!==-1&&(Z.infix={priority:$,type:"xfy"}),e(oe,"yfx")!==-1&&(Z.infix={priority:$,type:"yfx"}))}var xe;switch(F.id){case"fy":case"fx":xe="prefix";break;case"yf":case"xf":xe="postfix";break;default:xe="infix";break}if(((Z.prefix&&xe==="prefix"||Z.postfix&&xe==="postfix"||Z.infix&&xe==="infix")&&Z[xe].type!==F.id||Z.infix&&xe==="postfix"||Z.postfix&&xe==="infix")&&y.value!==0)w.throw_error(x.error.permission("create","operator",z,P.indicator));else return Z[xe]&&(we(w.session.__operators[Z[xe].priority][z.id],F.id),w.session.__operators[Z[xe].priority][z.id].length===0&&delete w.session.__operators[Z[xe].priority][z.id]),y.value>0&&(w.session.__operators[y.value]||(w.session.__operators[y.value.toString()]={}),w.session.__operators[y.value][z.id]||(w.session.__operators[y.value][z.id]=[]),w.session.__operators[y.value][z.id].push(F.id)),!0}}},predicate:{"op/3":function(w,P,y){x.directive["op/3"](w,y)&&w.success(P)},"current_op/3":function(w,P,y){var F=y.args[0],z=y.args[1],Z=y.args[2],$=[];for(var oe in w.session.__operators)for(var xe in w.session.__operators[oe])for(var Re=0;Re1)r=e;else if(this.head)s=this.head.next,r=this.head.value;else throw new TypeError("Reduce of empty list with no initial value");for(var a=0;s!==null;a++)r=t(r,s.value,a),s=s.next;return r};Fn.prototype.reduceReverse=function(t,e){var r,s=this.tail;if(arguments.length>1)r=e;else if(this.tail)s=this.tail.prev,r=this.tail.value;else throw new TypeError("Reduce of empty list with no initial value");for(var a=this.length-1;s!==null;a--)r=t(r,s.value,a),s=s.prev;return r};Fn.prototype.toArray=function(){for(var t=new Array(this.length),e=0,r=this.head;r!==null;e++)t[e]=r.value,r=r.next;return t};Fn.prototype.toArrayReverse=function(){for(var t=new Array(this.length),e=0,r=this.tail;r!==null;e++)t[e]=r.value,r=r.prev;return t};Fn.prototype.slice=function(t,e){e=e||this.length,e<0&&(e+=this.length),t=t||0,t<0&&(t+=this.length);var r=new Fn;if(e0&&(Ae=p.slice(0,E),p=p.slice(E),C-=E),ye&&I===!0&&C>0?(ye=p.slice(0,C),se=p.slice(C)):I===!0?(ye="",se=p):ye=p,ye&&ye!==""&&ye!=="/"&&ye!==p&&Uoe(ye.charCodeAt(ye.length-1))&&(ye=ye.slice(0,-1)),r.unescape===!0&&(se&&(se=Ooe.removeBackslashes(se)),ye&&W===!0&&(ye=Ooe.removeBackslashes(ye)));let X={prefix:Ae,input:t,start:E,base:ye,glob:se,isBrace:S,isBracket:b,isGlob:I,isExtglob:T,isGlobstar:N,negated:ee,negatedExtglob:ie};if(r.tokens===!0&&(X.maxDepth=0,Uoe(pe)||c.push(Be),X.tokens=c),r.parts===!0||r.tokens===!0){let De;for(let Te=0;Te("lookup"in r||(r.lookup=this.lookup),e[pI](r,s))}uninstall(e){if(Rue(e),e[pI]){if(e[rH]!==this)throw new Error("The agent is not owned by this CacheableLookup instance");e.createConnection=e[pI],delete e[pI],delete e[rH]}}updateInterfaceInfo(){let{_iface:e}=this;this._iface=Tue(),(e.has4&&!this._iface.has4||e.has6&&!this._iface.has6)&&this._cache.clear()}clear(e){if(e){this._cache.delete(e);return}this._cache.clear()}};nH.exports=_Q;nH.exports.default=_Q});var Uue=_((hMt,iH)=>{"use strict";var Oet=typeof URL>"u"?Ie("url").URL:URL,Let="text/plain",Met="us-ascii",Lue=(t,e)=>e.some(r=>r instanceof RegExp?r.test(t):r===t),Uet=(t,{stripHash:e})=>{let r=t.match(/^data:([^,]*?),([^#]*?)(?:#(.*))?$/);if(!r)throw new Error(`Invalid URL: ${t}`);let s=r[1].split(";"),a=r[2],n=e?"":r[3],c=!1;s[s.length-1]==="base64"&&(s.pop(),c=!0);let f=(s.shift()||"").toLowerCase(),h=[...s.map(E=>{let[C,S=""]=E.split("=").map(b=>b.trim());return C==="charset"&&(S=S.toLowerCase(),S===Met)?"":`${C}${S?`=${S}`:""}`}).filter(Boolean)];return c&&h.push("base64"),(h.length!==0||f&&f!==Let)&&h.unshift(f),`data:${h.join(";")},${c?a.trim():a}${n?`#${n}`:""}`},Mue=(t,e)=>{if(e={defaultProtocol:"http:",normalizeProtocol:!0,forceHttp:!1,forceHttps:!1,stripAuthentication:!0,stripHash:!1,stripWWW:!0,removeQueryParameters:[/^utm_\w+/i],removeTrailingSlash:!0,removeDirectoryIndex:!1,sortQueryParameters:!0,...e},Reflect.has(e,"normalizeHttps"))throw new Error("options.normalizeHttps is renamed to options.forceHttp");if(Reflect.has(e,"normalizeHttp"))throw new Error("options.normalizeHttp is renamed to options.forceHttps");if(Reflect.has(e,"stripFragment"))throw new Error("options.stripFragment is renamed to options.stripHash");if(t=t.trim(),/^data:/i.test(t))return Uet(t,e);let r=t.startsWith("//");!r&&/^\.*\//.test(t)||(t=t.replace(/^(?!(?:\w+:)?\/\/)|^\/\//,e.defaultProtocol));let a=new Oet(t);if(e.forceHttp&&e.forceHttps)throw new Error("The `forceHttp` and `forceHttps` options cannot be used together");if(e.forceHttp&&a.protocol==="https:"&&(a.protocol="http:"),e.forceHttps&&a.protocol==="http:"&&(a.protocol="https:"),e.stripAuthentication&&(a.username="",a.password=""),e.stripHash&&(a.hash=""),a.pathname&&(a.pathname=a.pathname.replace(/((?!:).|^)\/{2,}/g,(n,c)=>/^(?!\/)/g.test(c)?`${c}/`:"/")),a.pathname&&(a.pathname=decodeURI(a.pathname)),e.removeDirectoryIndex===!0&&(e.removeDirectoryIndex=[/^index\.[a-z]+$/]),Array.isArray(e.removeDirectoryIndex)&&e.removeDirectoryIndex.length>0){let n=a.pathname.split("/"),c=n[n.length-1];Lue(c,e.removeDirectoryIndex)&&(n=n.slice(0,n.length-1),a.pathname=n.slice(1).join("/")+"/")}if(a.hostname&&(a.hostname=a.hostname.replace(/\.$/,""),e.stripWWW&&/^www\.([a-z\-\d]{2,63})\.([a-z.]{2,5})$/.test(a.hostname)&&(a.hostname=a.hostname.replace(/^www\./,""))),Array.isArray(e.removeQueryParameters))for(let n of[...a.searchParams.keys()])Lue(n,e.removeQueryParameters)&&a.searchParams.delete(n);return e.sortQueryParameters&&a.searchParams.sort(),e.removeTrailingSlash&&(a.pathname=a.pathname.replace(/\/$/,"")),t=a.toString(),(e.removeTrailingSlash||a.pathname==="/")&&a.hash===""&&(t=t.replace(/\/$/,"")),r&&!e.normalizeProtocol&&(t=t.replace(/^http:\/\//,"//")),e.stripProtocol&&(t=t.replace(/^(?:https?:)?\/\//,"")),t};iH.exports=Mue;iH.exports.default=Mue});var jue=_((gMt,Hue)=>{Hue.exports=_ue;function _ue(t,e){if(t&&e)return _ue(t)(e);if(typeof t!="function")throw new TypeError("need wrapper function");return Object.keys(t).forEach(function(s){r[s]=t[s]}),r;function r(){for(var s=new Array(arguments.length),a=0;a{"use strict";var dst=DI(),d0e=BT(),qI=Ie("fs"),mst=GI(),g0e=Ie("path"),iG=FI();y0e.exports=(t,e,r)=>{typeof t=="function"?(r=t,e=null,t={}):Array.isArray(t)&&(e=t,t={}),typeof e=="function"&&(r=e,e=null),e?e=Array.from(e):e=[];let s=dst(t);if(s.sync&&typeof r=="function")throw new TypeError("callback not supported for sync tar functions");if(!s.file&&typeof r=="function")throw new TypeError("callback only supported with file option");return e.length&&Est(s,e),s.noResume||yst(s),s.file&&s.sync?Ist(s):s.file?Cst(s,r):m0e(s)};var yst=t=>{let e=t.onentry;t.onentry=e?r=>{e(r),r.resume()}:r=>r.resume()},Est=(t,e)=>{let r=new Map(e.map(n=>[iG(n),!0])),s=t.filter,a=(n,c)=>{let f=c||g0e.parse(n).root||".",p=n===f?!1:r.has(n)?r.get(n):a(g0e.dirname(n),f);return r.set(n,p),p};t.filter=s?(n,c)=>s(n,c)&&a(iG(n)):n=>a(iG(n))},Ist=t=>{let e=m0e(t),r=t.file,s=!0,a;try{let n=qI.statSync(r),c=t.maxReadSize||16*1024*1024;if(n.size