@mashkovd/pelican-vue 0.3.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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pelican-libertex-social.umd.cjs","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 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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"}
|
|
1
|
+
{"version":3,"file":"pelican-libertex-social.umd.cjs","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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"}
|