@mashkovd/pelican-vue 0.2.0 → 0.3.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.
- package/README.md +15 -1
- package/dist/index.d.ts +8 -0
- package/dist/pelican-libertex-social.mjs +630 -619
- package/dist/pelican-libertex-social.mjs.map +1 -1
- package/dist/pelican-libertex-social.umd.cjs +1 -1
- package/dist/pelican-libertex-social.umd.cjs.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pelican-libertex-social.mjs","sources":["../src/composables/useDebounce.ts","../src/constants/defaults.ts","../src/constants/sort.ts","../src/components/Toolbar.vue","../src/components/filters/RiskChips.vue","../src/components/filters/RangeSingle.vue","../src/components/filters/RangeDual.vue","../src/utils/format.ts","../src/utils/scales.ts","../src/components/filters/InvestAmount.vue","../src/components/FiltersPanel.vue","../src/constants/palette.ts","../src/utils/svg.ts","../src/components/Sparkline.vue","../src/components/MarketsDonut.vue","../src/components/TradesPanel.vue","../src/utils/winrate.ts","../src/injection-keys.ts","../src/components/StrategyRow.vue","../src/components/Pager.vue","../src/components/StrategyTable.vue","../src/components/ProgressBar.vue","../src/composables/useTheme.ts","../src/utils/http.ts","../src/composables/useCatalog.ts","../src/types/filters.ts","../src/composables/useFilters.ts","../src/composables/useSort.ts","../src/composables/usePagination.ts","../src/composables/useSignals.ts","../src/PelicanLibertexSocial.vue"],"sourcesContent":["import { onScopeDispose } from 'vue';\n\nexport function useDebounce<T extends (...args: never[]) => void>(fn: T, delay: number) {\n let t: ReturnType<typeof setTimeout> | null = null;\n const wrapped = (...args: Parameters<T>) => {\n if (t) clearTimeout(t);\n t = setTimeout(() => {\n t = null;\n fn(...args);\n }, delay);\n };\n const cancel = () => {\n if (t) {\n clearTimeout(t);\n t = null;\n }\n };\n onScopeDispose(cancel);\n return { wrapped, cancel };\n}\n","export const PAGE_SIZE = 20;\nexport const SEARCH_DEBOUNCE_MS = 350;\nexport const PROGRESS_POLL_INTERVAL_MS = 2000;\nexport const PARTIAL_REPAINT_INTERVAL_MS = 20000;\nexport const SIGNALS_CLOSED_WINDOW_DAYS = 30;\n","export const SORT_KEYS = [\n 'return-desc',\n 'return-asc',\n 'copiers-desc',\n 'copiers-asc',\n 'aum-desc',\n 'aum-asc',\n 'dd-asc',\n 'dd-desc',\n 'fee-asc',\n 'fee-desc',\n 'age-desc',\n 'age-asc',\n 'balance-desc',\n 'balance-asc',\n 'winrate-desc',\n 'winrate-asc',\n 'trades-desc',\n 'trades-asc',\n 'monthly-desc',\n 'monthly-asc',\n] as const;\nexport type SortKey = (typeof SORT_KEYS)[number];\n\nexport const SORT_LABELS: Record<SortKey, string> = {\n 'return-desc': 'Return ↓',\n 'return-asc': 'Return ↑',\n 'copiers-desc': 'Copiers ↓',\n 'copiers-asc': 'Copiers ↑',\n 'aum-desc': 'Copiers AUM ↓',\n 'aum-asc': 'Copiers AUM ↑',\n 'dd-asc': 'Drawdown ↑',\n 'dd-desc': 'Drawdown ↓',\n 'fee-asc': 'Fee ↑',\n 'fee-desc': 'Fee ↓',\n 'age-desc': 'Age ↓',\n 'age-asc': 'Age ↑',\n 'balance-desc': 'Balance ↓',\n 'balance-asc': 'Balance ↑',\n 'winrate-desc': 'Win Rate ↓',\n 'winrate-asc': 'Win Rate ↑',\n 'trades-desc': 'Trades ↓',\n 'trades-asc': 'Trades ↑',\n 'monthly-desc': 'Monthly Profit ↓',\n 'monthly-asc': 'Monthly Profit ↑',\n};\n\nexport type SortColumn =\n | 'return'\n | 'copiers'\n | 'aum'\n | 'dd'\n | 'fee'\n | 'age'\n | 'balance';\n\nexport const SORT_TOGGLE: Record<SortColumn, [SortKey, SortKey]> = {\n return: ['return-desc', 'return-asc'],\n copiers: ['copiers-desc', 'copiers-asc'],\n aum: ['aum-desc', 'aum-asc'],\n dd: ['dd-asc', 'dd-desc'],\n fee: ['fee-asc', 'fee-desc'],\n age: ['age-desc', 'age-asc'],\n balance: ['balance-desc', 'balance-asc'],\n};\n","<script setup lang=\"ts\">\nimport { ref, watch } from 'vue';\nimport { useDebounce } from '../composables/useDebounce';\nimport { SEARCH_DEBOUNCE_MS } from '../constants/defaults';\nimport { SORT_KEYS, SORT_LABELS, type SortKey } from '../constants/sort';\n\nconst props = defineProps<{\n search: string;\n sortKey: SortKey;\n total: number;\n filteredTotal: number;\n page: number;\n totalPages: number;\n}>();\n\nconst emit = defineEmits<{\n (e: 'update:search', v: string): void;\n (e: 'update:sortKey', v: SortKey): void;\n (e: 'refresh'): void;\n (e: 'toggle-filters'): void;\n}>();\n\nconst local = ref(props.search);\nwatch(\n () => props.search,\n (v) => {\n if (v !== local.value) local.value = v;\n },\n);\n\nconst { wrapped: debounced } = useDebounce((v: string) => emit('update:search', v), SEARCH_DEBOUNCE_MS);\n\nfunction onSearchInput(e: Event) {\n const v = (e.target as HTMLInputElement).value;\n local.value = v;\n debounced(v);\n}\n\nfunction onSort(e: Event) {\n emit('update:sortKey', (e.target as HTMLSelectElement).value as SortKey);\n}\n</script>\n\n<template>\n <div class=\"pelican-toolbar\">\n <button class=\"btn-flat filters-toggle\" type=\"button\" @click=\"emit('toggle-filters')\">\n Filters\n </button>\n <div class=\"counts\">\n Showing <b>{{ filteredTotal.toLocaleString('en-US') }}</b>\n of <b>{{ total.toLocaleString('en-US') }}</b>\n · page <b>{{ page }}</b> / {{ totalPages }}\n </div>\n <input\n class=\"search\"\n type=\"search\"\n placeholder=\"Search by signal name…\"\n autocomplete=\"off\"\n :value=\"local\"\n @input=\"onSearchInput\"\n />\n <div class=\"sort\">\n <label>Sort:</label>\n <select :value=\"sortKey\" @change=\"onSort\">\n <option v-for=\"k in SORT_KEYS\" :key=\"k\" :value=\"k\">{{ SORT_LABELS[k] }}</option>\n </select>\n </div>\n <button class=\"btn-flat\" type=\"button\" title=\"reload\" @click=\"emit('refresh')\">\n ↻ reload\n </button>\n </div>\n</template>\n\n<style scoped>\n.pelican-toolbar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n border-bottom: 1px solid var(--line);\n background: var(--header-bg);\n}\n.btn-flat {\n background: transparent;\n border: 1px solid var(--line);\n color: var(--text);\n padding: 6px 10px;\n border-radius: 6px;\n cursor: pointer;\n font: inherit;\n}\n.btn-flat:hover {\n border-color: var(--orange);\n}\n.filters-toggle {\n display: none;\n}\n.counts {\n color: var(--muted);\n font-size: 13px;\n}\n.counts b {\n color: var(--text);\n}\n.search {\n flex: 1 1 220px;\n min-width: 160px;\n padding: 8px 12px;\n border: 1px solid var(--line);\n border-radius: 8px;\n background: var(--input-bg);\n color: var(--text);\n font: inherit;\n}\n.search:focus {\n outline: none;\n border-color: var(--orange);\n}\n.sort {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n color: var(--muted);\n font-size: 13px;\n}\n.sort select {\n padding: 6px 8px;\n border: 1px solid var(--line);\n border-radius: 6px;\n background: var(--input-bg);\n color: var(--text);\n font: inherit;\n}\n@media (max-width: 720px) {\n .filters-toggle {\n display: inline-flex;\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport type { RiskLevel } from '../../types/strategy';\n\nconst props = defineProps<{ modelValue: Set<RiskLevel> }>();\nconst emit = defineEmits<{ (e: 'update:modelValue', v: Set<RiskLevel>): void }>();\n\nconst LEVELS: RiskLevel[] = ['Low', 'Medium', 'High'];\n\nfunction toggle(level: RiskLevel) {\n const next = new Set(props.modelValue);\n if (next.has(level)) next.delete(level);\n else next.add(level);\n emit('update:modelValue', next);\n}\n</script>\n\n<template>\n <div class=\"pelican-chips\">\n <button\n v-for=\"l in LEVELS\"\n :key=\"l\"\n type=\"button\"\n class=\"chip\"\n :class=\"['risk-' + l.toLowerCase(), { on: modelValue.has(l) }]\"\n @click=\"toggle(l)\"\n >\n {{ l }}\n </button>\n </div>\n</template>\n\n<style scoped>\n.pelican-chips {\n display: flex;\n gap: 6px;\n}\n.chip {\n cursor: pointer;\n padding: 6px 10px;\n border: 1px solid var(--line);\n border-radius: 999px;\n background: var(--card);\n color: var(--text);\n font: inherit;\n font-size: 12px;\n transition: background 0.15s, border-color 0.15s;\n}\n.chip:hover {\n border-color: var(--orange);\n}\n.chip.risk-low.on {\n background: var(--chip-low-bg);\n color: var(--chip-low-text);\n border-color: var(--chip-low-bg);\n}\n.chip.risk-medium.on {\n background: var(--chip-med-bg);\n color: var(--chip-med-text);\n border-color: var(--chip-med-bg);\n}\n.chip.risk-high.on {\n background: var(--chip-high-bg);\n color: var(--chip-high-text);\n border-color: var(--chip-high-bg);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\nconst props = withDefaults(\n defineProps<{\n label: string;\n modelValue: number | null;\n min: number;\n max: number;\n step?: number;\n /** If set, format(rawValue) → display string. Otherwise raw is used. */\n format?: (v: number) => string;\n /** raw value at which the filter is \"any\" (no constraint). Default = min. */\n anyAt?: number;\n inverted?: boolean;\n }>(),\n { step: 1 },\n);\n\nconst emit = defineEmits<{ (e: 'update:modelValue', v: number | null): void }>();\n\nconst anyAt = computed(() => props.anyAt ?? props.min);\nconst inverted = computed(() => !!props.inverted);\n\nconst raw = computed<number>(() => {\n if (props.modelValue == null) return inverted.value ? props.max : anyAt.value;\n return props.modelValue;\n});\n\nconst display = computed(() => {\n if (props.modelValue == null) return 'any';\n return props.format ? props.format(props.modelValue) : String(props.modelValue);\n});\n\nfunction onInput(e: Event) {\n const v = parseInt((e.target as HTMLInputElement).value, 10);\n if (isNaN(v)) return;\n if ((inverted.value && v >= props.max) || (!inverted.value && v <= anyAt.value)) {\n emit('update:modelValue', null);\n } else {\n emit('update:modelValue', v);\n }\n}\n</script>\n\n<template>\n <div class=\"pelican-fgroup\">\n <div class=\"title-row\">\n <label class=\"title\">{{ label }}</label>\n <span class=\"val\">{{ display }}</span>\n </div>\n <input\n type=\"range\"\n class=\"range\"\n :min=\"min\"\n :max=\"max\"\n :step=\"step\"\n :value=\"raw\"\n @input=\"onInput\"\n @change=\"onInput\"\n />\n </div>\n</template>\n\n<style scoped>\n.pelican-fgroup {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.title-row {\n display: flex;\n justify-content: space-between;\n align-items: baseline;\n}\n.title {\n font-size: 12px;\n color: var(--muted);\n}\n.val {\n font-size: 12px;\n color: var(--text);\n}\n.range {\n width: 100%;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\nconst props = defineProps<{\n label: string;\n /** Raw min handle value (0..rawMax). null = no min filter. */\n modelValueMin: number | null;\n /** Raw max handle value (0..rawMax). null = no max filter. */\n modelValueMax: number | null;\n rawMin?: number;\n rawMax?: number;\n /** Format raw → display (\"$10K\" / \"200%\"). Used for both min and max. */\n formatRaw: (v: number) => string;\n /** Map raw 0..rawMax onto domain (returnFromRaw, balanceFromRaw). */\n rawToDomain: (raw: number) => number;\n scaleHints?: string[];\n minLabel?: string;\n maxLabel?: string;\n}>();\n\nconst emit = defineEmits<{\n (e: 'update:modelValueMin', v: number | null): void;\n (e: 'update:modelValueMax', v: number | null): void;\n}>();\n\nconst rawMin = computed(() => props.rawMin ?? 0);\nconst rawMax = computed(() => props.rawMax ?? 100);\n\nconst lo = computed(() => props.modelValueMin ?? rawMin.value);\nconst hi = computed(() => props.modelValueMax ?? rawMax.value);\n\nconst loLabel = computed(() =>\n lo.value <= rawMin.value ? (props.minLabel ?? 'any') : props.formatRaw(props.rawToDomain(lo.value)),\n);\nconst hiLabel = computed(() =>\n hi.value >= rawMax.value\n ? (props.maxLabel ?? 'any')\n : props.formatRaw(props.rawToDomain(hi.value)),\n);\n\nconst rangeText = computed(() => {\n if (lo.value <= rawMin.value && hi.value >= rawMax.value) return 'any';\n return `${loLabel.value} – ${hiLabel.value}`;\n});\n\nfunction onMin(e: Event) {\n let v = parseInt((e.target as HTMLInputElement).value, 10);\n if (isNaN(v)) return;\n if (v > hi.value) v = hi.value;\n emit('update:modelValueMin', v <= rawMin.value ? null : v);\n}\nfunction onMax(e: Event) {\n let v = parseInt((e.target as HTMLInputElement).value, 10);\n if (isNaN(v)) return;\n if (v < lo.value) v = lo.value;\n emit('update:modelValueMax', v >= rawMax.value ? null : v);\n}\n</script>\n\n<template>\n <div class=\"pelican-fgroup\">\n <div class=\"title-row\">\n <label class=\"title\">{{ label }}</label>\n <span class=\"val\">{{ rangeText }}</span>\n </div>\n <div class=\"dual-track\">\n <input\n type=\"range\"\n class=\"range-dual\"\n :min=\"rawMin\"\n :max=\"rawMax\"\n :value=\"lo\"\n @input=\"onMin\"\n @change=\"onMin\"\n />\n <input\n type=\"range\"\n class=\"range-dual\"\n :min=\"rawMin\"\n :max=\"rawMax\"\n :value=\"hi\"\n @input=\"onMax\"\n @change=\"onMax\"\n />\n </div>\n <div v-if=\"scaleHints?.length\" class=\"scale\">\n <span v-for=\"h in scaleHints\" :key=\"h\">{{ h }}</span>\n </div>\n </div>\n</template>\n\n<style scoped>\n.pelican-fgroup {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.title-row {\n display: flex;\n justify-content: space-between;\n align-items: baseline;\n}\n.title {\n font-size: 12px;\n color: var(--muted);\n}\n.val {\n font-size: 12px;\n color: var(--text);\n}\n.dual-track {\n position: relative;\n height: 24px;\n display: flex;\n align-items: center;\n}\n.dual-track .range-dual {\n position: absolute;\n inset: 0;\n width: 100%;\n background: transparent;\n pointer-events: auto;\n}\n.scale {\n display: flex;\n justify-content: space-between;\n color: var(--muted);\n font-size: 11px;\n margin-top: 2px;\n}\n</style>\n","export type FormatLocale = string;\n\nexport interface FmtPctResult {\n text: string;\n positive: boolean;\n}\n\nexport function fmtPct(v: number | null | undefined, d = 2): FmtPctResult | null {\n if (v == null || isNaN(Number(v))) return null;\n const n = Number(v);\n return { text: `${n.toFixed(d)}%`, positive: n >= 0 };\n}\n\nexport function fmtMoney(v: number | null | undefined, locale: FormatLocale = 'en-US'): string {\n if (v == null || isNaN(Number(v))) return '—';\n const n = Number(v);\n const sign = n < 0 ? '-' : '';\n const abs = Math.abs(n);\n let s: string;\n if (abs >= 1e6) s = (abs / 1e6).toFixed(2) + 'M';\n else if (abs >= 1e3) s = Math.round(abs).toLocaleString(locale);\n else s = abs.toFixed(2);\n return `${sign}$${s}`;\n}\n\nexport function fmtMoneyFull(v: number | null | undefined, locale: FormatLocale = 'en-US'): string {\n if (v == null || isNaN(Number(v))) return '—';\n const n = Number(v);\n return `${n < 0 ? '-' : ''}$${Math.abs(n).toLocaleString(locale, {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n })}`;\n}\n\nexport function fmtNum(v: number | null | undefined, locale: FormatLocale = 'en-US'): string {\n return v == null ? '—' : Number(v).toLocaleString(locale);\n}\n\nexport function fmtFee(s: { Fee: number | null; _meta?: boolean }): string {\n if (s.Fee == null) {\n return s._meta ? 'free' : '—';\n }\n return `${(s.Fee * 100).toFixed(0)}%`;\n}\n\nexport function fmtTradeTime(iso: string | null | undefined, locale: FormatLocale = 'en-US'): string {\n if (!iso) return '—';\n const d = new Date(iso);\n if (isNaN(d.getTime())) return '—';\n return d.toLocaleString(locale, {\n year: '2-digit',\n month: 'short',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n hour12: false,\n });\n}\n\nexport function fmtAge(days: number | null): string {\n if (days == null) return '—';\n if (days < 30) return `${days}d`;\n const months = Math.floor(days / 30);\n if (months < 12) return `${months}mo`;\n const years = Math.floor(days / 365);\n const remMonths = Math.floor((days - years * 365) / 30);\n return remMonths ? `${years}y ${remMonths}mo` : `${years}y`;\n}\n\nexport function fmtAUM(v: number): string {\n if (v >= 1e6) return '$' + (v / 1e6).toFixed(2) + 'M';\n if (v >= 1e3) return '$' + Math.round(v / 1e3) + 'K';\n return '$' + Math.round(v);\n}\n\nexport function fmtRetMag(v: number): string {\n if (v >= 1000) {\n return (v / 1000).toFixed(1).replace(/\\.0$/, '') + 'K%';\n }\n return Math.round(v) + '%';\n}\n\nexport function escapeHtml(s: string | null | undefined): string {\n if (s == null) return '';\n return String(s)\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\nexport function initials(name: string | null | undefined): string {\n if (!name) return '?';\n const parts = name.trim().split(/\\s+/).slice(0, 2);\n return parts.map((p) => p.charAt(0).toUpperCase()).join('') || '?';\n}\n\nexport function ageDays(inception: string | null | undefined): number | null {\n if (!inception) return null;\n const d = new Date(inception);\n if (isNaN(d.getTime())) return null;\n return Math.floor((Date.now() - d.getTime()) / 86400000);\n}\n","// Ported from app.js:622-629.\n// Balance slider: log scale [10, 10^7] mapped to [0..100] raw ticks.\n// Return slider: log scale [10, 10^4.7 ~= 50000] mapped to [0..100] raw ticks.\n\nexport const balanceFromRaw = (v: number): number =>\n v <= 0 ? 0 : Math.round(Math.pow(10, 1 + ((v - 1) / 99) * 6));\n\nexport const rawFromBalance = (b: number): number =>\n b <= 0 ? 0 : Math.max(1, Math.min(100, Math.round(1 + ((Math.log10(b) - 1) * 99) / 6)));\n\nexport const returnFromRaw = (v: number): number =>\n v <= 0 ? 0 : Math.round(Math.pow(10, ((v - 1) / 99) * 4.7));\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { fmtAUM } from '../../utils/format';\nimport { rawFromBalance } from '../../utils/scales';\n\nconst props = defineProps<{\n modelValue: number | null;\n}>();\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', v: number | null): void;\n (e: 'apply', balance: { min: number; max: number } | null): void;\n}>();\n\nconst display = computed(() =>\n props.modelValue == null ? 'any' : fmtAUM(props.modelValue),\n);\n\nfunction onChange(e: Event) {\n const raw = (e.target as HTMLInputElement).value.trim();\n if (!raw) {\n emit('update:modelValue', null);\n emit('apply', null);\n return;\n }\n const v = parseInt(raw, 10);\n if (isNaN(v) || v <= 0) {\n emit('update:modelValue', null);\n emit('apply', null);\n return;\n }\n emit('update:modelValue', v);\n emit('apply', { min: rawFromBalance(50), max: rawFromBalance(v) });\n}\n</script>\n\n<template>\n <div class=\"pelican-fgroup\">\n <div class=\"title-row\">\n <label class=\"title\">Your Investment Amount, $</label>\n <span class=\"val\">{{ display }}</span>\n </div>\n <input\n type=\"number\"\n :min=\"50\"\n :step=\"50\"\n placeholder=\"e.g. 5000\"\n autocomplete=\"off\"\n :value=\"modelValue ?? ''\"\n @change=\"onChange\"\n />\n </div>\n</template>\n\n<style scoped>\n.pelican-fgroup {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.title-row {\n display: flex;\n justify-content: space-between;\n align-items: baseline;\n}\n.title {\n font-size: 12px;\n color: var(--muted);\n}\n.val {\n font-size: 12px;\n color: var(--text);\n}\ninput {\n width: 100%;\n padding: 8px 10px;\n border: 1px solid var(--line);\n border-radius: 6px;\n background: var(--input-bg);\n color: var(--text);\n font: inherit;\n}\ninput:focus {\n outline: none;\n border-color: var(--orange);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { ref, watch } from 'vue';\nimport RiskChips from './filters/RiskChips.vue';\nimport RangeSingle from './filters/RangeSingle.vue';\nimport RangeDual from './filters/RangeDual.vue';\nimport InvestAmount from './filters/InvestAmount.vue';\nimport type { FiltersState } from '../types/filters';\nimport type { RiskLevel } from '../types/strategy';\nimport { fmtAUM, fmtRetMag } from '../utils/format';\nimport { balanceFromRaw, returnFromRaw } from '../utils/scales';\n\nconst props = defineProps<{\n filters: FiltersState;\n investAmount: number | null;\n open: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: 'update:filters', f: Partial<FiltersState>): void;\n (e: 'update:investAmount', v: number | null): void;\n (e: 'reset'): void;\n}>();\n\n// Dual-range sliders need raw 0..100 positions held *here*, not derived from\n// `filters.retMin/retMax` (the slider's log scale isn't trivially invertible\n// per-tick, and round-tripping reactively would jitter the handle). We keep\n// the raw positions here and only push the domain values up to the parent's\n// FiltersState. When the parent resets filters externally, the watchers below\n// snap raw positions back to the extremes.\nconst retRawMin = ref<number>(0);\nconst retRawMax = ref<number>(100);\nconst balRawMin = ref<number>(0);\nconst balRawMax = ref<number>(100);\n\nwatch(retRawMin, (v) => {\n emit('update:filters', { retMin: v <= 0 ? null : returnFromRaw(v) });\n});\nwatch(retRawMax, (v) => {\n emit('update:filters', { retMax: v >= 100 ? null : returnFromRaw(v) });\n});\nwatch(balRawMin, (v) => {\n emit('update:filters', { balanceMin: v <= 0 ? null : balanceFromRaw(v) });\n});\nwatch(balRawMax, (v) => {\n emit('update:filters', { balanceMax: v >= 100 ? null : balanceFromRaw(v) });\n});\n\n// External reset (parent's `resetFilters` or InvestAmount-clear) → snap handles.\nwatch(\n () => [props.filters.retMin, props.filters.retMax],\n ([lo, hi]) => {\n if (lo == null) retRawMin.value = 0;\n if (hi == null) retRawMax.value = 100;\n },\n);\nwatch(\n () => [props.filters.balanceMin, props.filters.balanceMax],\n ([lo, hi]) => {\n if (lo == null) balRawMin.value = 0;\n if (hi == null) balRawMax.value = 100;\n },\n);\n\nfunction patch(p: Partial<FiltersState>) {\n emit('update:filters', p);\n}\nfunction setRisk(v: Set<RiskLevel>) {\n patch({ risk: v });\n}\n\nfunction applyInvest(range: { min: number; max: number } | null) {\n if (range == null) {\n patch({ balanceMin: null, balanceMax: null });\n balRawMin.value = 0;\n balRawMax.value = 100;\n } else {\n balRawMin.value = range.min;\n balRawMax.value = range.max;\n // The watchers above will fire and propagate to filters.balanceMin/Max.\n }\n}\n</script>\n\n<template>\n <aside class=\"pelican-filters\" :class=\"{ open }\">\n <div class=\"ftitle-row\">\n <label class=\"ftitle\">Risk</label>\n <button class=\"btn-reset\" type=\"button\" @click=\"emit('reset')\">reset filters</button>\n </div>\n <RiskChips :model-value=\"filters.risk\" @update:model-value=\"setRisk\" />\n\n <InvestAmount\n :model-value=\"investAmount\"\n @update:model-value=\"(v) => emit('update:investAmount', v)\"\n @apply=\"applyInvest\"\n />\n\n <RangeDual\n label=\"Return %\"\n :model-value-min=\"retRawMin\"\n :model-value-max=\"retRawMax\"\n :format-raw=\"(v) => fmtRetMag(v)\"\n :raw-to-domain=\"(raw) => returnFromRaw(raw)\"\n :scale-hints=\"['0%', '200%', '50K%+']\"\n max-label=\"50K%+\"\n @update:model-value-min=\"(v) => (retRawMin = v ?? 0)\"\n @update:model-value-max=\"(v) => (retRawMax = v ?? 100)\"\n />\n\n <RangeSingle\n label=\"Max Drawdown ≤\"\n :model-value=\"filters.ddMax\"\n :min=\"0\"\n :max=\"100\"\n :step=\"5\"\n :any-at=\"100\"\n :inverted=\"true\"\n :format=\"(v) => v + '%'\"\n @update:model-value=\"(v) => patch({ ddMax: v == null || v >= 100 ? null : v })\"\n />\n\n <RangeDual\n label=\"Balance\"\n :model-value-min=\"balRawMin\"\n :model-value-max=\"balRawMax\"\n :format-raw=\"(v) => fmtAUM(v)\"\n :raw-to-domain=\"(raw) => balanceFromRaw(raw)\"\n :scale-hints=\"['$0', '$10K', '$10M']\"\n max-label=\"$10M+\"\n @update:model-value-min=\"(v) => (balRawMin = v ?? 0)\"\n @update:model-value-max=\"(v) => (balRawMax = v ?? 100)\"\n />\n\n <RangeSingle\n label=\"Mgmt Fee ≤\"\n :model-value=\"filters.feeMax\"\n :min=\"0\"\n :max=\"100\"\n :step=\"5\"\n :any-at=\"100\"\n :inverted=\"true\"\n :format=\"(v) => v + '%'\"\n @update:model-value=\"(v) => patch({ feeMax: v == null || v >= 100 ? null : v })\"\n />\n\n <RangeSingle\n label=\"Copiers AUM ≥\"\n :model-value=\"filters.aumMin\"\n :min=\"0\"\n :max=\"5000000\"\n :step=\"50000\"\n :format=\"(v) => '≥ ' + fmtAUM(v)\"\n @update:model-value=\"(v) => patch({ aumMin: v && v > 0 ? v : null })\"\n />\n\n <RangeSingle\n label=\"Copiers ≥\"\n :model-value=\"filters.copiersMin\"\n :min=\"0\"\n :max=\"3000\"\n :step=\"10\"\n :format=\"(v) => '≥ ' + v\"\n @update:model-value=\"(v) => patch({ copiersMin: v && v > 0 ? v : null })\"\n />\n\n <RangeSingle\n label=\"Age ≥ (days)\"\n :model-value=\"filters.ageMin\"\n :min=\"0\"\n :max=\"3000\"\n :step=\"10\"\n :format=\"(v) => '≥ ' + v + 'd'\"\n @update:model-value=\"(v) => patch({ ageMin: v && v > 0 ? v : null })\"\n />\n\n <RangeSingle\n label=\"Trades ≥\"\n :model-value=\"filters.tradesMin\"\n :min=\"0\"\n :max=\"10000\"\n :step=\"50\"\n :format=\"(v) => '≥ ' + v\"\n @update:model-value=\"(v) => patch({ tradesMin: v && v > 0 ? v : null })\"\n />\n\n <RangeSingle\n label=\"Win Rate ≥\"\n :model-value=\"filters.winrateMin\"\n :min=\"0\"\n :max=\"100\"\n :step=\"5\"\n :format=\"(v) => '≥ ' + v + '%'\"\n @update:model-value=\"(v) => patch({ winrateMin: v && v > 0 ? v : null })\"\n />\n </aside>\n</template>\n\n<style scoped>\n.pelican-filters {\n display: flex;\n flex-direction: column;\n gap: 18px;\n padding: 16px;\n border-right: 1px solid var(--line);\n background: var(--card);\n width: 260px;\n flex: none;\n}\n.ftitle-row {\n display: flex;\n justify-content: space-between;\n align-items: baseline;\n}\n.ftitle {\n font-size: 13px;\n font-weight: 600;\n color: var(--text);\n}\n.btn-reset {\n background: transparent;\n border: none;\n color: var(--orange);\n font: inherit;\n font-size: 12px;\n cursor: pointer;\n padding: 0;\n}\n.btn-reset:hover {\n text-decoration: underline;\n}\n\n@media (max-width: 720px) {\n .pelican-filters {\n display: none;\n width: 100%;\n border-right: none;\n border-bottom: 1px solid var(--line);\n }\n .pelican-filters.open {\n display: flex;\n }\n}\n</style>\n","export const DONUT_PALETTE: string[] = [\n '#f97316',\n '#3b82f6',\n '#10b981',\n '#a855f7',\n '#ef4444',\n '#eab308',\n '#06b6d4',\n '#ec4899',\n '#14b8a6',\n '#8b5cf6',\n '#f59e0b',\n '#22c55e',\n];\n","import { DONUT_PALETTE } from '../constants/palette';\nimport type { HistoryPoint, MarketSlice } from '../types/strategy';\n\nexport type SparklinePoint = HistoryPoint;\n\nexport interface SparklineGeometry {\n hasData: boolean;\n width: number;\n height: number;\n zeroY: number;\n areaPath: string;\n linePath: string;\n positive: boolean;\n startX: number;\n endX: number;\n}\n\nexport function sparklineGeometry(\n history: SparklinePoint[] | null | undefined,\n w = 140,\n h = 34,\n): SparklineGeometry {\n if (!history || history.length < 2) {\n return {\n hasData: false,\n width: w,\n height: h,\n zeroY: h / 2,\n areaPath: '',\n linePath: '',\n positive: true,\n startX: 1,\n endX: w - 1,\n };\n }\n const times = history.map((p) => Date.parse(p.Timestamp));\n const tMin = times[0];\n const tMax = times[times.length - 1];\n const tSpan = tMax - tMin || 1;\n const ys = history.map((p) => p.AccountReturn);\n const yMin = Math.min(0, ...ys);\n const yMax = Math.max(0, ...ys);\n const yRange = yMax - yMin || 1;\n const px = (t: number) => ((t - tMin) / tSpan) * (w - 2) + 1;\n const py = (v: number) => h - 2 - ((v - yMin) / yRange) * (h - 4);\n const pts = history.map((p, i) => `${px(times[i]).toFixed(1)},${py(p.AccountReturn).toFixed(1)}`);\n const last = ys[ys.length - 1];\n const zeroY = py(0);\n const startX = px(tMin);\n const endX = px(tMax);\n const linePath = `M ${pts.join(' L ')}`;\n const areaPath =\n `M ${pts[0]} ` +\n pts.slice(1).map((p) => `L ${p}`).join(' ') +\n ` L ${endX.toFixed(1)},${zeroY.toFixed(1)} L ${startX.toFixed(1)},${zeroY.toFixed(1)} Z`;\n return {\n hasData: true,\n width: w,\n height: h,\n zeroY,\n areaPath,\n linePath,\n positive: last >= 0,\n startX,\n endX,\n };\n}\n\nexport interface DonutSlice {\n marketName: string;\n count: number;\n fraction: number;\n color: string;\n arcPath: string;\n labelLine: string | null;\n labelX: number;\n labelY: number;\n labelAnchor: 'start' | 'end';\n}\n\nexport interface DonutGeometry {\n width: number;\n height: number;\n cx: number;\n cy: number;\n outerR: number;\n innerR: number;\n slices: DonutSlice[];\n}\n\nexport function donutGeometry(items: MarketSlice[], w = 520, h = 280): DonutGeometry {\n const sorted = items.slice().sort((a, b) => (b.c || 0) - (a.c || 0));\n const total = sorted.reduce((acc, m) => acc + (m.c || 0), 0) || 1;\n const cx = w / 2;\n const cy = h / 2;\n const R = 90;\n const r = 52;\n const labelR = R + 10;\n const labelText = R + 30;\n\n let angle = -Math.PI / 2;\n const slices: DonutSlice[] = [];\n sorted.forEach((m, i) => {\n const frac = (m.c || 0) / total;\n const sweep = frac * Math.PI * 2;\n const a0 = angle;\n const a1 = angle + sweep;\n angle = a1;\n const aMid = (a0 + a1) / 2;\n const large = sweep > Math.PI ? 1 : 0;\n const x0 = cx + R * Math.cos(a0);\n const y0 = cy + R * Math.sin(a0);\n const x1 = cx + R * Math.cos(a1);\n const y1 = cy + R * Math.sin(a1);\n const xi0 = cx + r * Math.cos(a0);\n const yi0 = cy + r * Math.sin(a0);\n const xi1 = cx + r * Math.cos(a1);\n const yi1 = cy + r * Math.sin(a1);\n const arcPath =\n `M ${x0.toFixed(2)} ${y0.toFixed(2)} A ${R} ${R} 0 ${large} 1 ${x1.toFixed(2)} ${y1.toFixed(2)}` +\n ` L ${xi1.toFixed(2)} ${yi1.toFixed(2)} A ${r} ${r} 0 ${large} 0 ${xi0.toFixed(2)} ${yi0.toFixed(2)} Z`;\n const color = DONUT_PALETTE[i % DONUT_PALETTE.length];\n\n let labelLine: string | null = null;\n let labelX = 0;\n let labelY = 0;\n let labelAnchor: 'start' | 'end' = 'start';\n if (frac >= 0.015) {\n const isLeft = Math.cos(aMid) < 0;\n const lx1 = cx + R * Math.cos(aMid);\n const ly1 = cy + R * Math.sin(aMid);\n const lx2 = cx + labelR * Math.cos(aMid);\n const ly2 = cy + labelR * Math.sin(aMid);\n const lx3 = isLeft ? lx2 - 4 : lx2 + 4;\n labelLine = `${lx1.toFixed(1)},${ly1.toFixed(1)} ${lx2.toFixed(1)},${ly2.toFixed(1)} ${lx3.toFixed(1)},${ly2.toFixed(1)}`;\n labelX = isLeft ? lx2 - 6 : lx2 + 6;\n labelY = ly2 + 4;\n labelAnchor = isLeft ? 'end' : 'start';\n }\n\n slices.push({\n marketName: m.n,\n count: m.c,\n fraction: frac,\n color,\n arcPath,\n labelLine,\n labelX,\n labelY,\n labelAnchor,\n });\n });\n\n // labelText is intentionally part of geometry to keep callers free of magic numbers.\n void labelText;\n\n return { width: w, height: h, cx, cy, outerR: R, innerR: r, slices };\n}\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { sparklineGeometry } from '../utils/svg';\nimport type { HistoryPoint } from '../types/strategy';\n\nconst props = withDefaults(\n defineProps<{\n history: HistoryPoint[] | null | undefined;\n width?: number;\n height?: number;\n }>(),\n { width: 140, height: 34 },\n);\n\nconst geom = computed(() => sparklineGeometry(props.history, props.width, props.height));\n</script>\n\n<template>\n <svg\n v-if=\"!geom.hasData\"\n class=\"pelican-spark\"\n :width=\"geom.width\"\n :height=\"geom.height\"\n role=\"img\"\n aria-label=\"No equity data\"\n >\n <text x=\"2\" y=\"20\" font-size=\"11\" fill=\"var(--spark-no-data)\">no data</text>\n </svg>\n <svg\n v-else\n class=\"pelican-spark\"\n :width=\"geom.width\"\n :height=\"geom.height\"\n :viewBox=\"`0 0 ${geom.width} ${geom.height}`\"\n preserveAspectRatio=\"none\"\n role=\"img\"\n aria-label=\"Equity curve\"\n >\n <line\n x1=\"0\"\n :x2=\"geom.width\"\n :y1=\"geom.zeroY\"\n :y2=\"geom.zeroY\"\n stroke=\"var(--grid-line)\"\n stroke-dasharray=\"2 3\"\n stroke-width=\"1\"\n vector-effect=\"non-scaling-stroke\"\n />\n <path\n :d=\"geom.areaPath\"\n :fill=\"geom.positive ? 'var(--area-green)' : 'var(--area-red)'\"\n stroke=\"none\"\n />\n <path\n :d=\"geom.linePath\"\n fill=\"none\"\n :stroke=\"geom.positive ? 'var(--green)' : 'var(--red)'\"\n stroke-width=\"1.6\"\n stroke-linejoin=\"round\"\n stroke-linecap=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n </svg>\n</template>\n\n<style scoped>\n.pelican-spark {\n display: block;\n width: 100%;\n max-width: 100%;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { MarketSlice } from '../types/strategy';\nimport { donutGeometry } from '../utils/svg';\n\nconst props = withDefaults(\n defineProps<{\n markets: MarketSlice[];\n width?: number;\n height?: number;\n }>(),\n { width: 520, height: 280 },\n);\n\nconst empty = computed(() => !props.markets || props.markets.length === 0);\nconst geom = computed(() => donutGeometry(props.markets, props.width, props.height));\n</script>\n\n<template>\n <span v-if=\"empty\" class=\"dim\">no market data</span>\n <svg\n v-else\n class=\"pelican-donut\"\n :viewBox=\"`0 0 ${geom.width} ${geom.height}`\"\n width=\"100%\"\n preserveAspectRatio=\"xMidYMid meet\"\n role=\"img\"\n aria-label=\"Markets donut chart\"\n >\n <g>\n <path\n v-for=\"s in geom.slices\"\n :key=\"s.marketName + s.fraction\"\n :d=\"s.arcPath\"\n :fill=\"s.color\"\n stroke=\"var(--card)\"\n stroke-width=\"1.5\"\n />\n </g>\n <g>\n <polyline\n v-for=\"s in geom.slices\"\n :key=\"`l-${s.marketName}`\"\n v-show=\"s.labelLine\"\n :points=\"s.labelLine ?? ''\"\n :stroke=\"s.color\"\n stroke-width=\"1\"\n fill=\"none\"\n />\n </g>\n <g>\n <text\n v-for=\"s in geom.slices\"\n :key=\"`t-${s.marketName}`\"\n v-show=\"s.labelLine\"\n :x=\"s.labelX\"\n :y=\"s.labelY\"\n :text-anchor=\"s.labelAnchor\"\n font-size=\"11\"\n fill=\"var(--text)\"\n font-weight=\"500\"\n >\n {{ s.marketName }}\n <tspan fill=\"var(--muted)\" font-weight=\"400\">{{ s.count }}</tspan>\n </text>\n </g>\n </svg>\n</template>\n\n<style scoped>\n.pelican-donut {\n display: block;\n width: 100%;\n max-width: 100%;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { SignalKind } from '../types/api';\nimport type { Trade } from '../types/strategy';\nimport { fmtTradeTime, fmtMoneyFull } from '../utils/format';\n\nconst props = defineProps<{\n kind: SignalKind;\n trades: Trade[] | null;\n loading: boolean;\n locale: string;\n}>();\n\nconst title = computed(() => (props.kind === 'open' ? 'Open Trades' : 'Trade History (30d)'));\nconst empty = computed(\n () => !props.loading && (props.trades == null || props.trades.length === 0),\n);\n</script>\n\n<template>\n <div class=\"pelican-trades\">\n <div class=\"hd\">{{ title }}</div>\n <div v-if=\"loading\" class=\"dim\">Loading…</div>\n <div v-else-if=\"empty\" class=\"dim\">No trades.</div>\n <ul v-else class=\"list\">\n <li v-for=\"(t, i) in trades ?? []\" :key=\"i\">\n <span class=\"market\">{{ t.MarketName ?? '—' }}</span>\n <span class=\"dir\" :class=\"t.Direction === 'Sell' ? 'red' : 'green'\">{{ t.Direction ?? '' }}</span>\n <span class=\"trade-time\">\n {{ fmtTradeTime(t.OpenTimestamp, locale) }}\n <template v-if=\"t.CloseTimestamp\"> → {{ fmtTradeTime(t.CloseTimestamp, locale) }}</template>\n </span>\n <span v-if=\"t.Pnl != null\" class=\"pnl\" :class=\"t.Pnl >= 0 ? 'green' : 'red'\">\n {{ fmtMoneyFull(t.Pnl, locale) }}\n </span>\n </li>\n </ul>\n </div>\n</template>\n\n<style scoped>\n.pelican-trades {\n padding: 12px 16px;\n background: var(--sage-2);\n border-radius: 8px;\n}\n.hd {\n font-weight: 600;\n margin-bottom: 8px;\n color: var(--text);\n}\n.list {\n list-style: none;\n padding: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n font-size: 12px;\n}\n.list li {\n display: grid;\n grid-template-columns: minmax(80px, 1.4fr) auto 1.6fr auto;\n gap: 8px;\n align-items: baseline;\n}\n.market {\n color: var(--text);\n font-weight: 500;\n}\n.dir {\n font-weight: 600;\n text-transform: uppercase;\n font-size: 10px;\n}\n.trade-time {\n color: var(--muted);\n}\n.pnl {\n font-variant-numeric: tabular-nums;\n text-align: right;\n}\n.green {\n color: var(--green);\n}\n.red {\n color: var(--red);\n}\n.dim {\n color: var(--muted);\n}\n</style>\n","import type { Strategy } from '../types/strategy';\n\nexport function winrate(s: Pick<Strategy, 'Wins' | 'Losses'>): number {\n const wins = s.Wins ?? 0;\n const losses = s.Losses ?? 0;\n const t = wins + losses;\n return t ? (wins / t) * 100 : -1;\n}\n","import type { InjectionKey } from 'vue';\n\nexport type ApiBaseKey = string;\nexport type LocaleKey = string;\n\nexport const API_BASE_KEY: InjectionKey<ApiBaseKey> = Symbol('pelican.apiBase');\nexport const LOCALE_KEY: InjectionKey<LocaleKey> = Symbol('pelican.locale');\n","<script setup lang=\"ts\">\nimport { computed, inject, ref } from 'vue';\nimport Sparkline from './Sparkline.vue';\nimport MarketsDonut from './MarketsDonut.vue';\nimport TradesPanel from './TradesPanel.vue';\nimport type { Strategy } from '../types/strategy';\nimport type { SignalKind } from '../types/api';\nimport {\n ageDays,\n fmtAge,\n fmtFee,\n fmtMoney,\n fmtMoneyFull,\n fmtNum,\n fmtPct,\n initials,\n} from '../utils/format';\nimport { winrate } from '../utils/winrate';\nimport { LOCALE_KEY } from '../injection-keys';\n\nconst props = defineProps<{\n s: Strategy;\n expanded: boolean;\n openTrades: { loading: boolean; trades: import('../types/strategy').Trade[] | null } | null;\n closedTrades: { loading: boolean; trades: import('../types/strategy').Trade[] | null } | null;\n}>();\n\nconst emit = defineEmits<{\n (e: 'toggle'): void;\n (e: 'load-trades', kind: SignalKind): void;\n (e: 'select'): void;\n}>();\n\nconst locale = inject(LOCALE_KEY, 'en-US');\n\nconst ret = computed(() => fmtPct(props.s.Return, 1));\nconst dd = computed(() => (props.s.MaxDD != null ? fmtPct(props.s.MaxDD, 2) : null));\nconst age = computed(() => ageDays(props.s.Inception));\nconst wr = computed(() => winrate(props.s));\nconst lr = computed(() => (wr.value >= 0 ? 100 - wr.value : -1));\nconst profileName = computed(\n () => props.s.Profile?.Name ?? (props.s.Profile?.Id ? '#' + props.s.Profile.Id : ''),\n);\nconst link = computed(() => `https://libertex.copy-trade.io/strategy/${props.s.Id}`);\n\nconst showOpen = ref(false);\nconst showClosed = ref(false);\n\nfunction toggleOpen() {\n showOpen.value = !showOpen.value;\n if (showOpen.value && !props.openTrades) emit('load-trades', 'open');\n}\nfunction toggleClosed() {\n showClosed.value = !showClosed.value;\n if (showClosed.value && !props.closedTrades) emit('load-trades', 'closed');\n}\n</script>\n\n<template>\n <div class=\"pelican-row\" :class=\"{ open: expanded }\" :data-id=\"s.Id\" @click=\"emit('toggle')\">\n <div class=\"name\">\n <div class=\"avatar\">\n <span class=\"avatar-fallback\">{{ initials(s.Name) }}</span>\n <img\n v-if=\"s.ImageUploaded\"\n class=\"avatar-img\"\n :src=\"`https://assets.copy-trade.io/images/strategies/thumbnails/${s.Id}`\"\n alt=\"\"\n loading=\"lazy\"\n decoding=\"async\"\n @error=\"($event.target as HTMLImageElement).remove()\"\n />\n </div>\n <div class=\"nm\">\n <div class=\"title\">\n {{ s.Name || '#' + s.Id }}\n <span v-if=\"s._meta && s.Fee == null\" class=\"free-badge\">free</span>\n </div>\n <div class=\"by\">{{ profileName }}</div>\n </div>\n </div>\n <div class=\"c-spark\" data-label=\"Equity curve\">\n <Sparkline :history=\"s.History\" />\n </div>\n <div class=\"c-num\" data-label=\"Return\">\n <span v-if=\"ret\" :class=\"ret.positive ? 'green' : 'red'\">{{ ret.text }}</span>\n <span v-else>—</span>\n </div>\n <div class=\"c-num\" data-label=\"Copiers\">{{ fmtNum(s.NumCopiers, locale) }}</div>\n <div class=\"c-num\" data-label=\"Copiers AUM\">{{ fmtMoney(s.CopiersAUM, locale) }}</div>\n <div class=\"c-num\" data-label=\"Max DD\">\n <span v-if=\"dd\" :class=\"dd.positive ? 'green' : 'red'\">{{ dd.text }}</span>\n <span v-else>—</span>\n </div>\n <div class=\"c-num\" data-label=\"Age\">{{ fmtAge(age) }}</div>\n <div class=\"c-num\" data-label=\"Balance\">{{ fmtMoney(s.AccountBalance, locale) }}</div>\n <div class=\"c-num\" data-label=\"Fee\">{{ fmtFee(s) }}</div>\n <div class=\"c-link\" @click.stop>\n <a class=\"signal-link\" :href=\"link\" target=\"_blank\" rel=\"noopener\" @click.stop>\n Get connected\n </a>\n <slot name=\"row-actions\" :strategy=\"s\" />\n </div>\n </div>\n\n <div v-if=\"expanded\" class=\"pelican-row-expanded\" @click.stop>\n <div class=\"grid\">\n <div class=\"col-stats\">\n <div class=\"field\"><div class=\"label\">Currency</div><div class=\"value\">{{ s.Currency ?? 'USD' }}</div></div>\n <div class=\"field\"><div class=\"label\">Monthly profit</div><div class=\"value\">{{ fmtMoneyFull(s.MonthlyProfit, locale) }}</div></div>\n <div class=\"field\"><div class=\"label\">Yearly profit</div><div class=\"value\">{{ fmtMoneyFull(s.YearlyProfit, locale) }}</div></div>\n <div class=\"field\"><div class=\"label\">Balance</div><div class=\"value\">{{ fmtMoneyFull(s.AccountBalance, locale) }}</div></div>\n <div class=\"field\"><div class=\"label\">Realized P/L</div><div class=\"value\">{{ fmtMoneyFull(s.RealisedPnl, locale) }}</div></div>\n <div class=\"field\"><div class=\"label\">Unrealized P/L</div><div class=\"value\">{{ fmtMoneyFull(s.UnrealisedPnl, locale) }}</div></div>\n <div class=\"field\"><div class=\"label\">Trades total</div><div class=\"value\">{{ fmtNum(s.TradesTotal, locale) }}</div></div>\n <div class=\"field\">\n <div class=\"label\">Win rate</div>\n <div class=\"value\">\n <span v-if=\"wr >= 0\">{{ wr.toFixed(1) }}% / {{ lr.toFixed(1) }}%</span>\n <span v-else class=\"dim\">—</span>\n </div>\n </div>\n </div>\n <div class=\"col-donut\">\n <div class=\"hd\">Markets</div>\n <MarketsDonut :markets=\"s.Markets\" />\n </div>\n </div>\n\n <div class=\"trade-toggles\">\n <button class=\"pill\" :class=\"{ on: showOpen }\" type=\"button\" @click=\"toggleOpen\">\n {{ showOpen ? 'Hide' : 'Open Trades' }}\n </button>\n <button class=\"pill\" :class=\"{ on: showClosed }\" type=\"button\" @click=\"toggleClosed\">\n {{ showClosed ? 'Hide' : 'Trade History' }}\n </button>\n </div>\n\n <TradesPanel\n v-if=\"showOpen\"\n kind=\"open\"\n :trades=\"openTrades?.trades ?? null\"\n :loading=\"!!openTrades?.loading\"\n :locale=\"locale\"\n />\n <TradesPanel\n v-if=\"showClosed\"\n kind=\"closed\"\n :trades=\"closedTrades?.trades ?? null\"\n :loading=\"!!closedTrades?.loading\"\n :locale=\"locale\"\n />\n </div>\n</template>\n\n<style scoped>\n.pelican-row {\n display: grid;\n grid-template-columns: minmax(160px, 1.6fr) minmax(120px, 1fr) repeat(7, minmax(70px, 0.8fr)) auto;\n gap: 12px;\n align-items: center;\n padding: 10px 16px;\n border-bottom: 1px solid var(--line-2);\n cursor: pointer;\n transition: background 0.15s;\n}\n.pelican-row:hover {\n background: var(--row-hover);\n}\n.pelican-row.open {\n background: var(--row-hover);\n}\n.name {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n.avatar {\n position: relative;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: var(--sage);\n color: var(--text-2);\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n flex: none;\n overflow: hidden;\n}\n.avatar-img {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n.title {\n font-weight: 600;\n color: var(--text);\n}\n.by {\n color: var(--muted);\n font-size: 12px;\n}\n.free-badge {\n margin-left: 6px;\n background: var(--chip-low-bg);\n color: var(--chip-low-text);\n font-size: 10px;\n padding: 1px 6px;\n border-radius: 999px;\n font-weight: 700;\n}\n.c-num {\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n.c-link {\n text-align: right;\n}\n.signal-link {\n color: var(--orange);\n text-decoration: none;\n font-size: 12px;\n}\n.signal-link:hover {\n text-decoration: underline;\n}\n.green {\n color: var(--green);\n}\n.red {\n color: var(--red);\n}\n.dim {\n color: var(--muted);\n}\n\n.pelican-row-expanded {\n padding: 16px;\n background: var(--sage-2);\n border-bottom: 1px solid var(--line);\n display: flex;\n flex-direction: column;\n gap: 14px;\n}\n.grid {\n display: grid;\n grid-template-columns: minmax(220px, 1fr) minmax(280px, 1.2fr);\n gap: 16px;\n}\n.col-stats {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 12px 16px;\n}\n.field .label {\n color: var(--muted);\n font-size: 12px;\n}\n.field .value {\n color: var(--text);\n font-weight: 500;\n}\n.col-donut .hd {\n font-weight: 600;\n color: var(--text);\n margin-bottom: 6px;\n}\n.trade-toggles {\n display: flex;\n gap: 8px;\n}\n.pill {\n cursor: pointer;\n padding: 6px 14px;\n border-radius: 999px;\n border: 1px solid var(--line);\n background: var(--card);\n color: var(--text);\n font: inherit;\n font-size: 12px;\n}\n.pill.on {\n background: var(--orange);\n border-color: var(--orange);\n color: #fff;\n}\n\n@media (max-width: 720px) {\n .pelican-row {\n grid-template-columns: 1fr;\n gap: 4px;\n }\n .pelican-row > [data-label]::before {\n content: attr(data-label);\n color: var(--muted);\n margin-right: 8px;\n font-size: 11px;\n }\n .grid {\n grid-template-columns: 1fr;\n }\n}\n</style>\n","<script setup lang=\"ts\">\nconst props = defineProps<{\n page: number;\n totalPages: number;\n range: (number | '…')[];\n}>();\n\nconst emit = defineEmits<{\n (e: 'go', page: number | 'prev' | 'next'): void;\n}>();\n\nfunction go(target: number | 'prev' | 'next') {\n emit('go', target);\n}\nfunction onGoto(e: Event) {\n const v = parseInt((e.target as HTMLInputElement).value, 10);\n if (!isNaN(v)) emit('go', v);\n}\n</script>\n\n<template>\n <nav v-if=\"props.totalPages > 1\" class=\"pelican-pager\">\n <button :disabled=\"page <= 1\" @click=\"go('prev')\">‹ prev</button>\n <template v-for=\"(p, i) in range\" :key=\"i\">\n <span v-if=\"p === '…'\" class=\"gap\">…</span>\n <button v-else class=\"page\" :class=\"{ cur: p === page }\" @click=\"go(p)\">{{ p }}</button>\n </template>\n <button :disabled=\"page >= totalPages\" @click=\"go('next')\">next ›</button>\n <span class=\"info\">\n go to\n <input type=\"number\" :min=\"1\" :max=\"totalPages\" :value=\"page\" @change=\"onGoto\" />\n </span>\n </nav>\n</template>\n\n<style scoped>\n.pelican-pager {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 6px;\n padding: 16px 0;\n font-size: 13px;\n}\n.pelican-pager button {\n background: var(--card);\n border: 1px solid var(--line);\n color: var(--text);\n border-radius: 6px;\n padding: 6px 10px;\n cursor: pointer;\n font: inherit;\n}\n.pelican-pager button:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n.pelican-pager button.page.cur {\n background: var(--orange);\n color: #fff;\n border-color: var(--orange);\n}\n.pelican-pager .gap {\n padding: 0 4px;\n color: var(--muted);\n}\n.pelican-pager .info {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n color: var(--muted);\n margin-left: 8px;\n}\n.pelican-pager .info input {\n width: 64px;\n padding: 6px;\n border: 1px solid var(--line);\n border-radius: 6px;\n background: var(--input-bg);\n color: var(--text);\n font: inherit;\n}\n</style>\n","<script setup lang=\"ts\">\nimport StrategyRow from './StrategyRow.vue';\nimport Pager from './Pager.vue';\nimport type { Strategy, Trade } from '../types/strategy';\nimport type { SignalKind } from '../types/api';\nimport type { SortColumn, SortKey } from '../constants/sort';\n\nconst props = defineProps<{\n pageItems: Strategy[];\n expanded: Set<number>;\n sortKey: SortKey;\n page: number;\n totalPages: number;\n pageRange: (number | '…')[];\n openSignals: Map<number, { loading: boolean; trades: Trade[] | null }>;\n closedSignals: Map<number, { loading: boolean; trades: Trade[] | null }>;\n}>();\n\nconst emit = defineEmits<{\n (e: 'toggle-row', id: number): void;\n (e: 'toggle-sort', col: SortColumn): void;\n (e: 'load-trades', payload: { id: number; kind: SignalKind }): void;\n (e: 'select', s: Strategy): void;\n (e: 'go', target: number | 'prev' | 'next'): void;\n}>();\n\nconst SORTABLE: { key: SortColumn; label: string }[] = [\n { key: 'return', label: 'Return %' },\n { key: 'copiers', label: 'Copiers' },\n { key: 'aum', label: 'Copiers AUM' },\n { key: 'dd', label: 'Max Drawdown' },\n { key: 'age', label: 'Age' },\n { key: 'balance', label: 'Balance' },\n { key: 'fee', label: 'Mgmt Fee %' },\n];\n\nfunction sortClass(col: SortColumn): string {\n if (props.sortKey === `${col}-asc`) return 'active-asc';\n if (props.sortKey === `${col}-desc`) return 'active-desc';\n return '';\n}\n</script>\n\n<template>\n <section class=\"pelican-table\">\n <div class=\"row head\">\n <div>Name</div>\n <div>Equity curve</div>\n <div\n v-for=\"col in SORTABLE\"\n :key=\"col.key\"\n class=\"c-num sortable\"\n :class=\"sortClass(col.key)\"\n @click=\"emit('toggle-sort', col.key)\"\n >\n {{ col.label }}\n </div>\n <div></div>\n </div>\n\n <div v-if=\"pageItems.length === 0\" class=\"empty\">\n <slot name=\"empty\">No matches.</slot>\n </div>\n <template v-else>\n <StrategyRow\n v-for=\"s in pageItems\"\n :key=\"s.Id\"\n :s=\"s\"\n :expanded=\"expanded.has(s.Id)\"\n :open-trades=\"openSignals.get(s.Id) ?? null\"\n :closed-trades=\"closedSignals.get(s.Id) ?? null\"\n @toggle=\"emit('toggle-row', s.Id)\"\n @load-trades=\"(kind) => emit('load-trades', { id: s.Id, kind })\"\n @select=\"emit('select', s)\"\n >\n <template #row-actions=\"slotProps\">\n <slot name=\"row-actions\" v-bind=\"slotProps\" />\n </template>\n </StrategyRow>\n </template>\n\n <Pager\n :page=\"page\"\n :total-pages=\"totalPages\"\n :range=\"pageRange\"\n @go=\"(t) => emit('go', t)\"\n />\n </section>\n</template>\n\n<style scoped>\n.pelican-table {\n flex: 1;\n min-width: 0;\n}\n.row.head {\n display: grid;\n grid-template-columns: minmax(160px, 1.6fr) minmax(120px, 1fr) repeat(7, minmax(70px, 0.8fr)) auto;\n gap: 12px;\n padding: 12px 16px;\n background: var(--sage-2);\n border-bottom: 1px solid var(--line);\n font-size: 12px;\n font-weight: 600;\n color: var(--muted);\n text-transform: uppercase;\n letter-spacing: 0.04em;\n}\n.row.head .c-num {\n text-align: right;\n}\n.row.head .sortable {\n cursor: pointer;\n user-select: none;\n}\n.row.head .sortable:hover {\n color: var(--text);\n}\n.row.head .sortable.active-asc::after {\n content: ' ↑';\n color: var(--orange);\n}\n.row.head .sortable.active-desc::after {\n content: ' ↓';\n color: var(--orange);\n}\n.empty {\n padding: 60px 20px;\n text-align: center;\n color: var(--muted);\n}\n@media (max-width: 720px) {\n .row.head {\n display: none;\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\nconst props = defineProps<{\n loaded: number;\n total: number;\n active: boolean;\n}>();\n\nconst pct = computed(() =>\n props.total > 0 ? Math.min(100, (props.loaded / props.total) * 100) : 0,\n);\n</script>\n\n<template>\n <div v-if=\"active\" class=\"pelican-progress\">\n <div class=\"bar\"><span :style=\"{ width: pct.toFixed(1) + '%' }\" /></div>\n <div class=\"caption\">\n Building full catalog: <b>{{ loaded.toLocaleString('en-US') }}</b>\n / {{ total.toLocaleString('en-US') }}\n strategies ({{ pct.toFixed(0) }}%) · <i>upstream rate-limited</i>\n </div>\n <div class=\"hint\">\n All {{ total.toLocaleString('en-US') }} strategies are visible. Stats fill in as the build\n progresses; refresh of data every 20 sec.\n </div>\n </div>\n</template>\n\n<style scoped>\n.pelican-progress {\n padding: 12px 16px;\n color: var(--muted);\n font-size: 13px;\n}\n.bar {\n position: relative;\n height: 6px;\n width: 100%;\n background: var(--line-2);\n border-radius: 4px;\n overflow: hidden;\n margin-bottom: 8px;\n}\n.bar span {\n display: block;\n height: 100%;\n background: var(--orange);\n transition: width 0.4s ease;\n}\n.caption b {\n color: var(--text);\n}\n.hint {\n margin-top: 6px;\n font-size: 12px;\n color: var(--muted-2);\n}\n</style>\n","import { ref, watch, onScopeDispose, type Ref } from 'vue';\nimport type { ThemeMode } from '../types/columns';\n\nconst STORAGE_KEY = 'pelican-theme';\n\nexport interface UseThemeReturn {\n mode: Ref<ThemeMode>;\n resolved: Ref<'dark' | 'light'>;\n setMode(next: ThemeMode): void;\n cycle(): void;\n}\n\nexport function useTheme(initial: ThemeMode = 'auto'): UseThemeReturn {\n const stored = readStored();\n const mode = ref<ThemeMode>(stored ?? initial);\n const resolved = ref<'dark' | 'light'>('dark');\n const mq = typeof window !== 'undefined' && window.matchMedia\n ? window.matchMedia('(prefers-color-scheme: dark)')\n : null;\n\n // Compute resolved value only — DO NOT touch document.documentElement.\n // The component template binds `:data-theme=\"resolved\"` on its own root div,\n // so theme stays scoped to the component and never collides with a host app's\n // own theme system.\n const apply = () => {\n const m = mode.value;\n resolved.value =\n m === 'dark' ? 'dark' : m === 'light' ? 'light' : mq?.matches ? 'dark' : 'light';\n };\n\n const onMq = () => {\n if (mode.value === 'auto') apply();\n };\n\n if (mq) {\n if (mq.addEventListener) mq.addEventListener('change', onMq);\n else mq.addListener(onMq);\n }\n\n watch(mode, (m) => {\n try {\n localStorage.setItem(STORAGE_KEY, m);\n } catch {\n /* storage unavailable */\n }\n apply();\n });\n\n apply();\n\n onScopeDispose(() => {\n if (mq) {\n if (mq.removeEventListener) mq.removeEventListener('change', onMq);\n else mq.removeListener(onMq);\n }\n });\n\n function setMode(next: ThemeMode) {\n mode.value = next;\n }\n function cycle() {\n mode.value = mode.value === 'dark' ? 'light' : mode.value === 'light' ? 'auto' : 'dark';\n }\n\n return { mode, resolved, setMode, cycle };\n}\n\nfunction readStored(): ThemeMode | null {\n try {\n const v = localStorage.getItem(STORAGE_KEY);\n if (v === 'dark' || v === 'light' || v === 'auto') return v;\n return null;\n } catch {\n return null;\n }\n}\n","export interface PelicanError extends Error {\n code: 'no_token' | 'fetch_failed' | 'http_error';\n status?: number;\n}\n\nexport function makeError(\n code: PelicanError['code'],\n message: string,\n status?: number,\n): PelicanError {\n const e = new Error(message) as PelicanError;\n e.code = code;\n if (status !== undefined) e.status = status;\n return e;\n}\n\nexport async function api<T = unknown>(path: string, apiBase: string): Promise<T> {\n const url = joinUrl(apiBase, path);\n let r: Response;\n try {\n r = await fetch(url);\n } catch (e) {\n throw makeError('fetch_failed', (e as Error).message ?? 'fetch failed');\n }\n if (r.status === 401 || r.status === 503) {\n throw makeError('no_token', 'Proxy has no token yet', r.status);\n }\n if (!r.ok) {\n const t = await r.text().catch(() => '');\n throw makeError('http_error', `${r.status}: ${t.slice(0, 120)}`, r.status);\n }\n return (await r.json()) as T;\n}\n\nexport function joinUrl(base: string, path: string): string {\n if (!base) return path;\n const b = base.endsWith('/') ? base.slice(0, -1) : base;\n const p = path.startsWith('/') ? path : '/' + path;\n return b + p;\n}\n","import { computed, onScopeDispose, ref, shallowRef, triggerRef, type Ref } from 'vue';\nimport type { Strategy, HistoryPoint } from '../types/strategy';\nimport type { ProgressResponse } from '../types/api';\nimport { api, joinUrl, type PelicanError } from '../utils/http';\nimport {\n PARTIAL_REPAINT_INTERVAL_MS,\n PROGRESS_POLL_INTERVAL_MS,\n} from '../constants/defaults';\n\nexport interface UseCatalogOptions {\n apiBase: Ref<string>;\n onError?(err: PelicanError): void;\n}\n\nexport interface UseCatalogReturn {\n catalog: Ref<Strategy[]>;\n ready: Ref<boolean>;\n building: Ref<boolean>;\n loaded: Ref<number>;\n total: Ref<number>;\n builtAt: Ref<number | null>;\n enrichOne(id: number): Promise<void>;\n searchExtra(filter: string): Promise<void>;\n refresh(): Promise<void>;\n start(): void;\n stop(): void;\n}\n\nexport function useCatalog({ apiBase, onError }: UseCatalogOptions): UseCatalogReturn {\n const byIdRef = shallowRef<Map<number, Strategy>>(new Map());\n const ready = ref(false);\n const building = ref(false);\n const loaded = ref(0);\n const total = ref(0);\n const builtAt = ref<number | null>(null);\n\n const catalog = computed<Strategy[]>(() => Array.from(byIdRef.value.values()));\n\n let stopped = false;\n\n const handleError = (e: unknown) => {\n if (onError) onError(e as PelicanError);\n else console.warn('[pelican-vue]', e);\n };\n\n async function fetchAndMerge(partial: boolean) {\n try {\n const url = partial ? '/api/strategies-full?partial=1' : '/api/strategies-full';\n const items = await api<Strategy[]>(url, apiBase.value);\n total.value = items.length;\n const m = byIdRef.value;\n for (const it of items) m.set(it.Id, { ...m.get(it.Id), ...it } as Strategy);\n triggerRef(byIdRef);\n } catch (e) {\n handleError(e);\n }\n }\n\n async function pollProgress(): Promise<ProgressResponse | null> {\n try {\n const p = await api<ProgressResponse>('/api/strategies-full/progress', apiBase.value);\n loaded.value = p.loaded;\n total.value = p.total || total.value;\n building.value = p.building;\n builtAt.value = p.built_at;\n return p;\n } catch (e) {\n handleError(e);\n return null;\n }\n }\n\n async function loadFull() {\n await fetchAndMerge(true);\n let lastPaint = Date.now();\n while (!stopped) {\n const p = await pollProgress();\n if (!p) {\n await sleep(1500);\n continue;\n }\n if (p.ready) break;\n if (Date.now() - lastPaint > PARTIAL_REPAINT_INTERVAL_MS) {\n await fetchAndMerge(true);\n lastPaint = Date.now();\n }\n await sleep(PROGRESS_POLL_INTERVAL_MS);\n }\n if (stopped) return;\n await fetchAndMerge(false);\n ready.value = true;\n }\n\n const enrichInflight = new Set<number>();\n async function enrichOne(id: number) {\n if (enrichInflight.has(id)) return;\n const existing = byIdRef.value.get(id);\n if (existing?._enrichAttempted && existing._meta && existing._stats) return;\n enrichInflight.add(id);\n try {\n const [meta, stats] = await Promise.all([\n safeFetchJson<MetaResponse>(joinUrl(apiBase.value, `/api/strategies/${id}`)),\n safeFetchJson<StatsResponse>(joinUrl(apiBase.value, `/api/strategies/${id}/stats`)),\n ]);\n const m = byIdRef.value;\n const cur = m.get(id) ?? ({ Id: id } as Strategy);\n mergeMetaInto(cur, meta);\n mergeStatsInto(cur, stats);\n cur._enrichAttempted = true;\n if (cur.IsEnabled === false) m.delete(id);\n else m.set(id, cur);\n triggerRef(byIdRef);\n } finally {\n enrichInflight.delete(id);\n }\n }\n\n async function searchExtra(filter: string) {\n if (!filter || !ready.value) return;\n try {\n const items = await api<Strategy[]>(\n `/api/strategies?filter=${encodeURIComponent(filter)}`,\n apiBase.value,\n );\n const m = byIdRef.value;\n const newIds: number[] = [];\n let added = 0;\n for (const it of items) {\n if (!m.has(it.Id)) {\n m.set(it.Id, { ...it, _stats: false, _meta: false });\n newIds.push(it.Id);\n added++;\n }\n }\n if (added) {\n total.value += added;\n triggerRef(byIdRef);\n }\n for (const id of newIds) void enrichOne(id);\n } catch (e) {\n handleError(e);\n }\n }\n\n function start() {\n stopped = false;\n void loadFull();\n }\n function stop() {\n stopped = true;\n }\n async function refresh() {\n stop();\n byIdRef.value = new Map();\n ready.value = false;\n loaded.value = 0;\n total.value = 0;\n builtAt.value = null;\n start();\n }\n\n onScopeDispose(stop);\n\n return {\n catalog,\n ready,\n building,\n loaded,\n total,\n builtAt,\n enrichOne,\n searchExtra,\n refresh,\n start,\n stop,\n };\n}\n\nasync function safeFetchJson<T = unknown>(url: string): Promise<T | null> {\n try {\n const r = await fetch(url);\n if (!r.ok) return null;\n return (await r.json()) as T;\n } catch {\n return null;\n }\n}\n\ninterface MetaResponse {\n Name?: string | null;\n NumCopiers?: number | null;\n Fee?: number | null;\n RiskProfile?: Strategy['RiskProfile'];\n IsSimulated?: boolean;\n IsEnabled?: boolean;\n ImageUploaded?: boolean | null;\n Profile?: Strategy['Profile'];\n}\n\ninterface StatsResponse {\n Inception?: string | null;\n CurrencyCode?: string | null;\n Profitability?: {\n Inception?: {\n UnrealisedReturn?: number | null;\n RealisedReturn?: number | null;\n MaxDrawdown?: number | null;\n RealisedPnl?: number | null;\n UnrealisedPnl?: number | null;\n History?: HistoryPoint[];\n };\n };\n Trades?: {\n Inception?: {\n Total?: number;\n Wins?: number;\n Losses?: number;\n Markets?: { MarketName: string; Count: number }[];\n };\n };\n Status?: { Balance?: number | null };\n CopiersBalance?: { Balance?: number | null };\n CopiersProfit?: { Month?: number | null; Year?: number | null };\n}\n\nfunction mergeMetaInto(cur: Strategy, meta: MetaResponse | null) {\n if (!meta) return;\n cur.Name = meta.Name ?? cur.Name;\n cur.NumCopiers = meta.NumCopiers ?? null;\n cur.Fee = meta.Fee ?? null;\n cur.RiskProfile = meta.RiskProfile ?? null;\n cur.IsSimulated = meta.IsSimulated ?? false;\n if (meta.IsEnabled !== undefined) cur.IsEnabled = meta.IsEnabled;\n if (meta.ImageUploaded !== undefined) cur.ImageUploaded = meta.ImageUploaded;\n cur.Profile = meta.Profile ?? cur.Profile;\n cur._meta = true;\n}\n\nfunction mergeStatsInto(cur: Strategy, stats: StatsResponse | null) {\n if (!stats) return;\n const inc = stats.Profitability?.Inception ?? {};\n const tr = stats.Trades?.Inception ?? {};\n const hist = inc.History ?? [];\n const stride = hist.length > 60 ? Math.ceil(hist.length / 60) : 1;\n const trimmed = hist\n .filter((_, i) => i % stride === 0 || i === hist.length - 1)\n .map((p) => ({ Timestamp: p.Timestamp, AccountReturn: p.AccountReturn }));\n\n cur.Inception = stats.Inception ?? cur.Inception;\n cur.Currency = stats.CurrencyCode || 'USD';\n cur.Return =\n inc.UnrealisedReturn != null\n ? inc.UnrealisedReturn * 100\n : inc.RealisedReturn != null\n ? inc.RealisedReturn * 100\n : null;\n cur.MaxDD = inc.MaxDrawdown != null ? inc.MaxDrawdown * 100 : null;\n cur.RealisedPnl = inc.RealisedPnl ?? null;\n cur.UnrealisedPnl = inc.UnrealisedPnl ?? null;\n cur.History = trimmed;\n cur.TradesTotal = tr.Total ?? 0;\n cur.Wins = tr.Wins ?? 0;\n cur.Losses = tr.Losses ?? 0;\n cur.Markets = Array.isArray(tr.Markets)\n ? tr.Markets.slice(0, 12).map((m) => ({ n: m.MarketName, c: m.Count }))\n : [];\n cur.AccountBalance = stats.Status?.Balance ?? null;\n cur.CopiersAUM = stats.CopiersBalance?.Balance ?? null;\n cur.MonthlyProfit = stats.CopiersProfit?.Month ?? null;\n cur.YearlyProfit = stats.CopiersProfit?.Year ?? null;\n cur._stats = true;\n}\n\nfunction sleep(ms: number) {\n return new Promise((r) => setTimeout(r, ms));\n}\n","import type { RiskLevel } from './strategy';\n\nexport interface FiltersState {\n risk: Set<RiskLevel>;\n retMin: number | null;\n retMax: number | null;\n ddMax: number | null;\n aumMin: number | null;\n copiersMin: number | null;\n ageMin: number | null;\n tradesMin: number | null;\n winrateMin: number | null;\n feeMax: number | null;\n balanceMin: number | null;\n balanceMax: number | null;\n search: string;\n}\n\nexport function defaultFilters(): FiltersState {\n return {\n risk: new Set<RiskLevel>(),\n retMin: null,\n retMax: null,\n ddMax: null,\n aumMin: null,\n copiersMin: null,\n ageMin: null,\n tradesMin: null,\n winrateMin: null,\n feeMax: null,\n balanceMin: null,\n balanceMax: null,\n search: '',\n };\n}\n","import { computed, reactive, type Reactive, type Ref } from 'vue';\nimport type { Strategy } from '../types/strategy';\nimport type { FiltersState } from '../types/filters';\nimport { defaultFilters } from '../types/filters';\nimport { winrate } from '../utils/winrate';\nimport { ageDays } from '../utils/format';\n\nexport interface UseFiltersReturn {\n filters: Reactive<FiltersState>;\n filtered: Ref<Strategy[]>;\n reset(): void;\n}\n\nexport function useFilters(\n source: Ref<Strategy[]>,\n initial: Partial<FiltersState> = {},\n): UseFiltersReturn {\n const base = defaultFilters();\n const filters = reactive<FiltersState>({\n ...base,\n ...initial,\n risk: new Set(initial.risk ?? base.risk),\n });\n\n const filtered = computed<Strategy[]>(() => source.value.filter((s) => passes(s, filters)));\n\n function reset() {\n const fresh = defaultFilters();\n filters.risk = fresh.risk;\n filters.retMin = null;\n filters.retMax = null;\n filters.ddMax = null;\n filters.aumMin = null;\n filters.copiersMin = null;\n filters.ageMin = null;\n filters.tradesMin = null;\n filters.winrateMin = null;\n filters.feeMax = null;\n filters.balanceMin = null;\n filters.balanceMax = null;\n filters.search = '';\n }\n\n return { filters, filtered, reset };\n}\n\nfunction passes(s: Strategy, f: FiltersState): boolean {\n if (f.search) {\n const q = f.search.toLowerCase();\n if (\n !(s.Name || '').toLowerCase().includes(q) &&\n !(s.Profile?.Name || '').toLowerCase().includes(q)\n ) {\n return false;\n }\n }\n if (f.risk.size && s.RiskProfile && !f.risk.has(s.RiskProfile)) return false;\n if (s.IsSimulated) return false;\n if (s._stats && !s.TradesTotal) return false;\n if (f.copiersMin != null && (s.NumCopiers ?? 0) < f.copiersMin) return false;\n if (f.aumMin != null && (s.CopiersAUM ?? 0) < f.aumMin) return false;\n if (f.balanceMin != null && (s.AccountBalance ?? 0) < f.balanceMin) return false;\n if (f.balanceMax != null && (s.AccountBalance ?? Infinity) > f.balanceMax) return false;\n if (f.feeMax != null && s.Fee != null && s.Fee * 100 > f.feeMax) return false;\n if (f.tradesMin != null && (s.TradesTotal ?? 0) < f.tradesMin) return false;\n const wr = winrate(s);\n if (f.winrateMin != null && (wr < 0 || wr < f.winrateMin)) return false;\n const age = ageDays(s.Inception);\n if (f.ageMin != null && (age == null || age < f.ageMin)) return false;\n if (f.retMin != null && (s.Return == null || s.Return < f.retMin)) return false;\n if (f.retMax != null && (s.Return == null || s.Return > f.retMax)) return false;\n if (f.ddMax != null && s.MaxDD != null && Math.abs(s.MaxDD) > f.ddMax) return false;\n return true;\n}\n","import { computed, ref, type Ref } from 'vue';\nimport type { Strategy } from '../types/strategy';\nimport { winrate } from '../utils/winrate';\nimport { ageDays } from '../utils/format';\nimport { SORT_TOGGLE, type SortColumn, type SortKey } from '../constants/sort';\n\ntype Comparator = (a: Strategy, b: Strategy) => number;\n\nconst COMPARATORS: Record<SortKey, Comparator> = {\n 'return-desc': (a, b) => (b.Return ?? -1e18) - (a.Return ?? -1e18),\n 'return-asc': (a, b) => (a.Return ?? 1e18) - (b.Return ?? 1e18),\n 'dd-asc': (a, b) => Math.abs(a.MaxDD ?? 1e9) - Math.abs(b.MaxDD ?? 1e9),\n 'dd-desc': (a, b) => Math.abs(b.MaxDD ?? -1e9) - Math.abs(a.MaxDD ?? -1e9),\n 'aum-desc': (a, b) => (b.CopiersAUM ?? -1) - (a.CopiersAUM ?? -1),\n 'aum-asc': (a, b) => (a.CopiersAUM ?? Infinity) - (b.CopiersAUM ?? Infinity),\n 'copiers-desc': (a, b) => (b.NumCopiers ?? -1) - (a.NumCopiers ?? -1),\n 'copiers-asc': (a, b) => (a.NumCopiers ?? Infinity) - (b.NumCopiers ?? Infinity),\n 'fee-asc': (a, b) => (a.Fee ?? Infinity) - (b.Fee ?? Infinity),\n 'fee-desc': (a, b) => (b.Fee ?? -1) - (a.Fee ?? -1),\n 'age-desc': (a, b) => (ageDays(b.Inception) ?? -1) - (ageDays(a.Inception) ?? -1),\n 'age-asc': (a, b) => (ageDays(a.Inception) ?? Infinity) - (ageDays(b.Inception) ?? Infinity),\n 'balance-desc': (a, b) => (b.AccountBalance ?? -1) - (a.AccountBalance ?? -1),\n 'balance-asc': (a, b) => (a.AccountBalance ?? Infinity) - (b.AccountBalance ?? Infinity),\n 'winrate-desc': (a, b) => winrate(b) - winrate(a),\n 'winrate-asc': (a, b) => winrate(a) - winrate(b),\n 'trades-desc': (a, b) => (b.TradesTotal ?? -1) - (a.TradesTotal ?? -1),\n 'trades-asc': (a, b) => (a.TradesTotal ?? Infinity) - (b.TradesTotal ?? Infinity),\n 'monthly-desc': (a, b) => (b.MonthlyProfit ?? -1e18) - (a.MonthlyProfit ?? -1e18),\n 'monthly-asc': (a, b) => (a.MonthlyProfit ?? 1e18) - (b.MonthlyProfit ?? 1e18),\n};\n\nexport interface UseSortReturn {\n sortKey: Ref<SortKey>;\n sorted: Ref<Strategy[]>;\n toggleColumn(col: SortColumn): void;\n setKey(k: SortKey): void;\n}\n\nexport function useSort(source: Ref<Strategy[]>, initial: SortKey = 'return-desc'): UseSortReturn {\n const sortKey = ref<SortKey>(initial);\n const sorted = computed<Strategy[]>(() => {\n const cmp = COMPARATORS[sortKey.value] ?? (() => 0);\n return source.value.slice().sort(cmp);\n });\n\n function toggleColumn(col: SortColumn) {\n const [primary, secondary] = SORT_TOGGLE[col];\n sortKey.value = sortKey.value === primary ? secondary : primary;\n }\n\n return {\n sortKey,\n sorted,\n toggleColumn,\n setKey: (k: SortKey) => {\n sortKey.value = k;\n },\n };\n}\n","import { computed, ref, watch, type Ref } from 'vue';\n\nexport interface UsePaginationReturn<T> {\n page: Ref<number>;\n totalPages: Ref<number>;\n pageItems: Ref<T[]>;\n pageRange: Ref<(number | '…')[]>;\n setPage(p: number): void;\n next(): void;\n prev(): void;\n}\n\nexport function usePagination<T>(source: Ref<T[]>, pageSize: number): UsePaginationReturn<T> {\n const page = ref(1);\n\n const totalPages = computed(() => Math.max(1, Math.ceil(source.value.length / pageSize)));\n\n watch(totalPages, (tp) => {\n if (page.value > tp) page.value = tp;\n if (page.value < 1) page.value = 1;\n });\n\n const pageItems = computed<T[]>(() => {\n const start = (page.value - 1) * pageSize;\n return source.value.slice(start, start + pageSize);\n });\n\n const pageRange = computed<(number | '…')[]>(() => {\n const cur = page.value;\n const total = totalPages.value;\n if (total <= 1) return [];\n const set = new Set<number>([1, total, cur, cur - 1, cur + 1, cur - 2, cur + 2, 2, total - 1]);\n const arr = [...set].filter((n) => n >= 1 && n <= total).sort((a, b) => a - b);\n const out: (number | '…')[] = [];\n for (let i = 0; i < arr.length; i++) {\n if (i && arr[i] - arr[i - 1] > 1) out.push('…');\n out.push(arr[i]);\n }\n return out;\n });\n\n return {\n page,\n totalPages,\n pageItems,\n pageRange,\n setPage: (p: number) => {\n page.value = Math.max(1, Math.min(totalPages.value, p));\n },\n next: () => {\n if (page.value < totalPages.value) page.value += 1;\n },\n prev: () => {\n if (page.value > 1) page.value -= 1;\n },\n };\n}\n","import { ref, type Ref } from 'vue';\nimport type { SignalKind } from '../types/api';\nimport type { Trade } from '../types/strategy';\nimport { SIGNALS_CLOSED_WINDOW_DAYS } from '../constants/defaults';\nimport { joinUrl, makeError, type PelicanError } from '../utils/http';\n\ninterface SignalsCacheEntry {\n loading: boolean;\n trades: Trade[] | null;\n error: PelicanError | null;\n}\n\nexport interface UseSignalsReturn {\n open: Ref<Map<number, SignalsCacheEntry>>;\n closed: Ref<Map<number, SignalsCacheEntry>>;\n load(strategyId: number, kind: SignalKind): Promise<void>;\n get(strategyId: number, kind: SignalKind): SignalsCacheEntry | null;\n}\n\nexport function useSignals(apiBase: Ref<string>): UseSignalsReturn {\n const open = ref<Map<number, SignalsCacheEntry>>(new Map());\n const closed = ref<Map<number, SignalsCacheEntry>>(new Map());\n\n function get(id: number, kind: SignalKind): SignalsCacheEntry | null {\n return (kind === 'open' ? open.value : closed.value).get(id) ?? null;\n }\n\n async function load(id: number, kind: SignalKind) {\n const store = kind === 'open' ? open : closed;\n const cur = store.value.get(id);\n if (cur && (cur.loading || cur.trades !== null)) return;\n const next = new Map(store.value);\n next.set(id, { loading: true, trades: null, error: null });\n store.value = next;\n\n let qs = '';\n if (kind === 'closed') {\n const end = new Date();\n const start = new Date(Date.now() - SIGNALS_CLOSED_WINDOW_DAYS * 86400_000);\n const fmt = (d: Date) => d.toISOString().replace(/\\.\\d+Z$/, 'Z');\n qs = `?startDate=${encodeURIComponent(fmt(start))}&endDate=${encodeURIComponent(fmt(end))}`;\n }\n const url = joinUrl(apiBase.value, `/api/strategies/${id}/signals/${kind}${qs}`);\n\n let trades: Trade[] = [];\n let error: PelicanError | null = null;\n try {\n const r = await fetch(url);\n if (!r.ok) throw makeError('http_error', `${r.status}`);\n trades = (await r.json()) as Trade[];\n } catch (e) {\n error = (e as PelicanError).code\n ? (e as PelicanError)\n : makeError('fetch_failed', (e as Error).message);\n trades = [];\n }\n\n const final = new Map(store.value);\n final.set(id, { loading: false, trades, error });\n store.value = final;\n }\n\n return { open, closed, load, get };\n}\n","<script setup lang=\"ts\">\nimport { onMounted, provide, reactive, ref, toRef, watch } from 'vue';\nimport Toolbar from './components/Toolbar.vue';\nimport FiltersPanel from './components/FiltersPanel.vue';\nimport StrategyTable from './components/StrategyTable.vue';\nimport ProgressBar from './components/ProgressBar.vue';\nimport { useTheme } from './composables/useTheme';\nimport { useCatalog } from './composables/useCatalog';\nimport { useFilters } from './composables/useFilters';\nimport { useSort } from './composables/useSort';\nimport { usePagination } from './composables/usePagination';\nimport { useSignals } from './composables/useSignals';\nimport { defaultFilters, type FiltersState } from './types/filters';\nimport type { Strategy } from './types/strategy';\nimport type { ThemeMode } from './types/columns';\n// `columns` is reserved for a future column-visibility API; type intentionally re-exported.\nimport type { ColumnKey } from './types/columns';\nimport type { SignalKind } from './types/api';\nimport type { PelicanError } from './utils/http';\nimport type { SortKey, SortColumn } from './constants/sort';\nimport { PAGE_SIZE } from './constants/defaults';\nimport { LOCALE_KEY, API_BASE_KEY } from './injection-keys';\nimport './styles/index.css';\n\nconst props = withDefaults(\n defineProps<{\n apiBase: string;\n theme?: ThemeMode;\n defaultSort?: SortKey;\n defaultFilters?: Partial<FiltersState>;\n columns?: ColumnKey[]; // reserved; not yet wired through\n locale?: string;\n pageSize?: number;\n }>(),\n {\n theme: 'auto',\n defaultSort: 'return-desc',\n locale: 'en-US',\n pageSize: PAGE_SIZE,\n },\n);\n\nconst emit = defineEmits<{\n (e: 'update:theme', m: ThemeMode): void;\n (e: 'select-strategy', s: Strategy): void;\n (e: 'error', err: PelicanError): void;\n}>();\n\nprovide(API_BASE_KEY, props.apiBase);\nprovide(LOCALE_KEY, props.locale);\n\nconst apiBaseRef = toRef(props, 'apiBase');\n\nconst themeApi = useTheme(props.theme);\nwatch(themeApi.mode, (m) => emit('update:theme', m));\nwatch(\n () => props.theme,\n (t) => themeApi.setMode(t),\n);\n\nconst catalog = useCatalog({\n apiBase: apiBaseRef,\n onError: (e) => emit('error', e),\n});\n\nconst filtersApi = useFilters(catalog.catalog, props.defaultFilters ?? {});\nconst sortApi = useSort(filtersApi.filtered, props.defaultSort);\nconst pagination = usePagination<Strategy>(sortApi.sorted, props.pageSize);\n\nconst signals = useSignals(apiBaseRef);\n\nconst expanded = reactive(new Set<number>());\nconst filtersOpen = ref(false);\nconst investAmount = ref<number | null>(null);\n\nfunction toggleRow(id: number) {\n if (expanded.has(id)) expanded.delete(id);\n else expanded.add(id);\n\n const s = catalog.catalog.value.find((x) => x.Id === id);\n if (s) {\n if ((!s._meta || !s._stats) && !s._enrichAttempted) void catalog.enrichOne(id);\n emit('select-strategy', s);\n }\n}\n\nfunction toggleSort(col: SortColumn) {\n sortApi.toggleColumn(col);\n pagination.setPage(1);\n}\n\nfunction patchFilters(p: Partial<FiltersState>) {\n Object.assign(filtersApi.filters, p);\n pagination.setPage(1);\n}\n\nfunction resetFilters() {\n const fresh = defaultFilters();\n Object.assign(filtersApi.filters, fresh);\n filtersApi.filters.risk = fresh.risk;\n investAmount.value = null;\n pagination.setPage(1);\n}\n\nfunction loadTrades({ id, kind }: { id: number; kind: SignalKind }) {\n void signals.load(id, kind);\n}\n\nfunction onPageGo(target: number | 'prev' | 'next') {\n if (target === 'prev') pagination.prev();\n else if (target === 'next') pagination.next();\n else pagination.setPage(target);\n}\n\nonMounted(() => catalog.start());\n</script>\n\n<template>\n <div class=\"pelican-libsoc\" :data-theme=\"themeApi.resolved.value\">\n <header class=\"brand-row\">\n <slot name=\"brand\">\n <div class=\"default-brand\">Libertex Social — Copy Trading</div>\n </slot>\n <button class=\"theme-toggle\" type=\"button\" :title=\"themeApi.mode.value\" @click=\"themeApi.cycle\">\n <span aria-hidden=\"true\">{{ themeApi.resolved.value === 'dark' ? '🌙' : '☀️' }}</span>\n </button>\n </header>\n\n <Toolbar\n :search=\"filtersApi.filters.search\"\n :sort-key=\"sortApi.sortKey.value\"\n :total=\"catalog.total.value\"\n :filtered-total=\"filtersApi.filtered.value.length\"\n :page=\"pagination.page.value\"\n :total-pages=\"pagination.totalPages.value\"\n @update:search=\"(v) => patchFilters({ search: v })\"\n @update:sort-key=\"(k) => sortApi.setKey(k)\"\n @refresh=\"catalog.refresh\"\n @toggle-filters=\"filtersOpen = !filtersOpen\"\n />\n\n <ProgressBar\n :loaded=\"catalog.loaded.value\"\n :total=\"catalog.total.value\"\n :active=\"catalog.building.value && !catalog.ready.value\"\n />\n\n <main class=\"pelican-main\">\n <FiltersPanel\n :filters=\"filtersApi.filters\"\n :invest-amount=\"investAmount\"\n :open=\"filtersOpen\"\n @update:filters=\"patchFilters\"\n @update:invest-amount=\"(v) => (investAmount = v)\"\n @reset=\"resetFilters\"\n />\n\n <StrategyTable\n :page-items=\"pagination.pageItems.value\"\n :expanded=\"expanded\"\n :sort-key=\"sortApi.sortKey.value\"\n :page=\"pagination.page.value\"\n :total-pages=\"pagination.totalPages.value\"\n :page-range=\"pagination.pageRange.value\"\n :open-signals=\"signals.open.value\"\n :closed-signals=\"signals.closed.value\"\n @toggle-row=\"toggleRow\"\n @toggle-sort=\"toggleSort\"\n @load-trades=\"loadTrades\"\n @select=\"(s) => emit('select-strategy', s)\"\n @go=\"onPageGo\"\n >\n <template #empty>\n <slot name=\"empty\">No matches.</slot>\n </template>\n <template #row-actions=\"slotProps\">\n <slot name=\"row-actions\" v-bind=\"slotProps\" />\n </template>\n </StrategyTable>\n </main>\n </div>\n</template>\n\n<style scoped>\n.brand-row {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 14px 16px;\n background: var(--header-bg);\n border-bottom: 1px solid var(--line);\n}\n.default-brand {\n font-weight: 700;\n color: var(--text);\n}\n.theme-toggle {\n margin-left: auto;\n width: 38px;\n height: 38px;\n border-radius: 8px;\n border: 1px solid var(--line);\n background: transparent;\n color: var(--text);\n cursor: pointer;\n font: inherit;\n font-size: 16px;\n}\n.theme-toggle:hover {\n border-color: var(--orange);\n}\n.pelican-main {\n display: flex;\n flex: 1;\n min-height: 0;\n}\n@media (max-width: 720px) {\n .pelican-main {\n flex-direction: column;\n }\n}\n</style>\n"],"names":["useDebounce","fn","delay","t","wrapped","args","cancel","onScopeDispose","PAGE_SIZE","SEARCH_DEBOUNCE_MS","PROGRESS_POLL_INTERVAL_MS","PARTIAL_REPAINT_INTERVAL_MS","SIGNALS_CLOSED_WINDOW_DAYS","SORT_KEYS","SORT_LABELS","SORT_TOGGLE","props","__props","emit","__emit","local","ref","watch","v","debounced","onSearchInput","e","onSort","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_toDisplayString","_createTextVNode","_hoisted_4","_cache","_Fragment","_renderList","_unref","k","_hoisted_6","LEVELS","toggle","level","next","l","_normalizeClass","$event","anyAt","computed","inverted","raw","display","onInput","_hoisted_3","rawMin","rawMax","lo","hi","loLabel","hiLabel","rangeText","onMin","onMax","_hoisted_5","_a","_hoisted_8","h","fmtPct","d","n","fmtMoney","locale","sign","abs","s","fmtMoneyFull","fmtNum","fmtFee","fmtTradeTime","iso","fmtAge","days","months","years","remMonths","fmtAUM","fmtRetMag","initials","name","p","ageDays","inception","balanceFromRaw","rawFromBalance","b","returnFromRaw","onChange","retRawMin","retRawMax","balRawMin","balRawMax","patch","setRisk","applyInvest","range","_createVNode","RiskChips","InvestAmount","RangeDual","RangeSingle","DONUT_PALETTE","sparklineGeometry","history","w","times","tMin","tMax","tSpan","ys","yMin","yRange","px","py","pts","i","last","zeroY","startX","endX","linePath","areaPath","donutGeometry","items","sorted","a","total","acc","m","cx","cy","R","r","labelR","angle","slices","frac","sweep","a0","a1","aMid","large","x0","y0","x1","y1","xi0","yi0","xi1","yi1","arcPath","color","labelLine","labelX","labelY","labelAnchor","isLeft","lx1","ly1","lx2","ly2","lx3","geom","empty","_vShow","title","_hoisted_7","winrate","wins","losses","API_BASE_KEY","LOCALE_KEY","inject","ret","dd","age","wr","lr","profileName","_b","link","showOpen","showClosed","toggleOpen","toggleClosed","_hoisted_9","_hoisted_10","Sparkline","_hoisted_11","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_17","_hoisted_18","_hoisted_19","_hoisted_20","_renderSlot","_ctx","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_25","_hoisted_26","_hoisted_27","_hoisted_28","_hoisted_29","_hoisted_30","_hoisted_31","_hoisted_32","_hoisted_33","_hoisted_34","_hoisted_35","_hoisted_36","_hoisted_37","_hoisted_38","_hoisted_39","_hoisted_40","_hoisted_41","MarketsDonut","_hoisted_42","_createBlock","TradesPanel","_c","_d","go","target","onGoto","SORTABLE","sortClass","col","StrategyRow","kind","_withCtx","slotProps","_mergeProps","Pager","pct","_normalizeStyle","STORAGE_KEY","useTheme","initial","stored","readStored","mode","resolved","mq","apply","onMq","setMode","cycle","makeError","code","message","status","api","path","apiBase","url","joinUrl","base","useCatalog","onError","byIdRef","shallowRef","ready","building","loaded","builtAt","catalog","stopped","handleError","fetchAndMerge","partial","it","triggerRef","pollProgress","loadFull","lastPaint","sleep","enrichInflight","enrichOne","id","existing","meta","stats","safeFetchJson","cur","mergeMetaInto","mergeStatsInto","searchExtra","filter","newIds","added","start","stop","refresh","inc","tr","hist","stride","trimmed","_","_e","_f","ms","defaultFilters","useFilters","source","filters","reactive","filtered","passes","reset","fresh","f","q","COMPARATORS","useSort","sortKey","cmp","toggleColumn","primary","secondary","usePagination","pageSize","page","totalPages","tp","pageItems","pageRange","arr","out","useSignals","open","closed","get","load","store","qs","end","fmt","trades","error","final","provide","apiBaseRef","toRef","themeApi","filtersApi","sortApi","pagination","signals","expanded","filtersOpen","investAmount","toggleRow","x","toggleSort","patchFilters","resetFilters","loadTrades","onPageGo","onMounted","Toolbar","ProgressBar","FiltersPanel","StrategyTable"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pelican-libertex-social.mjs","sources":["../src/composables/useDebounce.ts","../src/constants/defaults.ts","../src/constants/sort.ts","../src/components/Toolbar.vue","../src/components/filters/RiskChips.vue","../src/components/filters/RangeSingle.vue","../src/components/filters/RangeDual.vue","../src/utils/format.ts","../src/utils/scales.ts","../src/components/filters/InvestAmount.vue","../src/components/FiltersPanel.vue","../src/constants/palette.ts","../src/utils/svg.ts","../src/components/Sparkline.vue","../src/components/MarketsDonut.vue","../src/components/TradesPanel.vue","../src/utils/winrate.ts","../src/injection-keys.ts","../src/components/StrategyRow.vue","../src/components/Pager.vue","../src/components/StrategyTable.vue","../src/components/ProgressBar.vue","../src/composables/useTheme.ts","../src/utils/http.ts","../src/composables/useCatalog.ts","../src/types/filters.ts","../src/composables/useFilters.ts","../src/composables/useSort.ts","../src/composables/usePagination.ts","../src/composables/useSignals.ts","../src/PelicanLibertexSocial.vue"],"sourcesContent":["import { onScopeDispose } from 'vue';\n\nexport function useDebounce<T extends (...args: never[]) => void>(fn: T, delay: number) {\n let t: ReturnType<typeof setTimeout> | null = null;\n const wrapped = (...args: Parameters<T>) => {\n if (t) clearTimeout(t);\n t = setTimeout(() => {\n t = null;\n fn(...args);\n }, delay);\n };\n const cancel = () => {\n if (t) {\n clearTimeout(t);\n t = null;\n }\n };\n onScopeDispose(cancel);\n return { wrapped, cancel };\n}\n","export const PAGE_SIZE = 20;\nexport const SEARCH_DEBOUNCE_MS = 350;\nexport const PROGRESS_POLL_INTERVAL_MS = 2000;\nexport const PARTIAL_REPAINT_INTERVAL_MS = 20000;\nexport const SIGNALS_CLOSED_WINDOW_DAYS = 30;\n","export const SORT_KEYS = [\n 'return-desc',\n 'return-asc',\n 'copiers-desc',\n 'copiers-asc',\n 'aum-desc',\n 'aum-asc',\n 'dd-asc',\n 'dd-desc',\n 'fee-asc',\n 'fee-desc',\n 'age-desc',\n 'age-asc',\n 'balance-desc',\n 'balance-asc',\n 'winrate-desc',\n 'winrate-asc',\n 'trades-desc',\n 'trades-asc',\n 'monthly-desc',\n 'monthly-asc',\n] as const;\nexport type SortKey = (typeof SORT_KEYS)[number];\n\nexport const SORT_LABELS: Record<SortKey, string> = {\n 'return-desc': 'Return ↓',\n 'return-asc': 'Return ↑',\n 'copiers-desc': 'Copiers ↓',\n 'copiers-asc': 'Copiers ↑',\n 'aum-desc': 'Copiers AUM ↓',\n 'aum-asc': 'Copiers AUM ↑',\n 'dd-asc': 'Drawdown ↑',\n 'dd-desc': 'Drawdown ↓',\n 'fee-asc': 'Fee ↑',\n 'fee-desc': 'Fee ↓',\n 'age-desc': 'Age ↓',\n 'age-asc': 'Age ↑',\n 'balance-desc': 'Balance ↓',\n 'balance-asc': 'Balance ↑',\n 'winrate-desc': 'Win Rate ↓',\n 'winrate-asc': 'Win Rate ↑',\n 'trades-desc': 'Trades ↓',\n 'trades-asc': 'Trades ↑',\n 'monthly-desc': 'Monthly Profit ↓',\n 'monthly-asc': 'Monthly Profit ↑',\n};\n\nexport type SortColumn =\n | 'return'\n | 'copiers'\n | 'aum'\n | 'dd'\n | 'fee'\n | 'age'\n | 'balance';\n\nexport const SORT_TOGGLE: Record<SortColumn, [SortKey, SortKey]> = {\n return: ['return-desc', 'return-asc'],\n copiers: ['copiers-desc', 'copiers-asc'],\n aum: ['aum-desc', 'aum-asc'],\n dd: ['dd-asc', 'dd-desc'],\n fee: ['fee-asc', 'fee-desc'],\n age: ['age-desc', 'age-asc'],\n balance: ['balance-desc', 'balance-asc'],\n};\n","<script setup lang=\"ts\">\nimport { ref, watch } from 'vue';\nimport { useDebounce } from '../composables/useDebounce';\nimport { SEARCH_DEBOUNCE_MS } from '../constants/defaults';\nimport { SORT_KEYS, SORT_LABELS, type SortKey } from '../constants/sort';\n\nconst props = defineProps<{\n search: string;\n sortKey: SortKey;\n total: number;\n filteredTotal: number;\n page: number;\n totalPages: number;\n}>();\n\nconst emit = defineEmits<{\n (e: 'update:search', v: string): void;\n (e: 'update:sortKey', v: SortKey): void;\n (e: 'refresh'): void;\n (e: 'toggle-filters'): void;\n}>();\n\nconst local = ref(props.search);\nwatch(\n () => props.search,\n (v) => {\n if (v !== local.value) local.value = v;\n },\n);\n\nconst { wrapped: debounced } = useDebounce((v: string) => emit('update:search', v), SEARCH_DEBOUNCE_MS);\n\nfunction onSearchInput(e: Event) {\n const v = (e.target as HTMLInputElement).value;\n local.value = v;\n debounced(v);\n}\n\nfunction onSort(e: Event) {\n emit('update:sortKey', (e.target as HTMLSelectElement).value as SortKey);\n}\n</script>\n\n<template>\n <div class=\"pelican-toolbar\">\n <button class=\"btn-flat filters-toggle\" type=\"button\" @click=\"emit('toggle-filters')\">\n Filters\n </button>\n <div class=\"counts\">\n Showing <b>{{ filteredTotal.toLocaleString('en-US') }}</b>\n of <b>{{ total.toLocaleString('en-US') }}</b>\n · page <b>{{ page }}</b> / {{ totalPages }}\n </div>\n <input\n class=\"search\"\n type=\"search\"\n placeholder=\"Search by signal name…\"\n autocomplete=\"off\"\n :value=\"local\"\n @input=\"onSearchInput\"\n />\n <div class=\"sort\">\n <label>Sort:</label>\n <select :value=\"sortKey\" @change=\"onSort\">\n <option v-for=\"k in SORT_KEYS\" :key=\"k\" :value=\"k\">{{ SORT_LABELS[k] }}</option>\n </select>\n </div>\n <button class=\"btn-flat\" type=\"button\" title=\"reload\" @click=\"emit('refresh')\">\n ↻ reload\n </button>\n </div>\n</template>\n\n<style scoped>\n.pelican-toolbar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n border-bottom: 1px solid var(--line);\n background: var(--header-bg);\n}\n.btn-flat {\n background: transparent;\n border: 1px solid var(--line);\n color: var(--text);\n padding: 6px 10px;\n border-radius: 6px;\n cursor: pointer;\n font: inherit;\n}\n.btn-flat:hover {\n border-color: var(--orange);\n}\n.filters-toggle {\n display: none;\n}\n.counts {\n color: var(--muted);\n font-size: 13px;\n}\n.counts b {\n color: var(--text);\n}\n.search {\n flex: 1 1 220px;\n min-width: 160px;\n padding: 8px 12px;\n border: 1px solid var(--line);\n border-radius: 8px;\n background: var(--input-bg);\n color: var(--text);\n font: inherit;\n}\n.search:focus {\n outline: none;\n border-color: var(--orange);\n}\n.sort {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n color: var(--muted);\n font-size: 13px;\n}\n.sort select {\n padding: 6px 8px;\n border: 1px solid var(--line);\n border-radius: 6px;\n background: var(--input-bg);\n color: var(--text);\n font: inherit;\n}\n@media (max-width: 720px) {\n .filters-toggle {\n display: inline-flex;\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport type { RiskLevel } from '../../types/strategy';\n\nconst props = defineProps<{ modelValue: Set<RiskLevel> }>();\nconst emit = defineEmits<{ (e: 'update:modelValue', v: Set<RiskLevel>): void }>();\n\nconst LEVELS: RiskLevel[] = ['Low', 'Medium', 'High'];\n\nfunction toggle(level: RiskLevel) {\n const next = new Set(props.modelValue);\n if (next.has(level)) next.delete(level);\n else next.add(level);\n emit('update:modelValue', next);\n}\n</script>\n\n<template>\n <div class=\"pelican-chips\">\n <button\n v-for=\"l in LEVELS\"\n :key=\"l\"\n type=\"button\"\n class=\"chip\"\n :class=\"['risk-' + l.toLowerCase(), { on: modelValue.has(l) }]\"\n @click=\"toggle(l)\"\n >\n {{ l }}\n </button>\n </div>\n</template>\n\n<style scoped>\n.pelican-chips {\n display: flex;\n gap: 6px;\n}\n.chip {\n cursor: pointer;\n padding: 6px 10px;\n border: 1px solid var(--line);\n border-radius: 999px;\n background: var(--card);\n color: var(--text);\n font: inherit;\n font-size: 12px;\n transition: background 0.15s, border-color 0.15s;\n}\n.chip:hover {\n border-color: var(--orange);\n}\n.chip.risk-low.on {\n background: var(--chip-low-bg);\n color: var(--chip-low-text);\n border-color: var(--chip-low-bg);\n}\n.chip.risk-medium.on {\n background: var(--chip-med-bg);\n color: var(--chip-med-text);\n border-color: var(--chip-med-bg);\n}\n.chip.risk-high.on {\n background: var(--chip-high-bg);\n color: var(--chip-high-text);\n border-color: var(--chip-high-bg);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\nconst props = withDefaults(\n defineProps<{\n label: string;\n modelValue: number | null;\n min: number;\n max: number;\n step?: number;\n /** If set, format(rawValue) → display string. Otherwise raw is used. */\n format?: (v: number) => string;\n /** raw value at which the filter is \"any\" (no constraint). Default = min. */\n anyAt?: number;\n inverted?: boolean;\n }>(),\n { step: 1 },\n);\n\nconst emit = defineEmits<{ (e: 'update:modelValue', v: number | null): void }>();\n\nconst anyAt = computed(() => props.anyAt ?? props.min);\nconst inverted = computed(() => !!props.inverted);\n\nconst raw = computed<number>(() => {\n if (props.modelValue == null) return inverted.value ? props.max : anyAt.value;\n return props.modelValue;\n});\n\nconst display = computed(() => {\n if (props.modelValue == null) return 'any';\n return props.format ? props.format(props.modelValue) : String(props.modelValue);\n});\n\nfunction onInput(e: Event) {\n const v = parseInt((e.target as HTMLInputElement).value, 10);\n if (isNaN(v)) return;\n if ((inverted.value && v >= props.max) || (!inverted.value && v <= anyAt.value)) {\n emit('update:modelValue', null);\n } else {\n emit('update:modelValue', v);\n }\n}\n</script>\n\n<template>\n <div class=\"pelican-fgroup\">\n <div class=\"title-row\">\n <label class=\"title\">{{ label }}</label>\n <span class=\"val\">{{ display }}</span>\n </div>\n <input\n type=\"range\"\n class=\"range\"\n :min=\"min\"\n :max=\"max\"\n :step=\"step\"\n :value=\"raw\"\n @input=\"onInput\"\n @change=\"onInput\"\n />\n </div>\n</template>\n\n<style scoped>\n.pelican-fgroup {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.title-row {\n display: flex;\n justify-content: space-between;\n align-items: baseline;\n}\n.title {\n font-size: 12px;\n color: var(--muted);\n}\n.val {\n font-size: 12px;\n color: var(--text);\n}\n.range {\n width: 100%;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\nconst props = defineProps<{\n label: string;\n /** Raw min handle value (0..rawMax). null = no min filter. */\n modelValueMin: number | null;\n /** Raw max handle value (0..rawMax). null = no max filter. */\n modelValueMax: number | null;\n rawMin?: number;\n rawMax?: number;\n /** Format raw → display (\"$10K\" / \"200%\"). Used for both min and max. */\n formatRaw: (v: number) => string;\n /** Map raw 0..rawMax onto domain (returnFromRaw, balanceFromRaw). */\n rawToDomain: (raw: number) => number;\n scaleHints?: string[];\n minLabel?: string;\n maxLabel?: string;\n}>();\n\nconst emit = defineEmits<{\n (e: 'update:modelValueMin', v: number | null): void;\n (e: 'update:modelValueMax', v: number | null): void;\n}>();\n\nconst rawMin = computed(() => props.rawMin ?? 0);\nconst rawMax = computed(() => props.rawMax ?? 100);\n\nconst lo = computed(() => props.modelValueMin ?? rawMin.value);\nconst hi = computed(() => props.modelValueMax ?? rawMax.value);\n\nconst loLabel = computed(() =>\n lo.value <= rawMin.value ? (props.minLabel ?? 'any') : props.formatRaw(props.rawToDomain(lo.value)),\n);\nconst hiLabel = computed(() =>\n hi.value >= rawMax.value\n ? (props.maxLabel ?? 'any')\n : props.formatRaw(props.rawToDomain(hi.value)),\n);\n\nconst rangeText = computed(() => {\n if (lo.value <= rawMin.value && hi.value >= rawMax.value) return 'any';\n return `${loLabel.value} – ${hiLabel.value}`;\n});\n\nfunction onMin(e: Event) {\n let v = parseInt((e.target as HTMLInputElement).value, 10);\n if (isNaN(v)) return;\n if (v > hi.value) v = hi.value;\n emit('update:modelValueMin', v <= rawMin.value ? null : v);\n}\nfunction onMax(e: Event) {\n let v = parseInt((e.target as HTMLInputElement).value, 10);\n if (isNaN(v)) return;\n if (v < lo.value) v = lo.value;\n emit('update:modelValueMax', v >= rawMax.value ? null : v);\n}\n</script>\n\n<template>\n <div class=\"pelican-fgroup\">\n <div class=\"title-row\">\n <label class=\"title\">{{ label }}</label>\n <span class=\"val\">{{ rangeText }}</span>\n </div>\n <div class=\"dual-track\">\n <input\n type=\"range\"\n class=\"range-dual\"\n :min=\"rawMin\"\n :max=\"rawMax\"\n :value=\"lo\"\n :style=\"{ zIndex: lo <= rawMin || lo >= hi ? 5 : 4 }\"\n @input=\"onMin\"\n @change=\"onMin\"\n />\n <input\n type=\"range\"\n class=\"range-dual\"\n :min=\"rawMin\"\n :max=\"rawMax\"\n :value=\"hi\"\n :style=\"{ zIndex: lo <= rawMin || lo >= hi ? 4 : 5 }\"\n @input=\"onMax\"\n @change=\"onMax\"\n />\n </div>\n <div v-if=\"scaleHints?.length\" class=\"scale\">\n <span v-for=\"h in scaleHints\" :key=\"h\">{{ h }}</span>\n </div>\n </div>\n</template>\n\n<style scoped>\n.pelican-fgroup {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.title-row {\n display: flex;\n justify-content: space-between;\n align-items: baseline;\n}\n.title {\n font-size: 12px;\n color: var(--muted);\n}\n.val {\n font-size: 12px;\n color: var(--text);\n}\n.dual-track {\n position: relative;\n height: 24px;\n display: flex;\n align-items: center;\n}\n.dual-track .range-dual {\n position: absolute;\n inset: 0;\n width: 100%;\n background: transparent;\n pointer-events: auto;\n}\n.scale {\n display: flex;\n justify-content: space-between;\n color: var(--muted);\n font-size: 11px;\n margin-top: 2px;\n}\n</style>\n","export type FormatLocale = string;\n\nexport interface FmtPctResult {\n text: string;\n positive: boolean;\n}\n\nexport function fmtPct(v: number | null | undefined, d = 2): FmtPctResult | null {\n if (v == null || isNaN(Number(v))) return null;\n const n = Number(v);\n return { text: `${n.toFixed(d)}%`, positive: n >= 0 };\n}\n\nexport function fmtMoney(v: number | null | undefined, locale: FormatLocale = 'en-US'): string {\n if (v == null || isNaN(Number(v))) return '—';\n const n = Number(v);\n const sign = n < 0 ? '-' : '';\n const abs = Math.abs(n);\n let s: string;\n if (abs >= 1e6) s = (abs / 1e6).toFixed(2) + 'M';\n else if (abs >= 1e3) s = Math.round(abs).toLocaleString(locale);\n else s = abs.toFixed(2);\n return `${sign}$${s}`;\n}\n\nexport function fmtMoneyFull(v: number | null | undefined, locale: FormatLocale = 'en-US'): string {\n if (v == null || isNaN(Number(v))) return '—';\n const n = Number(v);\n return `${n < 0 ? '-' : ''}$${Math.abs(n).toLocaleString(locale, {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n })}`;\n}\n\nexport function fmtNum(v: number | null | undefined, locale: FormatLocale = 'en-US'): string {\n return v == null ? '—' : Number(v).toLocaleString(locale);\n}\n\nexport function fmtFee(s: { Fee: number | null; _meta?: boolean }): string {\n if (s.Fee == null) {\n return s._meta ? 'free' : '—';\n }\n return `${(s.Fee * 100).toFixed(0)}%`;\n}\n\nexport function fmtTradeTime(iso: string | null | undefined, locale: FormatLocale = 'en-US'): string {\n if (!iso) return '—';\n const d = new Date(iso);\n if (isNaN(d.getTime())) return '—';\n return d.toLocaleString(locale, {\n year: '2-digit',\n month: 'short',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n hour12: false,\n });\n}\n\nexport function fmtAge(days: number | null): string {\n if (days == null) return '—';\n if (days < 30) return `${days}d`;\n const months = Math.floor(days / 30);\n if (months < 12) return `${months}mo`;\n const years = Math.floor(days / 365);\n const remMonths = Math.floor((days - years * 365) / 30);\n return remMonths ? `${years}y ${remMonths}mo` : `${years}y`;\n}\n\nexport function fmtAUM(v: number): string {\n if (v >= 1e6) return '$' + (v / 1e6).toFixed(2) + 'M';\n if (v >= 1e3) return '$' + Math.round(v / 1e3) + 'K';\n return '$' + Math.round(v);\n}\n\nexport function fmtRetMag(v: number): string {\n if (v >= 1000) {\n return (v / 1000).toFixed(1).replace(/\\.0$/, '') + 'K%';\n }\n return Math.round(v) + '%';\n}\n\nexport function escapeHtml(s: string | null | undefined): string {\n if (s == null) return '';\n return String(s)\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\nexport function initials(name: string | null | undefined): string {\n if (!name) return '?';\n const parts = name.trim().split(/\\s+/).slice(0, 2);\n return parts.map((p) => p.charAt(0).toUpperCase()).join('') || '?';\n}\n\nexport function ageDays(inception: string | null | undefined): number | null {\n if (!inception) return null;\n const d = new Date(inception);\n if (isNaN(d.getTime())) return null;\n return Math.floor((Date.now() - d.getTime()) / 86400000);\n}\n","// Ported from app.js:622-629.\n// Balance slider: log scale [10, 10^7] mapped to [0..100] raw ticks.\n// Return slider: log scale [10, 10^4.7 ~= 50000] mapped to [0..100] raw ticks.\n\nexport const balanceFromRaw = (v: number): number =>\n v <= 0 ? 0 : Math.round(Math.pow(10, 1 + ((v - 1) / 99) * 6));\n\nexport const rawFromBalance = (b: number): number =>\n b <= 0 ? 0 : Math.max(1, Math.min(100, Math.round(1 + ((Math.log10(b) - 1) * 99) / 6)));\n\nexport const returnFromRaw = (v: number): number =>\n v <= 0 ? 0 : Math.round(Math.pow(10, ((v - 1) / 99) * 4.7));\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { fmtAUM } from '../../utils/format';\nimport { rawFromBalance } from '../../utils/scales';\n\nconst props = defineProps<{\n modelValue: number | null;\n}>();\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', v: number | null): void;\n (e: 'apply', balance: { min: number; max: number } | null): void;\n}>();\n\nconst display = computed(() =>\n props.modelValue == null ? 'any' : fmtAUM(props.modelValue),\n);\n\nfunction onChange(e: Event) {\n const raw = (e.target as HTMLInputElement).value.trim();\n if (!raw) {\n emit('update:modelValue', null);\n emit('apply', null);\n return;\n }\n const v = parseInt(raw, 10);\n if (isNaN(v) || v <= 0) {\n emit('update:modelValue', null);\n emit('apply', null);\n return;\n }\n emit('update:modelValue', v);\n emit('apply', { min: rawFromBalance(50), max: rawFromBalance(v) });\n}\n</script>\n\n<template>\n <div class=\"pelican-fgroup\">\n <div class=\"title-row\">\n <label class=\"title\">Your Investment Amount, $</label>\n <span class=\"val\">{{ display }}</span>\n </div>\n <input\n type=\"number\"\n :min=\"50\"\n :step=\"50\"\n placeholder=\"e.g. 5000\"\n autocomplete=\"off\"\n :value=\"modelValue ?? ''\"\n @change=\"onChange\"\n />\n </div>\n</template>\n\n<style scoped>\n.pelican-fgroup {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.title-row {\n display: flex;\n justify-content: space-between;\n align-items: baseline;\n}\n.title {\n font-size: 12px;\n color: var(--muted);\n}\n.val {\n font-size: 12px;\n color: var(--text);\n}\ninput {\n width: 100%;\n padding: 8px 10px;\n border: 1px solid var(--line);\n border-radius: 6px;\n background: var(--input-bg);\n color: var(--text);\n font: inherit;\n}\ninput:focus {\n outline: none;\n border-color: var(--orange);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { ref, watch } from 'vue';\nimport RiskChips from './filters/RiskChips.vue';\nimport RangeSingle from './filters/RangeSingle.vue';\nimport RangeDual from './filters/RangeDual.vue';\nimport InvestAmount from './filters/InvestAmount.vue';\nimport type { FiltersState } from '../types/filters';\nimport type { RiskLevel } from '../types/strategy';\nimport { fmtAUM, fmtRetMag } from '../utils/format';\nimport { balanceFromRaw, returnFromRaw } from '../utils/scales';\n\nconst props = defineProps<{\n filters: FiltersState;\n investAmount: number | null;\n open: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: 'update:filters', f: Partial<FiltersState>): void;\n (e: 'update:investAmount', v: number | null): void;\n (e: 'reset'): void;\n}>();\n\n// Dual-range sliders need raw 0..100 positions held *here*, not derived from\n// `filters.retMin/retMax` (the slider's log scale isn't trivially invertible\n// per-tick, and round-tripping reactively would jitter the handle). We keep\n// the raw positions here and only push the domain values up to the parent's\n// FiltersState. When the parent resets filters externally, the watchers below\n// snap raw positions back to the extremes.\nconst retRawMin = ref<number>(0);\nconst retRawMax = ref<number>(100);\nconst balRawMin = ref<number>(0);\nconst balRawMax = ref<number>(100);\n\nwatch(retRawMin, (v) => {\n emit('update:filters', { retMin: v <= 0 ? null : returnFromRaw(v) });\n});\nwatch(retRawMax, (v) => {\n emit('update:filters', { retMax: v >= 100 ? null : returnFromRaw(v) });\n});\nwatch(balRawMin, (v) => {\n emit('update:filters', { balanceMin: v <= 0 ? null : balanceFromRaw(v) });\n});\nwatch(balRawMax, (v) => {\n emit('update:filters', { balanceMax: v >= 100 ? null : balanceFromRaw(v) });\n});\n\n// External reset (parent's `resetFilters` or InvestAmount-clear) → snap handles.\nwatch(\n () => [props.filters.retMin, props.filters.retMax],\n ([lo, hi]) => {\n if (lo == null) retRawMin.value = 0;\n if (hi == null) retRawMax.value = 100;\n },\n);\nwatch(\n () => [props.filters.balanceMin, props.filters.balanceMax],\n ([lo, hi]) => {\n if (lo == null) balRawMin.value = 0;\n if (hi == null) balRawMax.value = 100;\n },\n);\n\nfunction patch(p: Partial<FiltersState>) {\n emit('update:filters', p);\n}\nfunction setRisk(v: Set<RiskLevel>) {\n patch({ risk: v });\n}\n\nfunction applyInvest(range: { min: number; max: number } | null) {\n if (range == null) {\n patch({ balanceMin: null, balanceMax: null });\n balRawMin.value = 0;\n balRawMax.value = 100;\n } else {\n balRawMin.value = range.min;\n balRawMax.value = range.max;\n // The watchers above will fire and propagate to filters.balanceMin/Max.\n }\n}\n</script>\n\n<template>\n <aside class=\"pelican-filters\" :class=\"{ open }\">\n <div class=\"ftitle-row\">\n <label class=\"ftitle\">Risk</label>\n <button class=\"btn-reset\" type=\"button\" @click=\"emit('reset')\">reset filters</button>\n </div>\n <RiskChips :model-value=\"filters.risk\" @update:model-value=\"setRisk\" />\n\n <InvestAmount\n :model-value=\"investAmount\"\n @update:model-value=\"(v) => emit('update:investAmount', v)\"\n @apply=\"applyInvest\"\n />\n\n <RangeDual\n label=\"Return %\"\n :model-value-min=\"retRawMin\"\n :model-value-max=\"retRawMax\"\n :format-raw=\"(v) => fmtRetMag(v)\"\n :raw-to-domain=\"(raw) => returnFromRaw(raw)\"\n :scale-hints=\"['0%', '200%', '50K%+']\"\n max-label=\"50K%+\"\n @update:model-value-min=\"(v) => (retRawMin = v ?? 0)\"\n @update:model-value-max=\"(v) => (retRawMax = v ?? 100)\"\n />\n\n <RangeSingle\n label=\"Max Drawdown ≤\"\n :model-value=\"filters.ddMax\"\n :min=\"0\"\n :max=\"100\"\n :step=\"5\"\n :any-at=\"100\"\n :inverted=\"true\"\n :format=\"(v) => v + '%'\"\n @update:model-value=\"(v) => patch({ ddMax: v == null || v >= 100 ? null : v })\"\n />\n\n <RangeDual\n label=\"Balance\"\n :model-value-min=\"balRawMin\"\n :model-value-max=\"balRawMax\"\n :format-raw=\"(v) => fmtAUM(v)\"\n :raw-to-domain=\"(raw) => balanceFromRaw(raw)\"\n :scale-hints=\"['$0', '$10K', '$10M']\"\n max-label=\"$10M+\"\n @update:model-value-min=\"(v) => (balRawMin = v ?? 0)\"\n @update:model-value-max=\"(v) => (balRawMax = v ?? 100)\"\n />\n\n <RangeSingle\n label=\"Mgmt Fee ≤\"\n :model-value=\"filters.feeMax\"\n :min=\"0\"\n :max=\"100\"\n :step=\"5\"\n :any-at=\"100\"\n :inverted=\"true\"\n :format=\"(v) => v + '%'\"\n @update:model-value=\"(v) => patch({ feeMax: v == null || v >= 100 ? null : v })\"\n />\n\n <RangeSingle\n label=\"Copiers AUM ≥\"\n :model-value=\"filters.aumMin\"\n :min=\"0\"\n :max=\"5000000\"\n :step=\"50000\"\n :format=\"(v) => '≥ ' + fmtAUM(v)\"\n @update:model-value=\"(v) => patch({ aumMin: v && v > 0 ? v : null })\"\n />\n\n <RangeSingle\n label=\"Copiers ≥\"\n :model-value=\"filters.copiersMin\"\n :min=\"0\"\n :max=\"3000\"\n :step=\"10\"\n :format=\"(v) => '≥ ' + v\"\n @update:model-value=\"(v) => patch({ copiersMin: v && v > 0 ? v : null })\"\n />\n\n <RangeSingle\n label=\"Age ≥ (days)\"\n :model-value=\"filters.ageMin\"\n :min=\"0\"\n :max=\"3000\"\n :step=\"10\"\n :format=\"(v) => '≥ ' + v + 'd'\"\n @update:model-value=\"(v) => patch({ ageMin: v && v > 0 ? v : null })\"\n />\n\n <RangeSingle\n label=\"Trades ≥\"\n :model-value=\"filters.tradesMin\"\n :min=\"0\"\n :max=\"10000\"\n :step=\"50\"\n :format=\"(v) => '≥ ' + v\"\n @update:model-value=\"(v) => patch({ tradesMin: v && v > 0 ? v : null })\"\n />\n\n <RangeSingle\n label=\"Win Rate ≥\"\n :model-value=\"filters.winrateMin\"\n :min=\"0\"\n :max=\"100\"\n :step=\"5\"\n :format=\"(v) => '≥ ' + v + '%'\"\n @update:model-value=\"(v) => patch({ winrateMin: v && v > 0 ? v : null })\"\n />\n </aside>\n</template>\n\n<style scoped>\n.pelican-filters {\n display: flex;\n flex-direction: column;\n gap: 18px;\n padding: 16px;\n border-right: 1px solid var(--line);\n background: var(--card);\n width: 260px;\n flex: none;\n}\n.ftitle-row {\n display: flex;\n justify-content: space-between;\n align-items: baseline;\n}\n.ftitle {\n font-size: 13px;\n font-weight: 600;\n color: var(--text);\n}\n.btn-reset {\n background: transparent;\n border: none;\n color: var(--orange);\n font: inherit;\n font-size: 12px;\n cursor: pointer;\n padding: 0;\n}\n.btn-reset:hover {\n text-decoration: underline;\n}\n\n@media (max-width: 720px) {\n .pelican-filters {\n display: none;\n width: 100%;\n border-right: none;\n border-bottom: 1px solid var(--line);\n }\n .pelican-filters.open {\n display: flex;\n }\n}\n</style>\n","export const DONUT_PALETTE: string[] = [\n '#f97316',\n '#3b82f6',\n '#10b981',\n '#a855f7',\n '#ef4444',\n '#eab308',\n '#06b6d4',\n '#ec4899',\n '#14b8a6',\n '#8b5cf6',\n '#f59e0b',\n '#22c55e',\n];\n","import { DONUT_PALETTE } from '../constants/palette';\nimport type { HistoryPoint, MarketSlice } from '../types/strategy';\n\nexport type SparklinePoint = HistoryPoint;\n\nexport interface SparklineGeometry {\n hasData: boolean;\n width: number;\n height: number;\n zeroY: number;\n areaPath: string;\n linePath: string;\n positive: boolean;\n startX: number;\n endX: number;\n}\n\nexport function sparklineGeometry(\n history: SparklinePoint[] | null | undefined,\n w = 140,\n h = 34,\n): SparklineGeometry {\n if (!history || history.length < 2) {\n return {\n hasData: false,\n width: w,\n height: h,\n zeroY: h / 2,\n areaPath: '',\n linePath: '',\n positive: true,\n startX: 1,\n endX: w - 1,\n };\n }\n const times = history.map((p) => Date.parse(p.Timestamp));\n const tMin = times[0];\n const tMax = times[times.length - 1];\n const tSpan = tMax - tMin || 1;\n const ys = history.map((p) => p.AccountReturn);\n const yMin = Math.min(0, ...ys);\n const yMax = Math.max(0, ...ys);\n const yRange = yMax - yMin || 1;\n const px = (t: number) => ((t - tMin) / tSpan) * (w - 2) + 1;\n const py = (v: number) => h - 2 - ((v - yMin) / yRange) * (h - 4);\n const pts = history.map((p, i) => `${px(times[i]).toFixed(1)},${py(p.AccountReturn).toFixed(1)}`);\n const last = ys[ys.length - 1];\n const zeroY = py(0);\n const startX = px(tMin);\n const endX = px(tMax);\n const linePath = `M ${pts.join(' L ')}`;\n const areaPath =\n `M ${pts[0]} ` +\n pts.slice(1).map((p) => `L ${p}`).join(' ') +\n ` L ${endX.toFixed(1)},${zeroY.toFixed(1)} L ${startX.toFixed(1)},${zeroY.toFixed(1)} Z`;\n return {\n hasData: true,\n width: w,\n height: h,\n zeroY,\n areaPath,\n linePath,\n positive: last >= 0,\n startX,\n endX,\n };\n}\n\nexport interface DonutSlice {\n marketName: string;\n count: number;\n fraction: number;\n color: string;\n arcPath: string;\n labelLine: string | null;\n labelX: number;\n labelY: number;\n labelAnchor: 'start' | 'end';\n}\n\nexport interface DonutGeometry {\n width: number;\n height: number;\n cx: number;\n cy: number;\n outerR: number;\n innerR: number;\n slices: DonutSlice[];\n}\n\nexport function donutGeometry(items: MarketSlice[], w = 520, h = 280): DonutGeometry {\n const sorted = items.slice().sort((a, b) => (b.c || 0) - (a.c || 0));\n const total = sorted.reduce((acc, m) => acc + (m.c || 0), 0) || 1;\n const cx = w / 2;\n const cy = h / 2;\n const R = 90;\n const r = 52;\n const labelR = R + 10;\n const labelText = R + 30;\n\n let angle = -Math.PI / 2;\n const slices: DonutSlice[] = [];\n sorted.forEach((m, i) => {\n const frac = (m.c || 0) / total;\n const sweep = frac * Math.PI * 2;\n const a0 = angle;\n const a1 = angle + sweep;\n angle = a1;\n const aMid = (a0 + a1) / 2;\n const large = sweep > Math.PI ? 1 : 0;\n const x0 = cx + R * Math.cos(a0);\n const y0 = cy + R * Math.sin(a0);\n const x1 = cx + R * Math.cos(a1);\n const y1 = cy + R * Math.sin(a1);\n const xi0 = cx + r * Math.cos(a0);\n const yi0 = cy + r * Math.sin(a0);\n const xi1 = cx + r * Math.cos(a1);\n const yi1 = cy + r * Math.sin(a1);\n const arcPath =\n `M ${x0.toFixed(2)} ${y0.toFixed(2)} A ${R} ${R} 0 ${large} 1 ${x1.toFixed(2)} ${y1.toFixed(2)}` +\n ` L ${xi1.toFixed(2)} ${yi1.toFixed(2)} A ${r} ${r} 0 ${large} 0 ${xi0.toFixed(2)} ${yi0.toFixed(2)} Z`;\n const color = DONUT_PALETTE[i % DONUT_PALETTE.length];\n\n let labelLine: string | null = null;\n let labelX = 0;\n let labelY = 0;\n let labelAnchor: 'start' | 'end' = 'start';\n if (frac >= 0.015) {\n const isLeft = Math.cos(aMid) < 0;\n const lx1 = cx + R * Math.cos(aMid);\n const ly1 = cy + R * Math.sin(aMid);\n const lx2 = cx + labelR * Math.cos(aMid);\n const ly2 = cy + labelR * Math.sin(aMid);\n const lx3 = isLeft ? lx2 - 4 : lx2 + 4;\n labelLine = `${lx1.toFixed(1)},${ly1.toFixed(1)} ${lx2.toFixed(1)},${ly2.toFixed(1)} ${lx3.toFixed(1)},${ly2.toFixed(1)}`;\n labelX = isLeft ? lx2 - 6 : lx2 + 6;\n labelY = ly2 + 4;\n labelAnchor = isLeft ? 'end' : 'start';\n }\n\n slices.push({\n marketName: m.n,\n count: m.c,\n fraction: frac,\n color,\n arcPath,\n labelLine,\n labelX,\n labelY,\n labelAnchor,\n });\n });\n\n // labelText is intentionally part of geometry to keep callers free of magic numbers.\n void labelText;\n\n return { width: w, height: h, cx, cy, outerR: R, innerR: r, slices };\n}\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { sparklineGeometry } from '../utils/svg';\nimport type { HistoryPoint } from '../types/strategy';\n\nconst props = withDefaults(\n defineProps<{\n history: HistoryPoint[] | null | undefined;\n width?: number;\n height?: number;\n }>(),\n { width: 140, height: 34 },\n);\n\nconst geom = computed(() => sparklineGeometry(props.history, props.width, props.height));\n</script>\n\n<template>\n <svg\n v-if=\"!geom.hasData\"\n class=\"pelican-spark\"\n :width=\"geom.width\"\n :height=\"geom.height\"\n role=\"img\"\n aria-label=\"No equity data\"\n >\n <text x=\"2\" y=\"20\" font-size=\"11\" fill=\"var(--spark-no-data)\">no data</text>\n </svg>\n <svg\n v-else\n class=\"pelican-spark\"\n :width=\"geom.width\"\n :height=\"geom.height\"\n :viewBox=\"`0 0 ${geom.width} ${geom.height}`\"\n preserveAspectRatio=\"none\"\n role=\"img\"\n aria-label=\"Equity curve\"\n >\n <line\n x1=\"0\"\n :x2=\"geom.width\"\n :y1=\"geom.zeroY\"\n :y2=\"geom.zeroY\"\n stroke=\"var(--grid-line)\"\n stroke-dasharray=\"2 3\"\n stroke-width=\"1\"\n vector-effect=\"non-scaling-stroke\"\n />\n <path\n :d=\"geom.areaPath\"\n :fill=\"geom.positive ? 'var(--area-green)' : 'var(--area-red)'\"\n stroke=\"none\"\n />\n <path\n :d=\"geom.linePath\"\n fill=\"none\"\n :stroke=\"geom.positive ? 'var(--green)' : 'var(--red)'\"\n stroke-width=\"1.6\"\n stroke-linejoin=\"round\"\n stroke-linecap=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n </svg>\n</template>\n\n<style scoped>\n.pelican-spark {\n display: block;\n width: 100%;\n max-width: 100%;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { MarketSlice } from '../types/strategy';\nimport { donutGeometry } from '../utils/svg';\n\nconst props = withDefaults(\n defineProps<{\n markets: MarketSlice[];\n width?: number;\n height?: number;\n }>(),\n { width: 520, height: 280 },\n);\n\nconst empty = computed(() => !props.markets || props.markets.length === 0);\nconst geom = computed(() => donutGeometry(props.markets, props.width, props.height));\n</script>\n\n<template>\n <span v-if=\"empty\" class=\"dim\">no market data</span>\n <svg\n v-else\n class=\"pelican-donut\"\n :viewBox=\"`0 0 ${geom.width} ${geom.height}`\"\n width=\"100%\"\n preserveAspectRatio=\"xMidYMid meet\"\n role=\"img\"\n aria-label=\"Markets donut chart\"\n >\n <g>\n <path\n v-for=\"s in geom.slices\"\n :key=\"s.marketName + s.fraction\"\n :d=\"s.arcPath\"\n :fill=\"s.color\"\n stroke=\"var(--card)\"\n stroke-width=\"1.5\"\n />\n </g>\n <g>\n <polyline\n v-for=\"s in geom.slices\"\n :key=\"`l-${s.marketName}`\"\n v-show=\"s.labelLine\"\n :points=\"s.labelLine ?? ''\"\n :stroke=\"s.color\"\n stroke-width=\"1\"\n fill=\"none\"\n />\n </g>\n <g>\n <text\n v-for=\"s in geom.slices\"\n :key=\"`t-${s.marketName}`\"\n v-show=\"s.labelLine\"\n :x=\"s.labelX\"\n :y=\"s.labelY\"\n :text-anchor=\"s.labelAnchor\"\n font-size=\"11\"\n fill=\"var(--text)\"\n font-weight=\"500\"\n >\n {{ s.marketName }}\n <tspan fill=\"var(--muted)\" font-weight=\"400\">{{ s.count }}</tspan>\n </text>\n </g>\n </svg>\n</template>\n\n<style scoped>\n.pelican-donut {\n display: block;\n width: 100%;\n max-width: 100%;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { SignalKind } from '../types/api';\nimport type { Trade } from '../types/strategy';\nimport { fmtTradeTime, fmtMoneyFull } from '../utils/format';\n\nconst props = defineProps<{\n kind: SignalKind;\n trades: Trade[] | null;\n loading: boolean;\n locale: string;\n}>();\n\nconst title = computed(() => (props.kind === 'open' ? 'Open Trades' : 'Trade History (30d)'));\nconst empty = computed(\n () => !props.loading && (props.trades == null || props.trades.length === 0),\n);\n</script>\n\n<template>\n <div class=\"pelican-trades\">\n <div class=\"hd\">{{ title }}</div>\n <div v-if=\"loading\" class=\"dim\">Loading…</div>\n <div v-else-if=\"empty\" class=\"dim\">No trades.</div>\n <ul v-else class=\"list\">\n <li v-for=\"(t, i) in trades ?? []\" :key=\"i\">\n <span class=\"market\">{{ t.MarketName ?? '—' }}</span>\n <span class=\"dir\" :class=\"t.Direction === 'Sell' ? 'red' : 'green'\">{{ t.Direction ?? '' }}</span>\n <span class=\"trade-time\">\n {{ fmtTradeTime(t.OpenTimestamp, locale) }}\n <template v-if=\"t.CloseTimestamp\"> → {{ fmtTradeTime(t.CloseTimestamp, locale) }}</template>\n </span>\n <span v-if=\"t.Pnl != null\" class=\"pnl\" :class=\"t.Pnl >= 0 ? 'green' : 'red'\">\n {{ fmtMoneyFull(t.Pnl, locale) }}\n </span>\n </li>\n </ul>\n </div>\n</template>\n\n<style scoped>\n.pelican-trades {\n padding: 12px 16px;\n background: var(--sage-2);\n border-radius: 8px;\n}\n.hd {\n font-weight: 600;\n margin-bottom: 8px;\n color: var(--text);\n}\n.list {\n list-style: none;\n padding: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n font-size: 12px;\n}\n.list li {\n display: grid;\n grid-template-columns: minmax(80px, 1.4fr) auto 1.6fr auto;\n gap: 8px;\n align-items: baseline;\n}\n.market {\n color: var(--text);\n font-weight: 500;\n}\n.dir {\n font-weight: 600;\n text-transform: uppercase;\n font-size: 10px;\n}\n.trade-time {\n color: var(--muted);\n}\n.pnl {\n font-variant-numeric: tabular-nums;\n text-align: right;\n}\n.green {\n color: var(--green);\n}\n.red {\n color: var(--red);\n}\n.dim {\n color: var(--muted);\n}\n</style>\n","import type { Strategy } from '../types/strategy';\n\nexport function winrate(s: Pick<Strategy, 'Wins' | 'Losses'>): number {\n const wins = s.Wins ?? 0;\n const losses = s.Losses ?? 0;\n const t = wins + losses;\n return t ? (wins / t) * 100 : -1;\n}\n","import type { InjectionKey } from 'vue';\n\nexport type ApiBaseKey = string;\nexport type CatalogBaseKey = string;\nexport type LocaleKey = string;\n\nexport const API_BASE_KEY: InjectionKey<ApiBaseKey> = Symbol('pelican.apiBase');\nexport const CATALOG_BASE_KEY: InjectionKey<CatalogBaseKey> = Symbol('pelican.catalogBase');\nexport const LOCALE_KEY: InjectionKey<LocaleKey> = Symbol('pelican.locale');\n","<script setup lang=\"ts\">\nimport { computed, inject, ref } from 'vue';\nimport Sparkline from './Sparkline.vue';\nimport MarketsDonut from './MarketsDonut.vue';\nimport TradesPanel from './TradesPanel.vue';\nimport type { Strategy } from '../types/strategy';\nimport type { SignalKind } from '../types/api';\nimport {\n ageDays,\n fmtAge,\n fmtFee,\n fmtMoney,\n fmtMoneyFull,\n fmtNum,\n fmtPct,\n initials,\n} from '../utils/format';\nimport { winrate } from '../utils/winrate';\nimport { LOCALE_KEY } from '../injection-keys';\n\nconst props = defineProps<{\n s: Strategy;\n expanded: boolean;\n openTrades: { loading: boolean; trades: import('../types/strategy').Trade[] | null } | null;\n closedTrades: { loading: boolean; trades: import('../types/strategy').Trade[] | null } | null;\n}>();\n\nconst emit = defineEmits<{\n (e: 'toggle'): void;\n (e: 'load-trades', kind: SignalKind): void;\n (e: 'select'): void;\n}>();\n\nconst locale = inject(LOCALE_KEY, 'en-US');\n\nconst ret = computed(() => fmtPct(props.s.Return, 1));\nconst dd = computed(() => (props.s.MaxDD != null ? fmtPct(props.s.MaxDD, 2) : null));\nconst age = computed(() => ageDays(props.s.Inception));\nconst wr = computed(() => winrate(props.s));\nconst lr = computed(() => (wr.value >= 0 ? 100 - wr.value : -1));\nconst profileName = computed(\n () => props.s.Profile?.Name ?? (props.s.Profile?.Id ? '#' + props.s.Profile.Id : ''),\n);\nconst link = computed(() => `https://libertex.copy-trade.io/strategy/${props.s.Id}`);\n\nconst showOpen = ref(false);\nconst showClosed = ref(false);\n\nfunction toggleOpen() {\n showOpen.value = !showOpen.value;\n if (showOpen.value && !props.openTrades) emit('load-trades', 'open');\n}\nfunction toggleClosed() {\n showClosed.value = !showClosed.value;\n if (showClosed.value && !props.closedTrades) emit('load-trades', 'closed');\n}\n</script>\n\n<template>\n <div class=\"pelican-row\" :class=\"{ open: expanded }\" :data-id=\"s.Id\" @click=\"emit('toggle')\">\n <div class=\"name\">\n <div class=\"avatar\">\n <span class=\"avatar-fallback\">{{ initials(s.Name) }}</span>\n <img\n v-if=\"s.ImageUploaded\"\n class=\"avatar-img\"\n :src=\"`https://assets.copy-trade.io/images/strategies/thumbnails/${s.Id}`\"\n alt=\"\"\n loading=\"lazy\"\n decoding=\"async\"\n @error=\"($event.target as HTMLImageElement).remove()\"\n />\n </div>\n <div class=\"nm\">\n <div class=\"title\">\n {{ s.Name || '#' + s.Id }}\n <span v-if=\"s._meta && s.Fee == null\" class=\"free-badge\">free</span>\n </div>\n <div class=\"by\">{{ profileName }}</div>\n </div>\n </div>\n <div class=\"c-spark\" data-label=\"Equity curve\">\n <Sparkline :history=\"s.History\" />\n </div>\n <div class=\"c-num\" data-label=\"Return\">\n <span v-if=\"ret\" :class=\"ret.positive ? 'green' : 'red'\">{{ ret.text }}</span>\n <span v-else>—</span>\n </div>\n <div class=\"c-num\" data-label=\"Copiers\">{{ fmtNum(s.NumCopiers, locale) }}</div>\n <div class=\"c-num\" data-label=\"Copiers AUM\">{{ fmtMoney(s.CopiersAUM, locale) }}</div>\n <div class=\"c-num\" data-label=\"Max DD\">\n <span v-if=\"dd\" :class=\"dd.positive ? 'green' : 'red'\">{{ dd.text }}</span>\n <span v-else>—</span>\n </div>\n <div class=\"c-num\" data-label=\"Age\">{{ fmtAge(age) }}</div>\n <div class=\"c-num\" data-label=\"Balance\">{{ fmtMoney(s.AccountBalance, locale) }}</div>\n <div class=\"c-num\" data-label=\"Fee\">{{ fmtFee(s) }}</div>\n <div class=\"c-link\" @click.stop>\n <a class=\"signal-link\" :href=\"link\" target=\"_blank\" rel=\"noopener\" @click.stop>\n Get connected\n </a>\n <slot name=\"row-actions\" :strategy=\"s\" />\n </div>\n </div>\n\n <div v-if=\"expanded\" class=\"pelican-row-expanded\" @click.stop>\n <div class=\"grid\">\n <div class=\"col-stats\">\n <div class=\"field\"><div class=\"label\">Currency</div><div class=\"value\">{{ s.Currency ?? 'USD' }}</div></div>\n <div class=\"field\"><div class=\"label\">Monthly profit</div><div class=\"value\">{{ fmtMoneyFull(s.MonthlyProfit, locale) }}</div></div>\n <div class=\"field\"><div class=\"label\">Yearly profit</div><div class=\"value\">{{ fmtMoneyFull(s.YearlyProfit, locale) }}</div></div>\n <div class=\"field\"><div class=\"label\">Balance</div><div class=\"value\">{{ fmtMoneyFull(s.AccountBalance, locale) }}</div></div>\n <div class=\"field\"><div class=\"label\">Realized P/L</div><div class=\"value\">{{ fmtMoneyFull(s.RealisedPnl, locale) }}</div></div>\n <div class=\"field\"><div class=\"label\">Unrealized P/L</div><div class=\"value\">{{ fmtMoneyFull(s.UnrealisedPnl, locale) }}</div></div>\n <div class=\"field\"><div class=\"label\">Trades total</div><div class=\"value\">{{ fmtNum(s.TradesTotal, locale) }}</div></div>\n <div class=\"field\">\n <div class=\"label\">Win rate</div>\n <div class=\"value\">\n <span v-if=\"wr >= 0\">{{ wr.toFixed(1) }}% / {{ lr.toFixed(1) }}%</span>\n <span v-else class=\"dim\">—</span>\n </div>\n </div>\n </div>\n <div class=\"col-donut\">\n <div class=\"hd\">Markets</div>\n <MarketsDonut :markets=\"s.Markets\" />\n </div>\n </div>\n\n <div class=\"trade-toggles\">\n <button class=\"pill\" :class=\"{ on: showOpen }\" type=\"button\" @click=\"toggleOpen\">\n {{ showOpen ? 'Hide' : 'Open Trades' }}\n </button>\n <button class=\"pill\" :class=\"{ on: showClosed }\" type=\"button\" @click=\"toggleClosed\">\n {{ showClosed ? 'Hide' : 'Trade History' }}\n </button>\n </div>\n\n <TradesPanel\n v-if=\"showOpen\"\n kind=\"open\"\n :trades=\"openTrades?.trades ?? null\"\n :loading=\"!!openTrades?.loading\"\n :locale=\"locale\"\n />\n <TradesPanel\n v-if=\"showClosed\"\n kind=\"closed\"\n :trades=\"closedTrades?.trades ?? null\"\n :loading=\"!!closedTrades?.loading\"\n :locale=\"locale\"\n />\n </div>\n</template>\n\n<style scoped>\n.pelican-row {\n display: grid;\n grid-template-columns: minmax(160px, 1.6fr) minmax(120px, 1fr) repeat(7, minmax(70px, 0.8fr)) auto;\n gap: 12px;\n align-items: center;\n padding: 10px 16px;\n border-bottom: 1px solid var(--line-2);\n cursor: pointer;\n transition: background 0.15s;\n}\n.pelican-row:hover {\n background: var(--row-hover);\n}\n.pelican-row.open {\n background: var(--row-hover);\n}\n.name {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n.avatar {\n position: relative;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: var(--sage);\n color: var(--text-2);\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n flex: none;\n overflow: hidden;\n}\n.avatar-img {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n.title {\n font-weight: 600;\n color: var(--text);\n}\n.by {\n color: var(--muted);\n font-size: 12px;\n}\n.free-badge {\n margin-left: 6px;\n background: var(--chip-low-bg);\n color: var(--chip-low-text);\n font-size: 10px;\n padding: 1px 6px;\n border-radius: 999px;\n font-weight: 700;\n}\n.c-num {\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n.c-link {\n text-align: right;\n}\n.signal-link {\n color: var(--orange);\n text-decoration: none;\n font-size: 12px;\n}\n.signal-link:hover {\n text-decoration: underline;\n}\n.green {\n color: var(--green);\n}\n.red {\n color: var(--red);\n}\n.dim {\n color: var(--muted);\n}\n\n.pelican-row-expanded {\n padding: 16px;\n background: var(--sage-2);\n border-bottom: 1px solid var(--line);\n display: flex;\n flex-direction: column;\n gap: 14px;\n}\n.grid {\n display: grid;\n grid-template-columns: minmax(220px, 1fr) minmax(280px, 1.2fr);\n gap: 16px;\n}\n.col-stats {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 12px 16px;\n}\n.field .label {\n color: var(--muted);\n font-size: 12px;\n}\n.field .value {\n color: var(--text);\n font-weight: 500;\n}\n.col-donut .hd {\n font-weight: 600;\n color: var(--text);\n margin-bottom: 6px;\n}\n.trade-toggles {\n display: flex;\n gap: 8px;\n}\n.pill {\n cursor: pointer;\n padding: 6px 14px;\n border-radius: 999px;\n border: 1px solid var(--line);\n background: var(--card);\n color: var(--text);\n font: inherit;\n font-size: 12px;\n}\n.pill.on {\n background: var(--orange);\n border-color: var(--orange);\n color: #fff;\n}\n\n@media (max-width: 720px) {\n .pelican-row {\n grid-template-columns: 1fr;\n gap: 4px;\n }\n .pelican-row > [data-label]::before {\n content: attr(data-label);\n color: var(--muted);\n margin-right: 8px;\n font-size: 11px;\n }\n .grid {\n grid-template-columns: 1fr;\n }\n}\n</style>\n","<script setup lang=\"ts\">\nconst props = defineProps<{\n page: number;\n totalPages: number;\n range: (number | '…')[];\n}>();\n\nconst emit = defineEmits<{\n (e: 'go', page: number | 'prev' | 'next'): void;\n}>();\n\nfunction go(target: number | 'prev' | 'next') {\n emit('go', target);\n}\nfunction onGoto(e: Event) {\n const v = parseInt((e.target as HTMLInputElement).value, 10);\n if (!isNaN(v)) emit('go', v);\n}\n</script>\n\n<template>\n <nav v-if=\"props.totalPages > 1\" class=\"pelican-pager\">\n <button :disabled=\"page <= 1\" @click=\"go('prev')\">‹ prev</button>\n <template v-for=\"(p, i) in range\" :key=\"i\">\n <span v-if=\"p === '…'\" class=\"gap\">…</span>\n <button v-else class=\"page\" :class=\"{ cur: p === page }\" @click=\"go(p)\">{{ p }}</button>\n </template>\n <button :disabled=\"page >= totalPages\" @click=\"go('next')\">next ›</button>\n <span class=\"info\">\n go to\n <input type=\"number\" :min=\"1\" :max=\"totalPages\" :value=\"page\" @change=\"onGoto\" />\n </span>\n </nav>\n</template>\n\n<style scoped>\n.pelican-pager {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 6px;\n padding: 16px 0;\n font-size: 13px;\n}\n.pelican-pager button {\n background: var(--card);\n border: 1px solid var(--line);\n color: var(--text);\n border-radius: 6px;\n padding: 6px 10px;\n cursor: pointer;\n font: inherit;\n}\n.pelican-pager button:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n.pelican-pager button.page.cur {\n background: var(--orange);\n color: #fff;\n border-color: var(--orange);\n}\n.pelican-pager .gap {\n padding: 0 4px;\n color: var(--muted);\n}\n.pelican-pager .info {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n color: var(--muted);\n margin-left: 8px;\n}\n.pelican-pager .info input {\n width: 64px;\n padding: 6px;\n border: 1px solid var(--line);\n border-radius: 6px;\n background: var(--input-bg);\n color: var(--text);\n font: inherit;\n}\n</style>\n","<script setup lang=\"ts\">\nimport StrategyRow from './StrategyRow.vue';\nimport Pager from './Pager.vue';\nimport type { Strategy, Trade } from '../types/strategy';\nimport type { SignalKind } from '../types/api';\nimport type { SortColumn, SortKey } from '../constants/sort';\n\nconst props = defineProps<{\n pageItems: Strategy[];\n expanded: Set<number>;\n sortKey: SortKey;\n page: number;\n totalPages: number;\n pageRange: (number | '…')[];\n openSignals: Map<number, { loading: boolean; trades: Trade[] | null }>;\n closedSignals: Map<number, { loading: boolean; trades: Trade[] | null }>;\n}>();\n\nconst emit = defineEmits<{\n (e: 'toggle-row', id: number): void;\n (e: 'toggle-sort', col: SortColumn): void;\n (e: 'load-trades', payload: { id: number; kind: SignalKind }): void;\n (e: 'select', s: Strategy): void;\n (e: 'go', target: number | 'prev' | 'next'): void;\n}>();\n\nconst SORTABLE: { key: SortColumn; label: string }[] = [\n { key: 'return', label: 'Return %' },\n { key: 'copiers', label: 'Copiers' },\n { key: 'aum', label: 'Copiers AUM' },\n { key: 'dd', label: 'Max Drawdown' },\n { key: 'age', label: 'Age' },\n { key: 'balance', label: 'Balance' },\n { key: 'fee', label: 'Mgmt Fee %' },\n];\n\nfunction sortClass(col: SortColumn): string {\n if (props.sortKey === `${col}-asc`) return 'active-asc';\n if (props.sortKey === `${col}-desc`) return 'active-desc';\n return '';\n}\n</script>\n\n<template>\n <section class=\"pelican-table\">\n <div class=\"row head\">\n <div>Name</div>\n <div>Equity curve</div>\n <div\n v-for=\"col in SORTABLE\"\n :key=\"col.key\"\n class=\"c-num sortable\"\n :class=\"sortClass(col.key)\"\n @click=\"emit('toggle-sort', col.key)\"\n >\n {{ col.label }}\n </div>\n <div></div>\n </div>\n\n <div v-if=\"pageItems.length === 0\" class=\"empty\">\n <slot name=\"empty\">No matches.</slot>\n </div>\n <template v-else>\n <StrategyRow\n v-for=\"s in pageItems\"\n :key=\"s.Id\"\n :s=\"s\"\n :expanded=\"expanded.has(s.Id)\"\n :open-trades=\"openSignals.get(s.Id) ?? null\"\n :closed-trades=\"closedSignals.get(s.Id) ?? null\"\n @toggle=\"emit('toggle-row', s.Id)\"\n @load-trades=\"(kind) => emit('load-trades', { id: s.Id, kind })\"\n @select=\"emit('select', s)\"\n >\n <template #row-actions=\"slotProps\">\n <slot name=\"row-actions\" v-bind=\"slotProps\" />\n </template>\n </StrategyRow>\n </template>\n\n <Pager\n :page=\"page\"\n :total-pages=\"totalPages\"\n :range=\"pageRange\"\n @go=\"(t) => emit('go', t)\"\n />\n </section>\n</template>\n\n<style scoped>\n.pelican-table {\n flex: 1;\n min-width: 0;\n}\n.row.head {\n display: grid;\n grid-template-columns: minmax(160px, 1.6fr) minmax(120px, 1fr) repeat(7, minmax(70px, 0.8fr)) auto;\n gap: 12px;\n padding: 12px 16px;\n background: var(--sage-2);\n border-bottom: 1px solid var(--line);\n font-size: 12px;\n font-weight: 600;\n color: var(--muted);\n text-transform: uppercase;\n letter-spacing: 0.04em;\n}\n.row.head .c-num {\n text-align: right;\n}\n.row.head .sortable {\n cursor: pointer;\n user-select: none;\n}\n.row.head .sortable:hover {\n color: var(--text);\n}\n.row.head .sortable.active-asc::after {\n content: ' ↑';\n color: var(--orange);\n}\n.row.head .sortable.active-desc::after {\n content: ' ↓';\n color: var(--orange);\n}\n.empty {\n padding: 60px 20px;\n text-align: center;\n color: var(--muted);\n}\n@media (max-width: 720px) {\n .row.head {\n display: none;\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\nconst props = defineProps<{\n loaded: number;\n total: number;\n active: boolean;\n}>();\n\nconst pct = computed(() =>\n props.total > 0 ? Math.min(100, (props.loaded / props.total) * 100) : 0,\n);\n</script>\n\n<template>\n <div v-if=\"active\" class=\"pelican-progress\">\n <div class=\"bar\"><span :style=\"{ width: pct.toFixed(1) + '%' }\" /></div>\n <div class=\"caption\">\n Building full catalog: <b>{{ loaded.toLocaleString('en-US') }}</b>\n / {{ total.toLocaleString('en-US') }}\n strategies ({{ pct.toFixed(0) }}%) · <i>upstream rate-limited</i>\n </div>\n <div class=\"hint\">\n All {{ total.toLocaleString('en-US') }} strategies are visible. Stats fill in as the build\n progresses; refresh of data every 20 sec.\n </div>\n </div>\n</template>\n\n<style scoped>\n.pelican-progress {\n padding: 12px 16px;\n color: var(--muted);\n font-size: 13px;\n}\n.bar {\n position: relative;\n height: 6px;\n width: 100%;\n background: var(--line-2);\n border-radius: 4px;\n overflow: hidden;\n margin-bottom: 8px;\n}\n.bar span {\n display: block;\n height: 100%;\n background: var(--orange);\n transition: width 0.4s ease;\n}\n.caption b {\n color: var(--text);\n}\n.hint {\n margin-top: 6px;\n font-size: 12px;\n color: var(--muted-2);\n}\n</style>\n","import { ref, watch, onScopeDispose, type Ref } from 'vue';\nimport type { ThemeMode } from '../types/columns';\n\nconst STORAGE_KEY = 'pelican-theme';\n\nexport interface UseThemeReturn {\n mode: Ref<ThemeMode>;\n resolved: Ref<'dark' | 'light'>;\n setMode(next: ThemeMode): void;\n cycle(): void;\n}\n\nexport function useTheme(initial: ThemeMode = 'auto'): UseThemeReturn {\n const stored = readStored();\n const mode = ref<ThemeMode>(stored ?? initial);\n const resolved = ref<'dark' | 'light'>('dark');\n const mq = typeof window !== 'undefined' && window.matchMedia\n ? window.matchMedia('(prefers-color-scheme: dark)')\n : null;\n\n // Compute resolved value only — DO NOT touch document.documentElement.\n // The component template binds `:data-theme=\"resolved\"` on its own root div,\n // so theme stays scoped to the component and never collides with a host app's\n // own theme system.\n const apply = () => {\n const m = mode.value;\n resolved.value =\n m === 'dark' ? 'dark' : m === 'light' ? 'light' : mq?.matches ? 'dark' : 'light';\n };\n\n const onMq = () => {\n if (mode.value === 'auto') apply();\n };\n\n if (mq) {\n if (mq.addEventListener) mq.addEventListener('change', onMq);\n else mq.addListener(onMq);\n }\n\n watch(mode, (m) => {\n try {\n localStorage.setItem(STORAGE_KEY, m);\n } catch {\n /* storage unavailable */\n }\n apply();\n });\n\n apply();\n\n onScopeDispose(() => {\n if (mq) {\n if (mq.removeEventListener) mq.removeEventListener('change', onMq);\n else mq.removeListener(onMq);\n }\n });\n\n function setMode(next: ThemeMode) {\n mode.value = next;\n }\n function cycle() {\n mode.value = mode.value === 'dark' ? 'light' : mode.value === 'light' ? 'auto' : 'dark';\n }\n\n return { mode, resolved, setMode, cycle };\n}\n\nfunction readStored(): ThemeMode | null {\n try {\n const v = localStorage.getItem(STORAGE_KEY);\n if (v === 'dark' || v === 'light' || v === 'auto') return v;\n return null;\n } catch {\n return null;\n }\n}\n","export interface PelicanError extends Error {\n code: 'no_token' | 'fetch_failed' | 'http_error';\n status?: number;\n}\n\nexport function makeError(\n code: PelicanError['code'],\n message: string,\n status?: number,\n): PelicanError {\n const e = new Error(message) as PelicanError;\n e.code = code;\n if (status !== undefined) e.status = status;\n return e;\n}\n\nexport async function api<T = unknown>(path: string, apiBase: string): Promise<T> {\n const url = joinUrl(apiBase, path);\n let r: Response;\n try {\n r = await fetch(url);\n } catch (e) {\n throw makeError('fetch_failed', (e as Error).message ?? 'fetch failed');\n }\n if (r.status === 401 || r.status === 503) {\n throw makeError('no_token', 'Proxy has no token yet', r.status);\n }\n if (!r.ok) {\n const t = await r.text().catch(() => '');\n throw makeError('http_error', `${r.status}: ${t.slice(0, 120)}`, r.status);\n }\n return (await r.json()) as T;\n}\n\nexport function joinUrl(base: string, path: string): string {\n if (!base) return path;\n const b = base.endsWith('/') ? base.slice(0, -1) : base;\n const p = path.startsWith('/') ? path : '/' + path;\n return b + p;\n}\n","import { computed, onScopeDispose, ref, shallowRef, triggerRef, type Ref } from 'vue';\nimport type { Strategy, HistoryPoint } from '../types/strategy';\nimport type { ProgressResponse } from '../types/api';\nimport { api, joinUrl, type PelicanError } from '../utils/http';\nimport {\n PARTIAL_REPAINT_INTERVAL_MS,\n PROGRESS_POLL_INTERVAL_MS,\n} from '../constants/defaults';\n\nexport interface UseCatalogOptions {\n apiBase: Ref<string>;\n /**\n * Optional separate origin for the *static* catalog endpoints\n * (`/api/strategies-full` and `/api/strategies-full/progress`).\n *\n * Intended use: a Cloudflare Worker fronting an R2 bucket — the catalog\n * lives on the edge, while live per-strategy data still goes through the\n * pelican-proxy at `apiBase`. When provided and different from `apiBase`,\n * `useCatalog` skips the partial-load polling loop (the edge always serves\n * a fully-built catalog).\n *\n * If omitted, all endpoints — including catalog — go through `apiBase`.\n */\n catalogBase?: Ref<string | undefined>;\n onError?(err: PelicanError): void;\n}\n\nexport interface UseCatalogReturn {\n catalog: Ref<Strategy[]>;\n ready: Ref<boolean>;\n building: Ref<boolean>;\n loaded: Ref<number>;\n total: Ref<number>;\n builtAt: Ref<number | null>;\n enrichOne(id: number): Promise<void>;\n searchExtra(filter: string): Promise<void>;\n refresh(): Promise<void>;\n start(): void;\n stop(): void;\n}\n\nexport function useCatalog({ apiBase, catalogBase, onError }: UseCatalogOptions): UseCatalogReturn {\n const byIdRef = shallowRef<Map<number, Strategy>>(new Map());\n const ready = ref(false);\n const building = ref(false);\n const loaded = ref(0);\n const total = ref(0);\n const builtAt = ref<number | null>(null);\n\n const catalog = computed<Strategy[]>(() => Array.from(byIdRef.value.values()));\n\n let stopped = false;\n\n const handleError = (e: unknown) => {\n if (onError) onError(e as PelicanError);\n else console.warn('[pelican-vue]', e);\n };\n\n // When catalogBase is set and points somewhere other than apiBase, the\n // edge catalog is pre-built and immediately complete — no progress/partial\n // dance needed. Otherwise (legacy single-origin setup) we fall back to the\n // proxy's partial-load + progress polling protocol.\n const isEdgeCatalog = () => {\n const cb = catalogBase?.value;\n return !!cb && cb !== apiBase.value;\n };\n const catalogOrigin = () => catalogBase?.value || apiBase.value;\n\n async function fetchAndMerge(partial: boolean) {\n try {\n const url = partial ? '/api/strategies-full?partial=1' : '/api/strategies-full';\n const items = await api<Strategy[]>(url, catalogOrigin());\n total.value = items.length;\n const m = byIdRef.value;\n for (const it of items) m.set(it.Id, { ...m.get(it.Id), ...it } as Strategy);\n triggerRef(byIdRef);\n } catch (e) {\n handleError(e);\n }\n }\n\n async function pollProgress(): Promise<ProgressResponse | null> {\n try {\n const p = await api<ProgressResponse>('/api/strategies-full/progress', catalogOrigin());\n loaded.value = p.loaded;\n total.value = p.total || total.value;\n building.value = p.building;\n builtAt.value = p.built_at;\n return p;\n } catch (e) {\n handleError(e);\n return null;\n }\n }\n\n async function loadFull() {\n if (isEdgeCatalog()) {\n // Single fetch — the edge catalog is always ready; no partial/polling.\n await fetchAndMerge(false);\n // Best-effort progress fetch so callers can read built_at; failures are non-fatal.\n void pollProgress();\n ready.value = true;\n return;\n }\n await fetchAndMerge(true);\n let lastPaint = Date.now();\n while (!stopped) {\n const p = await pollProgress();\n if (!p) {\n await sleep(1500);\n continue;\n }\n if (p.ready) break;\n if (Date.now() - lastPaint > PARTIAL_REPAINT_INTERVAL_MS) {\n await fetchAndMerge(true);\n lastPaint = Date.now();\n }\n await sleep(PROGRESS_POLL_INTERVAL_MS);\n }\n if (stopped) return;\n await fetchAndMerge(false);\n ready.value = true;\n }\n\n const enrichInflight = new Set<number>();\n async function enrichOne(id: number) {\n if (enrichInflight.has(id)) return;\n const existing = byIdRef.value.get(id);\n if (existing?._enrichAttempted && existing._meta && existing._stats) return;\n enrichInflight.add(id);\n try {\n const [meta, stats] = await Promise.all([\n safeFetchJson<MetaResponse>(joinUrl(apiBase.value, `/api/strategies/${id}`)),\n safeFetchJson<StatsResponse>(joinUrl(apiBase.value, `/api/strategies/${id}/stats`)),\n ]);\n const m = byIdRef.value;\n const cur = m.get(id) ?? ({ Id: id } as Strategy);\n mergeMetaInto(cur, meta);\n mergeStatsInto(cur, stats);\n cur._enrichAttempted = true;\n if (cur.IsEnabled === false) m.delete(id);\n else m.set(id, cur);\n triggerRef(byIdRef);\n } finally {\n enrichInflight.delete(id);\n }\n }\n\n async function searchExtra(filter: string) {\n if (!filter || !ready.value) return;\n try {\n const items = await api<Strategy[]>(\n `/api/strategies?filter=${encodeURIComponent(filter)}`,\n apiBase.value,\n );\n const m = byIdRef.value;\n const newIds: number[] = [];\n let added = 0;\n for (const it of items) {\n if (!m.has(it.Id)) {\n m.set(it.Id, { ...it, _stats: false, _meta: false });\n newIds.push(it.Id);\n added++;\n }\n }\n if (added) {\n total.value += added;\n triggerRef(byIdRef);\n }\n for (const id of newIds) void enrichOne(id);\n } catch (e) {\n handleError(e);\n }\n }\n\n function start() {\n stopped = false;\n void loadFull();\n }\n function stop() {\n stopped = true;\n }\n async function refresh() {\n stop();\n byIdRef.value = new Map();\n ready.value = false;\n loaded.value = 0;\n total.value = 0;\n builtAt.value = null;\n start();\n }\n\n onScopeDispose(stop);\n\n return {\n catalog,\n ready,\n building,\n loaded,\n total,\n builtAt,\n enrichOne,\n searchExtra,\n refresh,\n start,\n stop,\n };\n}\n\nasync function safeFetchJson<T = unknown>(url: string): Promise<T | null> {\n try {\n const r = await fetch(url);\n if (!r.ok) return null;\n return (await r.json()) as T;\n } catch {\n return null;\n }\n}\n\ninterface MetaResponse {\n Name?: string | null;\n NumCopiers?: number | null;\n Fee?: number | null;\n RiskProfile?: Strategy['RiskProfile'];\n IsSimulated?: boolean;\n IsEnabled?: boolean;\n ImageUploaded?: boolean | null;\n Profile?: Strategy['Profile'];\n}\n\ninterface StatsResponse {\n Inception?: string | null;\n CurrencyCode?: string | null;\n Profitability?: {\n Inception?: {\n UnrealisedReturn?: number | null;\n RealisedReturn?: number | null;\n MaxDrawdown?: number | null;\n RealisedPnl?: number | null;\n UnrealisedPnl?: number | null;\n History?: HistoryPoint[];\n };\n };\n Trades?: {\n Inception?: {\n Total?: number;\n Wins?: number;\n Losses?: number;\n Markets?: { MarketName: string; Count: number }[];\n };\n };\n Status?: { Balance?: number | null };\n CopiersBalance?: { Balance?: number | null };\n CopiersProfit?: { Month?: number | null; Year?: number | null };\n}\n\nfunction mergeMetaInto(cur: Strategy, meta: MetaResponse | null) {\n if (!meta) return;\n cur.Name = meta.Name ?? cur.Name;\n cur.NumCopiers = meta.NumCopiers ?? null;\n cur.Fee = meta.Fee ?? null;\n cur.RiskProfile = meta.RiskProfile ?? null;\n cur.IsSimulated = meta.IsSimulated ?? false;\n if (meta.IsEnabled !== undefined) cur.IsEnabled = meta.IsEnabled;\n if (meta.ImageUploaded !== undefined) cur.ImageUploaded = meta.ImageUploaded;\n cur.Profile = meta.Profile ?? cur.Profile;\n cur._meta = true;\n}\n\nfunction mergeStatsInto(cur: Strategy, stats: StatsResponse | null) {\n if (!stats) return;\n const inc = stats.Profitability?.Inception ?? {};\n const tr = stats.Trades?.Inception ?? {};\n const hist = inc.History ?? [];\n const stride = hist.length > 60 ? Math.ceil(hist.length / 60) : 1;\n const trimmed = hist\n .filter((_, i) => i % stride === 0 || i === hist.length - 1)\n .map((p) => ({ Timestamp: p.Timestamp, AccountReturn: p.AccountReturn }));\n\n cur.Inception = stats.Inception ?? cur.Inception;\n cur.Currency = stats.CurrencyCode || 'USD';\n cur.Return =\n inc.UnrealisedReturn != null\n ? inc.UnrealisedReturn * 100\n : inc.RealisedReturn != null\n ? inc.RealisedReturn * 100\n : null;\n cur.MaxDD = inc.MaxDrawdown != null ? inc.MaxDrawdown * 100 : null;\n cur.RealisedPnl = inc.RealisedPnl ?? null;\n cur.UnrealisedPnl = inc.UnrealisedPnl ?? null;\n cur.History = trimmed;\n cur.TradesTotal = tr.Total ?? 0;\n cur.Wins = tr.Wins ?? 0;\n cur.Losses = tr.Losses ?? 0;\n cur.Markets = Array.isArray(tr.Markets)\n ? tr.Markets.slice(0, 12).map((m) => ({ n: m.MarketName, c: m.Count }))\n : [];\n cur.AccountBalance = stats.Status?.Balance ?? null;\n cur.CopiersAUM = stats.CopiersBalance?.Balance ?? null;\n cur.MonthlyProfit = stats.CopiersProfit?.Month ?? null;\n cur.YearlyProfit = stats.CopiersProfit?.Year ?? null;\n cur._stats = true;\n}\n\nfunction sleep(ms: number) {\n return new Promise((r) => setTimeout(r, ms));\n}\n","import type { RiskLevel } from './strategy';\n\nexport interface FiltersState {\n risk: Set<RiskLevel>;\n retMin: number | null;\n retMax: number | null;\n ddMax: number | null;\n aumMin: number | null;\n copiersMin: number | null;\n ageMin: number | null;\n tradesMin: number | null;\n winrateMin: number | null;\n feeMax: number | null;\n balanceMin: number | null;\n balanceMax: number | null;\n search: string;\n}\n\nexport function defaultFilters(): FiltersState {\n return {\n risk: new Set<RiskLevel>(),\n retMin: null,\n retMax: null,\n ddMax: null,\n aumMin: null,\n copiersMin: null,\n ageMin: null,\n tradesMin: null,\n winrateMin: null,\n feeMax: null,\n balanceMin: null,\n balanceMax: null,\n search: '',\n };\n}\n","import { computed, reactive, type Reactive, type Ref } from 'vue';\nimport type { Strategy } from '../types/strategy';\nimport type { FiltersState } from '../types/filters';\nimport { defaultFilters } from '../types/filters';\nimport { winrate } from '../utils/winrate';\nimport { ageDays } from '../utils/format';\n\nexport interface UseFiltersReturn {\n filters: Reactive<FiltersState>;\n filtered: Ref<Strategy[]>;\n reset(): void;\n}\n\nexport function useFilters(\n source: Ref<Strategy[]>,\n initial: Partial<FiltersState> = {},\n): UseFiltersReturn {\n const base = defaultFilters();\n const filters = reactive<FiltersState>({\n ...base,\n ...initial,\n risk: new Set(initial.risk ?? base.risk),\n });\n\n const filtered = computed<Strategy[]>(() => source.value.filter((s) => passes(s, filters)));\n\n function reset() {\n const fresh = defaultFilters();\n filters.risk = fresh.risk;\n filters.retMin = null;\n filters.retMax = null;\n filters.ddMax = null;\n filters.aumMin = null;\n filters.copiersMin = null;\n filters.ageMin = null;\n filters.tradesMin = null;\n filters.winrateMin = null;\n filters.feeMax = null;\n filters.balanceMin = null;\n filters.balanceMax = null;\n filters.search = '';\n }\n\n return { filters, filtered, reset };\n}\n\nfunction passes(s: Strategy, f: FiltersState): boolean {\n if (f.search) {\n const q = f.search.toLowerCase();\n if (\n !(s.Name || '').toLowerCase().includes(q) &&\n !(s.Profile?.Name || '').toLowerCase().includes(q)\n ) {\n return false;\n }\n }\n if (f.risk.size && s.RiskProfile && !f.risk.has(s.RiskProfile)) return false;\n if (s.IsSimulated) return false;\n if (s._stats && !s.TradesTotal) return false;\n if (f.copiersMin != null && (s.NumCopiers ?? 0) < f.copiersMin) return false;\n if (f.aumMin != null && (s.CopiersAUM ?? 0) < f.aumMin) return false;\n if (f.balanceMin != null && (s.AccountBalance ?? 0) < f.balanceMin) return false;\n if (f.balanceMax != null && (s.AccountBalance ?? Infinity) > f.balanceMax) return false;\n if (f.feeMax != null && s.Fee != null && s.Fee * 100 > f.feeMax) return false;\n if (f.tradesMin != null && (s.TradesTotal ?? 0) < f.tradesMin) return false;\n const wr = winrate(s);\n if (f.winrateMin != null && (wr < 0 || wr < f.winrateMin)) return false;\n const age = ageDays(s.Inception);\n if (f.ageMin != null && (age == null || age < f.ageMin)) return false;\n if (f.retMin != null && (s.Return == null || s.Return < f.retMin)) return false;\n if (f.retMax != null && (s.Return == null || s.Return > f.retMax)) return false;\n if (f.ddMax != null && s.MaxDD != null && Math.abs(s.MaxDD) > f.ddMax) return false;\n return true;\n}\n","import { computed, ref, type Ref } from 'vue';\nimport type { Strategy } from '../types/strategy';\nimport { winrate } from '../utils/winrate';\nimport { ageDays } from '../utils/format';\nimport { SORT_TOGGLE, type SortColumn, type SortKey } from '../constants/sort';\n\ntype Comparator = (a: Strategy, b: Strategy) => number;\n\nconst COMPARATORS: Record<SortKey, Comparator> = {\n 'return-desc': (a, b) => (b.Return ?? -1e18) - (a.Return ?? -1e18),\n 'return-asc': (a, b) => (a.Return ?? 1e18) - (b.Return ?? 1e18),\n 'dd-asc': (a, b) => Math.abs(a.MaxDD ?? 1e9) - Math.abs(b.MaxDD ?? 1e9),\n 'dd-desc': (a, b) => Math.abs(b.MaxDD ?? -1e9) - Math.abs(a.MaxDD ?? -1e9),\n 'aum-desc': (a, b) => (b.CopiersAUM ?? -1) - (a.CopiersAUM ?? -1),\n 'aum-asc': (a, b) => (a.CopiersAUM ?? Infinity) - (b.CopiersAUM ?? Infinity),\n 'copiers-desc': (a, b) => (b.NumCopiers ?? -1) - (a.NumCopiers ?? -1),\n 'copiers-asc': (a, b) => (a.NumCopiers ?? Infinity) - (b.NumCopiers ?? Infinity),\n 'fee-asc': (a, b) => (a.Fee ?? Infinity) - (b.Fee ?? Infinity),\n 'fee-desc': (a, b) => (b.Fee ?? -1) - (a.Fee ?? -1),\n 'age-desc': (a, b) => (ageDays(b.Inception) ?? -1) - (ageDays(a.Inception) ?? -1),\n 'age-asc': (a, b) => (ageDays(a.Inception) ?? Infinity) - (ageDays(b.Inception) ?? Infinity),\n 'balance-desc': (a, b) => (b.AccountBalance ?? -1) - (a.AccountBalance ?? -1),\n 'balance-asc': (a, b) => (a.AccountBalance ?? Infinity) - (b.AccountBalance ?? Infinity),\n 'winrate-desc': (a, b) => winrate(b) - winrate(a),\n 'winrate-asc': (a, b) => winrate(a) - winrate(b),\n 'trades-desc': (a, b) => (b.TradesTotal ?? -1) - (a.TradesTotal ?? -1),\n 'trades-asc': (a, b) => (a.TradesTotal ?? Infinity) - (b.TradesTotal ?? Infinity),\n 'monthly-desc': (a, b) => (b.MonthlyProfit ?? -1e18) - (a.MonthlyProfit ?? -1e18),\n 'monthly-asc': (a, b) => (a.MonthlyProfit ?? 1e18) - (b.MonthlyProfit ?? 1e18),\n};\n\nexport interface UseSortReturn {\n sortKey: Ref<SortKey>;\n sorted: Ref<Strategy[]>;\n toggleColumn(col: SortColumn): void;\n setKey(k: SortKey): void;\n}\n\nexport function useSort(source: Ref<Strategy[]>, initial: SortKey = 'return-desc'): UseSortReturn {\n const sortKey = ref<SortKey>(initial);\n const sorted = computed<Strategy[]>(() => {\n const cmp = COMPARATORS[sortKey.value] ?? (() => 0);\n return source.value.slice().sort(cmp);\n });\n\n function toggleColumn(col: SortColumn) {\n const [primary, secondary] = SORT_TOGGLE[col];\n sortKey.value = sortKey.value === primary ? secondary : primary;\n }\n\n return {\n sortKey,\n sorted,\n toggleColumn,\n setKey: (k: SortKey) => {\n sortKey.value = k;\n },\n };\n}\n","import { computed, ref, watch, type Ref } from 'vue';\n\nexport interface UsePaginationReturn<T> {\n page: Ref<number>;\n totalPages: Ref<number>;\n pageItems: Ref<T[]>;\n pageRange: Ref<(number | '…')[]>;\n setPage(p: number): void;\n next(): void;\n prev(): void;\n}\n\nexport function usePagination<T>(source: Ref<T[]>, pageSize: number): UsePaginationReturn<T> {\n const page = ref(1);\n\n const totalPages = computed(() => Math.max(1, Math.ceil(source.value.length / pageSize)));\n\n watch(totalPages, (tp) => {\n if (page.value > tp) page.value = tp;\n if (page.value < 1) page.value = 1;\n });\n\n const pageItems = computed<T[]>(() => {\n const start = (page.value - 1) * pageSize;\n return source.value.slice(start, start + pageSize);\n });\n\n const pageRange = computed<(number | '…')[]>(() => {\n const cur = page.value;\n const total = totalPages.value;\n if (total <= 1) return [];\n const set = new Set<number>([1, total, cur, cur - 1, cur + 1, cur - 2, cur + 2, 2, total - 1]);\n const arr = [...set].filter((n) => n >= 1 && n <= total).sort((a, b) => a - b);\n const out: (number | '…')[] = [];\n for (let i = 0; i < arr.length; i++) {\n if (i && arr[i] - arr[i - 1] > 1) out.push('…');\n out.push(arr[i]);\n }\n return out;\n });\n\n return {\n page,\n totalPages,\n pageItems,\n pageRange,\n setPage: (p: number) => {\n page.value = Math.max(1, Math.min(totalPages.value, p));\n },\n next: () => {\n if (page.value < totalPages.value) page.value += 1;\n },\n prev: () => {\n if (page.value > 1) page.value -= 1;\n },\n };\n}\n","import { ref, type Ref } from 'vue';\nimport type { SignalKind } from '../types/api';\nimport type { Trade } from '../types/strategy';\nimport { SIGNALS_CLOSED_WINDOW_DAYS } from '../constants/defaults';\nimport { joinUrl, makeError, type PelicanError } from '../utils/http';\n\ninterface SignalsCacheEntry {\n loading: boolean;\n trades: Trade[] | null;\n error: PelicanError | null;\n}\n\nexport interface UseSignalsReturn {\n open: Ref<Map<number, SignalsCacheEntry>>;\n closed: Ref<Map<number, SignalsCacheEntry>>;\n load(strategyId: number, kind: SignalKind): Promise<void>;\n get(strategyId: number, kind: SignalKind): SignalsCacheEntry | null;\n}\n\nexport function useSignals(apiBase: Ref<string>): UseSignalsReturn {\n const open = ref<Map<number, SignalsCacheEntry>>(new Map());\n const closed = ref<Map<number, SignalsCacheEntry>>(new Map());\n\n function get(id: number, kind: SignalKind): SignalsCacheEntry | null {\n return (kind === 'open' ? open.value : closed.value).get(id) ?? null;\n }\n\n async function load(id: number, kind: SignalKind) {\n const store = kind === 'open' ? open : closed;\n const cur = store.value.get(id);\n if (cur && (cur.loading || cur.trades !== null)) return;\n const next = new Map(store.value);\n next.set(id, { loading: true, trades: null, error: null });\n store.value = next;\n\n let qs = '';\n if (kind === 'closed') {\n const end = new Date();\n const start = new Date(Date.now() - SIGNALS_CLOSED_WINDOW_DAYS * 86400_000);\n const fmt = (d: Date) => d.toISOString().replace(/\\.\\d+Z$/, 'Z');\n qs = `?startDate=${encodeURIComponent(fmt(start))}&endDate=${encodeURIComponent(fmt(end))}`;\n }\n const url = joinUrl(apiBase.value, `/api/strategies/${id}/signals/${kind}${qs}`);\n\n let trades: Trade[] = [];\n let error: PelicanError | null = null;\n try {\n const r = await fetch(url);\n if (!r.ok) throw makeError('http_error', `${r.status}`);\n trades = (await r.json()) as Trade[];\n } catch (e) {\n error = (e as PelicanError).code\n ? (e as PelicanError)\n : makeError('fetch_failed', (e as Error).message);\n trades = [];\n }\n\n const final = new Map(store.value);\n final.set(id, { loading: false, trades, error });\n store.value = final;\n }\n\n return { open, closed, load, get };\n}\n","<script setup lang=\"ts\">\nimport { onMounted, provide, reactive, ref, toRef, watch } from 'vue';\nimport Toolbar from './components/Toolbar.vue';\nimport FiltersPanel from './components/FiltersPanel.vue';\nimport StrategyTable from './components/StrategyTable.vue';\nimport ProgressBar from './components/ProgressBar.vue';\nimport { useTheme } from './composables/useTheme';\nimport { useCatalog } from './composables/useCatalog';\nimport { useFilters } from './composables/useFilters';\nimport { useSort } from './composables/useSort';\nimport { usePagination } from './composables/usePagination';\nimport { useSignals } from './composables/useSignals';\nimport { defaultFilters, type FiltersState } from './types/filters';\nimport type { Strategy } from './types/strategy';\nimport type { ThemeMode } from './types/columns';\n// `columns` is reserved for a future column-visibility API; type intentionally re-exported.\nimport type { ColumnKey } from './types/columns';\nimport type { SignalKind } from './types/api';\nimport type { PelicanError } from './utils/http';\nimport type { SortKey, SortColumn } from './constants/sort';\nimport { PAGE_SIZE } from './constants/defaults';\nimport { LOCALE_KEY, API_BASE_KEY, CATALOG_BASE_KEY } from './injection-keys';\nimport './styles/index.css';\n\nconst props = withDefaults(\n defineProps<{\n apiBase: string;\n /**\n * Optional separate origin for the *static* catalog endpoints\n * (`/api/strategies-full` and `/api/strategies-full/progress`). When set,\n * the catalog is fetched from this URL — typically a Cloudflare Worker\n * fronting an R2 bucket — while live per-strategy data continues to go\n * through `apiBase`.\n */\n catalogBase?: string;\n theme?: ThemeMode;\n defaultSort?: SortKey;\n defaultFilters?: Partial<FiltersState>;\n columns?: ColumnKey[]; // reserved; not yet wired through\n locale?: string;\n pageSize?: number;\n }>(),\n {\n theme: 'auto',\n defaultSort: 'return-desc',\n locale: 'en-US',\n pageSize: PAGE_SIZE,\n },\n);\n\nconst emit = defineEmits<{\n (e: 'update:theme', m: ThemeMode): void;\n (e: 'select-strategy', s: Strategy): void;\n (e: 'error', err: PelicanError): void;\n}>();\n\nprovide(API_BASE_KEY, props.apiBase);\nprovide(CATALOG_BASE_KEY, props.catalogBase ?? props.apiBase);\nprovide(LOCALE_KEY, props.locale);\n\nconst apiBaseRef = toRef(props, 'apiBase');\nconst catalogBaseRef = toRef(props, 'catalogBase');\n\nconst themeApi = useTheme(props.theme);\nwatch(themeApi.mode, (m) => emit('update:theme', m));\nwatch(\n () => props.theme,\n (t) => themeApi.setMode(t),\n);\n\nconst catalog = useCatalog({\n apiBase: apiBaseRef,\n catalogBase: catalogBaseRef,\n onError: (e) => emit('error', e),\n});\n\nconst filtersApi = useFilters(catalog.catalog, props.defaultFilters ?? {});\nconst sortApi = useSort(filtersApi.filtered, props.defaultSort);\nconst pagination = usePagination<Strategy>(sortApi.sorted, props.pageSize);\n\nconst signals = useSignals(apiBaseRef);\n\nconst expanded = reactive(new Set<number>());\nconst filtersOpen = ref(false);\nconst investAmount = ref<number | null>(null);\n\nfunction toggleRow(id: number) {\n if (expanded.has(id)) expanded.delete(id);\n else expanded.add(id);\n\n const s = catalog.catalog.value.find((x) => x.Id === id);\n if (s) {\n if ((!s._meta || !s._stats) && !s._enrichAttempted) void catalog.enrichOne(id);\n emit('select-strategy', s);\n }\n}\n\nfunction toggleSort(col: SortColumn) {\n sortApi.toggleColumn(col);\n pagination.setPage(1);\n}\n\nfunction patchFilters(p: Partial<FiltersState>) {\n Object.assign(filtersApi.filters, p);\n pagination.setPage(1);\n}\n\nfunction resetFilters() {\n const fresh = defaultFilters();\n Object.assign(filtersApi.filters, fresh);\n filtersApi.filters.risk = fresh.risk;\n investAmount.value = null;\n pagination.setPage(1);\n}\n\nfunction loadTrades({ id, kind }: { id: number; kind: SignalKind }) {\n void signals.load(id, kind);\n}\n\nfunction onPageGo(target: number | 'prev' | 'next') {\n if (target === 'prev') pagination.prev();\n else if (target === 'next') pagination.next();\n else pagination.setPage(target);\n}\n\nonMounted(() => catalog.start());\n</script>\n\n<template>\n <div class=\"pelican-libsoc\" :data-theme=\"themeApi.resolved.value\">\n <header class=\"brand-row\">\n <slot name=\"brand\">\n <div class=\"default-brand\">Libertex Social — Copy Trading</div>\n </slot>\n <button class=\"theme-toggle\" type=\"button\" :title=\"themeApi.mode.value\" @click=\"themeApi.cycle\">\n <span aria-hidden=\"true\">{{ themeApi.resolved.value === 'dark' ? '🌙' : '☀️' }}</span>\n </button>\n </header>\n\n <Toolbar\n :search=\"filtersApi.filters.search\"\n :sort-key=\"sortApi.sortKey.value\"\n :total=\"catalog.total.value\"\n :filtered-total=\"filtersApi.filtered.value.length\"\n :page=\"pagination.page.value\"\n :total-pages=\"pagination.totalPages.value\"\n @update:search=\"(v) => patchFilters({ search: v })\"\n @update:sort-key=\"(k) => sortApi.setKey(k)\"\n @refresh=\"catalog.refresh\"\n @toggle-filters=\"filtersOpen = !filtersOpen\"\n />\n\n <ProgressBar\n :loaded=\"catalog.loaded.value\"\n :total=\"catalog.total.value\"\n :active=\"catalog.building.value && !catalog.ready.value\"\n />\n\n <main class=\"pelican-main\">\n <FiltersPanel\n :filters=\"filtersApi.filters\"\n :invest-amount=\"investAmount\"\n :open=\"filtersOpen\"\n @update:filters=\"patchFilters\"\n @update:invest-amount=\"(v) => (investAmount = v)\"\n @reset=\"resetFilters\"\n />\n\n <StrategyTable\n :page-items=\"pagination.pageItems.value\"\n :expanded=\"expanded\"\n :sort-key=\"sortApi.sortKey.value\"\n :page=\"pagination.page.value\"\n :total-pages=\"pagination.totalPages.value\"\n :page-range=\"pagination.pageRange.value\"\n :open-signals=\"signals.open.value\"\n :closed-signals=\"signals.closed.value\"\n @toggle-row=\"toggleRow\"\n @toggle-sort=\"toggleSort\"\n @load-trades=\"loadTrades\"\n @select=\"(s) => emit('select-strategy', s)\"\n @go=\"onPageGo\"\n >\n <template #empty>\n <slot name=\"empty\">No matches.</slot>\n </template>\n <template #row-actions=\"slotProps\">\n <slot name=\"row-actions\" v-bind=\"slotProps\" />\n </template>\n </StrategyTable>\n </main>\n </div>\n</template>\n\n<style scoped>\n.brand-row {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 14px 16px;\n background: var(--header-bg);\n border-bottom: 1px solid var(--line);\n}\n.default-brand {\n font-weight: 700;\n color: var(--text);\n}\n.theme-toggle {\n margin-left: auto;\n width: 38px;\n height: 38px;\n border-radius: 8px;\n border: 1px solid var(--line);\n background: transparent;\n color: var(--text);\n cursor: pointer;\n font: inherit;\n font-size: 16px;\n}\n.theme-toggle:hover {\n border-color: var(--orange);\n}\n.pelican-main {\n display: flex;\n flex: 1;\n min-height: 0;\n}\n@media (max-width: 720px) {\n .pelican-main {\n flex-direction: column;\n }\n}\n</style>\n"],"names":["useDebounce","fn","delay","t","wrapped","args","cancel","onScopeDispose","PAGE_SIZE","SEARCH_DEBOUNCE_MS","PROGRESS_POLL_INTERVAL_MS","PARTIAL_REPAINT_INTERVAL_MS","SIGNALS_CLOSED_WINDOW_DAYS","SORT_KEYS","SORT_LABELS","SORT_TOGGLE","props","__props","emit","__emit","local","ref","watch","v","debounced","onSearchInput","e","onSort","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_toDisplayString","_createTextVNode","_hoisted_4","_cache","_Fragment","_renderList","_unref","k","_hoisted_6","LEVELS","toggle","level","next","l","_normalizeClass","$event","anyAt","computed","inverted","raw","display","onInput","_hoisted_3","rawMin","rawMax","lo","hi","loLabel","hiLabel","rangeText","onMin","onMax","_hoisted_5","_a","_hoisted_8","h","fmtPct","d","n","fmtMoney","locale","sign","abs","s","fmtMoneyFull","fmtNum","fmtFee","fmtTradeTime","iso","fmtAge","days","months","years","remMonths","fmtAUM","fmtRetMag","initials","name","p","ageDays","inception","balanceFromRaw","rawFromBalance","b","returnFromRaw","onChange","retRawMin","retRawMax","balRawMin","balRawMax","patch","setRisk","applyInvest","range","_createVNode","RiskChips","InvestAmount","RangeDual","RangeSingle","DONUT_PALETTE","sparklineGeometry","history","w","times","tMin","tMax","tSpan","ys","yMin","yRange","px","py","pts","i","last","zeroY","startX","endX","linePath","areaPath","donutGeometry","items","sorted","a","total","acc","m","cx","cy","R","r","labelR","angle","slices","frac","sweep","a0","a1","aMid","large","x0","y0","x1","y1","xi0","yi0","xi1","yi1","arcPath","color","labelLine","labelX","labelY","labelAnchor","isLeft","lx1","ly1","lx2","ly2","lx3","geom","empty","_vShow","title","_hoisted_7","winrate","wins","losses","API_BASE_KEY","CATALOG_BASE_KEY","LOCALE_KEY","inject","ret","dd","age","wr","lr","profileName","_b","link","showOpen","showClosed","toggleOpen","toggleClosed","_hoisted_9","_hoisted_10","Sparkline","_hoisted_11","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_17","_hoisted_18","_hoisted_19","_hoisted_20","_renderSlot","_ctx","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_25","_hoisted_26","_hoisted_27","_hoisted_28","_hoisted_29","_hoisted_30","_hoisted_31","_hoisted_32","_hoisted_33","_hoisted_34","_hoisted_35","_hoisted_36","_hoisted_37","_hoisted_38","_hoisted_39","_hoisted_40","_hoisted_41","MarketsDonut","_hoisted_42","_createBlock","TradesPanel","_c","_d","go","target","onGoto","SORTABLE","sortClass","col","StrategyRow","kind","_withCtx","slotProps","_mergeProps","Pager","pct","_normalizeStyle","STORAGE_KEY","useTheme","initial","stored","readStored","mode","resolved","mq","apply","onMq","setMode","cycle","makeError","code","message","status","api","path","apiBase","url","joinUrl","base","useCatalog","catalogBase","onError","byIdRef","shallowRef","ready","building","loaded","builtAt","catalog","stopped","handleError","isEdgeCatalog","cb","catalogOrigin","fetchAndMerge","partial","it","triggerRef","pollProgress","loadFull","lastPaint","sleep","enrichInflight","enrichOne","id","existing","meta","stats","safeFetchJson","cur","mergeMetaInto","mergeStatsInto","searchExtra","filter","newIds","added","start","stop","refresh","inc","tr","hist","stride","trimmed","_","_e","_f","ms","defaultFilters","useFilters","source","filters","reactive","filtered","passes","reset","fresh","f","q","COMPARATORS","useSort","sortKey","cmp","toggleColumn","primary","secondary","usePagination","pageSize","page","totalPages","tp","pageItems","pageRange","arr","out","useSignals","open","closed","get","load","store","qs","end","fmt","trades","error","final","provide","apiBaseRef","toRef","catalogBaseRef","themeApi","filtersApi","sortApi","pagination","signals","expanded","filtersOpen","investAmount","toggleRow","x","toggleSort","patchFilters","resetFilters","loadTrades","onPageGo","onMounted","Toolbar","ProgressBar","FiltersPanel","StrategyTable"],"mappings":"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"}
|