{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "stream-processing-flink-topology",
  "title": "Stream Processing Flink Topology",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/stream-processing-flink-topology/stream-processing-flink-topology.component.ts",
      "content": "// Apache Flink & RisingWave stateful streaming graph: real-time DAG topology, window\n// throughput, checkpointing duration, RocksDB state inspector, and backpressure heat\n// monitor. Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, Input, computed, signal } from '@angular/core'\nimport {\n  AlertTriangle,\n  ArrowRight,\n  Camera,\n  Check,\n  CheckCircle2,\n  Clock,\n  Copy,\n  Cpu,\n  Database,\n  Loader2,\n  LucideAngularModule,\n  Radio,\n  Square,\n  Workflow,\n} from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiBadgeComponent } from '@/ui/badge/badge.component'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport {\n  UiCardComponent,\n  UiCardContentComponent,\n  UiCardDescriptionComponent,\n  UiCardHeaderComponent,\n  UiCardTitleComponent,\n} from '@/ui/card/card.component'\nimport { UiStreamOperatorDetailComponent } from './stream-operator-detail.component'\nimport { UiStreamTopologyTelemetryComponent } from './stream-topology-telemetry.component'\nimport type { FlinkOperatorNode, FlinkSubtask } from './stream-topology-types'\nimport { defaultFlinkOperators } from './stream-topology-data'\n\nexport type { FlinkOperatorNode, FlinkSubtask }\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-stream-processing-flink-topology, [ui-stream-processing-flink-topology]',\n  standalone: true,\n  // React renders the root <div> itself: the host stays out of layout and `class` goes to the root.\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [\n    LucideAngularModule,\n    UiBadgeComponent,\n    UiButtonComponent,\n    UiCardComponent,\n    UiCardContentComponent,\n    UiCardDescriptionComponent,\n    UiCardHeaderComponent,\n    UiCardTitleComponent,\n    UiStreamOperatorDetailComponent,\n    UiStreamTopologyTelemetryComponent,\n  ],\n  template: `\n    <div data-slot=\"stream-processing-flink-topology\" [class]=\"rootClass\">\n      <!-- 1. Header Section -->\n      <div class=\"flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between\">\n        <div class=\"space-y-1.5\">\n          <div class=\"flex flex-wrap items-center gap-2.5\">\n            <div\n              class=\"bg-muted text-muted-foreground border-border flex size-9 shrink-0 items-center justify-center rounded-lg border shadow-xs\"\n              aria-hidden=\"true\"\n            >\n              <lucide-icon [img]=\"Workflow\" class=\"text-primary size-4.5\" />\n            </div>\n            <div class=\"flex flex-wrap items-center gap-2\">\n              <h1 class=\"text-foreground font-mono text-xl font-bold tracking-tight break-all sm:text-2xl\">\n                realtime-fraud-scoring-pipeline\n              </h1>\n              <span ui-badge variant=\"outline\" class=\"font-mono text-xs\">Flink 1.19 on Kubernetes</span>\n            </div>\n            <span ui-badge variant=\"success\" class=\"gap-1.5 text-xs font-medium\">\n              <span class=\"relative flex size-2 shrink-0\">\n                <span class=\"bg-success absolute inline-flex h-full w-full rounded-full opacity-75\"></span>\n                <span class=\"bg-success relative inline-flex size-2 rounded-full\"></span>\n              </span>\n              <span>Job Running · Checkpointing Healthy</span>\n            </span>\n          </div>\n          <p class=\"text-muted-foreground font-mono text-xs\">\n            Checkpoint Interval: Every 10s · RocksDB StateBackend · SLA Target: &lt; 50ms Lag · Job ID: flink_job_992014\n          </p>\n        </div>\n\n        <!-- Action Buttons -->\n        <div class=\"flex flex-wrap items-center gap-2\">\n          <button\n            ui-button\n            variant=\"outline\"\n            size=\"sm\"\n            class=\"gap-1.5 text-xs font-medium\"\n            [disabled]=\"isTriggeringSavepoint()\"\n            (click)=\"handleTriggerSavepoint()\"\n          >\n            @if (isTriggeringSavepoint()) {\n              <lucide-icon [img]=\"Loader2\" class=\"size-3.5 animate-spin\" />\n            } @else {\n              <lucide-icon [img]=\"Camera\" class=\"text-info size-3.5\" />\n            }\n            <span>{{ isTriggeringSavepoint() ? 'Creating Savepoint...' : 'Trigger Savepoint' }}</span>\n          </button>\n\n          <button\n            ui-button\n            variant=\"outline\"\n            size=\"sm\"\n            class=\"text-destructive hover:border-destructive/40 hover:bg-destructive/10 gap-1.5 text-xs font-medium\"\n            [disabled]=\"isCanceling()\"\n            (click)=\"handleCancelJob()\"\n          >\n            @if (isCanceling()) {\n              <lucide-icon [img]=\"Loader2\" class=\"size-3.5 animate-spin\" />\n            } @else {\n              <lucide-icon [img]=\"Square\" class=\"size-3.5 fill-current\" />\n            }\n            <span>{{ isCanceling() ? 'Canceling with Savepoint...' : 'Cancel Job with Savepoint' }}</span>\n          </button>\n        </div>\n      </div>\n\n      <!-- Active Savepoint Notice Banner -->\n      @if (savepointNotice(); as notice) {\n        <div\n          class=\"text-foreground border-info/30 bg-info/10 flex items-center justify-between rounded-lg border p-3 text-xs shadow-xs\"\n          role=\"status\"\n        >\n          <div class=\"flex items-center gap-2.5\">\n            <lucide-icon [img]=\"CheckCircle2\" class=\"text-info size-4 shrink-0\" />\n            <div>\n              <span class=\"text-info font-semibold\">Savepoint completed successfully:</span>\n              <span class=\"ml-1 font-mono text-xs\">{{ notice }}</span>\n            </div>\n          </div>\n          <button\n            ui-button\n            variant=\"ghost\"\n            size=\"xs\"\n            class=\"h-6 gap-1 px-2 text-xs\"\n            (click)=\"copyText('savepoint', notice)\"\n          >\n            @if (copiedKey() === 'savepoint') {\n              <lucide-icon [img]=\"Check\" class=\"text-success size-3\" />\n            } @else {\n              <lucide-icon [img]=\"Copy\" class=\"size-3\" />\n            }\n            <span>{{ copiedKey() === 'savepoint' ? 'Copied' : 'Copy URI' }}</span>\n          </button>\n        </div>\n      }\n\n      <!-- Active Cancellation Notice Banner -->\n      @if (cancelConfirmed()) {\n        <div\n          class=\"text-foreground border-warning/30 bg-warning/10 flex items-center justify-between rounded-lg border p-3 text-xs shadow-xs\"\n          role=\"status\"\n        >\n          <div class=\"flex items-center gap-2.5\">\n            <lucide-icon [img]=\"AlertTriangle\" class=\"text-warning size-4 shrink-0\" />\n            <div>\n              <span class=\"text-warning font-semibold\">Graceful Job Drain Initiated:</span>\n              <span class=\"ml-1\">Stopping topology sources and committing final RocksDB savepoint to S3 storage.</span>\n            </div>\n          </div>\n          <span ui-badge variant=\"outline\" class=\"font-mono text-xs\">Drain Status: 100%</span>\n        </div>\n      }\n\n      <!-- 2. 4 Stream Telemetry KPI Cards -->\n      <ui-stream-topology-telemetry />\n\n      <!-- 3. Interactive 4-Operator Streaming Topology DAG -->\n      <div ui-card class=\"shadow-xs\">\n        <div ui-card-header class=\"pb-3\">\n          <div class=\"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between\">\n            <div>\n              <div class=\"flex items-center gap-2\">\n                <h3 ui-card-title class=\"text-base font-semibold\">Streaming Execution Topology DAG</h3>\n                <span ui-badge variant=\"outline\" class=\"font-mono text-xs\">4 Stateful Operators</span>\n              </div>\n              <p ui-card-description class=\"text-xs\">\n                Live dataflow graph with event-time watermarking, state sizes, and backpressure telemetry. Click any\n                operator to inspect metrics and subtasks.\n              </p>\n            </div>\n            <div class=\"flex flex-wrap items-center gap-2\">\n              <div\n                class=\"border-border bg-muted/40 text-muted-foreground flex items-center gap-1.5 rounded-md border px-2.5 py-1 font-mono text-xs\"\n              >\n                <span class=\"bg-success size-2 rounded-full\"></span>\n                <span>Backpressure Heat: 0.0% (Green)</span>\n              </div>\n              <div\n                class=\"border-border bg-muted/40 text-muted-foreground flex items-center gap-1.5 rounded-md border px-2.5 py-1 font-mono text-xs\"\n              >\n                <lucide-icon [img]=\"Database\" class=\"size-3\" />\n                <span>Total Managed State: 57.0 MB</span>\n              </div>\n            </div>\n          </div>\n        </div>\n\n        <div ui-card-content class=\"p-4 pt-1 sm:p-6\">\n          <div class=\"border-border bg-muted/15 rounded-xl border p-4 sm:p-5\">\n            <!-- 4 Connected Nodes Grid -->\n            <div class=\"grid grid-cols-1 gap-4 lg:grid-cols-4\">\n              <!-- Node 1: Kafka Ingestion Source -->\n              <div\n                role=\"button\"\n                tabindex=\"0\"\n                [class]=\"nodeClass('op-kafka-source')\"\n                (click)=\"selectOperator('op-kafka-source')\"\n                (keydown.enter)=\"selectOperator('op-kafka-source')\"\n                (keydown.space)=\"$event.preventDefault(); selectOperator('op-kafka-source')\"\n              >\n                <div class=\"space-y-3\">\n                  <div class=\"flex items-start justify-between gap-2\">\n                    <div class=\"flex items-center gap-2\">\n                      <div\n                        class=\"border-info/30 bg-info/10 text-info flex size-7 items-center justify-center rounded-md border\"\n                      >\n                        <lucide-icon [img]=\"Radio\" class=\"size-3.5\" />\n                      </div>\n                      <span ui-badge variant=\"outline\" class=\"border-info/30 text-info font-mono text-xs\">SOURCE</span>\n                    </div>\n                    <span ui-badge variant=\"outline\" class=\"font-mono text-xs\">p=8</span>\n                  </div>\n\n                  <div>\n                    <div class=\"text-foreground font-mono text-xs leading-snug font-bold\">Kafka Ingestion Source</div>\n                    <p class=\"text-muted-foreground mt-1 font-mono text-xs\">42.5k rec/s · Backpressure: 0%</p>\n                  </div>\n\n                  <div class=\"border-border/60 space-y-1.5 border-t pt-2.5 font-mono text-xs\">\n                    <div class=\"text-muted-foreground flex items-center justify-between\">\n                      <span>Throughput:</span>\n                      <span class=\"text-foreground font-semibold tabular-nums\">8.4 MB/s</span>\n                    </div>\n                    <div class=\"text-muted-foreground flex items-center justify-between\">\n                      <span>State Size:</span>\n                      <span class=\"text-foreground tabular-nums\">0 MB (Stateless)</span>\n                    </div>\n                  </div>\n                </div>\n\n                <div class=\"border-border/60 mt-3 flex items-center justify-between border-t pt-2 text-xs\">\n                  <span class=\"text-muted-foreground font-mono\">events.fraud.transactions</span>\n                  <lucide-icon\n                    [img]=\"ArrowRight\"\n                    class=\"text-muted-foreground group-hover:text-primary size-3.5 shrink-0 transition-colors\"\n                  />\n                </div>\n              </div>\n\n              <!-- Node 2: Keyed Sliding Window -->\n              <div\n                role=\"button\"\n                tabindex=\"0\"\n                [class]=\"nodeClass('op-keyed-window')\"\n                (click)=\"selectOperator('op-keyed-window')\"\n                (keydown.enter)=\"selectOperator('op-keyed-window')\"\n                (keydown.space)=\"$event.preventDefault(); selectOperator('op-keyed-window')\"\n              >\n                <div class=\"space-y-3\">\n                  <div class=\"flex items-start justify-between gap-2\">\n                    <div class=\"flex items-center gap-2\">\n                      <div\n                        class=\"border-chart-1/30 bg-chart-1/10 text-chart-1 flex size-7 items-center justify-center rounded-md border\"\n                      >\n                        <lucide-icon [img]=\"Clock\" class=\"size-3.5\" />\n                      </div>\n                      <span ui-badge variant=\"outline\" class=\"border-chart-1/30 text-chart-1 font-mono text-xs\"\n                        >WINDOW</span\n                      >\n                    </div>\n                    <span ui-badge variant=\"outline\" class=\"font-mono text-xs\">p=16</span>\n                  </div>\n\n                  <div>\n                    <div class=\"text-foreground font-mono text-xs leading-snug font-bold\">Keyed Sliding Window</div>\n                    <p class=\"text-muted-foreground mt-1 font-mono text-xs\">5-min window, 10s slide · 12,400 keys</p>\n                  </div>\n\n                  <div class=\"border-border/60 space-y-1.5 border-t pt-2.5 font-mono text-xs\">\n                    <div class=\"text-muted-foreground flex items-center justify-between\">\n                      <span>Output Rate:</span>\n                      <span class=\"text-foreground font-semibold tabular-nums\">38.2k rec/s</span>\n                    </div>\n                    <div class=\"text-muted-foreground flex items-center justify-between\">\n                      <span>RocksDB State:</span>\n                      <span class=\"text-foreground text-chart-1 font-semibold tabular-nums\">18.4 MB</span>\n                    </div>\n                  </div>\n                </div>\n\n                <div class=\"border-border/60 mt-3 flex items-center justify-between border-t pt-2 text-xs\">\n                  <span class=\"text-muted-foreground font-mono\">Cardholder Velocity Agg</span>\n                  <lucide-icon\n                    [img]=\"ArrowRight\"\n                    class=\"text-muted-foreground group-hover:text-primary size-3.5 shrink-0 transition-colors\"\n                  />\n                </div>\n              </div>\n\n              <!-- Node 3: ML Fraud Scoring Pattern Matcher -->\n              <div\n                role=\"button\"\n                tabindex=\"0\"\n                [class]=\"nodeClass('op-ml-scoring')\"\n                (click)=\"selectOperator('op-ml-scoring')\"\n                (keydown.enter)=\"selectOperator('op-ml-scoring')\"\n                (keydown.space)=\"$event.preventDefault(); selectOperator('op-ml-scoring')\"\n              >\n                <div class=\"space-y-3\">\n                  <div class=\"flex items-start justify-between gap-2\">\n                    <div class=\"flex items-center gap-2\">\n                      <div\n                        class=\"border-chart-2/30 bg-chart-2/10 text-chart-2 flex size-7 items-center justify-center rounded-md border\"\n                      >\n                        <lucide-icon [img]=\"Cpu\" class=\"size-3.5\" />\n                      </div>\n                      <span ui-badge variant=\"outline\" class=\"border-chart-2/30 text-chart-2 font-mono text-xs\"\n                        >CEP & ML</span\n                      >\n                    </div>\n                    <span ui-badge variant=\"outline\" class=\"font-mono text-xs\">p=16</span>\n                  </div>\n\n                  <div>\n                    <div class=\"text-foreground font-mono text-xs leading-snug font-bold\">ML Fraud Scoring Matcher</div>\n                    <p class=\"text-muted-foreground mt-1 font-mono text-xs\">Inference: 1.2ms · RocksDB: 38.2 MB</p>\n                  </div>\n\n                  <div class=\"border-border/60 space-y-1.5 border-t pt-2.5 font-mono text-xs\">\n                    <div class=\"text-muted-foreground flex items-center justify-between\">\n                      <span>ONNX Inference:</span>\n                      <span class=\"text-success text-success font-semibold tabular-nums\">p99 &lt; 1.2ms</span>\n                    </div>\n                    <div class=\"text-muted-foreground flex items-center justify-between\">\n                      <span>Managed State:</span>\n                      <span class=\"text-foreground text-chart-2 font-semibold tabular-nums\">38.2 MB</span>\n                    </div>\n                  </div>\n                </div>\n\n                <div class=\"border-border/60 mt-3 flex items-center justify-between border-t pt-2 text-xs\">\n                  <span class=\"text-muted-foreground font-mono\">xgboost_v4.onnx</span>\n                  <lucide-icon\n                    [img]=\"ArrowRight\"\n                    class=\"text-muted-foreground group-hover:text-primary size-3.5 shrink-0 transition-colors\"\n                  />\n                </div>\n              </div>\n\n              <!-- Node 4: Sink: Alert Dispatcher & Redis Cache -->\n              <div\n                role=\"button\"\n                tabindex=\"0\"\n                [class]=\"nodeClass('op-sink-dispatcher')\"\n                (click)=\"selectOperator('op-sink-dispatcher')\"\n                (keydown.enter)=\"selectOperator('op-sink-dispatcher')\"\n                (keydown.space)=\"$event.preventDefault(); selectOperator('op-sink-dispatcher')\"\n              >\n                <div class=\"space-y-3\">\n                  <div class=\"flex items-start justify-between gap-2\">\n                    <div class=\"flex items-center gap-2\">\n                      <div\n                        class=\"border-success/30 bg-success/10 text-success flex size-7 items-center justify-center rounded-md border\"\n                      >\n                        <lucide-icon [img]=\"Database\" class=\"size-3.5\" />\n                      </div>\n                      <span ui-badge variant=\"outline\" class=\"border-success/30 text-success font-mono text-xs\"\n                        >SINK</span\n                      >\n                    </div>\n                    <span ui-badge variant=\"outline\" class=\"font-mono text-xs\">p=8</span>\n                  </div>\n\n                  <div>\n                    <div class=\"text-foreground font-mono text-xs leading-snug font-bold\">Sink: Alert Dispatcher</div>\n                    <p class=\"text-muted-foreground mt-1 font-mono text-xs\">Redis Cache & Webhooks · 42.5k rec/s</p>\n                  </div>\n\n                  <div class=\"border-border/60 space-y-1.5 border-t pt-2.5 font-mono text-xs\">\n                    <div class=\"text-muted-foreground flex items-center justify-between\">\n                      <span>Semantics:</span>\n                      <span class=\"text-foreground font-semibold\">2PC Exactly-Once</span>\n                    </div>\n                    <div class=\"text-muted-foreground flex items-center justify-between\">\n                      <span>Fan-Out:</span>\n                      <span class=\"text-foreground font-semibold tabular-nums\">42.5k rec/s</span>\n                    </div>\n                  </div>\n                </div>\n\n                <div class=\"border-border/60 mt-3 flex items-center justify-between border-t pt-2 text-xs\">\n                  <span class=\"text-muted-foreground font-mono\">redis:6379 + alerts.queue</span>\n                  <lucide-icon [img]=\"CheckCircle2\" class=\"text-success size-3.5 shrink-0\" />\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n\n      <!-- 4. Operator Detailed Performance & State Inspector Panel -->\n      <ui-stream-operator-detail\n        [operator]=\"selectedOperator()\"\n        [copiedKey]=\"copiedKey()\"\n        (copy)=\"copyText($event.key, $event.value)\"\n      />\n    </div>\n  `,\n})\nexport class UiStreamProcessingFlinkTopologyComponent {\n  protected readonly AlertTriangle = AlertTriangle\n  protected readonly ArrowRight = ArrowRight\n  protected readonly Camera = Camera\n  protected readonly Check = Check\n  protected readonly CheckCircle2 = CheckCircle2\n  protected readonly Clock = Clock\n  protected readonly Copy = Copy\n  protected readonly Cpu = Cpu\n  protected readonly Database = Database\n  protected readonly Loader2 = Loader2\n  protected readonly Radio = Radio\n  protected readonly Square = Square\n  protected readonly Workflow = Workflow\n\n  @Input() operators: FlinkOperatorNode[] = defaultFlinkOperators\n  @Input('class') className?: string\n\n  readonly selectedOperatorId = signal<string>('op-ml-scoring')\n  readonly isTriggeringSavepoint = signal<boolean>(false)\n  readonly savepointNotice = signal<string | null>(null)\n  readonly isCanceling = signal<boolean>(false)\n  readonly cancelConfirmed = signal<boolean>(false)\n  readonly copiedKey = signal<string | null>(null)\n\n  readonly selectedOperator = computed(() => {\n    return this.operators.find((op) => op.id === this.selectedOperatorId()) ?? this.operators[0]!\n  })\n\n  get rootClass(): string {\n    return cn('w-full space-y-6', this.className)\n  }\n\n  nodeClass(id: string): string {\n    return cn(\n      'group focus-visible:ring-ring relative flex cursor-pointer flex-col justify-between rounded-xl border p-4 transition-colors duration-200 focus-visible:ring-2 focus-visible:outline-none',\n      this.selectedOperatorId() === id\n        ? 'border-primary bg-primary/[0.04] ring-primary/30 shadow-xs ring-2'\n        : 'border-border bg-card hover:border-primary/50 hover:bg-muted/30',\n    )\n  }\n\n  selectOperator(id: string): void {\n    this.selectedOperatorId.set(id)\n  }\n\n  handleTriggerSavepoint(): void {\n    if (this.isTriggeringSavepoint()) return\n    this.isTriggeringSavepoint.set(true)\n    this.savepointNotice.set(null)\n    setTimeout(() => {\n      this.isTriggeringSavepoint.set(false)\n      this.savepointNotice.set('s3://flink-savepoints/prod/savepoint-fraud-90412-20260821-143245/')\n      setTimeout(() => {\n        if (this.savepointNotice()?.includes('savepoint-fraud-90412')) this.savepointNotice.set(null)\n      }, 6500)\n    }, 1800)\n  }\n\n  handleCancelJob(): void {\n    if (this.isCanceling()) return\n    this.isCanceling.set(true)\n    setTimeout(() => {\n      this.isCanceling.set(false)\n      this.cancelConfirmed.set(true)\n      setTimeout(() => {\n        this.cancelConfirmed.set(false)\n      }, 4500)\n    }, 2000)\n  }\n\n  copyText(key: string, value: string): void {\n    try {\n      if (typeof navigator !== 'undefined' && navigator.clipboard) {\n        void navigator.clipboard.writeText(value)\n        this.copiedKey.set(key)\n        setTimeout(() => {\n          if (this.copiedKey() === key) this.copiedKey.set(null)\n        }, 2000)\n      }\n    } catch {\n      // Clipboard fallback\n    }\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/stream-processing-flink-topology/stream-processing-flink-topology.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/stream-processing-flink-topology/stream-operator-detail.component.ts",
      "content": "// Operator detailed performance and state inspector panel: subtask distribution table,\n// RocksDB managed state, JVM and GC telemetry, and runtime configuration parameters.\n// Port of the Vue/React operator detail panel 1:1.\nimport { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, signal } from '@angular/core'\nimport { Activity, Check, Copy, LucideAngularModule, Server, ShieldCheck } from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiBadgeComponent } from '@/ui/badge/badge.component'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport {\n  UiCardComponent,\n  UiCardContentComponent,\n  UiCardDescriptionComponent,\n  UiCardHeaderComponent,\n  UiCardTitleComponent,\n} from '@/ui/card/card.component'\nimport { UiProgressComponent } from '@/ui/progress/progress.component'\nimport { UiSeparatorComponent } from '@/ui/separator/separator.component'\nimport {\n  UiTableBodyComponent,\n  UiTableCellComponent,\n  UiTableComponent,\n  UiTableHeadComponent,\n  UiTableHeaderComponent,\n  UiTableRowComponent,\n} from '@/ui/table/table.component'\nimport type { FlinkOperatorNode } from './stream-topology-types'\n\nexport type InspectorTab = 'subtasks' | 'state' | 'resources' | 'config'\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-stream-operator-detail, [ui-stream-operator-detail]',\n  standalone: true,\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [\n    LucideAngularModule,\n    UiBadgeComponent,\n    UiButtonComponent,\n    UiCardComponent,\n    UiCardContentComponent,\n    UiCardDescriptionComponent,\n    UiCardHeaderComponent,\n    UiCardTitleComponent,\n    UiProgressComponent,\n    UiSeparatorComponent,\n    UiTableBodyComponent,\n    UiTableCellComponent,\n    UiTableComponent,\n    UiTableHeadComponent,\n    UiTableHeaderComponent,\n    UiTableRowComponent,\n  ],\n  template: `\n    <div ui-card class=\"shadow-xs\">\n      <div ui-card-header class=\"pb-3\">\n        <div class=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n          <div class=\"space-y-1\">\n            <div class=\"flex flex-wrap items-center gap-2\">\n              <h3 ui-card-title class=\"font-mono text-base font-bold\">{{ operator.name }}</h3>\n              <span ui-badge variant=\"success\" class=\"gap-1 font-mono text-xs\">\n                <span class=\"bg-success size-1.5 rounded-full\"></span>\n                {{ operator.status }}\n              </span>\n              <span ui-badge variant=\"outline\" class=\"font-mono text-xs\">\n                Parallelism: {{ operator.parallelism }} subtasks\n              </span>\n            </div>\n            <p ui-card-description class=\"text-xs\">{{ operator.description }}</p>\n          </div>\n\n          <!-- Inspector Tab Navigation Buttons -->\n          <div class=\"bg-muted/60 flex flex-wrap items-center gap-1 rounded-lg border p-1\">\n            <button type=\"button\" [class]=\"tabClass('subtasks')\" (click)=\"activeInspectorTab.set('subtasks')\">\n              Subtasks & Distribution\n            </button>\n            <button type=\"button\" [class]=\"tabClass('state')\" (click)=\"activeInspectorTab.set('state')\">\n              RocksDB Managed State\n            </button>\n            <button type=\"button\" [class]=\"tabClass('resources')\" (click)=\"activeInspectorTab.set('resources')\">\n              JVM & GC Telemetry\n            </button>\n            <button type=\"button\" [class]=\"tabClass('config')\" (click)=\"activeInspectorTab.set('config')\">\n              Configuration Parameters\n            </button>\n          </div>\n        </div>\n      </div>\n\n      <!-- Key Operator Telemetry Bar -->\n      <div class=\"bg-muted/20 divide-border/60 grid grid-cols-2 divide-x border-y sm:grid-cols-4 lg:grid-cols-6\">\n        <div class=\"p-3\">\n          <div class=\"text-muted-foreground text-xs font-medium\">Input Rate</div>\n          <div class=\"text-foreground mt-0.5 font-mono text-sm font-bold tabular-nums\">\n            {{ operator.inputRecordsRate }}\n          </div>\n          <div class=\"text-muted-foreground font-mono text-xs tabular-nums\">{{ operator.inputBytesRate }}</div>\n        </div>\n        <div class=\"p-3\">\n          <div class=\"text-muted-foreground text-xs font-medium\">Output Rate</div>\n          <div class=\"text-foreground mt-0.5 font-mono text-sm font-bold tabular-nums\">\n            {{ operator.outputRecordsRate }}\n          </div>\n          <div class=\"text-muted-foreground font-mono text-xs tabular-nums\">{{ operator.outputBytesRate }}</div>\n        </div>\n        <div class=\"p-3\">\n          <div class=\"text-muted-foreground text-xs font-medium\">Managed State</div>\n          <div class=\"text-primary mt-0.5 font-mono text-sm font-bold tabular-nums\">\n            {{ operator.managedStateSize }}\n          </div>\n          <div class=\"text-muted-foreground truncate font-mono text-xs\">{{ operator.stateBackend }}</div>\n        </div>\n        <div class=\"p-3\">\n          <div class=\"text-muted-foreground text-xs font-medium\">Watermark Lag</div>\n          <div class=\"text-success text-success mt-0.5 font-mono text-sm font-bold tabular-nums\">\n            {{ operator.watermarkLag }}\n          </div>\n          <div class=\"text-muted-foreground font-mono text-xs\">Event Time OK</div>\n        </div>\n        <div class=\"p-3\">\n          <div class=\"text-muted-foreground text-xs font-medium\">CPU Core Load</div>\n          <div class=\"text-foreground mt-0.5 font-mono text-sm font-bold tabular-nums\">{{ operator.cpuPeak }}</div>\n          <div class=\"text-muted-foreground font-mono text-xs\">Across {{ operator.parallelism }} cores</div>\n        </div>\n        <div class=\"p-3\">\n          <div class=\"text-muted-foreground text-xs font-medium\">GC Pause Time</div>\n          <div class=\"text-foreground mt-0.5 font-mono text-sm font-bold tabular-nums\">{{ operator.gcTime }}</div>\n          <div class=\"text-muted-foreground font-mono text-xs\">G1 Garbage Collector</div>\n        </div>\n      </div>\n\n      <div ui-card-content class=\"p-0\">\n        <!-- TAB 1: Subtasks Table -->\n        @if (activeInspectorTab() === 'subtasks') {\n          <div class=\"overflow-x-auto\">\n            <table ui-table>\n              <thead ui-table-header>\n                <tr ui-table-row>\n                  <th ui-table-head class=\"text-xs font-semibold\">Subtask Index</th>\n                  <th ui-table-head class=\"text-xs font-semibold\">Host / Pod</th>\n                  <th ui-table-head class=\"text-right text-xs font-semibold\">Input Rate</th>\n                  <th ui-table-head class=\"text-right text-xs font-semibold\">Output Rate</th>\n                  <th ui-table-head class=\"text-right text-xs font-semibold\">CPU %</th>\n                  <th ui-table-head class=\"text-right text-xs font-semibold\">Heap Usage</th>\n                  <th ui-table-head class=\"text-right text-xs font-semibold\">Watermark Lag</th>\n                  <th ui-table-head class=\"text-right text-xs font-semibold\">Checkpoint Ack</th>\n                  <th ui-table-head class=\"text-center text-xs font-semibold\">Status</th>\n                </tr>\n              </thead>\n              <tbody ui-table-body>\n                @for (subtask of operator.subtasks; track subtask.id) {\n                  <tr ui-table-row class=\"group\">\n                    <td ui-table-cell class=\"py-2.5\">\n                      <div class=\"flex items-center gap-2\">\n                        <span class=\"bg-success size-2 rounded-full\" aria-hidden=\"true\"></span>\n                        <span class=\"font-mono text-xs font-semibold\">Subtask #{{ subtask.id }}</span>\n                      </div>\n                    </td>\n                    <td ui-table-cell class=\"text-muted-foreground py-2.5 font-mono text-xs\">{{ subtask.host }}</td>\n                    <td\n                      ui-table-cell\n                      class=\"text-foreground py-2.5 text-right font-mono text-xs font-medium tabular-nums\"\n                    >\n                      {{ subtask.inRate }}\n                    </td>\n                    <td\n                      ui-table-cell\n                      class=\"text-foreground py-2.5 text-right font-mono text-xs font-medium tabular-nums\"\n                    >\n                      {{ subtask.outRate }}\n                    </td>\n                    <td ui-table-cell class=\"py-2.5 text-right font-mono text-xs tabular-nums\">\n                      <span ui-badge variant=\"outline\" class=\"font-mono text-xs\">{{ subtask.cpu }}</span>\n                    </td>\n                    <td ui-table-cell class=\"text-muted-foreground py-2.5 text-right font-mono text-xs tabular-nums\">\n                      {{ subtask.heapMemory }}\n                    </td>\n                    <td\n                      ui-table-cell\n                      class=\"text-success text-success py-2.5 text-right font-mono text-xs font-medium tabular-nums\"\n                    >\n                      {{ subtask.watermarkLag }}\n                    </td>\n                    <td ui-table-cell class=\"text-muted-foreground py-2.5 text-right font-mono text-xs tabular-nums\">\n                      {{ subtask.checkpointAckMs }}ms\n                    </td>\n                    <td ui-table-cell class=\"py-2.5 text-center\">\n                      <span ui-badge variant=\"success\" class=\"font-mono text-xs\">{{ subtask.status }}</span>\n                    </td>\n                  </tr>\n                }\n              </tbody>\n            </table>\n          </div>\n        } @else if (activeInspectorTab() === 'state') {\n          <!-- TAB 2: RocksDB Managed State -->\n          <div class=\"space-y-5 p-5\">\n            <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n              <div class=\"bg-muted/10 space-y-2 rounded-lg border p-4\">\n                <div class=\"text-muted-foreground text-xs font-medium\">State Backend Engine</div>\n                <div class=\"text-foreground font-mono text-base font-bold\">{{ operator.stateBackend }}</div>\n                <p class=\"text-muted-foreground text-xs\">\n                  Off-heap SSD persistence with block caching and incremental checkpoints\n                </p>\n              </div>\n              <div class=\"bg-muted/10 space-y-2 rounded-lg border p-4\">\n                <div class=\"text-muted-foreground text-xs font-medium\">Total Live State Size</div>\n                <div class=\"text-primary font-mono text-base font-bold\">{{ operator.managedStateSize }}</div>\n                <p class=\"text-muted-foreground text-xs\">Incremental checkpoint delta: ~2.4 MB / snapshot</p>\n              </div>\n              <div class=\"bg-muted/10 space-y-2 rounded-lg border p-4\">\n                <div class=\"text-muted-foreground text-xs font-medium\">Key Eviction & TTL</div>\n                <div class=\"text-foreground font-mono text-base font-bold\">10-min Sliding TTL</div>\n                <p class=\"text-muted-foreground text-xs\">\n                  Automatic compaction filter evicts expired cardholder keys on disk\n                </p>\n              </div>\n            </div>\n\n            <!-- RocksDB Performance Metrics Grid -->\n            <div class=\"bg-card space-y-3 rounded-lg border p-4\">\n              <h4 class=\"text-foreground text-xs font-semibold\">RocksDB Native Engine Statistics</h4>\n              <div class=\"grid grid-cols-2 gap-4 font-mono text-xs sm:grid-cols-4\">\n                <div>\n                  <span class=\"text-muted-foreground\">Block Cache Hit Ratio:</span>\n                  <div class=\"text-foreground mt-0.5 font-bold tabular-nums\">99.42% (512 MB cache)</div>\n                </div>\n                <div>\n                  <span class=\"text-muted-foreground\">MemTable Flush Rate:</span>\n                  <div class=\"text-foreground mt-0.5 font-bold tabular-nums\">14.2 MB/min</div>\n                </div>\n                <div>\n                  <span class=\"text-muted-foreground\">SST Files Count:</span>\n                  <div class=\"text-foreground mt-0.5 font-bold tabular-nums\">128 active SSTs</div>\n                </div>\n                <div>\n                  <span class=\"text-muted-foreground\">Level-0 Compaction Stall:</span>\n                  <div class=\"text-success text-success mt-0.5 font-bold tabular-nums\">0.0ms (No stalls)</div>\n                </div>\n              </div>\n            </div>\n          </div>\n        } @else if (activeInspectorTab() === 'resources') {\n          <!-- TAB 3: JVM & Resource Metrics -->\n          <div class=\"space-y-5 p-5\">\n            <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n              <div class=\"bg-muted/10 space-y-3 rounded-lg border p-4\">\n                <div class=\"flex items-center justify-between text-xs\">\n                  <span class=\"text-foreground font-medium\">JVM Heap Memory Utilization</span>\n                  <span class=\"text-muted-foreground font-mono\">{{ operator.heapMemory }} / 4,096 MB</span>\n                </div>\n                <ui-progress [value]=\"34\" class=\"h-2\" />\n                <div class=\"text-muted-foreground flex justify-between font-mono text-xs\">\n                  <span>Survivor: 64 MB</span>\n                  <span>Tenured / Old: 348 MB</span>\n                </div>\n              </div>\n\n              <div class=\"bg-muted/10 space-y-3 rounded-lg border p-4\">\n                <div class=\"flex items-center justify-between text-xs\">\n                  <span class=\"text-foreground font-medium\">Managed Off-Heap & Native Memory</span>\n                  <span class=\"text-muted-foreground font-mono\">{{ operator.managedMemory }} Allocated</span>\n                </div>\n                <ui-progress [value]=\"50\" class=\"h-2\" />\n                <div class=\"text-muted-foreground flex justify-between font-mono text-xs\">\n                  <span>RocksDB Cache: 512 MB</span>\n                  <span>Network Buffers: 256 MB</span>\n                </div>\n              </div>\n            </div>\n\n            <div class=\"bg-card space-y-2 rounded-lg border p-4\">\n              <div class=\"text-foreground text-xs font-semibold\">Garbage Collection Profile</div>\n              <p class=\"text-muted-foreground font-mono text-xs\">\n                Collector: Garbage-First (G1) GC · Max Pause Target: 20ms · Current Observed Pause:\n                {{ operator.gcTime }}\n              </p>\n            </div>\n          </div>\n        } @else {\n          <!-- TAB 4: Configuration Parameters -->\n          <div class=\"space-y-4 p-5\">\n            <div class=\"overflow-hidden rounded-lg border\">\n              <div\n                class=\"bg-muted/50 text-foreground flex items-center justify-between border-b p-3 text-xs font-semibold\"\n              >\n                <span>Runtime Operator Configuration</span>\n                <span ui-badge variant=\"outline\" class=\"font-mono text-xs\">{{ operator.operatorClass }}</span>\n              </div>\n              <div class=\"divide-y font-mono text-xs\">\n                @for (entry of configEntries(); track entry.key) {\n                  <div\n                    class=\"hover:bg-muted/20 flex flex-col justify-between gap-2 p-3 transition-colors sm:flex-row sm:items-center\"\n                  >\n                    <span class=\"text-muted-foreground font-medium\">{{ entry.key }}</span>\n                    <div class=\"flex items-center gap-2\">\n                      <span class=\"text-foreground font-semibold\">{{ entry.value }}</span>\n                      <button\n                        ui-button\n                        [attr.aria-label]=\"'Copy ' + entry.key\"\n                        variant=\"ghost\"\n                        size=\"xs\"\n                        class=\"text-muted-foreground hover:text-foreground h-6 w-6 p-0\"\n                        (click)=\"copy.emit({ key: entry.key, value: entry.value })\"\n                      >\n                        @if (copiedKey === entry.key) {\n                          <lucide-icon [img]=\"Check\" class=\"text-success size-3\" />\n                        } @else {\n                          <lucide-icon [img]=\"Copy\" class=\"size-3\" />\n                        }\n                      </button>\n                    </div>\n                  </div>\n                }\n              </div>\n            </div>\n          </div>\n        }\n      </div>\n\n      <!-- Bottom Engine Metadata Strip -->\n      <div\n        class=\"bg-muted/40 flex flex-col gap-2.5 border-t px-4 py-3 font-mono text-xs sm:flex-row sm:items-center sm:justify-between\"\n      >\n        <div class=\"text-muted-foreground flex flex-wrap items-center gap-4\">\n          <div class=\"text-foreground flex items-center gap-1.5 font-medium\">\n            <lucide-icon [img]=\"Activity\" class=\"text-success size-3.5\" />\n            <span>Pipeline Ingestion:</span>\n            <span>42,500 records/sec (8.4 MB/s)</span>\n          </div>\n\n          <ui-separator orientation=\"vertical\" class=\"hidden h-3.5 sm:block\" />\n\n          <div class=\"flex items-center gap-1.5\">\n            <lucide-icon [img]=\"Server\" class=\"text-info size-3.5\" />\n            <span>TaskManagers:</span>\n            <span class=\"text-foreground\">8 Kubernetes Pods</span>\n          </div>\n\n          <ui-separator orientation=\"vertical\" class=\"hidden h-3.5 sm:block\" />\n\n          <div class=\"flex items-center gap-1.5\">\n            <lucide-icon [img]=\"ShieldCheck\" class=\"text-success size-3.5\" />\n            <span>State Consistency:</span>\n            <span class=\"text-foreground\">Exactly-Once (2PC)</span>\n          </div>\n        </div>\n\n        <div class=\"text-muted-foreground flex items-center gap-2\">\n          <span class=\"bg-success size-1.5 rounded-full\"></span>\n          <span>Watermark Alignment: 42ms · Checkpoint #1,420 OK</span>\n        </div>\n      </div>\n    </div>\n  `,\n})\nexport class UiStreamOperatorDetailComponent {\n  protected readonly Activity = Activity\n  protected readonly Check = Check\n  protected readonly Copy = Copy\n  protected readonly Server = Server\n  protected readonly ShieldCheck = ShieldCheck\n\n  @Input({ required: true }) operator!: FlinkOperatorNode\n  @Input() copiedKey: string | null = null\n  @Output() copy = new EventEmitter<{ key: string; value: string }>()\n\n  readonly activeInspectorTab = signal<InspectorTab>('subtasks')\n\n  tabClass(tab: InspectorTab): string {\n    return cn(\n      'focus-visible:ring-ring rounded-md px-2.5 py-1 text-xs font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none',\n      this.activeInspectorTab() === tab\n        ? 'bg-card text-foreground font-semibold shadow-xs'\n        : 'text-muted-foreground hover:text-foreground',\n    )\n  }\n\n  configEntries(): { key: string; value: string }[] {\n    return Object.entries(this.operator.config ?? {}).map(([key, value]) => ({ key, value }))\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/stream-processing-flink-topology/stream-operator-detail.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/stream-processing-flink-topology/stream-topology-telemetry.component.ts",
      "content": "// Real-time stream telemetry KPI cards: ingestion throughput, checkpoint duration,\n// watermark alignment latency, and backpressure heat. Port of the Vue/React telemetry\n// card grid 1:1.\nimport { ChangeDetectionStrategy, Component, Input } from '@angular/core'\nimport { Activity, Clock, Flame, LucideAngularModule, Zap } from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiBadgeComponent } from '@/ui/badge/badge.component'\nimport {\n  UiCardComponent,\n  UiCardContentComponent,\n  UiCardHeaderComponent,\n  UiCardTitleComponent,\n} from '@/ui/card/card.component'\nimport { UiProgressComponent } from '@/ui/progress/progress.component'\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-stream-topology-telemetry, [ui-stream-topology-telemetry]',\n  standalone: true,\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [\n    LucideAngularModule,\n    UiBadgeComponent,\n    UiCardComponent,\n    UiCardContentComponent,\n    UiCardHeaderComponent,\n    UiCardTitleComponent,\n    UiProgressComponent,\n  ],\n  template: `\n    <div [class]=\"rootClass\">\n      <!-- Card 1: Current Ingestion Throughput -->\n      <div ui-card class=\"flex flex-col justify-between shadow-xs\">\n        <div ui-card-header class=\"pb-2\">\n          <div class=\"flex items-center justify-between gap-2\">\n            <div class=\"flex min-w-0 items-center gap-2\">\n              <div\n                class=\"bg-muted text-muted-foreground border-border flex size-8 shrink-0 items-center justify-center rounded-lg border shadow-xs\"\n                aria-hidden=\"true\"\n              >\n                <lucide-icon [img]=\"Activity\" class=\"text-primary size-4\" />\n              </div>\n              <h3 ui-card-title class=\"truncate text-xs font-medium\">Current Ingestion Throughput</h3>\n            </div>\n            <span ui-badge variant=\"outline\" class=\"shrink-0 text-xs font-normal tabular-nums\">+4.2% 10m</span>\n          </div>\n        </div>\n        <div ui-card-content class=\"space-y-3\">\n          <div>\n            <div class=\"text-foreground font-mono text-2xl font-bold tracking-tight tabular-nums\">\n              42,500 records/sec\n            </div>\n            <p class=\"text-muted-foreground font-mono text-xs tabular-nums\">8.4 MB/s ingress bandwidth</p>\n          </div>\n          <div class=\"space-y-1.5\">\n            <div class=\"text-muted-foreground flex items-center justify-between text-xs\">\n              <span>Ingress Capacity</span>\n              <span class=\"text-foreground font-mono font-medium tabular-nums\">68% allocated</span>\n            </div>\n            <ui-progress [value]=\"68\" class=\"h-1.5\" />\n          </div>\n        </div>\n      </div>\n\n      <!-- Card 2: Checkpoint Duration -->\n      <div ui-card class=\"flex flex-col justify-between shadow-xs\">\n        <div ui-card-header class=\"pb-2\">\n          <div class=\"flex items-center justify-between gap-2\">\n            <div class=\"flex min-w-0 items-center gap-2\">\n              <div\n                class=\"bg-muted text-muted-foreground border-border flex size-8 shrink-0 items-center justify-center rounded-lg border shadow-xs\"\n                aria-hidden=\"true\"\n              >\n                <lucide-icon [img]=\"Clock\" class=\"text-success size-4\" />\n              </div>\n              <h3 ui-card-title class=\"truncate text-xs font-medium\">Checkpoint Duration</h3>\n            </div>\n            <span ui-badge variant=\"success\" class=\"shrink-0 font-mono text-xs\">100% Succeeded</span>\n          </div>\n        </div>\n        <div ui-card-content class=\"space-y-3\">\n          <div>\n            <div class=\"text-foreground font-mono text-2xl font-bold tracking-tight tabular-nums\">185ms duration</div>\n            <p class=\"text-muted-foreground font-mono text-xs tabular-nums\">42 MB state size · Checkpoint #1,420</p>\n          </div>\n          <div class=\"space-y-1.5\">\n            <div class=\"text-muted-foreground flex items-center justify-between text-xs\">\n              <span>SLA Budget (1,000ms)</span>\n              <span class=\"text-foreground font-mono font-medium tabular-nums\">18.5% of interval</span>\n            </div>\n            <ui-progress [value]=\"18.5\" class=\"h-1.5\" />\n          </div>\n        </div>\n      </div>\n\n      <!-- Card 3: Watermark Alignment Latency -->\n      <div ui-card class=\"flex flex-col justify-between shadow-xs\">\n        <div ui-card-header class=\"pb-2\">\n          <div class=\"flex items-center justify-between gap-2\">\n            <div class=\"flex min-w-0 items-center gap-2\">\n              <div\n                class=\"bg-muted text-muted-foreground border-border flex size-8 shrink-0 items-center justify-center rounded-lg border shadow-xs\"\n                aria-hidden=\"true\"\n              >\n                <lucide-icon [img]=\"Zap\" class=\"text-warning size-4\" />\n              </div>\n              <h3 ui-card-title class=\"truncate text-xs font-medium\">Watermark Alignment</h3>\n            </div>\n            <span ui-badge variant=\"outline\" class=\"border-success/30 text-success font-mono text-xs\">Event Time</span>\n          </div>\n        </div>\n        <div ui-card-content class=\"space-y-3\">\n          <div>\n            <div class=\"text-foreground font-mono text-2xl font-bold tracking-tight tabular-nums\">Lag: 42ms</div>\n            <p class=\"text-muted-foreground font-mono text-xs tabular-nums\">Event Time Alignment · 0 Late Drops</p>\n          </div>\n          <div class=\"space-y-1.5\">\n            <div class=\"text-muted-foreground flex items-center justify-between text-xs\">\n              <span>Skew Drift</span>\n              <span class=\"text-foreground font-mono font-medium tabular-nums\">Max 12ms cross-partition</span>\n            </div>\n            <ui-progress [value]=\"8.4\" class=\"h-1.5\" />\n          </div>\n        </div>\n      </div>\n\n      <!-- Card 4: Max Backpressure Heat Ratio -->\n      <div ui-card class=\"flex flex-col justify-between shadow-xs\">\n        <div ui-card-header class=\"pb-2\">\n          <div class=\"flex items-center justify-between gap-2\">\n            <div class=\"flex min-w-0 items-center gap-2\">\n              <div\n                class=\"bg-muted text-muted-foreground border-border flex size-8 shrink-0 items-center justify-center rounded-lg border shadow-xs\"\n                aria-hidden=\"true\"\n              >\n                <lucide-icon [img]=\"Flame\" class=\"text-success size-4\" />\n              </div>\n              <h3 ui-card-title class=\"truncate text-xs font-medium\">Max Backpressure Heat</h3>\n            </div>\n            <span ui-badge variant=\"success\" class=\"shrink-0 font-mono text-xs\">Low Risk</span>\n          </div>\n        </div>\n        <div ui-card-content class=\"space-y-3\">\n          <div>\n            <div class=\"text-foreground font-mono text-2xl font-bold tracking-tight tabular-nums\">\n              0.0% Backpressure\n            </div>\n            <p class=\"text-muted-foreground font-mono text-xs tabular-nums\">All 4 operators running at nominal load</p>\n          </div>\n          <div class=\"space-y-1.5\">\n            <div class=\"text-muted-foreground flex items-center justify-between text-xs\">\n              <span>Choked Subtasks</span>\n              <span class=\"text-success text-success font-mono font-medium tabular-nums\">0 / 48 active</span>\n            </div>\n            <ui-progress [value]=\"0\" class=\"h-1.5\" />\n          </div>\n        </div>\n      </div>\n    </div>\n  `,\n})\nexport class UiStreamTopologyTelemetryComponent {\n  protected readonly Activity = Activity\n  protected readonly Clock = Clock\n  protected readonly Flame = Flame\n  protected readonly Zap = Zap\n\n  @Input('class') className?: string\n\n  get rootClass(): string {\n    return cn('grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4', this.className)\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/stream-processing-flink-topology/stream-topology-telemetry.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/stream-processing-flink-topology/stream-topology-types.ts",
      "content": "export interface FlinkSubtask {\n  id: number\n  host: string\n  status: 'RUNNING' | 'DEPLOYING' | 'RECONCILING'\n  inRate: string\n  outRate: string\n  cpu: string\n  heapMemory: string\n  backpressure: number\n  watermarkLag: string\n  checkpointAckMs: number\n}\n\nexport interface FlinkOperatorNode {\n  id: string\n  name: string\n  shortTitle: string\n  stageNumber: number\n  category: 'source' | 'window' | 'inference' | 'sink'\n  operatorClass: string\n  parallelism: number\n  status: 'RUNNING' | 'CANCELED' | 'FAILING'\n  backpressure: number\n  inputRecordsRate: string\n  inputBytesRate: string\n  outputRecordsRate: string\n  outputBytesRate: string\n  totalRecordsIn: number\n  totalRecordsOut: number\n  managedStateSize: string\n  stateBackend: string\n  heapMemory: string\n  managedMemory: string\n  gcTime: string\n  cpuPeak: string\n  watermarkLag: string\n  currentWatermark: string\n  description: string\n  config: Record<string, string>\n  subtasks: FlinkSubtask[]\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/stream-processing-flink-topology/stream-topology-types.ts"
    },
    {
      "path": "packages/registry-angular/blocks/stream-processing-flink-topology/stream-topology-data.ts",
      "content": "import type { FlinkOperatorNode } from './stream-topology-types'\n\nexport const defaultFlinkOperators: FlinkOperatorNode[] = [\n  {\n    id: 'op-kafka-source',\n    name: 'Source: Kafka Ingestion (events.fraud.transactions)',\n    shortTitle: 'Kafka Ingestion Source',\n    stageNumber: 1,\n    category: 'source',\n    operatorClass: 'org.apache.flink.connector.kafka.source.KafkaSource',\n    parallelism: 8,\n    status: 'RUNNING',\n    backpressure: 0.0,\n    inputRecordsRate: '42,500 rec/s',\n    inputBytesRate: '8.4 MB/s',\n    outputRecordsRate: '42,500 rec/s',\n    outputBytesRate: '8.4 MB/s',\n    totalRecordsIn: 184290410,\n    totalRecordsOut: 184290410,\n    managedStateSize: '0 MB (Stateless)',\n    stateBackend: 'None (Stateless Source)',\n    heapMemory: '412 MB',\n    managedMemory: '0 MB',\n    gcTime: '0.8 ms/min',\n    cpuPeak: '14%',\n    watermarkLag: '28ms',\n    currentWatermark: '2026-08-21 14:32:45.892 UTC',\n    description:\n      'Consumes high-throughput payment transaction stream with snappy decompression and bounded out-of-orderness watermark generation.',\n    config: {\n      topic: 'events.fraud.transactions',\n      'consumer.group.id': 'flink-fraud-scoring-v2',\n      'scan.startup.mode': 'latest-offset',\n      'watermark.strategy': 'BoundedOutOfOrderness(Duration.ofMillis(200))',\n      'partition.discovery.interval.ms': '30000',\n      'deserializer.format': 'AvroConfluentSchemaRegistry',\n    },\n    subtasks: [\n      {\n        id: 0,\n        host: 'taskmanager-pod-0.k8s',\n        status: 'RUNNING',\n        inRate: '5,320 rec/s',\n        outRate: '5,320 rec/s',\n        cpu: '14%',\n        heapMemory: '52 MB',\n        backpressure: 0.0,\n        watermarkLag: '22ms',\n        checkpointAckMs: 42,\n      },\n      {\n        id: 1,\n        host: 'taskmanager-pod-0.k8s',\n        status: 'RUNNING',\n        inRate: '5,310 rec/s',\n        outRate: '5,310 rec/s',\n        cpu: '13%',\n        heapMemory: '51 MB',\n        backpressure: 0.0,\n        watermarkLag: '24ms',\n        checkpointAckMs: 44,\n      },\n      {\n        id: 2,\n        host: 'taskmanager-pod-1.k8s',\n        status: 'RUNNING',\n        inRate: '5,315 rec/s',\n        outRate: '5,315 rec/s',\n        cpu: '15%',\n        heapMemory: '53 MB',\n        backpressure: 0.0,\n        watermarkLag: '26ms',\n        checkpointAckMs: 41,\n      },\n      {\n        id: 3,\n        host: 'taskmanager-pod-1.k8s',\n        status: 'RUNNING',\n        inRate: '5,305 rec/s',\n        outRate: '5,305 rec/s',\n        cpu: '14%',\n        heapMemory: '50 MB',\n        backpressure: 0.0,\n        watermarkLag: '23ms',\n        checkpointAckMs: 45,\n      },\n      {\n        id: 4,\n        host: 'taskmanager-pod-2.k8s',\n        status: 'RUNNING',\n        inRate: '5,325 rec/s',\n        outRate: '5,325 rec/s',\n        cpu: '14%',\n        heapMemory: '52 MB',\n        backpressure: 0.0,\n        watermarkLag: '25ms',\n        checkpointAckMs: 40,\n      },\n      {\n        id: 5,\n        host: 'taskmanager-pod-2.k8s',\n        status: 'RUNNING',\n        inRate: '5,310 rec/s',\n        outRate: '5,310 rec/s',\n        cpu: '13%',\n        heapMemory: '51 MB',\n        backpressure: 0.0,\n        watermarkLag: '24ms',\n        checkpointAckMs: 43,\n      },\n      {\n        id: 6,\n        host: 'taskmanager-pod-3.k8s',\n        status: 'RUNNING',\n        inRate: '5,308 rec/s',\n        outRate: '5,308 rec/s',\n        cpu: '15%',\n        heapMemory: '52 MB',\n        backpressure: 0.0,\n        watermarkLag: '28ms',\n        checkpointAckMs: 42,\n      },\n      {\n        id: 7,\n        host: 'taskmanager-pod-3.k8s',\n        status: 'RUNNING',\n        inRate: '5,307 rec/s',\n        outRate: '5,307 rec/s',\n        cpu: '14%',\n        heapMemory: '51 MB',\n        backpressure: 0.0,\n        watermarkLag: '25ms',\n        checkpointAckMs: 43,\n      },\n    ],\n  },\n  {\n    id: 'op-keyed-window',\n    name: 'Keyed Sliding Window (5-min window, 10s slide)',\n    shortTitle: 'Keyed Sliding Window',\n    stageNumber: 2,\n    category: 'window',\n    operatorClass: 'org.apache.flink.streaming.runtime.operators.windowing.WindowOperator',\n    parallelism: 16,\n    status: 'RUNNING',\n    backpressure: 0.0,\n    inputRecordsRate: '42,500 rec/s',\n    inputBytesRate: '8.4 MB/s',\n    outputRecordsRate: '38,200 rec/s',\n    outputBytesRate: '6.9 MB/s',\n    totalRecordsIn: 184290410,\n    totalRecordsOut: 165861369,\n    managedStateSize: '18.4 MB (RocksDB)',\n    stateBackend: 'EmbeddedRocksDBStateBackend',\n    heapMemory: '780 MB',\n    managedMemory: '1,024 MB',\n    gcTime: '1.2 ms/min',\n    cpuPeak: '28%',\n    watermarkLag: '34ms',\n    currentWatermark: '2026-08-21 14:32:45.886 UTC',\n    description:\n      'Aggregates velocity, cumulative transaction volumes, and rapid card-testing frequency per cardholder ID across 5m windows triggered every 10s.',\n    config: {\n      'window.assigner': 'SlidingEventTimeWindows.of(Time.minutes(5), Time.seconds(10))',\n      'allowed.lateness': '0ms',\n      'state.backend.ttl': '600000ms (10m TTL)',\n      'state.active.cardholders': '12,400 keys in state',\n      trigger: 'EventTimeTrigger.create()',\n      evictor: 'TimeEvictor.of(Time.minutes(5))',\n    },\n    subtasks: [\n      {\n        id: 0,\n        host: 'taskmanager-pod-0.k8s',\n        status: 'RUNNING',\n        inRate: '2,660 rec/s',\n        outRate: '2,390 rec/s',\n        cpu: '28%',\n        heapMemory: '49 MB',\n        backpressure: 0.0,\n        watermarkLag: '32ms',\n        checkpointAckMs: 65,\n      },\n      {\n        id: 1,\n        host: 'taskmanager-pod-0.k8s',\n        status: 'RUNNING',\n        inRate: '2,655 rec/s',\n        outRate: '2,385 rec/s',\n        cpu: '27%',\n        heapMemory: '48 MB',\n        backpressure: 0.0,\n        watermarkLag: '34ms',\n        checkpointAckMs: 68,\n      },\n      {\n        id: 2,\n        host: 'taskmanager-pod-1.k8s',\n        status: 'RUNNING',\n        inRate: '2,662 rec/s',\n        outRate: '2,392 rec/s',\n        cpu: '29%',\n        heapMemory: '50 MB',\n        backpressure: 0.0,\n        watermarkLag: '33ms',\n        checkpointAckMs: 64,\n      },\n      {\n        id: 3,\n        host: 'taskmanager-pod-1.k8s',\n        status: 'RUNNING',\n        inRate: '2,650 rec/s',\n        outRate: '2,380 rec/s',\n        cpu: '28%',\n        heapMemory: '48 MB',\n        backpressure: 0.0,\n        watermarkLag: '35ms',\n        checkpointAckMs: 66,\n      },\n      {\n        id: 4,\n        host: 'taskmanager-pod-2.k8s',\n        status: 'RUNNING',\n        inRate: '2,658 rec/s',\n        outRate: '2,388 rec/s',\n        cpu: '27%',\n        heapMemory: '49 MB',\n        backpressure: 0.0,\n        watermarkLag: '34ms',\n        checkpointAckMs: 65,\n      },\n      {\n        id: 5,\n        host: 'taskmanager-pod-2.k8s',\n        status: 'RUNNING',\n        inRate: '2,654 rec/s',\n        outRate: '2,386 rec/s',\n        cpu: '29%',\n        heapMemory: '50 MB',\n        backpressure: 0.0,\n        watermarkLag: '33ms',\n        checkpointAckMs: 67,\n      },\n      {\n        id: 6,\n        host: 'taskmanager-pod-3.k8s',\n        status: 'RUNNING',\n        inRate: '2,660 rec/s',\n        outRate: '2,390 rec/s',\n        cpu: '28%',\n        heapMemory: '49 MB',\n        backpressure: 0.0,\n        watermarkLag: '35ms',\n        checkpointAckMs: 66,\n      },\n      {\n        id: 7,\n        host: 'taskmanager-pod-3.k8s',\n        status: 'RUNNING',\n        inRate: '2,652 rec/s',\n        outRate: '2,384 rec/s',\n        cpu: '28%',\n        heapMemory: '48 MB',\n        backpressure: 0.0,\n        watermarkLag: '34ms',\n        checkpointAckMs: 64,\n      },\n      {\n        id: 8,\n        host: 'taskmanager-pod-4.k8s',\n        status: 'RUNNING',\n        inRate: '2,659 rec/s',\n        outRate: '2,389 rec/s',\n        cpu: '29%',\n        heapMemory: '50 MB',\n        backpressure: 0.0,\n        watermarkLag: '33ms',\n        checkpointAckMs: 65,\n      },\n      {\n        id: 9,\n        host: 'taskmanager-pod-4.k8s',\n        status: 'RUNNING',\n        inRate: '2,655 rec/s',\n        outRate: '2,385 rec/s',\n        cpu: '27%',\n        heapMemory: '48 MB',\n        backpressure: 0.0,\n        watermarkLag: '36ms',\n        checkpointAckMs: 68,\n      },\n      {\n        id: 10,\n        host: 'taskmanager-pod-5.k8s',\n        status: 'RUNNING',\n        inRate: '2,661 rec/s',\n        outRate: '2,391 rec/s',\n        cpu: '28%',\n        heapMemory: '49 MB',\n        backpressure: 0.0,\n        watermarkLag: '34ms',\n        checkpointAckMs: 63,\n      },\n      {\n        id: 11,\n        host: 'taskmanager-pod-5.k8s',\n        status: 'RUNNING',\n        inRate: '2,650 rec/s',\n        outRate: '2,380 rec/s',\n        cpu: '28%',\n        heapMemory: '48 MB',\n        backpressure: 0.0,\n        watermarkLag: '35ms',\n        checkpointAckMs: 66,\n      },\n      {\n        id: 12,\n        host: 'taskmanager-pod-6.k8s',\n        status: 'RUNNING',\n        inRate: '2,657 rec/s',\n        outRate: '2,387 rec/s',\n        cpu: '27%',\n        heapMemory: '49 MB',\n        backpressure: 0.0,\n        watermarkLag: '33ms',\n        checkpointAckMs: 67,\n      },\n      {\n        id: 13,\n        host: 'taskmanager-pod-6.k8s',\n        status: 'RUNNING',\n        inRate: '2,653 rec/s',\n        outRate: '2,383 rec/s',\n        cpu: '29%',\n        heapMemory: '50 MB',\n        backpressure: 0.0,\n        watermarkLag: '34ms',\n        checkpointAckMs: 65,\n      },\n      {\n        id: 14,\n        host: 'taskmanager-pod-7.k8s',\n        status: 'RUNNING',\n        inRate: '2,658 rec/s',\n        outRate: '2,388 rec/s',\n        cpu: '28%',\n        heapMemory: '49 MB',\n        backpressure: 0.0,\n        watermarkLag: '35ms',\n        checkpointAckMs: 66,\n      },\n      {\n        id: 15,\n        host: 'taskmanager-pod-7.k8s',\n        status: 'RUNNING',\n        inRate: '2,651 rec/s',\n        outRate: '2,382 rec/s',\n        cpu: '28%',\n        heapMemory: '48 MB',\n        backpressure: 0.0,\n        watermarkLag: '34ms',\n        checkpointAckMs: 64,\n      },\n    ],\n  },\n  {\n    id: 'op-ml-scoring',\n    name: 'ML Fraud Scoring Pattern Matcher (CEP + XGBoost ONNX)',\n    shortTitle: 'ML Fraud Scoring Pattern Matcher',\n    stageNumber: 3,\n    category: 'inference',\n    operatorClass: 'com.uipkge.fraud.engine.AsyncFraudScoringKeyedProcessFunction',\n    parallelism: 16,\n    status: 'RUNNING',\n    backpressure: 0.0,\n    inputRecordsRate: '38,200 rec/s',\n    inputBytesRate: '6.9 MB/s',\n    outputRecordsRate: '38,200 rec/s',\n    outputBytesRate: '7.1 MB/s',\n    totalRecordsIn: 165861369,\n    totalRecordsOut: 165861369,\n    managedStateSize: '38.2 MB (RocksDB)',\n    stateBackend: 'EmbeddedRocksDBStateBackend',\n    heapMemory: '1,420 MB',\n    managedMemory: '2,048 MB',\n    gcTime: '1.4 ms/min',\n    cpuPeak: '38%',\n    watermarkLag: '38ms',\n    currentWatermark: '2026-08-21 14:32:45.882 UTC',\n    description:\n      'Evaluates stateful complex event patterns (CEP) and executes low-latency XGBoost model scoring via embedded ONNX native runtime.',\n    config: {\n      'model.runtime': 'ONNX Runtime 1.18 (AVX-512)',\n      'model.artifact': 's3://ml-models-registry/fraud/xgboost_v4_18.onnx',\n      'inference.latency.p99': '1.2ms',\n      'rocksdb.block.cache.size': '512 MB',\n      'rocksdb.compaction.style': 'LEVEL',\n      'alert.confidence.threshold': '0.85',\n    },\n    subtasks: [\n      {\n        id: 0,\n        host: 'taskmanager-pod-0.k8s',\n        status: 'RUNNING',\n        inRate: '2,390 rec/s',\n        outRate: '2,390 rec/s',\n        cpu: '38%',\n        heapMemory: '89 MB',\n        backpressure: 0.0,\n        watermarkLag: '37ms',\n        checkpointAckMs: 110,\n      },\n      {\n        id: 1,\n        host: 'taskmanager-pod-0.k8s',\n        status: 'RUNNING',\n        inRate: '2,385 rec/s',\n        outRate: '2,385 rec/s',\n        cpu: '37%',\n        heapMemory: '88 MB',\n        backpressure: 0.0,\n        watermarkLag: '38ms',\n        checkpointAckMs: 114,\n      },\n      {\n        id: 2,\n        host: 'taskmanager-pod-1.k8s',\n        status: 'RUNNING',\n        inRate: '2,392 rec/s',\n        outRate: '2,392 rec/s',\n        cpu: '39%',\n        heapMemory: '90 MB',\n        backpressure: 0.0,\n        watermarkLag: '36ms',\n        checkpointAckMs: 108,\n      },\n      {\n        id: 3,\n        host: 'taskmanager-pod-1.k8s',\n        status: 'RUNNING',\n        inRate: '2,380 rec/s',\n        outRate: '2,380 rec/s',\n        cpu: '38%',\n        heapMemory: '87 MB',\n        backpressure: 0.0,\n        watermarkLag: '39ms',\n        checkpointAckMs: 112,\n      },\n      {\n        id: 4,\n        host: 'taskmanager-pod-2.k8s',\n        status: 'RUNNING',\n        inRate: '2,388 rec/s',\n        outRate: '2,388 rec/s',\n        cpu: '37%',\n        heapMemory: '88 MB',\n        backpressure: 0.0,\n        watermarkLag: '38ms',\n        checkpointAckMs: 111,\n      },\n      {\n        id: 5,\n        host: 'taskmanager-pod-2.k8s',\n        status: 'RUNNING',\n        inRate: '2,386 rec/s',\n        outRate: '2,386 rec/s',\n        cpu: '39%',\n        heapMemory: '90 MB',\n        backpressure: 0.0,\n        watermarkLag: '37ms',\n        checkpointAckMs: 115,\n      },\n      {\n        id: 6,\n        host: 'taskmanager-pod-3.k8s',\n        status: 'RUNNING',\n        inRate: '2,390 rec/s',\n        outRate: '2,390 rec/s',\n        cpu: '38%',\n        heapMemory: '89 MB',\n        backpressure: 0.0,\n        watermarkLag: '39ms',\n        checkpointAckMs: 110,\n      },\n      {\n        id: 7,\n        host: 'taskmanager-pod-3.k8s',\n        status: 'RUNNING',\n        inRate: '2,384 rec/s',\n        outRate: '2,384 rec/s',\n        cpu: '37%',\n        heapMemory: '87 MB',\n        backpressure: 0.0,\n        watermarkLag: '38ms',\n        checkpointAckMs: 112,\n      },\n      {\n        id: 8,\n        host: 'taskmanager-pod-4.k8s',\n        status: 'RUNNING',\n        inRate: '2,389 rec/s',\n        outRate: '2,389 rec/s',\n        cpu: '38%',\n        heapMemory: '89 MB',\n        backpressure: 0.0,\n        watermarkLag: '37ms',\n        checkpointAckMs: 109,\n      },\n      {\n        id: 9,\n        host: 'taskmanager-pod-4.k8s',\n        status: 'RUNNING',\n        inRate: '2,385 rec/s',\n        outRate: '2,385 rec/s',\n        cpu: '37%',\n        heapMemory: '88 MB',\n        backpressure: 0.0,\n        watermarkLag: '39ms',\n        checkpointAckMs: 113,\n      },\n      {\n        id: 10,\n        host: 'taskmanager-pod-5.k8s',\n        status: 'RUNNING',\n        inRate: '2,391 rec/s',\n        outRate: '2,391 rec/s',\n        cpu: '39%',\n        heapMemory: '90 MB',\n        backpressure: 0.0,\n        watermarkLag: '37ms',\n        checkpointAckMs: 108,\n      },\n      {\n        id: 11,\n        host: 'taskmanager-pod-5.k8s',\n        status: 'RUNNING',\n        inRate: '2,380 rec/s',\n        outRate: '2,380 rec/s',\n        cpu: '38%',\n        heapMemory: '87 MB',\n        backpressure: 0.0,\n        watermarkLag: '38ms',\n        checkpointAckMs: 112,\n      },\n      {\n        id: 12,\n        host: 'taskmanager-pod-6.k8s',\n        status: 'RUNNING',\n        inRate: '2,387 rec/s',\n        outRate: '2,387 rec/s',\n        cpu: '37%',\n        heapMemory: '88 MB',\n        backpressure: 0.0,\n        watermarkLag: '36ms',\n        checkpointAckMs: 111,\n      },\n      {\n        id: 13,\n        host: 'taskmanager-pod-6.k8s',\n        status: 'RUNNING',\n        inRate: '2,383 rec/s',\n        outRate: '2,383 rec/s',\n        cpu: '39%',\n        heapMemory: '90 MB',\n        backpressure: 0.0,\n        watermarkLag: '38ms',\n        checkpointAckMs: 114,\n      },\n      {\n        id: 14,\n        host: 'taskmanager-pod-7.k8s',\n        status: 'RUNNING',\n        inRate: '2,388 rec/s',\n        outRate: '2,388 rec/s',\n        cpu: '38%',\n        heapMemory: '89 MB',\n        backpressure: 0.0,\n        watermarkLag: '39ms',\n        checkpointAckMs: 110,\n      },\n      {\n        id: 15,\n        host: 'taskmanager-pod-7.k8s',\n        status: 'RUNNING',\n        inRate: '2,382 rec/s',\n        outRate: '2,382 rec/s',\n        cpu: '38%',\n        heapMemory: '88 MB',\n        backpressure: 0.0,\n        watermarkLag: '37ms',\n        checkpointAckMs: 112,\n      },\n    ],\n  },\n  {\n    id: 'op-sink-dispatcher',\n    name: 'Sink: Alert Dispatcher & Redis Cache',\n    shortTitle: 'Sink: Alert Dispatcher & Redis Cache',\n    stageNumber: 4,\n    category: 'sink',\n    operatorClass: 'com.uipkge.fraud.sink.TwoPhaseCommitRedisAlertSink',\n    parallelism: 8,\n    status: 'RUNNING',\n    backpressure: 0.0,\n    inputRecordsRate: '38,200 rec/s',\n    inputBytesRate: '7.1 MB/s',\n    outputRecordsRate: '42,500 rec/s',\n    outputBytesRate: '9.2 MB/s',\n    totalRecordsIn: 165861369,\n    totalRecordsOut: 165861369,\n    managedStateSize: '0.4 MB (2PC WAL)',\n    stateBackend: 'Transactional Two-Phase Commit',\n    heapMemory: '380 MB',\n    managedMemory: '128 MB',\n    gcTime: '0.9 ms/min',\n    cpuPeak: '16%',\n    watermarkLag: '42ms',\n    currentWatermark: '2026-08-21 14:32:45.878 UTC',\n    description:\n      'Commits risk scoring states to Redis Cluster for zero-latency checkout authorization gates and pushes flagged transactions to incident queues.',\n    config: {\n      'sink.semantics': 'EXACTLY_ONCE (2PC Transactional)',\n      'redis.cluster.nodes': 'redis-cluster.internal:6379 (6 nodes)',\n      'redis.ttl': '86400s (24-hour key expiration)',\n      'webhook.alert.queue': 'https://alerts.security.internal/v1/fraud',\n      'batch.flush.interval.ms': '50',\n    },\n    subtasks: [\n      {\n        id: 0,\n        host: 'taskmanager-pod-0.k8s',\n        status: 'RUNNING',\n        inRate: '4,775 rec/s',\n        outRate: '5,312 rec/s',\n        cpu: '16%',\n        heapMemory: '48 MB',\n        backpressure: 0.0,\n        watermarkLag: '41ms',\n        checkpointAckMs: 52,\n      },\n      {\n        id: 1,\n        host: 'taskmanager-pod-1.k8s',\n        status: 'RUNNING',\n        inRate: '4,770 rec/s',\n        outRate: '5,308 rec/s',\n        cpu: '15%',\n        heapMemory: '47 MB',\n        backpressure: 0.0,\n        watermarkLag: '43ms',\n        checkpointAckMs: 55,\n      },\n      {\n        id: 2,\n        host: 'taskmanager-pod-2.k8s',\n        status: 'RUNNING',\n        inRate: '4,780 rec/s',\n        outRate: '5,315 rec/s',\n        cpu: '17%',\n        heapMemory: '49 MB',\n        backpressure: 0.0,\n        watermarkLag: '40ms',\n        checkpointAckMs: 51,\n      },\n      {\n        id: 3,\n        host: 'taskmanager-pod-3.k8s',\n        status: 'RUNNING',\n        inRate: '4,765 rec/s',\n        outRate: '5,305 rec/s',\n        cpu: '16%',\n        heapMemory: '46 MB',\n        backpressure: 0.0,\n        watermarkLag: '44ms',\n        checkpointAckMs: 56,\n      },\n      {\n        id: 4,\n        host: 'taskmanager-pod-4.k8s',\n        status: 'RUNNING',\n        inRate: '4,778 rec/s',\n        outRate: '5,314 rec/s',\n        cpu: '16%',\n        heapMemory: '48 MB',\n        backpressure: 0.0,\n        watermarkLag: '42ms',\n        checkpointAckMs: 53,\n      },\n      {\n        id: 5,\n        host: 'taskmanager-pod-5.k8s',\n        status: 'RUNNING',\n        inRate: '4,772 rec/s',\n        outRate: '5,310 rec/s',\n        cpu: '15%',\n        heapMemory: '47 MB',\n        backpressure: 0.0,\n        watermarkLag: '43ms',\n        checkpointAckMs: 54,\n      },\n      {\n        id: 6,\n        host: 'taskmanager-pod-6.k8s',\n        status: 'RUNNING',\n        inRate: '4,782 rec/s',\n        outRate: '5,318 rec/s',\n        cpu: '17%',\n        heapMemory: '49 MB',\n        backpressure: 0.0,\n        watermarkLag: '41ms',\n        checkpointAckMs: 50,\n      },\n      {\n        id: 7,\n        host: 'taskmanager-pod-7.k8s',\n        status: 'RUNNING',\n        inRate: '4,768 rec/s',\n        outRate: '5,308 rec/s',\n        cpu: '16%',\n        heapMemory: '47 MB',\n        backpressure: 0.0,\n        watermarkLag: '43ms',\n        checkpointAckMs: 55,\n      },\n    ],\n  },\n]\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/stream-processing-flink-topology/stream-topology-data.ts"
    },
    {
      "path": "packages/registry-angular/blocks/stream-processing-flink-topology/index.ts",
      "content": "export { UiStreamProcessingFlinkTopologyComponent } from './stream-processing-flink-topology.component'\nexport { UiStreamOperatorDetailComponent, type InspectorTab } from './stream-operator-detail.component'\nexport { UiStreamTopologyTelemetryComponent } from './stream-topology-telemetry.component'\nexport type { FlinkOperatorNode, FlinkSubtask } from './stream-topology-types'\nexport { defaultFlinkOperators } from './stream-topology-data'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/stream-processing-flink-topology/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/angular/badge.json",
    "https://uipkge.dev/r/angular/button.json",
    "https://uipkge.dev/r/angular/card.json",
    "https://uipkge.dev/r/angular/progress.json",
    "https://uipkge.dev/r/angular/separator.json",
    "https://uipkge.dev/r/angular/table.json"
  ],
  "description": "Apache Flink & RisingWave stateful streaming graph: real-time DAG topology, window throughput, checkpointing duration, RocksDB state inspector, and backpressure heat monitor.",
  "categories": [
    "devops",
    "dashboard",
    "data",
    "app"
  ]
}