@malloy-publisher/server 0.9.0 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/README.docker.md +46 -5
  2. package/dist/app/api-doc.yaml +144 -54
  3. package/dist/app/assets/EnvironmentPage-B-t_QP32.js +1 -0
  4. package/dist/app/assets/{HomePage-D3MvQaZn.js → HomePage-Cpu2zMy-.js} +1 -1
  5. package/dist/app/assets/{LightMode-e1lNBfpL.js → LightMode-DOBl6awB.js} +1 -1
  6. package/dist/app/assets/MainPage-C7ySrclP.js +1 -0
  7. package/dist/app/assets/ModelPage-D8r_J-N9.js +2 -0
  8. package/dist/app/assets/PackagePage-CcVFBhnT.js +1 -0
  9. package/dist/app/assets/RenderedResult-CBLHr32C.es-DRr9Gmsz.js +141 -0
  10. package/dist/app/assets/{RouteError-BQnzPJvb.js → RouteError-mgOkv7XK.js} +1 -1
  11. package/dist/app/assets/ThemeEditorPage-CIPDs2w9.js +1 -0
  12. package/dist/app/assets/ToggleButtonGroup-CEZThrzh.js +1 -0
  13. package/dist/app/assets/{index-CCNqF0-G.js → index-Bg-M8sZz.js} +1 -1
  14. package/dist/app/assets/index-CGdwupPP.js +457 -0
  15. package/dist/app/assets/{index-CKmZ4HG7.js → index-CeLTZAFW.js} +116 -116
  16. package/dist/app/assets/{index-CdExa3Pk.js → index-DoF8ihra.js} +1 -1
  17. package/dist/app/assets/{index-ufFZR_K-.js → index-IC0jPCkR.js} +1 -1
  18. package/dist/app/assets/index.es-6eARPKZf.js +198 -0
  19. package/dist/app/index.html +1 -1
  20. package/dist/package_load_worker.mjs +571 -107
  21. package/dist/server.mjs +10356 -9719
  22. package/package.json +1 -1
  23. package/dist/app/assets/EnvironmentPage-UMS7Py4Q.js +0 -1
  24. package/dist/app/assets/MainPage-B0ozqtQO.js +0 -2
  25. package/dist/app/assets/ModelPage-lQj4Axqu.js +0 -2
  26. package/dist/app/assets/PackagePage-BT0YKNKU.js +0 -1
  27. package/dist/app/assets/RenderedResult-BRgIgxWh.es-DiE7kPNX.js +0 -136
  28. package/dist/app/assets/ThemeEditorPage-D6t7w9Js.js +0 -1
  29. package/dist/app/assets/ToggleButtonGroup-CJT2JKTC.js +0 -1
  30. package/dist/app/assets/index-TiWjmdoW.js +0 -450
  31. package/dist/app/assets/index.es-iUV0gCYk.js +0 -111
  32. package/dist/cpufeatures-1yrn0vtw.node +0 -0
package/README.docker.md CHANGED
@@ -80,12 +80,26 @@ Every application file is root-owned, so the server cannot modify one in place.
80
80
 
81
81
  - `/publisher/`, the server root, where it creates `publisher.db`. Because it owns this directory, the server can also rename aside and replace any of its top-level entries: `package.json`, `bun.lock`, and the `packages/` and `node_modules/` directories. Such a change lasts as long as the container. Some storage drivers, Docker's default overlayfs among them, refuse to rename a directory that comes from an image layer, but that is the driver's limit, not the image's.
82
82
  - `/publisher/publisher_data/`.
83
+ - `/publisher/ducklake_data/`, when a DuckLake storage destination's `bucketUrl` points there.
83
84
  - `/home/bun/.duckdb/extensions/`, for an extension the image did not bake.
84
85
 
85
- What you mount has to be writable by uid 1000 too:
86
+ What you mount has to be writable by uid 1000 too. Per kind of mount:
86
87
 
87
- - **A new named volume on `/publisher/publisher_data`** works as-is. Docker seeds an empty named volume from the image's directory, ownership included, and that is the only writable mount point the image prepares.
88
- - **A new named volume anywhere else** starts owned by root, because the image has no directory there to copy ownership from. That includes a DuckLake storage destination whose `bucketUrl` is a local path. Prepare it yourself: build a derived image with `RUN mkdir -p /path && chown 1000:1000 /path` (new named volumes there are then seeded correctly), chown the volume once with `--user 0`, or bind-mount a host directory owned by uid 1000. DuckDB reports the unprepared case as `No such file or directory` (for example `Failed to create directory "/data/lake/main/daily_orders"`), not as `EACCES`. The one-time chown names the mount path twice, as the mount target and as chown's argument:
88
+ | Mount | The server | What to do |
89
+ | --- | --- | --- |
90
+ | A new named volume on `/publisher/publisher_data` or `/publisher/ducklake_data` | writes | Nothing: Docker seeds it from the image, owned by uid 1000. |
91
+ | A new named volume anywhere else | writes | `docker run --rm --user 0 --entrypoint chown -v <volume>:/path ms2data/malloy-publisher -R 1000:1000 /path`, once. |
92
+ | A volume an older, root-run image wrote to | writes | The same `chown`, once, before starting the new image. With Compose, `docker compose run --rm --no-deps --user 0 --entrypoint chown publisher -R 1000:1000 /publisher/publisher_data`. |
93
+ | A bind of a host directory the server writes | writes | `sudo chown -R 1000:1000 <dir>`, or keep your ownership and add an ACL, which needs no `sudo` on a directory you own: `setfacl -R -m u:1000:rwX -m d:u:1000:rwX <dir>`. |
94
+ | A bind of a host directory the server only reads (a package `location`, a directory of zips) | reads | Readable by others, `chmod -R o+rX <dir>`, or group-readable with `sudo chgrp -R 1000 <dir> && chmod -R g+rX <dir>`. Mount it `:ro`. |
95
+ | A single bound file (the config, a key file) | reads | Readable by others or by gid 1000; a `0600` file is not. See the key-file recipes below. Mount it `:ro`. |
96
+ | A Kubernetes PersistentVolume | writes | `fsGroup: 1000` and `fsGroupChangePolicy: OnRootMismatch` in the pod's `securityContext`. |
97
+ | A Kubernetes Secret or projected token | reads | `fsGroup: 1000` makes a `0600`-mounted file readable by the group. |
98
+
99
+ Before starting the server, the probe at the end of this section confirms a mount is usable as uid 1000. The detail behind each row:
100
+
101
+ - **A new named volume on `/publisher/publisher_data` or `/publisher/ducklake_data`** works as-is. Docker seeds an empty named volume from the image's directory, ownership included, and those are the two writable mount points the image prepares: `publisher_data` for packages and per-package sandboxes, `ducklake_data` for a DuckLake storage destination whose `bucketUrl` is a local path.
102
+ - **A new named volume anywhere else** starts owned by root, because the image has no directory there to copy ownership from. Prepare it yourself: build a derived image with `RUN mkdir -p /path && chown 1000:1000 /path` (new named volumes there are then seeded correctly), chown the volume once with `--user 0`, or bind-mount a host directory owned by uid 1000. DuckDB reports the unprepared case as `No such file or directory` (for example `Failed to create directory "/data/lake/main/daily_orders"`), not as `EACCES`. The one-time chown names the mount path twice, as the mount target and as chown's argument:
89
103
 
