@roxyapi/ui 0.1.3 → 0.2.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 (161) hide show
  1. package/AGENTS.md +6 -0
  2. package/README.md +9 -3
  3. package/dist/cdn/components/ashtakavarga-grid.js +349 -0
  4. package/dist/cdn/components/ashtakavarga-grid.js.map +7 -0
  5. package/dist/cdn/components/choghadiya-grid.js +239 -0
  6. package/dist/cdn/components/choghadiya-grid.js.map +7 -0
  7. package/dist/cdn/components/compatibility-card.js +6 -6
  8. package/dist/cdn/components/compatibility-card.js.map +1 -1
  9. package/dist/cdn/components/dasha-timeline.js +4 -4
  10. package/dist/cdn/components/dasha-timeline.js.map +1 -1
  11. package/dist/cdn/components/data.js +9 -9
  12. package/dist/cdn/components/data.js.map +4 -4
  13. package/dist/cdn/components/divisional-chart.js +279 -0
  14. package/dist/cdn/components/divisional-chart.js.map +7 -0
  15. package/dist/cdn/components/dosha-card.js +39 -39
  16. package/dist/cdn/components/dosha-card.js.map +3 -3
  17. package/dist/cdn/components/endpoint-form.js +8 -8
  18. package/dist/cdn/components/endpoint-form.js.map +4 -4
  19. package/dist/cdn/components/guna-milan.js +64 -22
  20. package/dist/cdn/components/guna-milan.js.map +3 -3
  21. package/dist/cdn/components/hexagram.js +9 -9
  22. package/dist/cdn/components/hexagram.js.map +3 -3
  23. package/dist/cdn/components/horoscope-card.js +28 -21
  24. package/dist/cdn/components/horoscope-card.js.map +4 -4
  25. package/dist/cdn/components/kp-planets-table.js +4 -4
  26. package/dist/cdn/components/kp-planets-table.js.map +1 -1
  27. package/dist/cdn/components/location-search.js.map +2 -2
  28. package/dist/cdn/components/moon-phase.js +13 -13
  29. package/dist/cdn/components/moon-phase.js.map +3 -3
  30. package/dist/cdn/components/natal-chart.js +196 -22
  31. package/dist/cdn/components/natal-chart.js.map +4 -4
  32. package/dist/cdn/components/numerology-card.js +6 -6
  33. package/dist/cdn/components/numerology-card.js.map +4 -4
  34. package/dist/cdn/components/panchang-table.js +9 -9
  35. package/dist/cdn/components/panchang-table.js.map +1 -1
  36. package/dist/cdn/components/shadbala-table.js +312 -0
  37. package/dist/cdn/components/shadbala-table.js.map +7 -0
  38. package/dist/cdn/components/synastry-chart.js +21 -21
  39. package/dist/cdn/components/synastry-chart.js.map +4 -4
  40. package/dist/cdn/components/transits-table.js +396 -0
  41. package/dist/cdn/components/transits-table.js.map +7 -0
  42. package/dist/cdn/components/vedic-kundli.js +51 -29
  43. package/dist/cdn/components/vedic-kundli.js.map +4 -4
  44. package/dist/cdn/components/yoga-list.js +334 -0
  45. package/dist/cdn/components/yoga-list.js.map +7 -0
  46. package/dist/cdn/roxy-ui.js +1877 -522
  47. package/dist/cdn/roxy-ui.js.map +4 -4
  48. package/dist/components/ashtakavarga-grid.d.ts +26 -0
  49. package/dist/components/ashtakavarga-grid.d.ts.map +1 -0
  50. package/dist/components/ashtakavarga-grid.js +457 -0
  51. package/dist/components/ashtakavarga-grid.js.map +7 -0
  52. package/dist/components/choghadiya-grid.d.ts +19 -0
  53. package/dist/components/choghadiya-grid.d.ts.map +1 -0
  54. package/dist/components/choghadiya-grid.js +304 -0
  55. package/dist/components/choghadiya-grid.js.map +7 -0
  56. package/dist/components/compatibility-card.js.map +1 -1
  57. package/dist/components/dasha-timeline.js.map +1 -1
  58. package/dist/components/data.d.ts +5 -7
  59. package/dist/components/data.d.ts.map +1 -1
  60. package/dist/components/data.js +7 -5
  61. package/dist/components/data.js.map +3 -3
  62. package/dist/components/divisional-chart.d.ts +20 -0
  63. package/dist/components/divisional-chart.d.ts.map +1 -0
  64. package/dist/components/divisional-chart.js +471 -0
  65. package/dist/components/divisional-chart.js.map +7 -0
  66. package/dist/components/dosha-card.d.ts.map +1 -1
  67. package/dist/components/dosha-card.js +33 -30
  68. package/dist/components/dosha-card.js.map +2 -2
  69. package/dist/components/endpoint-form.d.ts.map +1 -1
  70. package/dist/components/endpoint-form.js +5 -3
  71. package/dist/components/endpoint-form.js.map +3 -3
  72. package/dist/components/guna-milan.d.ts.map +1 -1
  73. package/dist/components/guna-milan.js +61 -12
  74. package/dist/components/guna-milan.js.map +3 -3
  75. package/dist/components/hexagram.js +17 -0
  76. package/dist/components/hexagram.js.map +2 -2
  77. package/dist/components/horoscope-card.d.ts.map +1 -1
  78. package/dist/components/horoscope-card.js +30 -3
  79. package/dist/components/horoscope-card.js.map +3 -3
  80. package/dist/components/kp-planets-table.js.map +1 -1
  81. package/dist/components/location-search.d.ts +2 -3
  82. package/dist/components/location-search.d.ts.map +1 -1
  83. package/dist/components/location-search.js.map +2 -2
  84. package/dist/components/moon-phase.js +17 -0
  85. package/dist/components/moon-phase.js.map +2 -2
  86. package/dist/components/natal-chart.d.ts +2 -0
  87. package/dist/components/natal-chart.d.ts.map +1 -1
  88. package/dist/components/natal-chart.js +243 -36
  89. package/dist/components/natal-chart.js.map +3 -3
  90. package/dist/components/numerology-card.d.ts.map +1 -1
  91. package/dist/components/numerology-card.js +5 -3
  92. package/dist/components/numerology-card.js.map +3 -3
  93. package/dist/components/panchang-table.js.map +1 -1
  94. package/dist/components/shadbala-table.d.ts +18 -0
  95. package/dist/components/shadbala-table.d.ts.map +1 -0
  96. package/dist/components/shadbala-table.js +400 -0
  97. package/dist/components/shadbala-table.js.map +7 -0
  98. package/dist/components/synastry-chart.d.ts.map +1 -1
  99. package/dist/components/synastry-chart.js +34 -29
  100. package/dist/components/synastry-chart.js.map +3 -3
  101. package/dist/components/transits-table.d.ts +21 -0
  102. package/dist/components/transits-table.d.ts.map +1 -0
  103. package/dist/components/transits-table.js +520 -0
  104. package/dist/components/transits-table.js.map +7 -0
  105. package/dist/components/vedic-kundli.d.ts +3 -6
  106. package/dist/components/vedic-kundli.d.ts.map +1 -1
  107. package/dist/components/vedic-kundli.js +132 -80
  108. package/dist/components/vedic-kundli.js.map +3 -3
  109. package/dist/components/yoga-list.d.ts +29 -0
  110. package/dist/components/yoga-list.d.ts.map +1 -0
  111. package/dist/components/yoga-list.js +389 -0
  112. package/dist/components/yoga-list.js.map +7 -0
  113. package/dist/index.cjs +2707 -980
  114. package/dist/index.cjs.map +4 -4
  115. package/dist/index.d.ts +7 -2
  116. package/dist/index.d.ts.map +1 -1
  117. package/dist/index.js +2714 -987
  118. package/dist/index.js.map +4 -4
  119. package/dist/manifest.d.ts +4 -10
  120. package/dist/manifest.d.ts.map +1 -1
  121. package/dist/manifest.json +7 -2
  122. package/dist/styles/tokens.css +26 -0
  123. package/dist/tokens/index.d.ts +6 -0
  124. package/dist/tokens/index.d.ts.map +1 -1
  125. package/dist/types/types.gen.d.ts +2 -2
  126. package/dist/utils/format.d.ts +15 -1
  127. package/dist/utils/format.d.ts.map +1 -1
  128. package/dist/utils/kundli-render.d.ts +63 -0
  129. package/dist/utils/kundli-render.d.ts.map +1 -0
  130. package/dist/utils/string.d.ts +14 -0
  131. package/dist/utils/string.d.ts.map +1 -0
  132. package/dist/version.d.ts +1 -1
  133. package/package.json +1 -1
  134. package/src/components/ashtakavarga-grid.ts +354 -0
  135. package/src/components/choghadiya-grid.ts +185 -0
  136. package/src/components/data.ts +8 -15
  137. package/src/components/divisional-chart.ts +214 -0
  138. package/src/components/dosha-card.ts +53 -36
  139. package/src/components/endpoint-form.ts +1 -7
  140. package/src/components/guna-milan.ts +74 -16
  141. package/src/components/horoscope-card.ts +8 -4
  142. package/src/components/location-search.ts +2 -3
  143. package/src/components/natal-chart.ts +251 -42
  144. package/src/components/numerology-card.ts +1 -7
  145. package/src/components/shadbala-table.ts +286 -0
  146. package/src/components/synastry-chart.ts +13 -39
  147. package/src/components/transits-table.ts +358 -0
  148. package/src/components/vedic-kundli.ts +38 -143
  149. package/src/components/yoga-list.ts +328 -0
  150. package/src/index.ts +8 -6
  151. package/src/manifest.ts +74 -100
  152. package/src/styles/tokens.css +26 -0
  153. package/src/tokens/index.ts +9 -0
  154. package/src/types/types.gen.ts +2 -2
  155. package/src/utils/format.ts +21 -3
  156. package/src/utils/kundli-render.ts +197 -0
  157. package/src/utils/string.ts +23 -0
  158. package/src/version.ts +1 -1
  159. package/dist/utils/motion.d.ts +0 -13
  160. package/dist/utils/motion.d.ts.map +0 -1
  161. package/src/utils/motion.ts +0 -18
