@roxyapi/ui 0.7.0 → 0.8.1

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 (40) hide show
  1. package/AGENTS.md +35 -52
  2. package/README.md +99 -41
  3. package/dist/cdn/components/bodygraph.js +54 -0
  4. package/dist/cdn/components/bodygraph.js.map +7 -0
  5. package/dist/cdn/components/forecast-timeline.js +45 -0
  6. package/dist/cdn/components/forecast-timeline.js.map +7 -0
  7. package/dist/cdn/roxy-ui.js +49 -40
  8. package/dist/cdn/roxy-ui.js.map +4 -4
  9. package/dist/components/bodygraph.d.ts +27 -0
  10. package/dist/components/bodygraph.d.ts.map +1 -0
  11. package/dist/components/bodygraph.js +11 -0
  12. package/dist/components/bodygraph.js.map +7 -0
  13. package/dist/components/forecast-timeline.d.ts +38 -0
  14. package/dist/components/forecast-timeline.d.ts.map +1 -0
  15. package/dist/components/forecast-timeline.js +2 -0
  16. package/dist/components/forecast-timeline.js.map +7 -0
  17. package/dist/index.cjs +45 -36
  18. package/dist/index.cjs.map +4 -4
  19. package/dist/index.d.ts +2 -0
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +52 -43
  22. package/dist/index.js.map +4 -4
  23. package/dist/manifest.d.ts.map +1 -1
  24. package/dist/manifest.json +2 -0
  25. package/dist/types/index.d.ts +1 -1
  26. package/dist/types/index.d.ts.map +1 -1
  27. package/dist/types/types.gen.d.ts +3994 -6
  28. package/dist/types/types.gen.d.ts.map +1 -1
  29. package/dist/utils/bodygraph-render.d.ts +105 -0
  30. package/dist/utils/bodygraph-render.d.ts.map +1 -0
  31. package/dist/version.d.ts +1 -1
  32. package/package.json +1 -1
  33. package/src/components/bodygraph.ts +390 -0
  34. package/src/components/forecast-timeline.ts +336 -0
  35. package/src/index.ts +4 -0
  36. package/src/manifest.ts +26 -0
  37. package/src/types/index.ts +1 -1
  38. package/src/types/types.gen.ts +4079 -6
  39. package/src/utils/bodygraph-render.ts +641 -0
  40. package/src/version.ts +1 -1
package/AGENTS.md CHANGED
@@ -8,7 +8,7 @@ Live preview: <https://roxyapi.github.io/ui/>. Source of truth for component typ
8
8
 
9
9
  ## Identity
10
10
 
11
- Roxy UI is the official web component library for the RoxyAPI catalog. Components and helpers cover Western astrology, Vedic astrology, numerology, tarot, biorhythm, I Ching, crystals, dreams, angel numbers, with the location helper for geocoding. New endpoints regenerate component types automatically.
11
+ Roxy UI is the official web component library for the RoxyAPI catalog. Components and helpers cover Western astrology, Vedic astrology, numerology, tarot, Human Design, forecast, biorhythm, I Ching, crystals, dreams, angel numbers, with the location helper for geocoding. New endpoints regenerate component types automatically.
12
12
 
13
13
  ## Decision tree for picking a component
14
14
 
@@ -32,6 +32,8 @@ Map the natural-language request to a component first; fall back to the table be
32
32
  | "life path number", "expression number", "personal year", "numerology chart" | `<roxy-numerology-card>` |
33
33
  | "draw a tarot card", "card of the day", "card meaning" | `<roxy-tarot-card>` |
34
34
  | "tarot reading", "three-card spread", "Celtic Cross", "yes or no tarot" | `<roxy-tarot-spread>` |
35
+ | "Human Design chart", "bodygraph", "my type and authority", "defined centers", "channels and gates" | `<roxy-bodygraph>` |
36
+ | "forecast", "what is coming up", "upcoming transits and events", "timeline of my year" | `<roxy-forecast-timeline>` |
35
37
  | "biorhythm", "physical/emotional/intellectual cycle", "critical days" | `<roxy-biorhythm-chart>` |
36
38
  | "I Ching", "hexagram", "cast the coins", "Book of Changes" | `<roxy-hexagram>` |
37
39
  | "moon phase", "moon calendar", "next full moon", "current moon" | `<roxy-moon-phase>` |
@@ -72,6 +74,8 @@ Use the table below for the formal endpoint to component mapping.
72
74
  | `<roxy-numerology-card>` | Numerology | POST /numerology/{life-path,expression,personal-year,chart} | Life path, expression, personal year, full chart |
73
75
  | `<roxy-tarot-card>` | Tarot | GET /tarot/cards/{id}, POST /tarot/daily | Single card with upright and reversed flip |
74
76
  | `<roxy-tarot-spread>` | Tarot | POST /tarot/spreads/{three-card,celtic-cross,love}, /tarot/yes-no, /tarot/draw | Spreads with positions and reading |
77
+ | `<roxy-bodygraph>` | Human Design | POST /human-design/bodygraph | Nine-center chart with defined and open centers, active channels, gates, and a type and authority summary |
78
+ | `<roxy-forecast-timeline>` | Forecast | POST /forecast/timeline | Date-grouped events across Western, Vedic, and biorhythm domains, weighted by significance |
75
79
  | `<roxy-biorhythm-chart>` | Biorhythm | POST /biorhythm/{daily,forecast,critical-days} | Daily bars, forecast cycle lines, critical days |
76
80
  | `<roxy-hexagram>` | I Ching | GET /iching/hexagrams/{number}, /iching/cast, POST /iching/daily, /iching/daily/cast | Hexagram with trigrams, judgment, image, changing lines |
77
81
  | `<roxy-endpoint-form>` | Helper | Any endpoint via x-roxy-ui hints | Schema-driven form, emits roxy-submit |
