{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "global-edge-network",
  "title": "Global Edge Network",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-vue/blocks/global-edge-network/GlobalEdgeNetwork.vue",
      "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { Globe, X } from 'lucide-vue-next'\nimport { DottedMapChart, type MapPin, type MapRoute } from '@/components/ui/charts/dotted-map-chart'\nimport { cn } from '@/lib/utils'\n\nexport interface EdgeNode {\n  id: string\n  name: string\n  code: string\n  region: 'Americas' | 'Europe' | 'APAC'\n  city: string\n  country: string\n  role: string\n  lat: number\n  lng: number\n  latencyMs: number\n  throughput: string\n  status: 'optimal' | 'degraded'\n}\n\nconst REGIONS = ['All', 'Americas', 'Europe', 'APAC'] as const\ntype RegionFilter = (typeof REGIONS)[number]\n\nconst ALL_NODES: EdgeNode[] = [\n  {\n    id: 'sfo-01',\n    name: 'SFO-Edge-1',\n    code: 'SFO',\n    region: 'Americas',\n    city: 'San Francisco',\n    country: 'United States',\n    role: 'Tier-1 Gateway',\n    lat: 37.7749,\n    lng: -122.4194,\n    latencyMs: 18,\n    throughput: '340 Gbps',\n    status: 'optimal',\n  },\n  {\n    id: 'iad-01',\n    name: 'IAD-Edge-1',\n    code: 'IAD',\n    region: 'Americas',\n    city: 'Ashburn',\n    country: 'United States',\n    role: 'Primary Transit Core',\n    lat: 39.0438,\n    lng: -77.4874,\n    latencyMs: 12,\n    throughput: '520 Gbps',\n    status: 'optimal',\n  },\n  {\n    id: 'ord-01',\n    name: 'ORD-Edge-1',\n    code: 'ORD',\n    region: 'Americas',\n    city: 'Chicago',\n    country: 'United States',\n    role: 'Midwest Exchange',\n    lat: 41.8781,\n    lng: -87.6298,\n    latencyMs: 19,\n    throughput: '280 Gbps',\n    status: 'optimal',\n  },\n  {\n    id: 'gru-01',\n    name: 'GRU-Edge-1',\n    code: 'GRU',\n    region: 'Americas',\n    city: 'São Paulo',\n    country: 'Brazil',\n    role: 'LATAM Core Transit',\n    lat: -23.5505,\n    lng: -46.6333,\n    latencyMs: 44,\n    throughput: '140 Gbps',\n    status: 'degraded',\n  },\n  {\n    id: 'lhr-01',\n    name: 'LHR-Edge-1',\n    code: 'LHR',\n    region: 'Europe',\n    city: 'London',\n    country: 'United Kingdom',\n    role: 'EMEA Backbone Core',\n    lat: 51.5074,\n    lng: -0.1278,\n    latencyMs: 14,\n    throughput: '480 Gbps',\n    status: 'optimal',\n  },\n  {\n    id: 'fra-01',\n    name: 'FRA-Edge-1',\n    code: 'FRA',\n    region: 'Europe',\n    city: 'Frankfurt',\n    country: 'Germany',\n    role: 'DE-CIX Direct Peer',\n    lat: 50.1109,\n    lng: 8.6821,\n    latencyMs: 16,\n    throughput: '410 Gbps',\n    status: 'optimal',\n  },\n  {\n    id: 'ams-01',\n    name: 'AMS-Edge-1',\n    code: 'AMS',\n    region: 'Europe',\n    city: 'Amsterdam',\n    country: 'Netherlands',\n    role: 'AMS-IX Transit Ring',\n    lat: 52.3676,\n    lng: 4.9041,\n    latencyMs: 15,\n    throughput: '390 Gbps',\n    status: 'optimal',\n  },\n  {\n    id: 'nrt-01',\n    name: 'NRT-Edge-1',\n    code: 'NRT',\n    region: 'APAC',\n    city: 'Tokyo',\n    country: 'Japan',\n    role: 'East Asia Gateway',\n    lat: 35.6762,\n    lng: 139.6503,\n    latencyMs: 22,\n    throughput: '360 Gbps',\n    status: 'optimal',\n  },\n  {\n    id: 'sin-01',\n    name: 'SIN-Edge-1',\n    code: 'SIN',\n    region: 'APAC',\n    city: 'Singapore',\n    country: 'Singapore',\n    role: 'South Asia Gateway',\n    lat: 1.3521,\n    lng: 103.8198,\n    latencyMs: 26,\n    throughput: '290 Gbps',\n    status: 'optimal',\n  },\n  {\n    id: 'syd-01',\n    name: 'SYD-Edge-1',\n    code: 'SYD',\n    region: 'APAC',\n    city: 'Sydney',\n    country: 'Australia',\n    role: 'Oceania Anycast POP',\n    lat: -33.8688,\n    lng: 151.2093,\n    latencyMs: 31,\n    throughput: '170 Gbps',\n    status: 'optimal',\n  },\n]\n\ninterface CorridorDefinition {\n  fromNodeId: string\n  toNodeId: string\n  color?: string\n  duration?: number\n  curvature?: number\n  dashed?: boolean\n  label: string\n}\n\nconst CORRIDORS: CorridorDefinition[] = [\n  {\n    fromNodeId: 'sfo-01',\n    toNodeId: 'iad-01',\n    color: 'var(--chart-1)',\n    duration: 2.6,\n    curvature: 0.2,\n    label: 'Trans-US Backbone (SFO ↔ IAD)',\n  },\n  {\n    fromNodeId: 'sfo-01',\n    toNodeId: 'ord-01',\n    color: 'var(--chart-1)',\n    duration: 2.2,\n    curvature: 0.16,\n    dashed: true,\n    label: 'Central Overland (SFO ↔ ORD)',\n  },\n  {\n    fromNodeId: 'ord-01',\n    toNodeId: 'iad-01',\n    color: 'var(--chart-1)',\n    duration: 1.8,\n    curvature: 0.14,\n    label: 'Great Lakes Trunk (ORD ↔ IAD)',\n  },\n  {\n    fromNodeId: 'iad-01',\n    toNodeId: 'lhr-01',\n    color: 'var(--chart-2)',\n    duration: 3.2,\n    curvature: 0.28,\n    label: 'Transatlantic Express (IAD ↔ LHR)',\n  },\n  {\n    fromNodeId: 'lhr-01',\n    toNodeId: 'fra-01',\n    color: 'var(--chart-3)',\n    duration: 1.9,\n    curvature: 0.15,\n    label: 'Channel Link (LHR ↔ FRA)',\n  },\n  {\n    fromNodeId: 'fra-01',\n    toNodeId: 'ams-01',\n    color: 'var(--chart-3)',\n    duration: 1.7,\n    curvature: 0.14,\n    dashed: true,\n    label: 'Rhine Valley Ring (FRA ↔ AMS)',\n  },\n  {\n    fromNodeId: 'lhr-01',\n    toNodeId: 'ams-01',\n    color: 'var(--chart-3)',\n    duration: 1.8,\n    curvature: 0.16,\n    label: 'North Sea Subsea (LHR ↔ AMS)',\n  },\n  {\n    fromNodeId: 'fra-01',\n    toNodeId: 'sin-01',\n    color: 'var(--chart-4)',\n    duration: 3.6,\n    curvature: 0.22,\n    label: 'Eurasia Optical Trunk (FRA ↔ SIN)',\n  },\n  {\n    fromNodeId: 'sin-01',\n    toNodeId: 'nrt-01',\n    color: 'var(--chart-4)',\n    duration: 2.5,\n    curvature: 0.18,\n    label: 'East Asia Marine Cable (SIN ↔ NRT)',\n  },\n  {\n    fromNodeId: 'sin-01',\n    toNodeId: 'syd-01',\n    color: 'var(--chart-5)',\n    duration: 3.0,\n    curvature: 0.22,\n    dashed: true,\n    label: 'Southern Cross Link (SIN ↔ SYD)',\n  },\n  {\n    fromNodeId: 'nrt-01',\n    toNodeId: 'sfo-01',\n    color: 'var(--chart-2)',\n    duration: 3.8,\n    curvature: 0.3,\n    label: 'Pacific High-Speed (NRT ↔ SFO)',\n  },\n  {\n    fromNodeId: 'iad-01',\n    toNodeId: 'gru-01',\n    color: 'var(--chart-5)',\n    duration: 3.4,\n    curvature: 0.24,\n    label: 'Americas Interlink (IAD ↔ GRU)',\n  },\n]\n\nconst activeRegion = ref<RegionFilter>('All')\nconst selectedNode = ref<EdgeNode | null>(null)\nconst hoveredNode = ref<EdgeNode | null>(null)\n\nconst activeNode = computed(() => hoveredNode.value || selectedNode.value)\n\nfunction setRegion(region: RegionFilter) {\n  activeRegion.value = region\n  if (selectedNode.value && region !== 'All' && selectedNode.value.region !== region) {\n    selectedNode.value = null\n  }\n}\n\nfunction handlePinClick(pin: MapPin) {\n  const node = ALL_NODES.find((n) => n.lat === pin.lat && n.lng === pin.lng)\n  if (node) {\n    selectedNode.value = selectedNode.value?.id === node.id ? null : node\n  }\n}\n\nfunction handlePinHover(pin: MapPin | null) {\n  if (!pin) {\n    hoveredNode.value = null\n  } else {\n    hoveredNode.value = ALL_NODES.find((n) => n.lat === pin.lat && n.lng === pin.lng) ?? null\n  }\n}\n\nconst filteredNodes = computed(() => {\n  if (activeRegion.value === 'All') return ALL_NODES\n  return ALL_NODES.filter((n) => n.region === activeRegion.value)\n})\n\nconst nodeMap = computed(() => new Map(ALL_NODES.map((n) => [n.id, n])))\n\nconst mapPins = computed<MapPin[]>(() => {\n  return filteredNodes.value.map((n) => ({\n    lat: n.lat,\n    lng: n.lng,\n    label: `${n.city} (${n.code})`,\n    color: n.status === 'optimal' ? 'var(--chart-1)' : '#f59e0b',\n    description: n.role,\n    value: `${n.latencyMs}ms • ${n.throughput}`,\n    status: n.status,\n  }))\n})\n\nconst mapRoutes = computed<MapRoute[]>(() => {\n  const visibleIds = new Set(filteredNodes.value.map((n) => n.id))\n  return CORRIDORS.filter((c) => {\n    if (activeRegion.value === 'All') return true\n    return visibleIds.has(c.fromNodeId) && visibleIds.has(c.toNodeId)\n  })\n    .map((c) => {\n      const fromNode = nodeMap.value.get(c.fromNodeId)\n      const toNode = nodeMap.value.get(c.toNodeId)\n      if (!fromNode || !toNode) return null\n      return {\n        from: { lat: fromNode.lat, lng: fromNode.lng },\n        to: { lat: toNode.lat, lng: toNode.lng },\n        color: c.color ?? 'var(--primary)',\n        duration: c.duration ?? 3,\n        curvature: c.curvature ?? 0.2,\n        dashed: c.dashed,\n        label: c.label,\n      }\n    })\n    .filter(Boolean) as MapRoute[]\n})\n\nconst activeNodesText = computed(() => {\n  switch (activeRegion.value) {\n    case 'Americas':\n      return '12 Nodes Active'\n    case 'Europe':\n      return '11 Nodes Active'\n    case 'APAC':\n      return '9 Nodes Active'\n    default:\n      return '32 Nodes Active'\n  }\n})\n\nconst activeAvgLatencyText = computed(() => {\n  switch (activeRegion.value) {\n    case 'Americas':\n      return '16ms avg'\n    case 'Europe':\n      return '15ms avg'\n    case 'APAC':\n      return '26ms avg'\n    default:\n      return '18ms avg'\n  }\n})\n\nconst p95Latency = computed(() => {\n  switch (activeRegion.value) {\n    case 'Americas':\n      return '19ms'\n    case 'Europe':\n      return '16ms'\n    case 'APAC':\n      return '28ms'\n    default:\n      return '24ms'\n  }\n})\n</script>\n\n<template>\n  <div\n    data-slot=\"global-edge-network\"\n    class=\"border-border bg-card/60 relative h-[500px] w-full overflow-hidden rounded-xl border shadow-xs backdrop-blur-xs\"\n  >\n    <!-- Map Canvas (Hero) -->\n    <DottedMapChart\n      :pins=\"mapPins\"\n      :routes=\"mapRoutes\"\n      :height=\"500\"\n      aria-label=\"Global Anycast Edge Network World Map\"\n      class=\"h-full w-full\"\n      @pin-click=\"handlePinClick\"\n      @pin-hover=\"handlePinHover\"\n    />\n\n    <!-- Top-Left Floating Chip: Title & Status -->\n    <div class=\"pointer-events-none absolute top-3 left-3 z-10 sm:top-4 sm:left-4\">\n      <div\n        class=\"border-border/60 bg-background/80 pointer-events-auto inline-flex items-center gap-2 rounded-full border px-3 py-1.5 text-xs font-medium shadow-xs backdrop-blur-md\"\n      >\n        <span class=\"text-foreground flex items-center gap-1.5\">\n          <Globe class=\"text-muted-foreground h-3.5 w-3.5\" />\n          <span class=\"tracking-tight\">Global Transit Mesh</span>\n        </span>\n        <span class=\"text-muted-foreground/40\">•</span>\n        <span class=\"text-muted-foreground inline-flex items-center gap-1.5\">\n          <span class=\"bg-success h-1.5 w-1.5 animate-pulse rounded-full\" />\n          <span>{{ activeNodesText }}</span>\n        </span>\n        <span class=\"text-muted-foreground/40 hidden md:inline\">•</span>\n        <span class=\"text-muted-foreground hidden font-mono md:inline\">{{ activeAvgLatencyText }}</span>\n      </div>\n    </div>\n\n    <!-- Top-Right Floating Chip: Glass Segmented Region Filter -->\n    <div class=\"pointer-events-none absolute top-3 right-3 z-10 sm:top-4 sm:right-4\">\n      <div\n        class=\"border-border/60 bg-muted/60 pointer-events-auto inline-flex items-center gap-0.5 rounded-lg border p-0.5 text-xs shadow-xs backdrop-blur-md\"\n      >\n        <button\n          v-for=\"region in REGIONS\"\n          :key=\"region\"\n          type=\"button\"\n          :class=\"\n            cn(\n              'rounded-md px-2.5 py-1 text-xs font-medium transition-colors duration-150',\n              activeRegion === region\n                ? 'bg-background text-foreground shadow-xs'\n                : 'text-muted-foreground hover:text-foreground hover:bg-background/40',\n            )\n          \"\n          @click=\"setRegion(region)\"\n        >\n          {{ region }}\n        </button>\n      </div>\n    </div>\n\n    <!-- Bottom-Left Floating Chip: Interactive Node Inspector -->\n    <div class=\"pointer-events-none absolute bottom-3 left-3 z-10 sm:bottom-4 sm:left-4\">\n      <div\n        class=\"border-border/60 bg-background/80 pointer-events-auto inline-flex items-center gap-2 rounded-full border px-3 py-1.5 text-xs shadow-xs backdrop-blur-md transition-colors duration-150\"\n      >\n        <template v-if=\"activeNode\">\n          <span\n            class=\"h-1.5 w-1.5 shrink-0 rounded-full\"\n            :class=\"activeNode.status === 'optimal' ? 'bg-success' : 'bg-warning'\"\n          />\n          <span class=\"text-foreground font-medium\"> {{ activeNode.city }} ({{ activeNode.code }}) </span>\n          <span class=\"text-muted-foreground/40\">•</span>\n          <span class=\"text-muted-foreground font-mono\">{{ activeNode.latencyMs }}ms</span>\n          <span class=\"text-muted-foreground/40 hidden sm:inline\">•</span>\n          <span class=\"text-muted-foreground hidden font-mono sm:inline\">{{ activeNode.throughput }}</span>\n          <button\n            v-if=\"selectedNode\"\n            type=\"button\"\n            aria-label=\"Clear selection\"\n            class=\"text-muted-foreground hover:text-foreground hover:bg-muted -mr-1 ml-0.5 rounded-full p-0.5 transition-colors\"\n            @click=\"selectedNode = null\"\n          >\n            <X class=\"h-3 w-3\" />\n          </button>\n        </template>\n        <template v-else>\n          <span class=\"bg-muted-foreground/40 h-1.5 w-1.5 shrink-0 rounded-full\" />\n          <span class=\"text-muted-foreground\">Click a node to inspect</span>\n        </template>\n      </div>\n    </div>\n\n    <!-- Bottom-Right Floating Chip: Minimal Latency Badge -->\n    <div class=\"pointer-events-none absolute right-3 bottom-3 z-10 sm:right-4 sm:bottom-4\">\n      <div\n        class=\"border-border/60 bg-background/80 pointer-events-auto inline-flex items-center gap-1.5 rounded-full border px-3 py-1.5 text-xs font-medium shadow-xs backdrop-blur-md\"\n      >\n        <span class=\"text-muted-foreground\">P95</span>\n        <span class=\"text-foreground font-mono\">{{ p95Latency }}</span>\n      </div>\n    </div>\n  </div>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/GlobalEdgeNetwork.vue"
    },
    {
      "path": "packages/registry-vue/blocks/global-edge-network/index.ts",
      "content": "export { default as GlobalEdgeNetwork } from './GlobalEdgeNetwork.vue'\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/global-edge-network/index.ts"
    }
  ],
  "dependencies": [
    "lucide-vue-next"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/vue/dotted-map-chart.json"
  ],
  "description": "Cloudflare Radar and Vercel Edge style infrastructure console with real-time anycast telemetry, interactive DottedMapChart with Bezier flow corridors, P95 latency HUD metrics, and live edge node routing table.",
  "categories": [
    "dashboard",
    "devops",
    "analytics"
  ]
}