@@ -0,0 +1,286 @@
1
+ import { css, html, LitElement, nothing } from 'lit';
2
+ import { customElement, property } from 'lit/decorators.js';
3
+ import { PLANET_GLYPH } from '../tokens/index.js';
4
+ import type { ShadbalaResponse } from '../types/index.js';
5
+ import { baseStyles } from '../utils/base-styles.js';
6
+ import { formatNumber } from '../utils/format.js';
7
+ import { capitalize } from '../utils/string.js';
8
+
9
+ type Planet = ShadbalaResponse['planets'][number];
10
+
11
+ /** CSS variable and display name for each of the 6 bala components. */
12
+ const BALA_COMPONENTS: Array<{
13
+ key: keyof Pick<
14
+ Planet,
15
+ | 'sthanaBala'
16
+ | 'digBala'
17
+ | 'kalaBala'
18
+ | 'chestaBala'
19
+ | 'naisargikaBala'
20
+ | 'drikBala'
21
+ >;
22
+ label: string;
23
+ color: string;
24
+ }> = [
25
+ { key: 'sthanaBala', label: 'Sthana', color: 'var(--roxy-info, #0284c7)' },
26
+ { key: 'digBala', label: 'Dig', color: 'var(--roxy-success, #16a34a)' },
27
+ { key: 'kalaBala', label: 'Kala', color: 'var(--roxy-warning, #ea580c)' },
28
+ { key: 'chestaBala', label: 'Chesta', color: 'var(--roxy-accent, #f59e0b)' },
29
+ {
30
+ key: 'naisargikaBala',
31
+ label: 'Naisargika',
32
+ color: 'var(--roxy-secondary, #475569)',
33
+ },
34
+ { key: 'drikBala', label: 'Drik', color: 'var(--roxy-danger, #dc2626)' },
35
+ ];
36
+
37
+ /**
38
+ * Shadbala six-fold planetary strength table with stacked bar visualization.
39
+ * Pass `data` from /vedic-astrology/shadbala.
40
+ */
41
+ @customElement('roxy-shadbala-table')
42
+ export class RoxyShadbalaTable extends LitElement {
43
+ static styles = [
44
+ baseStyles,
45
+ css`
46
+ .wrap {
47
+ display: grid;
48
+ gap: var(--roxy-space-md, 1rem);
49
+ }
50
+
51
+ .head {
52
+ display: flex;
53
+ justify-content: space-between;
54
+ align-items: baseline;
55
+ gap: var(--roxy-space-md, 1rem);
56
+ flex-wrap: wrap;
57
+ }
58
+
59
+ .title {
60
+ font-size: var(--roxy-text-lg, 1.125rem);
61
+ font-weight: var(--roxy-weight-bold, 600);
62
+ margin: 0;
63
+ }
64
+
65
+ .subtitle {
66
+ color: var(--roxy-muted, #71717a);
67
+ font-size: var(--roxy-text-sm, 0.875rem);
68
+ margin: 0;
69
+ }
70
+
71
+ .planet-row {
72
+ display: grid;
73
+ grid-template-columns: 8rem 1fr auto;
74
+ align-items: center;
75
+ gap: var(--roxy-space-sm, 0.5rem);
76
+ padding: var(--roxy-space-sm, 0.5rem) 0;
77
+ border-bottom: 1px solid var(--roxy-border, #e4e4e7);
78
+ }
79
+
80
+ .planet-row:last-of-type {
81
+ border-bottom: none;
82
+ }
83
+
84
+ .planet-label {
85
+ display: flex;
86
+ align-items: center;
87
+ gap: 6px;
88
+ font-size: var(--roxy-text-sm, 0.875rem);
89
+ font-weight: var(--roxy-weight-bold, 600);
90
+ }
91
+
92
+ .glyph {
93
+ font-size: 1.2em;
94
+ line-height: 1;
95
+ }
96
+
97
+ .bar-wrap {
98
+ display: flex;
99
+ flex-direction: column;
100
+ gap: 4px;
101
+ }
102
+
103
+ .bar {
104
+ display: flex;
105
+ height: 12px;
106
+ border-radius: var(--roxy-radius-sm, 4px);
107
+ overflow: hidden;
108
+ background: var(--roxy-border, #e4e4e7);
109
+ }
110
+
111
+ .bar-segment {
112
+ height: 100%;
113
+ transition: flex-grow var(--roxy-motion-duration, 200ms)
114
+ var(--roxy-motion-easing, cubic-bezier(0.4, 0, 0.2, 1));
115
+ }
116
+
117
+ .pills {
118
+ display: flex;
119
+ flex-direction: column;
120
+ align-items: flex-end;
121
+ gap: 4px;
122
+ }
123
+
124
+ .rupas-label {
125
+ font-variant-numeric: tabular-nums;
126
+ font-size: var(--roxy-text-xs, 0.75rem);
127
+ color: var(--roxy-muted, #71717a);
128
+ white-space: nowrap;
129
+ }
130
+
131
+ .adequacy-badge {
132
+ display: inline-block;
133
+ padding: 1px 6px;
134
+ border-radius: var(--roxy-radius-full, 9999px);
135
+ font-size: var(--roxy-text-xs, 0.75rem);
136
+ font-weight: var(--roxy-weight-bold, 600);
137
+ }
138
+
139
+ .adequacy-badge--adequate {
140
+ background: color-mix(in srgb, var(--roxy-success, #16a34a) 12%, transparent);
141
+ color: var(--roxy-success-fg, #166534);
142
+ }
143
+
144
+ .adequacy-badge--weak {
145
+ background: color-mix(in srgb, var(--roxy-danger, #dc2626) 12%, transparent);
146
+ color: var(--roxy-danger-fg, #991b1b);
147
+ }
148
+
149
+ .rank-badge {
150
+ font-size: var(--roxy-text-xs, 0.75rem);
151
+ color: var(--roxy-accent-fg, #b45309);
152
+ font-weight: var(--roxy-weight-bold, 600);
153
+ }
154
+
155
+ .legend {
156
+ display: flex;
157
+ flex-wrap: wrap;
158
+ gap: var(--roxy-space-sm, 0.5rem) var(--roxy-space-md, 1rem);
159
+ border-top: 1px solid var(--roxy-border, #e4e4e7);
160
+ padding-top: var(--roxy-space-sm, 0.5rem);
161
+ }
162
+
163
+ .legend-row {
164
+ display: flex;
165
+ align-items: center;
166
+ gap: 6px;
167
+ font-size: var(--roxy-text-xs, 0.75rem);
168
+ color: var(--roxy-muted, #71717a);
169
+ }
170
+
171
+ .legend-swatch {
172
+ display: inline-block;
173
+ width: 10px;
174
+ height: 10px;
175
+ border-radius: var(--roxy-radius-sm, 4px);
176
+ flex-shrink: 0;
177
+ }
178
+
179
+ @container (max-width: 480px) {
180
+ .planet-row {
181
+ grid-template-columns: 6rem 1fr;
182
+ grid-template-rows: auto auto;
183
+ }
184
+ .pills {
185
+ grid-column: 1 / -1;
186
+ flex-direction: row;
187
+ align-items: center;
188
+ justify-content: flex-start;
189
+ }
190
+ }
191
+ `,
192
+ ];
193
+
194
+ @property({ attribute: false })
195
+ data: ShadbalaResponse | null = null;
196
+
197
+ render() {
198
+ if (!this.data?.planets?.length) {
199
+ return html`<div class="roxy-empty" role="status">No shadbala data</div>`;
200
+ }
201
+
202
+ const sorted = [...this.data.planets].sort(
203
+ (a, b) => a.relativeRank - b.relativeRank,
204
+ );
205
+
206
+ return html`<div class="wrap" aria-label="Shadbala planetary strength">
207
+ <div class="head">
208
+ <h2 class="title">Shadbala</h2>
209
+ <p class="subtitle">${sorted.length} planets ranked by strength</p>
210
+ </div>
211
+
212
+ <div role="list" aria-label="Planet strength bars">
213
+ ${sorted.map((p) => this.renderPlanetRow(p))}
214
+ </div>
215
+
216
+ <div class="legend" aria-label="Strength component legend">
217
+ ${BALA_COMPONENTS.map(
218
+ (b) => html`<div class="legend-row">
219
+ <span
220
+ class="legend-swatch"
221
+ style="background: ${b.color}"
222
+ aria-hidden="true"
223
+ ></span>
224
+ ${b.label}
225
+ </div>`,
226
+ )}
227
+ </div>
228
+ </div>`;
229
+ }
230
+
231
+ private renderPlanetRow(p: Planet) {
232
+ const glyph = PLANET_GLYPH[capitalize(p.planet)] ?? '';
233
+
234
+ // Compute positive component values (drikBala can be negative)
235
+ const values = BALA_COMPONENTS.map((b) => Math.max(0, p[b.key] as number));
236
+ const total = values.reduce((s, v) => s + v, 0);
237
+
238
+ const isAdequate =
239
+ typeof p.strengthRatio === 'number' && p.strengthRatio >= 1;
240
+ const badgeClass = isAdequate
241
+ ? 'adequacy-badge--adequate'
242
+ : 'adequacy-badge--weak';
243
+ const badgeLabel = isAdequate ? 'adequate' : 'weak';
244
+
245
+ const rupasStr =
246
+ formatNumber(p.totalRupas, 2) && formatNumber(p.minRequired, 2)
247
+ ? `${formatNumber(p.totalRupas, 2)} / ${formatNumber(p.minRequired, 2)} R`
248
+ : '';
249
+
250
+ return html`<div class="planet-row" role="listitem" aria-label="${p.planet} shadbala">
251
+ <div class="planet-label">
252
+ <span class="glyph" aria-hidden="true">${glyph}</span>
253
+ ${p.planet}
254
+ <span class="rank-badge" aria-label="rank ${p.relativeRank}">#${p.relativeRank}</span>
255
+ </div>
256
+ <div class="bar-wrap">
257
+ <div class="bar" role="img" aria-label="Strength components for ${p.planet}">
258
+ ${
259
+ total > 0
260
+ ? BALA_COMPONENTS.map((b, i) => {
261
+ const v = values[i];
262
+ if (v <= 0) return nothing;
263
+ const grow = (v / total) * 100;
264
+ return html`<div
265
+ class="bar-segment"
266
+ style="flex-grow: ${grow}; background: ${b.color};"
267
+ title="${b.label}: ${formatNumber(v, 1)}"
268
+ ></div>`;
269
+ })
270
+ : nothing
271
+ }
272
+ </div>
273
+ </div>
274
+ <div class="pills">
275
+ ${rupasStr ? html`<span class="rupas-label">${rupasStr}</span>` : nothing}
276
+ <span class="${`adequacy-badge ${badgeClass}`}">${badgeLabel}</span>
277
+ </div>
278
+ </div>`;
279
+ }
280
+ }
281
+
282
+ declare global {
283
+ interface HTMLElementTagNameMap {
284
+ 'roxy-shadbala-table': RoxyShadbalaTable;
285
+ }
286
+ }
@@ -1,22 +1,27 @@
1
1
  import { css, html, LitElement, nothing, svg } from 'lit';