@@ -116,16 +120,13 @@ const { data: chart } = await roxy.astrology.generateNatalChart({
116
120
 
117
121
  Every chart endpoint accepts `timezone` as either a decimal-hour offset (`5.5` for IST, `-5` for EST) or an IANA name (`'Asia/Kolkata'`, `'America/New_York'`). The decimal form is what `/location/search` returns; the IANA form is correct over DST boundaries. Pick one and stay consistent in a single integration. Mixing them does not break the API but makes the bug surface area larger.
118
122
 
119
- ### 4. Secret key in the browser
123
+ ### 4. API key in the browser
120
124
 
121
- There are two key classes. **Secret keys are unprefixed** and grant full access; they belong server-side only (Node, Bun, Hono, Next.js route handlers, Workers, Edge functions). **Publishable keys** are prefixed `pk_live_*` or `pk_test_*` and are safe in the browser; they are locked to an origin allowlist at the API gateway. For widgets, embeds, vanilla HTML, and `data-publishable-key` use the publishable key. For the typed SDK on a server, use the secret key.
125
+ Keys are server side only. Call `createRoxy(process.env.ROXY_API_KEY!)` on your server (Node, Bun, Hono, Next.js route handlers, Workers, Edge functions), then send the response, not the key, to the component. Never ship the key in a client bundle. Browser-safe keys for direct client-side embedding are on the roadmap, not yet available.
122
126
 
123
127
  ```ts
124
- // Server (Next.js route handler, Workers, Bun): secret key
128
+ // Server side only
125
129
  const roxy = createRoxy(process.env.ROXY_API_KEY!);
126
-
127
- // Browser (widgets auto-mount): publishable key
128
- <div data-roxy-widget="natal-chart" data-publishable-key="pk_live_xxx" ...></div>
129
130
  ```
130
131
 
131
132
  ### 5. Missing `'use client'` in Next.js App Router
@@ -190,30 +191,30 @@ import type { NatalChartResponse } from '@roxyapi/sdk';
190
191
 
191
192
  ### Pattern 1: vanilla HTML, no build step
192
193
 
194
+ Fetch on your server with the secret key, then inline the response into the component as a child `<script type="application/json" class="roxy-data">`. The component reads it on load. No key in the browser.
195
+
193
196
  ```html
194
197
  <script
195
198
  src="https://cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/roxy-ui.js"
196
199
  crossorigin="anonymous"
197
200
  ></script>
198
201
 
199
- <roxy-natal-chart id="chart"></roxy-natal-chart>
200
-
201
- <script type="module">
202
- import { createRoxy } from 'https://cdn.jsdelivr.net/npm/@roxyapi/sdk@latest/dist/factory.js';
203
- const roxy = createRoxy('pk_live_xxx');
204
- const { data } = await roxy.astrology.generateNatalChart({
205
- body: { date: '1990-01-15', time: '14:30:00', latitude: 19.07, longitude: 72.88, timezone: 5.5 },
206
- });
207
- document.getElementById('chart').data = data;
208
- </script>
202
+ <roxy-natal-chart>
203
+ <script type="application/json" class="roxy-data">
204
+ { "planets": [ ... ], "houses": [ ... ], "aspects": [ ... ] }
205
+ </script>
206
+ </roxy-natal-chart>
209
207
  ```
210
208
 
211
- ### Pattern 2: React, with the typed SDK
209
+ Setting the JavaScript `data` property always wins over the inlined JSON, so the same element also drives dynamic pages.
210
+
211
+ ### Pattern 2: React, interactive
212
+
213
+ `<RoxyLocationSearch>` runs in the browser. On select, call your own route, which holds the secret key, and set the returned data on the chart. The key never reaches the client.
212
214
 
213
215
  ```tsx
214
216
  'use client';
215
217
 
216
- import { createRoxy } from '@roxyapi/sdk';
217
218
  import {
218
219
  RoxyNatalChart,
219
220
  RoxyLocationSearch,
@@ -221,18 +222,18 @@ import {
221
222
  } from '@roxyapi/ui-react';
222
223
  import { useState } from 'react';
223
224
 
224
- const roxy = createRoxy(process.env.NEXT_PUBLIC_ROXY_API_KEY!);
225
-
226
225
  export function BirthChartView() {
227
226
  const [chart, setChart] = useState<RoxyNatalChartProps['data']>(undefined);
228
227
 
229
228
  const onLocationSelect = async (e: CustomEvent<{ latitude?: number; longitude?: number; timezone?: number | string }>) => {
230
229
  const { latitude, longitude, timezone } = e.detail;
231
230
  if (latitude == null || longitude == null) return;
232
- const { data } = await roxy.astrology.generateNatalChart({
233
- body: { date: '1990-01-15', time: '14:30:00', latitude, longitude, timezone },
231
+ // Your route calls roxy.astrology.generateNatalChart with the secret key.
232
+ const res = await fetch('/api/natal-chart', {
233
+ method: 'POST',
234
+ body: JSON.stringify({ date: '1990-01-15', time: '14:30:00', latitude, longitude, timezone }),
234
235
  });
235
- setChart(data);
236
+ setChart(await res.json());
236
237
  };
237
238
 
238
239
  return (
@@ -244,9 +245,11 @@ export function BirthChartView() {
244
245
  }
245
246
  ```
246
247
 
248
+ For a static chart with no picker, fetch in a Server Component and pass `data` to a client component (Pattern 6).
249
+
247
250
  ### Pattern 3: schema-driven form
248
251
 
249
- `<roxy-endpoint-form>` reads the OpenAPI spec and renders the inputs for any endpoint. Listen for the `roxy-submit` event with the validated payload.
252
+ `<roxy-endpoint-form>` reads the OpenAPI spec and renders the inputs for any endpoint. On `roxy-submit`, POST the validated values to your own route, which calls the SDK with the secret key, then set the returned data on the target component.
250
253
 
251
254
  ```html
252
255
  <roxy-endpoint-form
@@ -254,41 +257,21 @@ export function BirthChartView() {
254
257
  method="POST"
255
258
  submit-label="Generate kundli"
256
259
  ></roxy-endpoint-form>
260
+ <roxy-vedic-kundli chart-style="south"></roxy-vedic-kundli>
257
261
 
258
262
  <script type="module">
259
- import { createRoxy } from 'https://cdn.jsdelivr.net/npm/@roxyapi/sdk@latest/dist/factory.js';
260
- const roxy = createRoxy('pk_live_xxx');
261
263
  const form = document.querySelector('roxy-endpoint-form');
262
264
  form.addEventListener('roxy-submit', async (e) => {
263
- const { values } = e.detail;
264
- const { data: kundli } = await roxy.vedicAstrology.generateBirthChart({ body: values });
265
- document.querySelector('roxy-vedic-kundli').data = kundli;
265
+ // Your route calls roxy.vedicAstrology.generateBirthChart with the secret key.
266
+ const res = await fetch('/api/kundli', { method: 'POST', body: JSON.stringify(e.detail.values) });
267
+ document.querySelector('roxy-vedic-kundli').data = await res.json();
266
268
  });
267
269
  </script>
268
270
  ```
269
271
 
270
- ### Pattern 4: widgets auto-mount (no JavaScript wiring)
271
-
272
- Use a publishable key (`pk_live_*` or `pk_test_*`) for client-side embeds. Get one at <https://roxyapi.com/account>. Publishable keys are origin-restricted at the API gateway. Register the customer domain (e.g. `https://customer.com`) when creating the key, and the gateway will reject requests from any other origin. Never use a secret key in client-side code (secret keys are unprefixed and live server-side only).
273
-
274
- ```html
275
- <script
276
- src="https://cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/widgets.js"
277
- defer
278
- ></script>
279
-
280
- <div
281
- data-roxy-widget="natal-chart"
282
- data-publishable-key="pk_live_xxx"
283
- data-date="1990-01-15"
284
- data-time="14:30:00"
285
- data-latitude="19.07"
286
- data-longitude="72.88"
287
- data-timezone="5.5"
288
- ></div>
289
- ```
272
+ ### Pattern 4: widgets auto-mount (coming soon)
290
273
 
291
- The auto-mount script reads `data-*` attributes, calls the matching endpoint, and renders the matching component.
274
+ A zero-wiring embed that reads `data-*` attributes and renders the matching component is on the roadmap. It needs browser-safe keys, which are not yet available. Until then, use Pattern 1 (inline JSON) for no-build pages.
292
275
 
293
276
  ### Pattern 5: MCP tool-call response
294
277
 
@@ -392,7 +375,7 @@ Every visible aspect of the chart is driven by `--roxy-*` CSS custom properties
392
375
 
393
376
  ## Domain ordering
394
377
 
395
- When listing domains in user-visible copy, use the canonical order: Western astrology, Vedic astrology, numerology, tarot, biorhythm, I Ching, crystals, dreams, angel numbers. Location is utility, not a selling domain.
378
+ When listing domains in user-visible copy, use the canonical order: Western astrology, Vedic astrology, numerology, tarot, human design, forecast, biorhythm, I Ching, crystals, dreams, angel numbers. Location is utility, not a selling domain.
396
379
 
397
380
  ## What not to ship
398
381
 
package/README.md CHANGED
@@ -42,6 +42,14 @@ Light, dark, your brand. Override one CSS variable and every component updates.
42
42
  <img src="https://raw.githubusercontent.com/RoxyAPI/ui/main/assets/screenshots/vedic-kundli-dark.png" alt="Vedic kundli, dark mode">
43
43
  </td>
44
44
  </tr>
45
+ <tr>
46
+ <td width="50%" align="center">
47
+ <img src="https://raw.githubusercontent.com/RoxyAPI/ui/main/assets/screenshots/bodygraph-light.png" alt="Human Design bodygraph, light mode">
48
+ </td>
49
+ <td width="50%" align="center">
50
+ <img src="https://raw.githubusercontent.com/RoxyAPI/ui/main/assets/screenshots/bodygraph-dark.png" alt="Human Design bodygraph, dark mode">
51
+ </td>
52
+ </tr>
45
53
  </table>
46
54
 
47
55
  ```css
@@ -148,6 +156,25 @@ Every chart, table, and card adapts to light and dark automatically. Hover any i
148
156
  </tr>
149
157
  </table>
150
158
 
159
+ ### Human Design and forecast
160
+
161
+ <table>
162
+ <tr>
163
+ <td width="50%"><strong>Bodygraph</strong> · <code>&lt;roxy-bodygraph&gt;</code><br><sub>POST /human-design/bodygraph</sub><br>
164
+ <picture>
165
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/RoxyAPI/ui/main/assets/screenshots/bodygraph-dark.png">
166
+ <img src="https://raw.githubusercontent.com/RoxyAPI/ui/main/assets/screenshots/bodygraph-light.png" alt="Human Design bodygraph with nine centers defined and open, channels between activated gates, plus type, authority, and profile summary">
167
+ </picture>
168
+ </td>
169
+ <td width="50%"><strong>Forecast timeline</strong> · <code>&lt;roxy-forecast-timeline&gt;</code><br><sub>POST /forecast/timeline</sub><br>
170
+ <picture>
171
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/RoxyAPI/ui/main/assets/screenshots/forecast-timeline-dark.png">
172
+ <img src="https://raw.githubusercontent.com/RoxyAPI/ui/main/assets/screenshots/forecast-timeline-light.png" alt="Cross-domain forecast timeline of transits, ingresses, retrograde stations, and biorhythm critical days grouped by date and weighted by significance">
173
+ </picture>
174
+ </td>
175
+ </tr>
176
+ </table>
177
+
151
178
  ### Other domains
152
179
 
153
180
  <table>
@@ -194,42 +221,24 @@ Tables, cards, forms, and helper components in the [live demo](https://roxyapi.g
194
221
 
195
222
  ## Start with one component
196
223
 
197
- Vanilla HTML. No build step. Replace `YOUR_API_KEY` with a publishable key from <https://roxyapi.com/account>.
224
+ Fetch with the typed SDK, pass `data` to the component. No glue code.
198
225
 
199
- ```html
200
- <script
201
- src="https://cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/roxy-ui.js"
202
- crossorigin="anonymous"
203
- defer
204
- ></script>
205
- <roxy-natal-chart id="chart"></roxy-natal-chart>
206
- <script type="module">
207
- import { createRoxy } from 'https://cdn.jsdelivr.net/npm/@roxyapi/sdk@latest/dist/factory.js';
208
- const roxy = createRoxy('YOUR_API_KEY');
209
- const { data } = await roxy.astrology.generateNatalChart({
210
- body: { date: '1990-01-15', time: '14:30:00', latitude: 19.07, longitude: 72.88, timezone: 5.5 },
211
- });
212
- document.getElementById('chart').data = data;
213
- </script>
214
- ```
226
+ ```tsx
227
+ import { createRoxy } from '@roxyapi/sdk';
228
+ import { RoxyHoroscopeCard } from '@roxyapi/ui-react';
215
229
 
216
- > **Unwrap `data` before passing to the component.** The SDK returns `{ data, error, request, response }`. Pass the envelope and the chart renders `[object Object]`. This is the most common integration bug.
230
+ const roxy = createRoxy(process.env.ROXY_API_KEY!);
217
231
 
218
- Want a Vedic kundli instead? Same shape, different SDK method:
232
+ const { data } = await roxy.astrology.getDailyHoroscope({ path: { sign: 'aries' } });
219
233
 
220
- ```html
221
- <roxy-vedic-kundli id="kundli" chart-style="south"></roxy-vedic-kundli>
222
- <script type="module">
223
- import { createRoxy } from 'https://cdn.jsdelivr.net/npm/@roxyapi/sdk@latest/dist/factory.js';
224
- const roxy = createRoxy('YOUR_API_KEY');
225
- const { data } = await roxy.vedicAstrology.generateBirthChart({
226
- body: { date: '1990-01-15', time: '14:30:00', latitude: 19.07, longitude: 72.88, timezone: 5.5 },
227
- });
228
- document.getElementById('kundli').data = data;
229
- </script>
234
+ return <RoxyHoroscopeCard data={data} />;
230
235
  ```
231
236
 
232
- In production, geocode the user's city with `<roxy-location-search>` (see [Quick start](#quick-start)) instead of hardcoding coordinates.
237
+ Then expand into natal charts, kundli, dasha, tarot, and every other domain. The SDK returns `data`, the component renders it; the same pairing holds for all 32 components.
238
+
239
+ > **Pass `data`, not the envelope.** The SDK returns `{ data, error, request, response }`. Pass `data`, or the component renders `[object Object]`. This is the most common integration bug.
240
+
241
+ The key stays on your server. Vanilla HTML or a server-rendered page fetches the same way, then [inlines the JSON into the component](#server-rendered-no-javascript-wiring): no build step, no key in the browser. Try every component in the [live demo](https://roxyapi.github.io/ui/), each with Preview, Code, and shadcn tabs and a live color customizer.
233
242
 
234
243
  ## Install
235
244
 
@@ -285,7 +294,12 @@ Always call `/location/search` first. Every chart endpoint expects latitude, lon
285
294
 
286
295
  Server-rendered and cached pages (WordPress, JSX SSR, static HTML) cannot always run JavaScript to set the `data` property per element. Render the response into a child `<script type="application/json" class="roxy-data">` on the server instead. The component reads it on load. No per-element script, no API key in the browser.
287
296
 
297
+ Load the bundle once anywhere on the page. It registers every `roxy-*` element, so every component on the page renders from that single tag.
298
+
288
299
  ```html
300
+ <!-- Once per page: defines every roxy-* element -->
301
+ <script src="https://cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/roxy-ui.js" crossorigin="anonymous" defer></script>
302
+
289
303
  <roxy-natal-chart>
290
304
  <script type="application/json" class="roxy-data">
291
305
  { "planets": [ ... ], "houses": [ ... ], "aspects": [ ... ] }
@@ -437,7 +451,48 @@ const { data: cc } = await roxy.tarot.castCelticCross({
437
451
  <RoxyTarotSpread data={cc} />
438
452
  ```
439
453
 
440
- ### 5. Biorhythm (daily, forecast)
454
+ ### 5. Human Design (bodygraph)
455
+
456
+ The breakout 2026 self-knowledge category, computed from the same ephemeris as Western astrology plus the I Ching gate wheel and chakra-style centers. Self-discovery apps, dating and compatibility products, and AI coaching bots ship the full bodygraph first. No coordinates needed; Human Design uses the birth instant, not the observer location.
457
+
458
+ ```tsx
459
+ import { RoxyBodygraph } from '@roxyapi/ui-react';
460
+
461
+ // Full bodygraph. The head term every Human Design app leads with ("human design chart").
462
+ // Type, strategy, authority, profile, the nine centers, channels, and every gate
463
+ // activation in one call. Pass the birth instant only, no latitude or longitude.
464
+ const { data: bodygraph } = await roxy.humanDesign.generateBodygraph({
465
+ body: { date: '1990-01-15', time: '14:30:00', timezone: 5.5 },
466
+ });
467
+ <RoxyBodygraph data={bodygraph} />
468
+ ```
469
+
470
+ ### 6. Forecast (transits, cross-domain timeline)
471
+
472
+ The first cross-domain, stateless forecast in the catalog: one call merges Western transits, Vedic Vimshottari dasha boundaries, and biorhythm critical days into a single significance-scored, time-ordered timeline. Forecast feeds, transit alerts, and timing tools are the buyers. Acquire on the high-volume `astrology transits` search, convert on the cross-domain timeline no competitor ships. No coordinates needed.
473
+
474
+ ```tsx
475
+ import { RoxyForecastTimeline } from '@roxyapi/ui-react';
476
+
477
+ // Transit forecast. The demand leader. Western transit-to-natal aspects, sign
478
+ // ingresses, and retrograde stations over the window.
479
+ const { data: transits } = await roxy.forecast.forecastTransits({
480
+ body: { birthData: { date: '1990-01-15', time: '14:30:00', timezone: 5.5 } },
481
+ });
482
+ <RoxyForecastTimeline data={transits} />
483
+
484
+ // Cross-domain timeline. The same window merged with Vedic dasha boundaries and
485
+ // biorhythm critical days into one significance-scored timeline.
486
+ const { data: timeline } = await roxy.forecast.generateTimeline({
487
+ body: {
488
+ birthData: { date: '1990-01-15', time: '14:30:00', timezone: 5.5 },
489
+ domains: ['western', 'vedic', 'biorhythm'],
490
+ },
491
+ });
492
+ <RoxyForecastTimeline data={timeline} />
493
+ ```
494
+
495
+ ### 7. Biorhythm (daily, forecast)
441
496
 
442
497
  Zero competition domain. Steady search volume with the top Google result being a static calculator page. Pure land-grab for wellness, productivity, sports, and couples apps.
443
498
 
@@ -458,7 +513,7 @@ const { data: forecast } = await roxy.biorhythm.getForecast({
458
513
  <RoxyBiorhythmChart data={forecast} mode="forecast" />
459
514
  ```
460
515
 
461
- ### 6. I Ching (cast a reading, hexagram lookup)
516
+ ### 8. I Ching (cast a reading, hexagram lookup)
462
517
 
463
518
  Meditation apps, decision-making tools, and wisdom chatbots. `i ching API` and `hexagram API` are the keywords.
464
519
 
@@ -478,12 +533,13 @@ const { data: random } = await roxy.iching.getRandomHexagram();
478
533
 
479
534
  ## API keys
480
535
 
481
- Get keys at <https://roxyapi.com/account>.
536
+ Get a key at <https://roxyapi.com/account>.
537
+
538
+ Today every key is a **secret key**: use it server side only (Node, Bun, Hono, Next.js route handlers, Workers). Never commit it, never ship it in a client bundle. Fetch on your server and send the rendered response, not the key, to the browser. The [Start with one component](#start-with-one-component) section and the [framework recipes](#most-used-components-per-domain) show the pattern.
482
539
 
483
- - **Secret key** (server-side only). Use in Node, Bun, Hono, Next.js route handlers, Workers. Never commit, never ship in client bundles.
484
- - **Publishable key** (`pk_live_*` / `pk_test_*`). Safe in browsers, locked to the origins you register on the key. Use with the widgets auto-mount script for WordPress, Shopify, static HTML, embed scenarios. The API gateway rejects requests from any origin not on the allowlist.
540
+ Set `ROXY_API_KEY` to your secret key in your server env for every SDK example on this page.
485
541
 
486
- For the SDK examples on this page, set `ROXY_API_KEY` to a secret key in your server env. For the widgets auto-mount path (`data-publishable-key="pk_live_xxx"`), use a publishable key with your domain registered on it.
542
+ Browser-safe keys for direct client-side embedding are on the roadmap, not yet available. Until they ship, keep the fetch on your server.
487
543
 
488
544
  ## Distribution
489
545
 
@@ -493,7 +549,7 @@ For the SDK examples on this page, set `ROXY_API_KEY` to a secret key in your se
493
549
  | npm `@roxyapi/ui-react` | `npmjs.com/package/@roxyapi/ui-react` |
494
550
  | jsDelivr CDN (full bundle) | `cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/roxy-ui.js` |
495
551
  | jsDelivr CDN (per component) | `cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/components/{name}.js` |
496
- | Widgets auto-mount | `cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/widgets.js` |
552
+ | Widgets auto-mount (with browser keys, coming soon) | `cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/widgets.js` |
497
553
  | shadcn registry | `npx shadcn@latest add https://cdn.jsdelivr.net/gh/RoxyAPI/ui@latest/registry/{name}.json` |
498
554
 
499
555
  ## Components
@@ -526,6 +582,8 @@ For the SDK examples on this page, set `ROXY_API_KEY` to a secret key in your se
526
582
  | `<roxy-numerology-card>` | Numerology | POST /numerology/{life-path,expression,personal-year,chart} | Life path, expression, personal year, full chart |
527
583
  | `<roxy-tarot-card>` | Tarot | GET /tarot/cards/{id}, POST /tarot/daily | Single card with upright and reversed flip |
528
584
  | `<roxy-tarot-spread>` | Tarot | POST /tarot/spreads/{three-card,celtic-cross,love}, /tarot/yes-no, /tarot/draw | Spreads with positions and reading |
585
+ | `<roxy-bodygraph>` | Human Design | POST /human-design/bodygraph | Nine-center chart with defined and open centers, active channels, gates, and a type and authority summary |
586
+ | `<roxy-forecast-timeline>` | Forecast | POST /forecast/timeline | Date-grouped events across Western, Vedic, and biorhythm domains, weighted by significance |
529
587
  | `<roxy-biorhythm-chart>` | Biorhythm | POST /biorhythm/{daily,forecast,critical-days} | Daily bars, forecast cycle lines, critical days |
530
588
  | `<roxy-hexagram>` | I Ching | GET /iching/hexagrams/{number}, /iching/cast, POST /iching/daily, /iching/daily/cast | Hexagram with trigrams, judgment, image, changing lines |
531
589
  | `<roxy-endpoint-form>` | Helper | Any endpoint via x-roxy-ui hints | Schema-driven form, emits roxy-submit |
@@ -565,7 +623,7 @@ roxy-natal-chart {
565
623
  - Consistent response formats across every domain in the catalog.
566
624
  - A11y zero violations enforced in CI.
567
625
  - Tight per-component bundle budget enforced in CI.
568
- - Coverage of the highest-demand endpoints across Western astrology, Vedic astrology, numerology, tarot, biorhythm, I Ching, plus helpers for location search and schema-driven forms.
626
+ - Coverage of the highest-demand endpoints across Western astrology, Vedic astrology, numerology, tarot, Human Design, forecast, biorhythm, I Ching, plus helpers for location search and schema-driven forms.
569
627
 
570
628
  ## Built for AI agents
571
629
 
@@ -741,7 +799,7 @@ Components ship in Shadow DOM for style isolation; Tailwind utilities are scoped
741
799
  <details>
742
800
  <summary><strong>What is the security model for API keys?</strong></summary>
743
801
 
744
- Two key classes. Secret keys (unprefixed) live server-side only and grant full access. Publishable keys (`pk_live_*` / `pk_test_*`) are browser-safe and locked to an origin allowlist registered on the key. The API gateway rejects requests from any other origin and counts the failed attempt against the rate limit, so a stolen key cannot be brute-fired from elsewhere.
802
+ Today keys are secret keys: they live server side only and grant full access, so never ship one in a client bundle. Fetch on your server and pass the rendered response, not the key, to the browser. Browser-safe keys with an origin allowlist for direct client-side embedding are on the roadmap and not yet available.
745
803
 
746
804
  For CSP, allow `script-src https://cdn.jsdelivr.net` if loading the bundle from the CDN. Subresource Integrity hashes are available via the jsDelivr SRI API for any pinned version.
747
805
  </details>
@@ -752,11 +810,11 @@ For CSP, allow `script-src https://cdn.jsdelivr.net` if loading the bundle from
752
810
  Semver. Pre-1.0, minor bumps may include breaking changes (we will note them in the changelog). Patch bumps are always backwards-compatible. Pin a concrete version in production code:
753
811
 
754
812
  ```bash
755
- npm install @roxyapi/ui@0.1.x
813
+ npm install @roxyapi/ui@0.8.x
756
814
  ```
757
815
 
758
816
  ```html
759
- <script src="https://cdn.jsdelivr.net/npm/@roxyapi/ui@0.1.5/dist/cdn/roxy-ui.js"></script>
817
+ <script src="https://cdn.jsdelivr.net/npm/@roxyapi/ui@0.8.0/dist/cdn/roxy-ui.js"></script>
760
818
  ```
761
819
 
762
820
  The `@latest` URL on this page is for paste-friendly marketing; production code should pin.
@@ -0,0 +1,54 @@
1
+ "use strict";var RoxyUI_bodygraph=(()=>{var j=Object.defineProperty;var fe=Object.getOwnPropertyDescriptor;var qe=Object.getOwnPropertyNames;var Ve=Object.prototype.hasOwnProperty;var Ye=(s,e)=>{for(var t in e)j(s,t,{get:e[t],enumerable:!0})},We=(s,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of qe(e))!Ve.call(s,n)&&n!==t&&j(s,n,{get:()=>e[n],enumerable:!(r=fe(e,n))||r.enumerable});return s};var Ke=s=>We(j({},"__esModule",{value:!0}),s),Z=(s,e,t,r)=>{for(var n=r>1?void 0:r?fe(e,t):e,o=s.length-1,i;o>=0;o--)(i=s[o])&&(n=(r?i(e,t,n):i(n))||n);return r&&n&&j(e,t,n),n};var Ct={};Ye(Ct,{RoxyBodygraph:()=>w});var G=globalThis,D=G.ShadowRoot&&(G.ShadyCSS===void 0||G.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,Q=Symbol(),ye=new WeakMap,R=class{constructor(e,t,r){if(this._$cssResult$=!0,r!==Q)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=e,this.t=t}get styleSheet(){let e=this.o,t=this.t;if(D&&e===void 0){let r=t!==void 0&&t.length===1;r&&(e=ye.get(t)),e===void 0&&((this.o=e=new CSSStyleSheet).replaceSync(this.cssText),r&&ye.set(t,e))}return e}toString(){return this.cssText}},be=s=>new R(typeof s=="string"?s:s+"",void 0,Q),T=(s,...e)=>{let t=s.length===1?s[0]:e.reduce((r,n,o)=>r+(i=>{if(i._$cssResult$===!0)return i.cssText;if(typeof i=="number")return i;throw Error("Value passed to 'css' function must be a 'css' function result: "+i+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(n)+s[o+1],s[0]);return new R(t,s,Q)},xe=(s,e)=>{if(D)s.adoptedStyleSheets=e.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(let t of e){let r=document.createElement("style"),n=G.litNonce;n!==void 0&&r.setAttribute("nonce",n),r.textContent=t.cssText,s.appendChild(r)}},ee=D?s=>s:s=>s instanceof CSSStyleSheet?(e=>{let t="";for(let r of e.cssRules)t+=r.cssText;return be(t)})(s):s;var{is:Je,defineProperty:Xe,getOwnPropertyDescriptor:Fe,getOwnPropertyNames:Ze,getOwnPropertySymbols:Qe,getPrototypeOf:et}=Object,z=globalThis,$e=z.trustedTypes,tt=$e?$e.emptyScript:"",rt=z.reactiveElementPolyfillSupport,N=(s,e)=>s,O={toAttribute(s,e){switch(e){case Boolean:s=s?tt:null;break;case Object:case Array:s=s==null?s:JSON.stringify(s)}return s},fromAttribute(s,e){let t=s;switch(e){case Boolean:t=s!==null;break;case Number:t=s===null?null:Number(s);break;case Object:case Array:try{t=JSON.parse(s)}catch{t=null}}return t}},q=(s,e)=>!Je(s,e),ve={attribute:!0,type:String,converter:O,reflect:!1,useDefault:!1,hasChanged:q};Symbol.metadata??=Symbol("metadata"),z.litPropertyMetadata??=new WeakMap;var y=class extends HTMLElement{static addInitializer(e){this._$Ei(),(this.l??=[]).push(e)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(e,t=ve){if(t.state&&(t.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(e)&&((t=Object.create(t)).wrapped=!0),this.elementProperties.set(e,t),!t.noAccessor){let r=Symbol(),n=this.getPropertyDescriptor(e,r,t);n!==void 0&&Xe(this.prototype,e,n)}}static getPropertyDescriptor(e,t,r){let{get:n,set:o}=Fe(this.prototype,e)??{get(){return this[t]},set(i){this[t]=i}};return{get:n,set(i){let a=n?.call(this);o?.call(this,i),this.requestUpdate(e,a,r)},configurable:!0,enumerable:!0}}static getPropertyOptions(e){return this.elementProperties.get(e)??ve}static _$Ei(){if(this.hasOwnProperty(N("elementProperties")))return;let e=et(this);e.finalize(),e.l!==void 0&&(this.l=[...e.l]),this.elementProperties=new Map(e.elementProperties)}static finalize(){if(this.hasOwnProperty(N("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(N("properties"))){let t=this.properties,r=[...Ze(t),...Qe(t)];for(let n of r)this.createProperty(n,t[n])}let e=this[Symbol.metadata];if(e!==null){let t=litPropertyMetadata.get(e);if(t!==void 0)for(let[r,n]of t)this.elementProperties.set(r,n)}this._$Eh=new Map;for(let[t,r]of this.elementProperties){let n=this._$Eu(t,r);n!==void 0&&this._$Eh.set(n,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(e){let t=[];if(Array.isArray(e)){let r=new Set(e.flat(1/0).reverse());for(let n of r)t.unshift(ee(n))}else e!==void 0&&t.push(ee(e));return t}static _$Eu(e,t){let r=t.attribute;return r===!1?void 0:typeof r=="string"?r:typeof e=="string"?e.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(e=>this.enableUpdating=e),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(e=>e(this))}addController(e){(this._$EO??=new Set).add(e),this.renderRoot!==void 0&&this.isConnected&&e.hostConnected?.()}removeController(e){this._$EO?.delete(e)}_$E_(){let e=new Map,t=this.constructor.elementProperties;for(let r of t.keys())this.hasOwnProperty(r)&&(e.set(r,this[r]),delete this[r]);e.size>0&&(this._$Ep=e)}createRenderRoot(){let e=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return xe(e,this.constructor.elementStyles),e}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(e=>e.hostConnected?.())}enableUpdating(e){}disconnectedCallback(){this._$EO?.forEach(e=>e.hostDisconnected?.())}attributeChangedCallback(e,t,r){this._$AK(e,r)}_$ET(e,t){let r=this.constructor.elementProperties.get(e),n=this.constructor._$Eu(e,r);if(n!==void 0&&r.reflect===!0){let o=(r.converter?.toAttribute!==void 0?r.converter:O).toAttribute(t,r.type);this._$Em=e,o==null?this.removeAttribute(n):this.setAttribute(n,o),this._$Em=null}}_$AK(e,t){let r=this.constructor,n=r._$Eh.get(e);if(n!==void 0&&this._$Em!==n){let o=r.getPropertyOptions(n),i=typeof o.converter=="function"?{fromAttribute:o.converter}:o.converter?.fromAttribute!==void 0?o.converter:O;this._$Em=n;let a=i.fromAttribute(t,o.type);this[n]=a??this._$Ej?.get(n)??a,this._$Em=null}}requestUpdate(e,t,r,n=!1,o){if(e!==void 0){let i=this.constructor;if(n===!1&&(o=this[e]),r??=i.getPropertyOptions(e),!((r.hasChanged??q)(o,t)||r.useDefault&&r.reflect&&o===this._$Ej?.get(e)&&!this.hasAttribute(i._$Eu(e,r))))return;this.C(e,t,r)}this.isUpdatePending===!1&&(this._$ES=this._$EP())}C(e,t,{useDefault:r,reflect:n,wrapped:o},i){r&&!(this._$Ej??=new Map).has(e)&&(this._$Ej.set(e,i??t??this[e]),o!==!0||i!==void 0)||(this._$AL.has(e)||(this.hasUpdated||r||(t=void 0),this._$AL.set(e,t)),n===!0&&this._$Em!==e&&(this._$Eq??=new Set).add(e))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(t){Promise.reject(t)}let e=this.scheduleUpdate();return e!=null&&await e,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(let[n,o]of this._$Ep)this[n]=o;this._$Ep=void 0}let r=this.constructor.elementProperties;if(r.size>0)for(let[n,o]of r){let{wrapped:i}=o,a=this[n];i!==!0||this._$AL.has(n)||a===void 0||this.C(n,void 0,o,a)}}let e=!1,t=this._$AL;try{e=this.shouldUpdate(t),e?(this.willUpdate(t),this._$EO?.forEach(r=>r.hostUpdate?.()),this.update(t)):this._$EM()}catch(r){throw e=!1,this._$EM(),r}e&&this._$AE(t)}willUpdate(e){}_$AE(e){this._$EO?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(e)),this.updated(e)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(e){return!0}update(e){this._$Eq&&=this._$Eq.forEach(t=>this._$ET(t,this[t])),this._$EM()}updated(e){}firstUpdated(e){}};y.elementStyles=[],y.shadowRootOptions={mode:"open"},y[N("elementProperties")]=new Map,y[N("finalized")]=new Map,rt?.({ReactiveElement:y}),(z.reactiveElementVersions??=[]).push("2.1.2");var ae=globalThis,Ae=s=>s,V=ae.trustedTypes,_e=V?V.createPolicy("lit-html",{createHTML:s=>s}):void 0,Re="$lit$",x=`lit$${Math.random().toFixed(9).slice(2)}$`,Te="?"+x,st=`<${Te}>`,_=document,k=()=>_.createComment(""),H=s=>s===null||typeof s!="object"&&typeof s!="function",le=Array.isArray,nt=s=>le(s)||typeof s?.[Symbol.iterator]=="function",te=`[
2
+ \f\r]`,M=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,Se=/-->/g,Ee=/>/g,v=RegExp(`>|${te}(?:([^\\s"'>=/]+)(${te}*=${te}*(?:[^
3
+ \f\r"'\`<>=]|("|')|))|$)`,"g"),we=/'/g,Ce=/"/g,Ne=/^(?:script|style|textarea|title)$/i,ce=s=>(e,...t)=>({_$litType$:s,strings:e,values:t}),m=ce(1),g=ce(2),Mt=ce(3),S=Symbol.for("lit-noChange"),c=Symbol.for("lit-nothing"),Pe=new WeakMap,A=_.createTreeWalker(_,129);function Oe(s,e){if(!le(s)||!s.hasOwnProperty("raw"))throw Error("invalid template strings array");return _e!==void 0?_e.createHTML(e):e}var ot=(s,e)=>{let t=s.length-1,r=[],n,o=e===2?"<svg>":e===3?"<math>":"",i=M;for(let a=0;a<t;a++){let l=s[a],p,h,d=-1,f=0;for(;f<l.length&&(i.lastIndex=f,h=i.exec(l),h!==null);)f=i.lastIndex,i===M?h[1]==="!--"?i=Se:h[1]!==void 0?i=Ee:h[2]!==void 0?(Ne.test(h[2])&&(n=RegExp("</"+h[2],"g")),i=v):h[3]!==void 0&&(i=v):i===v?h[0]===">"?(i=n??M,d=-1):h[1]===void 0?d=-2:(d=i.lastIndex-h[2].length,p=h[1],i=h[3]===void 0?v:h[3]==='"'?Ce:we):i===Ce||i===we?i=v:i===Se||i===Ee?i=M:(i=v,n=void 0);let b=i===v&&s[a+1].startsWith("/>")?" ":"";o+=i===M?l+st:d>=0?(r.push(p),l.slice(0,d)+Re+l.slice(d)+x+b):l+x+(d===-2?a:b)}return[Oe(s,o+(s[t]||"<?>")+(e===2?"</svg>":e===3?"</math>":"")),r]},L=class s{constructor({strings:e,_$litType$:t},r){let n;this.parts=[];let o=0,i=0,a=e.length-1,l=this.parts,[p,h]=ot(e,t);if(this.el=s.createElement(p,r),A.currentNode=this.el.content,t===2||t===3){let d=this.el.content.firstChild;d.replaceWith(...d.childNodes)}for(;(n=A.nextNode())!==null&&l.length<a;){if(n.nodeType===1){if(n.hasAttributes())for(let d of n.getAttributeNames())if(d.endsWith(Re)){let f=h[i++],b=n.getAttribute(d).split(x),B=/([.?@])?(.*)/.exec(f);l.push({type:1,index:o,name:B[2],strings:b,ctor:B[1]==="."?se:B[1]==="?"?ne:B[1]==="@"?oe:P}),n.removeAttribute(d)}else d.startsWith(x)&&(l.push({type:6,index:o}),n.removeAttribute(d));if(Ne.test(n.tagName)){let d=n.textContent.split(x),f=d.length-1;if(f>0){n.textContent=V?V.emptyScript:"";for(let b=0;b<f;b++)n.append(d[b],k()),A.nextNode(),l.push({type:2,index:++o});n.append(d[f],k())}}}else if(n.nodeType===8)if(n.data===Te)l.push({type:2,index:o});else{let d=-1;for(;(d=n.data.indexOf(x,d+1))!==-1;)l.push({type:7,index:o}),d+=x.length-1}o++}}static createElement(e,t){let r=_.createElement("template");return r.innerHTML=e,r}};function C(s,e,t=s,r){if(e===S)return e;let n=r!==void 0?t._$Co?.[r]:t._$Cl,o=H(e)?void 0:e._$litDirective$;return n?.constructor!==o&&(n?._$AO?.(!1),o===void 0?n=void 0:(n=new o(s),n._$AT(s,t,r)),r!==void 0?(t._$Co??=[])[r]=n:t._$Cl=n),n!==void 0&&(e=C(s,n._$AS(s,e.values),n,r)),e}var re=class{constructor(e,t){this._$AV=[],this._$AN=void 0,this._$AD=e,this._$AM=t}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(e){let{el:{content:t},parts:r}=this._$AD,n=(e?.creationScope??_).importNode(t,!0);A.currentNode=n;let o=A.nextNode(),i=0,a=0,l=r[0];for(;l!==void 0;){if(i===l.index){let p;l.type===2?p=new U(o,o.nextSibling,this,e):l.type===1?p=new l.ctor(o,l.name,l.strings,this,e):l.type===6&&(p=new ie(o,this,e)),this._$AV.push(p),l=r[++a]}i!==l?.index&&(o=A.nextNode(),i++)}return A.currentNode=_,n}p(e){let t=0;for(let r of this._$AV)r!==void 0&&(r.strings!==void 0?(r._$AI(e,r,t),t+=r.strings.length-2):r._$AI(e[t])),t++}},U=class s{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(e,t,r,n){this.type=2,this._$AH=c,this._$AN=void 0,this._$AA=e,this._$AB=t,this._$AM=r,this.options=n,this._$Cv=n?.isConnected??!0}get parentNode(){let e=this._$AA.parentNode,t=this._$AM;return t!==void 0&&e?.nodeType===11&&(e=t.parentNode),e}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(e,t=this){e=C(this,e,t),H(e)?e===c||e==null||e===""?(this._$AH!==c&&this._$AR(),this._$AH=c):e!==this._$AH&&e!==S&&this._(e):e._$litType$!==void 0?this.$(e):e.nodeType!==void 0?this.T(e):nt(e)?this.k(e):this._(e)}O(e){return this._$AA.parentNode.insertBefore(e,this._$AB)}T(e){this._$AH!==e&&(this._$AR(),this._$AH=this.O(e))}_(e){this._$AH!==c&&H(this._$AH)?this._$AA.nextSibling.data=e:this.T(_.createTextNode(e)),this._$AH=e}$(e){let{values:t,_$litType$:r}=e,n=typeof r=="number"?this._$AC(e):(r.el===void 0&&(r.el=L.createElement(Oe(r.h,r.h[0]),this.options)),r);if(this._$AH?._$AD===n)this._$AH.p(t);else{let o=new re(n,this),i=o.u(this.options);o.p(t),this.T(i),this._$AH=o}}_$AC(e){let t=Pe.get(e.strings);return t===void 0&&Pe.set(e.strings,t=new L(e)),t}k(e){le(this._$AH)||(this._$AH=[],this._$AR());let t=this._$AH,r,n=0;for(let o of e)n===t.length?t.push(r=new s(this.O(k()),this.O(k()),this,this.options)):r=t[n],r._$AI(o),n++;n<t.length&&(this._$AR(r&&r._$AB.nextSibling,n),t.length=n)}_$AR(e=this._$AA.nextSibling,t){for(this._$AP?.(!1,!0,t);e!==this._$AB;){let r=Ae(e).nextSibling;Ae(e).remove(),e=r}}setConnected(e){this._$AM===void 0&&(this._$Cv=e,this._$AP?.(e))}},P=class{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(e,t,r,n,o){this.type=1,this._$AH=c,this._$AN=void 0,this.element=e,this.name=t,this._$AM=n,this.options=o,r.length>2||r[0]!==""||r[1]!==""?(this._$AH=Array(r.length-1).fill(new String),this.strings=r):this._$AH=c}_$AI(e,t=this,r,n){let o=this.strings,i=!1;if(o===void 0)e=C(this,e,t,0),i=!H(e)||e!==this._$AH&&e!==S,i&&(this._$AH=e);else{let a=e,l,p;for(e=o[0],l=0;l<o.length-1;l++)p=C(this,a[r+l],t,l),p===S&&(p=this._$AH[l]),i||=!H(p)||p!==this._$AH[l],p===c?e=c:e!==c&&(e+=(p??"")+o[l+1]),this._$AH[l]=p}i&&!n&&this.j(e)}j(e){e===c?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,e??"")}},se=class extends P{constructor(){super(...arguments),this.type=3}j(e){this.element[this.name]=e===c?void 0:e}},ne=class extends P{constructor(){super(...arguments),this.type=4}j(e){this.element.toggleAttribute(this.name,!!e&&e!==c)}},oe=class extends P{constructor(e,t,r,n,o){super(e,t,r,n,o),this.type=5}_$AI(e,t=this){if((e=C(this,e,t,0)??c)===S)return;let r=this._$AH,n=e===c&&r!==c||e.capture!==r.capture||e.once!==r.once||e.passive!==r.passive,o=e!==c&&(r===c||n);n&&this.element.removeEventListener(this.name,this,r),o&&this.element.addEventListener(this.name,this,e),this._$AH=e}handleEvent(e){typeof this._$AH=="function"?this._$AH.call(this.options?.host??this.element,e):this._$AH.handleEvent(e)}},ie=class{constructor(e,t,r){this.element=e,this.type=6,this._$AN=void 0,this._$AM=t,this.options=r}get _$AU(){return this._$AM._$AU}_$AI(e){C(this,e)}};var it=ae.litHtmlPolyfillSupport;it?.(L,U),(ae.litHtmlVersions??=[]).push("3.3.2");var Me=(s,e,t)=>{let r=t?.renderBefore??e,n=r._$litPart$;if(n===void 0){let o=t?.renderBefore??null;r._$litPart$=n=new U(e.insertBefore(k(),o),o,void 0,t??{})}return n._$AI(s),n};var de=globalThis,$=class extends y{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){let e=super.createRenderRoot();return this.renderOptions.renderBefore??=e.firstChild,e}update(e){let t=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(e),this._$Do=Me(t,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return S}};$._$litElement$=!0,$.finalized=!0,de.litElementHydrateSupport?.({LitElement:$});var at=de.litElementPolyfillSupport;at?.({LitElement:$});(de.litElementVersions??=[]).push("4.2.2");var ke=s=>(e,t)=>{t!==void 0?t.addInitializer(()=>{customElements.define(s,e)}):customElements.define(s,e)};var lt={attribute:!0,type:String,converter:O,reflect:!1,hasChanged:q},ct=(s=lt,e,t)=>{let{kind:r,metadata:n}=t,o=globalThis.litPropertyMetadata.get(n);if(o===void 0&&globalThis.litPropertyMetadata.set(n,o=new Map),r==="setter"&&((s=Object.create(s)).wrapped=!0),o.set(t.name,s),r==="accessor"){let{name:i}=t;return{set(a){let l=e.get.call(this);e.set.call(this,a),this.requestUpdate(i,l,s,!0,a)},init(a){return a!==void 0&&this.C(i,void 0,s,a),a}}}if(r==="setter"){let{name:i}=t;return function(a){let l=this[i];e.call(this,a),this.requestUpdate(i,l,s,!0,a)}}throw Error("Unsupported decorator location: "+r)};function pe(s){return(e,t)=>typeof t=="object"?ct(s,e,t):((r,n,o)=>{let i=n.hasOwnProperty(o);return n.constructor.createProperty(o,r),i?Object.getOwnPropertyDescriptor(n,o):void 0})(s,e,t)}var He={Sun:"\u2609",Moon:"\u263D",Mercury:"\u263F",Venus:"\u2640",Earth:"\u2641",Mars:"\u2642",Jupiter:"\u2643",Saturn:"\u2644",Uranus:"\u2645",Neptune:"\u2646",Pluto:"\u2647",Rahu:"\u260A",Ketu:"\u260B",Ascendant:"Asc",Lagna:"La",NorthNode:"\u260A",SouthNode:"\u260B","North node":"\u260A","South node":"\u260B",Chiron:"\u26B7",Lilith:"\u26B8","Black moon lilith":"\u26B8"};var dt=["Aries","Taurus","Gemini","Cancer","Leo","Virgo","Libra","Scorpio","Sagittarius","Capricorn","Aquarius","Pisces"],xr=dt.map(s=>s.toLowerCase());var Le=T`:host{font-family:var(--roxy-font-sans,system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif);color:var(--roxy-fg,#0a0a0a);font-size:var(--roxy-text-base,1rem);line-height:var(--roxy-leading-normal,1.5);animation:roxy-fade-in var(--roxy-motion-duration,.2s) var(--roxy-motion-easing,cubic-bezier(.4, 0, .2, 1)) both;background:0 0;display:block;container-type:inline-size}*,:before,:after{box-sizing:border-box}@keyframes roxy-fade-in{0%{opacity:0;transform:translateY(2px)}to{opacity:1;transform:translateY(0)}}@media (prefers-reduced-motion:reduce){:host{animation:none}}.roxy-skeleton{background:linear-gradient(90deg, var(--roxy-border,#e4e4e7) 0%, color-mix(in srgb, var(--roxy-border,#e4e4e7) 60%, transparent) 50%, var(--roxy-border,#e4e4e7) 100%);border-radius:var(--roxy-radius-md,8px);background-size:200% 100%;animation:1.4s ease-in-out infinite roxy-shimmer}@keyframes roxy-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}@media (prefers-reduced-motion:reduce){.roxy-skeleton{animation:none}}.roxy-empty{padding:var(--roxy-space-lg,1.5rem);color:var(--roxy-muted,#71717a);text-align:center;font-size:var(--roxy-text-sm,.875rem)}:host(:focus-within) .roxy-card{outline:2px solid var(--roxy-ring,#f59e0b66);outline-offset:2px}:host{font-variant-emoji:text}`;var J=4,X=9,Ie=(100+2*X)*J,pt=(100+2*X)*J;function u(s,e){return{x:(s+X)*J,y:(e+X)*J}}var I=50,ge=s=>2*I-s,he={head:{64:[45.5,11.2],61:[50,11.2],63:[54.5,11.2]},ajna:{47:[45.3,18],24:[50,18],4:[54.7,18],17:[45.6,20.6],11:[54.4,20.6],43:[50,25.3]},throat:{62:[45.5,32.3],23:[50,32.3],56:[54.5,32.3],16:[42,34.6],35:[58,34.6],12:[58,37.6],20:[42,40.6],45:[58,40.6],31:[46,42.4],8:[50,42.4],33:[54,42.4]},g:{1:[50,47.5],7:[45.6,50.3],13:[54.4,50.3],10:[40,53.3],25:[60,53.3],15:[45.6,56.6],46:[54.4,56.6],2:[50,59]},heart:{21:[62.5,58.5],51:[62.5,61.3],26:[62.5,64.1],40:[73,61.3]},spleen:{48:[20,70.6],57:[24,72.3],44:[28,74],50:[32,75.6],32:[28,77.2],28:[24,78.9],18:[20,80.6]},sacral:{5:[45.5,72.5],14:[50,72.5],29:[54.5,72.5],34:[42,75.6],27:[42,79],59:[58,79],42:[45.5,81.4],3:[50,81.4],9:[54.5,81.4]},"solar-plexus":{},root:{53:[45.5,89.9],60:[50,89.9],52:[54.5,89.9],54:[42,92.7],19:[58,92.7],38:[42,95.3],39:[58,95.3],58:[42,98],41:[58,98]}},ht={48:36,57:22,44:37,50:6,32:49,28:55,18:30};function ut(){let s={},e={};for(let[t,[r,n]]of Object.entries(he.spleen))he["solar-plexus"][ht[Number(t)]]=[ge(r),n];for(let[t,r]of Object.entries(he))for(let[n,[o,i]]of Object.entries(r))s[Number(n)]=u(o,i),e[Number(n)]=t;return{points:s,centerOf:e}}var{points:me,centerOf:Sr}=ut(),Er=Ie/2;function E(s){return s.map(([e,t])=>u(e,t))}function ue(s,e,t){return E([[I-s,e],[I+s,e],[I+s,t],[I-s,t]])}var Ue=[[18.4,68],[18.4,81.8],[34.7,74.9]],mt=[{id:"head",label:"Head",color:"gold",points:E([[40,14.3],[60,14.3],[50,6]]),labelAnchor:u(63,9),labelAlign:"start"},{id:"ajna",label:"Ajna",color:"green",points:E([[40,15.6],[60,15.6],[50,27.6]]),labelAnchor:u(62,21),labelAlign:"start"},{id:"throat",label:"Throat",color:"brown",points:ue(9.5,30.4,43.6),labelAnchor:u(83,34),labelAlign:"start"},{id:"g",label:"G",color:"gold",points:E([[50,45],[60.7,53.3],[50,61.6],[39.3,53.3]]),labelAnchor:u(13,51),labelAlign:"end"},{id:"heart",label:"Heart",color:"red",points:E([[61.5,57],[76.5,61.3],[61.5,65.6]]),labelAnchor:u(85,56),labelAlign:"start"},{id:"spleen",label:"Spleen",color:"brown",points:E(Ue),labelAnchor:u(13,70),labelAlign:"end"},{id:"sacral",label:"Sacral",color:"red",points:ue(9.5,70.6,83.6),labelAnchor:u(85,88),labelAlign:"start"},{id:"solar-plexus",label:"Solar Plexus",color:"brown",points:E(Ue.map(([s,e])=>[ge(s),e])),labelAnchor:u(87,73),labelAlign:"start"},{id:"root",label:"Root",color:"brown",points:ue(9.5,87.9,99.9),labelAnchor:u(50,103),labelAlign:"middle"}],gt=[[64,47],[61,24],[63,4],[17,62],[11,56],[43,23],[16,48],[20,34],[20,10],[7,31],[1,8],[13,33],[21,45],[12,22],[35,36],[57,20],[15,5],[2,14],[46,29],[34,10],[10,57],[25,51],[27,50],[57,34],[26,44],[18,58],[28,38],[32,54],[3,60],[9,52],[42,53],[59,6],[19,49],[39,55],[41,30],[37,40]],ft=yt();function yt(){let s=ge,e=[[50,-2],[60,-2],[60.5,9],[57,18],[56,21],[54,24],[52,27],[54,28],[64,30],[80,34],[83.5,40],[84,56],[83,74],[82,84],[76,92],[68,97],[64,99],[62,100],[60,100]],t=[`M ${W(e[0])}`];for(let r=1;r+2<e.length;r+=3)t.push(`C ${W(e[r])} ${W(e[r+1])} ${W(e[r+2])}`);t.push(`L ${K(e[e.length-1],s)}`);for(let r=e.length-3;r>=1;r-=3)t.push(`C ${K(e[r+1],s)} ${K(e[r],s)} ${K(e[r-1],s)}`);return t.push("Z"),t.join(" ")}function W([s,e]){let t=u(s,e);return`${t.x} ${t.y}`}function K([s,e],t){let r=u(t(s),e);return`${r.x} ${r.y}`}function bt(s){return s.map(e=>`${e.x},${e.y}`).join(" ")}function Be(s,e){return s<e?`${s}-${e}`:`${e}-${s}`}function xt(){return g`<path class="bg-body" d=${ft} />`}function $t(s,e){let t=[];for(let[r,n]of gt){let o=me[r],i=me[n];if(!o||!i)continue;if(t.push(g`<line class="bg-channel" x1=${o.x} y1=${o.y} x2=${i.x} y2=${i.y} />`),s.has(Be(r,n))){t.push(g`<line class="bg-channel on" x1=${o.x} y1=${o.y} x2=${i.x} y2=${i.y} />`);continue}let a={x:(o.x+i.x)/2,y:(o.y+i.y)/2};e.has(r)&&t.push(g`<line class="bg-half" x1=${o.x} y1=${o.y} x2=${a.x} y2=${a.y} />`),e.has(n)&&t.push(g`<line class="bg-half" x1=${i.x} y1=${i.y} x2=${a.x} y2=${a.y} />`)}return t}function vt(s,e,t){let r=t.x-e.x,n=t.y-e.y,o=r*r+n*n;if(o===0)return e;let i=Math.max(0,Math.min(1,((s.x-e.x)*r+(s.y-e.y)*n)/o));return{x:e.x+i*r,y:e.y+i*n}}function At(s,e){let t=e[0],r=Number.POSITIVE_INFINITY;for(let n=0;n<e.length;n++){let o=vt(s,e[n],e[(n+1)%e.length]),i=(o.x-s.x)**2+(o.y-s.y)**2;i<r&&(r=i,t=o)}return t}function _t(s){return mt.map(e=>{let t=s.has(e.id),r=`bg-center bg-${e.color}${t?" defined":""}`,n=At(e.labelAnchor,e.points);return g`<g>
4
+ <line class="bg-leader" x1=${e.labelAnchor.x} y1=${e.labelAnchor.y} x2=${n.x} y2=${n.y} />
5
+ <polygon class=${r} points=${bt(e.points)}><title>${e.label}: ${t?"defined":"open"}</title></polygon>
6
+ <text class="bg-center-label" x=${e.labelAnchor.x} y=${e.labelAnchor.y} text-anchor=${e.labelAlign} dominant-baseline="central">${e.label}</text>
7
+ </g>`})}function St(s,e){let t=[];for(let[r,n]of Object.entries(me)){let o=Number(r);if(!s.has(o))continue;let i=e.get(o);t.push(g`<text class="bg-gate" x=${n.x} y=${n.y} text-anchor="middle" dominant-baseline="central">${o}${i?g`<title>${i}</title>`:c}</text>`)}return t}function je(s,e){return Be(s,e)}var Ge=`0 0 ${Ie} ${pt}`;function De(s){return g`
8
+ ${xt()}
9
+ ${$t(s.activeChannels,s.activeGates)}
10
+ ${_t(s.definedCenters)}
11
+ ${St(s.activeGates,s.gateTitles)}
12
+ `}var Et="roxy-data";function wt(s){return s.nodeName==="SCRIPT"&&s.getAttribute("type")==="application/json"}var F=class{constructor(e){this.host=e,e.addController(this)}hostConnected(){if(this.host.data!=null)return;let e=this.read();e!==void 0&&(this.host.data=e,this.host.requestUpdate())}read(){let e=this.findInlineScript();return e?this.parse(e.textContent):void 0}findInlineScript(){for(let e of Array.from(this.host.children))if(wt(e)&&e.classList.contains(Et))return e;return null}parse(e){if(e?.trim())try{return JSON.parse(e)}catch{return}}};function ze(s){return s?s.charAt(0).toUpperCase()+s.slice(1).toLowerCase():""}var w=class extends ${constructor(){super();this.data=null;new F(this)}render(){let t=this.data;if(!t)return m`<div class="roxy-empty" role="status">No bodygraph data</div>`;let r=new Set((t.centers??[]).filter(a=>a.defined).map(a=>a.id)),n=new Set((t.gates??[]).map(a=>a.gate).filter(a=>a!=null)),o=new Set((t.channels??[]).map(a=>je(a.gateA,a.gateB))),i=this.buildGateTitles(t.gates??[]);return m`<div class="wrap"><header class="head"><h2 class="title">Bodygraph</h2>${t.type?m`<div class="type-line">${t.type}${t.profile?m`· Profile ${t.profile}`:c}</div>`:c}</header><div class="layout"><svg viewBox="${Ge}" preserveAspectRatio="xMidYMid meet" role="img" aria-label="Human Design bodygraph with nine centers, channels, and activated gates overlaid on a human silhouette"><title>Human Design bodygraph</title><desc>Nine energy centers in their canonical positions over a human silhouette, each filled with its traditional color when defined and outlined when open, wired by channels between activated gates.</desc>${De({definedCenters:r,activeChannels:o,activeGates:n,gateTitles:i})}</svg> ${this.renderSummary(t)}</div></div>`}buildGateTitles(t){let r=new Map;for(let n of t){if(n.gate==null)continue;let o=[`Gate ${n.gate}`];n.line!=null&&(o[0]+=`.${n.line}`),n.gateName&&o.push(n.gateName);let i=n.planet?ze(n.planet):"",a=i?He[i]??i:"";a&&o.push(`${a} ${n.side??""}`.trim()),r.set(n.gate,o.join(" \xB7 "))}return r}renderSummary(t){let r=[{label:"Type",value:t.type},{label:"Strategy",value:t.strategy},{label:"Authority",value:t.authority},{label:"Profile",value:t.profile},{label:"Definition",value:t.definition}],n=t.incarnationCross;return m`<div class="summary"><div class="facts">${r.map(o=>o.value?m`<div class="fact"><span>${o.label}</span> <strong>${o.value}</strong></div>`:c)}</div>${n?.name?m`<p class="cross">${n.name} ${n.gates?.length?m`<span class="gates">(${n.gates.join(", ")})</span>`:c}</p>`:c} ${t.signature||t.notSelf?m`<div class="themes">${t.signature?m`<span class="pill pill--good">Signature: ${t.signature}</span>`:c} ${t.notSelf?m`<span class="pill pill--shadow">Not-self: ${t.notSelf}</span>`:c}</div>`:c}<div class="legend"><span class="legend-caption">Center colors when defined. Open centers are outlined.</span> <span><span class="swatch bg-gold defined"></span>Head, G</span> <span><span class="swatch bg-green defined"></span>Ajna</span> <span><span class="swatch bg-brown defined"></span>Throat, Spleen, Solar Plexus, Root</span> <span><span class="swatch bg-red defined"></span>Heart, Sacral</span> <span><span class="swatch"></span>Open center</span></div></div>`}};w.styles=[Le,T`.wrap{gap:var(--roxy-space-md,1rem);display:grid}.head{justify-content:space-between;align-items:baseline;gap:var(--roxy-space-sm,.5rem);flex-wrap:wrap;display:flex}.title{font-size:var(--roxy-text-lg,1.125rem);font-weight:var(--roxy-weight-bold,600);margin:0}.type-line{color:var(--roxy-muted,#71717a);font-size:var(--roxy-text-sm,.875rem)}.layout{gap:var(--roxy-space-lg,1.5rem);grid-template-columns:minmax(0,1fr);align-items:start;display:grid}@container (width>=520px){.layout{grid-template-columns:minmax(0,340px) minmax(0,1fr)}}svg{width:100%;max-width:340px;height:auto;margin:0 auto;display:block}.bg-body{fill:color-mix(in srgb, var(--roxy-secondary,#475569) 8%, transparent);stroke:var(--roxy-border,#e4e4e7);stroke-width:1px}.bg-channel{stroke:var(--roxy-secondary,#475569);stroke-width:1.6px;opacity:.3}.bg-channel.on{stroke-width:3.4px;stroke-linecap:round;opacity:1}.bg-half{stroke:var(--roxy-secondary,#475569);stroke-width:3.2px;stroke-linecap:round;opacity:.9}.bg-leader{stroke:var(--roxy-muted,#71717a);stroke-width:1px;opacity:.5}.bg-center{fill:#0000;stroke:var(--roxy-secondary,#475569);stroke-width:1.8px}.bg-center.defined{stroke:#00000073}.bg-center.bg-gold.defined{fill:#e0a200}.bg-center.bg-green.defined{fill:#2f8f00}.bg-center.bg-red.defined{fill:#c41f1f}.bg-center.bg-brown.defined{fill:#76502f}.bg-center-label{fill:var(--roxy-muted,#71717a);font-size:11px;font-family:var(--roxy-font-sans)}.bg-gate{fill:var(--roxy-fg,#0a0a0a);font-size:8px;font-weight:600;font-family:var(--roxy-font-sans);paint-order:stroke;stroke:var(--roxy-bg,#fff);stroke-width:1.6px;stroke-linejoin:round}.summary{gap:var(--roxy-space-md,1rem);display:grid}.facts{gap:var(--roxy-space-sm,.5rem);grid-template-columns:repeat(auto-fit,minmax(8rem,1fr));display:grid}.fact{border:1px solid var(--roxy-border,#e4e4e7);border-radius:var(--roxy-radius-md,8px);padding:var(--roxy-space-sm,.5rem) var(--roxy-space-md,1rem);background:var(--roxy-bg,#fff)}.fact span{color:var(--roxy-muted,#71717a);font-size:var(--roxy-text-xs,.75rem);text-transform:uppercase;letter-spacing:.06em;display:block}.fact strong{font-size:var(--roxy-text-base,1rem);color:var(--roxy-fg,#0a0a0a)}.cross{font-size:var(--roxy-text-sm,.875rem);color:var(--roxy-fg,#0a0a0a);border-left:2px solid var(--roxy-accent,#f59e0b);padding-left:var(--roxy-space-sm,.5rem);margin:0}.cross .gates{color:var(--roxy-muted,#71717a);font-variant-numeric:tabular-nums}.themes{gap:var(--roxy-space-sm,.5rem);flex-wrap:wrap;display:flex}.pill{border-radius:var(--roxy-radius-full,9999px);font-size:var(--roxy-text-xs,.75rem);padding:2px 10px}.pill--good{background:color-mix(in srgb, var(--roxy-success,#16a34a) 16%, transparent);color:var(--roxy-success-fg,#166534)}.pill--shadow{background:color-mix(in srgb, var(--roxy-danger,#dc2626) 16%, transparent);color:var(--roxy-danger-fg,#991b1b)}.legend{gap:var(--roxy-space-sm,.5rem) var(--roxy-space-md,1rem);font-size:var(--roxy-text-xs,.75rem);color:var(--roxy-muted,#71717a);flex-wrap:wrap;display:flex}.legend-caption{color:var(--roxy-muted,#71717a);flex-basis:100%}.legend .swatch{vertical-align:middle;border:1px solid var(--roxy-secondary,#475569);border-radius:2px;width:10px;height:10px;margin-right:4px;display:inline-block}.legend .swatch.defined{border-color:#00000073}.legend .swatch.bg-gold{background:#e0a200}.legend .swatch.bg-green{background:#2f8f00}.legend .swatch.bg-red{background:#c41f1f}.legend .swatch.bg-brown{background:#76502f}`],Z([pe({attribute:!1})],w.prototype,"data",2),w=Z([ke("roxy-bodygraph")],w);return Ke(Ct);})();
13
+ /*! Bundled license information:
14
+
15
+ @lit/reactive-element/css-tag.js:
16
+ (**
17
+ * @license
18
+ * Copyright 2019 Google LLC
19
+ * SPDX-License-Identifier: BSD-3-Clause
20
+ *)
21
+
22
+ @lit/reactive-element/reactive-element.js:
23
+ lit-html/lit-html.js:
24
+ lit-element/lit-element.js:
25
+ @lit/reactive-element/decorators/custom-element.js:
26
+ @lit/reactive-element/decorators/property.js:
27
+ @lit/reactive-element/decorators/state.js:
28
+ @lit/reactive-element/decorators/event-options.js:
29
+ @lit/reactive-element/decorators/base.js:
30
+ @lit/reactive-element/decorators/query.js:
31
+ @lit/reactive-element/decorators/query-all.js:
32
+ @lit/reactive-element/decorators/query-async.js:
33
+ @lit/reactive-element/decorators/query-assigned-nodes.js:
34
+ (**
35
+ * @license
36
+ * Copyright 2017 Google LLC
37
+ * SPDX-License-Identifier: BSD-3-Clause
38
+ *)
39
+
40
+ lit-html/is-server.js:
41
+ (**
42
+ * @license
43
+ * Copyright 2022 Google LLC
44
+ * SPDX-License-Identifier: BSD-3-Clause
45
+ *)
46
+
47
+ @lit/reactive-element/decorators/query-assigned-elements.js:
48
+ (**
49
+ * @license
50
+ * Copyright 2021 Google LLC
51
+ * SPDX-License-Identifier: BSD-3-Clause
52
+ *)
53
+ */
54
+ //# sourceMappingURL=bodygraph.js.map