velo-plot 2.0.0 → 2.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/{ChartCore-BhQ4j7f5.js → ChartCore-ivzLqxVb.js} +419 -393
  2. package/dist/ChartCore-ivzLqxVb.js.map +1 -0
  3. package/dist/{SciPlot-GJvw7GJo.js → SciPlot-CEU4ApgD.js} +2 -2
  4. package/dist/{SciPlot-GJvw7GJo.js.map → SciPlot-CEU4ApgD.js.map} +1 -1
  5. package/dist/{axisFormat-SPX-CD5s.js → axisFormat-CzumxpCL.js} +3 -3
  6. package/dist/axisFormat-CzumxpCL.js.map +1 -0
  7. package/dist/core/chart/ChartAxisManager.d.ts +2 -0
  8. package/dist/core/chart/ChartCore.d.ts +15 -0
  9. package/dist/core/chart/ChartPluginBridge.d.ts +1 -0
  10. package/dist/core/chart/ChartRenderLoop.d.ts +2 -0
  11. package/dist/core/chart/ChartStateManager.d.ts +2 -0
  12. package/dist/core/chart/types.d.ts +5 -0
  13. package/dist/core/sync/index.d.ts +0 -1
  14. package/dist/{createStackedChart-DJSmqerD.js → createStackedChart-DxNW0VkF.js} +178 -179
  15. package/dist/createStackedChart-DxNW0VkF.js.map +1 -0
  16. package/dist/{index-D7dTq6VB.js → index-BBpJwOct.js} +17 -19
  17. package/dist/index-BBpJwOct.js.map +1 -0
  18. package/dist/{index-CUGS98p4.js → index-CaXWSOTk.js} +3 -6
  19. package/dist/index-CaXWSOTk.js.map +1 -0
  20. package/dist/{index-CWipqOLP.js → index-qunX30Xu.js} +2 -2
  21. package/dist/{index-CWipqOLP.js.map → index-qunX30Xu.js.map} +1 -1
  22. package/dist/{index.core-fpZ1dYN0.js → index.core-COREBDNq.js} +25 -24
  23. package/dist/{index.core-fpZ1dYN0.js.map → index.core-COREBDNq.js.map} +1 -1
  24. package/dist/index.d.ts +1 -1
  25. package/dist/{mockDatafeed-Cdg5hKEo.js → mockDatafeed-927foCM4.js} +2 -2
  26. package/dist/mockDatafeed-927foCM4.js.map +1 -0
  27. package/dist/plugins/analysis/contours.d.ts +31 -0
  28. package/dist/plugins/analysis.js +494 -407
  29. package/dist/plugins/analysis.js.map +1 -1
  30. package/dist/plugins/broken-axis.js +170 -181
  31. package/dist/plugins/broken-axis.js.map +1 -1
  32. package/dist/plugins/forecasting/algorithms.d.ts +7 -2
  33. package/dist/plugins/forecasting/types.d.ts +13 -3
  34. package/dist/plugins/forecasting.js +355 -175
  35. package/dist/plugins/forecasting.js.map +1 -1
  36. package/dist/plugins/latex/symbols.d.ts +50 -0
  37. package/dist/plugins/latex/types.d.ts +13 -1
  38. package/dist/plugins/latex.js +351 -331
  39. package/dist/plugins/latex.js.map +1 -1
  40. package/dist/plugins/ml-integration/native-algorithms.d.ts +24 -4
  41. package/dist/plugins/ml-integration/types.d.ts +19 -0
  42. package/dist/plugins/ml-integration.js +191 -140
  43. package/dist/plugins/ml-integration.js.map +1 -1
  44. package/dist/plugins/pattern-recognition/types.d.ts +28 -1
  45. package/dist/plugins/pattern-recognition.js +416 -343
  46. package/dist/plugins/pattern-recognition.js.map +1 -1
  47. package/dist/plugins/snapshot.js +36 -36
  48. package/dist/plugins/snapshot.js.map +1 -1
  49. package/dist/plugins/sync.js +1 -1
  50. package/dist/plugins/tools.js +1 -1
  51. package/dist/plugins/virtualization.js +1 -1
  52. package/dist/react.js +2 -2
  53. package/dist/symbols-DT0eLlpW.js +568 -0
  54. package/dist/symbols-DT0eLlpW.js.map +1 -0
  55. package/dist/trading.js +5 -5
  56. package/dist/velo-plot.full.js +184 -182
  57. package/dist/velo-plot.js +3 -3
  58. package/dist/workers/indicatorsAsync.d.ts +24 -0
  59. package/package.json +1 -1
  60. package/dist/ChartCore-BhQ4j7f5.js.map +0 -1
  61. package/dist/axisFormat-SPX-CD5s.js.map +0 -1
  62. package/dist/createStackedChart-DJSmqerD.js.map +0 -1
  63. package/dist/index-CUGS98p4.js.map +0 -1
  64. package/dist/index-D7dTq6VB.js.map +0 -1
  65. package/dist/mockDatafeed-Cdg5hKEo.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"pattern-recognition.js","sources":["../../src/plugins/pattern-recognition/patterns.ts","../../src/plugins/pattern-recognition/index.ts"],"sourcesContent":["/**\n * Pattern Recognition Plugin - Pattern Definitions\n * \n * Implements common technical analysis patterns for financial and scientific data.\n * Includes head-shoulders, double tops/bottoms, triangles, and more.\n * \n * @packageDocumentation\n * @module plugins/pattern-recognition\n */\n\nimport type {\n PatternDefinition,\n PatternType,\n PatternPoint,\n PatternValidationResult,\n PatternSegment,\n PatternMeasurements\n} from './types';\n\n// ============================================\n// Utility Functions\n// ============================================\n\nfunction findPeaksAndValleys(points: PatternPoint[]): { peaks: PatternPoint[], valleys: PatternPoint[] } {\n const peaks: PatternPoint[] = [];\n const valleys: PatternPoint[] = [];\n \n for (let i = 1; i < points.length - 1; i++) {\n const prev = points[i - 1];\n const curr = points[i];\n const next = points[i + 1];\n \n // Peak detection\n if (curr.y > prev.y && curr.y > next.y) {\n peaks.push({ ...curr, type: 'peak' });\n }\n // Valley detection\n else if (curr.y < prev.y && curr.y < next.y) {\n valleys.push({ ...curr, type: 'valley' });\n }\n }\n \n return { peaks, valleys };\n}\n\nfunction calculateSlope(p1: PatternPoint, p2: PatternPoint): number {\n return (p2.y - p1.y) / (p2.x - p1.x);\n}\n\nfunction calculatePatternMeasurements(points: PatternPoint[]): PatternMeasurements {\n const yValues = points.map(p => p.y);\n const xValues = points.map(p => p.x);\n \n const height = Math.max(...yValues) - Math.min(...yValues);\n const width = Math.max(...xValues) - Math.min(...xValues);\n const slope = calculateSlope(points[0], points[points.length - 1]);\n \n return {\n height,\n width,\n slope,\n volumeProfile: {\n increasing: 0.4, // Mock values\n decreasing: 0.3,\n neutral: 0.3\n },\n breakoutTarget: Math.max(...yValues) + height * 0.8,\n stopLoss: Math.min(...yValues) - height * 0.2\n };\n}\n\n// ============================================\n// Head and Shoulders Pattern\n// ============================================\n\nfunction validateHeadShoulders(points: PatternPoint[]): PatternValidationResult {\n if (points.length < 5) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient points for head-shoulders pattern'] };\n }\n \n const { peaks, valleys } = findPeaksAndValleys(points);\n \n // Need at least 3 peaks and 2 valleys for head-shoulders\n if (peaks.length < 3 || valleys.length < 2) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient peaks/valleys'] };\n }\n \n // Find left shoulder, head, and right shoulder\n const leftShoulder = peaks[0];\n const head = peaks[1];\n const rightShoulder = peaks[2];\n \n // Find the valleys between shoulders and head\n const leftValley = valleys[0];\n const rightValley = valleys[1];\n \n // Validate pattern structure\n const headHigherThanShoulders = head.y > leftShoulder.y && head.y > rightShoulder.y;\n const shouldersApproximatelyEqual = Math.abs(leftShoulder.y - rightShoulder.y) / leftShoulder.y < 0.1;\n const valleyBelowShoulders = leftValley.y < leftShoulder.y && rightValley.y < rightShoulder.y;\n \n if (!headHigherThanShoulders || !shouldersApproximatelyEqual || !valleyBelowShoulders) {\n return { \n valid: false, \n confidence: 0, \n segments: [], \n keyPoints: [], \n errors: ['Invalid head-shoulders structure'] \n };\n }\n \n // Create segments\n const segments: PatternSegment[] = [\n { start: leftShoulder, end: leftValley, type: 'resistance', strength: 0.8 },\n { start: leftValley, end: head, type: 'support', strength: 0.7 },\n { start: head, end: rightValley, type: 'resistance', strength: 0.8 },\n { start: rightValley, end: rightShoulder, type: 'support', strength: 0.7 }\n ];\n \n const keyPoints = [leftShoulder, leftValley, head, rightValley, rightShoulder];\n const measurements = calculatePatternMeasurements(points);\n \n // Calculate confidence based on pattern symmetry\n const shoulderSymmetry = 1 - Math.abs(leftShoulder.y - rightShoulder.y) / head.y;\n const valleySymmetry = 1 - Math.abs(leftValley.y - rightValley.y) / head.y;\n const confidence = (shoulderSymmetry + valleySymmetry) / 2;\n \n return {\n valid: true,\n confidence,\n segments,\n keyPoints,\n measurements\n };\n}\n\n// ============================================\n// Double Top/Bottom Pattern\n// ============================================\n\nfunction validateDoubleTop(points: PatternPoint[]): PatternValidationResult {\n if (points.length < 4) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient points for double top'] };\n }\n \n const { peaks, valleys } = findPeaksAndValleys(points);\n \n if (peaks.length < 2 || valleys.length < 1) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient peaks/valleys'] };\n }\n \n const firstTop = peaks[0];\n const secondTop = peaks[1];\n const valley = valleys[0];\n \n // Validate double top structure\n const topsApproximatelyEqual = Math.abs(firstTop.y - secondTop.y) / firstTop.y < 0.05;\n const valleyBelowTops = valley.y < firstTop.y && valley.y < secondTop.y;\n const significantDrop = (firstTop.y - valley.y) / firstTop.y > 0.1;\n \n if (!topsApproximatelyEqual || !valleyBelowTops || !significantDrop) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Invalid double top structure'] };\n }\n \n const segments: PatternSegment[] = [\n { start: firstTop, end: valley, type: 'resistance', strength: 0.9 },\n { start: valley, end: secondTop, type: 'support', strength: 0.8 },\n { start: firstTop, end: secondTop, type: 'resistance', strength: 0.9 }\n ];\n \n const keyPoints = [firstTop, valley, secondTop];\n const measurements = calculatePatternMeasurements(points);\n \n // Confidence based on top equality and depth of valley\n const topEquality = 1 - Math.abs(firstTop.y - secondTop.y) / firstTop.y;\n const depthRatio = (firstTop.y - valley.y) / firstTop.y;\n const confidence = (topEquality + Math.min(depthRatio * 2, 1)) / 2;\n \n return {\n valid: true,\n confidence,\n segments,\n keyPoints,\n measurements\n };\n}\n\nfunction validateDoubleBottom(points: PatternPoint[]): PatternValidationResult {\n if (points.length < 4) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient points for double bottom'] };\n }\n \n const { peaks, valleys } = findPeaksAndValleys(points);\n \n if (valleys.length < 2 || peaks.length < 1) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient peaks/valleys'] };\n }\n \n const firstBottom = valleys[0];\n const secondBottom = valleys[1];\n const peak = peaks[0];\n \n // Validate double bottom structure\n const bottomsApproximatelyEqual = Math.abs(firstBottom.y - secondBottom.y) / firstBottom.y < 0.05;\n const peakAboveBottoms = peak.y > firstBottom.y && peak.y > secondBottom.y;\n const significantRise = (peak.y - firstBottom.y) / firstBottom.y > 0.1;\n \n if (!bottomsApproximatelyEqual || !peakAboveBottoms || !significantRise) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Invalid double bottom structure'] };\n }\n \n const segments: PatternSegment[] = [\n { start: firstBottom, end: peak, type: 'support', strength: 0.9 },\n { start: peak, end: secondBottom, type: 'resistance', strength: 0.8 },\n { start: firstBottom, end: secondBottom, type: 'support', strength: 0.9 }\n ];\n \n const keyPoints = [firstBottom, peak, secondBottom];\n const measurements = calculatePatternMeasurements(points);\n \n // Confidence based on bottom equality and height of peak\n const bottomEquality = 1 - Math.abs(firstBottom.y - secondBottom.y) / firstBottom.y;\n const heightRatio = (peak.y - firstBottom.y) / firstBottom.y;\n const confidence = (bottomEquality + Math.min(heightRatio * 2, 1)) / 2;\n \n return {\n valid: true,\n confidence,\n segments,\n keyPoints,\n measurements\n };\n}\n\n// ============================================\n// Triangle Patterns\n// ============================================\n\nfunction validateAscendingTriangle(points: PatternPoint[]): PatternValidationResult {\n if (points.length < 4) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient points for ascending triangle'] };\n }\n \n // Find horizontal resistance line and ascending support line\n const yValues = points.map(p => p.y);\n const resistanceLevel = Math.max(...yValues);\n const resistancePoints = points.filter(p => Math.abs(p.y - resistanceLevel) / resistanceLevel < 0.02);\n \n if (resistancePoints.length < 2) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient resistance points'] };\n }\n \n // Check for ascending support (higher lows)\n const lows = points.filter((p, i) => i === 0 || p.y < points[i - 1].y);\n if (lows.length < 2) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient low points'] };\n }\n \n const firstLow = lows[0];\n const lastLow = lows[lows.length - 1];\n const supportSlope = calculateSlope(firstLow, lastLow);\n \n // Support should be ascending (positive slope)\n if (supportSlope <= 0) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Support not ascending'] };\n }\n \n const segments: PatternSegment[] = [\n { start: resistancePoints[0], end: resistancePoints[resistancePoints.length - 1], type: 'resistance', strength: 0.8 },\n { start: firstLow, end: lastLow, type: 'support', strength: 0.7 }\n ];\n \n const keyPoints = [...resistancePoints.slice(0, 2), firstLow, lastLow];\n const measurements = calculatePatternMeasurements(points);\n \n // Confidence based on horizontal resistance and ascending support\n const resistanceFlatness = 1 - Math.abs(resistancePoints[0].y - resistancePoints[resistancePoints.length - 1].y) / resistanceLevel;\n const supportAscending = Math.min(supportSlope / 0.01, 1); // Normalize slope\n const confidence = (resistanceFlatness + supportAscending) / 2;\n \n return {\n valid: true,\n confidence,\n segments,\n keyPoints,\n measurements\n };\n}\n\n// ============================================\n// Pattern Definitions Registry\n// ============================================\n\nexport const BUILTIN_PATTERNS: Record<PatternType, PatternDefinition> = {\n 'head-shoulders': {\n id: 'head-shoulders',\n type: 'head-shoulders',\n name: 'Head and Shoulders',\n description: 'Bearish reversal pattern with three peaks',\n minPoints: 5,\n maxPoints: 7,\n validator: validateHeadShoulders\n },\n \n 'inverse-head-shoulders': {\n id: 'inverse-head-shoulders',\n type: 'inverse-head-shoulders',\n name: 'Inverse Head and Shoulders',\n description: 'Bullish reversal pattern with three valleys',\n minPoints: 5,\n maxPoints: 7,\n validator: (points) => {\n // Invert points and validate as regular head-shoulders\n const invertedPoints = points.map(p => ({ ...p, y: -p.y }));\n const result = validateHeadShoulders(invertedPoints);\n return result;\n }\n },\n \n 'double-top': {\n id: 'double-top',\n type: 'double-top',\n name: 'Double Top',\n description: 'Bearish reversal pattern with two equal peaks',\n minPoints: 4,\n maxPoints: 6,\n validator: validateDoubleTop\n },\n \n 'double-bottom': {\n id: 'double-bottom',\n type: 'double-bottom',\n name: 'Double Bottom',\n description: 'Bullish reversal pattern with two equal valleys',\n minPoints: 4,\n maxPoints: 6,\n validator: validateDoubleBottom\n },\n \n 'triple-top': {\n id: 'triple-top',\n type: 'triple-top',\n name: 'Triple Top',\n description: 'Bearish reversal pattern with three equal peaks',\n minPoints: 5,\n maxPoints: 7,\n validator: (points) => {\n if (points.length < 5) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient points'] };\n }\n \n const { peaks } = findPeaksAndValleys(points);\n if (peaks.length < 3) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Need at least 3 peaks'] };\n }\n \n const peak1 = peaks[0].y;\n const peak2 = peaks[1].y;\n const peak3 = peaks[2].y;\n \n const tolerance = 0.05;\n const peaksEqual = Math.abs(peak1 - peak2) / peak1 < tolerance && Math.abs(peak2 - peak3) / peak2 < tolerance;\n \n if (!peaksEqual) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Peaks not equal'] };\n }\n \n const segments: PatternSegment[] = [\n { start: peaks[0], end: peaks[1], type: 'resistance', strength: 0.8 },\n { start: peaks[1], end: peaks[2], type: 'resistance', strength: 0.8 }\n ];\n \n const keyPoints = [peaks[0], peaks[1], peaks[2]];\n const measurements = calculatePatternMeasurements(points);\n \n return {\n valid: true,\n confidence: 0.8,\n segments,\n keyPoints,\n measurements\n };\n }\n },\n \n 'triple-bottom': {\n id: 'triple-bottom',\n type: 'triple-bottom',\n name: 'Triple Bottom',\n description: 'Bullish reversal pattern with three equal valleys',\n minPoints: 5,\n maxPoints: 7,\n validator: (points) => {\n const invertedPoints = points.map(p => ({ ...p, y: -p.y }));\n return BUILTIN_PATTERNS['triple-top'].validator(invertedPoints);\n }\n },\n \n 'ascending-triangle': {\n id: 'ascending-triangle',\n type: 'ascending-triangle',\n name: 'Ascending Triangle',\n description: 'Continuation pattern with horizontal resistance and ascending support',\n minPoints: 4,\n maxPoints: 8,\n validator: validateAscendingTriangle\n },\n \n 'descending-triangle': {\n id: 'descending-triangle',\n type: 'descending-triangle',\n name: 'Descending Triangle',\n description: 'Continuation pattern with horizontal support and descending resistance',\n minPoints: 4,\n maxPoints: 8,\n validator: (points) => {\n // Invert points and validate as ascending triangle\n const invertedPoints = points.map(p => ({ ...p, y: -p.y }));\n const result = validateAscendingTriangle(invertedPoints);\n return result;\n }\n },\n \n 'symmetrical-triangle': {\n id: 'symmetrical-triangle',\n type: 'symmetrical-triangle',\n name: 'Symmetrical Triangle',\n description: 'Continuation pattern with converging support and resistance',\n minPoints: 4,\n maxPoints: 8,\n validator: (points) => {\n // Simplified validation for symmetrical triangle\n if (points.length < 4) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient points'] };\n }\n \n // Check for converging trendlines\n const firstHalf = points.slice(0, Math.floor(points.length / 2));\n const secondHalf = points.slice(Math.floor(points.length / 2));\n \n const firstSlope = calculateSlope(firstHalf[0], firstHalf[firstHalf.length - 1]);\n const secondSlope = calculateSlope(secondHalf[0], secondHalf[secondHalf.length - 1]);\n \n // Slopes should be converging (opposite signs)\n const converging = (firstSlope > 0 && secondSlope < 0) || (firstSlope < 0 && secondSlope > 0);\n \n if (!converging) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Lines not converging'] };\n }\n \n const segments: PatternSegment[] = [\n { start: firstHalf[0], end: firstHalf[firstHalf.length - 1], type: 'trendline', strength: 0.7 },\n { start: secondHalf[0], end: secondHalf[secondHalf.length - 1], type: 'trendline', strength: 0.7 }\n ];\n \n const keyPoints = [firstHalf[0], firstHalf[firstHalf.length - 1], secondHalf[0], secondHalf[secondHalf.length - 1]];\n const measurements = calculatePatternMeasurements(points);\n \n return {\n valid: true,\n confidence: 0.7,\n segments,\n keyPoints,\n measurements\n };\n }\n },\n \n 'rising-wedge': {\n id: 'rising-wedge',\n type: 'rising-wedge',\n name: 'Rising Wedge',\n description: 'Bearish reversal pattern with two converging upward lines',\n minPoints: 4,\n maxPoints: 8,\n validator: (points) => {\n // Simplified rising wedge validation\n if (points.length < 4) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient points'] };\n }\n \n const { peaks, valleys } = findPeaksAndValleys(points);\n if (peaks.length < 2 || valleys.length < 2) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient peaks/valleys'] };\n }\n \n const peakSlope = calculateSlope(peaks[0], peaks[peaks.length - 1]);\n const valleySlope = calculateSlope(valleys[0], valleys[valleys.length - 1]);\n \n // Both lines should be rising but converging (valley slope > peak slope)\n const wedgePattern = peakSlope > 0 && valleySlope > 0 && valleySlope > peakSlope;\n \n if (!wedgePattern) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Not a rising wedge pattern'] };\n }\n \n const segments: PatternSegment[] = [\n { start: peaks[0], end: peaks[peaks.length - 1], type: 'resistance', strength: 0.8 },\n { start: valleys[0], end: valleys[valleys.length - 1], type: 'support', strength: 0.8 }\n ];\n \n const keyPoints = [peaks[0], peaks[peaks.length - 1], valleys[0], valleys[valleys.length - 1]];\n const measurements = calculatePatternMeasurements(points);\n \n return {\n valid: true,\n confidence: 0.75,\n segments,\n keyPoints,\n measurements\n };\n }\n },\n \n 'falling-wedge': {\n id: 'falling-wedge',\n type: 'falling-wedge',\n name: 'Falling Wedge',\n description: 'Bullish reversal pattern with two converging downward lines',\n minPoints: 4,\n maxPoints: 8,\n validator: (points) => {\n // Invert points and validate as rising wedge\n const invertedPoints = points.map(p => ({ ...p, y: -p.y }));\n const result = BUILTIN_PATTERNS['rising-wedge'].validator(invertedPoints);\n return result;\n }\n },\n \n 'rectangle': {\n id: 'rectangle',\n type: 'rectangle',\n name: 'Rectangle',\n description: 'Continuation pattern with horizontal support and resistance',\n minPoints: 4,\n maxPoints: 10,\n validator: (points) => {\n if (points.length < 4) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient points'] };\n }\n \n const yValues = points.map(p => p.y);\n const resistance = Math.max(...yValues);\n const support = Math.min(...yValues);\n \n // Check for relatively flat top and bottom\n const resistancePoints = points.filter(p => Math.abs(p.y - resistance) / resistance < 0.05);\n const supportPoints = points.filter(p => Math.abs(p.y - support) / support < 0.05);\n \n if (resistancePoints.length < 2 || supportPoints.length < 2) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient horizontal lines'] };\n }\n \n const segments: PatternSegment[] = [\n { start: resistancePoints[0], end: resistancePoints[resistancePoints.length - 1], type: 'resistance', strength: 0.9 },\n { start: supportPoints[0], end: supportPoints[supportPoints.length - 1], type: 'support', strength: 0.9 }\n ];\n \n const keyPoints = [resistancePoints[0], resistancePoints[resistancePoints.length - 1], supportPoints[0], supportPoints[supportPoints.length - 1]];\n const measurements = calculatePatternMeasurements(points);\n \n return {\n valid: true,\n confidence: 0.8,\n segments,\n keyPoints,\n measurements\n };\n }\n },\n \n 'flag': {\n id: 'flag',\n type: 'flag',\n name: 'Flag',\n description: 'Short-term continuation pattern after strong move',\n minPoints: 3,\n maxPoints: 6,\n validator: (points) => {\n // Simplified flag validation\n if (points.length < 3) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient points'] };\n }\n \n const slope = calculateSlope(points[0], points[points.length - 1]);\n \n // Flag should be relatively horizontal (small slope)\n const horizontal = Math.abs(slope) < 0.01;\n \n if (!horizontal) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Not horizontal enough'] };\n }\n \n const segments: PatternSegment[] = [\n { start: points[0], end: points[points.length - 1], type: 'trendline', strength: 0.6 }\n ];\n \n const keyPoints = [points[0], points[points.length - 1]];\n const measurements = calculatePatternMeasurements(points);\n \n return {\n valid: true,\n confidence: 0.6,\n segments,\n keyPoints,\n measurements\n };\n }\n },\n \n 'pennant': {\n id: 'pennant',\n type: 'pennant',\n name: 'Pennant',\n description: 'Short-term continuation pattern with converging lines',\n minPoints: 3,\n maxPoints: 5,\n validator: (points) => {\n // Similar to symmetrical triangle but smaller\n return BUILTIN_PATTERNS['symmetrical-triangle'].validator(points);\n }\n },\n \n 'custom': {\n id: 'custom',\n type: 'custom',\n name: 'Custom Pattern',\n description: 'User-defined pattern',\n minPoints: 3,\n validator: (_points) => {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Custom pattern not implemented'] };\n }\n }\n};","/**\n * Pattern Recognition Plugin - Main Implementation\n * \n * Provides technical pattern recognition for financial and scientific data.\n * Supports common chart patterns and custom pattern definitions.\n * \n * @example\n * ```typescript\n * import { PluginPatternRecognition } from 'velo-plot/plugins/pattern-recognition';\n * \n * chart.use(PluginPatternRecognition({\n * defaultParameters: {\n * minConfidence: 0.7,\n * patternTypes: ['head-shoulders', 'double-top', 'ascending-triangle'],\n * sensitivity: 0.5\n * },\n * enableRealtime: true,\n * visualization: {\n * showPatterns: true,\n * showLabels: true,\n * colorScheme: {\n * 'head-shoulders': '#ff6b6b',\n * 'double-top': '#4ecdc4',\n * 'ascending-triangle': '#45b7d1'\n * }\n * }\n * }));\n * \n * // Detect patterns\n * const result = await chart.patterns.detectPatterns('series1', dataPoints);\n * console.log(`Found ${result.matches.length} patterns`);\n * \n * // Enable real-time detection\n * chart.patterns.enableRealtimeDetection('series1');\n * ```\n * \n * @packageDocumentation\n * @module plugins/pattern-recognition\n */\n\nimport type { \n PluginManifest, \n ChartPlugin, \n PluginContext,\n BeforeRenderEvent,\n DataUpdateEvent\n} from '../types';\n\nimport type {\n PluginPatternRecognitionConfig,\n PatternRecognitionAPI,\n PatternDetectionResult,\n PatternMatch,\n PatternPoint,\n PatternDetectionParameters,\n PatternType,\n CustomPatternConfig,\n PatternDefinition,\n PatternValidationResult,\n PatternDetectedEvent\n} from './types';\n\nimport { BUILTIN_PATTERNS } from './patterns';\n\n// ============================================\n// Plugin Manifest\n// ============================================\n\nconst manifestPatternRecognition: PluginManifest = {\n name: 'pattern-recognition',\n version: '1.0.0',\n description: 'Technical pattern recognition for financial and scientific data',\n author: 'Sci Plot Team',\n provides: ['patterns', 'technical-analysis', 'chart-patterns']\n};\n\n// ============================================\n// Default Configuration\n// ============================================\n\nconst DEFAULT_CONFIG: Required<PluginPatternRecognitionConfig> = {\n defaultParameters: {\n minConfidence: 0.7,\n maxPatterns: 10,\n patternTypes: ['head-shoulders', 'double-top', 'double-bottom', 'ascending-triangle', 'descending-triangle'],\n sensitivity: 0.5,\n minPatternSize: 5,\n maxPatternSize: 50,\n overlapTolerance: 0.3,\n enableVolumeConfirmation: false,\n enableTrendConfirmation: true\n },\n customPatterns: [],\n enableRealtime: false,\n debounceTime: 500,\n maxStoredPatterns: 100,\n visualization: {\n showPatterns: true,\n showLabels: true,\n showTargets: true,\n colorScheme: {\n 'head-shoulders': '#ff6b6b',\n 'inverse-head-shoulders': '#4ecdc4',\n 'double-top': '#ff9f43',\n 'double-bottom': '#00d2d3',\n 'triple-top': '#ff6b6b',\n 'triple-bottom': '#4ecdc4',\n 'ascending-triangle': '#45b7d1',\n 'descending-triangle': '#f39c12',\n 'symmetrical-triangle': '#9b59b6',\n 'rising-wedge': '#e74c3c',\n 'falling-wedge': '#27ae60',\n 'rectangle': '#34495e',\n 'flag': '#f1c40f',\n 'pennant': '#e67e22',\n 'custom': '#95a5a6'\n },\n opacity: 0.7,\n lineWidth: 2\n },\n notifications: {\n enableAlerts: false,\n minAlertConfidence: 0.8,\n alertTypes: ['head-shoulders', 'double-top', 'double-bottom']\n }\n};\n\n// ============================================\n// Pattern Recognition Plugin Implementation\n// ============================================\n\nexport function PluginPatternRecognition(\n userConfig: Partial<PluginPatternRecognitionConfig> = {}\n): ChartPlugin<PluginPatternRecognitionConfig> {\n const config = { ...DEFAULT_CONFIG, ...userConfig };\n let ctx: PluginContext | null = null;\n \n // Pattern storage\n const patternMatches = new Map<string, PatternMatch[]>();\n const registeredPatterns = new Map<PatternType, PatternDefinition>(Object.entries(BUILTIN_PATTERNS) as [PatternType, PatternDefinition][]);\n const realtimeSeries = new Set<string>();\n const debounceTimers = new Map<string, any>();\n \n // ============================================\n // Pattern Detection Engine\n // ============================================\n \n async function detectPatterns(\n seriesId: string, \n dataPoints: PatternPoint[], \n parameters?: Partial<PatternDetectionParameters>\n ): Promise<PatternDetectionResult> {\n const params = { ...config.defaultParameters, ...parameters };\n const startTime = performance.now();\n \n const matches: PatternMatch[] = [];\n const patternsByType: Record<PatternType, number> = {} as any;\n \n // Preprocess data - find peaks and valleys\n const processedPoints = preprocessData(dataPoints, params.sensitivity);\n \n // Check each pattern type\n for (const patternType of params.patternTypes) {\n const pattern = registeredPatterns.get(patternType);\n if (!pattern) continue;\n \n // Slide window through data\n for (let i = params.minPatternSize; i <= Math.min(processedPoints.length, params.maxPatternSize); i++) {\n const window = processedPoints.slice(Math.max(0, i - params.maxPatternSize), i);\n \n if (window.length < pattern.minPoints) continue;\n if (pattern.maxPoints && window.length > pattern.maxPoints) continue;\n \n // Validate pattern\n const validation = pattern.validator(window);\n \n if (validation.valid && validation.confidence >= params.minConfidence) {\n const match: PatternMatch = {\n pattern,\n confidence: validation.confidence,\n location: {\n startIndex: Math.max(0, i - params.maxPatternSize),\n endIndex: i,\n startPoint: window[0],\n endPoint: window[window.length - 1]\n },\n validation,\n timestamp: Date.now(),\n seriesId\n };\n \n // Check for overlaps\n if (!hasSignificantOverlap(match, matches, params.overlapTolerance)) {\n matches.push(match);\n patternsByType[patternType] = (patternsByType[patternType] || 0) + 1;\n \n // Limit number of patterns\n if (matches.length >= params.maxPatterns!) {\n break;\n }\n }\n }\n }\n \n if (matches.length >= params.maxPatterns!) {\n break;\n }\n }\n \n // Sort by confidence\n matches.sort((a, b) => b.confidence - a.confidence);\n \n // Store matches\n patternMatches.set(seriesId, matches);\n \n const detectionTime = performance.now() - startTime;\n \n // Emit events for high-confidence patterns\n for (const match of matches) {\n if (match.confidence >= config.notifications.minAlertConfidence &&\n config.notifications.alertTypes.includes(match.pattern.type)) {\n ctx?.events.emit('pattern:detected', {\n match,\n seriesId,\n timestamp: Date.now()\n } as PatternDetectedEvent);\n }\n }\n \n const result: PatternDetectionResult = {\n matches,\n summary: {\n totalPatterns: matches.length,\n patternsByType,\n averageConfidence: matches.length > 0 ? matches.reduce((sum, m) => sum + m.confidence, 0) / matches.length : 0,\n detectionTime\n },\n processedPoints: processedPoints.length,\n parameters: params\n };\n \n ctx?.log.info(`Pattern detection completed for ${seriesId}: ${matches.length} patterns found`);\n \n return result;\n }\n \n function preprocessData(dataPoints: PatternPoint[], sensitivity: number): PatternPoint[] {\n return dataPoints.filter((point, index) => {\n if (index === 0 || index === dataPoints.length - 1) return true;\n \n const prev = dataPoints[index - 1];\n \n const priceChange = Math.abs(point.y - prev.y) / prev.y;\n return priceChange >= sensitivity * 0.01;\n });\n }\n \n function hasSignificantOverlap(newMatch: PatternMatch, existingMatches: PatternMatch[], tolerance: number): boolean {\n for (const existing of existingMatches) {\n const overlapStart = Math.max(newMatch.location.startIndex, existing.location.startIndex);\n const overlapEnd = Math.min(newMatch.location.endIndex, existing.location.endIndex);\n const overlapSize = overlapEnd - overlapStart;\n \n const newMatchSize = newMatch.location.endIndex - newMatch.location.startIndex;\n const existingMatchSize = existing.location.endIndex - existing.location.startIndex;\n \n const overlapRatio = overlapSize / Math.min(newMatchSize, existingMatchSize);\n \n if (overlapRatio > tolerance) {\n return true;\n }\n }\n return false;\n }\n \n // ============================================\n // Custom Pattern Registration\n // ============================================\n \n function registerCustomPattern(customConfig: CustomPatternConfig): void {\n const pattern: PatternDefinition = {\n id: customConfig.id,\n type: 'custom',\n name: customConfig.name,\n minPoints: customConfig.pointSequence.length,\n maxPoints: customConfig.pointSequence.length,\n validator: (points) => validateCustomPattern(points, customConfig)\n };\n \n registeredPatterns.set('custom', pattern);\n ctx?.log.info(`Custom pattern registered: ${customConfig.id}`);\n }\n \n function validateCustomPattern(points: PatternPoint[], config: CustomPatternConfig): PatternValidationResult {\n if (points.length < config.pointSequence.length) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient points'] };\n }\n \n let confidence = 1.0;\n const errors: string[] = [];\n \n for (let i = 0; i < config.pointSequence.length; i++) {\n const sequencePoint = config.pointSequence[i];\n const actualPoint = points[i];\n \n if (sequencePoint.constraints) {\n const constraints = sequencePoint.constraints;\n \n if (constraints.higherThanPrevious && i > 0) {\n if (actualPoint.y <= points[i - 1].y) {\n confidence *= 0.8;\n errors.push(`Point ${i} not higher than previous`);\n }\n }\n \n if (constraints.lowerThanPrevious && i > 0) {\n if (actualPoint.y >= points[i - 1].y) {\n confidence *= 0.8;\n errors.push(`Point ${i} not lower than previous`);\n }\n }\n \n if (constraints.withinRange) {\n const [min, max] = constraints.withinRange;\n if (actualPoint.y < min || actualPoint.y > max) {\n confidence *= 0.7;\n errors.push(`Point ${i} not within range [${min}, ${max}]`);\n }\n }\n }\n }\n \n return {\n valid: confidence >= 0.5,\n confidence,\n segments: [],\n keyPoints: points,\n errors: errors.length > 0 ? errors : undefined\n };\n }\n \n // ============================================\n // API Implementation\n // ============================================\n \n const api: PatternRecognitionAPI & Record<string, unknown> = {\n detectPatterns,\n \n registerCustomPattern,\n \n getRegisteredPatterns(): PatternDefinition[] {\n return Array.from(registeredPatterns.values());\n },\n \n getPatternMatches(seriesId: string): PatternMatch[] {\n return patternMatches.get(seriesId) || [];\n },\n \n clearPatternMatches(seriesId: string): void {\n patternMatches.delete(seriesId);\n ctx?.log.info(`Pattern matches cleared for series: ${seriesId}`);\n },\n \n enableRealtimeDetection(seriesId: string, parameters?: Partial<PatternDetectionParameters>): void {\n realtimeSeries.add(seriesId);\n \n const chart = ctx?.chart;\n if (chart) {\n const targetSeries = chart.getSeries(seriesId);\n if (targetSeries) {\n const data = targetSeries.getData();\n if (data && data.x.length > 0) {\n const points: PatternPoint[] = Array.from(data.x).map((x, i) => ({\n x: x as number,\n y: data.y[i]\n }));\n \n detectPatterns(seriesId, points, parameters);\n }\n }\n }\n \n ctx?.log.info(`Real-time pattern detection enabled for series: ${seriesId}`);\n },\n \n disableRealtimeDetection(seriesId: string): void {\n realtimeSeries.delete(seriesId);\n \n const timer = debounceTimers.get(seriesId);\n if (timer) {\n clearTimeout(timer);\n debounceTimers.delete(seriesId);\n }\n \n ctx?.log.info(`Real-time pattern detection disabled for series: ${seriesId}`);\n },\n \n getStatistics(seriesId?: string) {\n if (seriesId) {\n const matches = patternMatches.get(seriesId) || [];\n const patternsByType: Record<PatternType, number> = {} as any;\n \n for (const match of matches) {\n patternsByType[match.pattern.type] = (patternsByType[match.pattern.type] || 0) + 1;\n }\n \n return {\n totalDetections: matches.length,\n patternsByType,\n averageConfidence: matches.length > 0 ? matches.reduce((sum, m) => sum + m.confidence, 0) / matches.length : 0,\n detectionRate: matches.length / 100\n };\n } else {\n let totalDetections = 0;\n const allPatternsByType: Record<PatternType, number> = {} as any;\n const allConfidences: number[] = [];\n \n for (const matches of patternMatches.values()) {\n totalDetections += matches.length;\n allConfidences.push(...matches.map(m => m.confidence));\n \n for (const match of matches) {\n allPatternsByType[match.pattern.type] = (allPatternsByType[match.pattern.type] || 0) + 1;\n }\n }\n \n return {\n totalDetections,\n patternsByType: allPatternsByType,\n averageConfidence: allConfidences.length > 0 ? allConfidences.reduce((sum, c) => sum + c, 0) / allConfidences.length : 0,\n detectionRate: totalDetections / 100\n };\n }\n },\n \n updateConfig: (newConfig: Partial<PluginPatternRecognitionConfig>) => {\n Object.assign(config, newConfig);\n },\n \n getConfig: () => ({ ...config }),\n \n visualizePatterns(seriesId: string, showTypes?: PatternType[]): void {\n const chart = ctx?.chart;\n if (!chart) return;\n \n const matches = patternMatches.get(seriesId) || [];\n const filteredMatches = showTypes ? matches.filter(m => showTypes.includes(m.pattern.type)) : matches;\n \n api.hidePatterns(seriesId);\n \n for (const match of filteredMatches) {\n const color = config.visualization.colorScheme[match.pattern.type] || '#666666';\n \n for (const segment of match.validation.segments) {\n const lineId = `${seriesId}_pattern_${match.pattern.id}_${match.location.startIndex}`;\n \n chart.addSeries({\n id: lineId,\n type: 'line',\n data: {\n x: new Float32Array([segment.start.x, segment.end.x]),\n y: new Float32Array([segment.start.y, segment.end.y])\n },\n style: {\n color,\n width: config.visualization.lineWidth,\n opacity: config.visualization.opacity,\n lineDash: [5, 5]\n }\n });\n }\n \n if (config.visualization.showLabels) {\n const labelId = `${seriesId}_label_${match.pattern.id}_${match.location.startIndex}`;\n const centerX = (match.location.startPoint.x + match.location.endPoint.x) / 2;\n const centerY = (match.location.startPoint.y + match.location.endPoint.y) / 2;\n \n chart.addAnnotation({\n id: labelId,\n type: 'text',\n text: match.pattern.name,\n x: centerX,\n y: centerY,\n style: {\n color,\n fontSize: 12,\n backgroundColor: 'rgba(255, 255, 255, 0.8)'\n }\n } as any);\n }\n }\n },\n \n hidePatterns(seriesId: string): void {\n const chart = ctx?.chart;\n if (!chart) return;\n \n const matches = patternMatches.get(seriesId) || [];\n \n for (const match of matches) {\n for (let i = 0; i < match.validation.segments.length; i++) {\n const lineId = `${seriesId}_pattern_${match.pattern.id}_${match.location.startIndex}`;\n if (chart.getSeries(lineId)) {\n chart.removeSeries(lineId);\n }\n }\n \n const labelId = `${seriesId}_label_${match.pattern.id}_${match.location.startIndex}`;\n if (chart.getAnnotation(labelId)) {\n chart.removeAnnotation(labelId);\n }\n }\n }\n };\n \n // ============================================\n // Event Handlers\n // ============================================\n \n function handleDataUpdate(context: PluginContext, event: DataUpdateEvent): void {\n if (!config.enableRealtime) return;\n \n const { seriesId } = event;\n \n if (realtimeSeries.has(seriesId)) {\n const timer = debounceTimers.get(seriesId);\n if (timer) {\n clearTimeout(timer);\n }\n \n const newTimer = setTimeout(() => {\n const chart = context.chart;\n if (chart) {\n const series = chart.getSeries(seriesId);\n if (series) {\n const data = series.getData();\n if (data && data.x.length > 0) {\n const points: PatternPoint[] = Array.from(data.x).map((x, i) => ({\n x: x as number,\n y: data.y[i]\n }));\n \n detectPatterns(seriesId, points);\n \n if (config.visualization.showPatterns) {\n api.visualizePatterns(seriesId);\n }\n }\n }\n }\n }, config.debounceTime);\n \n debounceTimers.set(seriesId, newTimer);\n }\n }\n \n // ============================================\n // Plugin Definition\n // ============================================\n \n return {\n manifest: manifestPatternRecognition,\n \n onInit(context: PluginContext) {\n ctx = context;\n \n if (config.customPatterns) {\n for (const customPattern of config.customPatterns) {\n registerCustomPattern(customPattern);\n }\n }\n \n ctx.log.info(`Pattern Recognition plugin initialized with ${registeredPatterns.size} patterns`);\n },\n \n onConfigChange(_context: PluginContext, _newConfig: PluginPatternRecognitionConfig) {\n // Handle config changes\n },\n \n onBeforeRender(_context: PluginContext, _event: BeforeRenderEvent) {\n // Handle pre-render tasks if needed\n },\n \n onDataUpdate: handleDataUpdate,\n \n onDestroy(_context: PluginContext) {\n for (const timer of debounceTimers.values()) {\n clearTimeout(timer);\n }\n debounceTimers.clear();\n \n patternMatches.clear();\n realtimeSeries.clear();\n registeredPatterns.clear();\n },\n \n api\n };\n}\n\nexport default PluginPatternRecognition;\n\nexport type {\n PatternType,\n PatternDefinition,\n PatternPoint,\n PatternSegment,\n PatternValidationResult,\n PatternMeasurements,\n PatternMatch,\n PatternDetectionResult,\n PatternDetectionParameters,\n CustomPatternConfig,\n PluginPatternRecognitionConfig,\n PatternDetectedEvent,\n PatternCompletedEvent,\n PatternFailedEvent,\n PatternRecognitionAPI\n} from './types';\n"],"names":["findPeaksAndValleys","points","peaks","valleys","i","prev","curr","next","calculateSlope","p1","p2","calculatePatternMeasurements","yValues","p","xValues","height","width","slope","validateHeadShoulders","leftShoulder","head","rightShoulder","leftValley","rightValley","headHigherThanShoulders","shouldersApproximatelyEqual","valleyBelowShoulders","segments","keyPoints","measurements","shoulderSymmetry","valleySymmetry","validateDoubleTop","firstTop","secondTop","valley","topsApproximatelyEqual","valleyBelowTops","significantDrop","topEquality","depthRatio","validateDoubleBottom","firstBottom","secondBottom","peak","bottomsApproximatelyEqual","peakAboveBottoms","significantRise","bottomEquality","heightRatio","validateAscendingTriangle","resistanceLevel","resistancePoints","lows","firstLow","lastLow","supportSlope","resistanceFlatness","supportAscending","BUILTIN_PATTERNS","invertedPoints","peak1","peak2","peak3","tolerance","firstHalf","secondHalf","firstSlope","secondSlope","peakSlope","valleySlope","resistance","support","supportPoints","_points","manifestPatternRecognition","DEFAULT_CONFIG","PluginPatternRecognition","userConfig","config","ctx","patternMatches","registeredPatterns","realtimeSeries","debounceTimers","detectPatterns","seriesId","dataPoints","parameters","params","startTime","matches","patternsByType","processedPoints","preprocessData","patternType","pattern","window","validation","match","hasSignificantOverlap","a","b","detectionTime","result","sum","m","sensitivity","point","index","newMatch","existingMatches","existing","overlapStart","overlapSize","newMatchSize","existingMatchSize","registerCustomPattern","customConfig","validateCustomPattern","confidence","errors","sequencePoint","actualPoint","constraints","min","max","api","chart","targetSeries","data","x","timer","totalDetections","allPatternsByType","allConfidences","newConfig","showTypes","filteredMatches","color","segment","lineId","labelId","centerX","centerY","handleDataUpdate","context","event","newTimer","series","customPattern","_context","_newConfig","_event"],"mappings":"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"}