2
2
  import { customElement, property } from 'lit/decorators.js';
3
- import { PLANET_GLYPH, SIGN_GLYPH } from '../tokens/index.js';
3
+ import { PLANET_GLYPH, SIGN_GLYPH, SIGNS_ORDER } from '../tokens/index.js';
4
4
  import type {
5
5
  CalculateSynastryResponse,
6
6
  NatalChartResponse,
7
7
  } from '../types/index.js';
8
8
  import { baseStyles } from '../utils/base-styles.js';
9
9
  import { polarToCartesian } from '../utils/degree.js';
10
- import { formatNumber } from '../utils/format.js';
10
+ import {
11
+ ASPECT_CLASS,
12
+ formatNumber,
13
+ normalizeAspect,
14
+ } from '../utils/format.js';
15
+ import { capitalize } from '../utils/string.js';
11
16
 
12
17
  type PlanetEntry = NatalChartResponse['planets'][number];
13
18
  type InterAspect = CalculateSynastryResponse['interAspects'][number];
14
19
 
15
- // TODO(spec): /astrology/synastry does not expose person1/person2 planet
16
- // positions, but the wheel needs them to plot the dual chart. The preview
17
- // injects them via scripts/refresh-samples.ts; production callers see an
18
- // empty wheel. Either add `planets` to the CalculateSynastry response or
19
- // document that callers must merge in their own natal-chart payloads.
20
+ // Drawing the dual wheel requires per-person planet longitudes alongside
21
+ // the synastry response. Callers can merge planet arrays from
22
+ // /astrology/natal-chart into `person1.planets` and `person2.planets`
23
+ // before passing the payload in; without them, the component falls back
24
+ // to the inter-aspects table and a status note instead of an empty wheel.
20
25
  type SynastryWithPlanets = CalculateSynastryResponse & {
21
26
  person1?: { planets?: PlanetEntry[] };
22
27
  person2?: { planets?: PlanetEntry[] };
@@ -364,21 +369,7 @@ export class RoxySynastryChart extends LitElement {
364
369
  }
365
370
 
366
371
  private renderSigns() {
367
- const order = [
368
- 'Aries',
369
- 'Taurus',
370
- 'Gemini',
371
- 'Cancer',
372
- 'Leo',
373
- 'Virgo',
374
- 'Libra',
375
- 'Scorpio',
376
- 'Sagittarius',
377
- 'Capricorn',
378
- 'Aquarius',
379
- 'Pisces',
380
- ];
381
- return order.map((s, i) => {
372
+ return SIGNS_ORDER.map((s, i) => {
382
373
  const angle = this.toAngle(i * 30 + 15);
383
374
  const pos = polarToCartesian(CENTER, CENTER, SIGN_R, angle);
384
375
  return svg`<text class="sign" x=${pos.x} y=${pos.y} text-anchor="middle" dominant-baseline="central">${SIGN_GLYPH[s]}</text>`;
@@ -454,23 +445,6 @@ export class RoxySynastryChart extends LitElement {
454
445
  }
455
446
  }
456
447
 
457
- function capitalize(s: string): string {
458
- if (!s) return '';
459
- return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase();
460
- }
461
-
462
- const ASPECT_CLASS: Record<string, string> = {
463
- conjunction: 'aspect-conjunction',
464
- sextile: 'aspect-sextile',
465
- square: 'aspect-square',
466
- trine: 'aspect-trine',
467
- opposition: 'aspect-opposition',
468
- };
469
-
470
- function normalizeAspect(a: InterAspect): string {
471
- return (a.type ?? '').toLowerCase().replace(/_/g, '-');
472
- }
473
-
474
448
  function formatStrength(s: number | undefined): string {
475
449
  if (typeof s === 'number') return Math.round(s).toString();
476
450
  return '';