Compare commits

...
22 Commits
Author SHA1 Message Date
hanzo-dev c9cd26e3ee fix(telemetry): require @hanzo/observe ^0.1.6 so clicks carry a position
Checks / unit-tests (push) Failing after 2m3s
Checks / checks (push) Failing after 2m35s
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-08-04 21:22:34 -07:00
hanzo-dev a93d68a05c fix(web): MISSING_THEME_MESSAGE names the actual most-common cause — a gui component rendered outside <GuiProvider>
Checks / checks (push) Failing after 2m57s
Checks / unit-tests (push) Failing after 2m55s
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-30 07:44:10 -07:00
hanzo-dev 33e4edcd8e revert(web): drop the server theme stubs — the crash was the app mounting a gui component outside <GuiProvider>; fabricating a config here silences the one diagnostic that finds it (keeps the useMedia empty-state snapshot: a viewport-less server genuinely matches no queries)
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-30 07:44:01 -07:00
hanzo-dev 2c79ff36ae feat(shell): server-safe ./registry + ./theme subpath exports, sideEffects false — RSC pages read the canonical registry without client references
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-30 06:41:03 -07:00
hanzo-dev 48c5832fca fix(web): unconfigured server theme degrades to light stub + lazy minimal config instead of crashing prerender
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-30 05:34:26 -07:00
hanzo-dev 75c5d5b5d0 fix(web): unconfigured server media snapshot degrades to empty state instead of crashing the prerender
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-30 05:15:39 -07:00
hanzo-devandClaude Opus 4.8 7d9f0fa2a4 refactor(iam): brand-neutral login hook (config-driven, PKCE, per-brand)
Replace hardcoded-hanzo useHanzoLogin (hanzo.id, placeholder clientId, shipped
client secret, wrong oauth-deep-link event) with brand-neutral useIamLogin that
reads the active brand's iam config (baseUrl/clientId/redirectUri/callbackEvent)
from @hanzo_network/brand-config and uses public-client PKCE. Adding a brand is
now a config entry; nothing is hardcoded to one brand.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-30 05:15:38 -07:00
hanzo-devandClaude Opus 4.8 da50042d5e feat(@hanzo/ai): decomplect the AI app into one declarative SDK
The entire shinkai-fork AI app (280 files) + its 7 @hanzo_network/* libs,
lifted into @hanzo/ai as <HanzoAI {...brand} host={}/> — brand is a prop,
platform is an injected HostAdapter (web / tauri / expo). One unified surface
for hanzo/zoo/lux desktop + mobile + web (hanzo.chat). Library build green
(2.8MB) and production web build green (14MB). Shims in examples/.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-30 05:15:38 -07:00
hanzo-dev e4700d2c30 fix(web): seed initState so useMedia's server snapshot is never undefined
Checks / checks (push) Failing after 3m29s
Checks / unit-tests (push) Failing after 5m54s
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-29 20:46:29 -07:00
zooqueenandhanzo-dev 22b7f62f89 docs: LLM.md is the guide; CLAUDE.md and AGENTS.md are symlinks to it
Checks / checks (push) Failing after 5m35s
Checks / unit-tests (push) Failing after 5m26s
One file per repo, three names for it. The names exist because different tools
look for different filenames; the CONTENT existing three times is how they drift,
and a drifted agent guide is worse than none — it is confidently wrong.

Where a name already held the only guide, that file BECAME LLM.md byte for byte
rather than being replaced by a copy, so nothing was rewritten or lost.

Repos where two names held genuinely DIFFERENT guides were skipped, not merged:
symlinking there would delete one of them, and choosing which paragraphs survive
is not a sweep's decision.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-29 18:25:11 -07:00
zooqueenandhanzo-dev 44a822f106 rip(ai)!: move @hanzo/app out of the primitives repo to hanzo-js/app
Checks / unit-tests (push) Failing after 6m48s
Checks / checks (push) Failing after 7m37s
gui holds primitives — @hanzogui/* and @hanzo/gui. pkgs/ai was a whole
desktop chat app (@hanzo/app: routes, pages, chat, agents, a Tauri host
shim) plus the seven @hanzo_network/* libraries it is built from. An
application inside the primitives repo is the layering mistake the owner
named on hanzo.team; it is also why this repo dragged app-weight deps.

Moved intact to hanzo-js/app, which is where @hanzo/* JS packages already
live one-per-repo (hanzo-js/ai -> @hanzo/ai). It builds and publishes
itself from there, so publish-app.yml goes with it.

Removed here: pkgs/ai + pkgs/net-{ui,state,i18n,message-ts,brand-config,
logo,artifacts} — 1045 source files — and 81 runtime dependencies that no
surviving package declares (25 @radix-ui/*, 3 @tanstack/*, 3 @rjsf/*,
plus pyodide, ethers, mermaid, primereact, sql.js, plotly, recharts,
framer-motion...), 328 MB of node_modules.

Nothing in gui imported any of it: no source import, no tsconfig path, no
turbo or knip entry. Build parity measured against the same tree before
the removal — 10 pre-existing @hanzogui/* failures before, the identical
10 after, zero new.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-28 23:40:49 -07:00
zooqueenandhanzo-dev 441ce04497 fix: name every cross-package type through its package entry — TypeScript 7 build is green
Checks / checks (push) Failing after 9m16s
Checks / unit-tests (push) Failing after 12m29s
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-28 20:21:55 -07:00
hanzo-dev e97433f553 fix(gui): declare react-native-web, make react-native an optional peer
A web-only consumer could not bundle @hanzo/gui at all: 12 packages emit
`import ... from "react-native-web"` in their web dist while nothing declared
it, and `react-native` was a required peer on 40 packages. react-native-web is
now a real dependency of every package whose web build imports it (an optional
peer is never auto-installed, so nothing weaker survives a clean install), and
react-native is optional wherever it is peered. The whole @hanzogui surface
moves 7.3.0 -> 7.3.1 in lockstep so no consumer resolves two @hanzogui/core.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-28 18:39:16 -07:00
zooqueenandhanzo-dev f74b440384 docs: the OIDC fallback paths are IAM's, not a vendor's
Three comments in apps/team/src/auth.ts credited the hardcoded discovery
fallback to Casdoor. Hanzo IAM (hanzoai/iam) is original work; the
Casdoor-derived server was hanzoai/iam-v1, retired and part of no current
product. The comments keep the fact -- these are the endpoint paths hanzo.id
serves when .well-known discovery is unreachable -- and lose the wrong name.

FALLBACK's URL paths are unchanged; they are what IAM answers on.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-28 17:12:52 -07:00
hanzo-dev 60c24492f1 fix(ci): smoke-test the renamed dist/app.css, and drop the HanzoAI symbol from the zoo/lux example shims
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-28 12:07:01 -07:00
hanzo-dev 81e2103f30 refactor(ai)!: rename the app SDK to @hanzo/app — @hanzo/ai belongs to the headless client, and ship the exports the types promise
Publish @hanzo/app / Build, smoke-test, publish @hanzo/app (push) Failing after 15s
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-28 11:58:41 -07:00
hanzo-dev 011441eb5a refactor(ai): de-brand the shared app surface — hanzo-node-manager -> node-manager, brand-driven dapp URL, browser shim, neutral test fixture
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-28 11:50:35 -07:00
zeekayandhanzo-dev e05c06e404 fix: declare CSS side-effect imports for TypeScript 7 (TS2882)
TypeScript 7 reports TS2882 for a stylesheet side-effect import with no type
declaration; TS 5.x accepted them silently. Bundlers resolve stylesheets through
their own loaders, so the import never reaches the TypeScript module resolver —
this declares them legitimate rather than giving them a shape.

MEASURED, not assumed: this repo reports TS2882 under tsc 7 without the file and
zero with it. Repos where a framework already ships ambient CSS declarations
(Next's next-env.d.ts) were left alone — the declaration is inert there and was
not added.

Co-Authored-By: Hanzo Dev <dev@hanzo.ai>
2026-07-27 18:23:47 -07:00
zeekayandhanzo-dev 3b3f9d6826 build: TypeScript 7 — module System -> esnext, moduleResolution -> bundler
TS7 removes `module: System` and `moduleResolution: node10` outright, so
every one of the 87 packages that extends this root failed to typecheck:

    error TS5108: Option 'module=System' has been removed.
    error TS5108: Option 'moduleResolution=node10' has been removed.
    error TS5095: Option 'bundler' can only be used when 'module' is
                  'preserve', 'commonjs', or 'es2015' or later.

That last one shows the config was already internally inconsistent — a
package sets moduleResolution: bundler while inheriting module: System.

Safe because tsc NEVER emits here: packages bundle with `gui-build`
(esbuild), and the only `tsc -b` is scripts/typecheck.sh against
tsconfig.build.json, which sets noEmit. So `module` governs type
resolution alone and System was vestigial — no published artifact changes.

Verified on both compilers, root + a sample of the extending packages:
tsconfig.build.json 0/0, pkgs/ui/tabs 0/0, pkgs/calendar 0/0 — zero
config errors and zero new type errors under TS7 and TS 5.9 alike.

Co-Authored-By: Hanzo Dev <dev@hanzo.ai>
2026-07-27 17:53:20 -07:00
zeekayandhanzo-dev d804cb3db1 fix: complete the TypeScript 7 tsconfig migration
The first pass left three classes of config that BOTH tsc 5.9 and tsc 7
reject. Each was proven against both compilers before changing:

  TS5090  A `paths` target must be relative once `baseUrl` is gone. The
          first pass skipped the "./" prefix wherever baseUrl pointed at
          the config's own directory, reasoning it was semantically
          equivalent. It is not — without baseUrl a non-relative target
          is rejected outright, by 5.9 as well as 7.

  TS5110  `moduleResolution: node16` requires `module: node16`. The first
          pass mapped commonjs projects to node16 resolution alone, which
          BROKE those configs for the current toolchain. Both are now set.

  TS5102  `downlevelIteration` is also removed in TS7; it was missing from
          the dead-flag list.

Verified: repos that tsc 7 previously refused (base-studio, js-sdk, kv-js)
now report zero config errors on tsc 7 AND tsc 5.9.

Co-Authored-By: Hanzo Dev <dev@hanzo.ai>
2026-07-27 17:53:20 -07:00
zeekayandhanzo-dev b3a0dc5861 build: migrate tsconfig to TypeScript 7 (native compiler)
TypeScript 7 is the native Go compiler and removes `baseUrl` and
`moduleResolution: node|node10`. Both appear here, so `tsc` from TS7
refuses the config outright (TS5102 / TS5108) and cannot typecheck.

`paths` targets resolve relative to `baseUrl` when it is set and relative
to the tsconfig file otherwise. Every `baseUrl` folded here already
pointed at the config's own directory, so dropping it moves nothing and
the targets are left byte-identical. Where a baseUrl pointed elsewhere,
each affected target was rewritten as join(baseUrl, target).

`moduleResolution` was chosen from the declared `module`: commonjs ->
node16, esnext/preserve -> bundler. Configs whose `module` is unset or
exotic were left alone rather than guessed at.

The result is accepted by BOTH toolchains, so nothing has to upgrade
TypeScript in lockstep. Verified on hanzo/chat packages/api: tsc 5.9
779 -> 778 errors (no regression), and tsc 7.0.2 now runs the project
in 2s where it previously refused the config.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-27 17:53:20 -07:00
hanzo-dev d313a71bee ci: drop the Gitea mirror-sync nudge
Superseded: the Hanzo GitHub App pushes a webhook, so the forge tracks GitHub
without a per-repo workflow. This file called git.hanzo.ai/api/v1/.../mirror-sync
— a Gitea API for a system we no longer drive — and would sit inert in every repo.

One mechanism, in one place, instead of ~350 copies of a cron.
2026-07-27 10:32:09 -07:00
1105 changed files with 5007 additions and 1487010 deletions
-102
View File
@@ -1,102 +0,0 @@
name: sync
# Carries pushed refs to git.hanzo.ai, the canonical forge, and does nothing
# else: build, test and release run natively there.
#
# Repo-agnostic. owner/name come from ${{ github.repository }}, so this file is
# dropped into every repo unchanged as .github/workflows/sync.yml and is the
# only workflow GitHub is permitted to run.
on:
push:
# '**' matches slashes; '*' does not, and would skip feature/foo.
branches: ['**']
tags: ['**']
workflow_dispatch:
# Serialize per ref. Never cancel: a cancelled run drops that ref and nothing
# reconciles it afterwards.
concurrency:
group: sync-${{ github.ref }}
cancel-in-progress: false
permissions:
contents: read
jobs:
sync:
# .github/workflows is also on the forge's own workflow search path, so this
# file executes there too in any repo without .hanzo/workflows, where it
# would push the forge to itself. server_url is the forge's AppURL, which
# makes this the test for "running on GitHub".
if: github.server_url == 'https://github.com'
# GitHub-hosted on purpose. This is the one workflow that must run ON GitHub,
# and the self-hosted pool that used to serve it is retired — a job asking for
# it now queues forever against a label nothing answers. Carrying refs is a
# push, not a build, so it does not belong on the build fabric anyway: builds
# run natively on git.hanzo.ai, which is the whole point of this file.
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
persist-credentials: false
- name: Push refs to git.hanzo.ai
env:
FORGE: https://git.hanzo.ai
GIT_TOKEN: ${{ secrets.GIT_TOKEN }}
run: |
set -euo pipefail
if [ -z "${GIT_TOKEN}" ]; then
echo "::error::GIT_TOKEN is unset, so this push never reached the canonical forge. Add the org secret."
exit 1
fi
REMOTE="${FORGE}/${GITHUB_REPOSITORY}.git"
# The forge reads the token from the basic-auth password and ignores
# the username. base64 of a secret is not masked automatically.
AUTH="$(printf 'x-access-token:%s' "${GIT_TOKEN}" | base64 -w0)"
echo "::add-mask::${AUTH}"
# Host-scoped, so the forge token is never sent to github.com.
git config --local "http.${FORGE}/.extraheader" "Authorization: Basic ${AUTH}"
# Reachability is the only transient failure here, so it is the only
# thing retried. ls-remote exits 0 on an existing empty repo and
# non-zero when the forge is down or the repo is absent.
ERR="$(mktemp)"
REACHED=""
for attempt in 1 2 3; do
if git ls-remote "${REMOTE}" >/dev/null 2>"${ERR}"; then
REACHED=1
break
fi
echo "forge probe failed (attempt ${attempt}/3): $(cat "${ERR}")"
if [ "${attempt}" -lt 3 ]; then
sleep $((attempt * 5))
fi
done
if [ -z "${REACHED}" ]; then
echo "::error::git.hanzo.ai is unreachable or ${GITHUB_REPOSITORY} does not exist there. $(cat "${ERR}")"
exit 1
fi
# Additive and fast-forward-only: no leading '+', no --force, no
# --prune, no --mirror. Tags go every run so a tag that missed its own
# event still lands; git refuses to move one that already differs.
REFS=('refs/tags/*:refs/tags/*')
case "${GITHUB_REF}" in
refs/heads/*) REFS+=("${GITHUB_REF}:${GITHUB_REF}") ;;
esac
# Not --atomic: a diverged ref must not hold back the refs that are
# clean. Rejections still fail the job.
if ! git push "${REMOTE}" "${REFS[@]}"; then
echo "::error::git.hanzo.ai rejected a ref for ${GITHUB_REPOSITORY}. The forge is canonical and is never force-updated from here; reconcile the diverged branch or tag by hand."
exit 1
fi
-121
View File
@@ -1,121 +0,0 @@
name: Publish @hanzo/ai
# Surgical publish of ONLY the @hanzo/ai SDK (pkgs/ai). The desktop apps
# (hanzo/zoo/lux) render `<HanzoAI/>` from this package; it must be on npm
# for a clean `npm i` to resolve it.
#
# Triggered only on `release/ai-v*` tags. A version bump alone does NOT
# publish — the tag gates the run. Tag scheme:
# release/ai-v0.1.1 -> @hanzo/ai@0.1.1
#
# NPM_TOKEN resolution order (same shape as publish-gui.yml):
# 1. KMS via Universal Auth (KMS_CLIENT_ID/SECRET -> short-lived token)
# 2. KMS via long-lived HANZO_API_KEY (legacy bootstrap)
# 3. Direct repo secret NPM_TOKEN (fallback until KMS is provisioned)
#
# Idempotent: skips if @hanzo/ai@<version> is already on npm.
on:
push:
tags:
- 'release/ai-v*'
workflow_dispatch:
inputs:
confirm:
description: 'Type "publish" to publish @hanzo/ai at its current on-disk version'
required: true
default: ''
permissions:
contents: read
id-token: write
# A transitive puppeteer dep tries to download Chromium in its postinstall,
# which fails on the runner and kills `bun install` (run #7). The publish
# never drives a browser, so skip every browser-binary download.
env:
PUPPETEER_SKIP_DOWNLOAD: '1'
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: '1'
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: '1'
PUPPETEER_SKIP_CHROME_DOWNLOAD: '1'
jobs:
publish:
name: Build, smoke-test, publish @hanzo/ai
# Same runner publish-gui.yml uses. @hanzo/ai is arch-independent JS, and the
# arm64 label this asked for is answered by one frequently-offline host — a job
# requesting a label nothing answers queues silently instead of failing, which
# is the worst outcome for a publisher. KMS is reachable from either pool.
runs-on: hanzo-build-linux-amd64
if: github.event_name == 'push' || github.event.inputs.confirm == 'publish'
steps:
- uses: actions/checkout@v5
with:
# Shallow: the publish only builds pkgs/ai — it needs no git history.
# A full clone (fetch-depth 0) of this monorepo's history OOMs git
# index-pack on the runner and fails checkout (runs #5/#6 died here).
fetch-depth: 1
- name: Install
uses: ./.github/actions/install
# Canonical, deterministic KMS auth — the ONE way every hanzo/lux/zoo repo
# loads secrets (see hanzoai/universe/.github/actions/kms-action). OIDC-
# first: GitHub's id-token proves this repo's identity to KMS, so NOTHING
# is stored — only non-secret `vars.*` config. NPM_TOKEN is exported into
# the job env at `secret-path`. No repo NPM_TOKEN secret, no client_id/
# secret. Set KMS_IDENTITY_ID + KMS_PROJECT_ID once at the org level.
- name: Load NPM_TOKEN from Hanzo KMS (OIDC)
uses: hanzoai/universe/.github/actions/kms-action@main
with:
identity-id: ${{ vars.KMS_IDENTITY_ID }}
project-id: ${{ vars.KMS_PROJECT_ID }}
environment: ${{ vars.KMS_ENVIRONMENT || 'prod' }}
secret-path: ${{ vars.KMS_PUBLISH_SECRET_PATH || '/publish' }}
export-type: env
- name: Configure npm registry
run: |
# NPM_TOKEN is now in the job env (kms-action export-type=env).
test -n "${NPM_TOKEN:-}" || { echo "::error::KMS did not yield NPM_TOKEN at the publish path"; exit 1; }
echo 'registry=https://registry.npmjs.org/' > ~/.npmrc
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" >> ~/.npmrc
- name: Build @hanzo/ai (dist + dist-desktop)
# pkgs/ai's own build runs BOTH vite passes: dist/ (web entry,
# ai.css) and dist-desktop/ (the <HanzoAI/> desktop bundle the apps
# import). Build it explicitly so both trees exist before publish.
working-directory: pkgs/ai
run: bun run build
- name: Smoke-test dist trees + exports
run: |
set -eu
cd pkgs/ai
test -f dist/index.js || (echo "::error::dist/index.js missing"; exit 1)
test -f dist/ai.css || (echo "::error::dist/ai.css missing"; exit 1)
test -f dist-desktop/index.js || (echo "::error::dist-desktop/index.js missing"; exit 1)
# Every file referenced from the exports map must exist.
node -e "
const fs=require('fs');
const pkg=require('./package.json');
const walk=(v)=>{
if (typeof v==='string') { if (v.startsWith('./') && !fs.existsSync(v)) { console.error('missing:',v); process.exitCode=1; } }
else if (v && typeof v==='object') { for (const k of Object.keys(v)) walk(v[k]); }
};
walk(pkg.exports||{}); walk(pkg.main); walk(pkg.module); walk(pkg.types);
"
echo "smoke OK: $(node -p "require('./package.json').name + '@' + require('./package.json').version")"
- name: Publish @hanzo/ai
env:
NODE_AUTH_TOKEN: ${{ env.NPM_TOKEN }}
working-directory: pkgs/ai
run: |
set -eu
version=$(node -p "require('./package.json').version")
if npm view "@hanzo/ai@${version}" version >/dev/null 2>&1; then
echo "@hanzo/ai@${version} already on npm - skipping."
exit 0
fi
# pkgs/ai has no workspace:* deps, so a direct publish is clean.
npm publish --access public
+1 -1
View File
@@ -103,7 +103,7 @@ jobs:
# Targeted publish of just the @hanzogui/* closure + hanzogui +
# @hanzo/gui, at the current on-disk version. Avoids release.ts's
# whole-workspace fan-out (which fails packing unrelated
# @hanzo_network/* packages) and its fragile tarball-rename step.
# unrelated workspace packages) and its fragile tarball-rename step.
# Idempotent — skips any name@version already on npm.
env:
NPM_TOKEN: ${{ steps.token.outputs.npm_token }}
+7 -12
View File
@@ -16,7 +16,6 @@ One way, and it runs on our own stack:
.hanzo/workflows/checks.yaml check, lint, unit tests
.hanzo/workflows/publish-gui.yml hanzogui + @hanzo/gui
.hanzo/workflows/publish-gui-all.yml every @hanzogui/* primitive
.hanzo/workflows/publish-ai.yml @hanzo/ai
.hanzo/workflows/build.yml ghcr.io/hanzoai/gui
**git.hanzo.ai is canonical; GitHub is a mirror.** `.github/workflows/` holds
@@ -35,19 +34,15 @@ every case — a version bump alone never ships.
| --- | --- | --- |
| `release/gui-v*` | `publish-gui.yml` | `hanzogui` + the `@hanzo/gui` alias |
| `release/gui-all-v*` (or dispatch) | `publish-gui-all.yml` | every `@hanzogui/*` primitive + both umbrellas |
| `release/ai-v*` | `publish-ai.yml` | `@hanzo/ai` from `pkgs/ai` |
`NPM_TOKEN` comes from KMS with a repo-secret fallback in the two `publish-gui*`
workflows, and from `hanzoai/universe/.github/actions/kms-action` over OIDC in
`publish-ai.yml`. The forge has to be able to resolve that cross-repo action, so
`hanzoai/universe` must exist there; if it does not, the KMS step is the thing that
fails.
`NPM_TOKEN` comes from KMS with a repo-secret fallback in both `publish-gui*`
workflows.
`publish-ai.yml` asked for `runs-on: [self-hosted, linux, arm64]`, which is one
frequently-offline host. A job requesting a label nothing answers queues silently
instead of failing, which is the worst possible outcome for a publisher, so it now
uses `hanzo-build-linux-amd64` like its two siblings — `@hanzo/ai` is
arch-independent JS.
**This repo publishes primitives only.** The AI app that used to live at
`pkgs/ai``@hanzo/app`, plus the seven `@hanzo_network/*` libraries it is
built from — moved to `hanzo-js/app` on 2026-07-28, and publishes itself from
there. An application inside the primitives repo is the layering mistake the
owner named: `@hanzo/gui` (primitives) -> `@hanzo/ui` (widgets) -> apps.
## Known dead ends
-2
View File
@@ -1,6 +1,5 @@
{
"compilerOptions": {
"baseUrl": ".",
"rootDir": ".",
"paths": {
"~/*": ["./*"]
@@ -11,7 +10,6 @@
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
"downlevelIteration": true,
"strict": true,
"esModuleInterop": true,
"inlineSourceMap": true,
-1
View File
@@ -1,6 +1,5 @@
{
"compilerOptions": {
"baseUrl": ".",
"module": "esnext",
"moduleResolution": "bundler",
"target": "esnext",
+3 -3
View File
@@ -34,7 +34,7 @@ interface Endpoints {
userinfo: string
}
// Casdoor/IAM defaults, used when discovery is unreachable.
// IAM's endpoint paths, used when discovery is unreachable.
const FALLBACK: Endpoints = {
authorization: `${ISSUER}/login/oauth/authorize`,
token: `${ISSUER}/api/login/oauth/access_token`,
@@ -43,7 +43,7 @@ const FALLBACK: Endpoints = {
let endpointsCache: Endpoints | undefined
/** Resolve OIDC endpoints from the discovery document, falling back to Casdoor paths. */
/** Resolve OIDC endpoints from the discovery document, falling back to IAM's paths. */
export async function discover(): Promise<Endpoints> {
if (endpointsCache !== undefined) return endpointsCache
try {
@@ -58,7 +58,7 @@ export async function discover(): Promise<Endpoints> {
return endpointsCache
}
} catch {
// discovery blocked — fall through to the known Casdoor paths
// discovery blocked — fall through to the known IAM paths
}
endpointsCache = FALLBACK
return endpointsCache
-1
View File
@@ -1,6 +1,5 @@
{
"compilerOptions": {
"baseUrl": ".",
"module": "esnext",
"moduleResolution": "bundler",
"target": "esnext",
-1
View File
@@ -4,7 +4,6 @@
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
"downlevelIteration": true,
"strict": true,
"esModuleInterop": true,
"inlineSourceMap": true,
+2 -4
View File
@@ -1,8 +1,6 @@
{
"compilerOptions": {
"composite": true,
// for jumping to things properly in vscode
"baseUrl": ".",
"paths": {
"hanzogui": [
"../ui/gui"
@@ -29,7 +27,7 @@
"./data/*"
],
"react-native": [
"react-native-web"
"./react-native-web"
]
},
"target": "es2021",
@@ -42,7 +40,7 @@
"allowJs": true,
"noEmit": true,
"module": "esnext",
"moduleResolution": "node",
"moduleResolution": "bundler",
"isolatedModules": true,
"jsx": "preserve",
"noImplicitThis": true,
+9 -3
View File
@@ -1,11 +1,9 @@
{
"compilerOptions": {
"baseUrl": ".",
"rootDir": ".",
"importHelpers": true,
"allowJs": false,
"allowSyntheticDefaultImports": true,
"downlevelIteration": true,
"esModuleInterop": true,
"preserveSymlinks": true,
"incremental": true,
@@ -26,7 +24,15 @@
"strictNullChecks": true,
"target": "es2020",
"types": ["node"],
"lib": ["dom", "esnext"]
"lib": [
"dom",
"esnext"
],
"paths": {
"*": [
"./*"
]
}
},
"exclude": ["_"],
"typeAcquisition": {
+1409 -2574
View File
File diff suppressed because it is too large Load Diff
+8
View File
@@ -0,0 +1,8 @@
// TypeScript 7 reports TS2882 for a side-effect import with no type
// declaration ("Cannot find module or type declarations for side-effect import
// of './globals.css'"). TS 5.x accepted these silently.
//
// Stylesheets are resolved by the bundler (Next/Vite/webpack), never by the
// TypeScript module resolver, so this declares them legitimate rather than
// giving them a shape.
declare module '*.css';
+1 -1
View File
@@ -208,4 +208,4 @@
"exports": {
"./package.json": "./package.json"
}
}
}
-59
View File
@@ -1,59 +0,0 @@
# Live chat — VERIFIED working end-to-end (web, local) 2026-06-05
The web app at `:1500` chats with **zen-coder-24b** through a real **hanzo-node**,
fully in the browser. Verified: prompt "Reply with exactly: E2E CHAT OK" →
zen-coder generated `E2E CHAT OK` (7 tokens), streamed back to the chat UI.
The full path:
```
browser :1500 ─(vite proxy /v1,/v2,/ws)→ hanzo-node :3700 ─job→ zen_engine provider
→ responses-proxy :36906 (rewrites /v1/engine/responses → /v1/responses)
→ hanzo-engine :36902 (zen-coder-24b) → "E2E CHAT OK" → streamed back to the UI
```
## The non-obvious fixes that made it work
1. **The node speaks the OpenAI _Responses_ API, the engine serves it at a
different path.** The node's `OpenAI` provider POSTs to
`<url>/v1/engine/responses` (`{input:[...], max_output_tokens, ...}`), but
hanzo-engine serves the Responses API at **`/v1/responses`** (`/v1/engine/...`
→ 404 → the node reports "AI Provider API Error: Unknown error"). A tiny proxy
rewrites the path (and injects `enable_thinking:false`). See
`local-runtime/responses-proxy.py`.
2. **Use `127.0.0.1`, never `localhost`.** `localhost` resolves to IPv6 `::1`
here; the engine/embeddings bind IPv4 only → instant connection failure.
3. **CORS:** the vite dev server proxies the app's own origin (`/v1`,`/v2`,`/ws`)
to the node, so the app's `nodeAddress` is just `http://<host>:1500`.
4. **Two migration import bugs** had to be fixed for the chat screens to render:
`main-layout.tsx` was missing `Box`/`Boxes`/`Coins` lucide imports, and the
merge pulled `react-resizable-panels@4` (renamed exports) — pinned to `^3.0.2`
in `pkgs/net-ui` (the app uses `PanelGroup`/`PanelResizeHandle`).
## Reproduce it
```bash
# 1. engine + embeddings already running: :36902 (zen-coder), :11436 (embed)
# 2. responses-proxy (path rewrite):
python3 pkgs/ai/local-runtime/responses-proxy.py & # :36906 → :36902
# 3. WS proxy (the app derives ws://host:1501 behind the vite proxy):
node pkgs/ai/local-runtime/ws-proxy.js & # :1501 → node WS :3701
# 4. a /v1 hanzo-node wired to the proxy (fresh storage, no reg code):
bash pkgs/ai/local-runtime/run-node.sh & # API :3700, zen_engine → :36906
# 5. web app pointed at the node + engine (engine-api proxy avoids CORS):
cd pkgs/ai/web && VITE_NODE_API=http://127.0.0.1:3700 VITE_NODE_WS=ws://127.0.0.1:3701 \
VITE_ENGINE_BASE_URL=/engine-api VITE_ENGINE_API=http://127.0.0.1:36906 \
bun x vite --config vite.config.ts # :1500
# 6. open http://spark.local:1500 → agree → Quick Connect (node address = same
# origin http://localhost:1500) → /home → chat. Reply streams from zen-coder.
```
## Console — clean (the e2e asserts it)
The earlier web console errors are fixed and guarded by `e2e/chat.e2e.test.ts`:
react-query "data cannot be undefined" (web `invoke` returns null), the
`isPermissionGranted`/notification gap, the `:36900/v1/engine/models` CORS
(routed via the `/engine-api` proxy), the `ws://…:1501` failure (ws-proxy), the
`available_models` 401 (gated `useGetLLMProviders` on auth), and the framer
`motion()` deprecation. Remaining: a rare, intermittent static-asset `404` and a
node-side `Embedding "Query is not read-only"` warning — neither affects chat.
-80
View File
@@ -1,80 +0,0 @@
# @hanzo/ai — one app surface, every platform
The Hanzo / Zoo / Lux AI app is **one** thing: `@hanzo/ai`. Web, desktop and
mobile are not three apps — they are the same app with two axes injected.
```
┌────────────────────────── @hanzo/ai ──────────────────────────┐
│ src/app/ (the migrated shinkai-fork app — ONE copy, one place) │
│ + net-* libs (ui, state, i18n, message-ts, brand-config, logo, │
│ artifacts) + src/host/* (the @tauri-apps shim surface) │
└──────────────────────────────────────────────────────────────────┘
▲ ▲ ▲
host = web (default) host = tauriHost host = expoHost
brand = getBrand() brand = getBrand() brand = getBrand()
│ │ │
hanzo.app / .chat hanzoai/desktop @hanzo/gui
zoo.cloud / lux.cloud zooai/app · luxfi/app (Expo mobile)
```
## The two orthogonal axes (decomplected)
| Axis | What it is | How it's injected | Default |
|---|---|---|---|
| **Brand** | hanzo / zoo / lux identity, cloud endpoints, chain, IAM | `getBrand()` (driven by `VITE_BRAND` or hostname) **or** spread as props `<HanzoAI {...brand}/>` | `getBrand()` → hostname → HANZO |
| **Platform** | how native calls (`invoke`, `listen`, fs, window…) resolve | `host` prop — a `HostAdapter` | web no-ops |
Everything else — the entire app — is shared. A new app is a ~10-line shim:
```tsx
import HanzoAI, { getBrand } from '@hanzo/ai';
import { tauriHost } from './tauri-host'; // desktop only; web omits it
createRoot(root).render(
<HanzoAI {...getBrand()} host={tauriHost} features={{ chat, wallet, agents }} />
);
```
## Web ⇄ desktop parity
The web shim and the desktop shim are **byte-identical except one prop**
(`host={tauriHost}`). They import the same `@hanzo/ai`, which is the same
`src/app`. So the rendered React tree — every screen, route and component — is
identical. The only runtime difference is what `HostAdapter` does:
| Call | web (default host) | desktop (tauriHost) |
|---|---|---|
| `invoke(cmd, args)` | no-op, returns `undefined` (logs in dev) | Tauri IPC → Rust |
| `listen(event, cb)` | no-op unlisten | Tauri event bus |
| `getCurrentWindow()` | no-op Window (emit/listen/geometry) | real Tauri window |
| fs / shell / process / updater | no-op / empty | Tauri plugins |
So on the web the app renders 1:1 with desktop; native-only actions (open a
folder, auto-update, tray) simply do nothing instead of crashing. Cloud
inference + chat work on both (they go over HTTP to the brand's
`inferenceEndpoint`, not through `invoke`).
## Verification (2026-06-04)
| Surface | Build | Render |
|---|---|---|
| web dev server (`pkgs/ai/web`, imports `src`) | ✅ | ✅ Hanzo onboarding |
| web prod (unminified, 55M) | ✅ 40s | ✅ |
| web prod (minified, 13M / gzip 3.75M) | ✅ 44s | ✅ |
| library `dist` (self-contained, react external) | ✅ | — |
| **external shim** (`examples/web`, only react provided, app from `dist`) | ✅ | ✅ — proves SDK consumption |
The render blocker that had to be cleared first: app modules imported
`useBrand` from the **`@hanzo/ai` package name**, which resolved to the built
`dist` — pulling a second React + a second app copy into the source graph (a
cycle → `useContext` of null). Fix: the brand store lives in
`@hanzo_network/brand-config` (plain getters, not hooks), aliased to `src`;
app code never imports the `@hanzo/ai` package by name.
## Turning the real repos into shims
`luxfi/app`, `zooai/app`, `hanzoai/desktop`, `hanzoai/app` each become the
shim above. Per repo: depend on `@hanzo/ai` (+ `react`, `react-dom`, and for
desktop `@tauri-apps/api`), set `VITE_BRAND`, drop all app source. The
Dockerfile/Tauri config builds from the pinned SDK — exactly how
`zooai/exchange` builds from `@luxfi/exchange`. (`@hanzo/ai` is not yet
published to npm; until then the shims consume it via the workspace.)
-51
View File
@@ -1,51 +0,0 @@
# Testing @hanzo/ai — and TDD going forward
## Run
```bash
bun run --cwd pkgs/ai test # unit + regression (vitest, jsdom) — fast, no external deps
bun run --cwd pkgs/ai test:watch # vitest watch mode (use while writing a fix)
bun run --cwd pkgs/ai test:e2e # Playwright e2e — needs the local runtime up (skips if not)
```
`test` runs everything under `src/**/*.{test,spec}.{ts,tsx}` in jsdom. Config:
`vitest.config.ts` mirrors the web build's alias graph (so `@/`, `@tauri-apps/*`
→ host shims, `@hanzo_network/*` → src resolve), stubs the streamdown markdown
stack (esbuild can't resolve its nested micromark), and loads
`@testing-library/jest-dom` via `src/__tests__/setup.ts`. Pyodide /
python-code-runner tests are excluded (30 MB wasm + network).
## What's covered
**Unit + regression** (`src/__tests__/`) — each guards a bug this stack actually hit:
- `brand-store.test.ts``useBrand`/`getBrand` are plain getters callable
outside render (the invalid-hook-call that blocked the whole web app).
- `host-shims.test.ts``getCurrentWindow().emit` etc. exist; the injected host
adapter switches web↔tauri (the "emit is not a function" mount crash).
- `resizable.test.tsx``react-resizable-panels` v3 API present, net-ui
resizable renders (the v4 "Element type is invalid" chat-view crash).
- `no-missing-imports.test.ts` — critical screens import every `<Component>`
they use (the dropped `Box`/`Boxes`/`Coins` lucide imports → "Box is not defined").
**App tests** (pre-existing, `src/app/**`) — engine client, machine-state queries,
mining page, playground utils. **E2E** (`e2e/chat.e2e.test.ts`) — drives the real
browser: onboarding renders, then connect → register → send → assert zen-coder's
reply (and assert no "is not defined" / "Element type is invalid" page errors).
## TDD workflow (going forward)
Every fix and feature starts with a failing test:
1. **Red** — write a test that reproduces the bug or specifies the behavior, in
`src/__tests__/` (unit) or `e2e/` (flow). Run `test:watch`; confirm it fails.
2. **Green** — make the smallest change that passes it.
3. **Refactor** — clean up with the test green.
4. Run `bun run --cwd pkgs/ai test` before committing; keep it green.
Most bugs this session were import/dep/runtime issues that *static render checks
missed but a test would have caught* — prefer a regression test over a manual
re-check. For anything touching the chat path, add/extend the e2e.
The local runtime for `test:e2e` is in `pkgs/ai/local-runtime/` (see `CHAT.md`):
restart `run-node.sh` (fresh storage) before a run so Quick Connect registers as
the first device.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-268
View File
@@ -1,268 +0,0 @@
import { P as withPath, Q as pi, S as cos, T as sin, V as constant, W as halfPi, X as epsilon, Y as tau, Z as sqrt, $ as min, a0 as abs, a1 as atan2, a2 as max, a3 as asin, a4 as acos } from './index-CjXUZi2M.js';
function arcInnerRadius(d) {
return d.innerRadius;
}
function arcOuterRadius(d) {
return d.outerRadius;
}
function arcStartAngle(d) {
return d.startAngle;
}
function arcEndAngle(d) {
return d.endAngle;
}
function arcPadAngle(d) {
return d && d.padAngle; // Note: optional!
}
function intersect(x0, y0, x1, y1, x2, y2, x3, y3) {
var x10 = x1 - x0, y10 = y1 - y0,
x32 = x3 - x2, y32 = y3 - y2,
t = y32 * x10 - x32 * y10;
if (t * t < epsilon) return;
t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / t;
return [x0 + t * x10, y0 + t * y10];
}
// Compute perpendicular offset line of length rc.
// http://mathworld.wolfram.com/Circle-LineIntersection.html
function cornerTangents(x0, y0, x1, y1, r1, rc, cw) {
var x01 = x0 - x1,
y01 = y0 - y1,
lo = (cw ? rc : -rc) / sqrt(x01 * x01 + y01 * y01),
ox = lo * y01,
oy = -lo * x01,
x11 = x0 + ox,
y11 = y0 + oy,
x10 = x1 + ox,
y10 = y1 + oy,
x00 = (x11 + x10) / 2,
y00 = (y11 + y10) / 2,
dx = x10 - x11,
dy = y10 - y11,
d2 = dx * dx + dy * dy,
r = r1 - rc,
D = x11 * y10 - x10 * y11,
d = (dy < 0 ? -1 : 1) * sqrt(max(0, r * r * d2 - D * D)),
cx0 = (D * dy - dx * d) / d2,
cy0 = (-D * dx - dy * d) / d2,
cx1 = (D * dy + dx * d) / d2,
cy1 = (-D * dx + dy * d) / d2,
dx0 = cx0 - x00,
dy0 = cy0 - y00,
dx1 = cx1 - x00,
dy1 = cy1 - y00;
// Pick the closer of the two intersection points.
// TODO Is there a faster way to determine which intersection to use?
if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;
return {
cx: cx0,
cy: cy0,
x01: -ox,
y01: -oy,
x11: cx0 * (r1 / r - 1),
y11: cy0 * (r1 / r - 1)
};
}
function d3arc() {
var innerRadius = arcInnerRadius,
outerRadius = arcOuterRadius,
cornerRadius = constant(0),
padRadius = null,
startAngle = arcStartAngle,
endAngle = arcEndAngle,
padAngle = arcPadAngle,
context = null,
path = withPath(arc);
function arc() {
var buffer,
r,
r0 = +innerRadius.apply(this, arguments),
r1 = +outerRadius.apply(this, arguments),
a0 = startAngle.apply(this, arguments) - halfPi,
a1 = endAngle.apply(this, arguments) - halfPi,
da = abs(a1 - a0),
cw = a1 > a0;
if (!context) context = buffer = path();
// Ensure that the outer radius is always larger than the inner radius.
if (r1 < r0) r = r1, r1 = r0, r0 = r;
// Is it a point?
if (!(r1 > epsilon)) context.moveTo(0, 0);
// Or is it a circle or annulus?
else if (da > tau - epsilon) {
context.moveTo(r1 * cos(a0), r1 * sin(a0));
context.arc(0, 0, r1, a0, a1, !cw);
if (r0 > epsilon) {
context.moveTo(r0 * cos(a1), r0 * sin(a1));
context.arc(0, 0, r0, a1, a0, cw);
}
}
// Or is it a circular or annular sector?
else {
var a01 = a0,
a11 = a1,
a00 = a0,
a10 = a1,
da0 = da,
da1 = da,
ap = padAngle.apply(this, arguments) / 2,
rp = (ap > epsilon) && (padRadius ? +padRadius.apply(this, arguments) : sqrt(r0 * r0 + r1 * r1)),
rc = min(abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),
rc0 = rc,
rc1 = rc,
t0,
t1;
// Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.
if (rp > epsilon) {
var p0 = asin(rp / r0 * sin(ap)),
p1 = asin(rp / r1 * sin(ap));
if ((da0 -= p0 * 2) > epsilon) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;
else da0 = 0, a00 = a10 = (a0 + a1) / 2;
if ((da1 -= p1 * 2) > epsilon) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;
else da1 = 0, a01 = a11 = (a0 + a1) / 2;
}
var x01 = r1 * cos(a01),
y01 = r1 * sin(a01),
x10 = r0 * cos(a10),
y10 = r0 * sin(a10);
// Apply rounded corners?
if (rc > epsilon) {
var x11 = r1 * cos(a11),
y11 = r1 * sin(a11),
x00 = r0 * cos(a00),
y00 = r0 * sin(a00),
oc;
// Restrict the corner radius according to the sector angle. If this
// intersection fails, its probably because the arc is too small, so
// disable the corner radius entirely.
if (da < pi) {
if (oc = intersect(x01, y01, x00, y00, x11, y11, x10, y10)) {
var ax = x01 - oc[0],
ay = y01 - oc[1],
bx = x11 - oc[0],
by = y11 - oc[1],
kc = 1 / sin(acos((ax * bx + ay * by) / (sqrt(ax * ax + ay * ay) * sqrt(bx * bx + by * by))) / 2),
lc = sqrt(oc[0] * oc[0] + oc[1] * oc[1]);
rc0 = min(rc, (r0 - lc) / (kc - 1));
rc1 = min(rc, (r1 - lc) / (kc + 1));
} else {
rc0 = rc1 = 0;
}
}
}
// Is the sector collapsed to a line?
if (!(da1 > epsilon)) context.moveTo(x01, y01);
// Does the sectors outer ring have rounded corners?
else if (rc1 > epsilon) {
t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);
t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);
context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);
// Have the corners merged?
if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw);
// Otherwise, draw the two corners and the ring.
else {
context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw);
context.arc(0, 0, r1, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw);
context.arc(t1.cx, t1.cy, rc1, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw);
}
}
// Or is the outer ring just a circular arc?
else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);
// Is there no inner ring, and its a circular sector?
// Or perhaps its an annular sector collapsed due to padding?
if (!(r0 > epsilon) || !(da0 > epsilon)) context.lineTo(x10, y10);
// Does the sectors inner ring (or point) have rounded corners?
else if (rc0 > epsilon) {
t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);
t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);
context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);
// Have the corners merged?
if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw);
// Otherwise, draw the two corners and the ring.
else {
context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw);
context.arc(0, 0, r0, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), cw);
context.arc(t1.cx, t1.cy, rc0, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw);
}
}
// Or is the inner ring just a circular arc?
else context.arc(0, 0, r0, a10, a00, cw);
}
context.closePath();
if (buffer) return context = null, buffer + "" || null;
}
arc.centroid = function() {
var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,
a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi / 2;
return [cos(a) * r, sin(a) * r];
};
arc.innerRadius = function(_) {
return arguments.length ? (innerRadius = typeof _ === "function" ? _ : constant(+_), arc) : innerRadius;
};
arc.outerRadius = function(_) {
return arguments.length ? (outerRadius = typeof _ === "function" ? _ : constant(+_), arc) : outerRadius;
};
arc.cornerRadius = function(_) {
return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : constant(+_), arc) : cornerRadius;
};
arc.padRadius = function(_) {
return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : constant(+_), arc) : padRadius;
};
arc.startAngle = function(_) {
return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant(+_), arc) : startAngle;
};
arc.endAngle = function(_) {
return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant(+_), arc) : endAngle;
};
arc.padAngle = function(_) {
return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant(+_), arc) : padAngle;
};
arc.context = function(_) {
return arguments.length ? ((context = _ == null ? null : _), arc) : context;
};
return arc;
}
export { d3arc as d };
-270
View File
@@ -1,270 +0,0 @@
'use strict';
const index = require('./index-DKX_wW-G.cjs');
function arcInnerRadius(d) {
return d.innerRadius;
}
function arcOuterRadius(d) {
return d.outerRadius;
}
function arcStartAngle(d) {
return d.startAngle;
}
function arcEndAngle(d) {
return d.endAngle;
}
function arcPadAngle(d) {
return d && d.padAngle; // Note: optional!
}
function intersect(x0, y0, x1, y1, x2, y2, x3, y3) {
var x10 = x1 - x0, y10 = y1 - y0,
x32 = x3 - x2, y32 = y3 - y2,
t = y32 * x10 - x32 * y10;
if (t * t < index.epsilon) return;
t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / t;
return [x0 + t * x10, y0 + t * y10];
}
// Compute perpendicular offset line of length rc.
// http://mathworld.wolfram.com/Circle-LineIntersection.html
function cornerTangents(x0, y0, x1, y1, r1, rc, cw) {
var x01 = x0 - x1,
y01 = y0 - y1,
lo = (cw ? rc : -rc) / index.sqrt(x01 * x01 + y01 * y01),
ox = lo * y01,
oy = -lo * x01,
x11 = x0 + ox,
y11 = y0 + oy,
x10 = x1 + ox,
y10 = y1 + oy,
x00 = (x11 + x10) / 2,
y00 = (y11 + y10) / 2,
dx = x10 - x11,
dy = y10 - y11,
d2 = dx * dx + dy * dy,
r = r1 - rc,
D = x11 * y10 - x10 * y11,
d = (dy < 0 ? -1 : 1) * index.sqrt(index.max(0, r * r * d2 - D * D)),
cx0 = (D * dy - dx * d) / d2,
cy0 = (-D * dx - dy * d) / d2,
cx1 = (D * dy + dx * d) / d2,
cy1 = (-D * dx + dy * d) / d2,
dx0 = cx0 - x00,
dy0 = cy0 - y00,
dx1 = cx1 - x00,
dy1 = cy1 - y00;
// Pick the closer of the two intersection points.
// TODO Is there a faster way to determine which intersection to use?
if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;
return {
cx: cx0,
cy: cy0,
x01: -ox,
y01: -oy,
x11: cx0 * (r1 / r - 1),
y11: cy0 * (r1 / r - 1)
};
}
function d3arc() {
var innerRadius = arcInnerRadius,
outerRadius = arcOuterRadius,
cornerRadius = index.constant(0),
padRadius = null,
startAngle = arcStartAngle,
endAngle = arcEndAngle,
padAngle = arcPadAngle,
context = null,
path = index.withPath(arc);
function arc() {
var buffer,
r,
r0 = +innerRadius.apply(this, arguments),
r1 = +outerRadius.apply(this, arguments),
a0 = startAngle.apply(this, arguments) - index.halfPi,
a1 = endAngle.apply(this, arguments) - index.halfPi,
da = index.abs(a1 - a0),
cw = a1 > a0;
if (!context) context = buffer = path();
// Ensure that the outer radius is always larger than the inner radius.
if (r1 < r0) r = r1, r1 = r0, r0 = r;
// Is it a point?
if (!(r1 > index.epsilon)) context.moveTo(0, 0);
// Or is it a circle or annulus?
else if (da > index.tau - index.epsilon) {
context.moveTo(r1 * index.cos(a0), r1 * index.sin(a0));
context.arc(0, 0, r1, a0, a1, !cw);
if (r0 > index.epsilon) {
context.moveTo(r0 * index.cos(a1), r0 * index.sin(a1));
context.arc(0, 0, r0, a1, a0, cw);
}
}
// Or is it a circular or annular sector?
else {
var a01 = a0,
a11 = a1,
a00 = a0,
a10 = a1,
da0 = da,
da1 = da,
ap = padAngle.apply(this, arguments) / 2,
rp = (ap > index.epsilon) && (padRadius ? +padRadius.apply(this, arguments) : index.sqrt(r0 * r0 + r1 * r1)),
rc = index.min(index.abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),
rc0 = rc,
rc1 = rc,
t0,
t1;
// Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.
if (rp > index.epsilon) {
var p0 = index.asin(rp / r0 * index.sin(ap)),
p1 = index.asin(rp / r1 * index.sin(ap));
if ((da0 -= p0 * 2) > index.epsilon) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;
else da0 = 0, a00 = a10 = (a0 + a1) / 2;
if ((da1 -= p1 * 2) > index.epsilon) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;
else da1 = 0, a01 = a11 = (a0 + a1) / 2;
}
var x01 = r1 * index.cos(a01),
y01 = r1 * index.sin(a01),
x10 = r0 * index.cos(a10),
y10 = r0 * index.sin(a10);
// Apply rounded corners?
if (rc > index.epsilon) {
var x11 = r1 * index.cos(a11),
y11 = r1 * index.sin(a11),
x00 = r0 * index.cos(a00),
y00 = r0 * index.sin(a00),
oc;
// Restrict the corner radius according to the sector angle. If this
// intersection fails, its probably because the arc is too small, so
// disable the corner radius entirely.
if (da < index.pi) {
if (oc = intersect(x01, y01, x00, y00, x11, y11, x10, y10)) {
var ax = x01 - oc[0],
ay = y01 - oc[1],
bx = x11 - oc[0],
by = y11 - oc[1],
kc = 1 / index.sin(index.acos((ax * bx + ay * by) / (index.sqrt(ax * ax + ay * ay) * index.sqrt(bx * bx + by * by))) / 2),
lc = index.sqrt(oc[0] * oc[0] + oc[1] * oc[1]);
rc0 = index.min(rc, (r0 - lc) / (kc - 1));
rc1 = index.min(rc, (r1 - lc) / (kc + 1));
} else {
rc0 = rc1 = 0;
}
}
}
// Is the sector collapsed to a line?
if (!(da1 > index.epsilon)) context.moveTo(x01, y01);
// Does the sectors outer ring have rounded corners?
else if (rc1 > index.epsilon) {
t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);
t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);
context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);
// Have the corners merged?
if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, index.atan2(t0.y01, t0.x01), index.atan2(t1.y01, t1.x01), !cw);
// Otherwise, draw the two corners and the ring.
else {
context.arc(t0.cx, t0.cy, rc1, index.atan2(t0.y01, t0.x01), index.atan2(t0.y11, t0.x11), !cw);
context.arc(0, 0, r1, index.atan2(t0.cy + t0.y11, t0.cx + t0.x11), index.atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw);
context.arc(t1.cx, t1.cy, rc1, index.atan2(t1.y11, t1.x11), index.atan2(t1.y01, t1.x01), !cw);
}
}
// Or is the outer ring just a circular arc?
else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);
// Is there no inner ring, and its a circular sector?
// Or perhaps its an annular sector collapsed due to padding?
if (!(r0 > index.epsilon) || !(da0 > index.epsilon)) context.lineTo(x10, y10);
// Does the sectors inner ring (or point) have rounded corners?
else if (rc0 > index.epsilon) {
t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);
t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);
context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);
// Have the corners merged?
if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, index.atan2(t0.y01, t0.x01), index.atan2(t1.y01, t1.x01), !cw);
// Otherwise, draw the two corners and the ring.
else {
context.arc(t0.cx, t0.cy, rc0, index.atan2(t0.y01, t0.x01), index.atan2(t0.y11, t0.x11), !cw);
context.arc(0, 0, r0, index.atan2(t0.cy + t0.y11, t0.cx + t0.x11), index.atan2(t1.cy + t1.y11, t1.cx + t1.x11), cw);
context.arc(t1.cx, t1.cy, rc0, index.atan2(t1.y11, t1.x11), index.atan2(t1.y01, t1.x01), !cw);
}
}
// Or is the inner ring just a circular arc?
else context.arc(0, 0, r0, a10, a00, cw);
}
context.closePath();
if (buffer) return context = null, buffer + "" || null;
}
arc.centroid = function() {
var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,
a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - index.pi / 2;
return [index.cos(a) * r, index.sin(a) * r];
};
arc.innerRadius = function(_) {
return arguments.length ? (innerRadius = typeof _ === "function" ? _ : index.constant(+_), arc) : innerRadius;
};
arc.outerRadius = function(_) {
return arguments.length ? (outerRadius = typeof _ === "function" ? _ : index.constant(+_), arc) : outerRadius;
};
arc.cornerRadius = function(_) {
return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : index.constant(+_), arc) : cornerRadius;
};
arc.padRadius = function(_) {
return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : index.constant(+_), arc) : padRadius;
};
arc.startAngle = function(_) {
return arguments.length ? (startAngle = typeof _ === "function" ? _ : index.constant(+_), arc) : startAngle;
};
arc.endAngle = function(_) {
return arguments.length ? (endAngle = typeof _ === "function" ? _ : index.constant(+_), arc) : endAngle;
};
arc.padAngle = function(_) {
return arguments.length ? (padAngle = typeof _ === "function" ? _ : index.constant(+_), arc) : padAngle;
};
arc.context = function(_) {
return arguments.length ? ((context = _ == null ? null : _), arc) : context;
};
return arc;
}
exports.d3arc = d3arc;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,3 +0,0 @@
var __viteBrowserExternal = {};
export { __viteBrowserExternal as default };
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-7
View File
@@ -1,7 +0,0 @@
const lang = Object.freeze(JSON.parse("{\"displayName\":\"Berry\",\"name\":\"berry\",\"patterns\":[{\"include\":\"#controls\"},{\"include\":\"#strings\"},{\"include\":\"#comment-block\"},{\"include\":\"#comments\"},{\"include\":\"#keywords\"},{\"include\":\"#function\"},{\"include\":\"#member\"},{\"include\":\"#identifier\"},{\"include\":\"#number\"},{\"include\":\"#operator\"}],\"repository\":{\"comment-block\":{\"begin\":\"#-\",\"end\":\"-#\",\"name\":\"comment.berry\",\"patterns\":[{}]},\"comments\":{\"begin\":\"#\",\"end\":\"\\\\n\",\"name\":\"comment.line.berry\",\"patterns\":[{}]},\"controls\":{\"patterns\":[{\"match\":\"\\\\b(if|elif|else|for|while|do|end|break|continue|return|try|except|raise)\\\\b\",\"name\":\"keyword.control.berry\"}]},\"function\":{\"patterns\":[{\"match\":\"\\\\b([A-Z_a-z][0-9A-Z_a-z]*(?=\\\\s*\\\\())\",\"name\":\"entity.name.function.berry\"}]},\"identifier\":{\"patterns\":[{\"match\":\"\\\\b[A-Z_a-z]\\\\w+\\\\b\",\"name\":\"identifier.berry\"}]},\"keywords\":{\"patterns\":[{\"match\":\"\\\\b(var|static|def|class|true|false|nil|self|super|import|as|_class)\\\\b\",\"name\":\"keyword.berry\"}]},\"member\":{\"patterns\":[{\"captures\":{\"0\":{\"name\":\"entity.other.attribute-name.berry\"}},\"match\":\"\\\\.([A-Z_a-z][0-9A-Z_a-z]*)\"}]},\"number\":{\"patterns\":[{\"match\":\"0x\\\\h+|\\\\d+|(\\\\d+\\\\.?|\\\\.\\\\d)\\\\d*([Ee][-+]?\\\\d+)?\",\"name\":\"constant.numeric.berry\"}]},\"operator\":{\"patterns\":[{\"match\":\"[-\\\\]!%\\\\&(-+./:<=>\\\\[^|~]\",\"name\":\"keyword.operator.berry\"}]},\"strings\":{\"patterns\":[{\"begin\":\"f(?=[\\\"'])\",\"patterns\":[{\"begin\":\"\\\"\",\"end\":\"\\\"\",\"name\":\"string.quoted.other.berry\",\"patterns\":[{\"match\":\"(\\\\\\\\x\\\\h{2})|(\\\\\\\\[0-7]{3})|(\\\\\\\\\\\\\\\\)|(\\\\\\\\\\\")|(\\\\\\\\')|(\\\\\\\\a)|(\\\\\\\\b)|(\\\\\\\\f)|(\\\\\\\\n)|(\\\\\\\\r)|(\\\\\\\\t)|(\\\\\\\\v)\",\"name\":\"constant.character.escape.berry\"},{\"match\":\"\\\\{\\\\{[^}]*}}\",\"name\":\"string.quoted.other.berry\"},{\"begin\":\"\\\\{\",\"end\":\"}\",\"name\":\"keyword.other.unit.berry\",\"patterns\":[{\"include\":\"#keywords\"},{\"include\":\"#numbers\"},{\"include\":\"#identifier\"},{\"include\":\"#operator\"},{\"include\":\"#member\"},{\"include\":\"#function\"}]}]},{\"begin\":\"'\",\"end\":\"'\",\"name\":\"string.quoted.other.berry\",\"patterns\":[{\"match\":\"(\\\\\\\\x\\\\h{2})|(\\\\\\\\[0-7]{3})|(\\\\\\\\\\\\\\\\)|(\\\\\\\\\\\")|(\\\\\\\\')|(\\\\\\\\a)|(\\\\\\\\b)|(\\\\\\\\f)|(\\\\\\\\n)|(\\\\\\\\r)|(\\\\\\\\t)|(\\\\\\\\v)\",\"name\":\"constant.character.escape.berry\"},{\"match\":\"\\\\{\\\\{[^}]*}}\",\"name\":\"string.quoted.other.berry\"},{\"begin\":\"\\\\{\",\"end\":\"}\",\"name\":\"keyword.other.unit.berry\",\"patterns\":[{\"include\":\"#keywords\"},{\"include\":\"#numbers\"},{\"include\":\"#identifier\"},{\"include\":\"#operator\"},{\"include\":\"#member\"},{\"include\":\"#function\"}]}]}],\"while\":\"\\\\G|^[\\\\t ]*(?=[\\\"'])\"},{\"begin\":\"([\\\"'])\",\"end\":\"\\\\1\",\"name\":\"string.quoted.double.berry\",\"patterns\":[{\"match\":\"(\\\\\\\\x\\\\h{2})|(\\\\\\\\[0-7]{3})|(\\\\\\\\\\\\\\\\)|(\\\\\\\\\\\")|(\\\\\\\\')|(\\\\\\\\a)|(\\\\\\\\b)|(\\\\\\\\f)|(\\\\\\\\n)|(\\\\\\\\r)|(\\\\\\\\t)|(\\\\\\\\v)\",\"name\":\"constant.character.escape.berry\"}]}]}},\"scopeName\":\"source.berry\",\"aliases\":[\"be\"]}"));
const berry = [
lang
];
export { berry as default };
-11
View File
@@ -1,11 +0,0 @@
'use strict';
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const lang = Object.freeze(JSON.parse("{\"displayName\":\"Berry\",\"name\":\"berry\",\"patterns\":[{\"include\":\"#controls\"},{\"include\":\"#strings\"},{\"include\":\"#comment-block\"},{\"include\":\"#comments\"},{\"include\":\"#keywords\"},{\"include\":\"#function\"},{\"include\":\"#member\"},{\"include\":\"#identifier\"},{\"include\":\"#number\"},{\"include\":\"#operator\"}],\"repository\":{\"comment-block\":{\"begin\":\"#-\",\"end\":\"-#\",\"name\":\"comment.berry\",\"patterns\":[{}]},\"comments\":{\"begin\":\"#\",\"end\":\"\\\\n\",\"name\":\"comment.line.berry\",\"patterns\":[{}]},\"controls\":{\"patterns\":[{\"match\":\"\\\\b(if|elif|else|for|while|do|end|break|continue|return|try|except|raise)\\\\b\",\"name\":\"keyword.control.berry\"}]},\"function\":{\"patterns\":[{\"match\":\"\\\\b([A-Z_a-z][0-9A-Z_a-z]*(?=\\\\s*\\\\())\",\"name\":\"entity.name.function.berry\"}]},\"identifier\":{\"patterns\":[{\"match\":\"\\\\b[A-Z_a-z]\\\\w+\\\\b\",\"name\":\"identifier.berry\"}]},\"keywords\":{\"patterns\":[{\"match\":\"\\\\b(var|static|def|class|true|false|nil|self|super|import|as|_class)\\\\b\",\"name\":\"keyword.berry\"}]},\"member\":{\"patterns\":[{\"captures\":{\"0\":{\"name\":\"entity.other.attribute-name.berry\"}},\"match\":\"\\\\.([A-Z_a-z][0-9A-Z_a-z]*)\"}]},\"number\":{\"patterns\":[{\"match\":\"0x\\\\h+|\\\\d+|(\\\\d+\\\\.?|\\\\.\\\\d)\\\\d*([Ee][-+]?\\\\d+)?\",\"name\":\"constant.numeric.berry\"}]},\"operator\":{\"patterns\":[{\"match\":\"[-\\\\]!%\\\\&(-+./:<=>\\\\[^|~]\",\"name\":\"keyword.operator.berry\"}]},\"strings\":{\"patterns\":[{\"begin\":\"f(?=[\\\"'])\",\"patterns\":[{\"begin\":\"\\\"\",\"end\":\"\\\"\",\"name\":\"string.quoted.other.berry\",\"patterns\":[{\"match\":\"(\\\\\\\\x\\\\h{2})|(\\\\\\\\[0-7]{3})|(\\\\\\\\\\\\\\\\)|(\\\\\\\\\\\")|(\\\\\\\\')|(\\\\\\\\a)|(\\\\\\\\b)|(\\\\\\\\f)|(\\\\\\\\n)|(\\\\\\\\r)|(\\\\\\\\t)|(\\\\\\\\v)\",\"name\":\"constant.character.escape.berry\"},{\"match\":\"\\\\{\\\\{[^}]*}}\",\"name\":\"string.quoted.other.berry\"},{\"begin\":\"\\\\{\",\"end\":\"}\",\"name\":\"keyword.other.unit.berry\",\"patterns\":[{\"include\":\"#keywords\"},{\"include\":\"#numbers\"},{\"include\":\"#identifier\"},{\"include\":\"#operator\"},{\"include\":\"#member\"},{\"include\":\"#function\"}]}]},{\"begin\":\"'\",\"end\":\"'\",\"name\":\"string.quoted.other.berry\",\"patterns\":[{\"match\":\"(\\\\\\\\x\\\\h{2})|(\\\\\\\\[0-7]{3})|(\\\\\\\\\\\\\\\\)|(\\\\\\\\\\\")|(\\\\\\\\')|(\\\\\\\\a)|(\\\\\\\\b)|(\\\\\\\\f)|(\\\\\\\\n)|(\\\\\\\\r)|(\\\\\\\\t)|(\\\\\\\\v)\",\"name\":\"constant.character.escape.berry\"},{\"match\":\"\\\\{\\\\{[^}]*}}\",\"name\":\"string.quoted.other.berry\"},{\"begin\":\"\\\\{\",\"end\":\"}\",\"name\":\"keyword.other.unit.berry\",\"patterns\":[{\"include\":\"#keywords\"},{\"include\":\"#numbers\"},{\"include\":\"#identifier\"},{\"include\":\"#operator\"},{\"include\":\"#member\"},{\"include\":\"#function\"}]}]}],\"while\":\"\\\\G|^[\\\\t ]*(?=[\\\"'])\"},{\"begin\":\"([\\\"'])\",\"end\":\"\\\\1\",\"name\":\"string.quoted.double.berry\",\"patterns\":[{\"match\":\"(\\\\\\\\x\\\\h{2})|(\\\\\\\\[0-7]{3})|(\\\\\\\\\\\\\\\\)|(\\\\\\\\\\\")|(\\\\\\\\')|(\\\\\\\\a)|(\\\\\\\\b)|(\\\\\\\\f)|(\\\\\\\\n)|(\\\\\\\\r)|(\\\\\\\\t)|(\\\\\\\\v)\",\"name\":\"constant.character.escape.berry\"}]}]}},\"scopeName\":\"source.berry\",\"aliases\":[\"be\"]}"));
const berry = [
lang
];
exports.default = berry;
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-14
View File
@@ -1,14 +0,0 @@
'use strict';
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const python = require('./python-R5Doq6Ap.cjs');
const lang = Object.freeze(JSON.parse("{\"displayName\":\"Cairo\",\"name\":\"cairo\",\"patterns\":[{\"begin\":\"\\\\b(if).*\\\\(\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.if\"},\"2\":{\"name\":\"entity.name.condition\"}},\"contentName\":\"source.cairo0\",\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"keyword.control.end\"}},\"name\":\"meta.control.if\",\"patterns\":[{\"include\":\"source.cairo0\"}]},{\"begin\":\"\\\\b(with)\\\\s+(.+)\\\\s*\\\\{\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.with\"},\"2\":{\"name\":\"entity.name.identifiers\"}},\"contentName\":\"source.cairo0\",\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"keyword.control.end\"}},\"name\":\"meta.control.with\",\"patterns\":[{\"include\":\"source.cairo0\"}]},{\"begin\":\"\\\\b(with_attr)\\\\s+([A-Z_a-z][0-9A-Z_a-z]*)\\\\s*[({]\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.with_attr\"},\"2\":{\"name\":\"entity.name.function\"}},\"contentName\":\"source.cairo0\",\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"keyword.control.end\"}},\"name\":\"meta.control.with_attr\",\"patterns\":[{\"include\":\"source.cairo0\"}]},{\"match\":\"\\\\belse\\\\b\",\"name\":\"keyword.control.else\"},{\"match\":\"\\\\b(call|jmp|ret|abs|rel|if)\\\\b\",\"name\":\"keyword.other.opcode\"},{\"match\":\"\\\\b([af]p)\\\\b\",\"name\":\"keyword.other.register\"},{\"match\":\"\\\\b(const|let|local|tempvar|felt|as|from|import|static_assert|return|assert|cast|alloc_locals|with|with_attr|nondet|dw|codeoffset|new|using|and)\\\\b\",\"name\":\"keyword.other.meta\"},{\"match\":\"\\\\b(SIZE(?:OF_LOCALS|))\\\\b\",\"name\":\"markup.italic\"},{\"match\":\"//[^\\\\n]*\\\\n\",\"name\":\"comment.line.sharp\"},{\"match\":\"\\\\b[A-Z_a-z][0-9A-Z_a-z]*:\\\\s*$\",\"name\":\"entity.name.function\"},{\"begin\":\"\\\\b(func)\\\\s+([A-Z_a-z][0-9A-Z_a-z]*)\\\\s*[({]\",\"beginCaptures\":{\"1\":{\"name\":\"storage.type.function.cairo\"},\"2\":{\"name\":\"entity.name.function\"}},\"contentName\":\"source.cairo0\",\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"storage.type.function.cairo\"}},\"name\":\"meta.function.cairo\",\"patterns\":[{\"include\":\"source.cairo0\"}]},{\"begin\":\"\\\\b(struct|namespace)\\\\s+([A-Z_a-z][0-9A-Z_a-z]*)\\\\s*\\\\{\",\"beginCaptures\":{\"1\":{\"name\":\"storage.type.function.cairo\"},\"2\":{\"name\":\"entity.name.function\"}},\"contentName\":\"source.cairo0\",\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"storage.type.function.cairo\"}},\"name\":\"meta.function.cairo\",\"patterns\":[{\"include\":\"source.cairo0\"}]},{\"match\":\"\\\\b[-+]?[0-9]+\\\\b\",\"name\":\"constant.numeric.decimal\"},{\"match\":\"\\\\b[-+]?0x\\\\h+\\\\b\",\"name\":\"constant.numeric.hexadecimal\"},{\"match\":\"'[^']*'\",\"name\":\"string.quoted.single\"},{\"match\":\"\\\"[^\\\"]*\\\"\",\"name\":\"string.quoted.double\"},{\"begin\":\"%\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.begin.python\"}},\"contentName\":\"source.python\",\"end\":\"%}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.end.python\"},\"1\":{\"name\":\"source.python\"}},\"name\":\"meta.embedded.block.python\",\"patterns\":[{\"include\":\"source.python\"}]}],\"scopeName\":\"source.cairo0\",\"embeddedLangs\":[\"python\"]}"));
const cairo = [
...python.default,
lang
];
exports.default = cairo;
-10
View File
@@ -1,10 +0,0 @@
import python from './python-CRy0opiU.js';
const lang = Object.freeze(JSON.parse("{\"displayName\":\"Cairo\",\"name\":\"cairo\",\"patterns\":[{\"begin\":\"\\\\b(if).*\\\\(\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.if\"},\"2\":{\"name\":\"entity.name.condition\"}},\"contentName\":\"source.cairo0\",\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"keyword.control.end\"}},\"name\":\"meta.control.if\",\"patterns\":[{\"include\":\"source.cairo0\"}]},{\"begin\":\"\\\\b(with)\\\\s+(.+)\\\\s*\\\\{\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.with\"},\"2\":{\"name\":\"entity.name.identifiers\"}},\"contentName\":\"source.cairo0\",\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"keyword.control.end\"}},\"name\":\"meta.control.with\",\"patterns\":[{\"include\":\"source.cairo0\"}]},{\"begin\":\"\\\\b(with_attr)\\\\s+([A-Z_a-z][0-9A-Z_a-z]*)\\\\s*[({]\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.with_attr\"},\"2\":{\"name\":\"entity.name.function\"}},\"contentName\":\"source.cairo0\",\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"keyword.control.end\"}},\"name\":\"meta.control.with_attr\",\"patterns\":[{\"include\":\"source.cairo0\"}]},{\"match\":\"\\\\belse\\\\b\",\"name\":\"keyword.control.else\"},{\"match\":\"\\\\b(call|jmp|ret|abs|rel|if)\\\\b\",\"name\":\"keyword.other.opcode\"},{\"match\":\"\\\\b([af]p)\\\\b\",\"name\":\"keyword.other.register\"},{\"match\":\"\\\\b(const|let|local|tempvar|felt|as|from|import|static_assert|return|assert|cast|alloc_locals|with|with_attr|nondet|dw|codeoffset|new|using|and)\\\\b\",\"name\":\"keyword.other.meta\"},{\"match\":\"\\\\b(SIZE(?:OF_LOCALS|))\\\\b\",\"name\":\"markup.italic\"},{\"match\":\"//[^\\\\n]*\\\\n\",\"name\":\"comment.line.sharp\"},{\"match\":\"\\\\b[A-Z_a-z][0-9A-Z_a-z]*:\\\\s*$\",\"name\":\"entity.name.function\"},{\"begin\":\"\\\\b(func)\\\\s+([A-Z_a-z][0-9A-Z_a-z]*)\\\\s*[({]\",\"beginCaptures\":{\"1\":{\"name\":\"storage.type.function.cairo\"},\"2\":{\"name\":\"entity.name.function\"}},\"contentName\":\"source.cairo0\",\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"storage.type.function.cairo\"}},\"name\":\"meta.function.cairo\",\"patterns\":[{\"include\":\"source.cairo0\"}]},{\"begin\":\"\\\\b(struct|namespace)\\\\s+([A-Z_a-z][0-9A-Z_a-z]*)\\\\s*\\\\{\",\"beginCaptures\":{\"1\":{\"name\":\"storage.type.function.cairo\"},\"2\":{\"name\":\"entity.name.function\"}},\"contentName\":\"source.cairo0\",\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"storage.type.function.cairo\"}},\"name\":\"meta.function.cairo\",\"patterns\":[{\"include\":\"source.cairo0\"}]},{\"match\":\"\\\\b[-+]?[0-9]+\\\\b\",\"name\":\"constant.numeric.decimal\"},{\"match\":\"\\\\b[-+]?0x\\\\h+\\\\b\",\"name\":\"constant.numeric.hexadecimal\"},{\"match\":\"'[^']*'\",\"name\":\"string.quoted.single\"},{\"match\":\"\\\"[^\\\"]*\\\"\",\"name\":\"string.quoted.double\"},{\"begin\":\"%\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.begin.python\"}},\"contentName\":\"source.python\",\"end\":\"%}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.end.python\"},\"1\":{\"name\":\"source.python\"}},\"name\":\"meta.embedded.block.python\",\"patterns\":[{\"include\":\"source.python\"}]}],\"scopeName\":\"source.cairo0\",\"embeddedLangs\":[\"python\"]}"));
const cairo = [
...python,
lang
];
export { cairo as default };
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More