90
104
  ```bash
91
105
  docker run --rm --user 0 --entrypoint chown \
@@ -110,8 +124,35 @@ What you mount has to be writable by uid 1000 too:
110
124
 
111
125
  `docker volume ls` shows the volume's full name if you would rather use the `docker run` form.
112
126
 
113
- - **A bind mount** keeps the host directory's ownership. On Linux, `chown -R 1000:1000` the host directory. Docker Desktop on macOS and Windows maps ownership for you. Running the container as some other uid to match the host is not a substitute: `/home/bun` is private to uid 1000, so that uid cannot read the baked DuckDB extensions.
114
- - **A read-only mount**, such as the config file, only needs to be readable.
127
+ - **A bind mount** keeps the host directory's ownership. On Linux, `sudo chown -R 1000:1000` the host directory, or keep it yours and grant uid 1000 through a POSIX ACL, which also covers files created later and, unlike `chown`, needs no `sudo` on a directory you own:
128
+
129
+ ```bash
130
+ setfacl -R -m u:1000:rwX -m d:u:1000:rwX <dir>
131
+ ```
132
+
133
+ Docker Desktop on macOS and Windows maps ownership for you. Running the container as some other uid to match the host is not a substitute: `/home/bun` is private to uid 1000, so that uid cannot read the baked DuckDB extensions.
134
+ - **A Kubernetes PersistentVolume** is not seeded from the image, so even a new one on `/publisher/publisher_data` starts owned by root (an `emptyDir` is world-writable and needs nothing). Set `fsGroup: 1000` in the pod's `securityContext`, which makes the volume group-writable by gid 1000, and `fsGroupChangePolicy: OnRootMismatch` so the kubelet does not re-chown a large volume on every start. `fsGroup` is also what makes a mounted Secret key file, or a projected service-account token, readable by uid 1000 where the platform mounts them `0600`.
135
+ - **A read-only mount** only needs to be readable by uid 1000. That covers the config file, a package `location`, a directory of package zips (a `.zip` location is extracted into `publisher_data/`, never beside the archive), and the key file `GOOGLE_APPLICATION_CREDENTIALS` names. A key file bound from a host path that does not exist arrives as a directory, and the server says so. The usual trap is the key file itself: a `gcloud` application-default credentials file is `0600` and owned by you, so uid 1000 cannot read it through a bind on Linux, unless your own uid is 1000 (the first user on most Ubuntu installs), in which case nothing is needed. Otherwise bind a copy it can read, or grant the group. Both need root, because only root can hand a file to another uid or to a group you are not in:
136
+
137
+ ```bash
138
+ sudo install -o 1000 -g 1000 -m 0400 ~/.config/gcloud/application_default_credentials.json ./secrets/key.json
139
+ # or, keeping the original in place:
140
+ sudo chgrp 1000 key.json && chmod 0640 key.json
141
+ ```
142
+
143
+ For a directory you own, `chmod -R o+rX <dir>` needs no root; the `chgrp 1000` / `g+rX` equivalent does.
144
+ - **Ownership is right and the server still reports `EACCES`:** on SELinux hosts (Fedora, RHEL) a bind mount needs the `:z` (shared) or `:Z` (private) option, or every access is refused whatever the owner. Under rootless Docker, Podman, or `userns-remap`, uid 1000 in the container is a subordinate uid on the host, so a host `chown 1000` names the wrong owner; use `podman unshare chown -R 1000:1000 <dir>`, or the remapped uid.
145
+
146
+ To check a mount before starting the server, run the probe as the image's user:
147
+
148
+ ```bash
149
+ docker run --rm --entrypoint sh -v <mount> ms2data/malloy-publisher \
150
+ -c 'id; touch <path>/.probe && rm <path>/.probe && echo writable'
151
+ ```
152
+
153
+ For a read-only mount, the same with `cat <file> >/dev/null && echo readable`.
154
+
155
+ When the server cannot make a write it needs, the response names the errno (`EACCES: permission denied, mkdir '…'`) rather than answering a bare `Internal server error.`. A package that cannot be mounted at boot, or added at runtime, is listed under `loadErrors` in `GET /api/v0/status` with that message, until it is added successfully or deleted. If the server cannot start at all, for example on a read-only root filesystem or with a config file it cannot read, `/api/v0/status` stays `initializing` and `initError` says why.
115
156
 
116
157
  If you cannot change the ownership yet, `--user 0` runs the server as root, as earlier images did. The image sets `HOME=/home/bun`, so a root run still finds the baked DuckDB extensions.
117
158
 
@@ -7,7 +7,7 @@ info:
7
7
  description: |
8
8
  The Malloy Publisher - Semantic Model Serving API provides access to Malloy packages and everything they contain.
9
9
  A Malloy package is a directory with a `publisher.json` manifest at its root, holding Malloy models (`.malloy` files),
10
- notebooks (`.malloynb` files and `.malloy` files under `notebooks/`), embedded data (`.parquet`, `.csv`, and `.xlsx` files), and optionally an HTML data app
10
+ notebooks (`.malloynb` files and tagged `.malloy` files that are notebooks), embedded data (`.parquet`, `.csv`, and `.xlsx` files), and optionally an HTML data app
11
11
  under `public/`.
12
12
 
13
13
  ## Key Features
@@ -1574,8 +1574,9 @@ paths:
1574
1574
  On a package with a surface (a root `index.malloy`, or a legacy `explores`), only the
1575
1575
  files on that surface are listed, unless `includeHiddenFilesAndSources` is true. With it, every
1576
1576
  model file is listed, and `isHidden` marks the ones the package hides. Dashboard files
1577
- are listed by the dashboards route either way. Served notebooks (`.malloy` files under
1578
- `notebooks/` that carry an `## artifact` note) are not models here, with or without a
1577
+ are listed by the dashboards route either way. Served notebooks (a `.malloy` at the top of
1578
+ `notebooks/` or `dashboards/` whose model-level `## artifact` tag says `kind=notebook`, or
1579
+ names no `kind` and sits under `notebooks/`) are not models here, with or without a
1579
1580
  surface; they are listed by list-notebooks.
1580
1581
  parameters:
1581
1582
  - name: environmentName
@@ -1631,14 +1632,15 @@ paths:
1631
1632
  On a package with a surface (a root `index.malloy`, or a legacy `explores`), a file off
1632
1633
  that surface answers 404 with the same message a query to it gets, unless
1633
1634
  `includeHiddenFilesAndSources` is true. With it, the file is returned with its `sourceText`, whatever
1634
- sources the text names. Dashboard files and served notebooks (`notebooks/*.malloy` with
1635
- an `## artifact` note) are always returned. A package with no surface, or with
1635
+ sources the text names. Dashboard files and served notebooks (a `.malloy` at the top of
1636
+ `notebooks/` or `dashboards/` whose model-level `## artifact` tag says `kind=notebook`, or
1637
+ names no `kind` and sits under `notebooks/`) are always returned. A package with no surface, or with
1636
1638
  `queryableSources: "all"`, returns every file. For a file it returns, `modelDef.contents` and `modelDef.exports`,
1637
1639
  `modelInfo`, `sources` and `sourceInfos` are limited to the names the file publishes, so
1638
1640
  the surface file does not carry the hidden sources it imports. A join to a hidden source
1639
1641
  keeps only its name and the names and types of its fields. `sourceText` is left out
1640
- when the text names a source the file does not publish; the text of a dashboard is
1641
- always returned.
1642
+ when the text names a source the file does not publish, unless
1643
+ `includeHiddenFilesAndSources` is true; the text of a dashboard is always returned.
1642
1644
  parameters:
1643
1645
  - name: environmentName
1644
1646
  in: path
@@ -1686,12 +1688,15 @@ paths:
1686
1688
  tags:
1687
1689
  - models
1688
1690
  operationId: update-model-source
1689
- summary: Write a dashboard file into the package
1691
+ summary: Write a dashboard or notebook file into the package
1690
1692
  description: |
1691
- Writes the Malloy text of a dashboard file — `dashboards/<slug>.malloy`,
1692
- the only paths this endpoint accepts — into the package, and reloads the
1693
- package in place so the dashboard is served from the new text. This is
1694
- the dashboard builder's save.
1693
+ Writes the Malloy text of a dashboard file — `dashboards/<slug>.malloy` —
1694
+ or a notebook file — `notebooks/<slug>.malloy`, which must carry an
1695
+ `## artifact` tag (an untagged file there is a shared include and is
1696
+ refused with 400, and so is a write over an existing file that is
1697
+ not a notebook) — the only paths this endpoint accepts,
1698
+ into the package, and reloads the package in place so it is served from
1699
+ the new text. This is the dashboard and notebook builder's save.
1695
1700
 
1696
1701
  The text is compiled first, as the file, and refused with its problems
1697
1702
  when it does not compile; nothing is written. The write is atomic (a
@@ -1700,16 +1705,30 @@ paths:
1700
1705
  a new file removed) and the package reloaded again, so a save never
1701
1706
  leaves the package serving less than it did.
1702
1707
 
1703
- `expectedHash` is the SHA-256 (hex) of the text the caller opened, as
1704
- `GET …/models/{path}` returned it in `sourceText`. When the file on disk
1705
- no longer hashes to it, the write is refused with 409 and nothing is
1708
+ `expectedHash` is the SHA-256 (hex) of the file's text as the caller
1709
+ opened it, as `GET …/models/{path}` returned it in `sourceText`. On a
1710
+ package with a surface, that GET withholds `sourceText` only when the
1711
+ text names a source the file does not publish, and returns it anyway
1712
+ with `includeHiddenFilesAndSources=true`. When the file on disk no
1713
+ longer hashes to it, the write is refused with 409 and nothing is
1706
1714
  merged: the caller re-opens and reapplies its change. Omit it to CREATE
