{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "global-edge-network",
  "title": "Global Edge Network",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/global-edge-network/global-edge-network.component.ts",
      "content": "// Global edge network console: a DottedMapChart hero with four floating HUD chips\n// (title + node count, region filter, node inspector, P95 latency). Hovering or\n// clicking a pin fills the inspector; the region filter narrows pins and corridors.\nimport { Component, computed, signal, ChangeDetectionStrategy } from '@angular/core'\nimport { Globe, LucideAngularModule, X } from 'lucide-angular'\nimport { UiDottedMapChartComponent } from '@/ui/charts/dotted-map-chart/dotted-map-chart.component'\nimport { cn } from '@/lib/utils'\n\n/** Pin shape the React/Vue DottedMapChart takes (`MapPin`). */\nexport interface MapPin {\n  lat: number\n  lng: number\n  label?: string\n  color?: string\n  description?: string\n  value?: string | number\n  status?: string\n}\n\n/** Route shape the React/Vue DottedMapChart takes (`MapRoute`). */\nexport interface MapRoute {\n  from: { lat: number; lng: number }\n  to: { lat: number; lng: number }\n  color?: string\n  width?: number\n  curvature?: number\n  animated?: boolean\n  dashed?: boolean\n  duration?: number\n  label?: string\n}\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\nexport type 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 NODE_MAP = new Map(ALL_NODES.map((n) => [n.id, n]))\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-global-edge-network, [ui-global-edge-network]',\n  standalone: true,\n  host: { class: 'contents' },\n  imports: [LucideAngularModule, UiDottedMapChartComponent],\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      <ui-dotted-map-chart\n        [pins]=\"mapPins()\"\n        [routes]=\"mapRoutes()\"\n        [height]=\"500\"\n        ariaLabel=\"Global Anycast Edge Network World Map\"\n        class=\"h-full w-full\"\n        (pinClick)=\"handlePinClick($any($event))\"\n        (pinHover)=\"handlePinHover($any($event))\"\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            <lucide-icon [img]=\"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\"></span>\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          @for (region of regions; track region) {\n            <button type=\"button\" [class]=\"regionClass(region)\" (click)=\"setRegion(region)\">{{ region }}</button>\n          }\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          @if (activeNode(); as node) {\n            <span [class]=\"statusDotClass(node)\"></span>\n            <span class=\"text-foreground font-medium\">{{ node.city }} ({{ node.code }})</span>\n            <span class=\"text-muted-foreground/40\">•</span>\n            <span class=\"text-muted-foreground font-mono\">{{ node.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\">{{ node.throughput }}</span>\n            @if (selectedNode()) {\n              <button\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.set(null)\"\n              >\n                <lucide-icon [img]=\"X\" class=\"h-3 w-3\" />\n              </button>\n            }\n          } @else {\n            <span class=\"bg-muted-foreground/40 h-1.5 w-1.5 shrink-0 rounded-full\"></span>\n            <span class=\"text-muted-foreground\">Click a node to inspect</span>\n          }\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  `,\n})\nexport class UiGlobalEdgeNetworkComponent {\n  protected readonly Globe = Globe\n  protected readonly X = X\n  protected readonly regions = REGIONS\n\n  readonly activeRegion = signal<RegionFilter>('All')\n  readonly selectedNode = signal<EdgeNode | null>(null)\n  readonly hoveredNode = signal<EdgeNode | null>(null)\n\n  readonly activeNode = computed(() => this.hoveredNode() || this.selectedNode())\n\n  readonly filteredNodes = computed(() => {\n    const region = this.activeRegion()\n    if (region === 'All') return ALL_NODES\n    return ALL_NODES.filter((n) => n.region === region)\n  })\n\n  readonly mapPins = computed<MapPin[]>(() =>\n    this.filteredNodes().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\n  readonly mapRoutes = computed<MapRoute[]>(() => {\n    const region = this.activeRegion()\n    const visibleIds = new Set(this.filteredNodes().map((n) => n.id))\n    const routes: MapRoute[] = []\n    for (const c of CORRIDORS) {\n      if (region !== 'All' && !(visibleIds.has(c.fromNodeId) && visibleIds.has(c.toNodeId))) continue\n      const fromNode = NODE_MAP.get(c.fromNodeId)\n      const toNode = NODE_MAP.get(c.toNodeId)\n      if (!fromNode || !toNode) continue\n      routes.push({\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    return routes\n  })\n\n  readonly activeNodesText = computed(() => {\n    switch (this.activeRegion()) {\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\n  readonly activeAvgLatencyText = computed(() => {\n    switch (this.activeRegion()) {\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\n  readonly p95Latency = computed(() => {\n    switch (this.activeRegion()) {\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\n  setRegion(region: RegionFilter): void {\n    this.activeRegion.set(region)\n    const selected = this.selectedNode()\n    if (selected && region !== 'All' && selected.region !== region) {\n      this.selectedNode.set(null)\n    }\n  }\n\n  handlePinClick(pin: MapPin): void {\n    const node = ALL_NODES.find((n) => n.lat === pin.lat && n.lng === pin.lng)\n    if (node) {\n      this.selectedNode.update((prev) => (prev?.id === node.id ? null : node))\n    }\n  }\n\n  handlePinHover(pin: MapPin | null): void {\n    if (!pin) {\n      this.hoveredNode.set(null)\n    } else {\n      this.hoveredNode.set(ALL_NODES.find((n) => n.lat === pin.lat && n.lng === pin.lng) ?? null)\n    }\n  }\n\n  regionClass(region: RegionFilter): string {\n    return cn(\n      'rounded-md px-2.5 py-1 text-xs font-medium transition-colors duration-150',\n      this.activeRegion() === region\n        ? 'bg-background text-foreground shadow-xs'\n        : 'text-muted-foreground hover:text-foreground hover:bg-background/40',\n    )\n  }\n\n  statusDotClass(node: EdgeNode): string {\n    return cn('h-1.5 w-1.5 shrink-0 rounded-full', node.status === 'optimal' ? 'bg-success' : 'bg-warning')\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/global-edge-network/global-edge-network.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/global-edge-network/index.ts",
      "content": "export {\n  UiGlobalEdgeNetworkComponent,\n  type EdgeNode,\n  type MapPin,\n  type MapRoute,\n  type RegionFilter,\n} from './global-edge-network.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/global-edge-network/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/angular/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"
  ]
}