diff --git a/frontend/src/components/StrategyEditorPage.tsx b/frontend/src/components/StrategyEditorPage.tsx
index aac1958..b763c88 100644
--- a/frontend/src/components/StrategyEditorPage.tsx
+++ b/frontend/src/components/StrategyEditorPage.tsx
@@ -91,6 +91,10 @@ import {
type StableStrategyFilterLevel,
type StableStrategyId,
} from '../utils/stableStrategyPairs';
+import {
+ buildIchimokuSituationTree,
+ isIchimokuSituationPaletteValue,
+} from '../utils/ichimokuSituationStrategy';
import {
buildStochOverboughtPairTree,
findStochPairRootInForest,
@@ -1367,7 +1371,8 @@ export default function StrategyEditorPage({
const inflection33 = isInflection33PaletteValue(item.value);
const ichimokuBb = isIchimokuBbPaletteValue(item.value);
const stableStrategy = isStableStrategyPaletteValue(item.value);
- const composite = item.kind === 'composite' && !stochPair && !priceExtremeBreakout && !inflection33 && !ichimokuBb && !stableStrategy;
+ const ichimokuSituation = isIchimokuSituationPaletteValue(item.value);
+ const composite = item.kind === 'composite' && !stochPair && !priceExtremeBreakout && !inflection33 && !ichimokuBb && !stableStrategy && !ichimokuSituation;
const newNode = stochPair
? buildStochOverboughtPairTree(item.secondaryIndicator ?? 'CCI', DEF)
: priceExtremeBreakout
@@ -1378,6 +1383,8 @@ export default function StrategyEditorPage({
? buildIchimokuBbTree(item.value, DEF)
: stableStrategy
? buildStableStrategyTree(item.value, DEF)
+ : ichimokuSituation
+ ? buildIchimokuSituationTree(item.value, DEF)
: makeNode('indicator', item.value, signalTab, DEF, composite ? { composite: true } : undefined);
if (!newNode) return;
handleEditorStateChange(prev => {
diff --git a/frontend/src/components/strategyEditor/FlowNodes.tsx b/frontend/src/components/strategyEditor/FlowNodes.tsx
index 767d3ac..2126c45 100644
--- a/frontend/src/components/strategyEditor/FlowNodes.tsx
+++ b/frontend/src/components/strategyEditor/FlowNodes.tsx
@@ -31,6 +31,11 @@ import {
inferStableStrategyFilterLevel,
type StableStrategyId,
} from '../../utils/stableStrategyPairs';
+import {
+ isIchimokuSituationPairRoot,
+ ichimokuSituationDisplayName,
+ type IchimokuSituationId,
+} from '../../utils/ichimokuSituationStrategy';
import StableStrategyPairNodeSettings from './StableStrategyPairNodeSettings';
import {
isStochOverboughtPairRoot,
@@ -241,12 +246,13 @@ export const LogicGateNode = memo(function LogicGateNode({ id, data, selected }:
const isInflection33Pair = isInflection33PairRoot(node);
const isIchimokuBbPair = isIchimokuBbPairRoot(node);
const isStableStrategyPair = isStableStrategyPairRoot(node);
+ const isIchimokuSituationPair = isIchimokuSituationPairRoot(node);
const { onDragEnter, onDragOver, onDragLeave, onDrop } = usePaletteDropHandlers(id, d);
const [settingsOpen, setSettingsOpen] = useState(false);
return (
)}
+ {isIchimokuSituationPair && node.ichimokuSituationPair && (
+
+
+ {ichimokuSituationDisplayName(
+ node.ichimokuSituationPair.situationId as IchimokuSituationId,
+ node.ichimokuSituationPair.mode,
+ )}
+
+
+ )}
{isInflection33Pair && node.inflection33Pair && (
diff --git a/frontend/src/components/strategyEditor/IndicatorPaletteTab.tsx b/frontend/src/components/strategyEditor/IndicatorPaletteTab.tsx
index af691b7..51f6882 100644
--- a/frontend/src/components/strategyEditor/IndicatorPaletteTab.tsx
+++ b/frontend/src/components/strategyEditor/IndicatorPaletteTab.tsx
@@ -8,6 +8,7 @@ import { isPriceExtremeBreakoutPairPaletteValue } from '../../utils/priceExtreme
import { isInflection33PaletteValue } from '../../utils/inflection33Strategy';
import { isIchimokuBbPaletteValue } from '../../utils/ichimokuBbStrategy';
import { isStableStrategyPaletteValue, STABLE_STRATEGY_PALETTE_ITEMS } from '../../utils/stableStrategyPairs';
+import { isIchimokuSituationPaletteValue } from '../../utils/ichimokuSituationStrategy';
import { getDefaultIndicatorPeriod } from '../../utils/conditionPeriods';
import { getStrategyIndicatorDisplayName } from '../../utils/strategyPaletteStorage';
import { getIndicatorPeriodLabel } from '../../utils/strategyFlowLayout';
@@ -39,6 +40,9 @@ function periodLabel(item: PaletteItem, def: DefType): string {
const meta = STABLE_STRATEGY_PALETTE_ITEMS.find(i => i.value === item.value);
return meta?.periodHint ?? '';
}
+ if (item.kind === 'composite' && isIchimokuSituationPaletteValue(item.value)) {
+ return '9 / 26 / 52';
+ }
if (item.kind === 'composite') {
const d = getCompositeDefaultPeriods(item.value, def);
return `${d.short} / ${d.long}`;
@@ -194,12 +198,14 @@ export default function IndicatorPaletteTab({
&& !isPriceExtremeBreakoutPairPaletteValue(item.value)
&& !isInflection33PaletteValue(item.value)
&& !isIchimokuBbPaletteValue(item.value)
- && !isStableStrategyPaletteValue(item.value)}
+ && !isStableStrategyPaletteValue(item.value)
+ && !isIchimokuSituationPaletteValue(item.value)}
stochPair={isStochOverboughtPairPaletteValue(item.value)}
priceExtremeBreakout={isPriceExtremeBreakoutPairPaletteValue(item.value)}
inflection33={isInflection33PaletteValue(item.value)}
ichimokuBb={isIchimokuBbPaletteValue(item.value)}
stableStrategy={isStableStrategyPaletteValue(item.value)}
+ ichimokuSituation={isIchimokuSituationPaletteValue(item.value)}
secondaryIndicator={item.secondaryIndicator}
period={periodLabel(item, def)}
periodValue={item.period}
diff --git a/frontend/src/components/strategyEditor/PaletteChip.tsx b/frontend/src/components/strategyEditor/PaletteChip.tsx
index a9f97a5..f42076a 100644
--- a/frontend/src/components/strategyEditor/PaletteChip.tsx
+++ b/frontend/src/components/strategyEditor/PaletteChip.tsx
@@ -29,6 +29,7 @@ interface Props {
inflection33?: boolean;
ichimokuBb?: boolean;
stableStrategy?: boolean;
+ ichimokuSituation?: boolean;
secondaryIndicator?: string;
selected?: boolean;
onSelect?: () => void;
@@ -37,7 +38,7 @@ interface Props {
export default function PaletteChip({
type, value, label, desc, color, period, periodValue, shortPeriod, longPeriod,
- composite = false, stochPair = false, priceExtremeBreakout = false, inflection33 = false, ichimokuBb = false, stableStrategy = false, secondaryIndicator, selected = false, onSelect, onAdd,
+ composite = false, stochPair = false, priceExtremeBreakout = false, inflection33 = false, ichimokuBb = false, stableStrategy = false, ichimokuSituation = false, secondaryIndicator, selected = false, onSelect, onAdd,
}: Props) {
const buildPayload = (): PaletteDragPayload => ({
type, value, label,
@@ -47,6 +48,7 @@ export default function PaletteChip({
inflection33: inflection33 || undefined,
ichimokuBb: ichimokuBb || undefined,
stableStrategy: stableStrategy || undefined,
+ ichimokuSituation: ichimokuSituation || undefined,
secondaryIndicator,
period: periodValue,
shortPeriod,
diff --git a/frontend/src/components/strategyEditor/StrategyEditorCanvas.tsx b/frontend/src/components/strategyEditor/StrategyEditorCanvas.tsx
index 07b2b1f..5245aa3 100644
--- a/frontend/src/components/strategyEditor/StrategyEditorCanvas.tsx
+++ b/frontend/src/components/strategyEditor/StrategyEditorCanvas.tsx
@@ -794,6 +794,9 @@ function StrategyEditorCanvasInner({
: n.stableStrategyPair?.mode === 'sell'
? (gateType === 'OR' ? n.stableStrategyPair : undefined)
: undefined,
+ ichimokuSituationPair: n.ichimokuSituationPair
+ ? n.ichimokuSituationPair
+ : undefined,
}
: n
);
diff --git a/frontend/src/hooks/useStrategyEvaluationEditor.ts b/frontend/src/hooks/useStrategyEvaluationEditor.ts
index ec6b080..9a6c4b0 100644
--- a/frontend/src/hooks/useStrategyEvaluationEditor.ts
+++ b/frontend/src/hooks/useStrategyEvaluationEditor.ts
@@ -51,6 +51,10 @@ import {
buildStableStrategyTree,
isStableStrategyPaletteValue,
} from '../utils/stableStrategyPairs';
+import {
+ buildIchimokuSituationTree,
+ isIchimokuSituationPaletteValue,
+} from '../utils/ichimokuSituationStrategy';
import {
buildSidewaysFilterNode,
loadSidewaysPaletteItems,
@@ -453,7 +457,8 @@ export function useStrategyEvaluationEditor({
const inflection33 = isInflection33PaletteValue(item.value);
const ichimokuBb = isIchimokuBbPaletteValue(item.value);
const stableStrategy = isStableStrategyPaletteValue(item.value);
- const composite = item.kind === 'composite' && !stochPair && !priceExtremeBreakout && !inflection33 && !ichimokuBb && !stableStrategy;
+ const ichimokuSituation = isIchimokuSituationPaletteValue(item.value);
+ const composite = item.kind === 'composite' && !stochPair && !priceExtremeBreakout && !inflection33 && !ichimokuBb && !stableStrategy && !ichimokuSituation;
const newNode = stochPair
? buildStochOverboughtPairTree(item.secondaryIndicator ?? 'CCI', def)
: priceExtremeBreakout
@@ -464,6 +469,8 @@ export function useStrategyEvaluationEditor({
? buildIchimokuBbTree(item.value, def)
: stableStrategy
? buildStableStrategyTree(item.value, def)
+ : ichimokuSituation
+ ? buildIchimokuSituationTree(item.value, def)
: makeNode('indicator', item.value, signalTab, def, composite ? { composite: true } : undefined);
if (!newNode) return;
handleEditorStateChange(prev => {
diff --git a/frontend/src/utils/ichimokuSituationStrategy.ts b/frontend/src/utils/ichimokuSituationStrategy.ts
new file mode 100644
index 0000000..b3d7cfc
--- /dev/null
+++ b/frontend/src/utils/ichimokuSituationStrategy.ts
@@ -0,0 +1,358 @@
+/**
+ * 일목균형표 상황별·엘리어트 파동 복합 전략
+ * @see 일목균형표 전략.md
+ */
+import type { ConditionDSL, LogicNode } from './strategyTypes';
+import { initConditionPeriodsInherit, type IndicatorPeriodDef } from './conditionPeriods';
+import { genId } from './strategyNodeIds';
+
+export type IchimokuSituationCategory = 'basic' | 'alignment' | 'elliott';
+
+export type IchimokuSituationId =
+ | 'GOLDEN_CROSS'
+ | 'BASE_BREAKUP'
+ | 'CLOUD_BREAKUP'
+ | 'LAGGING_BULL'
+ | 'CLOUD_SUPPORT'
+ | 'DEAD_CROSS'
+ | 'BASE_BREAKDOWN'
+ | 'CLOUD_BREAKDOWN'
+ | 'LAGGING_BEAR'
+ | 'CLOUD_RESISTANCE'
+ | 'SANYAKU_REVERSE'
+ | 'HOJEON'
+ | 'GYEOKJEON'
+ | 'EW1'
+ | 'EW2'
+ | 'EW3'
+ | 'EW4'
+ | 'EW5'
+ | 'EW_A'
+ | 'EW_B'
+ | 'EW_C';
+
+const SITUATION_PREFIX = 'ICHIMOKU_SIT_';
+
+export function ichimokuSituationPaletteValue(id: IchimokuSituationId, mode: 'buy' | 'sell'): string {
+ return `${SITUATION_PREFIX}${id}_${mode.toUpperCase()}`;
+}
+
+export interface IchimokuSituationPaletteMeta {
+ value: string;
+ label: string;
+ desc: string;
+ situationId: IchimokuSituationId;
+ mode: 'buy' | 'sell';
+ category: IchimokuSituationCategory;
+}
+
+export const ICHIMOKU_SITUATION_PALETTE_ITEMS: IchimokuSituationPaletteMeta[] = [
+ // §2.1 기본 매수
+ { value: ichimokuSituationPaletteValue('GOLDEN_CROSS', 'buy'), label: '일목 골든크로스 매수', situationId: 'GOLDEN_CROSS', mode: 'buy', category: 'basic',
+ desc: 'L1 — 전환선이 기준선 상향 돌파 (호전 1차)' },
+ { value: ichimokuSituationPaletteValue('BASE_BREAKUP', 'buy'), label: '일목 기준선 돌파 매수', situationId: 'BASE_BREAKUP', mode: 'buy', category: 'basic',
+ desc: 'L2 — 종가가 기준선 상향 돌파 (중기 추세 전환)' },
+ { value: ichimokuSituationPaletteValue('CLOUD_BREAKUP', 'buy'), label: '일목 구름 돌파 매수', situationId: 'CLOUD_BREAKUP', mode: 'buy', category: 'basic',
+ desc: 'L3 — 구름대 상향 돌파 (매물·심리 저항 돌파)' },
+ { value: ichimokuSituationPaletteValue('LAGGING_BULL', 'buy'), label: '일목 후행 호전 매수', situationId: 'LAGGING_BULL', mode: 'buy', category: 'basic',
+ desc: 'L4 — 후행스팬 > 26봉 전 종가 (추세 확정)' },
+ { value: ichimokuSituationPaletteValue('CLOUD_SUPPORT', 'buy'), label: '일목 구름 지지 매수', situationId: 'CLOUD_SUPPORT', mode: 'buy', category: 'basic',
+ desc: 'L5 — 종가 > 선행1·기준선 (양운·기준선 지지 반등)' },
+ // §1.3 호전
+ { value: ichimokuSituationPaletteValue('HOJEON', 'buy'), label: '일목 호전(정배열) 매수', situationId: 'HOJEON', mode: 'buy', category: 'alignment',
+ desc: '괘·구름 위·양운·후행 — 완벽한 상승 추세 4조건' },
+ // §2.2 기본 매도
+ { value: ichimokuSituationPaletteValue('DEAD_CROSS', 'sell'), label: '일목 데드크로스 매도', situationId: 'DEAD_CROSS', mode: 'sell', category: 'basic',
+ desc: 'S1 — 전환선이 기준선 하향 이탈' },
+ { value: ichimokuSituationPaletteValue('BASE_BREAKDOWN', 'sell'), label: '일목 기준선 이탈 매도', situationId: 'BASE_BREAKDOWN', mode: 'sell', category: 'basic',
+ desc: 'S2 — 종가가 기준선 하향 이탈' },
+ { value: ichimokuSituationPaletteValue('CLOUD_BREAKDOWN', 'sell'), label: '일목 구름 이탈 매도', situationId: 'CLOUD_BREAKDOWN', mode: 'sell', category: 'basic',
+ desc: 'S3 — 구름대 하향 이탈 (지지 붕괴)' },
+ { value: ichimokuSituationPaletteValue('LAGGING_BEAR', 'sell'), label: '일목 후행 역전 매도', situationId: 'LAGGING_BEAR', mode: 'sell', category: 'basic',
+ desc: 'S4 — 후행스팬 < 26봉 전 종가' },
+ { value: ichimokuSituationPaletteValue('CLOUD_RESISTANCE', 'sell'), label: '일목 구름 저항 매도', situationId: 'CLOUD_RESISTANCE', mode: 'sell', category: 'basic',
+ desc: 'S5 — 종가 < 선행1·기준선 (음운·기준선 저항)' },
+ { value: ichimokuSituationPaletteValue('SANYAKU_REVERSE', 'sell'), label: '일목 삼역역전 매도', situationId: 'SANYAKU_REVERSE', mode: 'sell', category: 'alignment',
+ desc: 'S6 — 데드 + 구름 아래 + 후행 역전 (강력 청산)' },
+ { value: ichimokuSituationPaletteValue('GYEOKJEON', 'sell'), label: '일목 역전(역배열) 매도', situationId: 'GYEOKJEON', mode: 'sell', category: 'alignment',
+ desc: '괘·구름 아래·음운·후행 — 완벽한 하락 추세 4조건' },
+ // §4 엘리어트 파동
+ { value: ichimokuSituationPaletteValue('EW1', 'buy'), label: '일목 1파 매수', situationId: 'EW1', mode: 'buy', category: 'elliott',
+ desc: '추세 전환 시동 — 기준선 돌파 + 전환>기준 (소액·분할)' },
+ { value: ichimokuSituationPaletteValue('EW2', 'buy'), label: '일목 2파 매수', situationId: 'EW2', mode: 'buy', category: 'elliott',
+ desc: '눌림목 — 기준선·구름하단(선행2) 지지 + 전환>기준' },
+ { value: ichimokuSituationPaletteValue('EW2', 'sell'), label: '일목 2파 손절', situationId: 'EW2', mode: 'sell', category: 'elliott',
+ desc: '2파 지지 이탈 — 기준선 이탈 OR 구름 하향 돌파' },
+ { value: ichimokuSituationPaletteValue('EW3', 'buy'), label: '일목 3파 매수', situationId: 'EW3', mode: 'buy', category: 'elliott',
+ desc: '본격 상승 — 삼역호전(괘·구름·후행·양운) 불타기' },
+ { value: ichimokuSituationPaletteValue('EW4', 'buy'), label: '일목 4파 재매수', situationId: 'EW4', mode: 'buy', category: 'elliott',
+ desc: '횡보 조정 — 구름 상단(선행1)·기준선 지지 반등' },
+ { value: ichimokuSituationPaletteValue('EW4', 'sell'), label: '일목 4파 익절', situationId: 'EW4', mode: 'sell', category: 'elliott',
+ desc: '4파 조정 — 기준선 이탈 OR 구름 하향 이탈' },
+ { value: ichimokuSituationPaletteValue('EW5', 'sell'), label: '일목 5파 분할매도', situationId: 'EW5', mode: 'sell', category: 'elliott',
+ desc: '과열 — 전환선·데드·구름 이탈 (분할 청산)' },
+ { value: ichimokuSituationPaletteValue('EW_A', 'sell'), label: '일목 A파 매도', situationId: 'EW_A', mode: 'sell', category: 'elliott',
+ desc: '하락 개시 — 기준선·데드크로스' },
+ { value: ichimokuSituationPaletteValue('EW_B', 'sell'), label: '일목 B파 매도', situationId: 'EW_B', mode: 'sell', category: 'elliott',
+ desc: '기술적 반등 실패 — 기준선·음운 저항 (전량 대피)' },
+ { value: ichimokuSituationPaletteValue('EW_C', 'sell'), label: '일목 C파 매도', situationId: 'EW_C', mode: 'sell', category: 'elliott',
+ desc: '본 하락 — 삼역역전 + 구름 이탈 (물타기 금지)' },
+];
+
+const VALUE_TO_META: Record =
+ Object.fromEntries(ICHIMOKU_SITUATION_PALETTE_ITEMS.map(i => [i.value, { situationId: i.situationId, mode: i.mode }]));
+
+export function isIchimokuSituationPaletteValue(value: string): boolean {
+ return value.startsWith(SITUATION_PREFIX) && value in VALUE_TO_META;
+}
+
+export function isIchimokuSituationPairRoot(node: LogicNode): boolean {
+ return !!node.ichimokuSituationPair?.situationId
+ && (node.type === 'AND' || node.type === 'OR');
+}
+
+function makeIch(
+ def: IndicatorPeriodDef,
+ conditionType: string,
+ leftField: string,
+ rightField: string,
+ extra?: Partial,
+): LogicNode {
+ const base: ConditionDSL = {
+ indicatorType: 'ICHIMOKU',
+ conditionType,
+ leftField,
+ rightField,
+ candleRange: 1,
+ valuePeriodOverride: false,
+ thresholdOverride: false,
+ rightPeriodOverride: false,
+ ...extra,
+ };
+ return {
+ id: genId(),
+ type: 'CONDITION',
+ condition: initConditionPeriodsInherit('ICHIMOKU', base, def),
+ };
+}
+
+function pairMeta(
+ situationId: IchimokuSituationId,
+ mode: 'buy' | 'sell',
+): LogicNode['ichimokuSituationPair'] {
+ return { situationId, mode };
+}
+
+function wrapAnd(children: LogicNode[], meta: LogicNode['ichimokuSituationPair']): LogicNode {
+ return { id: genId(), type: 'AND', ichimokuSituationPair: meta, children };
+}
+
+function wrapOr(children: LogicNode[], meta: LogicNode['ichimokuSituationPair']): LogicNode {
+ return { id: genId(), type: 'OR', ichimokuSituationPair: meta, children };
+}
+
+type Builder = (def: IndicatorPeriodDef) => LogicNode;
+
+const BUILDERS: Record>> = {
+ GOLDEN_CROSS: {
+ buy: def => wrapAnd([
+ makeIch(def, 'CROSS_UP', 'CONVERSION_LINE', 'BASE_LINE'),
+ ], pairMeta('GOLDEN_CROSS', 'buy')),
+ },
+ BASE_BREAKUP: {
+ buy: def => wrapAnd([
+ makeIch(def, 'CROSS_UP', 'CLOSE_PRICE', 'BASE_LINE'),
+ ], pairMeta('BASE_BREAKUP', 'buy')),
+ },
+ CLOUD_BREAKUP: {
+ buy: def => wrapAnd([
+ makeIch(def, 'CLOUD_BREAK_UP', 'CLOSE_PRICE', 'NONE'),
+ ], pairMeta('CLOUD_BREAKUP', 'buy')),
+ },
+ LAGGING_BULL: {
+ buy: def => wrapAnd([
+ makeIch(def, 'LAGGING_GT_PRICE', 'LAGGING_SPAN', 'CLOSE_PRICE'),
+ ], pairMeta('LAGGING_BULL', 'buy')),
+ },
+ CLOUD_SUPPORT: {
+ buy: def => wrapAnd([
+ makeIch(def, 'GT', 'CLOSE_PRICE', 'LEADING_SPAN1'),
+ makeIch(def, 'GT', 'CLOSE_PRICE', 'BASE_LINE'),
+ ], pairMeta('CLOUD_SUPPORT', 'buy')),
+ },
+ HOJEON: {
+ buy: def => wrapAnd([
+ makeIch(def, 'GT', 'CONVERSION_LINE', 'BASE_LINE'),
+ makeIch(def, 'ABOVE_CLOUD', 'CLOSE_PRICE', 'NONE'),
+ makeIch(def, 'SPAN1_GT_SPAN2', 'LEADING_SPAN1', 'LEADING_SPAN2'),
+ makeIch(def, 'LAGGING_GT_PRICE', 'LAGGING_SPAN', 'CLOSE_PRICE'),
+ ], pairMeta('HOJEON', 'buy')),
+ },
+ DEAD_CROSS: {
+ sell: def => wrapOr([
+ makeIch(def, 'CROSS_DOWN', 'CONVERSION_LINE', 'BASE_LINE'),
+ ], pairMeta('DEAD_CROSS', 'sell')),
+ },
+ BASE_BREAKDOWN: {
+ sell: def => wrapOr([
+ makeIch(def, 'CROSS_DOWN', 'CLOSE_PRICE', 'BASE_LINE'),
+ ], pairMeta('BASE_BREAKDOWN', 'sell')),
+ },
+ CLOUD_BREAKDOWN: {
+ sell: def => wrapOr([
+ makeIch(def, 'CLOUD_BREAK_DOWN', 'CLOSE_PRICE', 'NONE'),
+ ], pairMeta('CLOUD_BREAKDOWN', 'sell')),
+ },
+ LAGGING_BEAR: {
+ sell: def => wrapOr([
+ makeIch(def, 'LAGGING_LT_PRICE', 'LAGGING_SPAN', 'CLOSE_PRICE'),
+ ], pairMeta('LAGGING_BEAR', 'sell')),
+ },
+ CLOUD_RESISTANCE: {
+ sell: def => wrapAnd([
+ makeIch(def, 'LT', 'CLOSE_PRICE', 'LEADING_SPAN1'),
+ makeIch(def, 'LT', 'CLOSE_PRICE', 'BASE_LINE'),
+ ], pairMeta('CLOUD_RESISTANCE', 'sell')),
+ },
+ SANYAKU_REVERSE: {
+ sell: def => wrapAnd([
+ makeIch(def, 'LT', 'CONVERSION_LINE', 'BASE_LINE'),
+ makeIch(def, 'BELOW_CLOUD', 'CLOSE_PRICE', 'NONE'),
+ makeIch(def, 'LAGGING_LT_PRICE', 'LAGGING_SPAN', 'CLOSE_PRICE'),
+ ], pairMeta('SANYAKU_REVERSE', 'sell')),
+ },
+ GYEOKJEON: {
+ sell: def => wrapAnd([
+ makeIch(def, 'LT', 'CONVERSION_LINE', 'BASE_LINE'),
+ makeIch(def, 'BELOW_CLOUD', 'CLOSE_PRICE', 'NONE'),
+ makeIch(def, 'SPAN1_LT_SPAN2', 'LEADING_SPAN1', 'LEADING_SPAN2'),
+ makeIch(def, 'LAGGING_LT_PRICE', 'LAGGING_SPAN', 'CLOSE_PRICE'),
+ ], pairMeta('GYEOKJEON', 'sell')),
+ },
+ EW1: {
+ buy: def => wrapAnd([
+ makeIch(def, 'CROSS_UP', 'CLOSE_PRICE', 'BASE_LINE'),
+ makeIch(def, 'GT', 'CONVERSION_LINE', 'BASE_LINE'),
+ ], pairMeta('EW1', 'buy')),
+ },
+ EW2: {
+ buy: def => wrapAnd([
+ makeIch(def, 'GT', 'CLOSE_PRICE', 'BASE_LINE'),
+ makeIch(def, 'GT', 'CLOSE_PRICE', 'LEADING_SPAN2'),
+ makeIch(def, 'GT', 'CONVERSION_LINE', 'BASE_LINE'),
+ ], pairMeta('EW2', 'buy')),
+ sell: def => wrapOr([
+ makeIch(def, 'CROSS_DOWN', 'CLOSE_PRICE', 'BASE_LINE'),
+ makeIch(def, 'CLOUD_BREAK_DOWN', 'CLOSE_PRICE', 'NONE'),
+ ], pairMeta('EW2', 'sell')),
+ },
+ EW3: {
+ buy: def => wrapAnd([
+ makeIch(def, 'GT', 'CONVERSION_LINE', 'BASE_LINE'),
+ makeIch(def, 'ABOVE_CLOUD', 'CLOSE_PRICE', 'NONE'),
+ makeIch(def, 'LAGGING_GT_PRICE', 'LAGGING_SPAN', 'CLOSE_PRICE'),
+ makeIch(def, 'SPAN1_GT_SPAN2', 'LEADING_SPAN1', 'LEADING_SPAN2'),
+ ], pairMeta('EW3', 'buy')),
+ },
+ EW4: {
+ buy: def => wrapAnd([
+ makeIch(def, 'GT', 'CLOSE_PRICE', 'LEADING_SPAN1'),
+ makeIch(def, 'GT', 'CONVERSION_LINE', 'BASE_LINE'),
+ ], pairMeta('EW4', 'buy')),
+ sell: def => wrapOr([
+ makeIch(def, 'CROSS_DOWN', 'CLOSE_PRICE', 'BASE_LINE'),
+ makeIch(def, 'CLOUD_BREAK_DOWN', 'CLOSE_PRICE', 'NONE'),
+ ], pairMeta('EW4', 'sell')),
+ },
+ EW5: {
+ sell: def => wrapOr([
+ makeIch(def, 'CROSS_DOWN', 'CLOSE_PRICE', 'CONVERSION_LINE'),
+ makeIch(def, 'CROSS_DOWN', 'CONVERSION_LINE', 'BASE_LINE'),
+ makeIch(def, 'CLOUD_BREAK_DOWN', 'CLOSE_PRICE', 'NONE'),
+ ], pairMeta('EW5', 'sell')),
+ },
+ EW_A: {
+ sell: def => wrapOr([
+ makeIch(def, 'CROSS_DOWN', 'CLOSE_PRICE', 'BASE_LINE'),
+ makeIch(def, 'CROSS_DOWN', 'CONVERSION_LINE', 'BASE_LINE'),
+ ], pairMeta('EW_A', 'sell')),
+ },
+ EW_B: {
+ sell: def => wrapAnd([
+ makeIch(def, 'LT', 'CLOSE_PRICE', 'BASE_LINE'),
+ makeIch(def, 'BELOW_CLOUD', 'CLOSE_PRICE', 'NONE'),
+ makeIch(def, 'LT', 'CONVERSION_LINE', 'BASE_LINE'),
+ ], pairMeta('EW_B', 'sell')),
+ },
+ EW_C: {
+ sell: def => wrapAnd([
+ makeIch(def, 'CLOUD_BREAK_DOWN', 'CLOSE_PRICE', 'NONE'),
+ makeIch(def, 'BELOW_CLOUD', 'CLOSE_PRICE', 'NONE'),
+ makeIch(def, 'LT', 'CONVERSION_LINE', 'BASE_LINE'),
+ makeIch(def, 'LAGGING_LT_PRICE', 'LAGGING_SPAN', 'CLOSE_PRICE'),
+ ], pairMeta('EW_C', 'sell')),
+ },
+};
+
+export function ichimokuSituationMetaFromValue(value: string): { situationId: IchimokuSituationId; mode: 'buy' | 'sell' } | null {
+ return VALUE_TO_META[value] ?? null;
+}
+
+export function buildIchimokuSituationTree(value: string, def: IndicatorPeriodDef): LogicNode | null {
+ const meta = ichimokuSituationMetaFromValue(value);
+ if (!meta) return null;
+ const builder = BUILDERS[meta.situationId][meta.mode];
+ return builder ? builder(def) : null;
+}
+
+export function ichimokuSituationDisplayName(situationId: IchimokuSituationId, mode: 'buy' | 'sell'): string {
+ const item = ICHIMOKU_SITUATION_PALETTE_ITEMS.find(
+ i => i.situationId === situationId && i.mode === mode,
+ );
+ return item?.label ?? `${situationId} ${mode === 'buy' ? '매수' : '매도'}`;
+}
+
+export function ichimokuSituationPaletteDesc(value: string): string {
+ return ICHIMOKU_SITUATION_PALETTE_ITEMS.find(i => i.value === value)?.desc ?? '';
+}
+
+const COND_LABEL: Record = {
+ CROSS_UP: '상향돌파', CROSS_DOWN: '하향돌파',
+ GT: '>', LT: '<',
+ ABOVE_CLOUD: '구름 위', BELOW_CLOUD: '구름 아래',
+ CLOUD_BREAK_UP: '구름 상향돌파', CLOUD_BREAK_DOWN: '구름 하향이탈',
+ SPAN1_GT_SPAN2: '양운', SPAN1_LT_SPAN2: '음운',
+ LAGGING_GT_PRICE: '후행>26봉전 종가', LAGGING_LT_PRICE: '후행<26봉전 종가',
+};
+
+function fmtNode(n: LogicNode): string {
+ if (n.type === 'CONDITION' && n.condition) {
+ const c = n.condition;
+ const op = COND_LABEL[c.conditionType] ?? c.conditionType;
+ return `${c.leftField} ${op} ${c.rightField ?? ''}`.trim();
+ }
+ if (n.type === 'AND' || n.type === 'OR') {
+ return (n.children ?? []).map(fmtNode).join(` ${n.type} `);
+ }
+ return '';
+}
+
+export function ichimokuSituationSummaryText(
+ situationId: IchimokuSituationId,
+ mode: 'buy' | 'sell',
+ def: IndicatorPeriodDef = {
+ rsiPeriod: 14, cciPeriod: 20, adxPeriod: 14, williamsR: 14,
+ trixPeriod: 12, vrPeriod: 26, psyPeriod: 12, newPsy: 12, investPsy: 12,
+ },
+): string {
+ const tree = BUILDERS[situationId][mode]?.(def);
+ return tree ? fmtNode(tree) : '';
+}
+
+export function ichimokuSituationCategoryLabel(cat: IchimokuSituationCategory): string {
+ switch (cat) {
+ case 'basic': return '기본';
+ case 'alignment': return '호전·역전';
+ case 'elliott': return '엘리어트';
+ }
+}
diff --git a/frontend/src/utils/strategyEditorShared.tsx b/frontend/src/utils/strategyEditorShared.tsx
index 00ebe74..09b636a 100644
--- a/frontend/src/utils/strategyEditorShared.tsx
+++ b/frontend/src/utils/strategyEditorShared.tsx
@@ -63,6 +63,14 @@ import {
stableStrategyFilterLevelLabel,
type StableStrategyId,
} from '../utils/stableStrategyPairs';
+import {
+ buildIchimokuSituationTree,
+ isIchimokuSituationPairRoot,
+ isIchimokuSituationPaletteValue,
+ ichimokuSituationDisplayName,
+ ichimokuSituationSummaryText,
+ type IchimokuSituationId,
+} from '../utils/ichimokuSituationStrategy';
import {
buildPriceExtremeBreakoutTree,
isPriceExtremeBreakoutPairPaletteValue,
@@ -1015,6 +1023,10 @@ export const nodeToText = (node: LogicNode, DEF: DefType = DEF_DEFAULTS): string
const cfg = inferIchimokuBbConfig(node);
return `${ichimokuBbDisplayName(cfg.mode, cfg.chikouDisplacement)}\n${ichimokuBbSummaryText(cfg)}`;
}
+ if (isIchimokuSituationPairRoot(node) && node.ichimokuSituationPair) {
+ const { situationId, mode } = node.ichimokuSituationPair;
+ return `${ichimokuSituationDisplayName(situationId as IchimokuSituationId, mode)}\n${ichimokuSituationSummaryText(situationId as IchimokuSituationId, mode, DEF)}`;
+ }
if (isPriceExtremeBreakoutPairRoot(node) && node.priceExtremePair) {
const { mode, shortPeriod, longPeriod } = node.priceExtremePair;
const level = inferPriceExtremeFilterLevel(node);
@@ -1038,6 +1050,10 @@ export const nodeToText = (node: LogicNode, DEF: DefType = DEF_DEFAULTS): string
const cfg = inferIchimokuBbConfig(node);
return `${ichimokuBbDisplayName(cfg.mode, cfg.chikouDisplacement)}\n${ichimokuBbSummaryText(cfg)}`;
}
+ if (isIchimokuSituationPairRoot(node) && node.ichimokuSituationPair) {
+ const { situationId, mode } = node.ichimokuSituationPair;
+ return `${ichimokuSituationDisplayName(situationId as IchimokuSituationId, mode)}\n${ichimokuSituationSummaryText(situationId as IchimokuSituationId, mode, DEF)}`;
+ }
if (isStochOverboughtPairRoot(node)) {
const sec = node.stochPair!.secondaryIndicatorType;
return `${stochPairDisplayName(sec)}\n${stochPairSummaryText(sec)}`;
@@ -1565,6 +1581,8 @@ export type MakeNodeOptions = {
ichimokuBb?: boolean;
/** 추천 안정형 전략 복합 */
stableStrategy?: boolean;
+ /** 일목균형표 상황별·엘리어트 복합 */
+ ichimokuSituation?: boolean;
};
/** 팔레트 드래그 payload → makeNode 옵션 */
@@ -1575,6 +1593,7 @@ export function makeNodeOptionsFromPalette(data: {
inflection33?: boolean;
ichimokuBb?: boolean;
stableStrategy?: boolean;
+ ichimokuSituation?: boolean;
secondaryIndicator?: string;
period?: number;
shortPeriod?: number;
@@ -1601,6 +1620,9 @@ export function makeNodeOptionsFromPalette(data: {
if (data.stableStrategy || (data.value && isStableStrategyPaletteValue(data.value))) {
return { stableStrategy: true };
}
+ if (data.ichimokuSituation || (data.value && isIchimokuSituationPaletteValue(data.value))) {
+ return { ichimokuSituation: true };
+ }
if (data.composite) {
return {
composite: true,
@@ -1638,6 +1660,10 @@ export const makeNode = (
const tree = buildStableStrategyTree(value, DEF);
if (tree) return tree;
}
+ if (options?.ichimokuSituation || isIchimokuSituationPaletteValue(value)) {
+ const tree = buildIchimokuSituationTree(value, DEF);
+ if (tree) return tree;
+ }
if (options?.composite) {
let condition = makeCompositeCondition(value, signalType, DEF);
condition = {
diff --git a/frontend/src/utils/strategyEditorTemplatePaletteRows.ts b/frontend/src/utils/strategyEditorTemplatePaletteRows.ts
index e2c7a2d..3de8728 100644
--- a/frontend/src/utils/strategyEditorTemplatePaletteRows.ts
+++ b/frontend/src/utils/strategyEditorTemplatePaletteRows.ts
@@ -12,6 +12,7 @@ import {
isNewLow920SellPaletteValue,
} from './priceExtremeBreakoutPair';
import { STABLE_STRATEGY_PALETTE_ITEMS } from './stableStrategyPairs';
+import { ichimokuSituationMetaFromValue } from './ichimokuSituationStrategy';
export type TemplatePaletteSource =
| 'user'
@@ -50,6 +51,8 @@ export function inferCompositePaletteSignal(item: PaletteItem): 'buy' | 'sell' {
}
const stable = STABLE_STRATEGY_PALETTE_ITEMS.find(s => s.value === item.value);
if (stable) return stable.mode;
+ const ichimokuSit = ichimokuSituationMetaFromValue(item.value);
+ if (ichimokuSit) return ichimokuSit.mode;
if (item.value.endsWith('_BUY')) return 'buy';
if (item.value.endsWith('_SELL')) return 'sell';
return 'buy';
diff --git a/frontend/src/utils/strategyEvaluationTemplateApply.ts b/frontend/src/utils/strategyEvaluationTemplateApply.ts
index 4074f28..5bcc9bf 100644
--- a/frontend/src/utils/strategyEvaluationTemplateApply.ts
+++ b/frontend/src/utils/strategyEvaluationTemplateApply.ts
@@ -26,6 +26,10 @@ import {
buildStableStrategyTree,
isStableStrategyPaletteValue,
} from './stableStrategyPairs';
+import {
+ buildIchimokuSituationTree,
+ isIchimokuSituationPaletteValue,
+} from './ichimokuSituationStrategy';
import {
buildSidewaysFilterNode,
loadSidewaysPaletteItems,
@@ -71,18 +75,21 @@ function buildLogicNodeFromPaletteItem(
const inflection33 = isInflection33PaletteValue(item.value);
const ichimokuBb = isIchimokuBbPaletteValue(item.value);
const stableStrategy = isStableStrategyPaletteValue(item.value);
+ const ichimokuSituation = isIchimokuSituationPaletteValue(item.value);
const composite = item.kind === 'composite'
&& !stochPair
&& !priceExtremeBreakout
&& !inflection33
&& !ichimokuBb
- && !stableStrategy;
+ && !stableStrategy
+ && !ichimokuSituation;
if (stochPair) return buildStochOverboughtPairTree(item.secondaryIndicator ?? 'CCI', def);
if (priceExtremeBreakout) return buildPriceExtremeBreakoutTree(item.value, def);
if (inflection33) return buildInflection33Tree(item.value, def);
if (ichimokuBb) return buildIchimokuBbTree(item.value, def);
if (stableStrategy) return buildStableStrategyTree(item.value, def);
+ if (ichimokuSituation) return buildIchimokuSituationTree(item.value, def);
return makeNode('indicator', item.value, signalTab, def, composite ? { composite: true } : undefined);
}
diff --git a/frontend/src/utils/strategyPaletteStorage.ts b/frontend/src/utils/strategyPaletteStorage.ts
index 0547c12..004c3b3 100644
--- a/frontend/src/utils/strategyPaletteStorage.ts
+++ b/frontend/src/utils/strategyPaletteStorage.ts
@@ -18,6 +18,9 @@ import {
import {
STABLE_STRATEGY_PALETTE_ITEMS,
} from './stableStrategyPairs';
+import {
+ ICHIMOKU_SITUATION_PALETTE_ITEMS,
+} from './ichimokuSituationStrategy';
import {
NEW_HIGH_9_20_BUY_VALUE,
NEW_LOW_9_20_SELL_VALUE,
@@ -125,6 +128,12 @@ export const DEFAULT_COMPOSITE_ITEMS: Omit[] = [
builtIn: true,
period: 26,
},
+ ...ICHIMOKU_SITUATION_PALETTE_ITEMS.map(i => ({
+ value: i.value,
+ label: i.label,
+ desc: `[${i.category === 'basic' ? '기본' : i.category === 'alignment' ? '호전·역전' : '엘리어트'}] ${i.desc}`,
+ builtIn: true,
+ })),
...STABLE_STRATEGY_PALETTE_ITEMS.map(i => ({
value: i.value,
label: i.label,
diff --git a/frontend/src/utils/strategyTypes.ts b/frontend/src/utils/strategyTypes.ts
index b6baec6..70e7016 100644
--- a/frontend/src/utils/strategyTypes.ts
+++ b/frontend/src/utils/strategyTypes.ts
@@ -80,6 +80,11 @@ export interface LogicNode {
bbBand: 'UPPER_BAND' | 'MIDDLE_BAND' | 'LOWER_BAND';
conditionType: 'CROSS_UP' | 'CROSS_DOWN' | 'GT' | 'LT';
};
+ /** 일목균형표 상황별·엘리어트 파동 복합 — @see 일목균형표 전략.md */
+ ichimokuSituationPair?: {
+ situationId: string;
+ mode: 'buy' | 'sell';
+ };
}
export interface StrategyDSLDto {
diff --git a/visible-ars/package-lock.json b/visible-ars/package-lock.json
new file mode 100644
index 0000000..fb1b87f
--- /dev/null
+++ b/visible-ars/package-lock.json
@@ -0,0 +1,2680 @@
+{
+ "name": "visible-ars",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "visible-ars",
+ "version": "1.0.0",
+ "dependencies": {
+ "lucide-react": "^0.468.0",
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
+ "react-router-dom": "^6.28.0"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-react": "^4.3.1",
+ "autoprefixer": "^10.4.20",
+ "postcss": "^8.4.49",
+ "tailwindcss": "^3.4.15",
+ "vite": "^5.4.0"
+ }
+ },
+ "node_modules/@alloc/quick-lru": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
+ "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",
+ "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.29.7",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz",
+ "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz",
+ "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.7",
+ "@babel/generator": "^7.29.7",
+ "@babel/helper-compilation-targets": "^7.29.7",
+ "@babel/helper-module-transforms": "^7.29.7",
+ "@babel/helpers": "^7.29.7",
+ "@babel/parser": "^7.29.7",
+ "@babel/template": "^7.29.7",
+ "@babel/traverse": "^7.29.7",
+ "@babel/types": "^7.29.7",
+ "@jridgewell/remapping": "^2.3.5",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz",
+ "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.7",
+ "@babel/types": "^7.29.7",
+ "@jridgewell/gen-mapping": "^0.3.12",
+ "@jridgewell/trace-mapping": "^0.3.28",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz",
+ "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.29.7",
+ "@babel/helper-validator-option": "^7.29.7",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-globals": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz",
+ "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz",
+ "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.29.7",
+ "@babel/types": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz",
+ "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.29.7",
+ "@babel/helper-validator-identifier": "^7.29.7",
+ "@babel/traverse": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz",
+ "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
+ "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
+ "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz",
+ "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz",
+ "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.29.7",
+ "@babel/types": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz",
+ "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.29.7"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-self": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz",
+ "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-source": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz",
+ "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz",
+ "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.7",
+ "@babel/parser": "^7.29.7",
+ "@babel/types": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz",
+ "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.7",
+ "@babel/generator": "^7.29.7",
+ "@babel/helper-globals": "^7.29.7",
+ "@babel/parser": "^7.29.7",
+ "@babel/template": "^7.29.7",
+ "@babel/types": "^7.29.7",
+ "debug": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz",
+ "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.29.7",
+ "@babel/helper-validator-identifier": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+ "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+ "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+ "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+ "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+ "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+ "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+ "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+ "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+ "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+ "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+ "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+ "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+ "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+ "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+ "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+ "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+ "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+ "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+ "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/remapping": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@remix-run/router": {
+ "version": "1.23.3",
+ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.3.tgz",
+ "integrity": "sha512-4An71tdz9X8+3sI4Qqqd2LWd9vS39J7sqd9EU4Scw7TJE/qB10Flv/UuqbPVgfQV9XoK8Np6jNquZitnZq5i+Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@rolldown/pluginutils": {
+ "version": "1.0.0-beta.27",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz",
+ "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.2.tgz",
+ "integrity": "sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.2.tgz",
+ "integrity": "sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.2.tgz",
+ "integrity": "sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.2.tgz",
+ "integrity": "sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.2.tgz",
+ "integrity": "sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.2.tgz",
+ "integrity": "sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.2.tgz",
+ "integrity": "sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.2.tgz",
+ "integrity": "sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.2.tgz",
+ "integrity": "sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.2.tgz",
+ "integrity": "sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.2.tgz",
+ "integrity": "sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-musl": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.2.tgz",
+ "integrity": "sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.2.tgz",
+ "integrity": "sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-musl": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.2.tgz",
+ "integrity": "sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.2.tgz",
+ "integrity": "sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.2.tgz",
+ "integrity": "sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.2.tgz",
+ "integrity": "sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.2.tgz",
+ "integrity": "sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.2.tgz",
+ "integrity": "sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-openbsd-x64": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.2.tgz",
+ "integrity": "sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.2.tgz",
+ "integrity": "sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.2.tgz",
+ "integrity": "sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.2.tgz",
+ "integrity": "sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.2.tgz",
+ "integrity": "sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.2.tgz",
+ "integrity": "sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@types/babel__core": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
+ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "node_modules/@types/babel__generator": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
+ "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__template": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
+ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__traverse": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
+ "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.28.2"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",
+ "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@vitejs/plugin-react": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz",
+ "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.28.0",
+ "@babel/plugin-transform-react-jsx-self": "^7.27.1",
+ "@babel/plugin-transform-react-jsx-source": "^7.27.1",
+ "@rolldown/pluginutils": "1.0.0-beta.27",
+ "@types/babel__core": "^7.20.5",
+ "react-refresh": "^0.17.0"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
+ }
+ },
+ "node_modules/any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/arg": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
+ "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/autoprefixer": {
+ "version": "10.5.1",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.1.tgz",
+ "integrity": "sha512-jwM2pcTuCWUoN70FEvf5XrXyDbUgRURK4FnU8v0jWZZYU/KkVvN9T33mu1sVLFY9JW3kTWzKheEpn6xYLRc/VA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/autoprefixer"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.28.4",
+ "caniuse-lite": "^1.0.30001799",
+ "fraction.js": "^5.3.4",
+ "picocolors": "^1.1.1",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "bin": {
+ "autoprefixer": "bin/autoprefixer"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.10.38",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.38.tgz",
+ "integrity": "sha512-31/02mVB4yuQU6adKk5SlY6m+mxDwUq5KZkyYgnLrrKl7TEm1+3PyDtDBz2kOv/wxZz41GHsvV1A/u6RmiyBvw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.cjs"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.28.4",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.4.tgz",
+ "integrity": "sha512-MTc8i/x9jBQd1iMw2CFGS+rwMa07eYjLR0CCTLDACl9xhxy+nIs3KeML/biicXtk9JrZ6dnnTatmc7ErPXIxqw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "baseline-browser-mapping": "^2.10.38",
+ "caniuse-lite": "^1.0.30001799",
+ "electron-to-chromium": "^1.5.376",
+ "node-releases": "^2.0.48",
+ "update-browserslist-db": "^1.2.3"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/camelcase-css": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
+ "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001799",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz",
+ "integrity": "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chokidar/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/didyoumean": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
+ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/dlv": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
+ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.378",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.378.tgz",
+ "integrity": "sha512-VinvOAuuPmdD1guEgGv5f2Qp7/vlfqOrUOMYNnOD4wj3pit8kRsQHzfIf6teyUGWo15Tg5+bOJaRunvyltpVWQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
+ "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.21.5",
+ "@esbuild/android-arm": "0.21.5",
+ "@esbuild/android-arm64": "0.21.5",
+ "@esbuild/android-x64": "0.21.5",
+ "@esbuild/darwin-arm64": "0.21.5",
+ "@esbuild/darwin-x64": "0.21.5",
+ "@esbuild/freebsd-arm64": "0.21.5",
+ "@esbuild/freebsd-x64": "0.21.5",
+ "@esbuild/linux-arm": "0.21.5",
+ "@esbuild/linux-arm64": "0.21.5",
+ "@esbuild/linux-ia32": "0.21.5",
+ "@esbuild/linux-loong64": "0.21.5",
+ "@esbuild/linux-mips64el": "0.21.5",
+ "@esbuild/linux-ppc64": "0.21.5",
+ "@esbuild/linux-riscv64": "0.21.5",
+ "@esbuild/linux-s390x": "0.21.5",
+ "@esbuild/linux-x64": "0.21.5",
+ "@esbuild/netbsd-x64": "0.21.5",
+ "@esbuild/openbsd-x64": "0.21.5",
+ "@esbuild/sunos-x64": "0.21.5",
+ "@esbuild/win32-arm64": "0.21.5",
+ "@esbuild/win32-ia32": "0.21.5",
+ "@esbuild/win32-x64": "0.21.5"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fastq": {
+ "version": "1.20.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
+ "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/fraction.js": {
+ "version": "5.3.4",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz",
+ "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/rawify"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
+ "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.2",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz",
+ "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/jiti": {
+ "version": "1.21.7",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
+ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jiti": "bin/jiti.js"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "license": "MIT"
+ },
+ "node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/lilconfig": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
+ "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antonk52"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/lucide-react": {
+ "version": "0.468.0",
+ "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.468.0.tgz",
+ "integrity": "sha512-6koYRhnM2N0GGZIdXzSeiNwguv1gt/FAjZOiPl76roBi3xKEXa4WmfpxgQwTTL4KipXjefrnf3oV4IsYhi4JFA==",
+ "license": "ISC",
+ "peerDependencies": {
+ "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc"
+ }
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/mz": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "any-promise": "^1.0.0",
+ "object-assign": "^4.0.1",
+ "thenify-all": "^1.0.0"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.15",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz",
+ "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.49",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.49.tgz",
+ "integrity": "sha512-f06bl1D+8ZDkn2oOQQKAh5/otFWqVnM1Q5oerA8Pex7UfT66Tx4IPHIqVVFKqFT3FUtaDstdgkM7yT7JWhqxfw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-hash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
+ "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
+ "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pirates": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz",
+ "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.15",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz",
+ "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.12",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-import": {
+ "version": "15.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
+ "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.0.0",
+ "read-cache": "^1.0.0",
+ "resolve": "^1.1.7"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.0.0"
+ }
+ },
+ "node_modules/postcss-js": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz",
+ "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "camelcase-css": "^2.0.1"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >= 16"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4.21"
+ }
+ },
+ "node_modules/postcss-load-config": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz",
+ "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "lilconfig": "^3.1.1"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "peerDependencies": {
+ "jiti": ">=1.21.0",
+ "postcss": ">=8.0.9",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ },
+ "postcss": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/postcss-nested": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
+ "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "postcss-selector-parser": "^6.1.1"
+ },
+ "engines": {
+ "node": ">=12.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.14"
+ }
+ },
+ "node_modules/postcss-selector-parser": {
+ "version": "6.1.4",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.4.tgz",
+ "integrity": "sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-value-parser": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/react": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
+ "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
+ "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.2"
+ },
+ "peerDependencies": {
+ "react": "^18.3.1"
+ }
+ },
+ "node_modules/react-refresh": {
+ "version": "0.17.0",
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
+ "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-router": {
+ "version": "6.30.4",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.4.tgz",
+ "integrity": "sha512-SVUsDe+DybHM/WmYKIVYhZh1o5Dcuf16yM6WjG02Q9XVFMZIJyHYhwrr6bFBXZkVP6z69kNkMyBCujt8FaFLJA==",
+ "license": "MIT",
+ "dependencies": {
+ "@remix-run/router": "1.23.3"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8"
+ }
+ },
+ "node_modules/react-router-dom": {
+ "version": "6.30.4",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.4.tgz",
+ "integrity": "sha512-q4HvNl+mmDdkS0g+MqiBZNteQJCuimWoOyHMy4T/RQLAn9Z29+E91QXRaxOujeMl2HTzRSS0KFPd7lxX3PjV0Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@remix-run/router": "1.23.3",
+ "react-router": "6.30.4"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8",
+ "react-dom": ">=16.8"
+ }
+ },
+ "node_modules/read-cache": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
+ "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pify": "^2.3.0"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.12",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz",
+ "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "is-core-module": "^2.16.1",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.62.2",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz",
+ "integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.9"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.62.2",
+ "@rollup/rollup-android-arm64": "4.62.2",
+ "@rollup/rollup-darwin-arm64": "4.62.2",
+ "@rollup/rollup-darwin-x64": "4.62.2",
+ "@rollup/rollup-freebsd-arm64": "4.62.2",
+ "@rollup/rollup-freebsd-x64": "4.62.2",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.62.2",
+ "@rollup/rollup-linux-arm-musleabihf": "4.62.2",
+ "@rollup/rollup-linux-arm64-gnu": "4.62.2",
+ "@rollup/rollup-linux-arm64-musl": "4.62.2",
+ "@rollup/rollup-linux-loong64-gnu": "4.62.2",
+ "@rollup/rollup-linux-loong64-musl": "4.62.2",
+ "@rollup/rollup-linux-ppc64-gnu": "4.62.2",
+ "@rollup/rollup-linux-ppc64-musl": "4.62.2",
+ "@rollup/rollup-linux-riscv64-gnu": "4.62.2",
+ "@rollup/rollup-linux-riscv64-musl": "4.62.2",
+ "@rollup/rollup-linux-s390x-gnu": "4.62.2",
+ "@rollup/rollup-linux-x64-gnu": "4.62.2",
+ "@rollup/rollup-linux-x64-musl": "4.62.2",
+ "@rollup/rollup-openbsd-x64": "4.62.2",
+ "@rollup/rollup-openharmony-arm64": "4.62.2",
+ "@rollup/rollup-win32-arm64-msvc": "4.62.2",
+ "@rollup/rollup-win32-ia32-msvc": "4.62.2",
+ "@rollup/rollup-win32-x64-gnu": "4.62.2",
+ "@rollup/rollup-win32-x64-msvc": "4.62.2",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/scheduler": {
+ "version": "0.23.2",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
+ "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/sucrase": {
+ "version": "3.35.1",
+ "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz",
+ "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "commander": "^4.0.0",
+ "lines-and-columns": "^1.1.6",
+ "mz": "^2.7.0",
+ "pirates": "^4.0.1",
+ "tinyglobby": "^0.2.11",
+ "ts-interface-checker": "^0.1.9"
+ },
+ "bin": {
+ "sucrase": "bin/sucrase",
+ "sucrase-node": "bin/sucrase-node"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/tailwindcss": {
+ "version": "3.4.19",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz",
+ "integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@alloc/quick-lru": "^5.2.0",
+ "arg": "^5.0.2",
+ "chokidar": "^3.6.0",
+ "didyoumean": "^1.2.2",
+ "dlv": "^1.1.3",
+ "fast-glob": "^3.3.2",
+ "glob-parent": "^6.0.2",
+ "is-glob": "^4.0.3",
+ "jiti": "^1.21.7",
+ "lilconfig": "^3.1.3",
+ "micromatch": "^4.0.8",
+ "normalize-path": "^3.0.0",
+ "object-hash": "^3.0.0",
+ "picocolors": "^1.1.1",
+ "postcss": "^8.4.47",
+ "postcss-import": "^15.1.0",
+ "postcss-js": "^4.0.1",
+ "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0",
+ "postcss-nested": "^6.2.0",
+ "postcss-selector-parser": "^6.1.2",
+ "resolve": "^1.22.8",
+ "sucrase": "^3.35.0"
+ },
+ "bin": {
+ "tailwind": "lib/cli.js",
+ "tailwindcss": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/thenify": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
+ "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "any-promise": "^1.0.0"
+ }
+ },
+ "node_modules/thenify-all": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+ "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "thenify": ">= 3.1.0 < 4"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.17",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
+ "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/tinyglobby/node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tinyglobby/node_modules/picomatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/ts-interface-checker": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
+ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
+ "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/vite": {
+ "version": "5.4.21",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz",
+ "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.21.3",
+ "postcss": "^8.4.43",
+ "rollup": "^4.20.0"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || >=20.0.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true,
+ "license": "ISC"
+ }
+ }
+}
diff --git a/visible-ars/tailwind.config.js b/visible-ars/tailwind.config.js
new file mode 100644
index 0000000..67ba788
--- /dev/null
+++ b/visible-ars/tailwind.config.js
@@ -0,0 +1,56 @@
+/** @type {import('tailwindcss').Config} */
+export default {
+ content: ['./index.html', './src/**/*.{js,jsx}'],
+ darkMode: 'class',
+ theme: {
+ extend: {
+ colors: {
+ trust: {
+ DEFAULT: '#0047AB',
+ 50: '#E8F0FA',
+ 100: '#C5D9F2',
+ 600: '#0047AB',
+ 700: '#003A8C',
+ 800: '#002D6D',
+ },
+ safety: {
+ DEFAULT: '#28A745',
+ 50: '#E8F5EC',
+ 600: '#28A745',
+ 700: '#1E7E34',
+ },
+ emergency: {
+ red: '#DC3545',
+ orange: '#FD7E14',
+ },
+ },
+ fontFamily: {
+ sans: ['Pretendard', '-apple-system', 'BlinkMacSystemFont', 'system-ui', 'sans-serif'],
+ },
+ boxShadow: {
+ card: '0 2px 12px rgba(0, 71, 171, 0.08)',
+ 'card-dark': '0 2px 16px rgba(0, 0, 0, 0.35)',
+ },
+ animation: {
+ 'fade-in': 'fadeIn 0.35s ease-out',
+ 'slide-up': 'slideUp 0.35s ease-out',
+ wave: 'wave 1.2s ease-in-out infinite',
+ },
+ keyframes: {
+ fadeIn: {
+ '0%': { opacity: '0' },
+ '100%': { opacity: '1' },
+ },
+ slideUp: {
+ '0%': { opacity: '0', transform: 'translateY(12px)' },
+ '100%': { opacity: '1', transform: 'translateY(0)' },
+ },
+ wave: {
+ '0%, 100%': { transform: 'scaleY(0.4)' },
+ '50%': { transform: 'scaleY(1)' },
+ },
+ },
+ },
+ },
+ plugins: [],
+};
diff --git a/일목균형표 전략.md b/일목균형표 전략.md
new file mode 100644
index 0000000..45f9695
--- /dev/null
+++ b/일목균형표 전략.md
@@ -0,0 +1,397 @@
+# 일목균형표(Ichimoku Kinko Hyo) 전략 — 구성 요소·매매 로직·엘리어트 파동 연계
+
+goldenChart **투자전략 DSL**의 `ICHIMOKU` 지표 조건과 연동하여, 일목균형표의 시간·가격 균형 관계와 엘리어트 파동(Elliott Wave) 단계별 전략 조건을 정리한 문서입니다.
+
+> **관련 문서:** [매매전략조건.md](./매매전략조건.md) · [전략편집기 로직 및 동작흐름.md](./전략편집기%20로직%20및%20동작흐름.md)
+> **내장 템플릿:** `ICHIMOKU_TREND` · `ICHIMOKU_SANYAKU`(삼역호전) · `ICHIMOKU_PERFECT`(5원소)
+
+---
+
+## 1. 일목균형표란
+
+일목균형표는 **과거·현재·미래**의 가격 균형을 한 차트(일목)에 담은 추세·지지·저항 통합 지표입니다.
+단순 이동평균 교차가 아니라, **선행(구름)·후행(26봉 지연)** 개념으로 시장의 “시간적 균형”을 읽습니다.
+
+### 1.1 핵심 구성 요소
+
+| 구성 요소 | DSL 필드 | 계산 (표준 9·26·52) | 시장에서의 역할 |
+|-----------|----------|---------------------|-----------------|
+| **전환선** (Conversion Line) | `CONVERSION_LINE` | (9봉 최고+최저) ÷ 2 | 단기 균형점. 주가의 **단기 방향·속도** |
+| **기준선** (Base Line) | `BASE_LINE` | (26봉 최고+최저) ÷ 2 | 중기 균형점. **추세 그 자체**, 강한 지지·저항 |
+| **선행스팬 1** (Leading Span 1) | `LEADING_SPAN1` | (전환선+기준선) ÷ 2, **26봉 선행** | 단·중기 평균을 미래로 투영 → **구름 상·하단** |
+| **선행스팬 2** (Leading Span 2) | `LEADING_SPAN2` | (52봉 최고+최저) ÷ 2, **26봉 선행** | 장기 균형점 → **구름 두께**·매물대 강도 |
+| **구름대** (Kumo / Cloud) | `LEADING_SPAN1` ↔ `LEADING_SPAN2` | 선행1·2 사이 영역 | 지지(양운) / 저항(음운) **매물·심리 경계** |
+| **후행스팬** (Lagging Span) | `LAGGING_SPAN` | 현재 종가를 **26봉 후행** 표시 | 현재 vs 26봉 전 종가 비교 → **추세 확정** |
+
+### 1.2 구성 요소 간 관계 (개념도)
+
+```text
+ [미래] ← 선행스팬1·2 (26봉 앞)
+ ╱╲ 구름대 (Kumo)
+ ╱ ╲
+ 전환선 ────●────●────●──── (9봉, 가장 민감)
+ 기준선 ────────●────●──── (26봉, 추세의 중심)
+ 종가 ──────────●──────── (현재)
+ 후행 ────────────────●── (종가를 26봉 뒤에 표시)
+ [과거]
+```
+
+| 관계 | 의미 | 해석 |
+|------|------|------|
+| 전환선 ↔ 기준선 | 단기 vs 중기 균형 | 교차 = **추세 전환 1차 신호** |
+| 선행1 vs 선행2 | 구름 색·두께 | 선행1>선행2 → **양운**(상승 구름), 반대 → **음운** |
+| 종가 vs 구름 | 현재가 위치 | 구름 위 = 강세, 아래 = 약세, 내부 = **전환·횡보** |
+| 후행 vs 26봉 전 종가 | 시간 지연 확인 | 후행이 과거 종가 위 = **상승 추세 확정** |
+
+### 1.3 호전(정배열) vs 역전(역배열)
+
+#### 🟩 호전 — 완벽한 상승 추세
+
+```text
+종가 > 전환선 > 기준선 > 구름(양운)
+후행스팬 > 26봉 전 종가
+(선택) 후행스팬 > 26봉 전 구름
+```
+
+| 확인 항목 | DSL 조건 예시 |
+|-----------|---------------|
+| 괘(가격선) | `CONVERSION_LINE GT BASE_LINE` |
+| 주가·구름 | `CLOSE_PRICE ABOVE_CLOUD` |
+| 구름 성격 | `SPAN1_GT_SPAN2` (양운) |
+| 후행 확정 | `LAGGING_GT_PRICE` |
+
+#### 🟥 역전 — 완벽한 하락 추세
+
+```text
+종가 < 전환선 < 기준선 < 구름(음운)
+후행스팬 < 26봉 전 종가
+```
+
+| 확인 항목 | DSL 조건 예시 |
+|-----------|---------------|
+| 괘 | `CONVERSION_LINE LT BASE_LINE` |
+| 주가·구름 | `CLOSE_PRICE BELOW_CLOUD` |
+| 구름 성격 | `SPAN1_LT_SPAN2` (음운) |
+| 후행 확정 | `LAGGING_LT_PRICE` |
+
+---
+
+## 2. 상황별 기본 매수·매도 판단 로직
+
+### 2.1 매수(Long) 타이밍
+
+| # | 상황 | 판단 근거 | DSL 조건 (예) | 강도 |
+|---|------|-----------|---------------|------|
+| L1 | **골든크로스(호전)** | 전환선이 기준선 상향 돌파 | `CONVERSION_LINE CROSS_UP BASE_LINE` | ★★★ |
+| L2 | **기준선 돌파** | 중기 추세 전환 | `CLOSE_PRICE CROSS_UP BASE_LINE` | ★★★ |
+| L3 | **구름 돌파** | 매물대·심리 저항 돌파 | `CLOUD_BREAK_UP` | ★★★★ |
+| L4 | **후행 호전** | 26봉 전 대비 추세 확정 | `LAGGING_GT_PRICE` (또는 `CROSS_UP`) | ★★★★ |
+| L5 | **구름 지지** | 양운 상단·기준선에서 반등 | `CLOSE_PRICE GT LEADING_SPAN1` + `GT BASE_LINE` | ★★ |
+| L6 | **삼역호전** | ①괘 ②구름 ③후행 동시 | 아래 §3.3 참조 | ★★★★★ |
+
+**매수 시 주의**
+
+- 구름 **내부**(`IN_CLOUD`)에서는 신호 빈도↑·신뢰도↓ → 필터(거래량·ADX) 권장.
+- `CROSS_*` 조건은 **해당 봉 1회**만 true → 연속 보유는 `GT`/`ABOVE_CLOUD` 등 **상태 조건** 병행.
+
+### 2.2 매도(Short / 청산) 타이밍
+
+| # | 상황 | 판단 근거 | DSL 조건 (예) | 강도 |
+|---|------|-----------|---------------|------|
+| S1 | **데드크로스(역전)** | 전환선 기준선 하향 이탈 | `CONVERSION_LINE CROSS_DOWN BASE_LINE` | ★★★ |
+| S2 | **기준선 이탈** | 중기 추세 붕괴 | `CLOSE_PRICE CROSS_DOWN BASE_LINE` | ★★★ |
+| S3 | **구름 이탈** | 지지 붕괴 | `CLOUD_BREAK_DOWN` | ★★★★ |
+| S4 | **후행 역전** | 하락 추세 확정 | `LAGGING_LT_PRICE` | ★★★★ |
+| S5 | **구름 저항** | 음운 하단·기준선에서 반락 | `CLOSE_PRICE LT LEADING_SPAN1` + `LT BASE_LINE` | ★★ |
+| S6 | **삼역역전** | ①데드 ②구름하 ③후행하 | §3.3 역방향 | ★★★★★ |
+
+**매도(청산) 설계 팁**
+
+- 추세 추종: `OR(데드크로스, 종가<전환선, 구름하향돌파)` — **연속 매도 방지**.
+- 익절: 5파·과열 구간에서는 전환선 이탈만으로도 1차 청산 신호로 사용.
+
+### 2.3 구름·선행스팬 해석 요약
+
+| 구름 상태 | 선행1 vs 선행2 | 종가 위치 | 일반적 해석 |
+|-----------|----------------|-----------|-------------|
+| **양운** | 선행1 > 선행2 | 종가 > 구름 | 상승 추세, 구름 = **지지** |
+| **음운** | 선행1 < 선행2 | 종가 < 구름 | 하락 추세, 구름 = **저항** |
+| **얇은 구름** | 두 선행 간격 좁음 | 돌파 직후 | 변곡·추세 전환 **임박** |
+| **두꺼운 구름** | 두 선행 간격 넓음 | 구름 안·근처 | **강한 매물대**, 돌파 난이도↑ |
+
+---
+
+## 3. 삼역호전 / 삼역역전 — 핵심 복합 신호
+
+### 3.1 삼역호전 (三役好轉) — 강력 매수
+
+| 역(役) | 일목 요소 | 조건 |
+|--------|-----------|------|
+| **괘** | 전환·기준 | 전환선 > 기준선 (또는 골든크로스) |
+| **주가** | 종가·구름 | 종가 > 구름 (`ABOVE_CLOUD` / `CLOUD_BREAK_UP`) |
+| **후행** | 후행·과거 종가 | 후행 > 26봉 전 종가 (`LAGGING_GT_PRICE`) |
+
+**goldenChart 템플릿:** `ICHIMOKU_SANYAKU` — 구름 돌파(현재 봉) + 단계별 필터(N봉 EXISTS_IN).
+
+### 3.2 삼역역전 — 강력 매도·대피
+
+| 역 | 조건 |
+|----|------|
+| 괘 | 전환선 < 기준선 (데드크로스) |
+| 주가 | 종가 < 구름 (`BELOW_CLOUD` / `CLOUD_BREAK_DOWN`) |
+| 후행 | 후행 < 26봉 전 종가 (`LAGGING_LT_PRICE`) |
+
+### 3.3 5원소 입체 매매 (Perfect Ichimoku)
+
+괘 · 주가 · 구름(양/음운) · 후행 **4중 AND** — ta4j `PerfectIchimokuStrategy` 동형.
+
+**goldenChart 템플릿:** `ICHIMOKU_PERFECT` (필터 강도에 따라 2~4조건).
+
+---
+
+## 4. 엘리어트 파동 × 일목균형표 — 단계별 전략 조건
+
+엘리어트 파동의 **추세 전개**와 일목의 **선행·후행 시간 구조**를 결합하면, 파동 단계별 진입·청산 근거를 명확히 할 수 있습니다.
+
+> **전제:** 아래 “파동”은 **추정**이며, 실전에서는 상위·하위 시간대 일목을 함께 봅니다.
+> 조건은 goldenChart DSL로 표현 가능한 형태로 기술합니다.
+
+---
+
+### 4.1 1파 — 상승 시동 (추세 전환 시작)
+
+| 항목 | 내용 |
+|------|------|
+| **파동 특징** | 장기 하락 종료 후 첫 반등. 바닥 예측 난이도 **최고** |
+| **일목 상태** | 하락하던 전환·기준선을 **순차 돌파** 시작. 위에는 **두터운 음운**이 여전히 존재 |
+| **관계** | 종가 ≈ 전환선 근처, 기준선 **미돌파 또는 돌파 직후**, 구름 **아래·내부** |
+
+**전략 조건**
+
+| 구분 | 조건 | DSL 예시 |
+|------|------|----------|
+| 공격적 매수 | 기준선 상향 돌파 | `CLOSE_PRICE CROSS_UP BASE_LINE` |
+| 보조 확인 | 전환 > 기준 | `CONVERSION_LINE GT BASE_LINE` |
+| 필터(권장) | 아직 구름 아래면 **소액·분할** | `NOT ABOVE_CLOUD` → 포지션 축소 |
+| 매도/관망 | 음운 하단 저항 | `CLOSE_PRICE LT LEADING_SPAN2` 유지 시 추가 매수 자제 |
+
+**판단:** 삼역호전 **미충족** → `ICHIMOKU_TREND`(골든크로스) 수준만 허용, `SANYAKU`/`PERFECT`는 **대기**.
+
+---
+
+### 4.2 2파 — 첫 번째 조정 (눌림목)
+
+| 항목 | 내용 |
+|------|------|
+| **파동 특징** | 1파 되돌림(종종 50~61.8%). **마지막 저가 테스트** |
+| **일목 상태** | 주가 재하락하나 **선행2(구름 하단)·과거 바닥** 미이탈. 전환·기준 **수평 방어** |
+| **관계** | 종가 > 기준선 또는 구름 하단(선행2) **지지** |
+
+**전략 조건**
+
+| 구분 | 조건 | DSL 예시 |
+|------|------|----------|
+| **1차 적극 매수** | 기준선·구름 하단 지지 후 반등 | `CLOSE_PRICE GT BASE_LINE` AND `CLOSE_PRICE GT LEADING_SPAN2` |
+| 확인 | 전환 > 기준 유지 | `CONVERSION_LINE GT BASE_LINE` |
+| 손절 | 기준선·선행2 동시 이탈 | `CLOSE_PRICE CROSS_DOWN BASE_LINE` OR `CLOUD_BREAK_DOWN` |
+| 금지 | 후행 아직 미호전 | `LAGGING_LT_PRICE` 지속 시 **풀매수 금지** |
+
+**판단:** **2파 끝 = 기준선/양운 상단 지지** → 3파 전 **핵심 분할 매수 구간**.
+
+---
+
+### 4.3 3파 — 본격 상승 (핵심 수익 구간)
+
+| 항목 | 내용 |
+|------|------|
+| **파동 특징** | 거래량·길이 **최대**. 추세 추종 수익 **극대화** 구간 |
+| **일목 상태** | **삼역호전 완성**. 얇은 구름 돌파 → 앞선 **두터운 양운** |
+| **관계** | 종가 > 전환 > 기준 > 구름, 후행 > 26봉 전 종가·구름 |
+
+**전략 조건 (삼역호전 = 3파 확인)**
+
+```text
+AND(
+ CONVERSION_LINE GT BASE_LINE, /* 괘 */
+ CLOSE_PRICE ABOVE_CLOUD, /* 주가 — 또는 CLOUD_BREAK_UP */
+ LAGGING_GT_PRICE, /* 후행 */
+ SPAN1_GT_SPAN2 /* 양운 (선택) */
+)
+```
+
+| 구분 | 전략 |
+|------|------|
+| **매수** | 삼역호전 충족 시 **추가 매수·불타기** (`ICHIMOKU_SANYAKU` / `PERFECT`) |
+| **보유** | 종가 > **전환선** 유지 → **매도 금지** (추세 타기) |
+| **청산 경고** | 전환선 이탈 **전**까지 보유 극대화 |
+| **손절** | `CLOUD_BREAK_DOWN` 또는 `CONVERSION_LINE CROSS_DOWN BASE_LINE` |
+
+**판단:** �lliott **3파 ≈ 일목 삼역호전** — 시스템상 **가장 신뢰도 높은 롱 구간**.
+
+---
+
+### 4.4 4파 — 조정 (복잡한 횡보)
+
+| 항목 | 내용 |
+|------|------|
+| **파동 특징** | 삼각형·횡보. 변동성↑, 방향성 혼란 |
+| **일목 상태** | 급등 후 **기준선 지지 테스트**. 일시 **구름 내부** 진입 가능 |
+| **관계** | 종가 ≈ 기준선 · 선행1(구름 상단). 전환·기준 **수렴** |
+
+**전략 조건**
+
+| 구분 | 조건 | DSL 예시 |
+|------|------|----------|
+| 일부 익절 | 기준선 이탈 | `CLOSE_PRICE CROSS_DOWN BASE_LINE` |
+| 재매수 | 구름 **상단(선행1)** 지지 | `CLOSE_PRICE GT LEADING_SPAN1` AND `IN_CLOUD` 또는 `ABOVE_CLOUD` 회복 |
+| 관망 | 구름 내부 장기 체류 | `IN_CLOUD` + `HOLD_N_DAYS` → 방향 재확인 전 **신규 진입 자제** |
+| 손절 | 구름 하단 이탈 | `CLOUD_BREAK_DOWN` |
+
+**판단:** **단기 매매** 구간. 추세 추종은 포지션 **축소**, 스윙만 선행1·기준선 지지에서 재진입.
+
+---
+
+### 4.5 5파 — 마지막 상승 (과열·분산 매도)
+
+| 항목 | 내용 |
+|------|------|
+| **파동 특징** | 신고가 갱신 but **모멘텀 둔화**. 대중 **후행 참여** |
+| **일목 상태** | 종가·전환·기준 **이격 과대**. 후행은 위에 있으나 **꺾임** 조짐. 구름 **얇아짐** |
+| **관계** | `DIFF_GT(종가, 전환선)` 과열 · `SPAN1`/`SPAN2` 간격 축소 |
+
+**전략 조건**
+
+| 구분 | 조건 | 전략 |
+|------|------|------|
+| 분할 매도 | 신고가 + 전환선과 이격 확대 | `CLOSE_PRICE GT CONVERSION_LINE` + `DIFF_GT` (임계값) |
+| 1차 청산 | **전환선 이탈** | `CLOSE_PRICE CROSS_DOWN CONVERSION_LINE` |
+| 2차 청산 | 데드크로스 | `CONVERSION_LINE CROSS_DOWN BASE_LINE` |
+| 전량 익절 | 구름 재진입·하향 | `CLOUD_BREAK_DOWN` 또는 `BELOW_CLOUD` |
+
+**판단:** **매수 금지** · 보유분 **점진적 분할 매도**. 3파와 달리 **전환선 = 생명선**.
+
+---
+
+### 4.6 A-B-C 조정파 — 하락 전환
+
+#### A파 (하락 개시)
+
+| 일목 | 조건 |
+|------|------|
+| 기준선 **강한 이탈** | `CLOSE_PRICE CROSS_DOWN BASE_LINE` |
+| 데드크로스 | `CONVERSION_LINE CROSS_DOWN BASE_LINE` |
+| 전략 | **신규 매수 중단**, 5파 잔량 **청산 가속** |
+
+#### B파 (기술적 반등)
+
+| 일목 | 조건 |
+|------|------|
+| 반등하나 **기준선·음운 하단** 저항 | `CLOSE_PRICE CROSS_UP BASE_LINE` 후 `LT BASE_LINE` 재이탈 |
+| 구름 | `BELOW_CLOUD` 유지, `CLOUD_BREAK_UP` **실패** |
+| 전략 | 기준선 터치 후 **전량 매도·대피** (가짜 반등) |
+
+**DSL 예시 (B파 저항 확인):**
+
+```text
+AND(
+ CLOSE_PRICE LT BASE_LINE,
+ BELOW_CLOUD,
+ CONVERSION_LINE LT BASE_LINE
+)
+```
+
+#### C파 (본 하락)
+
+| 일목 | 조건 |
+|------|------|
+| 구름 완전 이탈 | `CLOUD_BREAK_DOWN` + `BELOW_CLOUD` |
+| 삼역역전 | 데드 + 구름 아래 + `LAGGING_LT_PRICE` |
+| 전략 | **물타기 금지**, 현금·인버스. `ICHIMOKU_SANYAKU` 매도 OR 조건 활용 |
+
+---
+
+## 5. 파동 × 일목 — 한눈에 보는 매매 매트릭스
+
+| 파동 | 일목 핵심 상태 | 매수 | 매도/청산 | goldenChart 템플릿 참고 |
+|------|----------------|------|-----------|-------------------------|
+| **1파** | 기준선 돌파 시도, 음운 위 | 소액·분할 | 관망 | `ICHIMOKU_TREND` (relaxed) |
+| **2파** | 기준선·선행2 지지 | **적극 1차 매수** | 지지 이탈 시 손절 | `TREND` + 구름 하단 `GT` |
+| **3파** | **삼역호전** | **추가·불타기** | 전환선 이탈 전 보유 | `ICHIMOKU_SANYAKU` / `PERFECT` |
+| **4파** | 기준선·구름 상단 횡보 | 지지 확인 시만 | 기준선 이탈 익절 | `IN_CLOUD` 필터 |
+| **5파** | 이격 과열, 얇은 구름 | **금지** | 전환선·데드 **분할 매도** | `CROSS_DOWN` 전환선 |
+| **A파** | 기준선 붕괴 | 금지 | 잔량 청산 | `TREND` sell |
+| **B파** | 기준선·음운 저항 | 금지 | **전량 매도** | `BELOW_CLOUD` + `LT BASE` |
+| **C파** | 삼역역전 | 금지 | 대피·숏 | `ICHIMOKU_SIT_EW_C_SELL` |
+
+> **복합지표 팔레트:** `ICHIMOKU_SIT_*` — 기본(L1~S6)·호전·역전·엘리어트(1~5·A~C) 파동별 매수/매도 조건 세트 (전략편집기 복합지표 탭)
+
+---
+
+## 6. goldenChart 전략편집기 적용 가이드
+
+### 6.1 내장 템플릿 매핑
+
+| 템플릿 | 적합 파동 | 핵심 조건 |
+|--------|-----------|-----------|
+| `ICHIMOKU_TREND` | 1파·2파·A파 | 전환↔기준 골든/데드 + (선택) 구름 |
+| `ICHIMOKU_SANYAKU` | **3파** | 구름 돌파 + 후행·전환 필터 |
+| `ICHIMOKU_PERFECT` | 3파 (strict) | 4중 AND — 신호↓ 품질↑ |
+| `ICHIMOKU_BB` | 4파·5파 | 후행 vs 볼린저 — 변동성·과열 |
+
+### 6.2 필터 강도 권장 (파동별)
+
+| 파동 | `relaxed` | `balanced` | `strict` |
+|------|-----------|------------|----------|
+| 1~2파 | ○ 진입 탐색 | △ | ✕ (과도) |
+| **3파** | △ | **○** | ○ (확신 시) |
+| 4~5파 | — (매수 X) | 청산 보조 | 익절 강화 |
+| A~C파 | — | 매도 | **삼역역전** |
+
+### 6.3 조건 설계 시 유의사항
+
+1. **`CROSS_*` vs `GT/LT`:** 돌파 **트리거**는 CROSS, **보유**는 GT/ABOVE_CLOUD.
+2. **EXISTS_IN 윈도우:** 삼역호전 보조 필터에만 사용 — 트리거에 쓰면 시그널 과다.
+3. **멀티 타임프레임:** 3파 확인 = 상위 TF `ABOVE_CLOUD` + 하위 TF `CROSS_UP` 조합 권장.
+4. **엘리어트 병행:** 파동 카운트는 주관적 → 일목 **상태 조건**으로 객관화.
+
+---
+
+## 7. 요약 — 판단 흐름도
+
+```text
+[하락/바닥] 1파: 기준선 돌파? ──No──→ 관망
+ │
+ Yes (소액)
+ ↓
+ 2파: 기준선·선행2 지지? ──No──→ 손절
+ │
+ Yes (1차 매수)
+ ↓
+ 3파: 삼역호전? ──No──→ 대기/추가 관망
+ │
+ Yes (적극 매수·보유)
+ ↓
+ 4파: 기준선·구름상단 지지? → 재매수 or 일부익절
+ ↓
+ 5파: 전환선 이탈? → 분할 매도
+ ↓
+ A-B-C: 기준선 저항·삼역역전? → 전량 청산·대피
+```
+
+---
+
+## 8. 참고 — 표준 기간 (9 · 26 · 52)
+
+| 요소 | 기간 | 시간축 의미 |
+|------|------|-------------|
+| 전환선 | 9 | 단기 (약 1.5주, 일봉 기준) |
+| 기준선 | 26 | 중기 (약 1달) |
+| 선행스팬 | 26 선행 | **1달 앞** 매물·심리 |
+| 선행2 | 52 | 장기 (약 2.5달) |
+| 후행 | 26 후행 | **1달 전**과 현재 비교 |
+
+분봉(3m·15m) 사용 시 동일 비율을 유지하되, `ICHIMOKU_SANYAKU` 템플릿의 EXISTS_IN 윈도우(N봉)를 **타임프레임에 맞게** 조절합니다.
+
+---
+
+*문서 버전: 2026-03 · goldenChart 전략 DSL `ICHIMOKU` 조건셋 기준*