1707
- the file: a file that already exists is then refused with 409 too, so an
1708
- unconditional overwrite is not something a caller can ask for by leaving
1709
- a field out. The check, the write, the reload and the restore all happen
1710
- under one hold of the package lock, so two saves racing on one file
1711
- cannot both pass the check, and a rollback cannot revert the other
1712
- writer's text instead of its own.
1715
+ the file: a file that already exists is then refused with 409 too, so
1716
+ an unconditional overwrite is not something a caller can ask for by
1717
+ leaving a field out. A notebook path over an existing file the package
1718
+ does not serve as a notebook answers 400 instead, with or without a
1719
+ hash, because that check comes before the hash. The check, the write,
1720
+ the reload and the restore all happen under one hold of the package
1721
+ lock, so two saves racing on one file cannot both pass the check, and a
1722
+ rollback cannot revert the other writer's text instead of its own.
1723
+
1724
+ A dashboard whose name (the file's basename) another file already holds
1725
+ is refused with 409 before anything is written, since the name is its
1726
+ URL and its `# drill` target. A `dashboards/` file whose text has no
1727
+ `# artifact` or `## artifact` tag (an `artifact` property anywhere on a
1728
+ tag line, outside a string) is refused with 400 before anything is
1729
+ written; a tag only inside a block comment passes that check but the
1730
+ compiled model carries none, so it is rolled back and answers 500. A
1731
+ tagged dashboard with no tiles saves but is not served until it has one.
1713
1732
 
1714
1733
  A create answers 201 and an update 200; `created` in the body says the
1715
1734
  same thing.
@@ -1732,7 +1751,7 @@ paths:
1732
1751
  type: string
1733
1752
  - name: path
1734
1753
  in: path
1735
- description: The dashboard file, `dashboards/<slug>.malloy`
1754
+ description: The file, `dashboards/<slug>.malloy` or `notebooks/<slug>.malloy`
1736
1755
  required: true
1737
1756
  schema:
1738
1757
  $ref: "#/components/schemas/PathPattern"
@@ -1771,8 +1790,9 @@ paths:
1771
1790
  $ref: "#/components/responses/NotFound"
1772
1791
  "409":
1773
1792
  description:
1774
- The file changed since the caller opened it, or already exists and
1775
- no `expectedHash` was sent
1793
+ The file changed since the caller opened it, already exists and
1794
+ no `expectedHash` was sent, or is a dashboard whose name another
1795
+ file already holds
1776
1796
  content:
1777
1797
  application/json:
1778
1798
  schema:
@@ -1918,10 +1938,12 @@ paths:
1918
1938
  operationId: list-dashboards
1919
1939
  summary: List package dashboards
1920
1940
  description: |
1921
- Lists the dashboards in the specified package — every `.malloy` file in
1922
- the package's `dashboards/` directory that carries an `# artifact` (or
1923
- model-level `## artifact`) annotation. A file in that directory with no
1924
- artifact tag is a shared include and is not listed, whether or not it
1941
+ Lists the dashboards in the specified package — every tagged `.malloy`
1942
+ file at the top of `dashboards/` or `notebooks/` carrying an
1943
+ `# artifact` (or model-level `## artifact`) annotation whose `kind` is
1944
+ `dashboard`, or names none under `dashboards/`. A `kind=notebook` file is
1945
+ listed as a notebook instead, whichever folder it sits in. A file with
1946
+ no artifact tag is a shared include and is not listed, whether or not it
1925
1947
  compiles.
1926
1948
 
1927
1949
  A tagged dashboard that failed to compile is listed carrying its
@@ -2055,8 +2077,9 @@ paths:
2055
2077
  summary: List package notebooks
2056
2078
  description: |
2057
2079
  Retrieves a list of all Malloy notebooks within the specified package: every
2058
- `.malloynb` file, and every `.malloy` file directly under `notebooks/` that has a
2059
- model-level `## artifact` note. Each notebook entry includes the relative path,
2080
+ `.malloynb` file, and every `.malloy` file at the top of `notebooks/` or `dashboards/`
2081
+ whose model-level `## artifact` tag says `kind=notebook` (or names no `kind` and sits
2082
+ under `notebooks/`). Each notebook entry includes the relative path,
2060
2083
  package name, title, description, and any compilation or reading error. This endpoint
2061
2084
  is useful for discovering available notebooks and checking their status.
2062
2085
  parameters:
@@ -2107,8 +2130,9 @@ paths:
2107
2130
  description: |
2108
2131
  Retrieves a Malloy notebook with its raw cell contents (markdown and code).
2109
2132
  Cell execution should be done separately via the execute-notebook-cell endpoint.
2110
- A served `notebooks/*.malloy` (one with an `## artifact` note) answers here as well as a
2111
- `.malloynb`.
2133
+ A served notebook (a `.malloy` at the top of `notebooks/` or `dashboards/` whose
2134
+ model-level `## artifact` tag says `kind=notebook`, or names no `kind` and sits under
2135
+ `notebooks/`) answers here as well as a `.malloynb`.
2112
2136
  On a package with a surface, the response shows only the sources the notebook may read.
2113
2137
  parameters:
2114
2138
  - name: environmentName
@@ -2160,8 +2184,9 @@ paths:
2160
2184
  description: |
2161
2185
  Executes a specific cell in a Malloy notebook by index. For code cells, this compiles
2162
2186
  and runs the Malloy code, returning query results and any new sources defined.
2163
- For markdown cells, this simply returns the cell content. A served `notebooks/*.malloy`
2164
- answers here as well as a `.malloynb`.
2187
+ For markdown cells, this simply returns the cell content. A served notebook
2188
+ (tagged `kind=notebook`, or untagged-kind under `notebooks/`) answers here as well as a
2189
+ `.malloynb`.
2165
2190
 
2166
2191
  On a package with a surface (a root `index.malloy`, or a legacy `explores`) with
2167
2192
  `queryableSources` left at `"declared"`, a code cell may read only sources the surface
@@ -2876,11 +2901,27 @@ components:
2876
2901
  environments list as intended. Absent once any environment exists, including one created
2877
2902
  at runtime through the API, and absent when a config was found but
2878
2903
  lists no environments.
2904
+ initError:
2905
+ type: string
2906
+ readOnly: true
2907
+ description:
2908
+ Present only when initialization failed, and says why. Such a
2909
+ server stays up but never becomes ready, so operationalState stays
2910
+ initializing; without this field that reads as a server still
2911
+ starting. Typical causes are a config file the server cannot read
2912
+ or parse, and a server root it cannot write (where it creates
2913
+ publisher.db), such as a read-only root filesystem. A package or
2914
+ environment that fails to load is reported under loadErrors
2915
+ instead. Fix the cause and restart.
2879
2916
  loadErrors:
2880
2917
  type: array
2881
2918
  readOnly: true
2882
2919
  description:
2883
- Configured packages and environments that did not load, and why. A
2920
+ Configured packages and environments that did not load, and why,
2921
+ including a package add through the API that failed on the
2922
+ server's side, carrying the same message the add was answered
2923
+ with (an entry cleared by a later successful add of that package,
2924
+ or by deleting it). A
2884
2925
  load failure is not fatal to the server, so operationalState stays
2885
2926
  serving and the affected packages are absent from environments,
2886
2927
  unless the entry carries stale = true, in which case the package is
@@ -3865,8 +3906,8 @@ components:
3865
3906
  Dashboard:
3866
3907
  type: object
3867
3908
  description: |
3868
- A dashboard within a Malloy package: a self-contained `.malloy` file in
3869
- the package's `dashboards/` directory carrying an `# artifact` (or
3909
+ A dashboard within a Malloy package: a self-contained `.malloy` file at
3910
+ the top of the package's `dashboards/` or `notebooks/` directory carrying an `# artifact` (or
3870
3911
  model-level `## artifact`) annotation. The list entry; see
3871
3912
  DashboardManifest for the detail a viewer needs to render one.
3872
3913
  properties:
@@ -3944,6 +3985,16 @@ components:
3944
3985
  error:
3945
3986
  type: string
3946
3987
  description: Error message if the dashboard file failed to compile
3988
+ kind:
3989
+ type: string
3990
+ enum: [dashboard, notebook]
3991
+ description: >-
3992
+ What the document is, from the `kind` property of its artifact tag
3993
+ (the folder only decides the default when the tag says nothing). A
3994
+ `notebook` is laid out as one column: `dashboardColumns` is 1
3995
+ whatever the file says. Always `dashboard` on
3996
+ `GET …/dashboards/{dashboardName}`; a notebook's manifest is the
3997
+ `dashboard` field of `GET …/notebooks/{path}`.
3947
3998
  query:
3948
3999
  type: string
3949
4000
  description: >-
@@ -3985,7 +4036,8 @@ components:
3985
4036
  type: array
3986
4037
  description: |
3987
4038
  The control row. Normally one entry per given the dashboard runs
3988
- with: the union over `tiles`, or what `query` references when the tag
4039
+ with: the union over `tiles` (less a given only a source's gate
4040
+ reads, which a host injects rather than a viewer sets), or what `query` references when the tag
3989
4041
  sits on a query, and which the entry file
3990
4042
  can bind. The row widens to
3991
4043
  every given the entry file surfaces when any tile is one discovery
@@ -4015,12 +4067,32 @@ components:
4015
4067
 
4016
4068
  DashboardTile:
4017
4069
  type: object
4018
- description: One tile of a dashboard
4070
+ description: >-
4071
+ One tile of a dashboard. A `query` tile (the default) runs a query; a
4072
+ `text` tile shows markdown and runs nothing, so a caller that runs a
4073
+ dashboard's tiles skips the ones with `kind` `text`.
4019
4074
  properties:
4075
+ kind:
4076
+ type: string
4077
+ enum: [query, text]
4078
+ description: >-
4079
+ `query` runs `query` through the model query endpoint; `text` shows
4080
+ `markdown`. Absent means `query`.
4081
+ name:
4082
+ type: string
4083
+ description: >-
4084
+ A text tile's name: the bare word in `tiles=[…]` and on its
4085
+ `##|(markdown) name` block. Absent on a query tile.
4086
+ markdown:
4087
+ type: string
4088
+ description: >-
4089
+ A text tile's body, the text of its `##|(markdown) name` block
4090
+ without the opener. Empty when the file has no such block. Absent on
4091
+ a query tile.
4020
4092
  query:
