From f512c24b9dafdc9ecaef829916b771e01f8863eb Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Mon, 9 Dec 2024 21:56:22 +0100 Subject: [PATCH] feat: add open telemetry instrumentation --- deno.json | 3 +- deno.lock | 10 +- src/app.ts | 20 +- src/context.ts | 35 +- src/dev/builder.ts | 2 +- src/dev/update_check.ts | 7 +- src/middlewares/static_files.ts | 114 ++-- src/otel.ts | 6 + src/plugins/fs_routes/mod.ts | 2 +- src/plugins/fs_routes/render_middleware.ts | 54 +- src/router.ts | 20 +- src/router_test.ts | 13 +- tests/fixture_update_check/mod.ts | 3 +- tests/partials_test.tsx | 2 +- tests/test_utils.tsx | 4 +- www/deno.json | 4 +- www/deno.lock | 631 ++++++++++++++++++++- www/main.ts | 1 + www/telemetry.ts | 3 + 19 files changed, 840 insertions(+), 94 deletions(-) create mode 100644 src/otel.ts create mode 100644 www/telemetry.ts diff --git a/deno.json b/deno.json index 680723cf870..6c3a0d0e050 100644 --- a/deno.json +++ b/deno.json @@ -38,6 +38,7 @@ "@fresh/plugin-tailwind": "./plugin-tailwindcss/src/mod.ts", "@luca/esbuild-deno-loader": "jsr:@luca/esbuild-deno-loader@^0.11.0", "@marvinh-test/fresh-island": "jsr:@marvinh-test/fresh-island@^0.0.1", + "@opentelemetry/api": "npm:@opentelemetry/api@^1.9.0", "@preact/signals": "npm:@preact/signals@^1.2.3", "@std/async": "jsr:@std/async@1", "@std/cli": "jsr:@std/cli@1", @@ -75,7 +76,7 @@ "ts-morph": "npm:ts-morph@^22.0.0" }, "compilerOptions": { - "lib": ["dom", "dom.asynciterable", "deno.ns"], + "lib": ["dom", "dom.asynciterable", "deno.ns", "deno.unstable"], "jsx": "precompile", "jsxImportSource": "preact", "jsxPrecompileSkipElements": ["a", "img", "source", "body", "html", "head"] diff --git a/deno.lock b/deno.lock index 02b9b5a280c..eb643d88bf5 100644 --- a/deno.lock +++ b/deno.lock @@ -36,6 +36,7 @@ "jsr:@std/toml@^1.0.1": "1.0.1", "jsr:@std/yaml@^1.0.5": "1.0.5", "jsr:@zip-js/zip-js@2.7.41": "2.7.41", + "npm:@opentelemetry/api@^1.9.0": "1.9.0", "npm:@preact/signals@1.3.0": "1.3.0_preact@10.24.2", "npm:@preact/signals@^1.2.3": "1.3.0_preact@10.24.2", "npm:@preact/signals@^1.3.0": "1.3.0_preact@10.24.2", @@ -185,7 +186,10 @@ "integrity": "7c139c6076a080eeaa4252c78b95ca5302818d7eafab0470d34cafd9930c13c8" }, "@std/streams@1.0.6": { - "integrity": "022ed94e380d06b4d91c49eb70241b7289ab78b8c2b4c4bbb7eb265e4997c25c" + "integrity": "022ed94e380d06b4d91c49eb70241b7289ab78b8c2b4c4bbb7eb265e4997c25c", + "dependencies": [ + "jsr:@std/bytes" + ] }, "@std/toml@1.0.1": { "integrity": "b55b407159930f338d384b1f8fd317c8e8a35e27ebb8946155f49e3a158d16c4", @@ -328,6 +332,9 @@ "fastq" ] }, + "@opentelemetry/api@1.9.0": { + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==" + }, "@pkgjs/parseargs@0.11.0": { "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==" }, @@ -1432,6 +1439,7 @@ "jsr:@std/path@1", "jsr:@std/semver@1", "jsr:@std/streams@1", + "npm:@opentelemetry/api@^1.9.0", "npm:@preact/signals@^1.2.3", "npm:autoprefixer@10.4.17", "npm:cssnano@6.0.3", diff --git a/src/app.ts b/src/app.ts index 44225b649c8..1f67789b460 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,3 +1,8 @@ +import * as path from "@std/path"; +import { type ComponentType, h } from "preact"; +import { renderToString } from "preact-render-to-string"; +import { trace } from "@opentelemetry/api"; + import { DENO_DEPLOYMENT_ID } from "./runtime/build_id.ts"; import * as colors from "@std/fmt/colors"; import { type MiddlewareFn, runMiddlewares } from "./middlewares/mod.ts"; @@ -14,10 +19,7 @@ import { type ResolvedFreshConfig, } from "./config.ts"; import { type BuildCache, ProdBuildCache } from "./build_cache.ts"; -import * as path from "@std/path"; -import { type ComponentType, h } from "preact"; import type { ServerIslandRegistry } from "./context.ts"; -import { renderToString } from "preact-render-to-string"; import { FinishSetup, ForgotBuild } from "./finish_setup.tsx"; import { HttpError } from "./error.ts"; @@ -140,8 +142,8 @@ export class App { // Special case when user calls one of these: // - `app.mountApp("/", otherApp)` - // - `app.mountApp("*", otherApp)` - const isSelf = path === "*" || path === "/"; + // - `app.mountApp("/*", otherApp)` + const isSelf = path === "/*" || path === "/"; if (isSelf && middlewares.length > 0) { this.#router._middlewares.push(...middlewares); } @@ -205,7 +207,7 @@ export class App { ? DEFAULT_NOT_ALLOWED_METHOD : DEFAULT_NOT_FOUND; - const { params, handlers } = matched; + const { params, handlers, pattern } = matched; const ctx = new FreshReqContext( req, url, @@ -217,6 +219,12 @@ export class App { this.#buildCache!, ); + const span = trace.getActiveSpan(); + if (span && pattern) { + span.updateName(`${method} ${pattern}`); + span.setAttribute("http.route", pattern); + } + try { if (handlers.length === 1 && handlers[0].length === 1) { return handlers[0][0](ctx); diff --git a/src/context.ts b/src/context.ts index b59dc25c475..49d6d91c9a7 100644 --- a/src/context.ts +++ b/src/context.ts @@ -6,6 +6,7 @@ import { type VNode, } from "preact"; import { renderToString } from "preact-render-to-string"; +import { SpanStatusCode } from "@opentelemetry/api"; import type { ResolvedFreshConfig } from "./config.ts"; import type { BuildCache } from "./build_cache.ts"; import { @@ -15,6 +16,7 @@ import { } from "./runtime/server/preact_hooks.tsx"; import { DEV_ERROR_OVERLAY_URL } from "./constants.ts"; import { BUILD_ID } from "./runtime/build_id.ts"; +import { tracer } from "./otel.ts"; export interface Island { file: string | URL; @@ -184,14 +186,31 @@ export class FreshReqContext headers.set("X-Fresh-Id", partialId); } - const html = preactRender( - vnode, - this, - this.#islandRegistry, - this.#buildCache, - partialId, - headers, - ); + const html = tracer.startActiveSpan("render", (span) => { + span.setAttribute("fresh.span_type", "render"); + try { + return preactRender( + vnode, + this, + this.#islandRegistry, + this.#buildCache, + partialId, + headers, + ); + } catch (err) { + if (err instanceof Error) { + span.recordException(err); + } else { + span.setStatus({ + code: SpanStatusCode.ERROR, + message: String(err), + }); + } + throw err; + } finally { + span.end(); + } + }); return new Response(html, responseInit); } } diff --git a/src/dev/builder.ts b/src/dev/builder.ts index f6e7a4836d5..bfa6c91f293 100644 --- a/src/dev/builder.ts +++ b/src/dev/builder.ts @@ -68,7 +68,7 @@ export class Builder implements FreshBuilder { const devApp = new App(app.config) .use(liveReload()) .use(devErrorOverlay()) - .mountApp("*", app); + .mountApp("/*", app); devApp.config.mode = "development"; diff --git a/src/dev/update_check.ts b/src/dev/update_check.ts index e78ba0cd036..7fc689db83b 100644 --- a/src/dev/update_check.ts +++ b/src/dev/update_check.ts @@ -1,6 +1,7 @@ import * as semver from "@std/semver"; import * as colors from "@std/fmt/colors"; import * as path from "@std/path"; +import { CURRENT_FRESH_VERSION } from "../otel.ts"; export interface CheckFile { last_checked: string; @@ -48,10 +49,8 @@ async function fetchLatestVersion() { throw new Error(`Could not fetch latest version.`); } -async function readCurrentVersion() { - return (await import("../../deno.json", { - with: { type: "json" }, - })).default.version; +function readCurrentVersion() { + return CURRENT_FRESH_VERSION; } export async function updateCheck( diff --git a/src/middlewares/static_files.ts b/src/middlewares/static_files.ts index 7bf84ae330f..c4f08ec60ff 100644 --- a/src/middlewares/static_files.ts +++ b/src/middlewares/static_files.ts @@ -4,6 +4,7 @@ import type { MiddlewareFn } from "./mod.ts"; import { ASSET_CACHE_BUST_KEY } from "../runtime/shared_internal.tsx"; import { BUILD_ID } from "../runtime/build_id.ts"; import { getBuildCache } from "../context.ts"; +import { tracer } from "../otel.ts"; /** * Fresh middleware to enable file-system based routing. @@ -25,6 +26,7 @@ export function staticFiles(): MiddlewareFn { } // Fast path bail out + const startTime = performance.now() + performance.timeOrigin; const file = await buildCache.readFile(pathname); if (pathname === "/" || file === null) { // Optimization: Prevent long responses for favicon.ico requests @@ -39,60 +41,74 @@ export function staticFiles(): MiddlewareFn { return new Response("Method Not Allowed", { status: 405 }); } - const cacheKey = url.searchParams.get(ASSET_CACHE_BUST_KEY); - if (cacheKey !== null && BUILD_ID !== cacheKey) { - url.searchParams.delete(ASSET_CACHE_BUST_KEY); - const location = url.pathname + url.search; - file.close(); - return new Response(null, { - status: 307, - headers: { - location, - }, - }); - } + const span = tracer.startSpan("static file", { + attributes: { "fresh.span_type": "static_file" }, + startTime, + }); - const ext = path.extname(pathname); - const etag = file.hash; + try { + const cacheKey = url.searchParams.get(ASSET_CACHE_BUST_KEY); + if (cacheKey !== null && BUILD_ID !== cacheKey) { + url.searchParams.delete(ASSET_CACHE_BUST_KEY); + const location = url.pathname + url.search; + file.close(); + span.setAttribute("fresh.cache", "invalid_bust_key"); + span.setAttribute("fresh.cache_key", cacheKey); + return new Response(null, { + status: 307, + headers: { + location, + }, + }); + } - const contentType = getContentType(ext); - const headers = new Headers({ - "Content-Type": contentType ?? "text/plain", - vary: "If-None-Match", - }); + const ext = path.extname(pathname); + const etag = file.hash; - const ifNoneMatch = req.headers.get("If-None-Match"); - if ( - ifNoneMatch !== null && - (ifNoneMatch === etag || ifNoneMatch === `W/"${etag}"`) - ) { - file.close(); - return new Response(null, { status: 304, headers }); - } else if (etag !== null) { - headers.set("Etag", `W/"${etag}"`); - } + const contentType = getContentType(ext); + const headers = new Headers({ + "Content-Type": contentType ?? "text/plain", + vary: "If-None-Match", + }); - if ( - ctx.config.mode !== "development" && - (BUILD_ID === cacheKey || - url.pathname.startsWith( - `${ctx.config.basePath}/_fresh/js/${BUILD_ID}/`, - )) - ) { - headers.append("Cache-Control", "public, max-age=31536000, immutable"); - } else { - headers.append( - "Cache-Control", - "no-cache, no-store, max-age=0, must-revalidate", - ); - } + const ifNoneMatch = req.headers.get("If-None-Match"); + if ( + ifNoneMatch !== null && + (ifNoneMatch === etag || ifNoneMatch === `W/"${etag}"`) + ) { + file.close(); + span.setAttribute("fresh.cache", "not_modified"); + return new Response(null, { status: 304, headers }); + } else if (etag !== null) { + headers.set("Etag", `W/"${etag}"`); + } - headers.set("Content-Length", String(file.size)); - if (req.method === "HEAD") { - file.close(); - return new Response(null, { status: 200, headers }); - } + if ( + ctx.config.mode !== "development" && + (BUILD_ID === cacheKey || + url.pathname.startsWith( + `${ctx.config.basePath}/_fresh/js/${BUILD_ID}/`, + )) + ) { + span.setAttribute("fresh.cache", "immutable"); + headers.append("Cache-Control", "public, max-age=31536000, immutable"); + } else { + span.setAttribute("fresh.cache", "no_cache"); + headers.append( + "Cache-Control", + "no-cache, no-store, max-age=0, must-revalidate", + ); + } + + headers.set("Content-Length", String(file.size)); + if (req.method === "HEAD") { + file.close(); + return new Response(null, { status: 200, headers }); + } - return new Response(file.readable, { headers }); + return new Response(file.readable, { headers }); + } finally { + span.end(); + } }; } diff --git a/src/otel.ts b/src/otel.ts new file mode 100644 index 00000000000..45c5633efda --- /dev/null +++ b/src/otel.ts @@ -0,0 +1,6 @@ +import { trace } from "@opentelemetry/api"; +import denoJson from "../deno.json" with { type: "json" }; + +export const CURRENT_FRESH_VERSION = denoJson.version; + +export const tracer = trace.getTracer("fresh", CURRENT_FRESH_VERSION); diff --git a/src/plugins/fs_routes/mod.ts b/src/plugins/fs_routes/mod.ts index c44e3d8bbc0..c85b0ace634 100644 --- a/src/plugins/fs_routes/mod.ts +++ b/src/plugins/fs_routes/mod.ts @@ -251,7 +251,7 @@ export async function fsRoutes( errorComponents.push(mod.component); } let parent = mod.path.slice(0, -"_error".length); - parent = parent === "/" ? "*" : parent + "*"; + parent = parent + "*"; // Add error route as its own route if (!specialPaths.has(mod.path)) { diff --git a/src/plugins/fs_routes/render_middleware.ts b/src/plugins/fs_routes/render_middleware.ts index ccd7f04f5a1..526a7645d0a 100644 --- a/src/plugins/fs_routes/render_middleware.ts +++ b/src/plugins/fs_routes/render_middleware.ts @@ -3,6 +3,8 @@ import type { MiddlewareFn } from "../../middlewares/mod.ts"; import type { HandlerFn, PageResponse } from "../../handlers.ts"; import type { FreshReqContext, PageProps } from "../../context.ts"; import { HttpError } from "../../error.ts"; +import { tracer } from "../../otel.ts"; +import { SpanStatusCode } from "@opentelemetry/api"; export type AsyncAnyComponent

= { ( @@ -31,7 +33,30 @@ export function renderMiddleware( return async (ctx) => { let result: PageResponse | undefined; if (handler !== undefined) { - const res = await handler(ctx); + const res = await tracer.startActiveSpan("handler", { + attributes: { "fresh.span_type": "fs_routes/handler" }, + }, async (span) => { + try { + const res = await handler(ctx); + span.setAttribute( + "fresh.handler_response", + res instanceof Response ? "http" : "data", + ); + return res; + } catch (err) { + if (err instanceof Error) { + span.recordException(err); + } else { + span.setStatus({ + code: SpanStatusCode.ERROR, + message: String(err), + }); + } + throw err; + } finally { + span.end(); + } + }); if (res instanceof Response) { return res; @@ -56,7 +81,32 @@ export function renderMiddleware( const fn = components[i]; if (isAsyncAnyComponent(fn)) { - const result = (await fn(props)) as VNode | Response; + const result = await tracer.startActiveSpan( + "invoke async component", + async (span) => { + span.setAttribute("fresh.span_type", "fs_routes/async_component"); + try { + const result = (await fn(props)) as VNode | Response; + span.setAttribute( + "fresh.component_response", + result instanceof Response ? "http" : "jsx", + ); + return result; + } catch (err) { + if (err instanceof Error) { + span.recordException(err); + } else { + span.setStatus({ + code: SpanStatusCode.ERROR, + message: String(err), + }); + } + throw err; + } finally { + span.end(); + } + }, + ); if (result instanceof Response) { return result; } diff --git a/src/router.ts b/src/router.ts index f8b7a55006e..34e85bcdbd7 100644 --- a/src/router.ts +++ b/src/router.ts @@ -11,6 +11,7 @@ export interface RouteResult { handlers: T[][]; methodMatch: boolean; patternMatch: boolean; + pattern: string | null; } export interface Router { @@ -28,7 +29,7 @@ export interface Router { export const IS_PATTERN = /[*:{}+?()]/; export function mergePaths(a: string, b: string) { - if (a === "" || a === "/" || a === "*") return b; + if (a === "" || a === "/" || a === "/*") return b; if (b === "/") return a; if (a.endsWith("/")) { return a.slice(0, -1) + b; @@ -48,7 +49,7 @@ export class UrlPatternRouter implements Router { add(method: Method | "ALL", pathname: string | URLPattern, handlers: T[]) { if ( - typeof pathname === "string" && pathname !== "*" && + typeof pathname === "string" && pathname !== "/*" && IS_PATTERN.test(pathname) ) { this._routes.push({ @@ -71,6 +72,7 @@ export class UrlPatternRouter implements Router { handlers: [], methodMatch: false, patternMatch: false, + pattern: null, }; if (this._middlewares.length > 0) { @@ -84,16 +86,15 @@ export class UrlPatternRouter implements Router { // to be either wildcard `*` match or an exact pathname match. if ( typeof route.path === "string" && - (route.path === "*" || route.path === url.pathname) + (route.path === "/*" || route.path === url.pathname) ) { - if (route.method !== "ALL") { - result.patternMatch = true; - } + if (route.method !== "ALL") result.patternMatch = true; + result.pattern = route.path; if (route.method === "ALL" || route.method === method) { result.handlers.push(route.handlers); - if (route.path === "*" && route.method === "ALL") { + if (route.path === "/*" && route.method === "ALL") { continue; } @@ -104,9 +105,8 @@ export class UrlPatternRouter implements Router { } else if (route.path instanceof URLPattern) { const match = route.path.exec(url); if (match !== null) { - if (route.method !== "ALL") { - result.patternMatch = true; - } + if (route.method !== "ALL") result.patternMatch = true; + result.pattern = route.path.pathname; if (route.method === "ALL" || route.method === method) { result.handlers.push(route.handlers); diff --git a/src/router_test.ts b/src/router_test.ts index 7c2e46ef52d..97addf3c0f7 100644 --- a/src/router_test.ts +++ b/src/router_test.ts @@ -30,6 +30,7 @@ Deno.test("UrlPatternRouter - GET get first match", () => { params: {}, handlers: [[A]], methodMatch: true, + pattern: "/", patternMatch: true, }); }); @@ -39,8 +40,8 @@ Deno.test("UrlPatternRouter - GET get matches with middlewares", () => { const A = () => {}; const B = () => {}; const C = () => {}; - router.add("ALL", "*", [A]); - router.add("ALL", "*", [B]); + router.add("ALL", "/*", [A]); + router.add("ALL", "/*", [B]); router.add("GET", "/", [C]); const res = router.match("GET", new URL("/", "http://localhost")); @@ -48,6 +49,7 @@ Deno.test("UrlPatternRouter - GET get matches with middlewares", () => { params: {}, handlers: [[A], [B], [C]], methodMatch: true, + pattern: "/", patternMatch: true, }); }); @@ -62,6 +64,7 @@ Deno.test("UrlPatternRouter - GET extract params", () => { params: { foo: "a", bar: "b" }, handlers: [[A]], methodMatch: true, + pattern: "/:foo/:bar/c", patternMatch: true, }); @@ -71,6 +74,7 @@ Deno.test("UrlPatternRouter - GET extract params", () => { params: { foo: "a a", bar: "b" }, handlers: [[A]], methodMatch: true, + pattern: "/:foo/:bar/c", patternMatch: true, }); }); @@ -85,6 +89,7 @@ Deno.test("UrlPatternRouter - Wrong method match", () => { params: {}, handlers: [], methodMatch: false, + pattern: "/foo", patternMatch: true, }); }); @@ -101,6 +106,7 @@ Deno.test("UrlPatternRouter - wrong + correct method", () => { params: {}, handlers: [[B]], methodMatch: true, + pattern: "/foo", patternMatch: true, }); }); @@ -117,6 +123,7 @@ Deno.test("UrlPatternRouter - convert patterns automatically", () => { }, handlers: [[A]], methodMatch: true, + pattern: "/books/:id", patternMatch: true, }); }); @@ -173,7 +180,7 @@ Deno.test("pathToPattern", async (t) => { Deno.test("mergePaths", () => { expect(mergePaths("", "")).toEqual(""); expect(mergePaths("/", "/foo")).toEqual("/foo"); - expect(mergePaths("*", "/foo")).toEqual("/foo"); + expect(mergePaths("/*", "/foo")).toEqual("/foo"); expect(mergePaths("/foo/bar", "/baz")).toEqual("/foo/bar/baz"); expect(mergePaths("/foo/bar/", "/baz")).toEqual("/foo/bar/baz"); expect(mergePaths("/foo/bar", "baz")).toEqual("/foo/bar/baz"); diff --git a/tests/fixture_update_check/mod.ts b/tests/fixture_update_check/mod.ts index e2c8b695cf4..b10801104f9 100644 --- a/tests/fixture_update_check/mod.ts +++ b/tests/fixture_update_check/mod.ts @@ -8,8 +8,7 @@ async function getLatestVersion() { return Deno.env.get("LATEST_VERSION") ?? "99.99.999"; } -// deno-lint-ignore require-await -async function getCurrentVersion() { +function getCurrentVersion() { return Deno.env.get("CURRENT_VERSION")!; } diff --git a/tests/partials_test.tsx b/tests/partials_test.tsx index ead9409e46d..a547c2a2f4c 100644 --- a/tests/partials_test.tsx +++ b/tests/partials_test.tsx @@ -2599,7 +2599,7 @@ Deno.test({ , ); }) - .get("*", (ctx) => { + .get("/*", (ctx) => { return ctx.render( diff --git a/tests/test_utils.tsx b/tests/test_utils.tsx index fc0bc6ebac4..d94d62bc214 100644 --- a/tests/test_utils.tsx +++ b/tests/test_utils.tsx @@ -92,7 +92,7 @@ export async function withBrowserApp( }, await app.handler()); const browser = await launch({ - args: ["--window-size=1280,720"], + args: ["--window-size=1280,720", "--no-sandbox"], headless: !Deno.args.includes("--headful"), }); @@ -113,7 +113,7 @@ export async function withBrowser(fn: (page: Page) => void | Promise) { const aborter = new AbortController(); try { const browser = await launch({ - args: ["--window-size=1280,720"], + args: ["--window-size=1280,720", "--no-sandbox"], headless: !Deno.args.includes("--headful"), }); diff --git a/www/deno.json b/www/deno.json index 2f9180bb004..62385b7f4c2 100644 --- a/www/deno.json +++ b/www/deno.json @@ -1,4 +1,5 @@ { + "unstable": ["otel"], "tasks": { "start": "deno run -A --watch=static/,routes/,../src,../docs dev.ts", "build": "deno run -A dev.ts build", @@ -20,6 +21,7 @@ "@std/media-types": "jsr:@std/media-types@1", "@std/path": "jsr:@std/path@1", "@std/semver": "jsr:@std/semver@1", + "@opentelemetry/api": "npm:@opentelemetry/api@^1.9.0", "autoprefixer": "npm:autoprefixer@10.4.17", "cssnano": "npm:cssnano@6.0.3", "esbuild": "npm:esbuild@0.23.1", @@ -39,7 +41,7 @@ "tailwindcss/plugin": "npm:/tailwindcss@^3.4.1/plugin.js" }, "compilerOptions": { - "lib": ["dom", "dom.asynciterable", "deno.ns"], + "lib": ["dom", "dom.asynciterable", "deno.ns", "deno.unstable"], "jsx": "precompile", "jsxImportSource": "preact", "jsxPrecompileSkipElements": ["a", "img", "source", "body", "html", "head"] diff --git a/www/deno.lock b/www/deno.lock index e331d359b93..4c2da942ab4 100644 --- a/www/deno.lock +++ b/www/deno.lock @@ -1,18 +1,33 @@ { "version": "4", "specifiers": { + "jsr:@deno/otel@*": "0.0.2", + "jsr:@luca/esbuild-deno-loader@0.11": "0.11.0", + "jsr:@std/bytes@^1.0.2": "1.0.4", "jsr:@std/collections@^1.0.5": "1.0.8", + "jsr:@std/crypto@1": "1.0.3", + "jsr:@std/datetime@0.225.0": "0.225.0", "jsr:@std/encoding@1": "1.0.5", + "jsr:@std/encoding@^1.0.5": "1.0.5", "jsr:@std/fmt@1": "1.0.2", "jsr:@std/front-matter@^1.0.5": "1.0.5", "jsr:@std/fs@1": "1.0.4", "jsr:@std/html@1": "1.0.3", + "jsr:@std/jsonc@1": "1.0.1", "jsr:@std/media-types@1": "1.0.3", "jsr:@std/path@1": "1.0.6", "jsr:@std/path@^1.0.6": "1.0.6", + "jsr:@std/semver@1": "1.0.3", "jsr:@std/toml@^1.0.1": "1.0.1", "jsr:@std/yaml@^1.0.5": "1.0.5", + "npm:@opentelemetry/api@1": "1.9.0", + "npm:@opentelemetry/api@^1.9.0": "1.9.0", + "npm:@opentelemetry/sdk-trace-base@1": "1.28.0_@opentelemetry+api@1.9.0", "npm:@preact/signals@^1.3.0": "1.3.0_preact@10.24.3", + "npm:autoprefixer@10.4.17": "10.4.17_postcss@8.4.35", + "npm:cssnano@6.0.3": "6.0.3_postcss@8.4.35", + "npm:esbuild-wasm@0.23.1": "0.23.1", + "npm:esbuild@0.23.1": "0.23.1", "npm:github-slugger@2": "2.0.0", "npm:marked-mangle@^1.1.9": "1.1.9_marked@14.1.2", "npm:marked@^14.1.2": "14.1.2", @@ -23,9 +38,33 @@ "npm:tailwindcss@^3.4.1": "3.4.13_postcss@8.4.35" }, "jsr": { + "@deno/otel@0.0.2": { + "integrity": "4ef61b7eb1c4063f8224d66fc43f25e428a566d2e18785d0dc67bb70a318f0ff", + "dependencies": [ + "npm:@opentelemetry/api@1", + "npm:@opentelemetry/sdk-trace-base" + ] + }, + "@luca/esbuild-deno-loader@0.11.0": { + "integrity": "c05a989aa7c4ee6992a27be5f15cfc5be12834cab7ff84cabb47313737c51a2c", + "dependencies": [ + "jsr:@std/bytes", + "jsr:@std/encoding@^1.0.5", + "jsr:@std/path@^1.0.6" + ] + }, + "@std/bytes@1.0.4": { + "integrity": "11a0debe522707c95c7b7ef89b478c13fb1583a7cfb9a85674cd2cc2e3a28abc" + }, "@std/collections@1.0.8": { "integrity": "de76692f9121838711b1d2fb5042619c074db26905a87b58cff56cfe1bd6d6d0" }, + "@std/crypto@1.0.3": { + "integrity": "a2a32f51ddef632d299e3879cd027c630dcd4d1d9a5285d6e6788072f4e51e7f" + }, + "@std/datetime@0.225.0": { + "integrity": "73ee4457218e06f50d3680fb0c430ba94006305e4104c84e783b3f5c0ec78900" + }, "@std/encoding@1.0.5": { "integrity": "ecf363d4fc25bd85bd915ff6733a7e79b67e0e7806334af15f4645c569fefc04" }, @@ -48,12 +87,18 @@ "@std/html@1.0.3": { "integrity": "7a0ac35e050431fb49d44e61c8b8aac1ebd55937e0dc9ec6409aa4bab39a7988" }, + "@std/jsonc@1.0.1": { + "integrity": "6b36956e2a7cbb08ca5ad7fbec72e661e6217c202f348496ea88747636710dda" + }, "@std/media-types@1.0.3": { "integrity": "b12d30a7852f7578f4d210622df713bbfd1cbdd9b4ec2eaf5c1845ab70bab159" }, "@std/path@1.0.6": { "integrity": "ab2c55f902b380cf28e0eec501b4906e4c1960d13f00e11cfbcd21de15f18fed" }, + "@std/semver@1.0.3": { + "integrity": "7c139c6076a080eeaa4252c78b95ca5302818d7eafab0470d34cafd9930c13c8" + }, "@std/toml@1.0.1": { "integrity": "b55b407159930f338d384b1f8fd317c8e8a35e27ebb8946155f49e3a158d16c4", "dependencies": [ @@ -68,6 +113,78 @@ "@alloc/quick-lru@5.2.0": { "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==" }, + "@esbuild/aix-ppc64@0.23.1": { + "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==" + }, + "@esbuild/android-arm64@0.23.1": { + "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==" + }, + "@esbuild/android-arm@0.23.1": { + "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==" + }, + "@esbuild/android-x64@0.23.1": { + "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==" + }, + "@esbuild/darwin-arm64@0.23.1": { + "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==" + }, + "@esbuild/darwin-x64@0.23.1": { + "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==" + }, + "@esbuild/freebsd-arm64@0.23.1": { + "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==" + }, + "@esbuild/freebsd-x64@0.23.1": { + "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==" + }, + "@esbuild/linux-arm64@0.23.1": { + "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==" + }, + "@esbuild/linux-arm@0.23.1": { + "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==" + }, + "@esbuild/linux-ia32@0.23.1": { + "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==" + }, + "@esbuild/linux-loong64@0.23.1": { + "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==" + }, + "@esbuild/linux-mips64el@0.23.1": { + "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==" + }, + "@esbuild/linux-ppc64@0.23.1": { + "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==" + }, + "@esbuild/linux-riscv64@0.23.1": { + "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==" + }, + "@esbuild/linux-s390x@0.23.1": { + "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==" + }, + "@esbuild/linux-x64@0.23.1": { + "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==" + }, + "@esbuild/netbsd-x64@0.23.1": { + "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==" + }, + "@esbuild/openbsd-arm64@0.23.1": { + "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==" + }, + "@esbuild/openbsd-x64@0.23.1": { + "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==" + }, + "@esbuild/sunos-x64@0.23.1": { + "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==" + }, + "@esbuild/win32-arm64@0.23.1": { + "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==" + }, + "@esbuild/win32-ia32@0.23.1": { + "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==" + }, + "@esbuild/win32-x64@0.23.1": { + "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==" + }, "@isaacs/cliui@8.0.2": { "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dependencies": [ @@ -120,6 +237,36 @@ "fastq" ] }, + "@opentelemetry/api@1.9.0": { + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==" + }, + "@opentelemetry/core@1.28.0_@opentelemetry+api@1.9.0": { + "integrity": "sha512-ZLwRMV+fNDpVmF2WYUdBHlq0eOWtEaUJSusrzjGnBt7iSRvfjFE3RXYUZJrqou/wIDWV0DwQ5KIfYe9WXg9Xqw==", + "dependencies": [ + "@opentelemetry/api", + "@opentelemetry/semantic-conventions" + ] + }, + "@opentelemetry/resources@1.28.0_@opentelemetry+api@1.9.0": { + "integrity": "sha512-cIyXSVJjGeTICENN40YSvLDAq4Y2502hGK3iN7tfdynQLKWb3XWZQEkPc+eSx47kiy11YeFAlYkEfXwR1w8kfw==", + "dependencies": [ + "@opentelemetry/api", + "@opentelemetry/core", + "@opentelemetry/semantic-conventions" + ] + }, + "@opentelemetry/sdk-trace-base@1.28.0_@opentelemetry+api@1.9.0": { + "integrity": "sha512-ceUVWuCpIao7Y5xE02Xs3nQi0tOGmMea17ecBdwtCvdo9ekmO+ijc9RFDgfifMl7XCBf41zne/1POM3LqSTZDA==", + "dependencies": [ + "@opentelemetry/api", + "@opentelemetry/core", + "@opentelemetry/resources", + "@opentelemetry/semantic-conventions" + ] + }, + "@opentelemetry/semantic-conventions@1.27.0": { + "integrity": "sha512-sAay1RrB+ONOem0OZanAR1ZI/k7yDpnOQSQmTMuGImUQb2y8EbSaCJ94FQluM74xoU03vlb2d2U90hZluL6nQg==" + }, "@pkgjs/parseargs@0.11.0": { "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==" }, @@ -133,6 +280,9 @@ "preact" ] }, + "@trysound/sax@0.2.0": { + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==" + }, "ansi-regex@5.0.1": { "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, @@ -161,12 +311,27 @@ "arg@5.0.2": { "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" }, + "autoprefixer@10.4.17_postcss@8.4.35": { + "integrity": "sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==", + "dependencies": [ + "browserslist", + "caniuse-lite", + "fraction.js", + "normalize-range", + "picocolors", + "postcss", + "postcss-value-parser" + ] + }, "balanced-match@1.0.2": { "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "binary-extensions@2.3.0": { "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==" }, + "boolbase@1.0.0": { + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, "brace-expansion@2.0.1": { "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dependencies": [ @@ -179,9 +344,30 @@ "fill-range" ] }, + "browserslist@4.24.2": { + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "dependencies": [ + "caniuse-lite", + "electron-to-chromium", + "node-releases", + "update-browserslist-db" + ] + }, "camelcase-css@2.0.1": { "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==" }, + "caniuse-api@3.0.0": { + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dependencies": [ + "browserslist", + "caniuse-lite", + "lodash.memoize", + "lodash.uniq" + ] + }, + "caniuse-lite@1.0.30001686": { + "integrity": "sha512-Y7deg0Aergpa24M3qLC5xjNklnKnhsmSyR/V89dLZ1n0ucJIFNs7PgR2Yfa/Zf6W79SbBicgtGxZr2juHkEUIA==" + }, "chokidar@3.6.0": { "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dependencies": [ @@ -204,9 +390,15 @@ "color-name@1.1.4": { "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "colord@2.9.3": { + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" + }, "commander@4.1.1": { "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" }, + "commander@7.2.0": { + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" + }, "cross-spawn@7.0.3": { "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dependencies": [ @@ -215,24 +407,179 @@ "which" ] }, + "css-declaration-sorter@7.2.0_postcss@8.4.35": { + "integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==", + "dependencies": [ + "postcss" + ] + }, + "css-select@5.1.0": { + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dependencies": [ + "boolbase", + "css-what", + "domhandler", + "domutils", + "nth-check" + ] + }, + "css-tree@2.2.1": { + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dependencies": [ + "mdn-data@2.0.28", + "source-map-js" + ] + }, + "css-tree@2.3.1": { + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dependencies": [ + "mdn-data@2.0.30", + "source-map-js" + ] + }, + "css-what@6.1.0": { + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==" + }, "cssesc@3.0.0": { "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" }, + "cssnano-preset-default@6.1.2_postcss@8.4.35": { + "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", + "dependencies": [ + "browserslist", + "css-declaration-sorter", + "cssnano-utils", + "postcss", + "postcss-calc", + "postcss-colormin", + "postcss-convert-values", + "postcss-discard-comments", + "postcss-discard-duplicates", + "postcss-discard-empty", + "postcss-discard-overridden", + "postcss-merge-longhand", + "postcss-merge-rules", + "postcss-minify-font-values", + "postcss-minify-gradients", + "postcss-minify-params", + "postcss-minify-selectors", + "postcss-normalize-charset", + "postcss-normalize-display-values", + "postcss-normalize-positions", + "postcss-normalize-repeat-style", + "postcss-normalize-string", + "postcss-normalize-timing-functions", + "postcss-normalize-unicode", + "postcss-normalize-url", + "postcss-normalize-whitespace", + "postcss-ordered-values", + "postcss-reduce-initial", + "postcss-reduce-transforms", + "postcss-svgo", + "postcss-unique-selectors" + ] + }, + "cssnano-utils@4.0.2_postcss@8.4.35": { + "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", + "dependencies": [ + "postcss" + ] + }, + "cssnano@6.0.3_postcss@8.4.35": { + "integrity": "sha512-MRq4CIj8pnyZpcI2qs6wswoYoDD1t0aL28n+41c1Ukcpm56m1h6mCexIHBGjfZfnTqtGSSCP4/fB1ovxgjBOiw==", + "dependencies": [ + "cssnano-preset-default", + "lilconfig@3.1.2", + "postcss" + ] + }, + "csso@5.0.5": { + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "dependencies": [ + "css-tree@2.2.1" + ] + }, "didyoumean@1.2.2": { "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" }, "dlv@1.1.3": { "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" }, + "dom-serializer@2.0.0": { + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dependencies": [ + "domelementtype", + "domhandler", + "entities" + ] + }, + "domelementtype@2.3.0": { + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" + }, + "domhandler@5.0.3": { + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dependencies": [ + "domelementtype" + ] + }, + "domutils@3.1.0": { + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dependencies": [ + "dom-serializer", + "domelementtype", + "domhandler" + ] + }, "eastasianwidth@0.2.0": { "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, + "electron-to-chromium@1.5.65": { + "integrity": "sha512-PWVzBjghx7/wop6n22vS2MLU8tKGd4Q91aCEGhG/TYmW6PP5OcSXcdnxTe1NNt0T66N8D6jxh4kC8UsdzOGaIw==" + }, "emoji-regex@8.0.0": { "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "emoji-regex@9.2.2": { "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, + "entities@4.5.0": { + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" + }, + "esbuild-wasm@0.23.1": { + "integrity": "sha512-L3vn7ctvBrtScRfoB0zG1eOCiV4xYvpLYWfe6PDZuV+iDFDm4Mt3xeLIDllG8cDHQ8clUouK3XekulE+cxgkgw==" + }, + "esbuild@0.23.1": { + "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", + "dependencies": [ + "@esbuild/aix-ppc64", + "@esbuild/android-arm", + "@esbuild/android-arm64", + "@esbuild/android-x64", + "@esbuild/darwin-arm64", + "@esbuild/darwin-x64", + "@esbuild/freebsd-arm64", + "@esbuild/freebsd-x64", + "@esbuild/linux-arm", + "@esbuild/linux-arm64", + "@esbuild/linux-ia32", + "@esbuild/linux-loong64", + "@esbuild/linux-mips64el", + "@esbuild/linux-ppc64", + "@esbuild/linux-riscv64", + "@esbuild/linux-s390x", + "@esbuild/linux-x64", + "@esbuild/netbsd-x64", + "@esbuild/openbsd-arm64", + "@esbuild/openbsd-x64", + "@esbuild/sunos-x64", + "@esbuild/win32-arm64", + "@esbuild/win32-ia32", + "@esbuild/win32-x64" + ] + }, + "escalade@3.2.0": { + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==" + }, "fast-glob@3.3.2": { "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dependencies": [ @@ -262,6 +609,9 @@ "signal-exit" ] }, + "fraction.js@4.3.7": { + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==" + }, "fsevents@2.3.3": { "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==" }, @@ -349,6 +699,12 @@ "lines-and-columns@1.2.4": { "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, + "lodash.memoize@4.1.2": { + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" + }, + "lodash.uniq@4.5.0": { + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + }, "lru-cache@10.4.3": { "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" }, @@ -361,6 +717,12 @@ "marked@14.1.2": { "integrity": "sha512-f3r0yqpz31VXiDB/wj9GaOB0a2PRLQl6vJmXiFrniNwjkKdvakqJRULhjFKJpxOchlCRiG5fcacoUZY5Xa6PEQ==" }, + "mdn-data@2.0.28": { + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==" + }, + "mdn-data@2.0.30": { + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" + }, "merge2@1.4.1": { "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" }, @@ -391,9 +753,21 @@ "nanoid@3.3.7": { "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==" }, + "node-releases@2.0.18": { + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" + }, "normalize-path@3.0.0": { "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, + "normalize-range@0.1.2": { + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==" + }, + "nth-check@2.1.1": { + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dependencies": [ + "boolbase" + ] + }, "object-assign@4.1.1": { "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, @@ -428,6 +802,56 @@ "pirates@4.0.6": { "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==" }, + "postcss-calc@9.0.1_postcss@8.4.35": { + "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", + "dependencies": [ + "postcss", + "postcss-selector-parser", + "postcss-value-parser" + ] + }, + "postcss-colormin@6.1.0_postcss@8.4.35": { + "integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==", + "dependencies": [ + "browserslist", + "caniuse-api", + "colord", + "postcss", + "postcss-value-parser" + ] + }, + "postcss-convert-values@6.1.0_postcss@8.4.35": { + "integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==", + "dependencies": [ + "browserslist", + "postcss", + "postcss-value-parser" + ] + }, + "postcss-discard-comments@6.0.2_postcss@8.4.35": { + "integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==", + "dependencies": [ + "postcss" + ] + }, + "postcss-discard-duplicates@6.0.3_postcss@8.4.35": { + "integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==", + "dependencies": [ + "postcss" + ] + }, + "postcss-discard-empty@6.0.3_postcss@8.4.35": { + "integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==", + "dependencies": [ + "postcss" + ] + }, + "postcss-discard-overridden@6.0.2_postcss@8.4.35": { + "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", + "dependencies": [ + "postcss" + ] + }, "postcss-import@15.1.0_postcss@8.4.35": { "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", "dependencies": [ @@ -452,6 +876,56 @@ "yaml" ] }, + "postcss-merge-longhand@6.0.5_postcss@8.4.35": { + "integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==", + "dependencies": [ + "postcss", + "postcss-value-parser", + "stylehacks" + ] + }, + "postcss-merge-rules@6.1.1_postcss@8.4.35": { + "integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==", + "dependencies": [ + "browserslist", + "caniuse-api", + "cssnano-utils", + "postcss", + "postcss-selector-parser" + ] + }, + "postcss-minify-font-values@6.1.0_postcss@8.4.35": { + "integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==", + "dependencies": [ + "postcss", + "postcss-value-parser" + ] + }, + "postcss-minify-gradients@6.0.3_postcss@8.4.35": { + "integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==", + "dependencies": [ + "colord", + "cssnano-utils", + "postcss", + "postcss-value-parser" + ] + }, + "postcss-minify-params@6.1.0_postcss@8.4.35": { + "integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==", + "dependencies": [ + "browserslist", + "cssnano-utils", + "postcss", + "postcss-value-parser" + ] + }, + "postcss-minify-selectors@6.0.4_postcss@8.4.35": { + "integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==", + "dependencies": [ + "postcss", + "postcss-selector-parser" + ] + }, "postcss-nested@6.2.0_postcss@8.4.35": { "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", "dependencies": [ @@ -459,6 +933,92 @@ "postcss-selector-parser" ] }, + "postcss-normalize-charset@6.0.2_postcss@8.4.35": { + "integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==", + "dependencies": [ + "postcss" + ] + }, + "postcss-normalize-display-values@6.0.2_postcss@8.4.35": { + "integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==", + "dependencies": [ + "postcss", + "postcss-value-parser" + ] + }, + "postcss-normalize-positions@6.0.2_postcss@8.4.35": { + "integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==", + "dependencies": [ + "postcss", + "postcss-value-parser" + ] + }, + "postcss-normalize-repeat-style@6.0.2_postcss@8.4.35": { + "integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==", + "dependencies": [ + "postcss", + "postcss-value-parser" + ] + }, + "postcss-normalize-string@6.0.2_postcss@8.4.35": { + "integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==", + "dependencies": [ + "postcss", + "postcss-value-parser" + ] + }, + "postcss-normalize-timing-functions@6.0.2_postcss@8.4.35": { + "integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==", + "dependencies": [ + "postcss", + "postcss-value-parser" + ] + }, + "postcss-normalize-unicode@6.1.0_postcss@8.4.35": { + "integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==", + "dependencies": [ + "browserslist", + "postcss", + "postcss-value-parser" + ] + }, + "postcss-normalize-url@6.0.2_postcss@8.4.35": { + "integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==", + "dependencies": [ + "postcss", + "postcss-value-parser" + ] + }, + "postcss-normalize-whitespace@6.0.2_postcss@8.4.35": { + "integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==", + "dependencies": [ + "postcss", + "postcss-value-parser" + ] + }, + "postcss-ordered-values@6.0.2_postcss@8.4.35": { + "integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==", + "dependencies": [ + "cssnano-utils", + "postcss", + "postcss-value-parser" + ] + }, + "postcss-reduce-initial@6.1.0_postcss@8.4.35": { + "integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==", + "dependencies": [ + "browserslist", + "caniuse-api", + "postcss" + ] + }, + "postcss-reduce-transforms@6.0.2_postcss@8.4.35": { + "integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==", + "dependencies": [ + "postcss", + "postcss-value-parser" + ] + }, "postcss-selector-parser@6.1.2": { "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "dependencies": [ @@ -466,6 +1026,21 @@ "util-deprecate" ] }, + "postcss-svgo@6.0.3_postcss@8.4.35": { + "integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==", + "dependencies": [ + "postcss", + "postcss-value-parser", + "svgo" + ] + }, + "postcss-unique-selectors@6.0.4_postcss@8.4.35": { + "integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==", + "dependencies": [ + "postcss", + "postcss-selector-parser" + ] + }, "postcss-value-parser@4.2.0": { "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, @@ -564,11 +1139,19 @@ "ansi-regex@6.1.0" ] }, + "stylehacks@6.1.1_postcss@8.4.35": { + "integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==", + "dependencies": [ + "browserslist", + "postcss", + "postcss-selector-parser" + ] + }, "sucrase@3.35.0": { "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", "dependencies": [ "@jridgewell/gen-mapping", - "commander", + "commander@4.1.1", "glob", "lines-and-columns", "mz", @@ -579,6 +1162,18 @@ "supports-preserve-symlinks-flag@1.0.0": { "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, + "svgo@3.3.2": { + "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", + "dependencies": [ + "@trysound/sax", + "commander@7.2.0", + "css-select", + "css-tree@2.3.1", + "css-what", + "csso", + "picocolors" + ] + }, "tailwindcss@3.4.13_postcss@8.4.35": { "integrity": "sha512-KqjHOJKogOUt5Bs752ykCeiwvi0fKVkr5oqsFNt/8px/tA8scFPIlkygsf6jXrfCqGHz7VflA6+yytWuM+XhFw==", "dependencies": [ @@ -627,6 +1222,14 @@ "ts-interface-checker@0.1.13": { "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" }, + "update-browserslist-db@1.1.1_browserslist@4.24.2": { + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "dependencies": [ + "browserslist", + "escalade", + "picocolors" + ] + }, "util-deprecate@1.0.2": { "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, @@ -657,8 +1260,31 @@ } }, "remote": { + "https://deno.land/std@0.120.0/async/deadline.ts": "1d6ac7aeaee22f75eb86e4e105d6161118aad7b41ae2dd14f4cfd3bf97472b93", + "https://deno.land/std@0.120.0/async/debounce.ts": "b2f693e4baa16b62793fd618de6c003b63228db50ecfe3bd51fc5f6dc0bc264b", + "https://deno.land/std@0.120.0/async/deferred.ts": "ab60d46ba561abb3b13c0c8085d05797a384b9f182935f051dc67136817acdee", + "https://deno.land/std@0.120.0/async/delay.ts": "f2d8ccaa8ebc26594bd8b0989edfd8a96257a714c1dee2fb54d986e5bdd840ac", + "https://deno.land/std@0.120.0/async/mod.ts": "78425176fabea7bd1046ce3819fd69ce40da85c83e0f174d17e8e224a91f7d10", + "https://deno.land/std@0.120.0/async/mux_async_iterator.ts": "62abff3af9ff619e8f2adc96fc70d4ca020fa48a50c23c13f12d02ed2b760dbe", + "https://deno.land/std@0.120.0/async/pool.ts": "353ce4f91865da203a097aa6f33de8966340c91b6f4a055611c8c5d534afd12f", + "https://deno.land/std@0.120.0/async/tee.ts": "3e9f2ef6b36e55188de16a667c702ace4ad0cf84e3720379160e062bf27348ad", + "https://deno.land/std@0.120.0/http/http_status.ts": "2ff185827bff21c7be2807fcb09a6a2166464ba57fcd94afe805abab8e09070a", + "https://deno.land/std@0.120.0/http/server.ts": "d0be8a9da160255623e645f5b515fa1c6b65eecfbb9cad87ef8002d4f8d56616", + "https://deno.land/std@0.143.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74", + "https://deno.land/std@0.143.0/datetime/formatter.ts": "7c8e6d16a0950f400aef41b9f1eb9168249869776ec520265dfda785d746589e", + "https://deno.land/std@0.143.0/datetime/mod.ts": "dcab9ae7be83cbf74b7863e83bd16e7c646a8dea2f019092905630eb7a545739", + "https://deno.land/std@0.143.0/datetime/tokenizer.ts": "7381e28f6ab51cb504c7e132be31773d73ef2f3e1e50a812736962b9df1e8c47", + "https://deno.land/std@0.143.0/http/cookie.ts": "526f27762fad7bf84fbe491de7eba7c406057501eec6edcad7884a16b242fddf", + "https://deno.land/x/case@2.1.1/lowerCase.ts": "86d5533f9587ed60003181591e40e648838c23f371edfa79d00288153d113b16", + "https://deno.land/x/case@2.1.1/normalCase.ts": "6a8b924da9ab0790d99233ae54bfcfc996d229cb91b2533639fe20972cc33dac", + "https://deno.land/x/case@2.1.1/snakeCase.ts": "ee2ab4e2c931d30bb79190d090c21eb5c00d1de1b7a9a3e7f33e035ae431333b", + "https://deno.land/x/case@2.1.1/types.ts": "8e2bd6edaa27c0d1972c0d5b76698564740f37b4d3787d58d1fb5f48de611e61", + "https://deno.land/x/case@2.1.1/vendor/camelCaseRegexp.ts": "7d9ff02aad4ab6429eeab7c7353f7bcdd6cc5909a8bd3dda97918c8bbb7621ae", + "https://deno.land/x/case@2.1.1/vendor/camelCaseUpperRegexp.ts": "292de54a698370f90adcdf95727993d09888b7f33d17f72f8e54ba75f7791787", + "https://deno.land/x/case@2.1.1/vendor/nonWordRegexp.ts": "c1a052629a694144b48c66b0175a22a83f4d61cb40f4e45293fc5d6b123f927e", "https://esm.sh/@docsearch/js@3.5.2?target=es2020": "f23fa2d5db04362149b5d03b2a274d850f7ad05c41625d508be170d0a2d9b1b1", - "https://esm.sh/v135/@docsearch/js@3.5.2/es2020/js.mjs": "072160862406760a27ba8c4592b42d6c4b8fab7a24c5ce265732f812eca867e6" + "https://esm.sh/v135/@docsearch/js@3.5.2/es2020/js.mjs": "072160862406760a27ba8c4592b42d6c4b8fab7a24c5ce265732f812eca867e6", + "https://raw.githubusercontent.com/denoland/ga4/main/mod.ts": "36f72ba1c90b5ebdb811427f367cd95fa6772d2de2fb45d6e57550501ee6d476" }, "workspace": { "dependencies": [ @@ -674,6 +1300,7 @@ "jsr:@std/media-types@1", "jsr:@std/path@1", "jsr:@std/semver@1", + "npm:@opentelemetry/api@^1.9.0", "npm:@preact/signals@^1.3.0", "npm:autoprefixer@10.4.17", "npm:cssnano@6.0.3", diff --git a/www/main.ts b/www/main.ts index cfdbe7eb120..094a3b2f8ee 100644 --- a/www/main.ts +++ b/www/main.ts @@ -1,3 +1,4 @@ +import "jsr:@deno/otel/register"; import { App, fsRoutes, staticFiles, trailingSlashes } from "fresh"; export const app = new App({ root: import.meta.url }) diff --git a/www/telemetry.ts b/www/telemetry.ts new file mode 100644 index 00000000000..acfba68d7cc --- /dev/null +++ b/www/telemetry.ts @@ -0,0 +1,3 @@ +import { register } from "jsr:@deno/otel"; + +if (Deno.telemetry) register();