1
+ {"version":3,"file":"pattern-recognition.js","sources":["../../src/plugins/pattern-recognition/patterns.ts","../../src/plugins/pattern-recognition/index.ts"],"sourcesContent":["/**\n * Pattern Recognition Plugin - Pattern Definitions\n * \n * Implements common technical analysis patterns for financial and scientific data.\n * Includes head-shoulders, double tops/bottoms, triangles, and more.\n * \n * @packageDocumentation\n * @module plugins/pattern-recognition\n */\n\nimport type {\n PatternDefinition,\n PatternType,\n PatternPoint,\n PatternValidationResult,\n PatternSegment,\n PatternMeasurements\n} from './types';\n\n// ============================================\n// Utility Functions\n// ============================================\n\nfunction findPeaksAndValleys(points: PatternPoint[]): { peaks: PatternPoint[], valleys: PatternPoint[] } {\n const peaks: PatternPoint[] = [];\n const valleys: PatternPoint[] = [];\n \n for (let i = 1; i < points.length - 1; i++) {\n const prev = points[i - 1];\n const curr = points[i];\n const next = points[i + 1];\n \n // Peak detection\n if (curr.y > prev.y && curr.y > next.y) {\n peaks.push({ ...curr, type: 'peak' });\n }\n // Valley detection\n else if (curr.y < prev.y && curr.y < next.y) {\n valleys.push({ ...curr, type: 'valley' });\n }\n }\n \n return { peaks, valleys };\n}\n\nfunction calculateSlope(p1: PatternPoint, p2: PatternPoint): number {\n return (p2.y - p1.y) / (p2.x - p1.x);\n}\n\nfunction calculatePatternMeasurements(points: PatternPoint[]): PatternMeasurements {\n const yValues = points.map(p => p.y);\n const xValues = points.map(p => p.x);\n \n const height = Math.max(...yValues) - Math.min(...yValues);\n const width = Math.max(...xValues) - Math.min(...xValues);\n const slope = calculateSlope(points[0], points[points.length - 1]);\n \n return {\n height,\n width,\n slope,\n volumeProfile: {\n increasing: 0.4, // Mock values\n decreasing: 0.3,\n neutral: 0.3\n },\n breakoutTarget: Math.max(...yValues) + height * 0.8,\n stopLoss: Math.min(...yValues) - height * 0.2\n };\n}\n\n// ============================================\n// Head and Shoulders Pattern\n// ============================================\n\nfunction validateHeadShoulders(points: PatternPoint[]): PatternValidationResult {\n if (points.length < 5) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient points for head-shoulders pattern'] };\n }\n \n const { peaks, valleys } = findPeaksAndValleys(points);\n \n // Need at least 3 peaks and 2 valleys for head-shoulders\n if (peaks.length < 3 || valleys.length < 2) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient peaks/valleys'] };\n }\n \n // Find left shoulder, head, and right shoulder\n const leftShoulder = peaks[0];\n const head = peaks[1];\n const rightShoulder = peaks[2];\n \n // Find the valleys between shoulders and head\n const leftValley = valleys[0];\n const rightValley = valleys[1];\n \n // Validate pattern structure\n const headHigherThanShoulders = head.y > leftShoulder.y && head.y > rightShoulder.y;\n const shouldersApproximatelyEqual = Math.abs(leftShoulder.y - rightShoulder.y) / leftShoulder.y < 0.1;\n const valleyBelowShoulders = leftValley.y < leftShoulder.y && rightValley.y < rightShoulder.y;\n \n if (!headHigherThanShoulders || !shouldersApproximatelyEqual || !valleyBelowShoulders) {\n return { \n valid: false, \n confidence: 0, \n segments: [], \n keyPoints: [], \n errors: ['Invalid head-shoulders structure'] \n };\n }\n \n // Create segments\n const segments: PatternSegment[] = [\n { start: leftShoulder, end: leftValley, type: 'resistance', strength: 0.8 },\n { start: leftValley, end: head, type: 'support', strength: 0.7 },\n { start: head, end: rightValley, type: 'resistance', strength: 0.8 },\n { start: rightValley, end: rightShoulder, type: 'support', strength: 0.7 }\n ];\n \n const keyPoints = [leftShoulder, leftValley, head, rightValley, rightShoulder];\n const measurements = calculatePatternMeasurements(points);\n \n // Calculate confidence based on pattern symmetry\n const shoulderSymmetry = 1 - Math.abs(leftShoulder.y - rightShoulder.y) / head.y;\n const valleySymmetry = 1 - Math.abs(leftValley.y - rightValley.y) / head.y;\n const confidence = (shoulderSymmetry + valleySymmetry) / 2;\n \n return {\n valid: true,\n confidence,\n segments,\n keyPoints,\n measurements\n };\n}\n\n// ============================================\n// Double Top/Bottom Pattern\n// ============================================\n\nfunction validateDoubleTop(points: PatternPoint[]): PatternValidationResult {\n if (points.length < 4) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient points for double top'] };\n }\n \n const { peaks, valleys } = findPeaksAndValleys(points);\n \n if (peaks.length < 2 || valleys.length < 1) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient peaks/valleys'] };\n }\n \n const firstTop = peaks[0];\n const secondTop = peaks[1];\n const valley = valleys[0];\n \n // Validate double top structure\n const topsApproximatelyEqual = Math.abs(firstTop.y - secondTop.y) / firstTop.y < 0.05;\n const valleyBelowTops = valley.y < firstTop.y && valley.y < secondTop.y;\n const significantDrop = (firstTop.y - valley.y) / firstTop.y > 0.1;\n \n if (!topsApproximatelyEqual || !valleyBelowTops || !significantDrop) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Invalid double top structure'] };\n }\n \n const segments: PatternSegment[] = [\n { start: firstTop, end: valley, type: 'resistance', strength: 0.9 },\n { start: valley, end: secondTop, type: 'support', strength: 0.8 },\n { start: firstTop, end: secondTop, type: 'resistance', strength: 0.9 }\n ];\n \n const keyPoints = [firstTop, valley, secondTop];\n const measurements = calculatePatternMeasurements(points);\n \n // Confidence based on top equality and depth of valley\n const topEquality = 1 - Math.abs(firstTop.y - secondTop.y) / firstTop.y;\n const depthRatio = (firstTop.y - valley.y) / firstTop.y;\n const confidence = (topEquality + Math.min(depthRatio * 2, 1)) / 2;\n \n return {\n valid: true,\n confidence,\n segments,\n keyPoints,\n measurements\n };\n}\n\nfunction validateDoubleBottom(points: PatternPoint[]): PatternValidationResult {\n if (points.length < 4) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient points for double bottom'] };\n }\n \n const { peaks, valleys } = findPeaksAndValleys(points);\n \n if (valleys.length < 2 || peaks.length < 1) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient peaks/valleys'] };\n }\n \n const firstBottom = valleys[0];\n const secondBottom = valleys[1];\n const peak = peaks[0];\n \n // Validate double bottom structure\n const bottomsApproximatelyEqual = Math.abs(firstBottom.y - secondBottom.y) / firstBottom.y < 0.05;\n const peakAboveBottoms = peak.y > firstBottom.y && peak.y > secondBottom.y;\n const significantRise = (peak.y - firstBottom.y) / firstBottom.y > 0.1;\n \n if (!bottomsApproximatelyEqual || !peakAboveBottoms || !significantRise) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Invalid double bottom structure'] };\n }\n \n const segments: PatternSegment[] = [\n { start: firstBottom, end: peak, type: 'support', strength: 0.9 },\n { start: peak, end: secondBottom, type: 'resistance', strength: 0.8 },\n { start: firstBottom, end: secondBottom, type: 'support', strength: 0.9 }\n ];\n \n const keyPoints = [firstBottom, peak, secondBottom];\n const measurements = calculatePatternMeasurements(points);\n \n // Confidence based on bottom equality and height of peak\n const bottomEquality = 1 - Math.abs(firstBottom.y - secondBottom.y) / firstBottom.y;\n const heightRatio = (peak.y - firstBottom.y) / firstBottom.y;\n const confidence = (bottomEquality + Math.min(heightRatio * 2, 1)) / 2;\n \n return {\n valid: true,\n confidence,\n segments,\n keyPoints,\n measurements\n };\n}\n\n// ============================================\n// Triangle Patterns\n// ============================================\n\nfunction validateAscendingTriangle(points: PatternPoint[]): PatternValidationResult {\n if (points.length < 4) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient points for ascending triangle'] };\n }\n \n // Find horizontal resistance line and ascending support line\n const yValues = points.map(p => p.y);\n const resistanceLevel = Math.max(...yValues);\n const resistancePoints = points.filter(p => Math.abs(p.y - resistanceLevel) / resistanceLevel < 0.02);\n \n if (resistancePoints.length < 2) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient resistance points'] };\n }\n \n // Check for ascending support (higher lows)\n const lows = points.filter((p, i) => i === 0 || p.y < points[i - 1].y);\n if (lows.length < 2) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient low points'] };\n }\n \n const firstLow = lows[0];\n const lastLow = lows[lows.length - 1];\n const supportSlope = calculateSlope(firstLow, lastLow);\n \n // Support should be ascending (positive slope)\n if (supportSlope <= 0) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Support not ascending'] };\n }\n \n const segments: PatternSegment[] = [\n { start: resistancePoints[0], end: resistancePoints[resistancePoints.length - 1], type: 'resistance', strength: 0.8 },\n { start: firstLow, end: lastLow, type: 'support', strength: 0.7 }\n ];\n \n const keyPoints = [...resistancePoints.slice(0, 2), firstLow, lastLow];\n const measurements = calculatePatternMeasurements(points);\n \n // Confidence based on horizontal resistance and ascending support\n const resistanceFlatness = 1 - Math.abs(resistancePoints[0].y - resistancePoints[resistancePoints.length - 1].y) / resistanceLevel;\n const supportAscending = Math.min(supportSlope / 0.01, 1); // Normalize slope\n const confidence = (resistanceFlatness + supportAscending) / 2;\n \n return {\n valid: true,\n confidence,\n segments,\n keyPoints,\n measurements\n };\n}\n\n// ============================================\n// Pattern Definitions Registry\n// ============================================\n\nexport const BUILTIN_PATTERNS: Record<PatternType, PatternDefinition> = {\n 'head-shoulders': {\n id: 'head-shoulders',\n type: 'head-shoulders',\n name: 'Head and Shoulders',\n description: 'Bearish reversal pattern with three peaks',\n minPoints: 5,\n maxPoints: 7,\n validator: validateHeadShoulders\n },\n \n 'inverse-head-shoulders': {\n id: 'inverse-head-shoulders',\n type: 'inverse-head-shoulders',\n name: 'Inverse Head and Shoulders',\n description: 'Bullish reversal pattern with three valleys',\n minPoints: 5,\n maxPoints: 7,\n validator: (points) => {\n // Invert points and validate as regular head-shoulders\n const invertedPoints = points.map(p => ({ ...p, y: -p.y }));\n const result = validateHeadShoulders(invertedPoints);\n return result;\n }\n },\n \n 'double-top': {\n id: 'double-top',\n type: 'double-top',\n name: 'Double Top',\n description: 'Bearish reversal pattern with two equal peaks',\n minPoints: 4,\n maxPoints: 6,\n validator: validateDoubleTop\n },\n \n 'double-bottom': {\n id: 'double-bottom',\n type: 'double-bottom',\n name: 'Double Bottom',\n description: 'Bullish reversal pattern with two equal valleys',\n minPoints: 4,\n maxPoints: 6,\n validator: validateDoubleBottom\n },\n \n 'triple-top': {\n id: 'triple-top',\n type: 'triple-top',\n name: 'Triple Top',\n description: 'Bearish reversal pattern with three equal peaks',\n minPoints: 5,\n maxPoints: 7,\n validator: (points) => {\n if (points.length < 5) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient points'] };\n }\n \n const { peaks } = findPeaksAndValleys(points);\n if (peaks.length < 3) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Need at least 3 peaks'] };\n }\n \n const peak1 = peaks[0].y;\n const peak2 = peaks[1].y;\n const peak3 = peaks[2].y;\n \n const tolerance = 0.05;\n const peaksEqual = Math.abs(peak1 - peak2) / peak1 < tolerance && Math.abs(peak2 - peak3) / peak2 < tolerance;\n \n if (!peaksEqual) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Peaks not equal'] };\n }\n \n const segments: PatternSegment[] = [\n { start: peaks[0], end: peaks[1], type: 'resistance', strength: 0.8 },\n { start: peaks[1], end: peaks[2], type: 'resistance', strength: 0.8 }\n ];\n \n const keyPoints = [peaks[0], peaks[1], peaks[2]];\n const measurements = calculatePatternMeasurements(points);\n \n return {\n valid: true,\n confidence: 0.8,\n segments,\n keyPoints,\n measurements\n };\n }\n },\n \n 'triple-bottom': {\n id: 'triple-bottom',\n type: 'triple-bottom',\n name: 'Triple Bottom',\n description: 'Bullish reversal pattern with three equal valleys',\n minPoints: 5,\n maxPoints: 7,\n validator: (points) => {\n const invertedPoints = points.map(p => ({ ...p, y: -p.y }));\n return BUILTIN_PATTERNS['triple-top'].validator(invertedPoints);\n }\n },\n \n 'ascending-triangle': {\n id: 'ascending-triangle',\n type: 'ascending-triangle',\n name: 'Ascending Triangle',\n description: 'Continuation pattern with horizontal resistance and ascending support',\n minPoints: 4,\n maxPoints: 8,\n validator: validateAscendingTriangle\n },\n \n 'descending-triangle': {\n id: 'descending-triangle',\n type: 'descending-triangle',\n name: 'Descending Triangle',\n description: 'Continuation pattern with horizontal support and descending resistance',\n minPoints: 4,\n maxPoints: 8,\n validator: (points) => {\n // Invert points and validate as ascending triangle\n const invertedPoints = points.map(p => ({ ...p, y: -p.y }));\n const result = validateAscendingTriangle(invertedPoints);\n return result;\n }\n },\n \n 'symmetrical-triangle': {\n id: 'symmetrical-triangle',\n type: 'symmetrical-triangle',\n name: 'Symmetrical Triangle',\n description: 'Continuation pattern with converging support and resistance',\n minPoints: 4,\n maxPoints: 8,\n validator: (points) => {\n // Simplified validation for symmetrical triangle\n if (points.length < 4) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient points'] };\n }\n \n // Check for converging trendlines\n const firstHalf = points.slice(0, Math.floor(points.length / 2));\n const secondHalf = points.slice(Math.floor(points.length / 2));\n \n const firstSlope = calculateSlope(firstHalf[0], firstHalf[firstHalf.length - 1]);\n const secondSlope = calculateSlope(secondHalf[0], secondHalf[secondHalf.length - 1]);\n \n // Slopes should be converging (opposite signs)\n const converging = (firstSlope > 0 && secondSlope < 0) || (firstSlope < 0 && secondSlope > 0);\n \n if (!converging) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Lines not converging'] };\n }\n \n const segments: PatternSegment[] = [\n { start: firstHalf[0], end: firstHalf[firstHalf.length - 1], type: 'trendline', strength: 0.7 },\n { start: secondHalf[0], end: secondHalf[secondHalf.length - 1], type: 'trendline', strength: 0.7 }\n ];\n \n const keyPoints = [firstHalf[0], firstHalf[firstHalf.length - 1], secondHalf[0], secondHalf[secondHalf.length - 1]];\n const measurements = calculatePatternMeasurements(points);\n \n return {\n valid: true,\n confidence: 0.7,\n segments,\n keyPoints,\n measurements\n };\n }\n },\n \n 'rising-wedge': {\n id: 'rising-wedge',\n type: 'rising-wedge',\n name: 'Rising Wedge',\n description: 'Bearish reversal pattern with two converging upward lines',\n minPoints: 4,\n maxPoints: 8,\n validator: (points) => {\n // Simplified rising wedge validation\n if (points.length < 4) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient points'] };\n }\n \n const { peaks, valleys } = findPeaksAndValleys(points);\n if (peaks.length < 2 || valleys.length < 2) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient peaks/valleys'] };\n }\n \n const peakSlope = calculateSlope(peaks[0], peaks[peaks.length - 1]);\n const valleySlope = calculateSlope(valleys[0], valleys[valleys.length - 1]);\n \n // Both lines should be rising but converging (valley slope > peak slope)\n const wedgePattern = peakSlope > 0 && valleySlope > 0 && valleySlope > peakSlope;\n \n if (!wedgePattern) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Not a rising wedge pattern'] };\n }\n \n const segments: PatternSegment[] = [\n { start: peaks[0], end: peaks[peaks.length - 1], type: 'resistance', strength: 0.8 },\n { start: valleys[0], end: valleys[valleys.length - 1], type: 'support', strength: 0.8 }\n ];\n \n const keyPoints = [peaks[0], peaks[peaks.length - 1], valleys[0], valleys[valleys.length - 1]];\n const measurements = calculatePatternMeasurements(points);\n \n return {\n valid: true,\n confidence: 0.75,\n segments,\n keyPoints,\n measurements\n };\n }\n },\n \n 'falling-wedge': {\n id: 'falling-wedge',\n type: 'falling-wedge',\n name: 'Falling Wedge',\n description: 'Bullish reversal pattern with two converging downward lines',\n minPoints: 4,\n maxPoints: 8,\n validator: (points) => {\n // Invert points and validate as rising wedge\n const invertedPoints = points.map(p => ({ ...p, y: -p.y }));\n const result = BUILTIN_PATTERNS['rising-wedge'].validator(invertedPoints);\n return result;\n }\n },\n \n 'rectangle': {\n id: 'rectangle',\n type: 'rectangle',\n name: 'Rectangle',\n description: 'Continuation pattern with horizontal support and resistance',\n minPoints: 4,\n maxPoints: 10,\n validator: (points) => {\n if (points.length < 4) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient points'] };\n }\n \n const yValues = points.map(p => p.y);\n const resistance = Math.max(...yValues);\n const support = Math.min(...yValues);\n \n // Check for relatively flat top and bottom\n const resistancePoints = points.filter(p => Math.abs(p.y - resistance) / resistance < 0.05);\n const supportPoints = points.filter(p => Math.abs(p.y - support) / support < 0.05);\n \n if (resistancePoints.length < 2 || supportPoints.length < 2) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient horizontal lines'] };\n }\n \n const segments: PatternSegment[] = [\n { start: resistancePoints[0], end: resistancePoints[resistancePoints.length - 1], type: 'resistance', strength: 0.9 },\n { start: supportPoints[0], end: supportPoints[supportPoints.length - 1], type: 'support', strength: 0.9 }\n ];\n \n const keyPoints = [resistancePoints[0], resistancePoints[resistancePoints.length - 1], supportPoints[0], supportPoints[supportPoints.length - 1]];\n const measurements = calculatePatternMeasurements(points);\n \n return {\n valid: true,\n confidence: 0.8,\n segments,\n keyPoints,\n measurements\n };\n }\n },\n \n 'flag': {\n id: 'flag',\n type: 'flag',\n name: 'Flag',\n description: 'Short-term continuation pattern after strong move',\n minPoints: 3,\n maxPoints: 6,\n validator: (points) => {\n // Simplified flag validation\n if (points.length < 3) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient points'] };\n }\n \n const slope = calculateSlope(points[0], points[points.length - 1]);\n \n // Flag should be relatively horizontal (small slope)\n const horizontal = Math.abs(slope) < 0.01;\n \n if (!horizontal) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Not horizontal enough'] };\n }\n \n const segments: PatternSegment[] = [\n { start: points[0], end: points[points.length - 1], type: 'trendline', strength: 0.6 }\n ];\n \n const keyPoints = [points[0], points[points.length - 1]];\n const measurements = calculatePatternMeasurements(points);\n \n return {\n valid: true,\n confidence: 0.6,\n segments,\n keyPoints,\n measurements\n };\n }\n },\n \n 'pennant': {\n id: 'pennant',\n type: 'pennant',\n name: 'Pennant',\n description: 'Short-term continuation pattern with converging lines',\n minPoints: 3,\n maxPoints: 5,\n validator: (points) => {\n // Similar to symmetrical triangle but smaller\n return BUILTIN_PATTERNS['symmetrical-triangle'].validator(points);\n }\n },\n \n 'custom': {\n id: 'custom',\n type: 'custom',\n name: 'Custom Pattern',\n description: 'User-defined pattern',\n minPoints: 3,\n validator: (_points) => {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Custom pattern not implemented'] };\n }\n }\n};","/**\n * Pattern Recognition Plugin - Main Implementation\n * \n * Provides technical pattern recognition for financial and scientific data.\n * Supports common chart patterns and custom pattern definitions.\n * \n * @example\n * ```typescript\n * import { PluginPatternRecognition } from 'velo-plot/plugins/pattern-recognition';\n * \n * chart.use(PluginPatternRecognition({\n * defaultParameters: {\n * minConfidence: 0.7,\n * patternTypes: ['head-shoulders', 'double-top', 'ascending-triangle'],\n * sensitivity: 0.5\n * },\n * enableRealtime: true,\n * visualization: {\n * showPatterns: true,\n * showLabels: true,\n * colorScheme: {\n * 'head-shoulders': '#ff6b6b',\n * 'double-top': '#4ecdc4',\n * 'ascending-triangle': '#45b7d1'\n * }\n * }\n * }));\n * \n * // Detect patterns\n * const result = await chart.patterns.detectPatterns('series1', dataPoints);\n * console.log(`Found ${result.matches.length} patterns`);\n * \n * // Enable real-time detection\n * chart.patterns.enableRealtimeDetection('series1');\n * ```\n * \n * @packageDocumentation\n * @module plugins/pattern-recognition\n */\n\nimport type { \n PluginManifest, \n ChartPlugin, \n PluginContext,\n BeforeRenderEvent,\n DataUpdateEvent\n} from '../types';\n\nimport type {\n PluginPatternRecognitionConfig,\n PatternRecognitionAPI,\n PatternDetectionResult,\n PatternMatch,\n PatternPoint,\n PatternDetectionParameters,\n PatternType,\n CustomPatternConfig,\n PatternDefinition,\n PatternValidationResult,\n PatternDetectedEvent,\n PatternSignalEvent\n} from './types';\n\nimport { BUILTIN_PATTERNS } from './patterns';\n\n// ============================================\n// Plugin Manifest\n// ============================================\n\nconst manifestPatternRecognition: PluginManifest = {\n name: 'pattern-recognition',\n version: '1.0.0',\n description: 'Technical pattern recognition for financial and scientific data',\n author: 'Sci Plot Team',\n provides: ['patterns', 'technical-analysis', 'chart-patterns']\n};\n\n// ============================================\n// Default Configuration\n// ============================================\n\nconst DEFAULT_CONFIG: Required<PluginPatternRecognitionConfig> = {\n defaultParameters: {\n minConfidence: 0.7,\n maxPatterns: 10,\n patternTypes: ['head-shoulders', 'double-top', 'double-bottom', 'ascending-triangle', 'descending-triangle'],\n sensitivity: 0.5,\n minPatternSize: 5,\n maxPatternSize: 50,\n overlapTolerance: 0.3,\n enableVolumeConfirmation: false,\n enableTrendConfirmation: true\n },\n customPatterns: [],\n enableRealtime: false,\n debounceTime: 500,\n maxStoredPatterns: 100,\n visualization: {\n showPatterns: true,\n showLabels: true,\n showTargets: true,\n colorScheme: {\n 'head-shoulders': '#ff6b6b',\n 'inverse-head-shoulders': '#4ecdc4',\n 'double-top': '#ff9f43',\n 'double-bottom': '#00d2d3',\n 'triple-top': '#ff6b6b',\n 'triple-bottom': '#4ecdc4',\n 'ascending-triangle': '#45b7d1',\n 'descending-triangle': '#f39c12',\n 'symmetrical-triangle': '#9b59b6',\n 'rising-wedge': '#e74c3c',\n 'falling-wedge': '#27ae60',\n 'rectangle': '#34495e',\n 'flag': '#f1c40f',\n 'pennant': '#e67e22',\n 'custom': '#95a5a6'\n },\n opacity: 0.7,\n lineWidth: 2\n },\n notifications: {\n enableAlerts: false,\n minAlertConfidence: 0.8,\n alertTypes: ['head-shoulders', 'double-top', 'double-bottom']\n }\n};\n\n// ============================================\n// Pattern Recognition Plugin Implementation\n// ============================================\n\nexport function PluginPatternRecognition(\n userConfig: Partial<PluginPatternRecognitionConfig> = {}\n): ChartPlugin<PluginPatternRecognitionConfig> {\n const config = { ...DEFAULT_CONFIG, ...userConfig };\n let ctx: PluginContext | null = null;\n \n // Pattern storage\n const patternMatches = new Map<string, PatternMatch[]>();\n const registeredPatterns = new Map<PatternType, PatternDefinition>(Object.entries(BUILTIN_PATTERNS) as [PatternType, PatternDefinition][]);\n // Named custom patterns, keyed by their unique id (task 3.6).\n const customPatterns = new Map<string, PatternDefinition>();\n const realtimeSeries = new Set<string>();\n const debounceTimers = new Map<string, any>();\n\n /**\n * Maps a pattern type to the directional trading bias it implies, so the\n * signal can be consumed by the Stage 2 alert system (task 3.8).\n */\n const SIGNAL_DIRECTION: Record<PatternType, 'bullish' | 'bearish' | 'neutral'> = {\n 'head-shoulders': 'bearish',\n 'inverse-head-shoulders': 'bullish',\n 'double-top': 'bearish',\n 'double-bottom': 'bullish',\n 'triple-top': 'bearish',\n 'triple-bottom': 'bullish',\n 'ascending-triangle': 'bullish',\n 'descending-triangle': 'bearish',\n 'symmetrical-triangle': 'neutral',\n 'rising-wedge': 'bearish',\n 'falling-wedge': 'bullish',\n 'rectangle': 'neutral',\n 'flag': 'neutral',\n 'pennant': 'neutral',\n 'custom': 'neutral',\n };\n\n /**\n * Scan a single pattern definition over the processed points with a sliding\n * window, pushing valid matches. Returns true when maxPatterns is reached.\n */\n function scanPattern(\n pattern: PatternDefinition,\n patternKey: PatternType | string,\n processedPoints: PatternPoint[],\n params: PatternDetectionParameters,\n seriesId: string,\n matches: PatternMatch[],\n patternsByType: Record<string, number>\n ): boolean {\n for (let i = params.minPatternSize; i <= Math.min(processedPoints.length, params.maxPatternSize); i++) {\n const window = processedPoints.slice(Math.max(0, i - params.maxPatternSize), i);\n if (window.length < pattern.minPoints) continue;\n if (pattern.maxPoints && window.length > pattern.maxPoints) continue;\n\n const validation = pattern.validator(window);\n if (validation.valid && validation.confidence >= params.minConfidence) {\n const match: PatternMatch = {\n pattern,\n confidence: validation.confidence,\n location: {\n startIndex: Math.max(0, i - params.maxPatternSize),\n endIndex: i,\n startPoint: window[0],\n endPoint: window[window.length - 1],\n },\n validation,\n timestamp: Date.now(),\n seriesId,\n };\n\n if (!hasSignificantOverlap(match, matches, params.overlapTolerance)) {\n matches.push(match);\n patternsByType[patternKey] = (patternsByType[patternKey] || 0) + 1;\n if (matches.length >= params.maxPatterns!) return true;\n }\n }\n }\n return false;\n }\n\n /** Emit a normalized trading signal for a detected pattern. */\n function emitSignal(match: PatternMatch): void {\n const direction = SIGNAL_DIRECTION[match.pattern.type] ?? 'neutral';\n ctx?.events.emit('pattern:signal', {\n seriesId: match.seriesId,\n patternType: match.pattern.type,\n patternName: match.pattern.name,\n direction,\n confidence: match.confidence,\n price: match.location.endPoint.y,\n x: match.location.endPoint.x,\n target: match.validation.measurements?.breakoutTarget,\n stopLoss: match.validation.measurements?.stopLoss,\n timestamp: match.timestamp,\n });\n }\n \n // ============================================\n // Pattern Detection Engine\n // ============================================\n \n async function detectPatterns(\n seriesId: string, \n dataPoints: PatternPoint[], \n parameters?: Partial<PatternDetectionParameters>\n ): Promise<PatternDetectionResult> {\n const params = { ...config.defaultParameters, ...parameters };\n const startTime = performance.now();\n \n const matches: PatternMatch[] = [];\n const patternsByType: Record<PatternType, number> = {} as any;\n \n // Preprocess data - find peaks and valleys\n const processedPoints = preprocessData(dataPoints, params.sensitivity);\n \n // Check each requested built-in pattern type\n let reachedLimit = false;\n for (const patternType of params.patternTypes) {\n const pattern = registeredPatterns.get(patternType);\n if (!pattern) continue;\n if (scanPattern(pattern, patternType, processedPoints, params, seriesId, matches, patternsByType)) {\n reachedLimit = true;\n break;\n }\n }\n\n // Also scan named custom patterns when the caller opts into 'custom'\n // (or provides no explicit list). Each custom pattern is keyed by its id.\n if (!reachedLimit && customPatterns.size > 0 && params.patternTypes.includes('custom')) {\n for (const [id, pattern] of customPatterns) {\n if (scanPattern(pattern, id, processedPoints, params, seriesId, matches, patternsByType)) {\n break;\n }\n }\n }\n \n // Sort by confidence\n matches.sort((a, b) => b.confidence - a.confidence);\n \n // Store matches\n patternMatches.set(seriesId, matches);\n \n const detectionTime = performance.now() - startTime;\n \n // Emit events for high-confidence patterns\n for (const match of matches) {\n // Trading signal bridge (task 3.8): every match at or above the alert\n // threshold emits a normalized directional signal.\n if (match.confidence >= config.notifications.minAlertConfidence) {\n emitSignal(match);\n }\n if (match.confidence >= config.notifications.minAlertConfidence &&\n config.notifications.alertTypes.includes(match.pattern.type)) {\n ctx?.events.emit('pattern:detected', {\n match,\n seriesId,\n timestamp: Date.now()\n } as PatternDetectedEvent);\n }\n }\n \n const result: PatternDetectionResult = {\n matches,\n summary: {\n totalPatterns: matches.length,\n patternsByType,\n averageConfidence: matches.length > 0 ? matches.reduce((sum, m) => sum + m.confidence, 0) / matches.length : 0,\n detectionTime\n },\n processedPoints: processedPoints.length,\n parameters: params\n };\n \n ctx?.log.info(`Pattern detection completed for ${seriesId}: ${matches.length} patterns found`);\n \n return result;\n }\n \n function preprocessData(dataPoints: PatternPoint[], sensitivity: number): PatternPoint[] {\n return dataPoints.filter((point, index) => {\n if (index === 0 || index === dataPoints.length - 1) return true;\n \n const prev = dataPoints[index - 1];\n \n const priceChange = Math.abs(point.y - prev.y) / prev.y;\n return priceChange >= sensitivity * 0.01;\n });\n }\n \n function hasSignificantOverlap(newMatch: PatternMatch, existingMatches: PatternMatch[], tolerance: number): boolean {\n for (const existing of existingMatches) {\n const overlapStart = Math.max(newMatch.location.startIndex, existing.location.startIndex);\n const overlapEnd = Math.min(newMatch.location.endIndex, existing.location.endIndex);\n const overlapSize = overlapEnd - overlapStart;\n \n const newMatchSize = newMatch.location.endIndex - newMatch.location.startIndex;\n const existingMatchSize = existing.location.endIndex - existing.location.startIndex;\n \n const overlapRatio = overlapSize / Math.min(newMatchSize, existingMatchSize);\n \n if (overlapRatio > tolerance) {\n return true;\n }\n }\n return false;\n }\n \n // ============================================\n // Custom Pattern Registration\n // ============================================\n \n function registerCustomPattern(customConfig: CustomPatternConfig): void {\n const pattern: PatternDefinition = {\n id: customConfig.id,\n type: 'custom',\n name: customConfig.name,\n minPoints: customConfig.pointSequence.length,\n maxPoints: customConfig.pointSequence.length,\n validator: (points) => validateCustomPattern(points, customConfig)\n };\n\n customPatterns.set(customConfig.id, pattern);\n ctx?.log.info(`Custom pattern registered: ${customConfig.id}`);\n }\n\n /**\n * Register a named custom pattern (task 3.6).\n *\n * The template can be either a full {@link PatternDefinition} (with its own\n * `validator`) or a declarative {@link CustomPatternConfig}. Multiple named\n * patterns coexist because each is stored under its own id.\n *\n * @example\n * chart.patterns.register('my-spike', {\n * name: 'Volatility Spike',\n * minPoints: 3,\n * validator: (pts) => ({ valid: true, confidence: 1, segments: [], keyPoints: pts })\n * });\n */\n function register(\n id: string,\n template: (Partial<PatternDefinition> & { validator: PatternDefinition['validator'] }) | CustomPatternConfig\n ): void {\n if ('pointSequence' in template) {\n registerCustomPattern({ ...(template as CustomPatternConfig), id });\n return;\n }\n\n const def = template as Partial<PatternDefinition> & { validator: PatternDefinition['validator'] };\n if (typeof def.validator !== 'function') {\n ctx?.log.error(`Cannot register pattern '${id}': a validator function is required`);\n return;\n }\n const pattern: PatternDefinition = {\n id,\n type: 'custom',\n name: def.name ?? id,\n description: def.description,\n minPoints: def.minPoints ?? 3,\n maxPoints: def.maxPoints,\n validator: def.validator,\n confidenceCalculator: def.confidenceCalculator,\n };\n customPatterns.set(id, pattern);\n ctx?.log.info(`Custom pattern registered: ${id}`);\n }\n\n /** Remove a previously registered custom pattern. */\n function unregister(id: string): boolean {\n const removed = customPatterns.delete(id);\n if (removed) ctx?.log.info(`Custom pattern removed: ${id}`);\n return removed;\n }\n \n function validateCustomPattern(points: PatternPoint[], config: CustomPatternConfig): PatternValidationResult {\n if (points.length < config.pointSequence.length) {\n return { valid: false, confidence: 0, segments: [], keyPoints: [], errors: ['Insufficient points'] };\n }\n \n let confidence = 1.0;\n const errors: string[] = [];\n \n for (let i = 0; i < config.pointSequence.length; i++) {\n const sequencePoint = config.pointSequence[i];\n const actualPoint = points[i];\n \n if (sequencePoint.constraints) {\n const constraints = sequencePoint.constraints;\n \n if (constraints.higherThanPrevious && i > 0) {\n if (actualPoint.y <= points[i - 1].y) {\n confidence *= 0.8;\n errors.push(`Point ${i} not higher than previous`);\n }\n }\n \n if (constraints.lowerThanPrevious && i > 0) {\n if (actualPoint.y >= points[i - 1].y) {\n confidence *= 0.8;\n errors.push(`Point ${i} not lower than previous`);\n }\n }\n \n if (constraints.withinRange) {\n const [min, max] = constraints.withinRange;\n if (actualPoint.y < min || actualPoint.y > max) {\n confidence *= 0.7;\n errors.push(`Point ${i} not within range [${min}, ${max}]`);\n }\n }\n }\n }\n \n return {\n valid: confidence >= 0.5,\n confidence,\n segments: [],\n keyPoints: points,\n errors: errors.length > 0 ? errors : undefined\n };\n }\n \n // ============================================\n // API Implementation\n // ============================================\n \n const api: PatternRecognitionAPI & Record<string, unknown> = {\n detectPatterns,\n \n registerCustomPattern,\n\n register,\n\n unregister,\n\n onSignal(handler: (signal: PatternSignalEvent) => void): () => void {\n return ctx?.events.onPlugin('pattern:signal', (data) => handler(data as PatternSignalEvent)) ?? (() => {});\n },\n \n getRegisteredPatterns(): PatternDefinition[] {\n return [...registeredPatterns.values(), ...customPatterns.values()];\n },\n \n getPatternMatches(seriesId: string): PatternMatch[] {\n return patternMatches.get(seriesId) || [];\n },\n \n clearPatternMatches(seriesId: string): void {\n patternMatches.delete(seriesId);\n ctx?.log.info(`Pattern matches cleared for series: ${seriesId}`);\n },\n \n enableRealtimeDetection(seriesId: string, parameters?: Partial<PatternDetectionParameters>): void {\n realtimeSeries.add(seriesId);\n \n const chart = ctx?.chart;\n if (chart) {\n const targetSeries = chart.getSeries(seriesId);\n if (targetSeries) {\n const data = targetSeries.getData();\n if (data && data.x.length > 0) {\n const points: PatternPoint[] = Array.from(data.x).map((x, i) => ({\n x: x as number,\n y: data.y[i]\n }));\n \n detectPatterns(seriesId, points, parameters);\n }\n }\n }\n \n ctx?.log.info(`Real-time pattern detection enabled for series: ${seriesId}`);\n },\n \n disableRealtimeDetection(seriesId: string): void {\n realtimeSeries.delete(seriesId);\n \n const timer = debounceTimers.get(seriesId);\n if (timer) {\n clearTimeout(timer);\n debounceTimers.delete(seriesId);\n }\n \n ctx?.log.info(`Real-time pattern detection disabled for series: ${seriesId}`);\n },\n \n getStatistics(seriesId?: string) {\n if (seriesId) {\n const matches = patternMatches.get(seriesId) || [];\n const patternsByType: Record<PatternType, number> = {} as any;\n \n for (const match of matches) {\n patternsByType[match.pattern.type] = (patternsByType[match.pattern.type] || 0) + 1;\n }\n \n return {\n totalDetections: matches.length,\n patternsByType,\n averageConfidence: matches.length > 0 ? matches.reduce((sum, m) => sum + m.confidence, 0) / matches.length : 0,\n detectionRate: matches.length / 100\n };\n } else {\n let totalDetections = 0;\n const allPatternsByType: Record<PatternType, number> = {} as any;\n const allConfidences: number[] = [];\n \n for (const matches of patternMatches.values()) {\n totalDetections += matches.length;\n allConfidences.push(...matches.map(m => m.confidence));\n \n for (const match of matches) {\n allPatternsByType[match.pattern.type] = (allPatternsByType[match.pattern.type] || 0) + 1;\n }\n }\n \n return {\n totalDetections,\n patternsByType: allPatternsByType,\n averageConfidence: allConfidences.length > 0 ? allConfidences.reduce((sum, c) => sum + c, 0) / allConfidences.length : 0,\n detectionRate: totalDetections / 100\n };\n }\n },\n \n updateConfig: (newConfig: Partial<PluginPatternRecognitionConfig>) => {\n Object.assign(config, newConfig);\n },\n \n getConfig: () => ({ ...config }),\n \n visualizePatterns(seriesId: string, showTypes?: PatternType[]): void {\n const chart = ctx?.chart;\n if (!chart) return;\n \n const matches = patternMatches.get(seriesId) || [];\n const filteredMatches = showTypes ? matches.filter(m => showTypes.includes(m.pattern.type)) : matches;\n \n api.hidePatterns(seriesId);\n \n for (const match of filteredMatches) {\n const color = config.visualization.colorScheme[match.pattern.type] || '#666666';\n \n for (const segment of match.validation.segments) {\n const lineId = `${seriesId}_pattern_${match.pattern.id}_${match.location.startIndex}`;\n \n chart.addSeries({\n id: lineId,\n type: 'line',\n data: {\n x: new Float32Array([segment.start.x, segment.end.x]),\n y: new Float32Array([segment.start.y, segment.end.y])\n },\n style: {\n color,\n width: config.visualization.lineWidth,\n opacity: config.visualization.opacity,\n lineDash: [5, 5]\n }\n });\n }\n \n if (config.visualization.showLabels) {\n const labelId = `${seriesId}_label_${match.pattern.id}_${match.location.startIndex}`;\n const centerX = (match.location.startPoint.x + match.location.endPoint.x) / 2;\n const centerY = (match.location.startPoint.y + match.location.endPoint.y) / 2;\n \n chart.addAnnotation({\n id: labelId,\n type: 'text',\n text: match.pattern.name,\n x: centerX,\n y: centerY,\n style: {\n color,\n fontSize: 12,\n backgroundColor: 'rgba(255, 255, 255, 0.8)'\n }\n } as any);\n }\n }\n },\n \n hidePatterns(seriesId: string): void {\n const chart = ctx?.chart;\n if (!chart) return;\n \n const matches = patternMatches.get(seriesId) || [];\n \n for (const match of matches) {\n for (let i = 0; i < match.validation.segments.length; i++) {\n const lineId = `${seriesId}_pattern_${match.pattern.id}_${match.location.startIndex}`;\n if (chart.getSeries(lineId)) {\n chart.removeSeries(lineId);\n }\n }\n \n const labelId = `${seriesId}_label_${match.pattern.id}_${match.location.startIndex}`;\n if (chart.getAnnotation(labelId)) {\n chart.removeAnnotation(labelId);\n }\n }\n }\n };\n \n // ============================================\n // Event Handlers\n // ============================================\n \n function handleDataUpdate(context: PluginContext, event: DataUpdateEvent): void {\n if (!config.enableRealtime) return;\n \n const { seriesId } = event;\n \n if (realtimeSeries.has(seriesId)) {\n const timer = debounceTimers.get(seriesId);\n if (timer) {\n clearTimeout(timer);\n }\n \n const newTimer = setTimeout(() => {\n const chart = context.chart;\n if (chart) {\n const series = chart.getSeries(seriesId);\n if (series) {\n const data = series.getData();\n if (data && data.x.length > 0) {\n const points: PatternPoint[] = Array.from(data.x).map((x, i) => ({\n x: x as number,\n y: data.y[i]\n }));\n \n detectPatterns(seriesId, points);\n \n if (config.visualization.showPatterns) {\n api.visualizePatterns(seriesId);\n }\n }\n }\n }\n }, config.debounceTime);\n \n debounceTimers.set(seriesId, newTimer);\n }\n }\n \n // ============================================\n // Plugin Definition\n // ============================================\n \n return {\n manifest: manifestPatternRecognition,\n \n onInit(context: PluginContext) {\n ctx = context;\n \n if (config.customPatterns) {\n for (const customPattern of config.customPatterns) {\n registerCustomPattern(customPattern);\n }\n }\n \n ctx.log.info(`Pattern Recognition plugin initialized with ${registeredPatterns.size} patterns`);\n },\n \n onConfigChange(_context: PluginContext, _newConfig: PluginPatternRecognitionConfig) {\n // Handle config changes\n },\n \n onBeforeRender(_context: PluginContext, _event: BeforeRenderEvent) {\n // Handle pre-render tasks if needed\n },\n \n onDataUpdate: handleDataUpdate,\n \n onDestroy(_context: PluginContext) {\n for (const timer of debounceTimers.values()) {\n clearTimeout(timer);\n }\n debounceTimers.clear();\n \n patternMatches.clear();\n realtimeSeries.clear();\n registeredPatterns.clear();\n customPatterns.clear();\n },\n \n api\n };\n}\n\nexport default PluginPatternRecognition;\n\nexport type {\n PatternType,\n PatternDefinition,\n PatternPoint,\n PatternSegment,\n PatternValidationResult,\n PatternMeasurements,\n PatternMatch,\n PatternDetectionResult,\n PatternDetectionParameters,\n CustomPatternConfig,\n PluginPatternRecognitionConfig,\n PatternDetectedEvent,\n PatternCompletedEvent,\n PatternFailedEvent,\n PatternRecognitionAPI\n} from './types';\n"],"names":["findPeaksAndValleys","points","peaks","valleys","i","prev","curr","next","calculateSlope","p1","p2","calculatePatternMeasurements","yValues","p","xValues","height","width","slope","validateHeadShoulders","leftShoulder","head","rightShoulder","leftValley","rightValley","headHigherThanShoulders","shouldersApproximatelyEqual","valleyBelowShoulders","segments","keyPoints","measurements","shoulderSymmetry","valleySymmetry","validateDoubleTop","firstTop","secondTop","valley","topsApproximatelyEqual","valleyBelowTops","significantDrop","topEquality","depthRatio","validateDoubleBottom","firstBottom","secondBottom","peak","bottomsApproximatelyEqual","peakAboveBottoms","significantRise","bottomEquality","heightRatio","validateAscendingTriangle","resistanceLevel","resistancePoints","lows","firstLow","lastLow","supportSlope","resistanceFlatness","supportAscending","BUILTIN_PATTERNS","invertedPoints","peak1","peak2","peak3","tolerance","firstHalf","secondHalf","firstSlope","secondSlope","peakSlope","valleySlope","resistance","support","supportPoints","_points","manifestPatternRecognition","DEFAULT_CONFIG","PluginPatternRecognition","userConfig","config","ctx","patternMatches","registeredPatterns","customPatterns","realtimeSeries","debounceTimers","SIGNAL_DIRECTION","scanPattern","pattern","patternKey","processedPoints","params","seriesId","matches","patternsByType","window","validation","match","hasSignificantOverlap","emitSignal","_a","_b","direction","detectPatterns","dataPoints","parameters","startTime","preprocessData","reachedLimit","patternType","id","a","b","detectionTime","result","sum","m","sensitivity","point","index","newMatch","existingMatches","existing","overlapStart","overlapSize","newMatchSize","existingMatchSize","registerCustomPattern","customConfig","validateCustomPattern","register","template","def","unregister","removed","confidence","errors","sequencePoint","actualPoint","constraints","min","max","api","handler","data","chart","targetSeries","x","timer","totalDetections","allPatternsByType","allConfidences","c","newConfig","showTypes","filteredMatches","color","segment","lineId","labelId","centerX","centerY","handleDataUpdate","context","event","newTimer","series","customPattern","_context","_newConfig","_event"],"mappings":"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"}
@@ -15,7 +15,7 @@ const b = {
15
15
  fileName: "velo-plot-snapshot-export",
16
16
  download: !1
17
17
  };
