@roxyapi/ui 0.11.0 → 0.12.0
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.
- package/AGENTS.md +6 -0
- package/README.md +6 -0
- package/components-catalog.json +111 -1
- package/dist/cdn/components/astrocartography-map.js +58 -0
- package/dist/cdn/components/astrocartography-map.js.map +7 -0
- package/dist/cdn/components/divisional-chart.js +7 -7
- package/dist/cdn/components/divisional-chart.js.map +1 -1
- package/dist/cdn/components/dosha-card.js +2 -2
- package/dist/cdn/components/dosha-card.js.map +3 -3
- package/dist/cdn/components/fixed-stars.js +52 -0
- package/dist/cdn/components/fixed-stars.js.map +7 -0
- package/dist/cdn/components/hd-variables.js +2 -2
- package/dist/cdn/components/hd-variables.js.map +3 -3
- package/dist/cdn/components/hexagram.js +3 -3
- package/dist/cdn/components/hexagram.js.map +3 -3
- package/dist/cdn/components/local-space-compass.js +58 -0
- package/dist/cdn/components/local-space-compass.js.map +7 -0
- package/dist/cdn/components/moon-phase.js +3 -3
- package/dist/cdn/components/moon-phase.js.map +3 -3
- package/dist/cdn/components/natal-chart.js +8 -8
- package/dist/cdn/components/natal-chart.js.map +2 -2
- package/dist/cdn/components/positions-table.js +52 -0
- package/dist/cdn/components/positions-table.js.map +7 -0
- package/dist/cdn/components/profection-card.js +52 -0
- package/dist/cdn/components/profection-card.js.map +7 -0
- package/dist/cdn/components/reference-card.js +3 -3
- package/dist/cdn/components/reference-card.js.map +3 -3
- package/dist/cdn/components/relocation-wheel.js +61 -0
- package/dist/cdn/components/relocation-wheel.js.map +7 -0
- package/dist/cdn/components/synastry-chart.js +4 -4
- package/dist/cdn/components/synastry-chart.js.map +2 -2
- package/dist/cdn/components/vedic-kundli.js +5 -5
- package/dist/cdn/components/vedic-kundli.js.map +1 -1
- package/dist/cdn/components/vedic-planets-table.js +2 -2
- package/dist/cdn/components/vedic-planets-table.js.map +1 -1
- package/dist/cdn/components/western-planets-table.js +2 -2
- package/dist/cdn/components/western-planets-table.js.map +1 -1
- package/dist/cdn/components/yoga-list.js +3 -3
- package/dist/cdn/components/yoga-list.js.map +3 -3
- package/dist/cdn/roxy-ui.js +83 -71
- package/dist/cdn/roxy-ui.js.map +4 -4
- package/dist/components/astrocartography-map.d.ts +27 -0
- package/dist/components/astrocartography-map.d.ts.map +1 -0
- package/dist/components/astrocartography-map.js +8 -0
- package/dist/components/astrocartography-map.js.map +7 -0
- package/dist/components/divisional-chart.js +22 -22
- package/dist/components/divisional-chart.js.map +1 -1
- package/dist/components/dosha-card.d.ts.map +1 -1
- package/dist/components/dosha-card.js +1 -1
- package/dist/components/dosha-card.js.map +3 -3
- package/dist/components/fixed-stars.d.ts +21 -0
- package/dist/components/fixed-stars.d.ts.map +1 -0
- package/dist/components/fixed-stars.js +2 -0
- package/dist/components/fixed-stars.js.map +7 -0
- package/dist/components/hd-variables.d.ts.map +1 -1
- package/dist/components/hd-variables.js +1 -1
- package/dist/components/hd-variables.js.map +3 -3
- package/dist/components/hexagram.d.ts +3 -1
- package/dist/components/hexagram.d.ts.map +1 -1
- package/dist/components/hexagram.js +1 -1
- package/dist/components/hexagram.js.map +3 -3
- package/dist/components/local-space-compass.d.ts +23 -0
- package/dist/components/local-space-compass.d.ts.map +1 -0
- package/dist/components/local-space-compass.js +8 -0
- package/dist/components/local-space-compass.js.map +7 -0
- package/dist/components/moon-phase.d.ts.map +1 -1
- package/dist/components/moon-phase.js +1 -1
- package/dist/components/moon-phase.js.map +3 -3
- package/dist/components/natal-chart.d.ts +2 -0
- package/dist/components/natal-chart.d.ts.map +1 -1
- package/dist/components/natal-chart.js +6 -6
- package/dist/components/natal-chart.js.map +2 -2
- package/dist/components/positions-table.d.ts +34 -0
- package/dist/components/positions-table.d.ts.map +1 -0
- package/dist/components/positions-table.js +2 -0
- package/dist/components/positions-table.js.map +7 -0
- package/dist/components/profection-card.d.ts +18 -0
- package/dist/components/profection-card.d.ts.map +1 -0
- package/dist/components/profection-card.js +2 -0
- package/dist/components/profection-card.js.map +7 -0
- package/dist/components/reference-card.d.ts.map +1 -1
- package/dist/components/reference-card.js +1 -1
- package/dist/components/reference-card.js.map +3 -3
- package/dist/components/relocation-wheel.d.ts +21 -0
- package/dist/components/relocation-wheel.d.ts.map +1 -0
- package/dist/components/relocation-wheel.js +11 -0
- package/dist/components/relocation-wheel.js.map +7 -0
- package/dist/components/synastry-chart.js +3 -3
- package/dist/components/synastry-chart.js.map +2 -2
- package/dist/components/vedic-kundli.js +14 -14
- package/dist/components/vedic-kundli.js.map +1 -1
- package/dist/components/vedic-planets-table.js +1 -1
- package/dist/components/vedic-planets-table.js.map +1 -1
- package/dist/components/western-planets-table.js +1 -1
- package/dist/components/western-planets-table.js.map +1 -1
- package/dist/components/yoga-list.d.ts +5 -2
- package/dist/components/yoga-list.d.ts.map +1 -1
- package/dist/components/yoga-list.js +1 -1
- package/dist/components/yoga-list.js.map +3 -3
- package/dist/generated/endpoint-bindings.d.ts.map +1 -1
- package/dist/index.cjs +62 -50
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +62 -50
- package/dist/index.js.map +4 -4
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.json +6 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/types.gen.d.ts +7864 -5381
- package/dist/types/types.gen.d.ts.map +1 -1
- package/dist/utils/degree.d.ts +2 -0
- package/dist/utils/degree.d.ts.map +1 -1
- package/dist/utils/planet-color.d.ts +3 -0
- package/dist/utils/planet-color.d.ts.map +1 -0
- package/dist/version.d.ts +1 -1
- package/package.json +2 -1
- package/src/components/astrocartography-map.ts +436 -0
- package/src/components/dosha-card.ts +48 -16
- package/src/components/fixed-stars.ts +254 -0
- package/src/components/hd-variables.ts +30 -2
- package/src/components/hexagram.ts +11 -11
- package/src/components/local-space-compass.ts +299 -0
- package/src/components/moon-phase.ts +21 -2
- package/src/components/natal-chart.ts +36 -24
- package/src/components/positions-table.ts +442 -0
- package/src/components/profection-card.ts +173 -0
- package/src/components/reference-card.ts +40 -8
- package/src/components/relocation-wheel.ts +170 -0
- package/src/components/yoga-list.ts +95 -2
- package/src/generated/endpoint-bindings.ts +62 -0
- package/src/index.ts +6 -0
- package/src/manifest.ts +79 -0
- package/src/types/index.ts +1 -1
- package/src/types/types.gen.ts +7814 -5263
- package/src/utils/degree.ts +11 -0
- package/src/utils/planet-color.ts +45 -0
- package/src/version.ts +1 -1
|
@@ -40,7 +40,15 @@ const PROSE_KEYS = new Set([
|
|
|
40
40
|
'motto',
|
|
41
41
|
]);
|
|
42
42
|
/** Keys never shown as their own row/section (rendered elsewhere or noise). */
|
|
43
|
-
const SKIP_KEYS = new Set(['id', 'symbol',
|
|
43
|
+
const SKIP_KEYS = new Set(['id', 'symbol', ...TITLE_KEYS]);
|
|
44
|
+
|
|
45
|
+
/** Best-effort one-line label for an object inside an array (e.g. a gate channel partner), joining its primitive values so it never renders as [object Object]. */
|
|
46
|
+
function objectLabel(obj: Record<string, unknown>): string {
|
|
47
|
+
return Object.values(obj)
|
|
48
|
+
.filter((v) => typeof v === 'string' || typeof v === 'number')
|
|
49
|
+
.map(String)
|
|
50
|
+
.join(' · ');
|
|
51
|
+
}
|
|
44
52
|
|
|
45
53
|
@customElement('roxy-reference-card')
|
|
46
54
|
export class RoxyReferenceCard extends RoxyDataElement<ReferenceData> {
|
|
@@ -140,17 +148,41 @@ export class RoxyReferenceCard extends RoxyDataElement<ReferenceData> {
|
|
|
140
148
|
const prose: Array<[string, string]> = [];
|
|
141
149
|
const lists: Array<[string, string[]]> = [];
|
|
142
150
|
const facts: Array<[string, string]> = [];
|
|
143
|
-
|
|
144
|
-
|
|
151
|
+
// Bucket each field into prose / chip-list / fact. Recurses one level into
|
|
152
|
+
// nested objects (description {short,long}, keywords {positive,negative},
|
|
153
|
+
// meaning {...}, ichingHexagram {number,english}) and labels object-array
|
|
154
|
+
// items by their primitives, so nested content is never dropped and an array
|
|
155
|
+
// of objects never stringifies to [object Object].
|
|
156
|
+
const collect = (label: string, value: unknown, depth: number): void => {
|
|
157
|
+
if (value == null) return;
|
|
145
158
|
if (Array.isArray(value)) {
|
|
146
|
-
const items = value
|
|
147
|
-
|
|
159
|
+
const items = value
|
|
160
|
+
.filter((v) => v != null)
|
|
161
|
+
.map((v) =>
|
|
162
|
+
typeof v === 'object'
|
|
163
|
+
? objectLabel(v as Record<string, unknown>)
|
|
164
|
+
: String(v),
|
|
165
|
+
)
|
|
166
|
+
.filter((s) => s.length > 0);
|
|
167
|
+
if (items.length > 0) lists.push([label, items]);
|
|
148
168
|
} else if (typeof value === 'string') {
|
|
149
|
-
if (PROSE_KEYS.has(
|
|
150
|
-
|
|
169
|
+
if (PROSE_KEYS.has(label) || value.length > 48)
|
|
170
|
+
prose.push([label, value]);
|
|
171
|
+
else facts.push([label, value]);
|
|
151
172
|
} else if (typeof value === 'number' || typeof value === 'boolean') {
|
|
152
|
-
facts.push([
|
|
173
|
+
facts.push([label, String(value)]);
|
|
174
|
+
} else if (typeof value === 'object' && depth < 2) {
|
|
175
|
+
for (const [k, v] of Object.entries(value as Record<string, unknown>)) {
|
|
176
|
+
collect(`${label} ${k}`, v, depth + 1);
|
|
177
|
+
}
|
|
153
178
|
}
|
|
179
|
+
};
|
|
180
|
+
for (const [key, value] of Object.entries(rec)) {
|
|
181
|
+
if (SKIP_KEYS.has(key)) continue;
|
|
182
|
+
// The hero chip row already shows a top-level keywords ARRAY; an object
|
|
183
|
+
// keywords ({positive,negative}) falls through to collect() instead.
|
|
184
|
+
if (key === 'keywords' && Array.isArray(value)) continue;
|
|
185
|
+
collect(key, value, 0);
|
|
154
186
|
}
|
|
155
187
|
|
|
156
188
|
return html`<article class="card" aria-label=${title}>
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { css, html, nothing } from 'lit';
|
|
2
|
+
import { customElement } from 'lit/decorators.js';
|
|
3
|
+
// Registers <roxy-natal-chart>, reused below as the wheel renderer. The
|
|
4
|
+
// relocation response is structurally a natal chart (same planets, houses, and
|
|
5
|
+
// angles), so the wheel is shared rather than duplicated.
|
|
6
|
+
import './natal-chart.js';
|
|
7
|
+
import { PLANET_GLYPH } from '../tokens/index.js';
|
|
8
|
+
import type {
|
|
9
|
+
NatalChartResponse,
|
|
10
|
+
RelocationChartResponse,
|
|
11
|
+
} from '../types/index.js';
|
|
12
|
+
import { RoxyDataElement } from '../utils/base-element.js';
|
|
13
|
+
import { baseStyles } from '../utils/base-styles.js';
|
|
14
|
+
import { capitalize } from '../utils/string.js';
|
|
15
|
+
|
|
16
|
+
type HouseChange =
|
|
17
|
+
RelocationChartResponse['changes']['planetsChangedHouse'][number];
|
|
18
|
+
|
|
19
|
+
const glyphFor = (name: string): string =>
|
|
20
|
+
PLANET_GLYPH[capitalize(name)] ?? PLANET_GLYPH[name] ?? '';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Relocation chart. The birth instant is unchanged, so every planet keeps its
|
|
24
|
+
* natal sign and degree while the houses and angles are recomputed for a new
|
|
25
|
+
* place. Reuses {@link RoxyNatalChart} for the wheel (identical data shape) and
|
|
26
|
+
* adds the relocation read: the move geometry, the planets that change house,
|
|
27
|
+
* and the bodies pulled onto a relocated angle.
|
|
28
|
+
*/
|
|
29
|
+
@customElement('roxy-relocation-wheel')
|
|
30
|
+
export class RoxyRelocationWheel extends RoxyDataElement<RelocationChartResponse> {
|
|
31
|
+
static styles = [
|
|
32
|
+
baseStyles,
|
|
33
|
+
css`
|
|
34
|
+
.stack {
|
|
35
|
+
display: grid;
|
|
36
|
+
gap: var(--roxy-space-md, 1rem);
|
|
37
|
+
}
|
|
38
|
+
.changes {
|
|
39
|
+
background: var(--roxy-surface, #fff);
|
|
40
|
+
color: var(--roxy-fg, #0a0a0a);
|
|
41
|
+
border: 1px solid var(--roxy-border, #e4e4e7);
|
|
42
|
+
border-radius: var(--roxy-radius-md, 8px);
|
|
43
|
+
padding: var(--roxy-space-lg, 1.5rem);
|
|
44
|
+
box-shadow: var(--roxy-shadow-sm);
|
|
45
|
+
display: grid;
|
|
46
|
+
gap: var(--roxy-space-md, 1rem);
|
|
47
|
+
}
|
|
48
|
+
.title {
|
|
49
|
+
font-size: var(--roxy-text-lg, 1.125rem);
|
|
50
|
+
font-weight: var(--roxy-weight-bold, 600);
|
|
51
|
+
margin: 0;
|
|
52
|
+
color: var(--roxy-primary, #0f172a);
|
|
53
|
+
}
|
|
54
|
+
.move {
|
|
55
|
+
display: flex;
|
|
56
|
+
flex-wrap: wrap;
|
|
57
|
+
gap: var(--roxy-space-xs, 0.25rem) var(--roxy-space-md, 1rem);
|
|
58
|
+
font-size: var(--roxy-text-sm, 0.875rem);
|
|
59
|
+
color: var(--roxy-muted, #71717a);
|
|
60
|
+
}
|
|
61
|
+
.summary {
|
|
62
|
+
font-size: var(--roxy-text-sm, 0.875rem);
|
|
63
|
+
color: var(--roxy-fg, #0a0a0a);
|
|
64
|
+
margin: 0;
|
|
65
|
+
}
|
|
66
|
+
.block-label {
|
|
67
|
+
font-size: var(--roxy-text-xs, 0.75rem);
|
|
68
|
+
font-weight: 600;
|
|
69
|
+
text-transform: uppercase;
|
|
70
|
+
letter-spacing: 0.06em;
|
|
71
|
+
color: var(--roxy-muted, #71717a);
|
|
72
|
+
margin: 0 0 var(--roxy-space-xs, 0.25rem);
|
|
73
|
+
}
|
|
74
|
+
.chips {
|
|
75
|
+
display: flex;
|
|
76
|
+
flex-wrap: wrap;
|
|
77
|
+
gap: var(--roxy-space-xs, 0.25rem);
|
|
78
|
+
}
|
|
79
|
+
.chip {
|
|
80
|
+
padding: 2px 10px;
|
|
81
|
+
border-radius: var(--roxy-radius-full, 9999px);
|
|
82
|
+
font-size: var(--roxy-text-xs, 0.75rem);
|
|
83
|
+
background: color-mix(in srgb, var(--roxy-accent, #f59e0b) 16%, transparent);
|
|
84
|
+
color: var(--roxy-fg, #0a0a0a);
|
|
85
|
+
}
|
|
86
|
+
.moves-list {
|
|
87
|
+
list-style: none;
|
|
88
|
+
margin: 0;
|
|
89
|
+
padding: 0;
|
|
90
|
+
display: grid;
|
|
91
|
+
gap: 2px;
|
|
92
|
+
}
|
|
93
|
+
.moves-list li {
|
|
94
|
+
font-size: var(--roxy-text-sm, 0.875rem);
|
|
95
|
+
color: var(--roxy-fg, #0a0a0a);
|
|
96
|
+
}
|
|
97
|
+
.moves-list .arrow {
|
|
98
|
+
color: var(--roxy-muted, #71717a);
|
|
99
|
+
}
|
|
100
|
+
.empty-note {
|
|
101
|
+
font-size: var(--roxy-text-sm, 0.875rem);
|
|
102
|
+
color: var(--roxy-muted, #71717a);
|
|
103
|
+
margin: 0;
|
|
104
|
+
}
|
|
105
|
+
`,
|
|
106
|
+
];
|
|
107
|
+
|
|
108
|
+
protected renderEmpty() {
|
|
109
|
+
return html`<div class="roxy-empty" role="status">No relocation data</div>`;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
protected renderData(data: RelocationChartResponse) {
|
|
113
|
+
const c = data.changes;
|
|
114
|
+
return html`<div class="stack">
|
|
115
|
+
<roxy-natal-chart
|
|
116
|
+
heading="Relocation chart"
|
|
117
|
+
.data=${data as unknown as NatalChartResponse}
|
|
118
|
+
></roxy-natal-chart>
|
|
119
|
+
<section class="changes">
|
|
120
|
+
<h3 class="title">What changes at this location</h3>
|
|
121
|
+
<div class="move">
|
|
122
|
+
${
|
|
123
|
+
typeof c?.distanceKm === 'number'
|
|
124
|
+
? html`<span>${Math.round(c.distanceKm).toLocaleString()} km ${c.direction ?? ''} of birthplace</span>`
|
|
125
|
+
: nothing
|
|
126
|
+
}
|
|
127
|
+
${
|
|
128
|
+
c
|
|
129
|
+
? html`<span>Ascendant ${c.ascendantSignChanged ? 'changes sign' : 'keeps its sign'}</span>`
|
|
130
|
+
: nothing
|
|
131
|
+
}
|
|
132
|
+
</div>
|
|
133
|
+
${
|
|
134
|
+
data.interpretation?.summary
|
|
135
|
+
? html`<p class="summary">${data.interpretation.summary}</p>`
|
|
136
|
+
: nothing
|
|
137
|
+
}
|
|
138
|
+
${
|
|
139
|
+
c?.angularPlanets?.length
|
|
140
|
+
? html`<div>
|
|
141
|
+
<p class="block-label">Angular planets here</p>
|
|
142
|
+
<div class="chips">
|
|
143
|
+
${c.angularPlanets.map((p) => html`<span class="chip">${glyphFor(p)} ${p}</span>`)}
|
|
144
|
+
</div>
|
|
145
|
+
</div>`
|
|
146
|
+
: nothing
|
|
147
|
+
}
|
|
148
|
+
<div>
|
|
149
|
+
<p class="block-label">Planets that change house</p>
|
|
150
|
+
${
|
|
151
|
+
c?.planetsChangedHouse?.length
|
|
152
|
+
? html`<ul class="moves-list">
|
|
153
|
+
${c.planetsChangedHouse.map(
|
|
154
|
+
(m: HouseChange) =>
|
|
155
|
+
html`<li>${glyphFor(m.planet)} ${m.planet}: house ${m.natalHouse} <span class="arrow">to</span> ${m.relocatedHouse}</li>`,
|
|
156
|
+
)}
|
|
157
|
+
</ul>`
|
|
158
|
+
: html`<p class="empty-note">No planet changes house at this location.</p>`
|
|
159
|
+
}
|
|
160
|
+
</div>
|
|
161
|
+
</section>
|
|
162
|
+
</div>`;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
declare global {
|
|
167
|
+
interface HTMLElementTagNameMap {
|
|
168
|
+
'roxy-relocation-wheel': RoxyRelocationWheel;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -15,12 +15,13 @@ type YogaListData =
|
|
|
15
15
|
| { yogas: Array<GetYogaResponse> };
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
* Yoga catalog and detail renderer. Accepts
|
|
18
|
+
* Yoga catalog and detail renderer. Accepts four data modes:
|
|
19
19
|
* - Catalog: ListYogasResponse (yogas array of {id, name} + total)
|
|
20
20
|
* - Detail: GetYogaResponse (single yoga with description, result, quality)
|
|
21
21
|
* - Detail array: { yogas: Array<GetYogaResponse> } for pre-filtered sets
|
|
22
|
+
* - Detect: DetectYogasResponse (each yoga carries a present verdict + evidence); present yogas render first, each badged present/absent with its classical evidence
|
|
22
23
|
*
|
|
23
|
-
*
|
|
24
|
+
* All multi-item modes include a live search filter.
|
|
24
25
|
*/
|
|
25
26
|
@customElement('roxy-yoga-list')
|
|
26
27
|
export class RoxyYogaList extends RoxyDataElement<YogaListData> {
|
|
@@ -132,6 +133,30 @@ export class RoxyYogaList extends RoxyDataElement<YogaListData> {
|
|
|
132
133
|
color: var(--roxy-warning-fg, #b45309);
|
|
133
134
|
border: 1px solid color-mix(in srgb, var(--roxy-warning, #f59e0b) 40%, transparent);
|
|
134
135
|
}
|
|
136
|
+
.present-badge {
|
|
137
|
+
display: inline-block;
|
|
138
|
+
font-size: var(--roxy-text-xs, 0.75rem);
|
|
139
|
+
font-weight: 600;
|
|
140
|
+
padding: 0.15em 0.6em;
|
|
141
|
+
border-radius: 999px;
|
|
142
|
+
}
|
|
143
|
+
.present-badge.is-present {
|
|
144
|
+
background: color-mix(in srgb, var(--roxy-success, #16a34a) 16%, transparent);
|
|
145
|
+
color: var(--roxy-success-fg, #166534);
|
|
146
|
+
}
|
|
147
|
+
.present-badge.is-absent {
|
|
148
|
+
background: color-mix(in srgb, var(--roxy-border, #e4e4e7) 55%, transparent);
|
|
149
|
+
color: var(--roxy-fg, #0a0a0a);
|
|
150
|
+
}
|
|
151
|
+
.detail-card.absent {
|
|
152
|
+
opacity: 0.72;
|
|
153
|
+
}
|
|
154
|
+
.evidence {
|
|
155
|
+
font-size: var(--roxy-text-xs, 0.75rem);
|
|
156
|
+
color: var(--roxy-muted, #71717a);
|
|
157
|
+
margin: 0;
|
|
158
|
+
line-height: var(--roxy-leading-normal, 1.5);
|
|
159
|
+
}
|
|
135
160
|
.description {
|
|
136
161
|
font-size: var(--roxy-text-sm, 0.875rem);
|
|
137
162
|
color: var(--roxy-muted, #71717a);
|
|
@@ -211,6 +236,27 @@ export class RoxyYogaList extends RoxyDataElement<YogaListData> {
|
|
|
211
236
|
</div>`;
|
|
212
237
|
}
|
|
213
238
|
|
|
239
|
+
/** Detect-mode card: shows the present/absent verdict and the classical evidence that triggered or failed it. */
|
|
240
|
+
private renderDetectCard(y: DetectYogasResponse['yogas'][number]) {
|
|
241
|
+
return html`<div class="detail-card ${y.present ? '' : 'absent'}">
|
|
242
|
+
<p class="detail-name">
|
|
243
|
+
${y.name}
|
|
244
|
+
${y.quality ? this.renderQualityChip(y.quality) : nothing}
|
|
245
|
+
<span class="present-badge ${y.present ? 'is-present' : 'is-absent'}">${y.present ? 'Present' : 'Not present'}</span>
|
|
246
|
+
</p>
|
|
247
|
+
${y.description ? html`<p class="description">${y.description}</p>` : nothing}
|
|
248
|
+
${
|
|
249
|
+
y.present && y.result
|
|
250
|
+
? html`<details>
|
|
251
|
+
<summary>Effects</summary>
|
|
252
|
+
<div class="result-body">${y.result}</div>
|
|
253
|
+
</details>`
|
|
254
|
+
: nothing
|
|
255
|
+
}
|
|
256
|
+
${y.evidence ? html`<p class="evidence">${y.evidence}</p>` : nothing}
|
|
257
|
+
</div>`;
|
|
258
|
+
}
|
|
259
|
+
|
|
214
260
|
protected renderEmpty() {
|
|
215
261
|
return html`<div class="roxy-empty" role="status">No yoga data</div>`;
|
|
216
262
|
}
|
|
@@ -232,6 +278,53 @@ export class RoxyYogaList extends RoxyDataElement<YogaListData> {
|
|
|
232
278
|
const allYogas = (
|
|
233
279
|
d as { yogas: Array<GetYogaResponse | { id: string; name: string }> }
|
|
234
280
|
).yogas;
|
|
281
|
+
|
|
282
|
+
// Detect mode: every entry carries a `present` verdict. Render present
|
|
283
|
+
// yogas first, mark each present/absent, and surface the classical
|
|
284
|
+
// evidence. Must precede the detail-array check because detect entries
|
|
285
|
+
// also carry `description`.
|
|
286
|
+
if (allYogas.length > 0 && 'present' in allYogas[0]) {
|
|
287
|
+
const detected = allYogas as DetectYogasResponse['yogas'];
|
|
288
|
+
const filtered = lc
|
|
289
|
+
? detected.filter((y) => y.name.toLowerCase().includes(lc))
|
|
290
|
+
: detected;
|
|
291
|
+
const ordered = [
|
|
292
|
+
...filtered.filter((y) => y.present),
|
|
293
|
+
...filtered.filter((y) => !y.present),
|
|
294
|
+
];
|
|
295
|
+
const presentCount =
|
|
296
|
+
(d as DetectYogasResponse).total ??
|
|
297
|
+
detected.filter((y) => y.present).length;
|
|
298
|
+
return html`<div class="wrap">
|
|
299
|
+
<div class="head">
|
|
300
|
+
<h2 class="title">Detected yogas</h2>
|
|
301
|
+
<span class="count">${presentCount} of ${detected.length} present</span>
|
|
302
|
+
</div>
|
|
303
|
+
<div class="search-wrap">
|
|
304
|
+
<input
|
|
305
|
+
class="search"
|
|
306
|
+
type="search"
|
|
307
|
+
placeholder="Filter yogas..."
|
|
308
|
+
aria-label="Filter detected yogas by name"
|
|
309
|
+
.value=${this.filter}
|
|
310
|
+
@input=${this.handleInput}
|
|
311
|
+
/>
|
|
312
|
+
</div>
|
|
313
|
+
<div
|
|
314
|
+
class="detail-grid"
|
|
315
|
+
role="region"
|
|
316
|
+
aria-live="polite"
|
|
317
|
+
aria-label="Detected yogas"
|
|
318
|
+
>
|
|
319
|
+
${
|
|
320
|
+
ordered.length > 0
|
|
321
|
+
? ordered.map((y) => this.renderDetectCard(y))
|
|
322
|
+
: html`<p class="no-results">No yogas match your search.</p>`
|
|
323
|
+
}
|
|
324
|
+
</div>
|
|
325
|
+
</div>`;
|
|
326
|
+
}
|
|
327
|
+
|
|
235
328
|
const isDetailArray = allYogas.length > 0 && 'description' in allYogas[0];
|
|
236
329
|
|
|
237
330
|
if (isDetailArray) {
|
|
@@ -53,6 +53,13 @@ export const ENDPOINT_BINDINGS: Record<string, EndpointBinding[]> = {
|
|
|
53
53
|
path: '/astrology/transit-aspects',
|
|
54
54
|
},
|
|
55
55
|
],
|
|
56
|
+
'roxy-astrocartography-map': [
|
|
57
|
+
{
|
|
58
|
+
operationId: 'generateAstrocartography',
|
|
59
|
+
method: 'POST',
|
|
60
|
+
path: '/astrology/astrocartography',
|
|
61
|
+
},
|
|
62
|
+
],
|
|
56
63
|
'roxy-biorhythm-chart': [
|
|
57
64
|
{
|
|
58
65
|
operationId: 'getCriticalDays',
|
|
@@ -216,6 +223,13 @@ export const ENDPOINT_BINDINGS: Record<string, EndpointBinding[]> = {
|
|
|
216
223
|
path: '/dreams/symbols',
|
|
217
224
|
},
|
|
218
225
|
],
|
|
226
|
+
'roxy-fixed-stars': [
|
|
227
|
+
{
|
|
228
|
+
operationId: 'generateFixedStars',
|
|
229
|
+
method: 'POST',
|
|
230
|
+
path: '/astrology/fixed-stars',
|
|
231
|
+
},
|
|
232
|
+
],
|
|
219
233
|
'roxy-forecast-digest': [
|
|
220
234
|
{
|
|
221
235
|
operationId: 'generateDigest',
|
|
@@ -329,6 +343,13 @@ export const ENDPOINT_BINDINGS: Record<string, EndpointBinding[]> = {
|
|
|
329
343
|
path: '/vedic-astrology/kp/ruling-planets',
|
|
330
344
|
},
|
|
331
345
|
],
|
|
346
|
+
'roxy-local-space-compass': [
|
|
347
|
+
{
|
|
348
|
+
operationId: 'generateLocalSpace',
|
|
349
|
+
method: 'POST',
|
|
350
|
+
path: '/astrology/local-space',
|
|
351
|
+
},
|
|
352
|
+
],
|
|
332
353
|
'roxy-moon-phase': [
|
|
333
354
|
{
|
|
334
355
|
operationId: 'getMoonCalendar',
|
|
@@ -477,6 +498,40 @@ export const ENDPOINT_BINDINGS: Record<string, EndpointBinding[]> = {
|
|
|
477
498
|
},
|
|
478
499
|
},
|
|
479
500
|
],
|
|
501
|
+
'roxy-positions-table': [
|
|
502
|
+
{
|
|
503
|
+
operationId: 'calculateArabicLots',
|
|
504
|
+
method: 'POST',
|
|
505
|
+
path: '/astrology/arabic-lots',
|
|
506
|
+
},
|
|
507
|
+
{
|
|
508
|
+
operationId: 'generateAsteroids',
|
|
509
|
+
method: 'POST',
|
|
510
|
+
path: '/astrology/asteroids',
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
operationId: 'generateLilith',
|
|
514
|
+
method: 'POST',
|
|
515
|
+
path: '/astrology/lilith',
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
operationId: 'generateProgressions',
|
|
519
|
+
method: 'POST',
|
|
520
|
+
path: '/astrology/progressions',
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
operationId: 'generateSolarArc',
|
|
524
|
+
method: 'POST',
|
|
525
|
+
path: '/astrology/solar-arc',
|
|
526
|
+
},
|
|
527
|
+
],
|
|
528
|
+
'roxy-profection-card': [
|
|
529
|
+
{
|
|
530
|
+
operationId: 'generateProfections',
|
|
531
|
+
method: 'POST',
|
|
532
|
+
path: '/astrology/profections',
|
|
533
|
+
},
|
|
534
|
+
],
|
|
480
535
|
'roxy-reference-card': [
|
|
481
536
|
{
|
|
482
537
|
operationId: 'getPlanetMeaning',
|
|
@@ -519,6 +574,13 @@ export const ENDPOINT_BINDINGS: Record<string, EndpointBinding[]> = {
|
|
|
519
574
|
path: '/vedic-astrology/rashis/{id}',
|
|
520
575
|
},
|
|
521
576
|
],
|
|
577
|
+
'roxy-relocation-wheel': [
|
|
578
|
+
{
|
|
579
|
+
operationId: 'generateRelocationChart',
|
|
580
|
+
method: 'POST',
|
|
581
|
+
path: '/astrology/relocation-chart',
|
|
582
|
+
},
|
|
583
|
+
],
|
|
522
584
|
'roxy-shadbala-table': [
|
|
523
585
|
{
|
|
524
586
|
operationId: 'calculateShadbala',
|
package/src/index.ts
CHANGED
|
@@ -11,6 +11,7 @@ export { RoxyAngelNumberLookup } from './components/angel-number-lookup.js';
|
|
|
11
11
|
export { RoxyAshtakavargaGrid } from './components/ashtakavarga-grid.js';
|
|
12
12
|
// Western astrology
|
|
13
13
|
export { RoxyAspectsTable } from './components/aspects-table.js';
|
|
14
|
+
export { RoxyAstrocartographyMap } from './components/astrocartography-map.js';
|
|
14
15
|
// Biorhythm
|
|
15
16
|
export { RoxyBiorhythmChart } from './components/biorhythm-chart.js';
|
|
16
17
|
// Human Design
|
|
@@ -30,6 +31,7 @@ export { RoxyDreamCard } from './components/dream-card.js';
|
|
|
30
31
|
export { RoxyDreamSearch } from './components/dream-search.js';
|
|
31
32
|
// Helpers
|
|
32
33
|
export { RoxyEndpointForm } from './components/endpoint-form.js';
|
|
34
|
+
export { RoxyFixedStars } from './components/fixed-stars.js';
|
|
33
35
|
// Forecast
|
|
34
36
|
export { RoxyForecastDigest } from './components/forecast-digest.js';
|
|
35
37
|
export { RoxyForecastTimeline } from './components/forecast-timeline.js';
|
|
@@ -45,6 +47,7 @@ export { RoxyHoroscopeCard } from './components/horoscope-card.js';
|
|
|
45
47
|
export { RoxyKpChart } from './components/kp-chart.js';
|
|
46
48
|
export { RoxyKpPlanetsTable } from './components/kp-planets-table.js';
|
|
47
49
|
export { RoxyKpRulingPlanets } from './components/kp-ruling-planets.js';
|
|
50
|
+
export { RoxyLocalSpaceCompass } from './components/local-space-compass.js';
|
|
48
51
|
export { RoxyLocationSearch } from './components/location-search.js';
|
|
49
52
|
export { RoxyMoonPhase } from './components/moon-phase.js';
|
|
50
53
|
export { RoxyNakshatraCard } from './components/nakshatra-card.js';
|
|
@@ -53,7 +56,10 @@ export { RoxyNatalChart } from './components/natal-chart.js';
|
|
|
53
56
|
// Numerology
|
|
54
57
|
export { RoxyNumerologyCard } from './components/numerology-card.js';
|
|
55
58
|
export { RoxyPanchangTable } from './components/panchang-table.js';
|
|
59
|
+
export { RoxyPositionsTable } from './components/positions-table.js';
|
|
60
|
+
export { RoxyProfectionCard } from './components/profection-card.js';
|
|
56
61
|
export { RoxyReferenceCard } from './components/reference-card.js';
|
|
62
|
+
export { RoxyRelocationWheel } from './components/relocation-wheel.js';
|
|
57
63
|
export { RoxyShadbalaTable } from './components/shadbala-table.js';
|
|
58
64
|
export { RoxySynastryChart } from './components/synastry-chart.js';
|
|
59
65
|
// Tarot
|
package/src/manifest.ts
CHANGED
|
@@ -126,6 +126,85 @@ export const ROXY_COMPONENTS: readonly RoxyComponent[] = [
|
|
|
126
126
|
docsSummary: 'Daily, weekly, or monthly horoscope card',
|
|
127
127
|
topic: 'Astrology',
|
|
128
128
|
},
|
|
129
|
+
{
|
|
130
|
+
pascal: 'RoxyAstrocartographyMap',
|
|
131
|
+
tag: 'roxy-astrocartography-map',
|
|
132
|
+
slug: 'astrocartography-map',
|
|
133
|
+
heading: 'Astrocartography',
|
|
134
|
+
description:
|
|
135
|
+
'Astrocartography world map plotting each body Midheaven, IC, Ascendant, and Descendant relocation lines',
|
|
136
|
+
docsLabel: 'Western',
|
|
137
|
+
endpointLabel: 'POST /astrology/astrocartography',
|
|
138
|
+
docsSummary:
|
|
139
|
+
'World map of planetary MC, IC, Ascendant, and Descendant lines with per-line interpretations',
|
|
140
|
+
topic: 'Astrology',
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
pascal: 'RoxyLocalSpaceCompass',
|
|
144
|
+
tag: 'roxy-local-space-compass',
|
|
145
|
+
slug: 'local-space-compass',
|
|
146
|
+
heading: 'Local space',
|
|
147
|
+
description:
|
|
148
|
+
'Local space compass plotting each body direction from the birthplace by azimuth and altitude',
|
|
149
|
+
docsLabel: 'Western',
|
|
150
|
+
endpointLabel: 'POST /astrology/local-space',
|
|
151
|
+
docsSummary:
|
|
152
|
+
'Compass dial of planetary azimuth lines from the birthplace, dimmed below the horizon',
|
|
153
|
+
topic: 'Astrology',
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
pascal: 'RoxyRelocationWheel',
|
|
157
|
+
tag: 'roxy-relocation-wheel',
|
|
158
|
+
slug: 'relocation-wheel',
|
|
159
|
+
heading: 'Relocation chart',
|
|
160
|
+
description:
|
|
161
|
+
'Relocation chart wheel recomputing houses and angles for a new place, with the planets that change house',
|
|
162
|
+
docsLabel: 'Western',
|
|
163
|
+
endpointLabel: 'POST /astrology/relocation-chart',
|
|
164
|
+
docsSummary:
|
|
165
|
+
'Relocated chart wheel plus the move geometry, angular planets, and planets that change house',
|
|
166
|
+
topic: 'Astrology',
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
pascal: 'RoxyPositionsTable',
|
|
170
|
+
tag: 'roxy-positions-table',
|
|
171
|
+
slug: 'positions-table',
|
|
172
|
+
heading: 'Positions table',
|
|
173
|
+
description:
|
|
174
|
+
'Editorial positions table for asteroids, Black Moon Lilith, secondary progressions, solar arc directions, and the Arabic lots',
|
|
175
|
+
docsLabel: 'Western',
|
|
176
|
+
endpointLabel:
|
|
177
|
+
'POST /astrology/asteroids, /astrology/lilith, /astrology/progressions, /astrology/solar-arc, /astrology/arabic-lots',
|
|
178
|
+
docsSummary:
|
|
179
|
+
'Body, sign, degree, and per-shape columns (house, motion, formula, or natal arc) plus each reading',
|
|
180
|
+
topic: 'Astrology',
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
pascal: 'RoxyFixedStars',
|
|
184
|
+
tag: 'roxy-fixed-stars',
|
|
185
|
+
slug: 'fixed-stars',
|
|
186
|
+
heading: 'Fixed stars',
|
|
187
|
+
description:
|
|
188
|
+
'Fixed star conjunctions to the natal chart, tightest first, with the precessed star catalog',
|
|
189
|
+
docsLabel: 'Western',
|
|
190
|
+
endpointLabel: 'POST /astrology/fixed-stars',
|
|
191
|
+
docsSummary:
|
|
192
|
+
'Star to natal point conjunctions with readings, plus a catalog of position, magnitude, nature, and keywords',
|
|
193
|
+
topic: 'Astrology',
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
pascal: 'RoxyProfectionCard',
|
|
197
|
+
tag: 'roxy-profection-card',
|
|
198
|
+
slug: 'profection-card',
|
|
199
|
+
heading: 'Annual profection',
|
|
200
|
+
description:
|
|
201
|
+
'Annual profection card with the profected house and sign, the lord of the year, and its natal placement',
|
|
202
|
+
docsLabel: 'Western',
|
|
203
|
+
endpointLabel: 'POST /astrology/profections',
|
|
204
|
+
docsSummary:
|
|
205
|
+
'Profected house and sign for the year, the lord of the year, its natal placement, and the reading',
|
|
206
|
+
topic: 'Astrology',
|
|
207
|
+
},
|
|
129
208
|
{
|
|
130
209
|
pascal: 'RoxyCompatibilityCard',
|
|
131
210
|
tag: 'roxy-compatibility-card',
|