{
  "workflow": {
    "id": 10765,
    "name": "Market intelligence engine with AI sentiment detection & competitor analysis",
    "views": 230,
    "recentViews": 1,
    "totalViews": 230,
    "createdAt": "2025-11-12T15:50:48.861Z",
    "description": "## How It Works\nA scheduled process aggregates content from eight distinct data sources and standardizes all inputs into a unified format. AI models perform sentiment scoring, detect conspiracy or misinformation signals, and generate trend analyses across domains. An MCDN routing model prioritizes and channels insights to the appropriate workflows. Dashboards visualize real-time analytics, trigger KPIs based on thresholds, and compile comprehensive market-intelligence reports for stakeholders.\n\n## Setup Steps\n1. **Data Sources:** Connect news APIs, social media platforms, academic databases, code repositories, and documentation feeds.\n2. **AI Analysis:** Configure OpenAI models for sentiment analysis, conspiracy detection, and trend scoring.\n3. **Dashboards:** Integrate analytics platforms and enable automated email or reporting outputs.\n4. **Storage:** Configure a database for historical records, trend archives, and competitive-intelligence storage.\n\n\n## Prerequisites\nMulti-source API credentials; OpenAI API key; dashboard platform access; email service; code repository access; academic database credentials\n\n## Use Cases\nCompetitive intelligence monitoring; market trend analysis; technology landscape tracking; product strategy research; misinformation filtering\n\n## Customization\nAdjust sentiment thresholds; add/remove data sources; modify analysis rules; extend AI models\n\n## Benefits\nReduces research time 80%; consolidates market intelligence; improves decision accuracy\n\n",
    "workflow": {
      "id": "vmiRUwq7lpvxIcfE",
      "meta": {
        "instanceId": "b91e510ebae4127f953fd2f5f8d40d58ca1e71c746d4500c12ae86aad04c1502",
        "templateCredsSetupCompleted": true
      },
      "name": "Market Intelligence Engine with AI Sentiment Detection & Competitor Analysis",
      "tags": [],
      "nodes": [
        {
          "id": "64a37127-3701-4fe2-98ac-3f0ec859594b",
          "name": "Schedule Data Collection",
          "type": "n8n-nodes-base.scheduleTrigger",
          "position": [
            400,
            384
          ],
          "parameters": {
            "rule": {
              "interval": [
                {
                  "field": "hours",
                  "hoursInterval": 6
                }
              ]
            }
          },
          "typeVersion": 1.2
        },
        {
          "id": "dc522946-aee3-4c76-92f7-ddeaeb7b7d6e",
          "name": "Workflow Configuration",
          "type": "n8n-nodes-base.set",
          "position": [
            608,
            384
          ],
          "parameters": {
            "options": {},
            "assignments": {
              "assignments": [
                {
                  "id": "id-1",
                  "name": "newsApiUrl",
                  "type": "string",
                  "value": "<__PLACEHOLDER_VALUE__News API endpoint URL__>"
                },
                {
                  "id": "id-2",
                  "name": "blogApiUrl",
                  "type": "string",
                  "value": "<__PLACEHOLDER_VALUE__Blog API endpoint URL__>"
                },
                {
                  "id": "id-3",
                  "name": "socialApiUrl",
                  "type": "string",
                  "value": "<__PLACEHOLDER_VALUE__Social media API endpoint URL__>"
                },
                {
                  "id": "id-4",
                  "name": "academicApiUrl",
                  "type": "string",
                  "value": "<__PLACEHOLDER_VALUE__Academic papers API endpoint URL (e.g., arXiv, Semantic Scholar)__>"
                },
                {
                  "id": "id-5",
                  "name": "githubApiUrl",
                  "type": "string",
                  "value": "<__PLACEHOLDER_VALUE__GitHub API endpoint URL__>"
                },
                {
                  "id": "id-6",
                  "name": "forumApiUrl",
                  "type": "string",
                  "value": "<__PLACEHOLDER_VALUE__Forum API endpoint URL (e.g., Reddit, HackerNews)__>"
                },
                {
                  "id": "id-7",
                  "name": "docsApiUrl",
                  "type": "string",
                  "value": "<__PLACEHOLDER_VALUE__Product docs API endpoint URL__>"
                },
                {
                  "id": "id-8",
                  "name": "alertThreshold",
                  "type": "number",
                  "value": 0.75
                },
                {
                  "id": "id-9",
                  "name": "dbTable",
                  "type": "string",
                  "value": "ai_trends"
                },
                {
                  "id": "id-10",
                  "name": "dashboardTable",
                  "type": "string",
                  "value": "trend_dashboard"
                },
                {
                  "id": "id-11",
                  "name": "kpiTable",
                  "type": "string",
                  "value": "trend_kpis"
                },
                {
                  "id": "id-12",
                  "name": "trainingTable",
                  "type": "string",
                  "value": "training_data"
                }
              ]
            },
            "includeOtherFields": true
          },
          "typeVersion": 3.4
        },
        {
          "id": "299667ff-10fe-4937-afb4-02f7f6153a1a",
          "name": "Fetch News Articles",
          "type": "n8n-nodes-base.httpRequest",
          "position": [
            864,
            448
          ],
          "parameters": {
            "url": "={{ $('Workflow Configuration').first().json.newsApiUrl }}",
            "options": {},
            "sendHeaders": true,
            "headerParameters": {
              "parameters": [
                {
                  "name": "Content-Type",
                  "value": "application/json"
                }
              ]
            }
          },
          "typeVersion": 4.3
        },
        {
          "id": "e33ccf59-9898-42e6-8f78-43eff861121f",
          "name": "Fetch Blog Posts",
          "type": "n8n-nodes-base.httpRequest",
          "position": [
            864,
            592
          ],
          "parameters": {
            "url": "={{ $('Workflow Configuration').first().json.blogApiUrl }}",
            "options": {},
            "sendHeaders": true,
            "headerParameters": {
              "parameters": [
                {
                  "name": "Content-Type",
                  "value": "application/json"
                }
              ]
            }
          },
          "typeVersion": 4.3
        },
        {
          "id": "78c33619-26a6-4ae6-9392-890e32c8f19e",
          "name": "Fetch Social Media",
          "type": "n8n-nodes-base.httpRequest",
          "position": [
            864,
            736
          ],
          "parameters": {
            "url": "={{ $('Workflow Configuration').first().json.socialApiUrl }}",
            "options": {},
            "sendHeaders": true,
            "headerParameters": {
              "parameters": [
                {
                  "name": "Content-Type",
                  "value": "application/json"
                }
              ]
            }
          },
          "typeVersion": 4.3
        },
        {
          "id": "6c17736f-5bb5-462a-bab7-fee420850f96",
          "name": "Fetch Academic Papers",
          "type": "n8n-nodes-base.httpRequest",
          "position": [
            864,
            928
          ],
          "parameters": {
            "url": "={{ $('Workflow Configuration').first().json.academicApiUrl }}",
            "options": {},
            "sendHeaders": true,
            "headerParameters": {
              "parameters": [
                {
                  "name": "Content-Type",
                  "value": "application/json"
                }
              ]
            }
          },
          "typeVersion": 4.3
        },
        {
          "id": "02727f99-066e-4778-a62d-7d5af023ef91",
          "name": "Fetch Code Repos",
          "type": "n8n-nodes-base.httpRequest",
          "position": [
            864,
            1120
          ],
          "parameters": {
            "url": "={{ $('Workflow Configuration').first().json.githubApiUrl }}",
            "options": {},
            "sendHeaders": true,
            "headerParameters": {
              "parameters": [
                {
                  "name": "Content-Type",
                  "value": "application/json"
                }
              ]
            }
          },
          "typeVersion": 4.3
        },
        {
          "id": "336e1343-34e8-4ace-8d3b-27fb12d35064",
          "name": "Fetch Forum Discussions",
          "type": "n8n-nodes-base.httpRequest",
          "position": [
            864,
            1312
          ],
          "parameters": {
            "url": "={{ $('Workflow Configuration').first().json.forumApiUrl }}",
            "options": {},
            "sendHeaders": true,
            "headerParameters": {
              "parameters": [
                {
                  "name": "Content-Type",
                  "value": "application/json"
                }
              ]
            }
          },
          "typeVersion": 4.3
        },
        {
          "id": "8e536043-0b4b-496b-9ff7-fda8a088de31",
          "name": "Fetch Product Docs",
          "type": "n8n-nodes-base.httpRequest",
          "position": [
            864,
            1504
          ],
          "parameters": {
            "url": "={{ $('Workflow Configuration').first().json.docsApiUrl }}",
            "options": {},
            "sendHeaders": true,
            "headerParameters": {
              "parameters": [
                {
                  "name": "Content-Type",
                  "value": "application/json"
                }
              ]
            }
          },
          "typeVersion": 4.3
        },
        {
          "id": "42637df4-a528-4614-ba7d-f2bac87b1ade",
          "name": "Merge All Sources",
          "type": "n8n-nodes-base.merge",
          "position": [
            1136,
            528
          ],
          "parameters": {
            "numberInputs": 7
          },
          "typeVersion": 3.2
        },
        {
          "id": "dab13587-245a-46a7-88ab-fb19cc495d25",
          "name": "Normalize Content Schema",
          "type": "n8n-nodes-base.code",
          "position": [
            1344,
            416
          ],
          "parameters": {
            "mode": "runOnceForEachItem",
            "jsCode": "// Normalize all incoming items into a unified schema\nconst item = $input.item.json;\n\n// Helper function to safely extract nested values\nfunction safeGet(obj, path, defaultValue = null) {\n  try {\n    return path.split('.').reduce((acc, part) => acc && acc[part], obj) || defaultValue;\n  } catch (e) {\n    return defaultValue;\n  }\n}\n\n// Helper function to generate ID if not present\nfunction generateId(item) {\n  if (item.id) return item.id;\n  if (item.url) return Buffer.from(item.url).toString('base64').substring(0, 32);\n  return `item_${Date.now()}_${Math.random().toString(36).substring(7)}`;\n}\n\n// Helper function to parse date\nfunction parseDate(dateValue) {\n  if (!dateValue) return new Date().toISOString();\n  try {\n    const date = new Date(dateValue);\n    return isNaN(date.getTime()) ? new Date().toISOString() : date.toISOString();\n  } catch (e) {\n    return new Date().toISOString();\n  }\n}\n\n// Helper function to extract tags\nfunction extractTags(item) {\n  const tags = [];\n  \n  if (item.tags && Array.isArray(item.tags)) {\n    tags.push(...item.tags);\n  } else if (item.keywords && Array.isArray(item.keywords)) {\n    tags.push(...item.keywords);\n  } else if (item.categories && Array.isArray(item.categories)) {\n    tags.push(...item.categories);\n  } else if (item.hashtags && Array.isArray(item.hashtags)) {\n    tags.push(...item.hashtags);\n  }\n  \n  return tags.filter(tag => tag && typeof tag === 'string');\n}\n\n// Normalize the item\nconst normalizedItem = {\n  id: generateId(item),\n  title: safeGet(item, 'title') || safeGet(item, 'headline') || safeGet(item, 'name') || 'Untitled',\n  content: safeGet(item, 'content') || safeGet(item, 'body') || safeGet(item, 'description') || safeGet(item, 'text') || '',\n  url: safeGet(item, 'url') || safeGet(item, 'link') || safeGet(item, 'permalink') || '',\n  source: safeGet(item, 'source') || safeGet(item, 'sourceName') || safeGet(item, 'publisher') || 'Unknown',\n  publishedDate: parseDate(safeGet(item, 'publishedDate') || safeGet(item, 'published_at') || safeGet(item, 'createdAt') || safeGet(item, 'date')),\n  author: safeGet(item, 'author') || safeGet(item, 'creator') || safeGet(item, 'username') || 'Unknown',\n  tags: extractTags(item),\n  metadata: {\n    originalSource: safeGet(item, 'source'),\n    language: safeGet(item, 'language') || safeGet(item, 'lang'),\n    score: safeGet(item, 'score') || safeGet(item, 'rating'),\n    engagement: {\n      likes: safeGet(item, 'likes') || safeGet(item, 'upvotes') || 0,\n      comments: safeGet(item, 'comments') || safeGet(item, 'replies') || 0,\n      shares: safeGet(item, 'shares') || safeGet(item, 'retweets') || 0\n    },\n    raw: item\n  }\n};\n\nreturn normalizedItem;"
          },
          "typeVersion": 2
        },
        {
          "id": "a6aae8b4-fbf3-458c-8784-561b1fc9f728",
          "name": "Deduplicate Content",
          "type": "n8n-nodes-base.removeDuplicates",
          "position": [
            1520,
            416
          ],
          "parameters": {
            "compare": "selectedFields",
            "options": {},
            "fieldsToCompare": "url"
          },
          "typeVersion": 2
        },
        {
          "id": "176067e6-a064-4d9e-ad03-3760320b08ca",
          "name": "Extract Entities & Topics",
          "type": "@n8n/n8n-nodes-langchain.openAi",
          "position": [
            1728,
            416
          ],
          "parameters": {
            "operation": "message"
          },
          "credentials": {
            "openAiApi": {
              "id": "credential-id",
              "name": "openAiApi Credential"
            }
          },
          "typeVersion": 2
        },
        {
          "id": "1cf1c8a9-03bf-4805-ac7e-b098607f2282",
          "name": "Parse Technical Signals",
          "type": "n8n-nodes-base.code",
          "position": [
            2080,
            416
          ],
          "parameters": {
            "mode": "runOnceForEachItem",
            "jsCode": "// Parse Technical Signals from Content\n// Extract: AI models, datasets, benchmarks, libraries/frameworks, version numbers\n\nconst item = $input.item.json;\nconst content = item.content || item.text || item.body || '';\n\n// Initialize signals object\nconst signals = {\n  aiModels: [],\n  datasets: [],\n  benchmarks: [],\n  libraries: [],\n  versions: []\n};\n\n// AI Models patterns (common model names)\nconst modelPatterns = [\n  /GPT-?\\d+(\\.\\d+)?/gi,\n  /Claude[\\s-]?\\d*/gi,\n  /LLaMA[\\s-]?\\d*/gi,\n  /PaLM[\\s-]?\\d*/gi,\n  /BERT/gi,\n  /T5/gi,\n  /Gemini[\\s-]?\\d*/gi,\n  /Mistral[\\s-]?\\d*/gi,\n  /Falcon[\\s-]?\\d*/gi,\n  /Stable\\s*Diffusion[\\s-]?\\d*/gi,\n  /DALL-?E[\\s-]?\\d*/gi,\n  /Midjourney/gi,\n  /Whisper/gi,\n  /CodeLlama/gi,\n  /Vicuna/gi,\n  /Alpaca/gi\n];\n\n// Dataset patterns\nconst datasetPatterns = [\n  /ImageNet/gi,\n  /COCO/gi,\n  /MNIST/gi,\n  /CIFAR-?\\d+/gi,\n  /SQuAD/gi,\n  /GLUE/gi,\n  /SuperGLUE/gi,\n  /Common\\s*Crawl/gi,\n  /WebText/gi,\n  /The\\s*Pile/gi,\n  /RedPajama/gi,\n  /C4/gi,\n  /BookCorpus/gi,\n  /WikiText/gi\n];\n\n// Benchmark patterns\nconst benchmarkPatterns = [\n  /MMLU/gi,\n  /HumanEval/gi,\n  /HellaSwag/gi,\n  /TruthfulQA/gi,\n  /GSM8K/gi,\n  /MATH/gi,\n  /BBH/gi,\n  /ARC[\\s-]?(?:Easy|Challenge)?/gi,\n  /WinoGrande/gi,\n  /LAMBADA/gi,\n  /BIG-?Bench/gi\n];\n\n// Library/Framework patterns\nconst libraryPatterns = [\n  /PyTorch/gi,\n  /TensorFlow/gi,\n  /JAX/gi,\n  /Keras/gi,\n  /Hugging\\s*Face/gi,\n  /Transformers/gi,\n  /LangChain/gi,\n  /LlamaIndex/gi,\n  /scikit-learn/gi,\n  /OpenAI/gi,\n  /Anthropic/gi,\n  /vLLM/gi,\n  /DeepSpeed/gi,\n  /Megatron/gi,\n  /PEFT/gi,\n  /LoRA/gi,\n  /QLoRA/gi\n];\n\n// Version number pattern (e.g., v1.2.3, version 2.0, 3.5.1)\nconst versionPattern = /(?:v(?:ersion)?\\s*)?\\d+\\.\\d+(?:\\.\\d+)?(?:-(?:alpha|beta|rc)\\d*)?/gi;\n\n// Extract AI Models\nmodelPatterns.forEach(pattern => {\n  const matches = content.match(pattern);\n  if (matches) {\n    signals.aiModels.push(...matches);\n  }\n});\n\n// Extract Datasets\ndatasetPatterns.forEach(pattern => {\n  const matches = content.match(pattern);\n  if (matches) {\n    signals.datasets.push(...matches);\n  }\n});\n\n// Extract Benchmarks\nbenchmarkPatterns.forEach(pattern => {\n  const matches = content.match(pattern);\n  if (matches) {\n    signals.benchmarks.push(...matches);\n  }\n});\n\n// Extract Libraries/Frameworks\nlibraryPatterns.forEach(pattern => {\n  const matches = content.match(pattern);\n  if (matches) {\n    signals.libraries.push(...matches);\n  }\n});\n\n// Extract Version Numbers\nconst versionMatches = content.match(versionPattern);\nif (versionMatches) {\n  signals.versions.push(...versionMatches);\n}\n\n// Deduplicate and normalize\nsignals.aiModels = [...new Set(signals.aiModels.map(m => m.trim()))];\nsignals.datasets = [...new Set(signals.datasets.map(d => d.trim()))];\nsignals.benchmarks = [...new Set(signals.benchmarks.map(b => b.trim()))];\nsignals.libraries = [...new Set(signals.libraries.map(l => l.trim()))];\nsignals.versions = [...new Set(signals.versions.map(v => v.trim()))];\n\n// Return enriched item with technical signals\nreturn {\n  ...item,\n  technicalSignals: signals,\n  signalCount: {\n    models: signals.aiModels.length,\n    datasets: signals.datasets.length,\n    benchmarks: signals.benchmarks.length,\n    libraries: signals.libraries.length,\n    versions: signals.versions.length,\n    total: signals.aiModels.length + signals.datasets.length + signals.benchmarks.length + signals.libraries.length + signals.versions.length\n  }\n};"
          },
          "typeVersion": 2
        },
        {
          "id": "0f28612a-98f1-442b-af18-a2f21a3e5873",
          "name": "Store Raw Data",
          "type": "n8n-nodes-base.postgres",
          "position": [
            2304,
            416
          ],
          "parameters": {
            "table": {
              "__rl": true,
              "mode": "name",
              "value": "={{ $('Workflow Configuration').first().json.dbTable }}"
            },
            "schema": {
              "__rl": true,
              "mode": "list",
              "value": "public"
            },
            "columns": {
              "value": null,
              "mappingMode": "autoMapInputData"
            },
            "options": {}
          },
          "typeVersion": 2.6
        },
        {
          "id": "6064ed22-fc1b-43d7-85a4-18dc578429f8",
          "name": "Time-Series Analytics",
          "type": "n8n-nodes-base.code",
          "position": [
            2544,
            304
          ],
          "parameters": {
            "jsCode": "// Time-Series Analytics: Calculate mention frequency, growth rates, and trending patterns\n\nconst items = $input.all();\n\n// Helper function to parse dates\nfunction parseDate(dateStr) {\n  return new Date(dateStr);\n}\n\n// Helper function to get time window key\nfunction getTimeWindowKey(date, window) {\n  const d = new Date(date);\n  switch(window) {\n    case 'daily':\n      return d.toISOString().split('T')[0];\n    case 'weekly':\n      const weekStart = new Date(d);\n      weekStart.setDate(d.getDate() - d.getDay());\n      return weekStart.toISOString().split('T')[0];\n    case 'monthly':\n      return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`;\n    default:\n      return d.toISOString().split('T')[0];\n  }\n}\n\n// Group data by entity/topic and time windows\nconst timeSeriesData = {};\n\nfor (const item of items) {\n  const entities = item.json.entities || [];\n  const topics = item.json.topics || [];\n  const timestamp = item.json.timestamp || item.json.publishedDate || new Date().toISOString();\n  \n  // Process entities\n  for (const entity of entities) {\n    if (!timeSeriesData[entity]) {\n      timeSeriesData[entity] = {\n        daily: {},\n        weekly: {},\n        monthly: {}\n      };\n    }\n    \n    ['daily', 'weekly', 'monthly'].forEach(window => {\n      const key = getTimeWindowKey(timestamp, window);\n      if (!timeSeriesData[entity][window][key]) {\n        timeSeriesData[entity][window][key] = 0;\n      }\n      timeSeriesData[entity][window][key]++;\n    });\n  }\n  \n  // Process topics\n  for (const topic of topics) {\n    if (!timeSeriesData[topic]) {\n      timeSeriesData[topic] = {\n        daily: {},\n        weekly: {},\n        monthly: {}\n      };\n    }\n    \n    ['daily', 'weekly', 'monthly'].forEach(window => {\n      const key = getTimeWindowKey(timestamp, window);\n      if (!timeSeriesData[topic][window][key]) {\n        timeSeriesData[topic][window][key] = 0;\n      }\n      timeSeriesData[topic][window][key]++;\n    });\n  }\n}\n\n// Calculate growth rates and moving averages\nfunction calculateMetrics(timeSeries, windowSize = 7) {\n  const sortedDates = Object.keys(timeSeries).sort();\n  const values = sortedDates.map(date => timeSeries[date]);\n  \n  // Calculate growth rate\n  const growthRates = [];\n  for (let i = 1; i < values.length; i++) {\n    const rate = values[i-1] === 0 ? 0 : ((values[i] - values[i-1]) / values[i-1]) * 100;\n    growthRates.push(rate);\n  }\n  \n  // Calculate moving average\n  const movingAverages = [];\n  for (let i = 0; i < values.length; i++) {\n    const start = Math.max(0, i - windowSize + 1);\n    const window = values.slice(start, i + 1);\n    const avg = window.reduce((sum, val) => sum + val, 0) / window.length;\n    movingAverages.push(avg);\n  }\n  \n  // Identify trending pattern\n  const recentGrowth = growthRates.slice(-3).reduce((sum, val) => sum + val, 0) / Math.min(3, growthRates.length);\n  let trend = 'stable';\n  if (recentGrowth > 20) trend = 'rising';\n  else if (recentGrowth < -20) trend = 'declining';\n  \n  return {\n    totalMentions: values.reduce((sum, val) => sum + val, 0),\n    averageGrowthRate: growthRates.length > 0 ? growthRates.reduce((sum, val) => sum + val, 0) / growthRates.length : 0,\n    recentGrowthRate: recentGrowth,\n    movingAverage: movingAverages[movingAverages.length - 1] || 0,\n    trend: trend,\n    dataPoints: sortedDates.length\n  };\n}\n\n// Generate output with analytics for each entity/topic\nconst results = [];\n\nfor (const [entityOrTopic, windows] of Object.entries(timeSeriesData)) {\n  const result = {\n    entity: entityOrTopic,\n    daily: calculateMetrics(windows.daily, 7),\n    weekly: calculateMetrics(windows.weekly, 4),\n    monthly: calculateMetrics(windows.monthly, 3),\n    rawTimeSeries: windows\n  };\n  \n  results.push(result);\n}\n\n// Sort by total mentions (daily) to prioritize high-volume entities\nresults.sort((a, b) => b.daily.totalMentions - a.daily.totalMentions);\n\nreturn results.map(result => ({ json: result }));"
          },
          "typeVersion": 2
        },
        {
          "id": "9c24ddb9-c02f-4015-b602-7af191f4e085",
          "name": "Topic Modeling & Velocity",
          "type": "n8n-nodes-base.code",
          "position": [
            2544,
            480
          ],
          "parameters": {
            "jsCode": "// Topic Modeling & Velocity Analysis using TF-IDF\n// Analyzes topic emergence, growth rate, and lifecycle stage\n\nconst items = $input.all();\n\n// Helper function to tokenize text\nfunction tokenize(text) {\n  return text.toLowerCase()\n    .replace(/[^a-z0-9\\s]/g, ' ')\n    .split(/\\s+/)\n    .filter(word => word.length > 3);\n}\n\n// Calculate TF (Term Frequency)\nfunction calculateTF(tokens) {\n  const tf = {};\n  const totalTokens = tokens.length;\n  \n  tokens.forEach(token => {\n    tf[token] = (tf[token] || 0) + 1;\n  });\n  \n  // Normalize by total tokens\n  Object.keys(tf).forEach(token => {\n    tf[token] = tf[token] / totalTokens;\n  });\n  \n  return tf;\n}\n\n// Calculate IDF (Inverse Document Frequency)\nfunction calculateIDF(documents) {\n  const idf = {};\n  const totalDocs = documents.length;\n  \n  // Count document frequency for each term\n  documents.forEach(doc => {\n    const uniqueTokens = [...new Set(doc.tokens)];\n    uniqueTokens.forEach(token => {\n      idf[token] = (idf[token] || 0) + 1;\n    });\n  });\n  \n  // Calculate IDF\n  Object.keys(idf).forEach(token => {\n    idf[token] = Math.log(totalDocs / idf[token]);\n  });\n  \n  return idf;\n}\n\n// Calculate TF-IDF scores\nfunction calculateTFIDF(tf, idf) {\n  const tfidf = {};\n  \n  Object.keys(tf).forEach(token => {\n    tfidf[token] = tf[token] * (idf[token] || 0);\n  });\n  \n  return tfidf;\n}\n\n// Extract topics from documents\nfunction extractTopics(documents, topN = 10) {\n  const allTFIDF = {};\n  \n  documents.forEach(doc => {\n    Object.keys(doc.tfidf).forEach(token => {\n      allTFIDF[token] = (allTFIDF[token] || 0) + doc.tfidf[token];\n    });\n  });\n  \n  // Sort by TF-IDF score and get top N\n  const sortedTopics = Object.entries(allTFIDF)\n    .sort((a, b) => b[1] - a[1])\n    .slice(0, topN)\n    .map(([topic, score]) => ({ topic, score }));\n  \n  return sortedTopics;\n}\n\n// Calculate topic velocity metrics\nfunction calculateTopicVelocity(documents, topic) {\n  // Group documents by time period (e.g., daily)\n  const timeGroups = {};\n  \n  documents.forEach(doc => {\n    const timestamp = new Date(doc.timestamp || doc.publishedAt || Date.now());\n    const dateKey = timestamp.toISOString().split('T')[0]; // Daily grouping\n    \n    if (!timeGroups[dateKey]) {\n      timeGroups[dateKey] = [];\n    }\n    \n    // Check if document contains the topic\n    if (doc.tokens.includes(topic)) {\n      timeGroups[dateKey].push(doc);\n    }\n  });\n  \n  // Calculate mention counts over time\n  const sortedDates = Object.keys(timeGroups).sort();\n  const mentionCounts = sortedDates.map(date => timeGroups[date].length);\n  \n  // Calculate velocity (rate of change)\n  const velocity = [];\n  for (let i = 1; i < mentionCounts.length; i++) {\n    velocity.push(mentionCounts[i] - mentionCounts[i - 1]);\n  }\n  \n  // Calculate acceleration (rate of change of velocity)\n  const acceleration = [];\n  for (let i = 1; i < velocity.length; i++) {\n    acceleration.push(velocity[i] - velocity[i - 1]);\n  }\n  \n  // Determine lifecycle stage\n  const avgVelocity = velocity.length > 0 ? velocity.reduce((a, b) => a + b, 0) / velocity.length : 0;\n  const avgAcceleration = acceleration.length > 0 ? acceleration.reduce((a, b) => a + b, 0) / acceleration.length : 0;\n  \n  let lifecycleStage = 'stable';\n  if (avgVelocity > 5 && avgAcceleration > 0) {\n    lifecycleStage = 'emerging';\n  } else if (avgVelocity > 0 && avgAcceleration < 0) {\n    lifecycleStage = 'peaking';\n  } else if (avgVelocity < -2) {\n    lifecycleStage = 'declining';\n  } else if (avgVelocity > 0) {\n    lifecycleStage = 'growing';\n  }\n  \n  return {\n    topic,\n    totalMentions: mentionCounts.reduce((a, b) => a + b, 0),\n    mentionsByDate: sortedDates.map((date, i) => ({ date, count: mentionCounts[i] })),\n    avgVelocity,\n    avgAcceleration,\n    lifecycleStage,\n    trendDirection: avgVelocity > 0 ? 'up' : avgVelocity < 0 ? 'down' : 'flat'\n  };\n}\n\n// Process documents\nconst documents = items.map(item => {\n  const content = item.json.content || item.json.text || item.json.title || '';\n  const tokens = tokenize(content);\n  \n  return {\n    ...item.json,\n    tokens,\n    timestamp: item.json.timestamp || item.json.publishedAt || item.json.createdAt || new Date().toISOString()\n  };\n});\n\n// Calculate TF for each document\ndocuments.forEach(doc => {\n  doc.tf = calculateTF(doc.tokens);\n});\n\n// Calculate IDF across all documents\nconst idf = calculateIDF(documents);\n\n// Calculate TF-IDF for each document\ndocuments.forEach(doc => {\n  doc.tfidf = calculateTFIDF(doc.tf, idf);\n});\n\n// Extract top topics\nconst topTopics = extractTopics(documents, 20);\n\n// Calculate velocity for each topic\nconst topicVelocityAnalysis = topTopics.map(({ topic, score }) => {\n  const velocityMetrics = calculateTopicVelocity(documents, topic);\n  return {\n    ...velocityMetrics,\n    tfidfScore: score\n  };\n});\n\n// Sort by emerging topics (high velocity and acceleration)\nconst emergingTopics = topicVelocityAnalysis\n  .filter(t => t.lifecycleStage === 'emerging' || t.lifecycleStage === 'growing')\n  .sort((a, b) => b.avgVelocity - a.avgVelocity);\n\n// Return analysis results\nreturn [\n  {\n    json: {\n      analysisType: 'topic_modeling_velocity',\n      timestamp: new Date().toISOString(),\n      totalDocuments: documents.length,\n      topTopics: topicVelocityAnalysis,\n      emergingTopics,\n      summary: {\n        totalTopicsAnalyzed: topTopics.length,\n        emergingCount: emergingTopics.length,\n        growingCount: topicVelocityAnalysis.filter(t => t.lifecycleStage === 'growing').length,\n        decliningCount: topicVelocityAnalysis.filter(t => t.lifecycleStage === 'declining').length,\n        stableCount: topicVelocityAnalysis.filter(t => t.lifecycleStage === 'stable').length\n      }\n    }\n  }\n];"
          },
          "typeVersion": 2
        },
        {
          "id": "4a6ed491-8a1f-4a68-9341-b0c241752fce",
          "name": "Sentiment Analysis",
          "type": "n8n-nodes-base.code",
          "position": [
            2544,
            672
          ],
          "parameters": {
            "mode": "runOnceForEachItem",
            "jsCode": "// Sentiment Analysis using lexicon-based approach\n// Analyzes sentiment scores (-1 to 1) and tracks trends over time\n\nconst item = $input.item.json;\n\n// Simple sentiment lexicon (can be expanded)\nconst positiveWords = [\n  'good', 'great', 'excellent', 'amazing', 'wonderful', 'fantastic', 'awesome',\n  'love', 'best', 'perfect', 'outstanding', 'brilliant', 'innovative', 'revolutionary',\n  'breakthrough', 'success', 'powerful', 'efficient', 'improved', 'better',\n  'exciting', 'impressive', 'superior', 'advanced', 'cutting-edge', 'promising'\n];\n\nconst negativeWords = [\n  'bad', 'terrible', 'awful', 'horrible', 'poor', 'worst', 'hate', 'disappointing',\n  'failed', 'failure', 'broken', 'bug', 'issue', 'problem', 'slow', 'difficult',\n  'complicated', 'confusing', 'outdated', 'deprecated', 'vulnerable', 'insecure',\n  'unstable', 'unreliable', 'inferior', 'lacking'\n];\n\nconst intensifiers = ['very', 'extremely', 'highly', 'incredibly', 'absolutely'];\nconst negations = ['not', 'no', 'never', 'neither', 'nobody', 'nothing', \"don't\", \"doesn't\", \"didn't\"];\n\n// Extract text content from item\nconst text = (item.content || item.text || item.title || '').toLowerCase();\nconst words = text.split(/\\W+/);\n\n// Calculate sentiment score\nlet sentimentScore = 0;\nlet positiveCount = 0;\nlet negativeCount = 0;\nlet totalWords = words.length;\n\nfor (let i = 0; i < words.length; i++) {\n  const word = words[i];\n  const prevWord = i > 0 ? words[i - 1] : '';\n  \n  // Check for intensifiers\n  const intensifier = intensifiers.includes(prevWord) ? 1.5 : 1.0;\n  \n  // Check for negations\n  const negated = negations.includes(prevWord) ? -1 : 1;\n  \n  if (positiveWords.includes(word)) {\n    const score = 1 * intensifier * negated;\n    sentimentScore += score;\n    if (score > 0) positiveCount++;\n    else negativeCount++;\n  } else if (negativeWords.includes(word)) {\n    const score = -1 * intensifier * negated;\n    sentimentScore += score;\n    if (score < 0) negativeCount++;\n    else positiveCount++;\n  }\n}\n\n// Normalize sentiment score to -1 to 1 range\nconst maxPossibleScore = totalWords;\nconst normalizedScore = maxPossibleScore > 0 ? \n  Math.max(-1, Math.min(1, sentimentScore / (maxPossibleScore * 0.1))) : 0;\n\n// Classify sentiment\nlet sentimentLabel = 'neutral';\nif (normalizedScore > 0.2) sentimentLabel = 'positive';\nelse if (normalizedScore < -0.2) sentimentLabel = 'negative';\n\n// Calculate sentiment confidence\nconst sentimentWordCount = positiveCount + negativeCount;\nconst confidence = totalWords > 0 ? sentimentWordCount / totalWords : 0;\n\n// Track sentiment trends (calculate moving average if timestamp available)\nconst timestamp = item.timestamp || item.publishedAt || item.createdAt || new Date().toISOString();\nconst date = new Date(timestamp);\n\n// Return enriched item with sentiment analysis\nreturn {\n  json: {\n    ...item,\n    sentiment: {\n      score: parseFloat(normalizedScore.toFixed(3)),\n      label: sentimentLabel,\n      confidence: parseFloat(confidence.toFixed(3)),\n      positiveWords: positiveCount,\n      negativeWords: negativeCount,\n      totalWords: totalWords,\n      timestamp: timestamp,\n      date: date.toISOString().split('T')[0],\n      hour: date.getHours(),\n      dayOfWeek: date.getDay()\n    },\n    sentimentTrend: {\n      score: normalizedScore,\n      timestamp: timestamp,\n      source: item.source || 'unknown',\n      topic: item.topic || item.category || 'general'\n    }\n  }\n};"
          },
          "typeVersion": 2
        },
        {
          "id": "f54f9bba-b2ef-4a5e-8a2f-e898b4280852",
          "name": "Changepoint Detection",
          "type": "n8n-nodes-base.code",
          "position": [
            2544,
            800
          ],
          "parameters": {
            "jsCode": "// Changepoint Detection using CUSUM and Bayesian methods\n// Detects sudden shifts in trend momentum from time-series data\n\nconst items = $input.all();\n\n// Helper function: Calculate mean\nfunction mean(arr) {\n  return arr.reduce((sum, val) => sum + val, 0) / arr.length;\n}\n\n// Helper function: Calculate standard deviation\nfunction stdDev(arr) {\n  const avg = mean(arr);\n  const squareDiffs = arr.map(val => Math.pow(val - avg, 2));\n  return Math.sqrt(mean(squareDiffs));\n}\n\n// CUSUM (Cumulative Sum) Changepoint Detection\nfunction cusumChangepoints(values, threshold = 3) {\n  const avg = mean(values);\n  const std = stdDev(values);\n  \n  let cumSum = 0;\n  let changepoints = [];\n  \n  for (let i = 0; i < values.length; i++) {\n    cumSum += (values[i] - avg) / std;\n    \n    if (Math.abs(cumSum) > threshold) {\n      changepoints.push({\n        index: i,\n        value: values[i],\n        cusum: cumSum,\n        type: cumSum > 0 ? 'upward_shift' : 'downward_shift'\n      });\n      cumSum = 0; // Reset after detection\n    }\n  }\n  \n  return changepoints;\n}\n\n// Bayesian Changepoint Detection (simplified)\nfunction bayesianChangepoints(values, prior = 0.01) {\n  const changepoints = [];\n  const n = values.length;\n  \n  for (let t = 10; t < n - 10; t++) {\n    const before = values.slice(Math.max(0, t - 10), t);\n    const after = values.slice(t, Math.min(n, t + 10));\n    \n    const meanBefore = mean(before);\n    const meanAfter = mean(after);\n    const stdBefore = stdDev(before);\n    const stdAfter = stdDev(after);\n    \n    // Calculate probability of changepoint\n    const meanDiff = Math.abs(meanAfter - meanBefore);\n    const pooledStd = Math.sqrt((stdBefore ** 2 + stdAfter ** 2) / 2);\n    \n    if (pooledStd > 0) {\n      const zScore = meanDiff / pooledStd;\n      \n      if (zScore > 2.5) { // Significant change\n        changepoints.push({\n          index: t,\n          value: values[t],\n          zScore: zScore,\n          meanBefore: meanBefore,\n          meanAfter: meanAfter,\n          type: meanAfter > meanBefore ? 'acceleration' : 'deceleration'\n        });\n      }\n    }\n  }\n  \n  return changepoints;\n}\n\n// Process each item's time-series data\nconst results = items.map(item => {\n  const data = item.json;\n  \n  // Extract time-series values (adjust field names based on your data structure)\n  const timeSeriesField = data.timeSeries || data.values || data.metrics || [];\n  const values = Array.isArray(timeSeriesField) \n    ? timeSeriesField.map(v => typeof v === 'object' ? (v.value || v.count || 0) : v)\n    : [];\n  \n  if (values.length < 20) {\n    return {\n      json: {\n        ...data,\n        changepoints: [],\n        changepointDetection: {\n          status: 'insufficient_data',\n          message: 'Need at least 20 data points for changepoint detection'\n        }\n      }\n    };\n  }\n  \n  // Run both detection methods\n  const cusumResults = cusumChangepoints(values, 3);\n  const bayesianResults = bayesianChangepoints(values, 0.01);\n  \n  // Combine and deduplicate changepoints\n  const allChangepoints = [...cusumResults, ...bayesianResults];\n  const uniqueChangepoints = [];\n  const seen = new Set();\n  \n  allChangepoints.forEach(cp => {\n    const key = `${cp.index}-${cp.type}`;\n    if (!seen.has(key)) {\n      seen.add(key);\n      uniqueChangepoints.push(cp);\n    }\n  });\n  \n  // Sort by index\n  uniqueChangepoints.sort((a, b) => a.index - b.index);\n  \n  // Calculate changepoint statistics\n  const changepointStats = {\n    totalChangepoints: uniqueChangepoints.length,\n    upwardShifts: uniqueChangepoints.filter(cp => cp.type === 'upward_shift' || cp.type === 'acceleration').length,\n    downwardShifts: uniqueChangepoints.filter(cp => cp.type === 'downward_shift' || cp.type === 'deceleration').length,\n    changepointDensity: uniqueChangepoints.length / values.length,\n    mostRecentChangepoint: uniqueChangepoints.length > 0 ? uniqueChangepoints[uniqueChangepoints.length - 1] : null\n  };\n  \n  // Determine trend momentum status\n  let momentumStatus = 'stable';\n  if (changepointStats.mostRecentChangepoint) {\n    const recentIndex = changepointStats.mostRecentChangepoint.index;\n    const recency = (values.length - recentIndex) / values.length;\n    \n    if (recency < 0.2) { // Recent changepoint (within last 20%)\n      momentumStatus = changepointStats.mostRecentChangepoint.type.includes('upward') || \n                       changepointStats.mostRecentChangepoint.type === 'acceleration' \n                       ? 'accelerating' : 'decelerating';\n    }\n  }\n  \n  return {\n    json: {\n      ...data,\n      changepoints: uniqueChangepoints,\n      changepointDetection: {\n        status: 'success',\n        stats: changepointStats,\n        momentumStatus: momentumStatus,\n        detectionMethods: ['cusum', 'bayesian'],\n        timestamp: new Date().toISOString()\n      }\n    }\n  };\n});\n\nreturn results;"
          },
          "typeVersion": 2
        },
        {
          "id": "8659195a-233c-4cfd-8697-26c3fee9f13a",
          "name": "Novelty Scoring",
          "type": "n8n-nodes-base.code",
          "position": [
            2544,
            992
          ],
          "parameters": {
            "jsCode": "// Novelty Scoring: Calculate uniqueness of content against historical baseline\n// Measures how novel current topics, entities, and signals are compared to past data\n\nconst items = $input.all();\nconst outputItems = [];\n\n// Helper function to calculate Jaccard similarity\nfunction jaccardSimilarity(set1, set2) {\n  const intersection = set1.filter(x => set2.includes(x)).length;\n  const union = new Set([...set1, ...set2]).size;\n  return union === 0 ? 0 : intersection / union;\n}\n\n// Helper function to calculate cosine similarity for numeric vectors\nfunction cosineSimilarity(vec1, vec2) {\n  if (vec1.length !== vec2.length) return 0;\n  \n  let dotProduct = 0;\n  let mag1 = 0;\n  let mag2 = 0;\n  \n  for (let i = 0; i < vec1.length; i++) {\n    dotProduct += vec1[i] * vec2[i];\n    mag1 += vec1[i] * vec1[i];\n    mag2 += vec2[i] * vec2[i];\n  }\n  \n  const magnitude = Math.sqrt(mag1) * Math.sqrt(mag2);\n  return magnitude === 0 ? 0 : dotProduct / magnitude;\n}\n\n// Process each item\nfor (const item of items) {\n  const data = item.json;\n  \n  // Extract current features\n  const currentTopics = data.topics || [];\n  const currentEntities = data.entities || [];\n  const currentSignals = data.technical_signals || [];\n  const currentKeywords = data.keywords || [];\n  \n  // Historical baseline (in production, fetch from database)\n  // For now, use a rolling window from previous items\n  const historicalWindow = items.slice(0, Math.max(0, items.indexOf(item)));\n  \n  if (historicalWindow.length === 0) {\n    // First item - assign high novelty\n    outputItems.push({\n      json: {\n        ...data,\n        novelty_score: 0.95,\n        topic_novelty: 0.95,\n        entity_novelty: 0.95,\n        signal_novelty: 0.95,\n        keyword_novelty: 0.95,\n        novelty_explanation: 'First item in dataset - baseline established',\n        is_novel: true\n      }\n    });\n    continue;\n  }\n  \n  // Calculate topic novelty\n  let topicSimilarities = [];\n  for (const histItem of historicalWindow) {\n    const histTopics = histItem.json.topics || [];\n    if (histTopics.length > 0 && currentTopics.length > 0) {\n      topicSimilarities.push(jaccardSimilarity(currentTopics, histTopics));\n    }\n  }\n  const avgTopicSimilarity = topicSimilarities.length > 0 \n    ? topicSimilarities.reduce((a, b) => a + b, 0) / topicSimilarities.length \n    : 0;\n  const topicNovelty = 1 - avgTopicSimilarity;\n  \n  // Calculate entity novelty\n  let entitySimilarities = [];\n  for (const histItem of historicalWindow) {\n    const histEntities = histItem.json.entities || [];\n    if (histEntities.length > 0 && currentEntities.length > 0) {\n      entitySimilarities.push(jaccardSimilarity(currentEntities, histEntities));\n    }\n  }\n  const avgEntitySimilarity = entitySimilarities.length > 0 \n    ? entitySimilarities.reduce((a, b) => a + b, 0) / entitySimilarities.length \n    : 0;\n  const entityNovelty = 1 - avgEntitySimilarity;\n  \n  // Calculate signal novelty\n  let signalSimilarities = [];\n  for (const histItem of historicalWindow) {\n    const histSignals = histItem.json.technical_signals || [];\n    if (histSignals.length > 0 && currentSignals.length > 0) {\n      signalSimilarities.push(jaccardSimilarity(currentSignals, histSignals));\n    }\n  }\n  const avgSignalSimilarity = signalSimilarities.length > 0 \n    ? signalSimilarities.reduce((a, b) => a + b, 0) / signalSimilarities.length \n    : 0;\n  const signalNovelty = 1 - avgSignalSimilarity;\n  \n  // Calculate keyword novelty\n  let keywordSimilarities = [];\n  for (const histItem of historicalWindow) {\n    const histKeywords = histItem.json.keywords || [];\n    if (histKeywords.length > 0 && currentKeywords.length > 0) {\n      keywordSimilarities.push(jaccardSimilarity(currentKeywords, histKeywords));\n    }\n  }\n  const avgKeywordSimilarity = keywordSimilarities.length > 0 \n    ? keywordSimilarities.reduce((a, b) => a + b, 0) / keywordSimilarities.length \n    : 0;\n  const keywordNovelty = 1 - avgKeywordSimilarity;\n  \n  // Composite novelty score (weighted average)\n  const weights = {\n    topic: 0.35,\n    entity: 0.25,\n    signal: 0.25,\n    keyword: 0.15\n  };\n  \n  const noveltyScore = (\n    topicNovelty * weights.topic +\n    entityNovelty * weights.entity +\n    signalNovelty * weights.signal +\n    keywordNovelty * weights.keyword\n  );\n  \n  // Determine if content is novel (threshold: 0.6)\n  const isNovel = noveltyScore >= 0.6;\n  \n  // Generate explanation\n  let explanation = [];\n  if (topicNovelty > 0.7) explanation.push('highly novel topics');\n  if (entityNovelty > 0.7) explanation.push('new entities');\n  if (signalNovelty > 0.7) explanation.push('unique technical signals');\n  if (keywordNovelty > 0.7) explanation.push('fresh keywords');\n  \n  const noveltyExplanation = explanation.length > 0 \n    ? `Novel content detected: ${explanation.join(', ')}` \n    : 'Content similar to historical baseline';\n  \n  outputItems.push({\n    json: {\n      ...data,\n      novelty_score: Math.round(noveltyScore * 1000) / 1000,\n      topic_novelty: Math.round(topicNovelty * 1000) / 1000,\n      entity_novelty: Math.round(entityNovelty * 1000) / 1000,\n      signal_novelty: Math.round(signalNovelty * 1000) / 1000,\n      keyword_novelty: Math.round(keywordNovelty * 1000) / 1000,\n      novelty_explanation: noveltyExplanation,\n      is_novel: isNovel,\n      historical_window_size: historicalWindow.length\n    }\n  });\n}\n\nreturn outputItems;"
          },
          "typeVersion": 2
        },
        {
          "id": "1c4677d9-f0d4-4fc6-808a-841d0da2a8f3",
          "name": "Merge Analytics Signals",
          "type": "n8n-nodes-base.merge",
          "position": [
            2816,
            464
          ],
          "parameters": {
            "numberInputs": 5
          },
          "typeVersion": 3.2
        },
        {
          "id": "cae688d8-5104-492a-b764-cfc5c80df974",
          "name": "MCDM Signal Fusion",
          "type": "n8n-nodes-base.code",
          "position": [
            3008,
            320
          ],
          "parameters": {
            "mode": "runOnceForEachItem",
            "jsCode": "// MCDM Signal Fusion using TOPSIS method\n// Combines multiple analytics signals: velocity, sentiment, changepoint, novelty, time-series growth\n\nconst item = $input.item.json;\n\n// Extract signals from merged analytics data\nconst signals = {\n  velocity: item.velocity || 0,\n  sentiment: item.sentiment || 0,\n  changepointMagnitude: item.changepointMagnitude || 0,\n  novelty: item.novelty || 0,\n  timeSeriesGrowth: item.timeSeriesGrowth || 0\n};\n\n// Define weights for each criterion (sum = 1)\nconst weights = {\n  velocity: 0.25,\n  sentiment: 0.15,\n  changepointMagnitude: 0.25,\n  novelty: 0.20,\n  timeSeriesGrowth: 0.15\n};\n\n// Normalize signals to [0, 1] range\nfunction normalize(value, min = 0, max = 100) {\n  if (max === min) return 0;\n  return (value - min) / (max - min);\n}\n\n// Normalize each signal\nconst normalized = {\n  velocity: normalize(signals.velocity, 0, 100),\n  sentiment: normalize(signals.sentiment, -1, 1),\n  changepointMagnitude: normalize(signals.changepointMagnitude, 0, 100),\n  novelty: normalize(signals.novelty, 0, 100),\n  timeSeriesGrowth: normalize(signals.timeSeriesGrowth, -50, 50)\n};\n\n// Calculate weighted normalized values\nconst weighted = {\n  velocity: normalized.velocity * weights.velocity,\n  sentiment: normalized.sentiment * weights.sentiment,\n  changepointMagnitude: normalized.changepointMagnitude * weights.changepointMagnitude,\n  novelty: normalized.novelty * weights.novelty,\n  timeSeriesGrowth: normalized.timeSeriesGrowth * weights.timeSeriesGrowth\n};\n\n// TOPSIS: Calculate ideal best and worst solutions\nconst idealBest = {\n  velocity: 1 * weights.velocity,\n  sentiment: 1 * weights.sentiment,\n  changepointMagnitude: 1 * weights.changepointMagnitude,\n  novelty: 1 * weights.novelty,\n  timeSeriesGrowth: 1 * weights.timeSeriesGrowth\n};\n\nconst idealWorst = {\n  velocity: 0,\n  sentiment: 0,\n  changepointMagnitude: 0,\n  novelty: 0,\n  timeSeriesGrowth: 0\n};\n\n// Calculate Euclidean distance to ideal best and worst\nfunction euclideanDistance(point1, point2) {\n  const keys = Object.keys(point1);\n  const sumSquares = keys.reduce((sum, key) => {\n    return sum + Math.pow(point1[key] - point2[key], 2);\n  }, 0);\n  return Math.sqrt(sumSquares);\n}\n\nconst distanceToBest = euclideanDistance(weighted, idealBest);\nconst distanceToWorst = euclideanDistance(weighted, idealWorst);\n\n// Calculate TOPSIS score (closeness coefficient)\nconst topsisScore = distanceToWorst / (distanceToBest + distanceToWorst);\n\n// Alternative: Weighted Sum Method score\nconst weightedSumScore = Object.values(weighted).reduce((sum, val) => sum + val, 0);\n\n// Calculate composite impact score (0-100 scale)\nconst impactScore = Math.round(topsisScore * 100);\n\n// Determine trend strength category\nlet trendStrength = 'Low';\nif (impactScore >= 75) trendStrength = 'Critical';\nelse if (impactScore >= 60) trendStrength = 'High';\nelse if (impactScore >= 40) trendStrength = 'Medium';\n\n// Return enriched data with MCDM scores\nreturn {\n  json: {\n    ...item,\n    mcdm: {\n      topsisScore: Math.round(topsisScore * 1000) / 1000,\n      weightedSumScore: Math.round(weightedSumScore * 1000) / 1000,\n      impactScore: impactScore,\n      trendStrength: trendStrength,\n      signalBreakdown: {\n        velocity: signals.velocity,\n        sentiment: signals.sentiment,\n        changepointMagnitude: signals.changepointMagnitude,\n        novelty: signals.novelty,\n        timeSeriesGrowth: signals.timeSeriesGrowth\n      },\n      normalizedSignals: normalized,\n      weightedSignals: weighted,\n      distanceToBest: Math.round(distanceToBest * 1000) / 1000,\n      distanceToWorst: Math.round(distanceToWorst * 1000) / 1000\n    }\n  }\n};"
          },
          "typeVersion": 2
        },
        {
          "id": "65b3005f-d59a-4fbb-a126-0e5cf81e43a6",
          "name": "Rank Trends by Impact",
          "type": "n8n-nodes-base.code",
          "position": [
            3232,
            320
          ],
          "parameters": {
            "jsCode": "// Rank trends by combined impact score, relevance, and maturity stage\n\nconst items = $input.all();\n\n// Process and rank trends\nconst rankedTrends = items.map((item, index) => {\n  const data = item.json;\n  \n  // Extract signals from merged analytics\n  const impactScore = data.impactScore || 0;\n  const velocityScore = data.velocityScore || 0;\n  const sentimentScore = data.sentimentScore || 0;\n  const noveltyScore = data.noveltyScore || 0;\n  const changepointScore = data.changepointScore || 0;\n  \n  // Calculate relevance to AI domain (0-1 scale)\n  const aiKeywords = ['ai', 'artificial intelligence', 'machine learning', 'ml', 'deep learning', \n                      'neural network', 'llm', 'gpt', 'transformer', 'nlp', 'computer vision',\n                      'reinforcement learning', 'generative', 'diffusion', 'embedding'];\n  \n  const topic = (data.topic || '').toLowerCase();\n  const content = (data.content || '').toLowerCase();\n  const combinedText = topic + ' ' + content;\n  \n  const relevanceScore = aiKeywords.reduce((score, keyword) => {\n    return score + (combinedText.includes(keyword) ? 1 : 0);\n  }, 0) / aiKeywords.length;\n  \n  // Determine maturity stage based on velocity and time metrics\n  let maturityStage = 'emerging';\n  const mentionCount = data.mentionCount || 0;\n  const growthRate = data.growthRate || 0;\n  \n  if (mentionCount > 100 && growthRate < 0.1) {\n    maturityStage = 'mature';\n  } else if (mentionCount > 100 && growthRate < 0) {\n    maturityStage = 'declining';\n  } else if (mentionCount > 20 && growthRate > 0.2) {\n    maturityStage = 'growing';\n  }\n  \n  // Calculate combined impact score with weighted factors\n  const combinedImpact = (\n    impactScore * 0.3 +\n    velocityScore * 0.2 +\n    sentimentScore * 0.15 +\n    noveltyScore * 0.2 +\n    changepointScore * 0.15\n  ) * relevanceScore; // Multiply by relevance to prioritize AI-related trends\n  \n  return {\n    json: {\n      ...data,\n      relevanceScore,\n      maturityStage,\n      combinedImpact,\n      rankingMetrics: {\n        impactScore,\n        velocityScore,\n        sentimentScore,\n        noveltyScore,\n        changepointScore,\n        relevanceScore,\n        maturityStage\n      }\n    }\n  };\n});\n\n// Sort by combined impact score (descending)\nrankedTrends.sort((a, b) => b.json.combinedImpact - a.json.combinedImpact);\n\n// Add rank position\nrankedTrends.forEach((item, index) => {\n  item.json.rank = index + 1;\n  item.json.rankedAt = new Date().toISOString();\n});\n\nreturn rankedTrends;"
          },
          "typeVersion": 2
        },
        {
          "id": "9740d6f2-8b8e-4451-90f3-503fe625816f",
          "name": "Store Trend Rankings",
          "type": "n8n-nodes-base.postgres",
          "position": [
            3456,
            320
          ],
          "parameters": {
            "table": {
              "__rl": true,
              "mode": "name",
              "value": "={{ $('Workflow Configuration').first().json.dbTable }}_rankings"
            },
            "schema": {
              "__rl": true,
              "mode": "list",
              "value": "public"
            },
            "columns": {
              "value": {
                "rank": "={{ $json.rank }}",
                "score": "={{ $json.score }}",
                "topic": "={{ $json.topic }}",
                "signals": "={{ $json.signals }}",
                "timestamp": "={{ $json.timestamp }}"
              },
              "mappingMode": "defineBelow"
            },
            "options": {}
          },
          "typeVersion": 2.6
        },
        {
          "id": "e3c252bb-b9bc-4939-8ee2-d332b47ded1d",
          "name": "Check Alert Threshold",
          "type": "n8n-nodes-base.if",
          "position": [
            3680,
            416
          ],
          "parameters": {
            "options": {},
            "conditions": {
              "options": {
                "leftValue": "",
                "caseSensitive": false,
                "typeValidation": "loose"
              },
              "combinator": "and",
              "conditions": [
                {
                  "id": "id-1",
                  "operator": {
                    "type": "number",
                    "operation": "gt"
                  },
                  "leftValue": "={{ $('Store Trend Rankings').item.json.impactScore }}",
                  "rightValue": "={{ $('Workflow Configuration').first().json.alertThreshold }}"
                }
              ]
            }
          },
          "typeVersion": 2.2
        },
        {
          "id": "937b6195-1477-425c-8222-3e69ad6965f7",
          "name": "Generate Trend Summary",
          "type": "@n8n/n8n-nodes-langchain.openAi",
          "position": [
            3904,
            320
          ],
          "parameters": {
            "operation": "message"
          },
          "credentials": {
            "openAiApi": {
              "id": "credential-id",
              "name": "openAiApi Credential"
            }
          },
          "typeVersion": 2
        },
        {
          "id": "d62439d4-c362-41e6-a191-a47fcb47f5cb",
          "name": "Send Slack Alert",
          "type": "n8n-nodes-base.slack",
          "position": [
            4240,
            416
          ],
          "webhookId": "b2064a92-a8d1-423d-8990-e33e4b2c80c5",
          "parameters": {
            "text": "=🚨 *New AI Trend Alert*\n\n{{ $json.message }}",
            "select": "channel",
            "channelId": {
              "__rl": true,
              "mode": "id",
              "value": "<__PLACEHOLDER_VALUE__Slack channel ID or name__>"
            },
            "otherOptions": {},
            "authentication": "oAuth2"
          },
          "credentials": {
            "slackOAuth2Api": {
              "id": "credential-id",
              "name": "slackOAuth2Api Credential"
            }
          },
          "typeVersion": 2.3
        },
        {
          "id": "9475aae7-ee6e-45df-ba41-2328cfe280d7",
          "name": "Send Email Report",
          "type": "n8n-nodes-base.gmail",
          "position": [
            4240,
            608
          ],
          "webhookId": "8ff31369-6412-4cc2-bfb8-bdec49cf612e",
          "parameters": {
            "sendTo": "<__PLACEHOLDER_VALUE__Recipient email address__>",
            "message": "={{ $json.message }}",
            "options": {},
            "subject": "=AI Trend Alert: {{ $json.trendName }}"
          },
          "credentials": {
            "gmailOAuth2": {
              "id": "credential-id",
              "name": "gmailOAuth2 Credential"
            }
          },
          "typeVersion": 2.1
        },
        {
          "id": "b13c795d-ad6b-4b2e-874f-38037130a5f2",
          "name": "Trigger Workflow Actions",
          "type": "n8n-nodes-base.httpRequest",
          "position": [
            4240,
            800
          ],
          "parameters": {
            "url": "<__PLACEHOLDER_VALUE__Workflow action API endpoint URL__>",
            "method": "POST",
            "options": {},
            "jsonBody": "={{ $json }}",
            "sendBody": true,
            "sendHeaders": true,
            "specifyBody": "json",
            "headerParameters": {
              "parameters": [
                {
                  "name": "Content-Type",
                  "value": "application/json"
                }
              ]
            }
          },
          "typeVersion": 4.3
        },
        {
          "id": "341af4d2-7b57-4001-878f-4163c00450f9",
          "name": "Store Dashboard Data",
          "type": "n8n-nodes-base.postgres",
          "position": [
            3680,
            608
          ],
          "parameters": {
            "table": {
              "__rl": true,
              "mode": "name",
              "value": "={{ $('Workflow Configuration').first().json.dashboardTable }}"
            },
            "schema": {
              "__rl": true,
              "mode": "list",
              "value": "public"
            },
            "columns": {
              "value": {
                "trend_id": "={{ $json.trend_id }}",
                "chart_data": "={{ $json.chart_data }}",
                "chart_type": "={{ $json.chart_type }}",
                "created_at": "={{ $now }}",
                "timeline_data": "={{ $json.timeline_data }}",
                "leaderboard_data": "={{ $json.leaderboard_data }}",
                "visualization_config": "={{ $json.visualization_config }}"
              },
              "mappingMode": "defineBelow"
            },
            "options": {}
          },
          "typeVersion": 2.6
        },
        {
          "id": "c7f65782-b356-4181-bc32-9efa4e60d32f",
          "name": "Track KPIs",
          "type": "n8n-nodes-base.postgres",
          "position": [
            3680,
            800
          ],
          "parameters": {
            "table": {
              "__rl": true,
              "mode": "name",
              "value": "={{ $('Workflow Configuration').first().json.kpiTable }}"
            },
            "schema": {
              "__rl": true,
              "mode": "list",
              "value": "public"
            },
            "columns": {
              "value": {
                "recall": "={{ $json.recall }}",
                "trend_id": "={{ $json.trend_id }}",
                "precision": "={{ $json.precision }}",
                "timestamp": "={{ $now.toISO() }}",
                "alert_accuracy": "={{ $json.alert_accuracy }}",
                "trend_lead_time": "={{ $json.trend_lead_time }}",
                "detection_latency": "={{ $json.detection_latency }}",
                "downstream_impact": "={{ $json.downstream_impact }}",
                "false_positive_rate": "={{ $json.false_positive_rate }}"
              },
              "schema": [],
              "mappingMode": "defineBelow",
              "matchingColumns": []
            },
            "options": {}
          },
          "typeVersion": 2.6
        },
        {
          "id": "9300c075-225d-4c5d-b840-44538a321c82",
          "name": "Sticky Note",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            336,
            -48
          ],
          "parameters": {
            "width": 464,
            "height": 240,
            "content": "## How It Works\nA scheduled process aggregates content from eight distinct data sources and standardizes all inputs into a unified format. AI models perform sentiment scoring, detect conspiracy or misinformation signals, and generate trend analyses across domains. An MCDN routing model prioritizes and channels insights to the appropriate workflows. Dashboards visualize real-time analytics, trigger KPIs based on thresholds, and compile comprehensive market-intelligence reports for stakeholders."
          },
          "typeVersion": 1
        },
        {
          "id": "1d58006c-94ed-410c-9238-aef234cffd12",
          "name": "Sticky Note3",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            816,
            -48
          ],
          "parameters": {
            "width": 480,
            "height": 256,
            "content": "## Setup Steps\n1. **Data Sources:** Connect news APIs, social media platforms, academic databases, code repositories, and documentation feeds.\n2. **AI Analysis:** Configure OpenAI models for sentiment analysis, conspiracy detection, and trend scoring.\n3. **Dashboards:** Integrate analytics platforms and enable automated email or reporting outputs.\n4. **Storage:** Configure a database for historical records, trend archives, and competitive-intelligence storage."
          },
          "typeVersion": 1
        },
        {
          "id": "e1c5bcad-64e9-4084-9cd9-aeee207a2fbf",
          "name": "Sticky Note4",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            2000,
            -32
          ],
          "parameters": {
            "color": 4,
            "width": 432,
            "height": 224,
            "content": "## Customization\nAdjust sentiment thresholds; add/remove data sources; modify analysis rules; extend AI models\n\n## Benefits\nReduces research time 80%; consolidates market intelligence; improves decision accuracy"
          },
          "typeVersion": 1
        },
        {
          "id": "fbe7866c-2701-49a9-b458-9a2506b8b592",
          "name": "Sticky Note5",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            1312,
            -48
          ],
          "parameters": {
            "color": 6,
            "width": 656,
            "height": 240,
            "content": "## Prerequisites\nMulti-source API credentials; OpenAI API key; dashboard platform access; email service; code repository access; academic database credentials\n\n## Use Cases\nCompetitive intelligence monitoring; market trend analysis; technology landscape tracking; product strategy research; misinformation filtering"
          },
          "typeVersion": 1
        },
        {
          "id": "fe5669b8-0743-4e76-a568-0527267b29a9",
          "name": "Sticky Note1",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            352,
            224
          ],
          "parameters": {
            "color": 7,
            "width": 416,
            "height": 336,
            "content": "## Schedule Daily Collection\nTriggers workflow to fetch news, blogs, social media, academic papers, code, docs\nWhy: Daily cadence captures emerging trends before competitors react"
          },
          "typeVersion": 1
        },
        {
          "id": "0ee5a556-a74b-46ad-8a59-46724f008b65",
          "name": "Sticky Note2",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            784,
            224
          ],
          "parameters": {
            "color": 7,
            "height": 1456,
            "content": "## Fetch News & Blog Content\nRetrieves articles from tech news sites, industry publications\nWhy: News breaks market shifts earliest\n"
          },
          "typeVersion": 1
        },
        {
          "id": "74636813-6e90-4a32-a3e5-cbdea263fc6d",
          "name": "Sticky Note6",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            1040,
            224
          ],
          "parameters": {
            "color": 7,
            "width": 272,
            "height": 736,
            "content": "## Aggregate Market Discussions\nCollects earnings calls, investor presentations\nWhy: Direct stakeholder commentary reveals strategy and positioning"
          },
          "typeVersion": 1
        },
        {
          "id": "bfd645a5-7624-4a29-b54a-5fa5747a0aba",
          "name": "Sticky Note7",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            1680,
            240
          ],
          "parameters": {
            "color": 7,
            "width": 736,
            "height": 432,
            "content": "## Extract Content & Parse Structure, Storage\nConverts PDFs, web pages, videos, code into machine-readable text with metadata\nWhy: Unified parsing enables cross-source analysis; structures data surfaces patterns\n"
          },
          "typeVersion": 1
        },
        {
          "id": "3d99cba6-840d-4626-bdfb-65ac763cd3ab",
          "name": "Sticky Note8",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            1328,
            224
          ],
          "parameters": {
            "color": 7,
            "width": 336,
            "height": 448,
            "content": "\n## Normalize All Formats and Duplicate\nStandardizes timestamps, authorship, hierarchy, classification across datasets\nWhy: Enables comparison"
          },
          "typeVersion": 1
        },
        {
          "id": "d57af54c-e831-4dc1-bacf-38dd29a635c3",
          "name": "Sticky Note9",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            2448,
            112
          ],
          "parameters": {
            "color": 7,
            "width": 272,
            "height": 1040,
            "content": "## Sentiment Analysis Across Sources\nScores tone: positive, negative, neutral, urgency for each piece\nWhy: Sentiment reveals market mood"
          },
          "typeVersion": 1
        },
        {
          "id": "5b5c1356-57fc-4ac3-aeca-0bbfd1a4f83e",
          "name": "Sticky Note10",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            2736,
            112
          ],
          "parameters": {
            "color": 7,
            "width": 208,
            "height": 624,
            "content": "## Merge Datasets for Analysis\nCombines sources into searchable repository with cross-source relationships\nWhy: Reveals connections; feature request "
          },
          "typeVersion": 1
        },
        {
          "id": "af3479c4-e236-44fd-b6fe-fba831f38338",
          "name": "Sticky Note11",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            2960,
            112
          ],
          "parameters": {
            "color": 7,
            "width": 608,
            "height": 400,
            "content": "## MCDN Signal Processing\n\nIngests market signals, ranks them by impact, and stores timestamped snapshots.\nWhy: Ensures all data enters a consistent pipeline "
          },
          "typeVersion": 1
        },
        {
          "id": "40c1655f-0315-4d99-aa1b-87898bd1e5a0",
          "name": "Sticky Note12",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            3600,
            112
          ],
          "parameters": {
            "color": 7,
            "width": 272,
            "height": 880,
            "content": "## Alert Evaluation  \n\nChecks signals against alert thresholds, generates concise trend summaries.\n**Why:** Ensures only meaningful alerts escalate, provides clear insights for decision-makers\n"
          },
          "typeVersion": 1
        },
        {
          "id": "49757569-d73f-4442-9955-0d2305d594f1",
          "name": "Sticky Note13",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            3888,
            112
          ],
          "parameters": {
            "color": 7,
            "width": 256,
            "height": 400,
            "content": "## Trend Summary\nMonitors key performance indicators and competitive metrics continuously\nWhy: KPI tracking reveals trends;  "
          },
          "typeVersion": 1
        },
        {
          "id": "747a00b5-e1e0-4bac-abf8-8eb4bd3fb059",
          "name": "Sticky Note14",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            4160,
            112
          ],
          "parameters": {
            "color": 7,
            "height": 864,
            "content": "## Output & Alerts\n\nSends critical signals via Slack, emails full analysis reports \n**Why:** Ensures fast team visibility, provides detailed context "
          },
          "typeVersion": 1
        }
      ],
      "active": false,
      "pinData": {},
      "settings": {
        "executionOrder": "v1"
      },
      "versionId": "b475a3ae-2269-46dd-8062-eaf64b82a026",
      "connections": {
        "Store Raw Data": {
          "main": [
            [
              {
                "node": "Time-Series Analytics",
                "type": "main",
                "index": 0
              },
              {
                "node": "Topic Modeling & Velocity",
                "type": "main",
                "index": 0
              },
              {
                "node": "Sentiment Analysis",
                "type": "main",
                "index": 0
              },
              {
                "node": "Changepoint Detection",
                "type": "main",
                "index": 0
              },
              {
                "node": "Novelty Scoring",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Novelty Scoring": {
          "main": [
            [
              {
                "node": "Merge Analytics Signals",
                "type": "main",
                "index": 4
              }
            ]
          ]
        },
        "Fetch Blog Posts": {
          "main": [
            [
              {
                "node": "Merge All Sources",
                "type": "main",
                "index": 1
              }
            ]
          ]
        },
        "Fetch Code Repos": {
          "main": [
            [
              {
                "node": "Merge All Sources",
                "type": "main",
                "index": 4
              }
            ]
          ]
        },
        "Merge All Sources": {
          "main": [
            [
              {
                "node": "Normalize Content Schema",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Fetch Product Docs": {
          "main": [
            [
              {
                "node": "Merge All Sources",
                "type": "main",
                "index": 6
              }
            ]
          ]
        },
        "Fetch Social Media": {
          "main": [
            [
              {
                "node": "Merge All Sources",
                "type": "main",
                "index": 2
              }
            ]
          ]
        },
        "MCDM Signal Fusion": {
          "main": [
            [
              {
                "node": "Rank Trends by Impact",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Sentiment Analysis": {
          "main": [
            [
              {
                "node": "Merge Analytics Signals",
                "type": "main",
                "index": 2
              }
            ]
          ]
        },
        "Deduplicate Content": {
          "main": [
            [
              {
                "node": "Extract Entities & Topics",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Fetch News Articles": {
          "main": [
            [
              {
                "node": "Merge All Sources",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Store Trend Rankings": {
          "main": [
            [
              {
                "node": "Check Alert Threshold",
                "type": "main",
                "index": 0
              },
              {
                "node": "Store Dashboard Data",
                "type": "main",
                "index": 0
              },
              {
                "node": "Track KPIs",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Changepoint Detection": {
          "main": [
            [
              {
                "node": "Merge Analytics Signals",
                "type": "main",
                "index": 3
              }
            ]
          ]
        },
        "Check Alert Threshold": {
          "main": [
            [
              {
                "node": "Generate Trend Summary",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Fetch Academic Papers": {
          "main": [
            [
              {
                "node": "Merge All Sources",
                "type": "main",
                "index": 3
              }
            ]
          ]
        },
        "Rank Trends by Impact": {
          "main": [
            [
              {
                "node": "Store Trend Rankings",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Time-Series Analytics": {
          "main": [
            [
              {
                "node": "Merge Analytics Signals",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Generate Trend Summary": {
          "main": [
            [
              {
                "node": "Send Slack Alert",
                "type": "main",
                "index": 0
              },
              {
                "node": "Send Email Report",
                "type": "main",
                "index": 0
              },
              {
                "node": "Trigger Workflow Actions",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Workflow Configuration": {
          "main": [
            [
              {
                "node": "Fetch News Articles",
                "type": "main",
                "index": 0
              },
              {
                "node": "Fetch Blog Posts",
                "type": "main",
                "index": 0
              },
              {
                "node": "Fetch Social Media",
                "type": "main",
                "index": 0
              },
              {
                "node": "Fetch Academic Papers",
                "type": "main",
                "index": 0
              },
              {
                "node": "Fetch Code Repos",
                "type": "main",
                "index": 0
              },
              {
                "node": "Fetch Forum Discussions",
                "type": "main",
                "index": 0
              },
              {
                "node": "Fetch Product Docs",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Fetch Forum Discussions": {
          "main": [
            [
              {
                "node": "Merge All Sources",
                "type": "main",
                "index": 5
              }
            ]
          ]
        },
        "Merge Analytics Signals": {
          "main": [
            [
              {
                "node": "MCDM Signal Fusion",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Parse Technical Signals": {
          "main": [
            [
              {
                "node": "Store Raw Data",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Normalize Content Schema": {
          "main": [
            [
              {
                "node": "Deduplicate Content",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Schedule Data Collection": {
          "main": [
            [
              {
                "node": "Workflow Configuration",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Extract Entities & Topics": {
          "main": [
            [
              {
                "node": "Parse Technical Signals",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Topic Modeling & Velocity": {
          "main": [
            [
              {
                "node": "Merge Analytics Signals",
                "type": "main",
                "index": 1
              }
            ]
          ]
        }
      }
    },
    "lastUpdatedBy": 1,
    "workflowInfo": {
      "nodeCount": 46,
      "nodeTypes": {
        "n8n-nodes-base.if": {
          "count": 1
        },
        "n8n-nodes-base.set": {
          "count": 1
        },
        "n8n-nodes-base.code": {
          "count": 9
        },
        "n8n-nodes-base.gmail": {
          "count": 1
        },
        "n8n-nodes-base.merge": {
          "count": 2
        },
        "n8n-nodes-base.slack": {
          "count": 1
        },
        "n8n-nodes-base.postgres": {
          "count": 4
        },
        "n8n-nodes-base.stickyNote": {
          "count": 15
        },
        "n8n-nodes-base.httpRequest": {
          "count": 8
        },
        "n8n-nodes-base.scheduleTrigger": {
          "count": 1
        },
        "@n8n/n8n-nodes-langchain.openAi": {
          "count": 2
        },
        "n8n-nodes-base.removeDuplicates": {
          "count": 1
        }
      }
    },
    "status": "published",
    "user": {
      "name": "Cheng Siong Chin",
      "username": "cschin",
      "bio": "Dr. Cheng Siong CHIN is an n8n workflow creator specializing in AI-powered automation, agent orchestration, and intelligent system integrations. He designs and builds end-to-end workflows that combine LLMs, APIs, and data pipelines to streamline complex processes and deliver production-ready automation solutions. Contact me to discuss custom AI workflows and agent architectures.\n",
      "verified": true,
      "links": [
        "https://gravatar.com/mysticluminary9fa255f7f5"
      ],
      "avatar": "https://gravatar.com/avatar/54544f98e839bb9dd9a764ad1e6823eeddb6db5138d201e42f291a7b0a73303f?r=pg&d=retro&size=200"
    },
    "nodes": [
      {
        "id": 19,
        "icon": "file:httprequest.svg",
        "name": "n8n-nodes-base.httpRequest",
        "codex": {
          "data": {
            "alias": [
              "API",
              "Request",
              "URL",
              "Build",
              "cURL"
            ],
            "resources": {
              "generic": [
                {
                  "url": "https://n8n.io/blog/2021-the-year-to-automate-the-new-you-with-n8n/",
                  "icon": "☀️",
                  "label": "2021: The Year to Automate the New You with n8n"
                },
                {
                  "url": "https://n8n.io/blog/why-business-process-automation-with-n8n-can-change-your-daily-life/",
                  "icon": "🧬",
                  "label": "Why business process automation with n8n can change your daily life"
                },
                {
                  "url": "https://n8n.io/blog/automatically-pulling-and-visualizing-data-with-n8n/",
                  "icon": "📈",
                  "label": "Automatically pulling and visualizing data with n8n"
                },
                {
                  "url": "https://n8n.io/blog/learn-how-to-automatically-cross-post-your-content-with-n8n/",
                  "icon": "✍️",
                  "label": "Learn how to automatically cross-post your content with n8n"
                },
                {
                  "url": "https://n8n.io/blog/automatically-adding-expense-receipts-to-google-sheets-with-telegram-mindee-twilio-and-n8n/",
                  "icon": "🧾",
                  "label": "Automatically Adding Expense Receipts to Google Sheets with Telegram, Mindee, Twilio, and n8n"
                },
                {
                  "url": "https://n8n.io/blog/running-n8n-on-ships-an-interview-with-maranics/",
                  "icon": "🛳",
                  "label": "Running n8n on ships: An interview with Maranics"
                },
                {
                  "url": "https://n8n.io/blog/what-are-apis-how-to-use-them-with-no-code/",
                  "icon": " 🪢",
                  "label": "What are APIs and how to use them with no code"
                },
                {
                  "url": "https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/",
                  "icon": "⚡️",
                  "label": "5 tasks you can automate with the new Notion API "
                },
                {
                  "url": "https://n8n.io/blog/world-poetry-day-workflow/",
                  "icon": "📜",
                  "label": "Celebrating World Poetry Day with a daily poem in Telegram"
                },
                {
                  "url": "https://n8n.io/blog/automate-google-apps-for-productivity/",
                  "icon": "💡",
                  "label": "15 Google apps you can combine and automate to increase productivity"
                },
                {
                  "url": "https://n8n.io/blog/automate-designs-with-bannerbear-and-n8n/",
                  "icon": "🎨",
                  "label": "Automate Designs with Bannerbear and n8n"
                },
                {
                  "url": "https://n8n.io/blog/how-uproc-scraped-a-multi-page-website-with-a-low-code-workflow/",
                  "icon": " 🕸️",
                  "label": "How uProc scraped a multi-page website with a low-code workflow"
                },
                {
                  "url": "https://n8n.io/blog/building-an-expense-tracking-app-in-10-minutes/",
                  "icon": "📱",
                  "label": "Building an expense tracking app in 10 minutes"
                },
                {
                  "url": "https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/",
                  "icon": "🤖",
                  "label": "5 workflow automations for Mattermost that we love at n8n"
                },
                {
                  "url": "https://n8n.io/blog/how-to-use-the-http-request-node-the-swiss-army-knife-for-workflow-automation/",
                  "icon": "🧰",
                  "label": "How to use the HTTP Request Node - The Swiss Army Knife for Workflow Automation"
                },
                {
                  "url": "https://n8n.io/blog/learn-how-to-use-webhooks-with-mattermost-slash-commands/",
                  "icon": "🦄",
                  "label": "Learn how to use webhooks with Mattermost slash commands"
                },
                {
                  "url": "https://n8n.io/blog/how-a-membership-development-manager-automates-his-work-and-investments/",
                  "icon": "📈",
                  "label": "How a Membership Development Manager automates his work and investments"
                },
                {
                  "url": "https://n8n.io/blog/a-low-code-bitcoin-ticker-built-with-questdb-and-n8n-io/",
                  "icon": "📈",
                  "label": "A low-code bitcoin ticker built with QuestDB and n8n.io"
                },
                {
                  "url": "https://n8n.io/blog/how-to-set-up-a-ci-cd-pipeline-with-no-code/",
                  "icon": "🎡",
                  "label": "How to set up a no-code CI/CD pipeline with GitHub and TravisCI"
                },
                {
                  "url": "https://n8n.io/blog/automations-for-activists/",
                  "icon": "✨",
                  "label": "How Common Knowledge use workflow automation for activism"
                },
                {
                  "url": "https://n8n.io/blog/creating-scheduled-text-affirmations-with-n8n/",
                  "icon": "🤟",
                  "label": "Creating scheduled text affirmations with n8n"
                },
                {
                  "url": "https://n8n.io/blog/how-goomer-automated-their-operations-with-over-200-n8n-workflows/",
                  "icon": "🛵",
                  "label": "How Goomer automated their operations with over 200 n8n workflows"
                },
                {
                  "url": "https://n8n.io/blog/aws-workflow-automation/",
                  "label": "7 no-code workflow automations for Amazon Web Services"
                }
              ],
              "primaryDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/"
                }
              ]
            },
            "categories": [
              "Development",
              "Core Nodes"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0",
            "subcategories": {
              "Core Nodes": [
                "Helpers"
              ]
            }
          }
        },
        "group": "[\"output\"]",
        "defaults": {
          "name": "HTTP Request",
          "color": "#0004F5"
        },
        "iconData": {
          "type": "file",
          "fileBuffer": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHZpZXdCb3g9IjAgMCA0MCA0MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00MCAyMEM0MCA4Ljk1MzE0IDMxLjA0NjkgMCAyMCAwQzguOTUzMTQgMCAwIDguOTUzMTQgMCAyMEMwIDMxLjA0NjkgOC45NTMxNCA0MCAyMCA0MEMzMS4wNDY5IDQwIDQwIDMxLjA0NjkgNDAgMjBaTTIwIDM2Ljk0NThDMTguODg1MiAzNi45NDU4IDE3LjEzNzggMzUuOTY3IDE1LjQ5OTggMzIuNjk4NUMxNC43OTY0IDMxLjI5MTggMTQuMTk2MSAyOS41NDMxIDEzLjc1MjYgMjcuNjg0N0gyNi4xODk4QzI1LjgwNDUgMjkuNTQwMyAyNS4yMDQ0IDMxLjI5MDEgMjQuNTAwMiAzMi42OTg1QzIyLjg2MjIgMzUuOTY3IDIxLjExNDggMzYuOTQ1OCAyMCAzNi45NDU4Wk0xMi45MDY0IDIwQzEyLjkwNjQgMjEuNjA5NyAxMy4wMDg3IDIzLjE2NCAxMy4yMDAzIDI0LjYzMDVIMjYuNzk5N0MyNi45OTEzIDIzLjE2NCAyNy4wOTM2IDIxLjYwOTcgMjcuMDkzNiAyMEMyNy4wOTM2IDE4LjM5MDMgMjYuOTkxMyAxNi44MzYgMjYuNzk5NyAxNS4zNjk1SDEzLjIwMDNDMTMuMDA4NyAxNi44MzYgMTIuOTA2NCAxOC4zOTAzIDEyLjkwNjQgMjBaTTIwIDMuMDU0MTlDMjEuMTE0OSAzLjA1NDE5IDIyLjg2MjIgNC4wMzA3OCAyNC41MDAxIDcuMzAwMzlDMjUuMjA2NiA4LjcxNDA4IDI1LjgwNzIgMTAuNDA2NyAyNi4xOTIgMTIuMzE1M0gxMy43NTAxQzE0LjE5MzMgMTAuNDA0NyAxNC43OTQyIDguNzEyNTQgMTUuNDk5OCA3LjMwMDY0QzE3LjEzNzcgNC4wMzA4MyAxOC44ODUxIDMuMDU0MTkgMjAgMy4wNTQxOVpNMzAuMTQ3OCAyMEMzMC4xNDc4IDE4LjQwOTkgMzAuMDU0MyAxNi44NjE3IDI5LjgyMjcgMTUuMzY5NUgzNi4zMDQyQzM2LjcyNTIgMTYuODQyIDM2Ljk0NTggMTguMzk2NCAzNi45NDU4IDIwQzM2Ljk0NTggMjEuNjAzNiAzNi43MjUyIDIzLjE1OCAzNi4zMDQyIDI0LjYzMDVIMjkuODIyN0MzMC4wNTQzIDIzLjEzODMgMzAuMTQ3OCAyMS41OTAxIDMwLjE0NzggMjBaTTI2LjI3NjcgNC4yNTUxMkMyNy42MzY1IDYuMzYwMTkgMjguNzExIDkuMTMyIDI5LjM3NzQgMTIuMzE1M0gzNS4xMDQ2QzMzLjI1MTEgOC42NjggMzAuMTA3IDUuNzgzNDYgMjYuMjc2NyA0LjI1NTEyWk0xMC42MjI2IDEyLjMxNTNINC44OTI5M0M2Ljc1MTQ3IDguNjY3ODQgOS44OTM1MSA1Ljc4MzQxIDEzLjcyMzIgNC4yNTUxM0MxMi4zNjM1IDYuMzYwMjEgMTEuMjg5IDkuMTMyMDEgMTAuNjIyNiAxMi4zMTUzWk0zLjA1NDE5IDIwQzMuMDU0MTkgMjEuNjAzIDMuMjc3NDMgMjMuMTU3NSAzLjY5NDg0IDI0LjYzMDVIMTAuMTIxN0M5Ljk0NjE5IDIzLjE0MiA5Ljg1MjIyIDIxLjU5NDMgOS44NTIyMiAyMEM5Ljg1MjIyIDE4LjQwNTcgOS45NDYxOSAxNi44NTggMTAuMTIxNyAxNS4zNjk1SDMuNjk0ODRDMy4yNzc0MyAxNi44NDI1IDMuMDU0MTkgMTguMzk3IDMuMDU0MTkgMjBaTTI2LjI3NjYgMzUuNzQyN0MyNy42MzY1IDMzLjYzOTMgMjguNzExIDMwLjg2OCAyOS4zNzc0IDI3LjY4NDdIMzUuMTA0NkMzMy4yNTEgMzEuMzMyMiAzMC4xMDY4IDM0LjIxNzkgMjYuMjc2NiAzNS43NDI3Wk0xMy43MjM0IDM1Ljc0MjdDOS44OTM2OSAzNC4yMTc5IDYuNzUxNTUgMzEuMzMyNCA0Ljg5MjkzIDI3LjY4NDdIMTAuNjIyNkMxMS4yODkgMzAuODY4IDEyLjM2MzUgMzMuNjM5MyAxMy43MjM0IDM1Ljc0MjdaIiBmaWxsPSIjM0E0MkU5Ii8+Cjwvc3ZnPgo="
        },
        "displayName": "HTTP Request",
        "typeVersion": 4,
        "nodeCategories": [
          {
            "id": 5,
            "name": "Development"
          },
          {
            "id": 9,
            "name": "Core Nodes"
          }
        ]
      },
      {
        "id": 20,
        "icon": "fa:map-signs",
        "name": "n8n-nodes-base.if",
        "codex": {
          "data": {
            "alias": [
              "Router",
              "Filter",
              "Condition",
              "Logic",
              "Boolean",
              "Branch"
            ],
            "details": "The IF node can be used to implement binary conditional logic in your workflow. You can set up one-to-many conditions to evaluate each item of data being inputted into the node. That data will either evaluate to TRUE or FALSE and route out of the node accordingly.\n\nThis node has multiple types of conditions: Bool, String, Number, and Date & Time.",
            "resources": {
              "generic": [
                {
                  "url": "https://n8n.io/blog/learn-to-automate-your-factorys-incident-reporting-a-step-by-step-guide/",
                  "icon": "🏭",
                  "label": "Learn to Automate Your Factory's Incident Reporting: A Step by Step Guide"
                },
                {
                  "url": "https://n8n.io/blog/2021-the-year-to-automate-the-new-you-with-n8n/",
                  "icon": "☀️",
                  "label": "2021: The Year to Automate the New You with n8n"
                },
                {
                  "url": "https://n8n.io/blog/why-business-process-automation-with-n8n-can-change-your-daily-life/",
                  "icon": "🧬",
                  "label": "Why business process automation with n8n can change your daily life"
                },
                {
                  "url": "https://n8n.io/blog/create-a-toxic-language-detector-for-telegram/",
                  "icon": "🤬",
                  "label": "Create a toxic language detector for Telegram in 4 step"
                },
                {
                  "url": "https://n8n.io/blog/no-code-ecommerce-workflow-automations/",
                  "icon": "store",
                  "label": "6 e-commerce workflows to power up your Shopify s"
                },
                {
                  "url": "https://n8n.io/blog/how-to-build-a-low-code-self-hosted-url-shortener/",
                  "icon": "🔗",
                  "label": "How to build a low-code, self-hosted URL shortener in 3 steps"
                },
                {
                  "url": "https://n8n.io/blog/automate-your-data-processing-pipeline-in-9-steps-with-n8n/",
                  "icon": "⚙️",
                  "label": "Automate your data processing pipeline in 9 steps"
                },
                {
                  "url": "https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/",
                  "icon": "👥",
                  "label": "How to get started with CRM automation (with 3 no-code workflow ideas"
                },
                {
                  "url": "https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/",
                  "icon": "⚡️",
                  "label": "5 tasks you can automate with the new Notion API "
                },
                {
                  "url": "https://n8n.io/blog/automate-google-apps-for-productivity/",
                  "icon": "💡",
                  "label": "15 Google apps you can combine and automate to increase productivity"
                },
                {
                  "url": "https://n8n.io/blog/automation-for-maintainers-of-open-source-projects/",
                  "icon": "🏷️",
                  "label": "How to automatically manage contributions to open-source projects"
                },
                {
                  "url": "https://n8n.io/blog/how-uproc-scraped-a-multi-page-website-with-a-low-code-workflow/",
                  "icon": " 🕸️",
                  "label": "How uProc scraped a multi-page website with a low-code workflow"
                },
                {
                  "url": "https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/",
                  "icon": "🤖",
                  "label": "5 workflow automations for Mattermost that we love at n8n"
                },
                {
                  "url": "https://n8n.io/blog/why-this-product-manager-loves-workflow-automation-with-n8n/",
                  "icon": "🧠",
                  "label": "Why this Product Manager loves workflow automation with n8n"
                },
                {
                  "url": "https://n8n.io/blog/sending-automated-congratulations-with-google-sheets-twilio-and-n8n/",
                  "icon": "🙌",
                  "label": "Sending Automated Congratulations with Google Sheets, Twilio, and n8n "
                },
                {
                  "url": "https://n8n.io/blog/how-to-set-up-a-ci-cd-pipeline-with-no-code/",
                  "icon": "🎡",
                  "label": "How to set up a no-code CI/CD pipeline with GitHub and TravisCI"
                },
                {
                  "url": "https://n8n.io/blog/benefits-of-automation-and-n8n-an-interview-with-hubspots-hugh-durkin/",
                  "icon": "🎖",
                  "label": "Benefits of automation and n8n: An interview with HubSpot's Hugh Durkin"
                },
                {
                  "url": "https://n8n.io/blog/aws-workflow-automation/",
                  "label": "7 no-code workflow automations for Amazon Web Services"
                }
              ],
              "primaryDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.if/"
                }
              ]
            },
            "categories": [
              "Core Nodes"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0",
            "subcategories": {
              "Core Nodes": [
                "Flow"
              ]
            }
          }
        },
        "group": "[\"transform\"]",
        "defaults": {
          "name": "If",
          "color": "#408000"
        },
        "iconData": {
          "icon": "map-signs",
          "type": "icon"
        },
        "displayName": "If",
        "typeVersion": 2,
        "nodeCategories": [
          {
            "id": 9,
            "name": "Core Nodes"
          }
        ]
      },
      {
        "id": 24,
        "icon": "file:merge.svg",
        "name": "n8n-nodes-base.merge",
        "codex": {
          "data": {
            "alias": [
              "Join",
              "Concatenate",
              "Wait"
            ],
            "resources": {
              "generic": [
                {
                  "url": "https://n8n.io/blog/how-to-sync-data-between-two-systems/",
                  "icon": "🏬",
                  "label": "How to synchronize data between two systems (one-way vs. two-way sync"
                },
                {
                  "url": "https://n8n.io/blog/supercharging-your-conference-registration-process-with-n8n/",
                  "icon": "🎫",
                  "label": "Supercharging your conference registration process with n8n"
                },
                {
                  "url": "https://n8n.io/blog/migrating-community-metrics-to-orbit-using-n8n/",
                  "icon": "📈",
                  "label": "Migrating Community Metrics to Orbit using n8n"
                },
                {
                  "url": "https://n8n.io/blog/build-your-own-virtual-assistant-with-n8n-a-step-by-step-guide/",
                  "icon": "👦",
                  "label": "Build your own virtual assistant with n8n: A step by step guide"
                },
                {
                  "url": "https://n8n.io/blog/sending-automated-congratulations-with-google-sheets-twilio-and-n8n/",
                  "icon": "🙌",
                  "label": "Sending Automated Congratulations with Google Sheets, Twilio, and n8n "
                },
                {
                  "url": "https://n8n.io/blog/aws-workflow-automation/",
                  "label": "7 no-code workflow automations for Amazon Web Services"
                }
              ],
              "primaryDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.merge/"
                }
              ]
            },
            "categories": [
              "Core Nodes"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0",
            "subcategories": {
              "Core Nodes": [
                "Flow",
                "Data Transformation"
              ]
            }
          }
        },
        "group": "[\"transform\"]",
        "defaults": {
          "name": "Merge"
        },
        "iconData": {
          "type": "file",
          "fileBuffer": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xMTc3XzUxOCkiPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTAgNDhDMCAyMS40OTAzIDIxLjQ5MDMgMCA0OCAwSDExMkMxMzguNTEgMCAxNjAgMjEuNDkwMyAxNjAgNDhWNTZIMTk2LjI1MkMyNDAuNDM1IDU2IDI3Ni4yNTIgOTEuODE3MiAyNzYuMjUyIDEzNlYxOTJDMjc2LjI1MiAyMTQuMDkxIDI5NC4xNjEgMjMyIDMxNi4yNTIgMjMySDM1MlYyMjRDMzUyIDE5Ny40OSAzNzMuNDkgMTc2IDQwMCAxNzZINDY0QzQ5MC41MSAxNzYgNTEyIDE5Ny40OSA1MTIgMjI0VjI4OEM1MTIgMzE0LjUxIDQ5MC41MSAzMzYgNDY0IDMzNkg0MDBDMzczLjQ5IDMzNiAzNTIgMzE0LjUxIDM1MiAyODhWMjgwSDMxNi4yNTJDMjk0LjE2MSAyODAgMjc2LjI1MiAyOTcuOTA5IDI3Ni4yNTIgMzIwVjM3NkMyNzYuMjUyIDQyMC4xODMgMjQwLjQzNSA0NTYgMTk2LjI1MiA0NTZIMTYwVjQ2NEMxNjAgNDkwLjUxIDEzOC41MSA1MTIgMTEyIDUxMkg0OEMyMS40OTAzIDUxMiAwIDQ5MC41MSAwIDQ2NFY0MDBDMCAzNzMuNDkgMjEuNDkwMyAzNTIgNDggMzUySDExMkMxMzguNTEgMzUyIDE2MCAzNzMuNDkgMTYwIDQwMFY0MDhIMTk2LjI1MkMyMTMuOTI1IDQwOCAyMjguMjUyIDM5My42NzMgMjI4LjI1MiAzNzZWMzIwQzIyOC4yNTIgMjk0Ljc4NCAyMzguODU5IDI3Mi4wNDQgMjU1Ljg1MyAyNTZDMjM4Ljg1OSAyMzkuOTU2IDIyOC4yNTIgMjE3LjIxNiAyMjguMjUyIDE5MlYxMzZDMjI4LjI1MiAxMTguMzI3IDIxMy45MjUgMTA0IDE5Ni4yNTIgMTA0SDE2MFYxMTJDMTYwIDEzOC41MSAxMzguNTEgMTYwIDExMiAxNjBINDhDMjEuNDkwMyAxNjAgMCAxMzguNTEgMCAxMTJWNDhaTTEwNCA0OEMxMDguNDE4IDQ4IDExMiA1MS41ODE3IDExMiA1NlYxMDRDMTEyIDEwOC40MTggMTA4LjQxOCAxMTIgMTA0IDExMkg1NkM1MS41ODE3IDExMiA0OCAxMDguNDE4IDQ4IDEwNFY1NkM0OCA1MS41ODE3IDUxLjU4MTcgNDggNTYgNDhIMTA0Wk00NTYgMjI0QzQ2MC40MTggMjI0IDQ2NCAyMjcuNTgyIDQ2NCAyMzJWMjgwQzQ2NCAyODQuNDE4IDQ2MC40MTggMjg4IDQ1NiAyODhINDA4QzQwMy41ODIgMjg4IDQwMCAyODQuNDE4IDQwMCAyODBWMjMyQzQwMCAyMjcuNTgyIDQwMy41ODIgMjI0IDQwOCAyMjRINDU2Wk0xMTIgNDA4QzExMiA0MDMuNTgyIDEwOC40MTggNDAwIDEwNCA0MDBINTZDNTEuNTgxNyA0MDAgNDggNDAzLjU4MiA0OCA0MDhWNDU2QzQ4IDQ2MC40MTggNTEuNTgxNyA0NjQgNTYgNDY0SDEwNEMxMDguNDE4IDQ2NCAxMTIgNDYwLjQxOCAxMTIgNDU2VjQwOFoiIGZpbGw9IiM1NEI4QzkiLz4KPC9nPgo8ZGVmcz4KPGNsaXBQYXRoIGlkPSJjbGlwMF8xMTc3XzUxOCI+CjxyZWN0IHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8L2RlZnM+Cjwvc3ZnPgo="
        },
        "displayName": "Merge",
        "typeVersion": 3,
        "nodeCategories": [
          {
            "id": 9,
            "name": "Core Nodes"
          }
        ]
      },
      {
        "id": 30,
        "icon": "file:postgres.svg",
        "name": "n8n-nodes-base.postgres",
        "codex": {
          "data": {
            "resources": {
              "generic": [
                {
                  "url": "https://n8n.io/blog/love-at-first-sight-ricardos-n8n-journey/",
                  "icon": "❤️",
                  "label": "Love at first sight: Ricardo’s n8n journey"
                },
                {
                  "url": "https://n8n.io/blog/why-i-chose-n8n-over-zapier-in-2020/",
                  "icon": "😍",
                  "label": "Why I chose n8n over Zapier in 2020"
                },
                {
                  "url": "https://n8n.io/blog/database-monitoring-and-alerting-with-n8n/",
                  "icon": "📡",
                  "label": "Database Monitoring and Alerting with n8n"
                },
                {
                  "url": "https://n8n.io/blog/running-n8n-on-ships-an-interview-with-maranics/",
                  "icon": "🛳",
                  "label": "Running n8n on ships: An interview with Maranics"
                },
                {
                  "url": "https://n8n.io/blog/automate-your-data-processing-pipeline-in-9-steps-with-n8n/",
                  "icon": "⚙️",
                  "label": "Automate your data processing pipeline in 9 steps"
                },
                {
                  "url": "https://n8n.io/blog/how-honest-burgers-use-automation-to-save-100k-per-year/",
                  "icon": "🍔",
                  "label": "How Honest Burgers Use Automation to Save $100k per year"
                }
              ],
              "primaryDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.postgres/"
                }
              ],
              "credentialDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/credentials/postgres/"
                }
              ]
            },
            "categories": [
              "Development",
              "Data & Storage"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0"
          }
        },
        "group": "[\"input\"]",
        "defaults": {
          "name": "Postgres"
        },
        "iconData": {
          "type": "file",
          "fileBuffer": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiB2aWV3Qm94PSIwIDAgNzkgODEiPjx1c2UgeGxpbms6aHJlZj0iI2EiIHg9Ii41IiB5PSIuNSIvPjxzeW1ib2wgaWQ9ImEiIG92ZXJmbG93PSJ2aXNpYmxlIj48ZyBmaWxsLXJ1bGU9Im5vbnplcm8iIHN0cm9rZT0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZD0iTTc3LjM5MSA0Ny45MjJjLS40NjYtMS40MTItMS42ODgtMi4zOTYtMy4yNjgtMi42MzItLjc0NS0uMTExLTEuNTk4LS4wNjQtMi42MDguMTQ0LTEuNzYuMzYzLTMuMDY1LjUwMS00LjAxOC41MjggMy41OTYtNi4wNzIgNi41MjEtMTIuOTk3IDguMjA0LTE5LjUxNSAyLjcyMi0xMC41NCAxLjI2OC0xNS4zNDEtLjQzMi0xNy41MTNDNzAuNzcgMy4xODUgNjQuMjA2LjA5NyA1Ni4yODcuMDAyYy00LjIyNC0uMDUyLTcuOTMzLjc4Mi05Ljg2NyAxLjM4MmEzNyAzNyAwIDAgMC01Ljc3LS41MjhjLTMuODA5LS4wNjEtNy4xNzQuNzctMTAuMDUgMi40NzZhNDYgNDYgMCAwIDAtNy4wOTgtMS43ODJDMTYuNTYxLjQxMSAxMC45NjggMS4yOTkgNi44NzYgNC4xOSAxLjkyMiA3LjY4OS0uMzc1IDEzLjc3LjA1IDIyLjI2MmMuMTM1IDIuNjk2IDEuNjQzIDEwLjkgNC4wMTggMTguNjggMS4zNjUgNC40NzIgMi44MiA4LjE4NSA0LjMyNiAxMS4wMzggMi4xMzUgNC4wNDYgNC40MTkgNi40MjggNi45ODQgNy4yODQgMS40MzguNDc5IDQuMDQ5LjgxNCA2Ljc5Ny0xLjQ3M2E2IDYgMCAwIDAgMS40MjkgMS4yM2MuNzgzLjQ5NCAxLjc0Ljg5NyAyLjY5NiAxLjEzNiAzLjQ0Ni44NjIgNi42NzQuNjQ2IDkuNDI3LS41NjFsLjA0MSAxLjM2Mi4wNiAxLjg5OWMuMTYzIDQuMDY0LjQ0IDcuMjIzIDEuMjU5IDkuNDM0LjA0NS4xMjIuMTA1LjMwNy4xNjkuNTAzLjQwOSAxLjI1MSAxLjA5MiAzLjM0NiAyLjgzIDQuOTg3IDEuOCAxLjY5OSAzLjk3OCAyLjIyIDUuOTcyIDIuMjIgMSAwIDEuOTU1LS4xMzEgMi43OTItLjMxMSAyLjk4NC0uNjM5IDYuMzczLTEuNjE0IDguODI0LTUuMTA0IDIuMzE4LTMuMyAzLjQ0NC04LjI3IDMuNjQ4LTE2LjEwMWwuMDc0LS42MzQuMDQ4LS40MTQuNTQ2LjA0OC4xNDEuMDFjMy4wMzkuMTM4IDYuNzU1LS41MDYgOS4wMzctMS41NjYgMS44MDMtLjgzNyA3LjU4Mi0zLjg4OCA2LjIyMS04LjAwNyIvPjxwYXRoIGZpbGw9IiMzMzY3OTEiIGQ9Ik03Mi4xOTUgNDguNzIzYy05LjAzNiAxLjg2NC05LjY1Ny0xLjE5NS05LjY1Ny0xLjE5NSA5LjU0MS0xNC4xNTcgMTMuNTI5LTMyLjEyNyAxMC4wODctMzYuNTI1QzYzLjIzNS0uOTk0IDQ2Ljk4MSA0LjY4IDQ2LjcxIDQuODI3bC0uMDg3LjAxNmMtMS43ODUtLjM3MS0zLjc4My0uNTkxLTYuMDI5LS42MjgtNC4wODktLjA2Ny03LjE5IDEuMDcyLTkuNTQ0IDIuODU3IDAgMC0yOC45OTUtMTEuOTQ1LTI3LjY0NyAxNS4wMjMuMjg3IDUuNzM3IDguMjIzIDQzLjQxIDE3LjY4OSAzMi4wMzEgMy40Ni00LjE2MSA2LjgwMy03LjY3OSA2LjgwMy03LjY3OSAxLjY2IDEuMTAzIDMuNjQ4IDEuNjY2IDUuNzMyIDEuNDYzbC4xNjItLjEzN2E2LjMgNi4zIDAgMCAwIC4wNjUgMS42MmMtMi40MzkgMi43MjUtMS43MjIgMy4yMDMtNi41OTcgNC4yMDYtNC45MzMgMS4wMTctMi4wMzUgMi44MjYtLjE0MyAzLjI5OSAyLjI5NC41NzQgNy42IDEuMzg2IDExLjE4NS0zLjYzM2wtLjE0My41NzNjLjk1Ni43NjUgMS42MjYgNC45NzggMS41MTQgOC43OTdzLS4xODggNi40NDEuNTY1IDguNDg5IDEuNTAzIDYuNjU2IDcuOTEyIDUuMjgyYzUuMzU1LTEuMTQ4IDguMTMtNC4xMjEgOC41MTYtOS4wODEuMjc0LTMuNTI2Ljg5NC0zLjAwNS45MzMtNi4xNThsLjQ5Ny0xLjQ5M2MuNTczLTQuNzguMDkxLTYuMzIyIDMuMzktNS42MDVsLjgwMi4wN2MyLjQyOC4xMSA1LjYwNi0uMzkxIDcuNDcxLTEuMjU3IDQuMDE2LTEuODY0IDYuMzk4LTQuOTc2IDIuNDM4LTQuMTU4Ii8+PHBhdGggZD0iTTMyLjc0NyAyNC42NmMtLjgxNC0uMTEzLTEuNTUyLS4wMDgtMS45MjUuMjc0YS43LjcgMCAwIDAtLjI5Mi40N2MtLjA0Ny4zMzYuMTg4LjcwNy4zMzMuODk4LjQwOS41NDIgMS4wMDYuOTE1IDEuNTk4Ljk5N2EyIDIgMCAwIDAgLjI1Ni4wMThjLjk4NiAwIDEuODgzLS43NjggMS45NjItMS4zMzUuMDk5LS43MS0uOTMyLTEuMTgzLTEuOTMxLTEuMzIybTI2Ljk3NS4wMjJjLS4wNzgtLjU1Ni0xLjA2OC0uNzE1LTIuMDA3LS41ODRzLTEuODQ4LjU1NC0xLjc3MiAxLjExMmMuMDYxLjQzNC44NDQgMS4xNzQgMS43NzEgMS4xNzRxLjExNyAwIC4yMzctLjAxNmMuNjE5LS4wODYgMS4wNzMtLjQ3OSAxLjI4OC0uNzA1LjMyOS0uMzQ1LjUxOC0uNzMuNDg0LS45OG0xNS40NzcgMjMuODI4Yy0uMzQ1LTEuMDQyLTEuNDUzLTEuMzc3LTMuMjk2LS45OTctNS40NzEgMS4xMjktNy40My4zNDctOC4wNzMtLjEyNyA0LjI1Mi02LjQ3OCA3Ljc1LTE0LjMwOCA5LjYzNy0yMS42MTQuODk0LTMuNDYxIDEuMzg4LTYuNjc1IDEuNDI4LTkuMjk0LjA0NS0yLjg3Ni0uNDQ1LTQuOTg4LTEuNDU1LTYuMjc5LTQuMDcyLTUuMjAzLTEwLjA0OC03Ljk5NC0xNy4yODMtOC4wNy00Ljk3My0uMDU2LTkuMTc1IDEuMjE3LTkuOTkgMS41NzVhMjUgMjUgMCAwIDAtNS42MjItLjcyMmMtMy43MzQtLjA2LTYuOTYxLjgzNC05LjYzMyAyLjY1NWE0MyA0MyAwIDAgMC03LjgyOC0yLjA1MmMtNi4zNDItMS4wMjEtMTEuMzgxLS4yNDgtMTQuOTc4IDIuMy00LjI5MSAzLjA0LTYuMjcyIDguNDc1LTUuODg4IDE2LjE1Mi4xMjkgMi41ODMgMS42MDEgMTAuNTI5IDMuOTIzIDE4LjEzOSAzLjA1NyAxMC4wMTYgNi4zOCAxNS42ODYgOS44NzcgMTYuODUyYTQuNCA0LjQgMCAwIDAgMS40MDIuMjMyYzEuMjc2IDAgMi44MzktLjU3NSA0LjQ2Ni0yLjUzMWExNjEgMTYxIDAgMCAxIDYuMTU2LTYuOTY2IDkuOSA5LjkgMCAwIDAgNC40MjkgMS4xOTFsLjAxLjEyMWMtLjMxLjM2OC0uNTY0LjY5LS43ODEuOTY1LTEuMDcgMS4zNTgtMS4yOTMgMS42NDEtNC43MzggMi4zNTEtLjk4LjIwMi0zLjU4Mi43MzgtMy42MiAyLjU2My0uMDQxIDEuOTkzIDMuMDc2IDIuODMgMy40MzEgMi45MTkgMS4yMzguMzEgMi40My40NjMgMy41NjguNDYzIDIuNzY2IDAgNS4yLS45MDkgNy4xNDUtMi42NjgtLjA2IDcuMTA2LjIzNiAxNC4xMDcgMS4wODkgMTYuMjQxLjY5OSAxLjc0NiAyLjQwNiA2LjAxNCA3Ljc5OCA2LjAxNC43OTEgMCAxLjY2Mi0uMDkyIDIuNjItLjI5NyA1LjYyNy0xLjIwNyA4LjA3MS0zLjY5NCA5LjAxNi05LjE3Ny41MDYtMi45MyAxLjM3NC05LjkyOCAxLjc4Mi0xMy42ODIuODYyLjI2OSAxLjk3MS4zOTIgMy4xNy4zOTIgMi41MDEgMCA1LjM4Ny0uNTMxIDcuMTk3LTEuMzcyIDIuMDMzLS45NDQgNS43MDItMy4yNjEgNS4wMzctNS4yNzR6TTYxLjggMjMuMTQ3Yy0uMDE5IDEuMTA4LS4xNzEgMi4xMTQtLjMzMyAzLjE2NC0uMTc0IDEuMTI5LS4zNTQgMi4yOTctLjM5OSAzLjcxNS0uMDQ1IDEuMzc5LjEyOCAyLjgxNC4yOTQgNC4yLjMzNyAyLjgwMS42ODIgNS42ODUtLjY1NSA4LjUzMWExMSAxMSAwIDAgMS0uNTkyLTEuMjE4Yy0uMTY2LS40MDMtLjUyNy0xLjA1LTEuMDI3LTEuOTQ2LTEuOTQ0LTMuNDg3LTYuNDk3LTExLjY1Mi00LjE2Ny0xNC45ODQuNjk0LS45OTIgMi40NTYtMi4wMTEgNi44NzktMS40NjN6TTU2LjQzOSA0LjM3NGM2LjQ4Mi4xNDMgMTEuNjA5IDIuNTY4IDE1LjI0IDcuMjA3IDIuNzg0IDMuNTU4LS4yODIgMTkuNzQ5LTkuMTU4IDMzLjcxNmwtLjI2OS0uMzM5LS4xMTItLjE0YzIuMjk0LTMuNzg4IDEuODQ1LTcuNTM2IDEuNDQ2LTEwLjg1OS0uMTY0LTEuMzY0LS4zMTktMi42NTItLjI4LTMuODYxLjA0MS0xLjI4My4yMS0yLjM4Mi4zNzQtMy40NDYuMjAyLTEuMzExLjQwNy0yLjY2Ny4zNS00LjI2NWExLjggMS44IDAgMCAwIC4wMzctLjYwMWMtLjE0NC0xLjUzMy0xLjg5NC02LjEyLTUuNDYyLTEwLjI3My0xLjk1MS0yLjI3MS00Ljc5Ny00LjgxMy04LjY4Mi02LjUyN2EyOS4zIDI5LjMgMCAwIDEgNi41MTUtLjYxMnpNMjAuMTY3IDUzLjI5OGMtMS43OTMgMi4xNTUtMy4wMzEgMS43NDItMy40MzggMS42MDctMi42NTMtLjg4NS01LjczLTYuNDkxLTguNDQ0LTE1LjM4Mi0yLjM0OC03LjY5My0zLjcyLTE1LjQyOC0zLjgyOS0xNy41OTctLjM0My02Ljg2IDEuMzItMTEuNjQxIDQuOTQzLTE0LjIxIDUuODk2LTQuMTgxIDE1LjU4OS0xLjY3OSAxOS40ODQtLjQwOWwtLjE3LjE2M2MtNi4zOTEgNi40NTUtNi4yNCAxNy40ODMtNi4yMjQgMTguMTU3YTIyIDIyIDAgMCAwIC4wNTEgMS4xMzVjLjExIDEuODU1LjMxNSA1LjMwNy0uMjMyIDkuMjE3LS41MDggMy42MzMuNjEyIDcuMTg5IDMuMDcyIDkuNzU2cS4zODMuMzk4Ljc5NS43NWExNjQgMTY0IDAgMCAwLTYuMDA4IDYuODE0em02LjgzLTkuMTEzYy0xLjk4My0yLjA2OS0yLjg4NC00Ljk0Ny0yLjQ3MS03Ljg5Ni41NzctNC4xMy4zNjQtNy43MjcuMjUtOS42NTlsLS4wMzktLjY5NGMuOTM0LS44MjggNS4yNjEtMy4xNDYgOC4zNDYtMi40MzkgMS40MDguMzIzIDIuMjY2IDEuMjgxIDIuNjIzIDIuOTMxIDEuODQ2IDguNTM5LjI0NCAxMi4wOTgtMS4wNDMgMTQuOTU3LS4yNjUuNTg5LS41MTYgMS4xNDYtLjczIDEuNzIybC0uMTY2LjQ0NWMtLjQyIDEuMTI2LS44MTEgMi4xNzMtMS4wNTMgMy4xNjctMi4xMDgtLjAwNi00LjE1OS0uOTA3LTUuNzE4LTIuNTM0em0uMzI0IDExLjUxNmE1IDUgMCAwIDEtMS40OTQtLjY0MmMuMjcxLS4xMjguNzU0LS4zMDEgMS41OTEtLjQ3NCA0LjA1Mi0uODM0IDQuNjc4LTEuNDIzIDYuMDQ1LTMuMTU4LjMxMy0uMzk4LjY2OS0uODQ5IDEuMTYtMS4zOTguNzMzLS44MjEgMS4wNjgtLjY4MiAxLjY3Ni0uNDMuNDkzLjIwNC45NzIuODIxIDEuMTY3IDEuNTAxLjA5Mi4zMjEuMTk1LjkzLS4xNDMgMS40MDQtMi44NTUgMy45OTctNy4wMTUgMy45NDYtMTAuMDAzIDMuMTk4em0yMS4yMDcgMTkuNzM1Yy00Ljk1NyAxLjA2Mi02LjcxMy0xLjQ2Ny03Ljg2OS00LjM1OS0uNzQ3LTEuODY3LTEuMTEzLTEwLjI4NS0uODUzLTE5LjU4MmExLjEgMS4xIDAgMCAwLS4wNDgtLjM1NiA1IDUgMCAwIDAtLjEzOS0uNjU3Yy0uMzg3LTEuMzUzLTEuMzMxLTIuNDg0LTIuNDYyLTIuOTUzLS40NS0uMTg2LTEuMjc1LS41MjgtMi4yNjctLjI3NC4yMTItLjg3MS41NzgtMS44NTUuOTc2LTIuOTIxbC4xNjctLjQ0OGMuMTg4LS41MDUuNDIzLTEuMDI5LjY3My0xLjU4MyAxLjM0Ny0yLjk5MiAzLjE5Mi03LjA5MSAxLjE5LTE2LjM1LS43NS0zLjQ2OC0zLjI1NC01LjE2MS03LjA1LTQuNzY4LTIuMjc2LjIzNS00LjM1OCAxLjE1NC01LjM5NiAxLjY4cS0uMzM0LjE2OS0uNjE4LjMyOWMuMjktMy40OTQgMS4zODUtMTAuMDI0IDUuNDgxLTE0LjE1NiAyLjU3OS0yLjYwMSA2LjAxNC0zLjg4NiAxMC4xOTktMy44MTcgOC4yNDYuMTM1IDEzLjUzNCA0LjM2NyAxNi41MTggNy44OTMgMi41NzEgMy4wMzkgMy45NjQgNi4xIDQuNTIgNy43NTEtNC4xNzktLjQyNS03LjAyMi40LTguNDYzIDIuNDYtMy4xMzUgNC40ODEgMS43MTUgMTMuMTc4IDQuMDQ2IDE3LjM1OC40MjcuNzY2Ljc5NiAxLjQyOC45MTIgMS43MDkuNzU5IDEuODM5IDEuNzQyIDMuMDY3IDIuNDU5IDMuOTY0LjIyLjI3NS40MzMuNTQxLjU5Ni43NzQtMS4yNjYuMzY1LTMuNTM5IDEuMjA4LTMuMzMyIDUuNDIyLS4xNjcgMi4xMTUtMS4zNTYgMTIuMDE2LTEuOTU5IDE1LjUxNC0uNzk3IDQuNjIxLTIuNDk3IDYuMzQzLTcuMjc5IDcuMzY4em0yMC42OTMtMjMuNjhjLTEuMjk0LjYwMS0zLjQ2IDEuMDUyLTUuNTE4IDEuMTQ4LTIuMjczLjEwNy0zLjQzLS4yNTUtMy43MDItLjQ3Ny0uMTI4LTIuNjI2Ljg1LTIuOTAxIDEuODg0LTMuMTkxLjE2My0uMDQ2LjMyMS0uMDkuNDc0LS4xNDRhNCA0IDAgMCAwIC4zMTMuMjNjMS44MjcgMS4yMDYgNS4wODUgMS4zMzYgOS42ODUuMzg2bC4wNS0uMDFjLS42Mi41OC0xLjY4MiAxLjM1OS0zLjE4NyAyLjA1OHoiLz48L2c+PC9zeW1ib2w+PC9zdmc+"
        },
        "displayName": "Postgres",
        "typeVersion": 3,
        "nodeCategories": [
          {
            "id": 3,
            "name": "Data & Storage"
          },
          {
            "id": 5,
            "name": "Development"
          }
        ]
      },
      {
        "id": 38,
        "icon": "fa:pen",
        "name": "n8n-nodes-base.set",
        "codex": {
          "data": {
            "alias": [
              "Set",
              "JS",
              "JSON",
              "Filter",
              "Transform",
              "Map"
            ],
            "resources": {
              "generic": [
                {
                  "url": "https://n8n.io/blog/learn-to-automate-your-factorys-incident-reporting-a-step-by-step-guide/",
                  "icon": "🏭",
                  "label": "Learn to Automate Your Factory's Incident Reporting: A Step by Step Guide"
                },
                {
                  "url": "https://n8n.io/blog/2021-the-year-to-automate-the-new-you-with-n8n/",
                  "icon": "☀️",
                  "label": "2021: The Year to Automate the New You with n8n"
                },
                {
                  "url": "https://n8n.io/blog/automatically-pulling-and-visualizing-data-with-n8n/",
                  "icon": "📈",
                  "label": "Automatically pulling and visualizing data with n8n"
                },
                {
                  "url": "https://n8n.io/blog/database-monitoring-and-alerting-with-n8n/",
                  "icon": "📡",
                  "label": "Database Monitoring and Alerting with n8n"
                },
                {
                  "url": "https://n8n.io/blog/automatically-adding-expense-receipts-to-google-sheets-with-telegram-mindee-twilio-and-n8n/",
                  "icon": "🧾",
                  "label": "Automatically Adding Expense Receipts to Google Sheets with Telegram, Mindee, Twilio, and n8n"
                },
                {
                  "url": "https://n8n.io/blog/no-code-ecommerce-workflow-automations/",
                  "icon": "store",
                  "label": "6 e-commerce workflows to power up your Shopify s"
                },
                {
                  "url": "https://n8n.io/blog/how-to-build-a-low-code-self-hosted-url-shortener/",
                  "icon": "🔗",
                  "label": "How to build a low-code, self-hosted URL shortener in 3 steps"
                },
                {
                  "url": "https://n8n.io/blog/automate-your-data-processing-pipeline-in-9-steps-with-n8n/",
                  "icon": "⚙️",
                  "label": "Automate your data processing pipeline in 9 steps"
                },
                {
                  "url": "https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/",
                  "icon": "👥",
                  "label": "How to get started with CRM automation (with 3 no-code workflow ideas"
                },
                {
                  "url": "https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/",
                  "icon": "⚡️",
                  "label": "5 tasks you can automate with the new Notion API "
                },
                {
                  "url": "https://n8n.io/blog/automate-google-apps-for-productivity/",
                  "icon": "💡",
                  "label": "15 Google apps you can combine and automate to increase productivity"
                },
                {
                  "url": "https://n8n.io/blog/how-uproc-scraped-a-multi-page-website-with-a-low-code-workflow/",
                  "icon": " 🕸️",
                  "label": "How uProc scraped a multi-page website with a low-code workflow"
                },
                {
                  "url": "https://n8n.io/blog/building-an-expense-tracking-app-in-10-minutes/",
                  "icon": "📱",
                  "label": "Building an expense tracking app in 10 minutes"
                },
                {
                  "url": "https://n8n.io/blog/the-ultimate-guide-to-automate-your-video-collaboration-with-whereby-mattermost-and-n8n/",
                  "icon": "📹",
                  "label": "The ultimate guide to automate your video collaboration with Whereby, Mattermost, and n8n"
                },
                {
                  "url": "https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/",
                  "icon": "🤖",
                  "label": "5 workflow automations for Mattermost that we love at n8n"
                },
                {
                  "url": "https://n8n.io/blog/learn-to-build-powerful-api-endpoints-using-webhooks/",
                  "icon": "🧰",
                  "label": "Learn to Build Powerful API Endpoints Using Webhooks"
                },
                {
                  "url": "https://n8n.io/blog/how-a-membership-development-manager-automates-his-work-and-investments/",
                  "icon": "📈",
                  "label": "How a Membership Development Manager automates his work and investments"
                },
                {
                  "url": "https://n8n.io/blog/a-low-code-bitcoin-ticker-built-with-questdb-and-n8n-io/",
                  "icon": "📈",
                  "label": "A low-code bitcoin ticker built with QuestDB and n8n.io"
                },
                {
                  "url": "https://n8n.io/blog/how-to-set-up-a-ci-cd-pipeline-with-no-code/",
                  "icon": "🎡",
                  "label": "How to set up a no-code CI/CD pipeline with GitHub and TravisCI"
                },
                {
                  "url": "https://n8n.io/blog/benefits-of-automation-and-n8n-an-interview-with-hubspots-hugh-durkin/",
                  "icon": "🎖",
                  "label": "Benefits of automation and n8n: An interview with HubSpot's Hugh Durkin"
                },
                {
                  "url": "https://n8n.io/blog/how-goomer-automated-their-operations-with-over-200-n8n-workflows/",
                  "icon": "🛵",
                  "label": "How Goomer automated their operations with over 200 n8n workflows"
                },
                {
                  "url": "https://n8n.io/blog/aws-workflow-automation/",
                  "label": "7 no-code workflow automations for Amazon Web Services"
                }
              ],
              "primaryDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.set/"
                }
              ]
            },
            "categories": [
              "Core Nodes"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0",
            "subcategories": {
              "Core Nodes": [
                "Data Transformation"
              ]
            }
          }
        },
        "group": "[\"input\"]",
        "defaults": {
          "name": "Edit Fields"
        },
        "iconData": {
          "icon": "pen",
          "type": "icon"
        },
        "displayName": "Edit Fields (Set)",
        "typeVersion": 3,
        "nodeCategories": [
          {
            "id": 9,
            "name": "Core Nodes"
          }
        ]
      },
      {
        "id": 40,
        "icon": "file:slack.svg",
        "name": "n8n-nodes-base.slack",
        "codex": {
          "data": {
            "alias": [
              "human",
              "form",
              "wait",
              "hitl",
              "approval"
            ],
            "resources": {
              "generic": [
                {
                  "url": "https://n8n.io/blog/no-code-ecommerce-workflow-automations/",
                  "icon": "store",
                  "label": "6 e-commerce workflows to power up your Shopify s"
                },
                {
                  "url": "https://n8n.io/blog/automate-your-data-processing-pipeline-in-9-steps-with-n8n/",
                  "icon": "⚙️",
                  "label": "Automate your data processing pipeline in 9 steps"
                },
                {
                  "url": "https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/",
                  "icon": "👥",
                  "label": "How to get started with CRM automation (with 3 no-code workflow ideas"
                },
                {
                  "url": "https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/",
                  "icon": "⚡️",
                  "label": "5 tasks you can automate with the new Notion API "
                },
                {
                  "url": "https://n8n.io/blog/build-your-own-virtual-assistant-with-n8n-a-step-by-step-guide/",
                  "icon": "👦",
                  "label": "Build your own virtual assistant with n8n: A step by step guide"
                },
                {
                  "url": "https://n8n.io/blog/how-to-automatically-give-kudos-to-contributors-with-github-slack-and-n8n/",
                  "icon": "👏",
                  "label": "How to automatically give kudos to contributors with GitHub, Slack, and n8n"
                },
                {
                  "url": "https://n8n.io/blog/automations-for-activists/",
                  "icon": "✨",
                  "label": "How Common Knowledge use workflow automation for activism"
                }
              ],
              "primaryDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.slack/"
                }
              ],
              "credentialDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/credentials/slack/"
                }
              ]
            },
            "categories": [
              "Communication",
              "HITL"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0",
            "subcategories": {
              "HITL": [
                "Human in the Loop"
              ]
            }
          }
        },
        "group": "[\"output\"]",
        "defaults": {
          "name": "Slack"
        },
        "iconData": {
          "type": "file",
          "fileBuffer": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiB2aWV3Qm94PSIwIDAgMTUwLjg1MiAxNTAuODUyIj48dXNlIHhsaW5rOmhyZWY9IiNhIiB4PSIuOTI2IiB5PSIuOTI2Ii8+PHN5bWJvbCBpZD0iYSIgb3ZlcmZsb3c9InZpc2libGUiPjxnIHN0cm9rZS13aWR0aD0iMS44NTIiPjxwYXRoIGZpbGw9IiNlMDFlNWEiIHN0cm9rZT0iI2UwMWU1YSIgZD0iTTQwLjc0MSA5My41NWMwLTguNzM1IDYuNjA3LTE1Ljc3MiAxNC44MTUtMTUuNzcyczE0LjgxNSA3LjAzNyAxNC44MTUgMTUuNzcydjM4LjgyNGMwIDguNzM3LTYuNjA3IDE1Ljc3NC0xNC44MTUgMTUuNzc0cy0xNC44MTUtNy4wMzctMTQuODE1LTE1Ljc3MnoiLz48cGF0aCBmaWxsPSIjZWNiMjJkIiBzdHJva2U9IiNlY2IyMmQiIGQ9Ik05My41NSAxMDcuNDA4Yy04LjczNSAwLTE1Ljc3Mi02LjYwNy0xNS43NzItMTQuODE1czcuMDM3LTE0LjgxNSAxNS43NzItMTQuODE1aDM4LjgyNmM4LjczNSAwIDE1Ljc3MiA2LjYwNyAxNS43NzIgMTQuODE1cy03LjAzNyAxNC44MTUtMTUuNzcyIDE0LjgxNXoiLz48cGF0aCBmaWxsPSIjMmZiNjdjIiBzdHJva2U9IiMyZmI2N2MiIGQ9Ik03Ny43NzggMTUuNzcyQzc3Ljc3OCA3LjAzNyA4NC4zODUgMCA5Mi41OTMgMHMxNC44MTUgNy4wMzcgMTQuODE1IDE1Ljc3MnYzOC44MjZjMCA4LjczNS02LjYwNyAxNS43NzItMTQuODE1IDE1Ljc3MnMtMTQuODE1LTcuMDM3LTE0LjgxNS0xNS43NzJ6Ii8+PHBhdGggZmlsbD0iIzM2YzVmMSIgc3Ryb2tlPSIjMzZjNWYxIiBkPSJNMTUuNzcyIDcwLjM3MUM3LjAzNyA3MC4zNzEgMCA2My43NjMgMCA1NS41NTZzNy4wMzctMTQuODE1IDE1Ljc3Mi0xNC44MTVoMzguODI2YzguNzM1IDAgMTUuNzcyIDYuNjA3IDE1Ljc3MiAxNC44MTVzLTcuMDM3IDE0LjgxNS0xNS43NzIgMTQuODE1eiIvPjxnIHN0cm9rZS1saW5lam9pbj0ibWl0ZXIiPjxwYXRoIGZpbGw9IiNlY2IyMmQiIHN0cm9rZT0iI2VjYjIyZCIgZD0iTTc3Ljc3OCAxMzMuMzMzYzAgOC4yMDggNi42MDcgMTQuODE1IDE0LjgxNSAxNC44MTVzMTQuODE1LTYuNjA3IDE0LjgxNS0xNC44MTUtNi42MDctMTQuODE1LTE0LjgxNS0xNC44MTVINzcuNzc4eiIvPjxwYXRoIGZpbGw9IiMyZmI2N2MiIHN0cm9rZT0iIzJmYjY3YyIgZD0iTTEzMy4zMzQgNzAuMzcxaC0xNC44MTVWNTUuNTU2YzAtOC4yMDcgNi42MDctMTQuODE1IDE0LjgxNS0xNC44MTVzMTQuODE1IDYuNjA3IDE0LjgxNSAxNC44MTUtNi42MDcgMTQuODE1LTE0LjgxNSAxNC44MTV6Ii8+PHBhdGggZmlsbD0iI2UwMWU1YSIgc3Ryb2tlPSIjZTAxZTVhIiBkPSJNMTQuODE1IDc3Ljc3OEgyOS42M3YxNC44MTVjMCA4LjIwNy02LjYwNyAxNC44MTUtMTQuODE1IDE0LjgxNVMwIDEwMC44IDAgOTIuNTkzczYuNjA3LTE0LjgxNSAxNC44MTUtMTQuODE1eiIvPjxwYXRoIGZpbGw9IiMzNmM1ZjEiIHN0cm9rZT0iIzM2YzVmMSIgZD0iTTcwLjM3MSAxNC44MTVWMjkuNjNINTUuNTU2Yy04LjIwNyAwLTE0LjgxNS02LjYwNy0xNC44MTUtMTQuODE1UzQ3LjM0OCAwIDU1LjU1NiAwczE0LjgxNSA2LjYwNyAxNC44MTUgMTQuODE1eiIvPjwvZz48L2c+PC9zeW1ib2w+PC9zdmc+"
        },
        "displayName": "Slack",
        "typeVersion": 2,
        "nodeCategories": [
          {
            "id": 6,
            "name": "Communication"
          },
          {
            "id": 28,
            "name": "HITL"
          }
        ]
      },
      {
        "id": 356,
        "icon": "file:gmail.svg",
        "name": "n8n-nodes-base.gmail",
        "codex": {
          "data": {
            "alias": [
              "email",
              "human",
              "form",
              "wait",
              "hitl",
              "approval"
            ],
            "resources": {
              "generic": [
                {
                  "url": "https://n8n.io/blog/why-business-process-automation-with-n8n-can-change-your-daily-life/",
                  "icon": "🧬",
                  "label": "Why business process automation with n8n can change your daily life"
                },
                {
                  "url": "https://n8n.io/blog/supercharging-your-conference-registration-process-with-n8n/",
                  "icon": "🎫",
                  "label": "Supercharging your conference registration process with n8n"
                },
                {
                  "url": "https://n8n.io/blog/no-code-ecommerce-workflow-automations/",
                  "icon": "store",
                  "label": "6 e-commerce workflows to power up your Shopify s"
                },
                {
                  "url": "https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/",
                  "icon": "👥",
                  "label": "How to get started with CRM automation (with 3 no-code workflow ideas"
                },
                {
                  "url": "https://n8n.io/blog/automate-google-apps-for-productivity/",
                  "icon": "💡",
                  "label": "15 Google apps you can combine and automate to increase productivity"
                },
                {
                  "url": "https://n8n.io/blog/your-business-doesnt-need-you-to-operate/",
                  "icon": " 🖥️",
                  "label": "Hey founders! Your business doesn't need you to operate"
                },
                {
                  "url": "https://n8n.io/blog/using-automation-to-boost-productivity-in-the-workplace/",
                  "icon": "💪",
                  "label": "Using Automation to Boost Productivity in the Workplace"
                }
              ],
              "primaryDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.gmail/"
                }
              ],
              "credentialDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/credentials/google/oauth-single-service/"
                }
              ]
            },
            "categories": [
              "Communication",
              "HITL"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0",
            "subcategories": {
              "HITL": [
                "Human in the Loop"
              ]
            }
          }
        },
        "group": "[\"transform\"]",
        "defaults": {
          "name": "Gmail"
        },
        "iconData": {
          "type": "file",
          "fileBuffer": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNTYiIGhlaWdodD0iMTkzIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCI+PHBhdGggZmlsbD0iIzQyODVGNCIgZD0iTTU4LjE4MiAxOTIuMDVWOTMuMTRMMjcuNTA3IDY1LjA3NyAwIDQ5LjUwNHYxMjUuMDkxYzAgOS42NTggNy44MjUgMTcuNDU1IDE3LjQ1NSAxNy40NTV6Ii8+PHBhdGggZmlsbD0iIzM0QTg1MyIgZD0iTTE5Ny44MTggMTkyLjA1aDQwLjcyN2M5LjY1OSAwIDE3LjQ1NS03LjgyNiAxNy40NTUtMTcuNDU1VjQ5LjUwNWwtMzEuMTU2IDE3LjgzNy0yNy4wMjYgMjUuNzk4eiIvPjxwYXRoIGZpbGw9IiNFQTQzMzUiIGQ9Im01OC4xODIgOTMuMTQtNC4xNzQtMzguNjQ3IDQuMTc0LTM2Ljk4OUwxMjggNjkuODY4bDY5LjgxOC01Mi4zNjQgNC42NyAzNC45OTItNC42NyA0MC42NDRMMTI4IDE0NS41MDR6Ii8+PHBhdGggZmlsbD0iI0ZCQkMwNCIgZD0iTTE5Ny44MTggMTcuNTA0VjkzLjE0TDI1NiA0OS41MDRWMjYuMjMxYzAtMjEuNTg1LTI0LjY0LTMzLjg5LTQxLjg5LTIwLjk0NXoiLz48cGF0aCBmaWxsPSIjQzUyMjFGIiBkPSJtMCA0OS41MDQgMjYuNzU5IDIwLjA3TDU4LjE4MiA5My4xNFYxNy41MDRMNDEuODkgNS4yODZDMjQuNjEtNy42NiAwIDQuNjQ2IDAgMjYuMjN6Ii8+PC9zdmc+"
        },
        "displayName": "Gmail",
        "typeVersion": 2,
        "nodeCategories": [
          {
            "id": 6,
            "name": "Communication"
          },
          {
            "id": 28,
            "name": "HITL"
          }
        ]
      },
      {
        "id": 565,
        "icon": "fa:sticky-note",
        "name": "n8n-nodes-base.stickyNote",
        "codex": {
          "data": {
            "alias": [
              "Comments",
              "Notes",
              "Sticky"
            ],
            "categories": [
              "Core Nodes"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0",
            "subcategories": {
              "Core Nodes": [
                "Helpers"
              ]
            }
          }
        },
        "group": "[\"input\"]",
        "defaults": {
          "name": "Sticky Note",
          "color": "#FFD233"
        },
        "iconData": {
          "icon": "sticky-note",
          "type": "icon"
        },
        "displayName": "Sticky Note",
        "typeVersion": 1,
        "nodeCategories": [
          {
            "id": 9,
            "name": "Core Nodes"
          }
        ]
      },
      {
        "id": 834,
        "icon": "file:code.svg",
        "name": "n8n-nodes-base.code",
        "codex": {
          "data": {
            "alias": [
              "cpde",
              "Javascript",
              "JS",
              "Python",
              "Script",
              "Custom Code",
              "Function"
            ],
            "details": "The Code node allows you to execute JavaScript in your workflow.",
            "resources": {
              "primaryDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.code/"
                }
              ]
            },
            "categories": [
              "Development",
              "Core Nodes"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0",
            "subcategories": {
              "Core Nodes": [
                "Helpers",
                "Data Transformation"
              ]
            }
          }
        },
        "group": "[\"transform\"]",
        "defaults": {
          "name": "Code"
        },
        "iconData": {
          "type": "file",
          "fileBuffer": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xMTcxXzQ0MSkiPgo8cGF0aCBkPSJNMTcwLjI4MyA0OEgxOTYuNUMyMDMuMTI3IDQ4IDIwOC41IDQyLjYyNzQgMjA4LjUgMzZWMTJDMjA4LjUgNS4zNzI1OCAyMDMuMTI3IDAgMTk2LjUgMEgxNzAuMjgzQzEyNi4xIDAgOTAuMjgzIDM1LjgxNzIgOTAuMjgzIDgwVjE3NkM5MC4yODMgMjA2LjkyOCA2NS4yMTA5IDIzMiAzNC4yODMgMjMySDIzQzE2LjM3MjYgMjMyIDExIDIzNy4zNzIgMTEgMjQ0VjI2OEMxMSAyNzQuNjI3IDE2LjM3MjQgMjgwIDIyLjk5OTYgMjgwTDM0LjI4MyAyODBDNjUuMjEwOSAyODAgOTAuMjgzIDMwNS4wNzIgOTAuMjgzIDMzNlY0NDBDOTAuMjgzIDQ3OS43NjQgMTIyLjUxOCA1MTIgMTYyLjI4MyA1MTJIMTk2LjVDMjAzLjEyNyA1MTIgMjA4LjUgNTA2LjYyNyAyMDguNSA1MDBWNDc2QzIwOC41IDQ2OS4zNzMgMjAzLjEyNyA0NjQgMTk2LjUgNDY0SDE2Mi4yODNDMTQ5LjAyOCA0NjQgMTM4LjI4MyA0NTMuMjU1IDEzOC4yODMgNDQwVjMzNkMxMzguMjgzIDMwOS4wMjIgMTI4LjAxMSAyODQuNDQzIDExMS4xNjQgMjY1Ljk2MUMxMDYuMTA5IDI2MC40MTYgMTA2LjEwOSAyNTEuNTg0IDExMS4xNjQgMjQ2LjAzOUMxMjguMDExIDIyNy41NTcgMTM4LjI4MyAyMDIuOTc4IDEzOC4yODMgMTc2VjgwQzEzOC4yODMgNjIuMzI2OSAxNTIuNjEgNDggMTcwLjI4MyA0OFoiIGZpbGw9IiNGRjk5MjIiLz4KPHBhdGggZD0iTTMwNSAzNkMzMDUgNDIuNjI3NCAzMTAuMzczIDQ4IDMxNyA0OEgzNDIuOTc5QzM2MC42NTIgNDggMzc0Ljk3OCA2Mi4zMjY5IDM3NC45NzggODBWMTc2QzM3NC45NzggMjAyLjk3OCAzODUuMjUxIDIyNy41NTcgNDAyLjA5OCAyNDYuMDM5QzQwNy4xNTMgMjUxLjU4NCA0MDcuMTUzIDI2MC40MTYgNDAyLjA5OCAyNjUuOTYxQzM4NS4yNTEgMjg0LjQ0MyAzNzQuOTc4IDMwOS4wMjIgMzc0Ljk3OCAzMzZWNDMyQzM3NC45NzggNDQ5LjY3MyAzNjAuNjUyIDQ2NCAzNDIuOTc5IDQ2NEgzMTdDMzEwLjM3MyA0NjQgMzA1IDQ2OS4zNzMgMzA1IDQ3NlY1MDBDMzA1IDUwNi42MjcgMzEwLjM3MyA1MTIgMzE3IDUxMkgzNDIuOTc5QzM4Ny4xNjEgNTEyIDQyMi45NzggNDc2LjE4MyA0MjIuOTc4IDQzMlYzMzZDNDIyLjk3OCAzMDUuMDcyIDQ0OC4wNTEgMjgwIDQ3OC45NzkgMjgwSDQ5MEM0OTYuNjI3IDI4MCA1MDIgMjc0LjYyOCA1MDIgMjY4VjI0NEM1MDIgMjM3LjM3MyA0OTYuNjI4IDIzMiA0OTAgMjMyTDQ3OC45NzkgMjMyQzQ0OC4wNTEgMjMyIDQyMi45NzggMjA2LjkyOCA0MjIuOTc4IDE3NlY4MEM0MjIuOTc4IDM1LjgxNzIgMzg3LjE2MSAwIDM0Mi45NzkgMEgzMTdDMzEwLjM3MyAwIDMwNSA1LjM3MjU4IDMwNSAxMlYzNloiIGZpbGw9IiNGRjk5MjIiLz4KPC9nPgo8ZGVmcz4KPGNsaXBQYXRoIGlkPSJjbGlwMF8xMTcxXzQ0MSI+CjxyZWN0IHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8L2RlZnM+Cjwvc3ZnPgo="
        },
        "displayName": "Code",
        "typeVersion": 2,
        "nodeCategories": [
          {
            "id": 5,
            "name": "Development"
          },
          {
            "id": 9,
            "name": "Core Nodes"
          }
        ]
      },
      {
        "id": 839,
        "icon": "fa:clock",
        "name": "n8n-nodes-base.scheduleTrigger",
        "codex": {
          "data": {
            "alias": [
              "Time",
              "Scheduler",
              "Polling",
              "Cron",
              "Interval"
            ],
            "resources": {
              "generic": [],
              "primaryDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.scheduletrigger/"
                }
              ]
            },
            "categories": [
              "Core Nodes"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0"
          }
        },
        "group": "[\"trigger\",\"schedule\"]",
        "defaults": {
          "name": "Schedule Trigger",
          "color": "#31C49F"
        },
        "iconData": {
          "icon": "clock",
          "type": "icon"
        },
        "displayName": "Schedule Trigger",
        "typeVersion": 1,
        "nodeCategories": [
          {
            "id": 9,
            "name": "Core Nodes"
          }
        ]
      },
      {
        "id": 1238,
        "icon": "file:removeDuplicates.svg",
        "name": "n8n-nodes-base.removeDuplicates",
        "codex": {
          "data": {
            "alias": [
              "Dedupe",
              "Deduplicate",
              "Duplicates",
              "Remove",
              "Unique",
              "Transform",
              "Array",
              "List",
              "Item"
            ],
            "details": "",
            "resources": {
              "generic": [],
              "primaryDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.removeduplicates/"
                }
              ]
            },
            "categories": [
              "Core Nodes"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0",
            "subcategories": {
              "Core Nodes": [
                "Data Transformation"
              ]
            }
          }
        },
        "group": "[\"transform\"]",
        "defaults": {
          "name": "Remove Duplicates"
        },
        "iconData": {
          "type": "file",
          "fileBuffer": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiBmaWxsPSJub25lIj48ZyBmaWxsPSIjNTRCOEM5IiBjbGlwLXBhdGg9InVybCgjYSkiPjxwYXRoIGQ9Ik0xMzQuMDk3IDExMWgzOC44Mjl2MzIuNTA4SDEzOC4xNnYzNC42MzVoLTMyLjUwOHYtMzguNjk5YzAtMTUuNzA5IDEyLjczNS0yOC40NDQgMjguNDQ1LTI4LjQ0NG03Ny42NTggMzIuNTA4VjExMWg3Ny42NTd2MzIuNTA4em0xMTYuNDg2IDBWMTExaDc3LjY1OHYzMi41MDh6bTExNi40ODcgMFYxMTFoMzguODI5YzE1LjcxIDAgMjguNDQ1IDEyLjczNSAyOC40NDUgMjguNDQ0djM4LjY5OWgtMzIuNTA4di0zNC42MzV6bTM0Ljc2NiA3My4yMzhoMzIuNTA4djM4LjY5OGMwIDE1LjcxLTEyLjczNSAyOC40NDUtMjguNDQ1IDI4LjQ0NWgtMzguODI5di0zMi41MDhoMzQuNzY2ek0wIDI0NC41MzdDMCAyMjkuMzI5IDEyLjczNSAyMTcgMjguNDQ0IDIxN2gzNDkuNDYxYzE1LjcwOSAwIDI4LjQ0NCAxMi4zMjkgMjguNDQ0IDI3LjUzN3YxMjkuODE1YzAgMTUuMjA4LTEyLjczNSAyNy41MzctMjguNDQ0IDI3LjUzN0gyOC40NDVDMTIuNzM0IDQwMS44ODkgMCAzODkuNTYgMCAzNzQuMzUyeiIvPjwvZz48ZGVmcz48Y2xpcFBhdGggaWQ9ImEiPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0wIDBoNTEydjUxMkgweiIvPjwvY2xpcFBhdGg+PC9kZWZzPjwvc3ZnPg=="
        },
        "displayName": "Remove Duplicates",
        "typeVersion": 2,
        "nodeCategories": [
          {
            "id": 9,
            "name": "Core Nodes"
          }
        ]
      },
      {
        "id": 1250,
        "icon": "file:openAi.svg",
        "name": "@n8n/n8n-nodes-langchain.openAi",
        "codex": {
          "data": {
            "alias": [
              "LangChain",
              "ChatGPT",
              "Sora",
              "DallE",
              "whisper",
              "audio",
              "transcribe",
              "tts",
              "assistant"
            ],
            "resources": {
              "primaryDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-langchain.openai/"
                }
              ]
            },
            "categories": [
              "AI",
              "Langchain"
            ],
            "subcategories": {
              "AI": [
                "Agents",
                "Miscellaneous",
                "Root Nodes"
              ]
            }
          }
        },
        "group": "[\"transform\"]",
        "defaults": {
          "name": "OpenAI"
        },
        "iconData": {
          "type": "file",
          "fileBuffer": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHZpZXdCb3g9IjAgMCA0MCA0MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTM2Ljg2NzEgMTYuMzcxOEMzNy43NzQ2IDEzLjY0OCAzNy40NjIxIDEwLjY2NDIgMzYuMDEwOCA4LjE4NjYxQzMzLjgyODIgNC4zODY1MyAyOS40NDA3IDIuNDMxNDkgMjUuMTU1NiAzLjM1MTUxQzIzLjI0OTMgMS4yMDM5NiAyMC41MTA1IC0wLjAxNzMxNDggMTcuNjM5MiAwLjAwMDE4NTUzM0MxMy4yNTkxIC0wLjAwOTgxNDY4IDkuMzcyNzMgMi44MTAyNSA4LjAyNTIgNi45Nzc4M0M1LjIxMTM5IDcuNTU0MSAyLjc4MjU4IDkuMzE1MzggMS4zNjEzIDExLjgxMTdDLTAuODM3NDkzIDE1LjYwMTggLTAuMzM2MjMyIDIwLjM3OTQgMi42MDEzMyAyMy42Mjk0QzEuNjkzODEgMjYuMzUzMiAyLjAwNjMyIDI5LjMzNzEgMy40NTc2IDMxLjgxNDZDNS42NDAxNSAzNS42MTQ3IDEwLjAyNzcgMzcuNTY5NyAxNC4zMTI4IDM2LjY0OTdDMTYuMjE3OSAzOC43OTczIDE4Ljk1NzkgNDAuMDE4NSAyMS44MjkyIDM5Ljk5OThDMjYuMjExOCA0MC4wMTEgMzAuMDk5NCAzNy4xODg1IDMxLjQ0NjkgMzMuMDE3MUMzNC4yNjA4IDMyLjQ0MDkgMzYuNjg5NiAzMC42Nzk2IDM4LjExMDggMjguMTgzM0M0MC4zMDcxIDI0LjM5MzIgMzkuODA0NiAxOS42MTk0IDM2Ljg2ODMgMTYuMzY5M0wzNi44NjcxIDE2LjM3MThaTTIxLjgzMTcgMzcuMzg2QzIwLjA3OCAzNy4zODg1IDE4LjM3OTIgMzYuNzc0NyAxNy4wMzI5IDM1LjY1MDlDMTcuMDk0MSAzNS42MTg1IDE3LjIwMDQgMzUuNTU5NyAxNy4yNjkxIDM1LjUxNzJMMjUuMjM0MyAzMC45MTcxQzI1LjY0MTggMzAuNjg1OCAyNS44OTE4IDMwLjI1MjEgMjUuODg5MyAyOS43ODMzVjE4LjU1NDNMMjkuMjU1NiAyMC40OTgxQzI5LjI5MTkgMjAuNTE1NiAyOS4zMTU3IDIwLjU1MDYgMjkuMzIwNyAyMC41OTA2VjI5Ljg4OTZDMjkuMzE1NyAzNC4wMjQ3IDI1Ljk2NjggMzcuMzc3MiAyMS44MzE3IDM3LjM4NlpNNS43MjY0IDMwLjUwNzFDNC44NDc2MyAyOC45ODk2IDQuNTMxMzcgMjcuMjEwOCA0LjgzMjYzIDI1LjQ4NDVDNC44OTEzOCAyNS41MTk1IDQuOTk1MTMgMjUuNTgzMiA1LjA2ODg4IDI1LjYyNTdMMTMuMDM0MSAzMC4yMjU4QzEzLjQzNzggMzAuNDYyMSAxMy45Mzc4IDMwLjQ2MjEgMTQuMzQyOCAzMC4yMjU4TDI0LjA2NjggMjQuNjEwN1YyOC40OTgzQzI0LjA2OTMgMjguNTM4MyAyNC4wNTA1IDI4LjU3NyAyNC4wMTkzIDI4LjYwMkwxNS45Njc5IDMzLjI1MDlDMTIuMzgxNSAzNS4zMTU5IDcuODAxNDQgMzQuMDg4NCA1LjcyNzY1IDMwLjUwNzFINS43MjY0Wk0zLjYzMDEgMTMuMTIwNUM0LjUwNTEyIDExLjYwMDQgNS44ODY0IDEwLjQzNzkgNy41MzE0NCA5LjgzNDE1QzcuNTMxNDQgOS45MDI5IDcuNTI3NjkgMTAuMDI0MSA3LjUyNzY5IDEwLjEwOTJWMTkuMzEwNkM3LjUyNTE5IDE5Ljc3ODEgNy43NzUxOSAyMC4yMTE5IDguMTgxNDUgMjAuNDQzMUwxNy45MDU0IDI2LjA1N0wxNC41MzkxIDI4LjAwMDhDMTQuNTA1MyAyOC4wMjMzIDE0LjQ2MjggMjguMDI3IDE0LjQyNTMgMjguMDEwOEw2LjM3MjY2IDIzLjM1ODJDMi43OTM4MyAyMS4yODU2IDEuNTY2MzEgMTYuNzA2OCAzLjYyODg1IDEzLjEyMTdMMy42MzAxIDEzLjEyMDVaTTMxLjI4ODIgMTkuNTU2OUwyMS41NjQyIDEzLjk0MTdMMjQuOTMwNiAxMS45OTkyQzI0Ljk2NDMgMTEuOTc2NyAyNS4wMDY4IDExLjk3MjkgMjUuMDQ0MyAxMS45ODkyTDMzLjA5NyAxNi42MzhDMzYuNjgyMSAxOC43MDkzIDM3LjkxMDggMjMuMjk1NyAzNS44Mzk1IDI2Ljg4MDhDMzQuOTYzMyAyOC4zOTgzIDMzLjU4MzIgMjkuNTYwOCAzMS45Mzk1IDMwLjE2NThWMjAuNjg5NEMzMS45NDMyIDIwLjIyMTkgMzEuNjk0NSAxOS43ODk0IDMxLjI4OTQgMTkuNTU2OUgzMS4yODgyWk0zNC42MzgzIDE0LjUxNDJDMzQuNTc5NSAxNC40NzggMzQuNDc1OCAxNC40MTU1IDM0LjQwMiAxNC4zNzNMMjYuNDM2OCA5Ljc3Mjg5QzI2LjAzMzEgOS41MzY2NCAyNS41MzMxIDkuNTM2NjQgMjUuMTI4MSA5Ljc3Mjg5TDE1LjQwNDEgMTUuMzg4VjExLjUwMDRDMTUuNDAxNiAxMS40NjA0IDE1LjQyMDQgMTEuNDIxNyAxNS40NTE2IDExLjM5NjdMMjMuNTAzIDYuNzUxNThDMjcuMDg5NCA0LjY4Mjc5IDMxLjY3NDUgNS45MTQwNiAzMy43NDIgOS41MDE2NEMzNC42MTU4IDExLjAxNjcgMzQuOTMyIDEyLjc5MDUgMzQuNjM1OCAxNC41MTQySDM0LjYzODNaTTEzLjU3NDEgMjEuNDQzMUwxMC4yMDY1IDE5LjQ5OTRDMTAuMTcwMiAxOS40ODE5IDEwLjE0NjUgMTkuNDQ2OCAxMC4xNDE1IDE5LjQwNjhWMTAuMTA3OUMxMC4xNDQgNS45Njc4MSAxMy41MDI4IDIuNjEyNzQgMTcuNjQyOSAyLjYxNTI0QzE5LjM5NDIgMi42MTUyNCAyMS4wODkyIDMuMjMwMjUgMjIuNDM1NSA0LjM1MDI4QzIyLjM3NDMgNC4zODI3OCAyMi4yNjkzIDQuNDQxNTMgMjIuMTk5MiA0LjQ4NDAzTDE0LjIzNDEgOS4wODQxM0MxMy44MjY2IDkuMzE1MzggMTMuNTc2NiA5Ljc0Nzg5IDEzLjU3OTEgMTAuMjE2N0wxMy41NzQxIDIxLjQ0MDZWMjEuNDQzMVpNMTUuNDAyOSAxNy41MDA2TDE5LjczNDIgMTQuOTk5M0wyNC4wNjU1IDE3LjQ5OTNWMjIuNTAwN0wxOS43MzQyIDI1LjAwMDdMMTUuNDAyOSAyMi41MDA3VjE3LjUwMDZaIiBmaWxsPSJibGFjayIvPgo8L3N2Zz4K"
        },
        "displayName": "OpenAI",
        "typeVersion": 2,
        "nodeCategories": [
          {
            "id": 25,
            "name": "AI"
          },
          {
            "id": 26,
            "name": "Langchain"
          }
        ]
      }
    ],
    "categories": [
      {
        "id": 32,
        "name": "Market Research"
      },
      {
        "id": 49,
        "name": "AI Summarization"
      }
    ],
    "image": []
  }
}