4021
4093
  type: string
4022
4094
  description: >-
4023
- The run expression exactly as written in `tiles=[…]`, for example
4095
+ Absent on a text tile. The run expression exactly as written in `tiles=[…]`, for example
4024
4096
  "orders -> by_month". An EXPRESSION rather than a name, so it goes in
4025
4097
  the `query` field of a `POST …/models/{path}/query` body, prefixed
4026
4098
  with `run:`. Sending it in `queryName`, the field
@@ -4030,13 +4102,17 @@ components:
4030
4102
  items:
4031
4103
  type: string
4032
4104
  description: |
4033
- Names of the givens this tile references. This is a scoping hint,
4034
- not a binding constraint: it tells a caller which tiles a changed
4035
- control actually needs to re-run. Running a tile with the
4036
- dashboard's whole control row also works, because an unreferenced
4037
- given is ignored. Absent when the tile expression is not one
4038
- discovery can resolve, a refinement or a multi-stage pipeline for
4039
- instance, in which case send the whole control row. One such tile
4105
+ Names of the givens this tile's compiled query reads: through its
4106
+ view, its source's `where:`, a joined source's `where:`, a
4107
+ dimension or measure it uses, and its source's `#(authorize)` and
4108
+ `#(access_filter)` gates. A control not listed does not change the
4109
+ tile, which is what a viewer's "Doesn't respond to" chip says. It
4110
+ also tells a caller which tiles a changed control needs to re-run;
4111
+ running a tile with the dashboard's whole control row also works,
4112
+ because an unreferenced given is ignored. Absent when discovery
4113
+ could not resolve the tile (its expression neither compiles nor is
4114
+ a plain `source -> view` or named query the static walk reads), in
4115
+ which case send the whole control row. One such tile
4040
4116
  widens `DashboardManifest.givens` to every given the entry file
4041
4117
  surfaces, rather than the union over the resolvable tiles, so that
4042
4118
  the row actually contains the givens that tile filters by.
@@ -4055,13 +4131,15 @@ components:
4055
4131
  type: integer
4056
4132
  description: >-
4057
4133
  Grid columns this tile spans, from a `# colspan=N` on the view or
4058
- query it names. Clamped to `dashboardColumns` at render time. Absent
4134
+ query it names, or from `colspan=N` on a text tile's entry in
4135
+ `tiles=[…]`. Clamped to `dashboardColumns` at render time. Absent
4059
4136
  means one column.
4060
4137
  break:
4061
4138
  type: boolean
4062
4139
  description: >-
4063
4140
  Start a new grid row at this tile, from a `# break` on the view or
4064
- query it names. Named for the tag, so every per-tile field on this
4141
+ query it names, or from `break` on a text tile's entry in
4142
+ `tiles=[…]`. Named for the tag, so every per-tile field on this
4065
4143
  schema is spelled the way an author writes it. A generated client
4066
4144
  escapes the attribute where the word is reserved (the Python client
4067
4145
  exposes `break_`) while the wire key stays `break`.
@@ -4127,8 +4205,9 @@ components:
4127
4205
  enum: ["malloynb", "malloy"]
4128
4206
  description:
4129
4207
  The file format the notebook is written in. `malloynb` is the
4130
- cell-separated format; `malloy` is a `.malloy` file under
4131
- `notebooks/` with a model-level `## artifact` note, whose cells are
4208
+ cell-separated format; `malloy` is a `.malloy` at the top of `notebooks/` or
4209
+ `dashboards/` whose model-level `## artifact` tag says `kind=notebook` (or names no
4210
+ `kind` and sits under `notebooks/`), whose cells are
4132
4211
  its statements and its floating `(markdown)` notes in file order.
4133
4212
  malloyVersion:
4134
4213
  type: string
@@ -4141,6 +4220,16 @@ components:
4141
4220
  description: Array of notebook cells containing raw markdown and code content
4142
4221
  items:
4143
4222
  $ref: "#/components/schemas/NotebookCell"
4223
+ dashboard:
4224
+ allOf:
4225
+ - $ref: "#/components/schemas/DashboardManifest"
4226
+ description: >-
4227
+ The tile layout of a notebook written as one (`## artifact {
4228
+ kind=notebook tiles=[…] }`), in the shape a dashboard has, with
4229
+ `kind` `notebook` and one column. Absent on a notebook written as
4230
+ cells. Its tiles run through the model query endpoint at
4231
+ `modelPath`; `notebookCells` carries the same content as cells for
4232
+ readers that do not draw a layout.
4144
4233
  annotations:
4145
4234
  type: array
4146
4235
  description:
@@ -4233,7 +4322,8 @@ components:
4233
4322
  server-side warning) when the file cannot be read, so a compiled
4234
4323
  model is never withheld for want of its text; and omitted when the
4235
4324
  file text names a source it does not publish, on a package with a
4236
- surface. A dashboard's text is always returned.
4325
+ surface, unless `includeHiddenFilesAndSources` is true. A
4326
+ dashboard's text is always returned.
4237
4327
 
4238
4328
  View:
4239
4329
  type: object
@@ -5982,7 +6072,7 @@ components:
5982
6072
 
5983
6073
  ModelSourceWriteRequest:
5984
6074
  type: object
5985
- description: The text to write into a dashboard file
6075
+ description: The text to write into a dashboard or notebook file
5986
6076
  required:
5987
6077
  - source
5988
6078
  properties:
@@ -5998,7 +6088,7 @@ components:
5998
6088
 
5999
6089
  ModelSourceWriteResult:
6000
6090
  type: object
6001
- description: What a dashboard write left in the package
6091
+ description: What a dashboard or notebook write left in the package
6002
6092
  required:
6003
6093
  - path
6004
6094
  - contentHash