18
- function S(c) {
18
+ function R(c) {
19
19
  if (typeof c == "number") return c;
20
20
  switch (c) {
21
21
  case "8k":
@@ -30,61 +30,61 @@ function S(c) {
30
30
  return 1;
31
31
  }
32
32
  }
33
- function R(c = {}) {
34
- let n = null;
35
- async function p(e = {}) {
36
- var f, h;
37
- if (!n) throw new Error("Snapshot plugin not initialized");
38
- const t = { ...k, ...c.defaultOptions, ...e }, s = n.chart, l = S(t.resolution), i = s.getDPR();
33
+ function S(c = {}) {
34
+ let a = null;
35
+ async function p(t = {}) {
36
+ var u, h;
37
+ if (!a) throw new Error("Snapshot plugin not initialized");
38
+ const e = { ...k, ...c.defaultOptions, ...t }, n = a.chart, s = R(e.resolution), i = n.getDPR();
39
39
  try {
40
- if (t.format === "svg") {
41
- const a = s.exportSVG();
42
- if (t.download) {
43
- const r = new Blob([a], { type: "image/svg+xml" }), v = URL.createObjectURL(r), u = document.createElement("a");
44
- u.download = `${t.fileName}.svg`, u.href = v, document.body.appendChild(u), u.click(), document.body.removeChild(u), URL.revokeObjectURL(v);
40
+ if (e.format === "svg") {
41
+ const o = n.exportSVG();
42
+ if (e.download) {
43
+ const l = new Blob([o], { type: "image/svg+xml" }), w = URL.createObjectURL(l), f = document.createElement("a");
44
+ f.download = `${e.fileName}.svg`, f.href = w, document.body.appendChild(f), f.click(), document.body.removeChild(f), URL.revokeObjectURL(w);
45
45
  }
46
- return a;
46
+ return o;
47
47
  }
48
- l > 1 && (s.setDPR(i * l), await new Promise((a) => requestAnimationFrame(a)), await new Promise((a) => setTimeout(a, 100)));
49
- const m = (f = n.render.gl) == null ? void 0 : f.canvas, g = (h = n.render.ctx2d) == null ? void 0 : h.canvas;
48
+ s > 1 && (typeof n.setDevicePixelRatioOverride == "function" ? n.setDevicePixelRatioOverride(i * s) : n.setDPR(i * s), typeof n.render == "function" && n.render(), await new Promise((o) => requestAnimationFrame(o)), await new Promise((o) => requestAnimationFrame(o)), await new Promise((o) => setTimeout(o, 100)));
49
+ const m = (u = a.render.gl) == null ? void 0 : u.canvas, g = (h = a.render.ctx2d) == null ? void 0 : h.canvas;
50
50
  if (!m) throw new Error("WebGL canvas not found");
51
- const o = document.createElement("canvas");
52
- o.width = m.width, o.height = m.height;
53
- const d = o.getContext("2d");
54
- !t.transparent && t.includeBackground && (d.fillStyle = n.ui.theme.backgroundColor || "#ffffff", d.fillRect(0, 0, o.width, o.height)), d.drawImage(m, 0, 0), t.includeOverlays && g && d.drawImage(g, 0, 0), t.watermarkText && x(d, t.watermarkText, o.width, o.height, i * l);
55
- const y = `image/${t.format}`, w = o.toDataURL(y, t.quality);
56
- if (t.download) {
57
- const a = t.format === "jpeg" ? "jpg" : t.format, r = document.createElement("a");
58
- r.download = `${t.fileName}.${a}`, r.href = w, document.body.appendChild(r), r.click(), document.body.removeChild(r);
51
+ const r = document.createElement("canvas");
52
+ r.width = m.width, r.height = m.height;
53
+ const d = r.getContext("2d");
54
+ !e.transparent && e.includeBackground && (d.fillStyle = a.ui.theme.backgroundColor || "#ffffff", d.fillRect(0, 0, r.width, r.height)), d.drawImage(m, 0, 0), e.includeOverlays && g && d.drawImage(g, 0, 0), e.watermarkText && x(d, e.watermarkText, r.width, r.height, i * s);
55
+ const y = `image/${e.format}`, v = r.toDataURL(y, e.quality);
56
+ if (e.download) {
57
+ const o = e.format === "jpeg" ? "jpg" : e.format, l = document.createElement("a");
58
+ l.download = `${e.fileName}.${o}`, l.href = v, document.body.appendChild(l), l.click(), document.body.removeChild(l);
59
59
  }
60
- return w;
60
+ return v;
61
61
  } finally {
62
- l > 1 && s.setDPR(i);
62
+ s > 1 && (typeof n.setDevicePixelRatioOverride == "function" ? n.setDevicePixelRatioOverride(null) : n.setDPR(i));
63
63
  }
64
64
  }
65
- function x(e, t, s, l, i) {
66
- e.save();
67
- const f = Math.max(16, 24 * (i / 2));
68
- e.font = `bold ${f}px Inter, system-ui, sans-serif`, e.fillStyle = "rgba(128, 128, 128, 0.4)", e.textAlign = "right", e.textBaseline = "bottom", e.fillText(t, s - 20 * i / 2, l - 20 * i / 2), e.restore();
65
+ function x(t, e, n, s, i) {
66
+ t.save();
67
+ const u = Math.max(16, 24 * (i / 2));
68
+ t.font = `bold ${u}px Inter, system-ui, sans-serif`, t.fillStyle = "rgba(128, 128, 128, 0.4)", t.textAlign = "right", t.textBaseline = "bottom", t.fillText(e, n - 20 * i / 2, s - 20 * i / 2), t.restore();
69
69
  }
70
70
  return {
71
71
  manifest: b,
72
- onInit(e) {
73
- n = e, n.log.info("Snapshot plugin initialized");
72
+ onInit(t) {
73
+ a = t, a.log.info("Snapshot plugin initialized");
74
74
  },
75
75
  onDestroy() {
76
- n = null;
76
+ a = null;
77
77
  },
78
78
  api: {
79
79
  takeSnapshot: p,
80
- downloadSnapshot: async (e) => {
81
- await p({ ...e, download: !0 });
80
+ downloadSnapshot: async (t) => {
81
+ await p({ ...t, download: !0 });
82
82
  }
83
83
  }
84
84
  };
85
85
  }
86
86
  export {
87
- R as PluginSnapshot,
88
- R as default
87
+ S as PluginSnapshot,
88
+ S as default
89
89
  };
90
90
  //# sourceMappingURL=snapshot.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot.js","sources":["../../src/plugins/snapshot/index.ts"],"sourcesContent":["/**\n * SciPlot - Snapshot Plugin\n * \n * Provides high-resolution image export capabilities.\n * Supports different formats (PNG, JPEG, WebP) and resolutions (Standard, 2K, 4K, 8K).\n * \n * @module plugins/snapshot\n */\n\nimport type { \n PluginManifest, \n ChartPlugin, \n PluginContext,\n} from '../types';\n\nimport type {\n PluginSnapshotConfig,\n SnapshotExportAPI,\n SnapshotExportOptions,\n SnapshotResolution,\n} from './types';\n\nconst manifestSnapshot: PluginManifest = {\n name: \"velo-plot-snapshot\",\n version: \"1.0.0\",\n description: \"High-resolution image export for velo-plot\",\n provides: [\"export\", \"snapshot\"],\n tags: [\"snapshot\", \"export\", \"publication\", \"image\"],\n};\n\nconst DEFAULT_OPTIONS: Required<SnapshotExportOptions> = {\n format: 'png',\n quality: 0.9,\n resolution: 'standard',\n includeBackground: true,\n includeOverlays: true,\n watermarkText: '',\n transparent: false,\n fileName: 'velo-plot-snapshot-export',\n download: false\n};\n\nfunction resolutionToScale(res: SnapshotResolution): number {\n if (typeof res === 'number') return res;\n switch (res) {\n case '8k': return 8;\n case '4k': return 4;\n case '2k': return 2;\n case 'standard': return 1;\n default: return 1;\n }\n}\n\n/**\n * SciPlot Snapshot Plugin\n * \n * Captures the current chart view with all layers (WebGL + Overlay).\n */\nexport function PluginSnapshot(\n config: PluginSnapshotConfig = {}\n): ChartPlugin<PluginSnapshotConfig> {\n let ctx: PluginContext | null = null;\n\n /**\n * Captures the chart as an image\n */\n async function takeSnapshot(options: SnapshotExportOptions = {}): Promise<string | Blob> {\n if (!ctx) throw new Error(\"Snapshot plugin not initialized\");\n \n const opt = { ...DEFAULT_OPTIONS, ...config.defaultOptions, ...options };\n const chart = ctx.chart;\n \n // 1. Determine target resolution scale\n const scale = resolutionToScale(opt.resolution);\n const originalDPR = chart.getDPR();\n \n try {\n if (opt.format === 'svg') {\n const svg = chart.exportSVG();\n if (opt.download) {\n const blob = new Blob([svg], { type: 'image/svg+xml' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.download = `${opt.fileName}.svg`;\n link.href = url;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n }\n return svg;\n }\n\n // High-res re-render if scale > 1\n // We temporarily boost the device pixel ratio to force a higher resolution render\n if (scale > 1) {\n chart.setDPR(originalDPR * scale);\n // Wait for DOM and GL updates\n await new Promise(r => requestAnimationFrame(r));\n // Small delay to ensure all overlays (which might have their own throttles) are ready\n await new Promise(r => setTimeout(r, 100));\n }\n\n const webglCanvas = (ctx.render.gl?.canvas) as HTMLCanvasElement;\n const overlayCanvas = (ctx.render.ctx2d?.canvas) as HTMLCanvasElement;\n \n if (!webglCanvas) throw new Error(\"WebGL canvas not found\");\n\n // 3. Compose layers into a final canvas\n const compositionCanvas = document.createElement('canvas');\n compositionCanvas.width = webglCanvas.width;\n compositionCanvas.height = webglCanvas.height;\n const compCtx = compositionCanvas.getContext('2d')!;\n \n // Fill background if not transparent\n if (!opt.transparent && opt.includeBackground) {\n compCtx.fillStyle = ctx.ui.theme.backgroundColor || '#ffffff';\n compCtx.fillRect(0, 0, compositionCanvas.width, compositionCanvas.height);\n }\n \n // Draw WebGL layer (bottom)\n compCtx.drawImage(webglCanvas, 0, 0);\n \n // Draw Overlay layer (top) - contains annotations, tooltips, etc.\n if (opt.includeOverlays && overlayCanvas) {\n compCtx.drawImage(overlayCanvas, 0, 0);\n }\n \n // Apply Watermark\n if (opt.watermarkText) {\n drawWatermark(compCtx, opt.watermarkText, compositionCanvas.width, compositionCanvas.height, originalDPR * scale);\n }\n \n const mimeType = `image/${opt.format}`;\n const dataUrl = compositionCanvas.toDataURL(mimeType, opt.quality);\n \n // Automatic download if requested\n if (opt.download) {\n const extension = opt.format === 'jpeg' ? 'jpg' : opt.format;\n const link = document.createElement('a');\n link.download = `${opt.fileName}.${extension}`;\n link.href = dataUrl;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n }\n \n return dataUrl;\n } finally {\n // 4. Restore original resolution\n if (scale > 1) {\n chart.setDPR(originalDPR);\n }\n }\n }\n\n /**\n * Helper to draw a watermark on the captured image\n */\n function drawWatermark(c: CanvasRenderingContext2D, text: string, w: number, h: number, dpr: number) {\n c.save();\n // Scale font size according to DPR\n const fontSize = Math.max(16, 24 * (dpr / 2));\n c.font = `bold ${fontSize}px Inter, system-ui, sans-serif`;\n c.fillStyle = 'rgba(128, 128, 128, 0.4)';\n c.textAlign = 'right';\n c.textBaseline = 'bottom';\n c.fillText(text, w - (20 * dpr/2), h - (20 * dpr/2));\n c.restore();\n }\n\n const api: SnapshotExportAPI & Record<string, unknown> = {\n takeSnapshot,\n downloadSnapshot: async (opt: SnapshotExportOptions) => {\n await takeSnapshot({ ...opt, download: true });\n }\n };\n\n return {\n manifest: manifestSnapshot,\n onInit(c) { \n ctx = c; \n ctx.log.info(\"Snapshot plugin initialized\");\n },\n onDestroy() {\n ctx = null;\n },\n api\n };\n}\n\nexport default PluginSnapshot;\n\nexport type {\n SnapshotFormat,\n SnapshotResolution,\n SnapshotExportOptions,\n SnapshotExportAPI,\n PluginSnapshotConfig\n} from './types';\n"],"names":["manifestSnapshot","DEFAULT_OPTIONS","resolutionToScale","res","PluginSnapshot","config","ctx","takeSnapshot","options","_a","_b","opt","chart","scale","originalDPR","svg","blob","url","link","r","webglCanvas","overlayCanvas","compositionCanvas","compCtx","drawWatermark","mimeType","dataUrl","extension","c","text","w","h","dpr","fontSize"],"mappings":"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"}
1
+ {"version":3,"file":"snapshot.js","sources":["../../src/plugins/snapshot/index.ts"],"sourcesContent":["/**\n * SciPlot - Snapshot Plugin\n * \n * Provides high-resolution image export capabilities.\n * Supports different formats (PNG, JPEG, WebP) and resolutions (Standard, 2K, 4K, 8K).\n * \n * @module plugins/snapshot\n */\n\nimport type { \n PluginManifest, \n ChartPlugin, \n PluginContext,\n} from '../types';\n\nimport type {\n PluginSnapshotConfig,\n SnapshotExportAPI,\n SnapshotExportOptions,\n SnapshotResolution,\n} from './types';\n\nconst manifestSnapshot: PluginManifest = {\n name: \"velo-plot-snapshot\",\n version: \"1.0.0\",\n description: \"High-resolution image export for velo-plot\",\n provides: [\"export\", \"snapshot\"],\n tags: [\"snapshot\", \"export\", \"publication\", \"image\"],\n};\n\nconst DEFAULT_OPTIONS: Required<SnapshotExportOptions> = {\n format: 'png',\n quality: 0.9,\n resolution: 'standard',\n includeBackground: true,\n includeOverlays: true,\n watermarkText: '',\n transparent: false,\n fileName: 'velo-plot-snapshot-export',\n download: false\n};\n\nfunction resolutionToScale(res: SnapshotResolution): number {\n if (typeof res === 'number') return res;\n switch (res) {\n case '8k': return 8;\n case '4k': return 4;\n case '2k': return 2;\n case 'standard': return 1;\n default: return 1;\n }\n}\n\n/**\n * SciPlot Snapshot Plugin\n * \n * Captures the current chart view with all layers (WebGL + Overlay).\n */\nexport function PluginSnapshot(\n config: PluginSnapshotConfig = {}\n): ChartPlugin<PluginSnapshotConfig> {\n let ctx: PluginContext | null = null;\n\n /**\n * Captures the chart as an image\n */\n async function takeSnapshot(options: SnapshotExportOptions = {}): Promise<string | Blob> {\n if (!ctx) throw new Error(\"Snapshot plugin not initialized\");\n \n const opt = { ...DEFAULT_OPTIONS, ...config.defaultOptions, ...options };\n const chart = ctx.chart;\n \n // 1. Determine target resolution scale\n const scale = resolutionToScale(opt.resolution);\n const originalDPR = chart.getDPR();\n \n try {\n if (opt.format === 'svg') {\n const svg = chart.exportSVG();\n if (opt.download) {\n const blob = new Blob([svg], { type: 'image/svg+xml' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.download = `${opt.fileName}.svg`;\n link.href = url;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n }\n return svg;\n }\n\n // High-res re-render if scale > 1.\n // We temporarily lock the device pixel ratio to force a higher-resolution\n // render. Using an explicit override (instead of setDPR) is essential:\n // a plain setDPR gets reverted by the very next resize() call, so the\n // backing stores would stay at screen resolution and every preset would\n // look identical / pixelated. The override survives resize().\n if (scale > 1) {\n if (typeof chart.setDevicePixelRatioOverride === 'function') {\n chart.setDevicePixelRatioOverride(originalDPR * scale);\n } else {\n chart.setDPR(originalDPR * scale);\n }\n // Force a synchronous full render at the boosted DPR before capture.\n if (typeof chart.render === 'function') {\n chart.render();\n }\n // Wait for DOM and GL updates\n await new Promise(r => requestAnimationFrame(r));\n // Second frame ensures the resized backing store has actually been painted.\n await new Promise(r => requestAnimationFrame(r));\n // Small delay to ensure all overlays (which might have their own throttles) are ready\n await new Promise(r => setTimeout(r, 100));\n }\n\n const webglCanvas = (ctx.render.gl?.canvas) as HTMLCanvasElement;\n const overlayCanvas = (ctx.render.ctx2d?.canvas) as HTMLCanvasElement;\n \n if (!webglCanvas) throw new Error(\"WebGL canvas not found\");\n\n // 3. Compose layers into a final canvas\n const compositionCanvas = document.createElement('canvas');\n compositionCanvas.width = webglCanvas.width;\n compositionCanvas.height = webglCanvas.height;\n const compCtx = compositionCanvas.getContext('2d')!;\n \n // Fill background if not transparent\n if (!opt.transparent && opt.includeBackground) {\n compCtx.fillStyle = ctx.ui.theme.backgroundColor || '#ffffff';\n compCtx.fillRect(0, 0, compositionCanvas.width, compositionCanvas.height);\n }\n \n // Draw WebGL layer (bottom)\n compCtx.drawImage(webglCanvas, 0, 0);\n \n // Draw Overlay layer (top) - contains annotations, tooltips, etc.\n if (opt.includeOverlays && overlayCanvas) {\n compCtx.drawImage(overlayCanvas, 0, 0);\n }\n \n // Apply Watermark\n if (opt.watermarkText) {\n drawWatermark(compCtx, opt.watermarkText, compositionCanvas.width, compositionCanvas.height, originalDPR * scale);\n }\n \n const mimeType = `image/${opt.format}`;\n const dataUrl = compositionCanvas.toDataURL(mimeType, opt.quality);\n \n // Automatic download if requested\n if (opt.download) {\n const extension = opt.format === 'jpeg' ? 'jpg' : opt.format;\n const link = document.createElement('a');\n link.download = `${opt.fileName}.${extension}`;\n link.href = dataUrl;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n }\n \n return dataUrl;\n } finally {\n // 4. Restore original resolution\n if (scale > 1) {\n if (typeof chart.setDevicePixelRatioOverride === 'function') {\n chart.setDevicePixelRatioOverride(null);\n } else {\n chart.setDPR(originalDPR);\n }\n }\n }\n }\n\n /**\n * Helper to draw a watermark on the captured image\n */\n function drawWatermark(c: CanvasRenderingContext2D, text: string, w: number, h: number, dpr: number) {\n c.save();\n // Scale font size according to DPR\n const fontSize = Math.max(16, 24 * (dpr / 2));\n c.font = `bold ${fontSize}px Inter, system-ui, sans-serif`;\n c.fillStyle = 'rgba(128, 128, 128, 0.4)';\n c.textAlign = 'right';\n c.textBaseline = 'bottom';\n c.fillText(text, w - (20 * dpr/2), h - (20 * dpr/2));\n c.restore();\n }\n\n const api: SnapshotExportAPI & Record<string, unknown> = {\n takeSnapshot,\n downloadSnapshot: async (opt: SnapshotExportOptions) => {\n await takeSnapshot({ ...opt, download: true });\n }\n };\n\n return {\n manifest: manifestSnapshot,\n onInit(c) { \n ctx = c; \n ctx.log.info(\"Snapshot plugin initialized\");\n },\n onDestroy() {\n ctx = null;\n },\n api\n };\n}\n\nexport default PluginSnapshot;\n\nexport type {\n SnapshotFormat,\n SnapshotResolution,\n SnapshotExportOptions,\n SnapshotExportAPI,\n PluginSnapshotConfig\n} from './types';\n"],"names":["manifestSnapshot","DEFAULT_OPTIONS","resolutionToScale","res","PluginSnapshot","config","ctx","takeSnapshot","options","_a","_b","opt","chart","scale","originalDPR","svg","blob","url","link","r","webglCanvas","overlayCanvas","compositionCanvas","compCtx","drawWatermark","mimeType","dataUrl","extension","c","text","w","h","dpr","fontSize"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { C as c, c as s, a as i, l } from "../index-CUGS98p4.js";
1
+ import { C as c, c as s, a as i, l } from "../index-CaXWSOTk.js";
2
2
  const n = {
3
3
  name: "velo-plot-sync",
4
4
  version: "1.0.0",
@@ -1,4 +1,4 @@
1
- import { D as l, b as s, P as e, T, P as t } from "../index-CWipqOLP.js";
1
+ import { D as l, b as s, P as e, T, P as t } from "../index-qunX30Xu.js";
2
2
  export {
3
3
  l as DeltaTool,
4
4
  s as PeakTool,
@@ -1,4 +1,4 @@
1
- import { P as t, P as l } from "../index-D7dTq6VB.js";
1
+ import { P as t, P as l } from "../index-BBpJwOct.js";
2
2
  export {
3
3
  t as PluginVirtualization,
4
4
  l as default
package/dist/react.js CHANGED
@@ -1,6 +1,6 @@
1
- import { S as x, u as C } from "./SciPlot-GJvw7GJo.js";
1
+ import { S as x, u as C } from "./SciPlot-CEU4ApgD.js";
2
2
  import { useRef as n, useState as a, useEffect as k, useCallback as f } from "react";
3
- import { c as m } from "./createStackedChart-DJSmqerD.js";
3
+ import { c as m } from "./createStackedChart-DxNW0VkF.js";
4
4
  function A(c) {
5
5
  const s = n(null), r = n(null), [i, l] = a(null), [d, u] = a(!1), o = n(c);
6
6
  o.current = c, k(() => {