From 43a1c0983ae28105c70396aff7e7fc32af960845 Mon Sep 17 00:00:00 2001 From: Gordon Smith Date: Wed, 3 Sep 2025 16:01:48 +0100 Subject: [PATCH] feat: Bump observablehq runtime support Signed-off-by: Gordon Smith --- .github/workflows/release-please.yml | 4 + package-lock.json | 224 +-- .../observablehq-compiler/.vscode/launch.json | 17 +- .../index-kit-preview.html | 246 +--- packages/observablehq-compiler/index-kit.html | 22 +- packages/observablehq-compiler/package.json | 18 +- .../observablehq-compiler/src/compiler.ts | 18 +- packages/observablehq-compiler/src/cst.ts | 3 +- packages/observablehq-compiler/src/index.css | 460 ------ packages/observablehq-compiler/src/index.ts | 5 +- .../observablehq-compiler/src/kit/compiler.ts | 41 + .../observablehq-compiler/src/kit/index.ts | 3 + .../observablehq-compiler/src/kit/runtime.ts | 57 + .../observablehq-compiler/src/kit/util.ts | 157 ++ packages/observablehq-compiler/src/util.ts | 135 +- packages/observablehq-compiler/tests/AMZN.csv | 1261 +++++++++++++++++ .../tests/albers-usa-projection.txt | 23 + .../tests/index-notebookkit.js | 217 +++ .../tests/index-notebookkit.ts | 336 +---- .../tests/system-guide.txt | 186 +++ .../tests/us-counties-10m.json | 1 + packages/observablehq-compiler/tsconfig.json | 3 +- packages/observablehq-compiler/vite.config.ts | 33 +- 23 files changed, 2205 insertions(+), 1265 deletions(-) delete mode 100644 packages/observablehq-compiler/src/index.css create mode 100644 packages/observablehq-compiler/src/kit/compiler.ts create mode 100644 packages/observablehq-compiler/src/kit/index.ts create mode 100644 packages/observablehq-compiler/src/kit/runtime.ts create mode 100644 packages/observablehq-compiler/src/kit/util.ts create mode 100644 packages/observablehq-compiler/tests/AMZN.csv create mode 100644 packages/observablehq-compiler/tests/albers-usa-projection.txt create mode 100644 packages/observablehq-compiler/tests/index-notebookkit.js create mode 100644 packages/observablehq-compiler/tests/system-guide.txt create mode 100644 packages/observablehq-compiler/tests/us-counties-10m.json diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index b29e535e85..a1f143a31d 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -15,6 +15,10 @@ permissions: name: PR Test and Release +concurrency: + group: release-please-${{ github.ref }} + cancel-in-progress: true + jobs: release-please: runs-on: ubuntu-latest diff --git a/package-lock.json b/package-lock.json index ca134ab1b6..125ab3d462 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4879,9 +4879,9 @@ } }, "node_modules/@observablehq/notebook-kit": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@observablehq/notebook-kit/-/notebook-kit-1.1.1.tgz", - "integrity": "sha512-u7ZjBbIoZSNFfPzxfwT7Fxh76NwWihZW+NwK86V6owoY0EXIX712MHucuj4+b2AFzj9ZOwISF+eXPBFclqm+wQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@observablehq/notebook-kit/-/notebook-kit-1.2.0.tgz", + "integrity": "sha512-aliUdVyYrt7Y7Gkf3SiXKbtYUWkauWEhayiaiRaCoV3f9Mi9TZWBw3s6at49duwk6kMuK7vnA0klZT4fBEFWQg==", "dev": true, "license": "ISC", "dependencies": { @@ -4909,14 +4909,22 @@ "notebooks": "dist/bin/notebooks.js" }, "peerDependencies": { + "@databricks/sql": "^1.11.0", "@duckdb/node-api": "^1.3.2-alpha.26", + "@google-cloud/bigquery": "^8.1.1", "postgres": "^3.4.7", "snowflake-sdk": "^2.1.3" }, "peerDependenciesMeta": { + "@databricks/sql": { + "optional": true + }, "@duckdb/node-api": { "optional": true }, + "@google-cloud/bigquery": { + "optional": true + }, "postgres": { "optional": true }, @@ -6164,52 +6172,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@swc/core": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.13.4.tgz", - "integrity": "sha512-bCq2GCuKV16DSOOEdaRqHMm1Ok4YEoLoNdgdzp8BS/Hxxr/0NVCHBUgRLLRy/TlJGv20Idx+djd5FIDvsnqMaw==", - "dev": true, - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "@swc/counter": "^0.1.3", - "@swc/types": "^0.1.24" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/swc" - }, - "optionalDependencies": { - "@swc/core-darwin-arm64": "1.13.4", - "@swc/core-darwin-x64": "1.13.4", - "@swc/core-linux-arm-gnueabihf": "1.13.4", - "@swc/core-linux-arm64-gnu": "1.13.4", - "@swc/core-linux-arm64-musl": "1.13.4", - "@swc/core-linux-x64-gnu": "1.13.4", - "@swc/core-linux-x64-musl": "1.13.4", - "@swc/core-win32-arm64-msvc": "1.13.4", - "@swc/core-win32-ia32-msvc": "1.13.4", - "@swc/core-win32-x64-msvc": "1.13.4" - }, - "peerDependencies": { - "@swc/helpers": ">=0.5.17" - }, - "peerDependenciesMeta": { - "@swc/helpers": { - "optional": true - } - } - }, - "node_modules/@swc/counter": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", - "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", - "dev": true, - "license": "Apache-2.0" - }, "node_modules/@swc/helpers": { "version": "0.5.17", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", @@ -6220,23 +6182,6 @@ "tslib": "^2.8.0" } }, - "node_modules/@swc/types": { - "version": "0.1.24", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.24.tgz", - "integrity": "sha512-tjTMh3V4vAORHtdTprLlfoMptu1WfTZG9Rsca6yOKyNYsRr+MUXutKmliB17orgSZk5DpnDxs8GUdd/qwYxOng==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@swc/counter": "^0.1.3" - } - }, - "node_modules/@swc/wasm": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/@swc/wasm/-/wasm-1.13.4.tgz", - "integrity": "sha512-Wpt3LDI9jqF4S2mUYyyY97eyEVhtwSrxp8XPD6cSzoXG8vXOdRbnDDnNuyOhLR1BhOWdPjJGT9UXmziMqrpW4g==", - "dev": true, - "license": "Apache-2.0" - }, "node_modules/@testing-library/dom": { "version": "10.4.1", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", @@ -9027,6 +8972,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, "license": "ISC", "dependencies": { "string-width": "^4.2.0", @@ -9041,6 +8987,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -18086,6 +18033,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -21095,22 +21043,6 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/vite-plugin-top-level-await": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/vite-plugin-top-level-await/-/vite-plugin-top-level-await-1.6.0.tgz", - "integrity": "sha512-bNhUreLamTIkoulCR9aDXbTbhLk6n1YE8NJUTTxl5RYskNRtzOR0ASzSjBVRtNdjIfngDXo11qOsybGLNsrdww==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rollup/plugin-virtual": "^3.0.2", - "@swc/core": "^1.12.14", - "@swc/wasm": "^1.12.14", - "uuid": "10.0.0" - }, - "peerDependencies": { - "vite": ">=2.8" - } - }, "node_modules/vite-prerender-plugin": { "version": "0.5.11", "resolved": "https://registry.npmjs.org/vite-prerender-plugin/-/vite-prerender-plugin-0.5.11.tgz", @@ -22136,6 +22068,7 @@ "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, "license": "MIT", "dependencies": { "cliui": "^8.0.1", @@ -22154,6 +22087,7 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, "license": "ISC", "engines": { "node": ">=12" @@ -23264,20 +23198,63 @@ "license": "Apache-2.0", "dependencies": { "jsdom": "26.1.0", - "yargs": "17.7.2" + "yargs": "18.0.0" }, "bin": { "ojscc": "bin/ojscc.mjs" }, "devDependencies": { "@hpcc-js/esbuild-plugins": "^1.5.0", - "@observablehq/notebook-kit": "1.1.1", + "@observablehq/notebook-kit": "1.2.0", "@observablehq/parser": "6.1.0", "@observablehq/runtime": "5.9.9", - "@types/jsdom": "21.1.7", - "vite-plugin-top-level-await": "^1.6.0" + "@types/jsdom": "21.1.7" + } + }, + "packages/observablehq-compiler/node_modules/ansi-regex": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz", + "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "packages/observablehq-compiler/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "packages/observablehq-compiler/node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" } }, + "packages/observablehq-compiler/node_modules/emoji-regex": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.5.0.tgz", + "integrity": "sha512-lb49vf1Xzfx080OKA0o6l8DQQpV+6Vg95zyCJX9VB/BqKYlhG7N4wgROUUHRA+ZPUefLnteQOad7z1kT2bV7bg==", + "license": "MIT" + }, "packages/observablehq-compiler/node_modules/jsdom": { "version": "26.1.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz", @@ -23323,6 +23300,38 @@ "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", "license": "MIT" }, + "packages/observablehq-compiler/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/observablehq-compiler/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "packages/observablehq-compiler/node_modules/tough-cookie": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", @@ -23335,6 +23344,49 @@ "node": ">=16" } }, + "packages/observablehq-compiler/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "packages/observablehq-compiler/node_modules/yargs": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", + "license": "MIT", + "dependencies": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^7.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "packages/observablehq-compiler/node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, "packages/other": { "name": "@hpcc-js/other", "version": "3.2.11", diff --git a/packages/observablehq-compiler/.vscode/launch.json b/packages/observablehq-compiler/.vscode/launch.json index f4a99c889f..fa496b298e 100644 --- a/packages/observablehq-compiler/.vscode/launch.json +++ b/packages/observablehq-compiler/.vscode/launch.json @@ -1,6 +1,19 @@ { "version": "0.2.0", "configurations": [ + { + "name": "bundle-watch", + "request": "launch", + "runtimeArgs": [ + "run-script", + "bundle-watch" + ], + "runtimeExecutable": "npm", + "skipFiles": [ + "/**" + ], + "type": "node" + }, { "name": "test-browser", "type": "msedge", @@ -62,9 +75,7 @@ "request": "launch", "type": "msedge", "url": "http://localhost:5514/index-kit.html", - "runtimeArgs": [ - "--disable-web-security" - ], + "runtimeArgs": [], "webRoot": "${workspaceFolder}", "outFiles": [ "${workspaceFolder}/**/*.js", diff --git a/packages/observablehq-compiler/index-kit-preview.html b/packages/observablehq-compiler/index-kit-preview.html index f683ef17f8..b7a3bcd4f1 100644 --- a/packages/observablehq-compiler/index-kit-preview.html +++ b/packages/observablehq-compiler/index-kit-preview.html @@ -3,255 +3,29 @@ Home + + ObservableHQ Kit Preview -

ESM Quick Test

-
+
diff --git a/packages/observablehq-compiler/index-kit.html b/packages/observablehq-compiler/index-kit.html index 441067e69e..3236282709 100644 --- a/packages/observablehq-compiler/index-kit.html +++ b/packages/observablehq-compiler/index-kit.html @@ -3,13 +3,18 @@ Home - - + + ObservableHQ Kit Preview + + -

ESM Quick Test


- \ No newline at end of file diff --git a/packages/observablehq-compiler/package.json b/packages/observablehq-compiler/package.json index 888ec90e67..6948e9ca7b 100644 --- a/packages/observablehq-compiler/package.json +++ b/packages/observablehq-compiler/package.json @@ -3,17 +3,19 @@ "version": "3.4.0", "description": "hpcc-js - ObservableHQ Compiler (unoffical)", "type": "module", - "main": "./dist/index.umd.cjs", + "main": "./dist/index.js", "module": "./dist/index.js", "exports": { ".": { "types": "./types/index.d.ts", - "import": "./dist/index.js", - "require": "./dist/index.umd.cjs" + "import": "./dist/index.js" + }, + "./runtime": { + "types": "./types/runtime.d.ts", + "import": "./dist/runtime.js" }, "./dist/*": "./dist/*" }, - "browser": "./dist/index.umd.cjs", "types": "./types/index.d.ts", "files": [ "dist/*", @@ -29,6 +31,7 @@ "bundle-browser": "vite build", "bundle": "run-s bundle-browser bundle-node", "bundle-watch": "vite --port 5514", + "bundle-preview": "vite preview --outDir /", "gen-types": "tsc --project tsconfig.json", "gen-types-watch": "npm run gen-types -- --watch", "build": "run-p gen-types bundle", @@ -46,15 +49,14 @@ }, "dependencies": { "jsdom": "26.1.0", - "yargs": "17.7.2" + "yargs": "18.0.0" }, "devDependencies": { "@hpcc-js/esbuild-plugins": "^1.5.0", - "@observablehq/notebook-kit": "1.1.1", + "@observablehq/notebook-kit": "1.2.0", "@observablehq/parser": "6.1.0", "@observablehq/runtime": "5.9.9", - "@types/jsdom": "21.1.7", - "vite-plugin-top-level-await": "^1.6.0" + "@types/jsdom": "21.1.7" }, "repository": { "type": "git", diff --git a/packages/observablehq-compiler/src/compiler.ts b/packages/observablehq-compiler/src/compiler.ts index a4946cb220..785c6a4450 100644 --- a/packages/observablehq-compiler/src/compiler.ts +++ b/packages/observablehq-compiler/src/compiler.ts @@ -1,10 +1,9 @@ -import { type Notebook, transpile } from "@observablehq/notebook-kit"; -import { type Definition } from "@observablehq/notebook-kit/runtime"; +import { type Notebook, type Definition, compile as compileKit, fixRelativeUrl, isRelativePath, obfuscatedImport } from "./kit/index.ts"; import { ohq, splitModule } from "./observable-shim.ts"; import { parseCell, ParsedImportCell } from "./cst.ts"; import { Writer } from "./writer.ts"; -import { fixRelativeUrl, isRelativePath, encodeBacktick, fetchEx, obfuscatedImport, ojs2notebook, omd2notebook, constructFunction } from "./util.ts"; +import { encodeBacktick, fetchEx, ojs2notebook, omd2notebook } from "./util.ts"; // Inspector Factory --- export type InspectorFactoryEx = (name: string | undefined, id: string | number) => Inspector; @@ -319,19 +318,6 @@ export function notebook(_files: ohq.File[] = [], _cells: CellFunc[] = [], { bas } type NotebookFunc = ReturnType; -export function compileKit(notebook: Notebook): Definition[] { - const retVal: Definition[] = []; - for (const cell of notebook.cells) { - const compiled = transpile(cell); - retVal.push({ - id: cell.id, - ...compiled, - body: constructFunction(compiled.body) - }); - } - return retVal; -} - export function isNotebookKit(value: any): value is Notebook { return !!value && Array.isArray(value.cells); } diff --git a/packages/observablehq-compiler/src/cst.ts b/packages/observablehq-compiler/src/cst.ts index 958acfc017..2c1f7002c9 100644 --- a/packages/observablehq-compiler/src/cst.ts +++ b/packages/observablehq-compiler/src/cst.ts @@ -1,6 +1,5 @@ import { ancestor, parseCell as ohqParseCell, Cell, Node, walk, AncestorVisitors } from "./observable-shim.ts"; - -import { fixRelativeUrl, createFunction, Refs } from "./util.ts"; +import { fixRelativeUrl, createFunction, Refs } from "./kit/index.ts"; function calcRefs(cellAst: Cell, cellStr: string): Refs { if (cellAst.references === undefined) return { inputs: [], args: [], patches: [] }; diff --git a/packages/observablehq-compiler/src/index.css b/packages/observablehq-compiler/src/index.css deleted file mode 100644 index a65f376406..0000000000 --- a/packages/observablehq-compiler/src/index.css +++ /dev/null @@ -1,460 +0,0 @@ -@import url("https://fonts.googleapis.com/css2?family=Source+Serif+Pro:ital,wght@0,400;0,600;0,700;1,400;1,600;1,700&display=swap"); - -:root { - --syntax-normal: #1b1e23; - --syntax-comment: #828282; - --syntax-number: #20a5ba; - --syntax-keyword: #c30771; - --syntax-atom: #10a778; - --syntax-string: #008ec4; - --syntax-error: #ffbedc; - --syntax-unknown-variable: #838383; - --syntax-known-variable: #005f87; - --syntax-matchbracket: #20bbfc; - --syntax-key: #6636b4; - --mono-fonts: 82%/1.5 Menlo, Consolas, monospace; -} - -.observablehq--expanded, -.observablehq--collapsed, -.observablehq--function, -.observablehq--import, -.observablehq--string:before, -.observablehq--string:after, -.observablehq--gray { - color: var(--syntax-normal); -} - -.observablehq--collapsed, -.observablehq--expanded.observablehq--inspect a { - cursor: pointer; -} - -.observablehq--field { - text-indent: -1em; - margin-left: 1em; -} - -.observablehq--empty { - color: var(--syntax_comment); -} - -a[href], -.observablehq--keyword, -.observablehq--blue { - color: #3182bd; -} - -.hljs-deletion, -.hljs-variable, -.observablehq--forbidden, -.observablehq--pink { - color: #e377c2; -} - -.observablehq--orange { - color: #e6550d; -} - -.observablehq--null, -.observablehq--undefined, -.observablehq--boolean, -.hljs-literal { - color: var(--syntax-atom); -} - -.hljs-number, -.hljs-regexp, -.hljs-bullet, -.hljs-link, -.observablehq--bigint, -.observablehq--number, -.observablehq--date, -.observablehq--regexp, -.observablehq--symbol, -.observablehq--green { - color: var(--syntax-number); -} - -.observablehq--index, -.observablehq--key { - color: var(--syntax-key); -} - -.observablehq--prototype-key { - color: #aaa; -} - -.observablehq--empty { - font-style: oblique; -} - -.hljs-string, -.hljs-meta, -.hljs-symbol, -.hljs-template-tag, -.hljs-template-variable, -.hljs-addition, -.observablehq--string, -.observablehq--purple { - color: var(--syntax-string); -} - -.observablehq--error, -.observablehq--red { - color: #e7040f; -} - -.observablehq:empty:after, -.observablehq>link:only-child, -.observablehq>style:only-child, -.observablehq--inspect { - font: var(--monospace-font); - overflow-x: auto; - display: block; - padding: 4px 0; - white-space: pre; -} - -.observablehq--error .observablehq--inspect { - word-break: break-all; - white-space: pre-wrap; -} - -:root { - --syntax-diff: #24292e; - --syntax-diff-bg: #ffffff; - --hr: rgba(0, 0, 0, 0.05); - --monospace: Menlo, Consolas, monospace; - --monospace-font: 14px/1.5 var(--monospace); - --serif: "Source Serif Pro", "Iowan Old Style", "Apple Garamond", - "Palatino Linotype", "Times New Roman", "Droid Serif", Times, serif, - "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; - --sans-serif: -apple-system, BlinkMacSystemFont, "avenir next", avenir, - helvetica, "helvetica neue", ubuntu, roboto, noto, "segoe ui", arial, - sans-serif; -} - -html { - font: 17px/1.5 var(--serif); - -webkit-text-size-adjust: 100%; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - color: #1b1e23; -} - -body { - margin: 0 14px; -} - -body.fullscreen { - margin: 0; -} - -h1, -h2, -h3, -h4, -h5, -h6 { - color: #333; - font-weight: 700; - line-height: 1.15; - margin-top: 0; - margin-bottom: 0.25rem; -} - -h2~p, -h3~p, -h4~p, -h2~table, -h3~table, -h4~table { - margin-top: 0; -} - -.observablehq:first-of-type h1+h2 { - font-size: 20px; - font-style: italic; - font-weight: normal; - margin-bottom: 1rem; - /* see h2 ~ p */ -} - -a[href] { - text-decoration: none; -} - -a[href]:hover { - text-decoration: underline; -} - -h1 code, -h2 code, -h3 code, -h4 code, -h5 code, -h6 code { - font-size: 90%; -} - -pre, -code, -tt { - font-family: var(--monospace); - font-size: 14px; - line-height: 1.5; -} - -img { - max-width: calc(100vw - 28px); -} - -p, -table, -figure, -figcaption, -h1, -h2, -h3, -h4, -h5, -h6, -.katex-display { - max-width: 640px; -} - -blockquote, -ol, -ul { - max-width: 600px; -} - -blockquote { - margin: 1rem 1.5rem; -} - -ul, -ol { - padding-left: 28px; -} - -hr { - height: 1px; - margin: 1rem 0; - padding: 1rem 0; - border: none; - background: no-repeat center/100% 1px linear-gradient(to right, var(--hr), var(--hr)); -} - -pre { - padding: 2px 0; -} - -.observablehq--md-pre { - overflow-x: auto; -} - -input:not([type]), -input[type="email"], -input[type="number"], -input[type="password"], -input[type="range"], -input[type="search"], -input[type="tel"], -input[type="text"], -input[type="url"] { - width: 240px; -} - -input, -canvas, -button { - vertical-align: middle; -} - -button, -input, -textarea { - accent-color: #3b5fc0; -} - -table { - width: 100%; - border-collapse: collapse; - font: 13px/1.2 var(--sans-serif); -} - -table pre, -table code, -table tt { - font-size: inherit; - line-height: inherit; -} - -th>pre:only-child, -td>pre:only-child { - margin: 0; - padding: 0; -} - -th { - color: #111; - text-align: left; - vertical-align: bottom; -} - -td { - color: #444; - vertical-align: top; -} - -th, -td { - padding: 3px 6.5px 3px 0; -} - -th:last-child, -td:last-child { - padding-right: 0; -} - -tr:not(:last-child) { - border-bottom: solid 1px #eee; -} - -thead tr { - border-bottom: solid 1px #ccc; -} - -figure, -table { - margin: 1rem 0; -} - -figure img { - max-width: 100%; -} - -figcaption { - font: small var(--sans-serif); - color: var(--syntax-unknown-variable); -} - -.observablehq--caret { - margin-right: 4px; - vertical-align: baseline; -} - -.observablehq--field { - text-indent: -1rem; - margin-left: 1rem; -} - -.observablehq--prototype-key, -.observablehq--empty, -.hljs-comment { - color: var(--syntax-comment); -} - -.hljs-built_in { - color: var(--syntax-known-variable); -} - -.observablehq--unknown { - color: var(--syntax-unknown-variable); -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-section, -.hljs-doctag, -.hljs-type, -.hljs-tag, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class, -.hljs-strong { - color: var(--syntax-keyword); -} - -.observablehq { - position: relative; - margin: 17px 0; - min-height: 1.5rem; - /* the standard line-height */ -} - -.observablehq:before { - content: ""; - position: absolute; - left: -14px; - top: 0; - bottom: 1px; - width: 4px; - transition: background-color 250ms linear; -} - -.observablehq--running:before, -.observablehq--changed:before { - background-color: hsl(217, 13%, 70%); - transition: none; -} - -.observablehq--error:before { - background-color: #e7040f; -} - -.observablehq:not(.observablehq--running):empty:after { - content: ""; - color: var(--syntax-comment); - font-style: oblique; -} - -.observablehq>link:only-child, -.observablehq>style:only-child { - visibility: hidden; - white-space: nowrap; - color: var(--syntax-keyword); -} - -.observablehq>link:only-child:before { - content: ""; - visibility: visible; - text-decoration: none; - pointer-events: none; -} - -.observablehq>style:only-child:before { - content: "