@@ -0,0 +1 @@
1
+ import{m as r,G as t,j as e,a2 as i,ak as o}from"./index-CGdwupPP.js";function c(){const s=r(),{environmentName:n}=t();if(n){const a=i({environmentName:n});return e.jsx(o,{onSelectPackage:s,resourceUri:a})}else return e.jsx("div",{children:e.jsx("h2",{children:"Missing environment name"})})}export{c as default};
@@ -1 +1 @@
1
- import{f as t,j as o,M as a}from"./index-TiWjmdoW.js";function s(){const n=t();return o.jsx(a,{onClickEnvironment:n})}export{s as default};
1
+ import{m as t,j as o,D as a}from"./index-CGdwupPP.js";function s(){const n=t();return o.jsx(a,{onClickEnvironment:n})}export{s as default};
@@ -1 +1 @@
1
- import{c,j as s}from"./index-TiWjmdoW.js";const t=c(s.jsx("path",{d:"M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9c0-.46-.04-.92-.1-1.36-.98 1.37-2.58 2.26-4.4 2.26-2.98 0-5.4-2.42-5.4-5.4 0-1.81.89-3.42 2.26-4.4-.44-.06-.9-.1-1.36-.1"})),a=c(s.jsx("path",{d:"M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5M2 13h2c.55 0 1-.45 1-1s-.45-1-1-1H2c-.55 0-1 .45-1 1s.45 1 1 1m18 0h2c.55 0 1-.45 1-1s-.45-1-1-1h-2c-.55 0-1 .45-1 1s.45 1 1 1M11 2v2c0 .55.45 1 1 1s1-.45 1-1V2c0-.55-.45-1-1-1s-1 .45-1 1m0 18v2c0 .55.45 1 1 1s1-.45 1-1v-2c0-.55-.45-1-1-1s-1 .45-1 1M5.99 4.58c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41zm12.37 12.37c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0 .39-.39.39-1.03 0-1.41zm1.06-10.96c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0zM7.05 18.36c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0z"}));export{t as D,a as L};
1
+ import{c,j as s}from"./index-CGdwupPP.js";const t=c(s.jsx("path",{d:"M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9c0-.46-.04-.92-.1-1.36-.98 1.37-2.58 2.26-4.4 2.26-2.98 0-5.4-2.42-5.4-5.4 0-1.81.89-3.42 2.26-4.4-.44-.06-.9-.1-1.36-.1"})),a=c(s.jsx("path",{d:"M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5M2 13h2c.55 0 1-.45 1-1s-.45-1-1-1H2c-.55 0-1 .45-1 1s.45 1 1 1m18 0h2c.55 0 1-.45 1-1s-.45-1-1-1h-2c-.55 0-1 .45-1 1s.45 1 1 1M11 2v2c0 .55.45 1 1 1s1-.45 1-1V2c0-.55-.45-1-1-1s-1 .45-1 1m0 18v2c0 .55.45 1 1 1s1-.45 1-1v-2c0-.55-.45-1-1-1s-1 .45-1 1M5.99 4.58c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41zm12.37 12.37c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0 .39-.39.39-1.03 0-1.41zm1.06-10.96c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0zM7.05 18.36c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0z"}));export{t as D,a as L};
@@ -0,0 +1 @@
1
+ import{c as S,j as t,s as E,B as Se,a as Q,e as ne,g as le,b as ce,r as d,u as de,d as Ce,f as F,h as pe,T as K,i as G,k as Pe,l as ze,n as Ee,o as ue,p as Ie,q as Me,t as oe,v as De,w as Te,x as W,y as $,M as Be,P as Re,z as Le,S as He,A as $e,C as A,I as N,E as Ne,F as he,G as xe,m as J,H as h,J as Ae,L as Z,O as Oe,K as We,N as se,Q as fe,R as me,U as ge,V as Ve,W as Fe,X as Ue,Y as Xe}from"./index-CGdwupPP.js";import{D as Ye,L as _e}from"./LightMode-DOBl6awB.js";const qe=S(t.jsx("path",{d:"M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"})),Qe=E(Se,{name:"MuiBreadcrumbCollapsed"})(Q(({theme:e})=>({display:"flex",marginLeft:`calc(${e.spacing(1)} * 0.5)`,marginRight:`calc(${e.spacing(1)} * 0.5)`,...e.palette.mode==="light"?{backgroundColor:e.palette.grey[100],color:e.palette.grey[700]}:{backgroundColor:e.palette.grey[700],color:e.palette.grey[100]},borderRadius:2,"&:hover, &:focus":{...e.palette.mode==="light"?{backgroundColor:e.palette.grey[200]}:{backgroundColor:e.palette.grey[600]}},"&:active":{boxShadow:e.shadows[0],...e.palette.mode==="light"?{backgroundColor:ne(e.palette.grey[200],.12)}:{backgroundColor:ne(e.palette.grey[600],.12)}}}))),Ke=E(qe)({width:24,height:16});function Ge(e){const{slots:r={},slotProps:n={},...o}=e,s=e;return t.jsx("li",{children:t.jsx(Qe,{focusRipple:!0,...o,ownerState:s,children:t.jsx(Ke,{as:r.CollapsedIcon,ownerState:s,...n.collapsedIcon})})})}function Je(e){return le("MuiBreadcrumbs",e)}const Ze=ce("MuiBreadcrumbs",["root","ol","li","separator"]),et=e=>{const{classes:r}=e;return pe({root:["root"],li:["li"],ol:["ol"],separator:["separator"]},Je,r)},tt=E(K,{name:"MuiBreadcrumbs",slot:"Root",overridesResolver:(e,r)=>[{[`& .${Ze.li}`]:r.li},r.root]})({}),rt=E("ol",{name:"MuiBreadcrumbs",slot:"Ol"})({display:"flex",flexWrap:"wrap",alignItems:"center",padding:0,margin:0,listStyle:"none"}),nt=E("li",{name:"MuiBreadcrumbs",slot:"Separator"})({display:"flex",userSelect:"none",marginLeft:8,marginRight:8});function ot(e,r,n,o){return e.reduce((s,c,i)=>(i<e.length-1?s=s.concat(c,t.jsx(nt,{"aria-hidden":!0,className:r,ownerState:o,children:n},`separator-${i}`)):s.push(c),s),[])}const st=d.forwardRef(function(r,n){const o=de({props:r,name:"MuiBreadcrumbs"}),{children:s,className:c,component:i="nav",slots:p={},slotProps:m={},expandText:u="Show path",itemsAfterCollapse:f=1,itemsBeforeCollapse:v=1,maxItems:g=8,separator:I="/",...H}=o,[M,C]=d.useState(!1),b={...o,component:i,expanded:M,expandText:u,itemsAfterCollapse:f,itemsBeforeCollapse:v,maxItems:g,separator:I},P=et(b),D=Ce({elementType:p.CollapsedIcon,externalSlotProps:m.collapsedIcon,ownerState:b}),j=d.useRef(null),k=l=>{const w=()=>{C(!0);const y=j.current.querySelector("a[href],button,[tabindex]");y&&y.focus()};return v+f>=l.length?l:[...l.slice(0,v),t.jsx(Ge,{"aria-label":u,slots:{CollapsedIcon:p.CollapsedIcon},slotProps:{collapsedIcon:D},onClick:w},"ellipsis"),...l.slice(l.length-f,l.length)]},T=d.Children.toArray(s).filter(l=>d.isValidElement(l)).map((l,w)=>t.jsx("li",{className:P.li,children:l},`child-${w}`));return t.jsx(tt,{ref:n,component:i,color:"textSecondary",className:F(P.root,c),ownerState:b,...H,children:t.jsx(rt,{className:P.ol,ref:j,ownerState:b,children:ot(M||g&&T.length<=g?T:k(T),P.separator,I,b)})})});function at(e,r,n){const o=r.getBoundingClientRect(),s=n&&n.getBoundingClientRect(),c=ue(r);let i;if(r.fakeTransform)i=r.fakeTransform;else{const u=c.getComputedStyle(r);i=u.getPropertyValue("-webkit-transform")||u.getPropertyValue("transform")}let p=0,m=0;if(i&&i!=="none"&&typeof i=="string"){const u=i.split("(")[1].split(")")[0].split(",");p=parseInt(u[4],10),m=parseInt(u[5],10)}return e==="left"?s?`translateX(${s.right+p-o.left}px)`:`translateX(${c.innerWidth+p-o.left}px)`:e==="right"?s?`translateX(-${o.right-s.left-p}px)`:`translateX(-${o.left+o.width-p}px)`:e==="up"?s?`translateY(${s.bottom+m-o.top}px)`:`translateY(${c.innerHeight+m-o.top}px)`:s?`translateY(-${o.top-s.top+o.height-m}px)`:`translateY(-${o.top+o.height-m}px)`}function it(e){return typeof e=="function"?e():e}function V(e,r,n){const o=it(n),s=at(e,r,o);s&&(r.style.webkitTransform=s,r.style.transform=s)}const lt=d.forwardRef(function(r,n){const o=G(),s={enter:o.transitions.easing.easeOut,exit:o.transitions.easing.sharp},c={enter:o.transitions.duration.enteringScreen,exit:o.transitions.duration.leavingScreen},{addEndListener:i,appear:p=!0,children:m,container:u,direction:f="down",easing:v=s,in:g,onEnter:I,onEntered:H,onEntering:M,onExit:C,onExited:b,onExiting:P,style:D,timeout:j=c,TransitionComponent:k=Pe,...T}=r,l=d.useRef(null),w=ze(Ee(m),l,n),y=a=>x=>{a&&(x===void 0?a(l.current):a(l.current,x))},U=y((a,x)=>{V(f,a,u),Me(a),I&&I(a,x)}),ee=y((a,x)=>{const L=oe({timeout:j,style:D,easing:v},{mode:"enter"});a.style.webkitTransition=o.transitions.create("-webkit-transform",{...L}),a.style.transition=o.transitions.create("transform",{...L}),a.style.webkitTransform="none",a.style.transform="none",M&&M(a,x)}),B=y(H),R=y(P),z=y(a=>{const x=oe({timeout:j,style:D,easing:v},{mode:"exit"});a.style.webkitTransition=o.transitions.create("-webkit-transform",x),a.style.transition=o.transitions.create("transform",x),V(f,a,u),C&&C(a)}),X=y(a=>{a.style.webkitTransition="",a.style.transition="",b&&b(a)}),Y=a=>{i&&i(l.current,a)},O=d.useCallback(()=>{l.current&&V(f,l.current,u)},[f,u]);return d.useEffect(()=>{if(g||f==="down"||f==="right")return;const a=Ie(()=>{l.current&&V(f,l.current,u)}),x=ue(l.current);return x.addEventListener("resize",a),()=>{a.clear(),x.removeEventListener("resize",a)}},[f,g,u]),d.useEffect(()=>{g||O()},[g,O]),t.jsx(k,{nodeRef:l,onEnter:U,onEntered:B,onEntering:ee,onExit:z,onExited:X,onExiting:R,addEndListener:Y,appear:p,in:g,timeout:j,...T,children:(a,{ownerState:x,...L})=>d.cloneElement(m,{ref:w,style:{visibility:a==="exited"&&!g?"hidden":void 0,...D,...m.props.style},...L})})});function ct(e){return le("MuiDrawer",e)}ce("MuiDrawer",["root","docked","paper","anchorLeft","anchorRight","anchorTop","anchorBottom","paperAnchorLeft","paperAnchorRight","paperAnchorTop","paperAnchorBottom","paperAnchorDockedLeft","paperAnchorDockedRight","paperAnchorDockedTop","paperAnchorDockedBottom","modal"]);const ye=(e,r)=>{const{ownerState:n}=e;return[r.root,(n.variant==="permanent"||n.variant==="persistent")&&r.docked,r.modal]},dt=e=>{const{classes:r,anchor:n,variant:o}=e,s={root:["root",`anchor${$(n)}`],docked:[(o==="permanent"||o==="persistent")&&"docked"],modal:["modal"],paper:["paper",`paperAnchor${$(n)}`,o!=="temporary"&&`paperAnchorDocked${$(n)}`]};return pe(s,ct,r)},pt=E(Be,{name:"MuiDrawer",slot:"Root",overridesResolver:ye})(Q(({theme:e})=>({zIndex:(e.vars||e).zIndex.drawer}))),ut=E("div",{shouldForwardProp:Le,name:"MuiDrawer",slot:"Docked",skipVariantsResolver:!1,overridesResolver:ye})({flex:"0 0 auto"}),ht=E(Re,{name:"MuiDrawer",slot:"Paper",overridesResolver:(e,r)=>{const{ownerState:n}=e;return[r.paper,r[`paperAnchor${$(n.anchor)}`],n.variant!=="temporary"&&r[`paperAnchorDocked${$(n.anchor)}`]]}})(Q(({theme:e})=>({overflowY:"auto",display:"flex",flexDirection:"column",height:"100%",flex:"1 0 auto",zIndex:(e.vars||e).zIndex.drawer,WebkitOverflowScrolling:"touch",position:"fixed",top:0,outline:0,variants:[{props:{anchor:"left"},style:{left:0}},{props:{anchor:"top"},style:{top:0,left:0,right:0,height:"auto",maxHeight:"100%"}},{props:{anchor:"right"},style:{right:0}},{props:{anchor:"bottom"},style:{top:"auto",left:0,bottom:0,right:0,height:"auto",maxHeight:"100%"}},{props:({ownerState:r})=>r.anchor==="left"&&r.variant!=="temporary",style:{borderRight:`1px solid ${(e.vars||e).palette.divider}`}},{props:({ownerState:r})=>r.anchor==="top"&&r.variant!=="temporary",style:{borderBottom:`1px solid ${(e.vars||e).palette.divider}`}},{props:({ownerState:r})=>r.anchor==="right"&&r.variant!=="temporary",style:{borderLeft:`1px solid ${(e.vars||e).palette.divider}`}},{props:({ownerState:r})=>r.anchor==="bottom"&&r.variant!=="temporary",style:{borderTop:`1px solid ${(e.vars||e).palette.divider}`}}]}))),be={left:"right",right:"left",top:"down",bottom:"up"};function xt(e){return["left","right"].includes(e)}function ft({direction:e},r){return e==="rtl"&&xt(r)?be[r]:r}const mt=d.forwardRef(function(r,n){const o=de({props:r,name:"MuiDrawer"}),s=G(),c=De(),i={enter:s.transitions.duration.enteringScreen,exit:s.transitions.duration.leavingScreen},{anchor:p="left",BackdropProps:m,children:u,className:f,elevation:v=16,hideBackdrop:g=!1,ModalProps:{BackdropProps:I,...H}={},onClose:M,open:C=!1,PaperProps:b={},SlideProps:P,TransitionComponent:D,transitionDuration:j=i,variant:k="temporary",slots:T={},slotProps:l={},...w}=o,y=d.useRef(!1);d.useEffect(()=>{y.current=!0},[]);const U=ft({direction:c?"rtl":"ltr"},p),B={...o,anchor:p,elevation:v,open:C,variant:k,...w},R=dt(B),z={slots:{transition:D,...T},slotProps:{paper:b,transition:P,...l,backdrop:Te(l.backdrop||{...m,...I},{transitionDuration:j})}},[X,Y]=W("root",{ref:n,elementType:pt,className:F(R.root,R.modal,f),shouldForwardComponentProp:!0,ownerState:B,externalForwardedProps:{...z,...w,...H},additionalProps:{open:C,onClose:M,hideBackdrop:g,slots:{backdrop:z.slots.backdrop},slotProps:{backdrop:z.slotProps.backdrop}}}),[O,a]=W("paper",{elementType:ht,shouldForwardComponentProp:!0,className:F(R.paper,b.className),ownerState:B,externalForwardedProps:z,additionalProps:{elevation:k==="temporary"?v:0,square:!0,...k==="temporary"&&{role:"dialog","aria-modal":"true"}}}),[x,L]=W("docked",{elementType:ut,ref:n,className:F(R.root,R.docked,f),ownerState:B,externalForwardedProps:z,additionalProps:w}),[ke,we]=W("transition",{elementType:lt,ownerState:B,externalForwardedProps:z,additionalProps:{in:C,direction:be[U],timeout:j,appear:y.current}}),te=t.jsx(O,{...a,children:u});if(k==="permanent")return t.jsx(x,{...L,children:te});const re=t.jsx(ke,{...we,children:te});return k==="persistent"?t.jsx(x,{...L,children:re}):t.jsx(X,{...Y,children:re})}),gt=S([t.jsx("path",{d:"M19 5v14H5V5zm0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2"},"0"),t.jsx("path",{d:"M14 17H7v-2h7zm3-4H7v-2h10zm0-4H7V7h10z"},"1")]),yt=S(t.jsx("path",{d:"M10.85 12.65h2.3L12 9zM20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12zM14.3 16l-.7-2h-3.2l-.7 2H7.8L11 7h2l3.2 9z"})),bt=S(t.jsx("path",{d:"M10 6 8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"})),vt=S(t.jsx("path",{d:"M9.4 16.6 4.8 12l4.6-4.6L8 6l-6 6 6 6zm5.2 0 4.6-4.6-4.6-4.6L16 6l6 6-6 6z"})),jt=S(t.jsx("path",{d:"m9.17 6 2 2H20v10H4V6zM10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8z"})),kt=S(t.jsx("path",{d:"m12 5.69 5 4.5V18h-2v-6H9v6H7v-7.81zM12 3 2 12h3v8h6v-6h2v6h6v-8h3z"})),wt=S(t.jsx("path",{d:"M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3z"})),St=S([t.jsx("path",{d:"M12 22C6.49 22 2 17.51 2 12S6.49 2 12 2s10 4.04 10 9c0 3.31-2.69 6-6 6h-1.77c-.28 0-.5.22-.5.5 0 .12.05.23.13.33.41.47.64 1.06.64 1.67 0 1.38-1.12 2.5-2.5 2.5m0-18c-4.41 0-8 3.59-8 8s3.59 8 8 8c.28 0 .5-.22.5-.5 0-.16-.08-.28-.14-.35-.41-.46-.63-1.05-.63-1.65 0-1.38 1.12-2.5 2.5-2.5H16c2.21 0 4-1.79 4-4 0-3.86-3.59-7-8-7"},"0"),t.jsx("circle",{cx:"6.5",cy:"11.5",r:"1.5"},"1"),t.jsx("circle",{cx:"9.5",cy:"7.5",r:"1.5"},"2"),t.jsx("circle",{cx:"14.5",cy:"7.5",r:"1.5"},"3"),t.jsx("circle",{cx:"17.5",cy:"11.5",r:"1.5"},"4")]);function q(e){return t.jsxs(He,{...e,viewBox:"0 0 24 24",sx:{fill:"none",...e.sx},children:[t.jsx("rect",{x:"3.25",y:"4.75",width:"17.5",height:"14.5",rx:"2.25",stroke:"currentColor",strokeWidth:"1.5"}),t.jsx("line",{x1:"8.5",y1:"5",x2:"8.5",y2:"19",stroke:"currentColor",strokeWidth:"1.5"})]})}const Ct={light:"dark",dark:"auto",auto:"light"},ae={light:"Light mode (click for dark)",dark:"Dark mode (click for auto)",auto:"Auto mode (follows OS, click for light)"};function Pt(){const{mode:e,userChoice:r,setMode:n,allowUserToggle:o}=$e();if(!o)return null;const s=r??e,c=Ct[s],i=s==="auto"?yt:s==="dark"?Ye:_e;return t.jsx(A,{title:ae[s],children:t.jsx(N,{"aria-label":ae[s],onClick:()=>n(c),size:"small",children:t.jsx(i,{fontSize:"small"})})})}const ie="Visualization theme";function zt(){const e=Ne(),n=he().pathname.startsWith("/settings/theme");return t.jsx(A,{title:ie,children:t.jsx(N,{"aria-label":ie,onClick:()=>e("/settings/theme"),size:"small",color:n?"primary":"default",children:t.jsx(St,{fontSize:"small"})})})}function _({label:e,onClick:r}){return t.jsx(Ae,{clickable:!0,onClick:r,label:e,size:"small","aria-label":`Navigate to ${e}`,sx:n=>({backgroundColor:"transparent",border:`1px solid ${n.palette.divider}`,color:"text.primary",fontWeight:500,fontSize:"0.875rem",height:32,cursor:"pointer",borderRadius:"4px",maxWidth:320,"& .MuiChip-label":{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},"&:hover":{backgroundColor:n.palette.mode==="dark"?"rgba(255, 255, 255, 0.08)":"grey.100"}})})}function Et(){const e=xe(),r=e["*"],n=J();return!e.environmentName&&!e.packageName&&!r?null:t.jsx(h,{sx:{display:"flex",alignItems:"center",minWidth:0},children:t.jsxs(st,{"aria-label":"breadcrumb",separator:t.jsx(bt,{sx:{fontSize:14,color:"text.secondary"}}),children:[e.environmentName&&t.jsx(_,{label:e.environmentName,onClick:o=>n(`/${e.environmentName}/`,o)}),e.packageName&&t.jsx(_,{label:e.packageName,onClick:o=>n(`/${e.environmentName}/${e.packageName}/`,o)}),r&&t.jsx(_,{label:r,onClick:o=>n(`/${e.environmentName}/${e.packageName}/${r}`,o)})]})})}const It=260,Mt=64;function ve({isCollapsed:e,onToggleCollapse:r,logoHeader:n}){return t.jsxs(h,{sx:{height:"100dvh",width:e?Mt:It,flexShrink:0,display:"flex",flexDirection:"column",backgroundColor:"background.paper",transition:"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)",overflow:"hidden"},children:[t.jsx(Dt,{isCollapsed:e,onToggleCollapse:r,logoHeader:n}),t.jsxs(h,{sx:{flex:1,overflowY:"auto",overflowX:"hidden",py:1},children:[t.jsx(Tt,{isCollapsed:e}),t.jsx(Bt,{isCollapsed:e})]}),t.jsx(Rt,{isCollapsed:e})]})}function Dt({isCollapsed:e,onToggleCollapse:r,logoHeader:n}){const o=J();return n?t.jsxs(h,{sx:{height:56,display:"flex",alignItems:"center",justifyContent:"space-between",px:e?0:2,flexShrink:0},children:[n,t.jsx(N,{size:"small",onClick:r,"aria-label":e?"Expand sidebar":"Collapse sidebar",children:t.jsx(q,{fontSize:"small"})})]}):t.jsxs(h,{sx:{minHeight:56,display:"flex",flexDirection:e?"column":"row",alignItems:"center",justifyContent:e?"center":"space-between",gap:e?.5:0,py:e?1:0,px:e?0:2,flexShrink:0},children:[t.jsxs(h,{onClick:s=>o("/",s),sx:{display:"flex",alignItems:"center",gap:1,cursor:"pointer",minWidth:0},children:[t.jsx(h,{component:"img",src:"/logo.svg",alt:"Malloy",sx:{width:24,height:24,flexShrink:0}}),!e&&t.jsx(K,{variant:"subtitle1",sx:{color:"text.primary",fontWeight:500,letterSpacing:"-0.025em",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},children:"Malloy Publisher"})]}),t.jsx(A,{title:e?"Expand sidebar":"Collapse sidebar",placement:"right",children:t.jsx(N,{size:"small",onClick:r,"aria-label":e?"Expand sidebar":"Collapse sidebar",children:t.jsx(q,{fontSize:"small"})})})]})}function Tt({isCollapsed:e}){const n=he().pathname==="/";return t.jsx(Z,{sx:{py:0},children:t.jsx(je,{icon:t.jsx(kt,{fontSize:"small"}),label:"Home",to:"/",selected:n,isCollapsed:e})})}function Bt({isCollapsed:e}){const{apiClients:r}=Oe(),n=xe(),{data:o}=We({queryKey:["environments"],queryFn:()=>r.environments.listEnvironments()}),s=o?.data??[];return s.length===0?null:t.jsxs(h,{sx:{mt:1},children:[!e&&t.jsx(K,{variant:"caption",sx:{display:"block",px:3,py:1,color:"text.secondary",fontWeight:500,textTransform:"uppercase",fontSize:"0.6875rem",letterSpacing:"0.5px"},children:"Environments"}),t.jsx(Z,{sx:{py:0},children:s.map(c=>{const i=c.name??"";return t.jsx(je,{icon:t.jsx(jt,{fontSize:"small"}),label:i,to:`/${i}`,selected:n.environmentName===i,isCollapsed:e},i)})})]})}function Rt({isCollapsed:e}){const r=[{label:"Malloy Docs",href:se.docsHome,icon:t.jsx(gt,{fontSize:"small"}),external:!0},{label:"Publisher Docs",href:se.publishing,icon:t.jsx(wt,{fontSize:"small"}),external:!0},{label:"Publisher API",href:"/api-doc.html",icon:t.jsx(vt,{fontSize:"small"}),external:!1}];return t.jsx(Z,{sx:{py:1},children:r.map(n=>t.jsx(Lt,{label:n.label,href:n.href,icon:n.icon,external:n.external,isCollapsed:e},n.label))})}function je({icon:e,label:r,to:n,selected:o,isCollapsed:s}){const c=J(),i=t.jsxs(fe,{selected:o,onClick:p=>c(n,p),sx:{justifyContent:s?"center":"flex-start",px:s?0:2},children:[t.jsx(me,{sx:{minWidth:s?0:36,justifyContent:"center",color:o?"text.primary":"text.secondary"},children:e}),!s&&t.jsx(ge,{primary:r,primaryTypographyProps:{variant:"body2",sx:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}})]});return s?t.jsx(A,{title:r,placement:"right",children:t.jsx(h,{children:i})}):i}function Lt({label:e,href:r,icon:n,external:o,isCollapsed:s}){const c=t.jsxs(fe,{component:"a",href:r,target:o?"_blank":void 0,rel:o?"noopener noreferrer":void 0,sx:{justifyContent:s?"center":"flex-start",px:s?0:2},children:[t.jsx(me,{sx:{minWidth:s?0:36,justifyContent:"center",color:"text.secondary"},children:n}),!s&&t.jsx(ge,{primary:e,primaryTypographyProps:{variant:"body2",sx:{color:"text.secondary",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}})]});return s?t.jsx(A,{title:e,placement:"right",children:t.jsx(h,{children:c})}):c}function Ht({open:e,onClose:r,logoHeader:n}){return t.jsx(mt,{anchor:"left",open:e,onClose:r,ModalProps:{keepMounted:!0},sx:{display:{xs:"block",md:"none"},"& .MuiDrawer-paper":{boxSizing:"border-box",width:260}},children:t.jsx(ve,{isCollapsed:!1,onToggleCollapse:r,logoHeader:n})})}function At({headerProps:e}){const r=G(),n=Ve(r.breakpoints.up("md")),[o,s]=d.useState(!1),[c,i]=d.useState(!1);return d.useEffect(()=>{n&&o&&s(!1)},[n,o]),t.jsxs(h,{sx:{height:"100dvh",display:"flex",flexDirection:"row",bgcolor:"background.default"},children:[n&&t.jsx(ve,{isCollapsed:c,onToggleCollapse:()=>i(p=>!p),logoHeader:e?.logoHeader}),t.jsxs(h,{component:"main",sx:{flex:1,display:"flex",flexDirection:"column",minWidth:0},children:[t.jsxs(h,{sx:{flexShrink:0,display:"flex",alignItems:"center",justifyContent:"space-between",height:Fe.headerHeight,px:{xs:1,md:3},backgroundColor:"background.default"},children:[t.jsx(h,{sx:{display:{xs:"flex",md:"none"},alignItems:"center",mr:1},children:t.jsx(N,{size:"small",onClick:()=>s(!0),"aria-label":"Open navigation",children:t.jsx(q,{fontSize:"small"})})}),t.jsx(h,{sx:{flex:1,minWidth:0,display:"flex",alignItems:"center"},children:t.jsx(Et,{})}),t.jsxs(h,{id:"header-actions-portal",sx:{display:"flex",alignItems:"center",flexShrink:0,gap:1},children:[t.jsx(zt,{}),t.jsx(Pt,{}),e?.endCap]})]}),t.jsx(h,{sx:{flex:1,overflow:"auto",minWidth:320,minHeight:0},children:t.jsx(d.Suspense,{fallback:t.jsx(Xe,{}),children:t.jsx(Ue,{})})})]}),t.jsx(Ht,{open:o,onClose:()=>s(!1),logoHeader:e?.logoHeader})]})}export{At as default};
@@ -0,0 +1,2 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index.es-6eARPKZf.js","assets/index-CGdwupPP.js","assets/index-DUqldpo0.css","assets/index-DoF8ihra.js","assets/index-ByieDZlo.js","assets/ToggleButtonGroup-CEZThrzh.js"])))=>i.map(i=>d[i]);
2
+ import{c as O,j as n,m as y,r as m,Z as $,E as k,F as C,_ as w,H as u,$ as g,a0 as W,a1 as F,a2 as b,a3 as E,a4 as U,a5 as N,a6 as D,a7 as M,a8 as A,a9 as z,aa as P,Y as R,ab as G,ac as V,ad as q,G as B,O as H,ae as K,af as Y,ag as Z,T as j,ah as p,ai as J}from"./index-CGdwupPP.js";const L=O(n.jsx("path",{d:"m14.06 9.02.92.92L5.92 19H5v-.92zM17.66 3c-.25 0-.51.1-.7.29l-1.83 1.83 3.75 3.75 1.83-1.83c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.2-.2-.45-.29-.71-.29m-3.6 3.19L3 17.25V21h3.75L17.81 9.94z"}));function I(e,s){const t=y();return m.useCallback((a,x)=>{const i=new URLSearchParams(a.givens).toString(),o=encodeURIComponent(e),h=encodeURIComponent(s),l=encodeURIComponent(a.dashboard);t(`/${o}/${h}/dashboards/${l}`+(i?`?${i}`:""),x)},[t,e,s])}function S({environmentName:e,packageName:s,notebookPath:t}){const{params:a,onGivensChange:x}=$(),i=I(e,s),o=y(),h=k(),{pathname:l}=C(),c=t.endsWith(".malloy"),r=w();return m.useEffect(()=>{if(!c||r)return;const d=()=>void E(()=>import("./index.es-6eARPKZf.js"),__vite__mapDeps([0,1,2,3,4,5])),f=window.requestIdleCallback;if(f){const T=f(d);return()=>window.cancelIdleCallback?.(T)}const v=setTimeout(d,1500);return()=>clearTimeout(v)},[c,r]),n.jsxs(u,{sx:{p:3,maxWidth:1200,mx:"auto"},children:[n.jsx(g,{label:s,href:`/${e}/${s}`,onClick:d=>o(`/${e}/${s}`,d)}),c&&!r&&n.jsx(u,{sx:{display:"flex",justifyContent:"flex-end",mb:1},children:n.jsx(W,{label:"Edit",icon:n.jsx(L,{}),onClick:()=>h(`${l.replace(/\/$/,"")}/edit`)})}),n.jsx(F,{resourceUri:b({environmentName:e,packageName:s,modelPath:t}),maxResultSize:1024*1024,givens:a,onGivensChange:x,onNavigate:o,onDrillNavigate:i})]})}function Q(){const[e,s]=m.useState(!1),t=m.useRef(!1),a=m.useRef(!1),x=m.useCallback(l=>{t.current=l,s(l)},[]),i=m.useCallback(()=>{a.current=!0},[]),o=U(m.useCallback(({currentLocation:l,nextLocation:c})=>t.current&&!a.current&&l.pathname!==c.pathname,[]));m.useEffect(()=>{if(!e)return;const l=c=>{c.preventDefault(),c.returnValue=""};return window.addEventListener("beforeunload",l),()=>window.removeEventListener("beforeunload",l)},[e]);const h=n.jsx(N,{open:o.state==="blocked",canSave:!1,onKeepEditing:()=>o.reset?.(),onDiscard:()=>o.proceed?.()});return{onDirtyChange:x,leaving:i,dialog:h}}const X=G.lazy(()=>E(()=>import("./index.es-6eARPKZf.js"),__vite__mapDeps([0,1,2,3,4,5])).then(e=>({default:e.DashboardEditor})));function ee({environmentName:e,packageName:s,dashboardName:t,kind:a="dashboard",path:x}){const i=k(),o=Q(),{pathname:h}=C(),l=h.replace(/\/edit\/?$/,""),c=m.useMemo(()=>a==="dashboard"?D({environmentName:e,packageName:s,dashboardName:t}):M({environmentName:e,packageName:s,notebookName:t}),[a,e,s,t]);return n.jsxs(u,{sx:{p:3,maxWidth:1600,mx:"auto"},children:[n.jsx(g,{label:s,href:`/${e}/${s}`,onClick:()=>i(`/${e}/${s}`)}),n.jsx(A,{children:n.jsx(m.Suspense,{fallback:n.jsxs(z,{sx:{gap:2},children:[n.jsx(P,{}),n.jsx(R,{text:"Opening the builder…"})]}),children:n.jsx(X,{resourceUri:b({environmentName:e,packageName:s}),dashboard:t,kind:a,path:x,onExit:()=>{o.leaving(),i(l)},onDirtyChange:o.onDirtyChange,onEvent:c},`${e}/${s}/${a}/${t}`)})}),o.dialog]})}function ne({environmentName:e,packageName:s,dashboardName:t}){const{params:a,onGivensChange:x}=$(),i=I(e,s),o=k(),{pathname:h}=C(),l=m.useMemo(()=>D({environmentName:e,packageName:s,dashboardName:t}),[e,s,t]),c=w();return m.useEffect(()=>{if(c)return;const r=()=>void E(()=>import("./index.es-6eARPKZf.js"),__vite__mapDeps([0,1,2,3,4,5])),d=window.requestIdleCallback;if(d){const v=d(r);return()=>window.cancelIdleCallback?.(v)}const f=setTimeout(r,1500);return()=>clearTimeout(f)},[c]),n.jsxs(u,{sx:{p:3,maxWidth:1600,mx:"auto"},children:[n.jsx(g,{label:s,href:`/${e}/${s}`,onClick:()=>o(`/${e}/${s}`)}),n.jsx(P,{children:!c&&n.jsx(W,{label:"Edit",icon:n.jsx(L,{}),onClick:()=>o(`${h.replace(/\/$/,"")}/edit`)})}),n.jsx(V,{resourceUri:b({environmentName:e,packageName:s}),dashboard:t,givens:a,onGivensChange:x,onNavigate:i,onEvent:l,maxResultSize:1024*1024})]})}function _({environmentName:e,packageName:s,routeKind:t,slug:a,edit:x}){const{location:i,settled:o}=q(e,s,t,a);if(!o)return n.jsx(R,{text:"Opening..."});const h=i?.kind??t;return x?n.jsx(ee,{environmentName:e,packageName:s,dashboardName:a,kind:h,...i?{path:i.path}:{}}):h==="dashboard"?n.jsx(ne,{environmentName:e,packageName:s,dashboardName:a}):n.jsx(S,{environmentName:e,packageName:s,notebookPath:i?.path??`notebooks/${a}.malloy`})}function te(){const e=B(),s=e["*"],{server:t}=H(),a=y(),{params:x,onGivensChange:i}=$();if(!e.environmentName)return n.jsx("div",{children:n.jsx("h2",{children:"Missing environment name"})});if(!e.packageName)return n.jsx("div",{children:n.jsx("h2",{children:"Missing package name"})});const o={p:3,maxWidth:1200,mx:"auto"};if(s?.startsWith("dashboards/")&&!s.endsWith(".malloy")&&!s.endsWith(".malloynb")){const r=s.slice(11),d=r.endsWith("/edit");return n.jsx(_,{environmentName:e.environmentName,packageName:e.packageName,routeKind:"dashboard",slug:d?r.slice(0,-5):r,edit:d})}if(s?.startsWith("notebooks/")&&!s.endsWith(".malloy")&&!s.endsWith(".malloynb")){const r=s.slice(10),d=r.endsWith("/edit");return n.jsx(_,{environmentName:e.environmentName,packageName:e.packageName,routeKind:"notebook",slug:d?r.slice(0,-5):r,edit:d})}if(s?.startsWith("data-apps/")&&!s.endsWith(".malloy")&&!s.endsWith(".malloynb")){const r=s.slice(10),d=b({environmentName:e.environmentName,packageName:e.packageName,modelPath:r});return n.jsxs(u,{sx:o,children:[n.jsx(g,{label:e.packageName,href:`/${e.environmentName}/${e.packageName}`,onClick:f=>a(`/${e.environmentName}/${e.packageName}`,f)}),n.jsx(K,{resourceUri:d})]})}const h=b({environmentName:e.environmentName,packageName:e.packageName,modelPath:s});if(s?.endsWith(".malloy"))return n.jsxs(u,{sx:o,children:[n.jsx(g,{label:e.packageName,href:`/${e.environmentName}/${e.packageName}`,onClick:r=>a(`/${e.environmentName}/${e.packageName}`,r)}),n.jsx(Y,{resourceUri:h,runOnDemand:!0,maxResultSize:512*1024,givens:x,onGivensChange:i})]});if(s?.endsWith(".malloynb"))return n.jsx(S,{environmentName:e.environmentName,packageName:e.packageName,notebookPath:s});const l=/\.[^./]+$/.test(s??""),c=Z({server:t,environmentName:e.environmentName,packageName:e.packageName,path:s??""});return n.jsxs(u,{sx:o,children:[n.jsx(g,{label:e.packageName,href:`/${e.environmentName}/${e.packageName}`,onClick:r=>a(`/${e.environmentName}/${e.packageName}`,r)}),n.jsx(j,{variant:"h6",sx:{fontWeight:600},children:"Nothing to open at this path"}),n.jsxs(j,{variant:"body2",color:"text.secondary",sx:{mt:1},children:[n.jsx(u,{component:"span",sx:{fontFamily:p},children:s})," ","does not name a"," ",n.jsx(u,{component:"span",sx:{fontFamily:p},children:".malloy"})," ","or"," ",n.jsx(u,{component:"span",sx:{fontFamily:p},children:".malloynb"})," ","file in package"," ",n.jsx(u,{component:"span",sx:{fontFamily:p},children:e.packageName}),". This address opens"," ",n.jsx(u,{component:"span",sx:{fontFamily:p},children:".malloy"})," ","and"," ",n.jsx(u,{component:"span",sx:{fontFamily:p},children:".malloynb"})," ","files."]}),l&&n.jsxs(j,{variant:"body2",color:"text.secondary",sx:{mt:1},children:["A file from the package's"," ",n.jsx(u,{component:"span",sx:{fontFamily:p},children:"public/"})," ","directory is served at ",n.jsx(J,{href:c,children:c}),"."]}),n.jsx(j,{variant:"body2",color:"text.secondary",sx:{mt:1},children:"The package lists its models, notebooks, and data apps."})]})}export{te as default};
@@ -0,0 +1 @@
1
+ import{G as r,m as t,j as e,a2 as c,aj as m}from"./index-CGdwupPP.js";function l(){const{environmentName:a,packageName:n}=r(),s=t();if(a)if(n){const i=c({environmentName:a,packageName:n});return e.jsx(m,{onClickPackageFile:s,resourceUri:i})}else return e.jsx("div",{children:e.jsx("h2",{children:"Missing package name"})});else return e.jsx("div",{children:e.jsx("h2",{children:"Missing environment name"})})}export{l as default};