Full Code of openstatusHQ/openstatus for AI

main d106d481b754 cached
2223 files
11.4 MB
3.1M tokens
4125 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (12,431K chars total). Download the full file to get everything.
Repository: openstatusHQ/openstatus
Branch: main
Commit: d106d481b754
Files: 2223
Total size: 11.4 MB

Directory structure:
gitextract_l155h8jc/

├── .claude/
│   └── commands/
│       └── ship.md
├── .dockerignore
├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       ├── api-preview.yml
│       ├── claude-code-review.yml
│       ├── claude.yml
│       ├── deploy-checker.yml
│       ├── deploy-private-location.yml
│       ├── deploy-workflows.yml
│       ├── deploy.yml
│       ├── docker-publish-dev.yml
│       ├── docker-publish.yml
│       ├── dx.yml
│       ├── go-tests.yml
│       ├── lint.yml
│       ├── migrate.yml
│       ├── publish-checker.yml
│       ├── synthetic.yml
│       ├── test.yml
│       └── workflow-preview.yml
├── .gitignore
├── .koyebignore
├── .npmrc
├── .oxlintrc.json
├── .prettierignore
├── .stacked.toml
├── .vscode/
│   └── settings.json
├── CLAUDE.md
├── CONTRIBUTING.MD
├── COOLIFY_DEPLOYMENT.md
├── COOLIFY_ENVIRONMENT_GUIDE.md
├── COOLIFY_SETUP.md
├── DOCKER.md
├── LICENSE
├── README.md
├── SECURITY.md
├── apps/
│   ├── README.md
│   ├── checker/
│   │   ├── .gitignore
│   │   ├── .golangci.yml
│   │   ├── .private.air.toml
│   │   ├── .probe.air.toml
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── ca/
│   │   │   └── ca-bundle.crt
│   │   ├── checker/
│   │   │   ├── dns.go
│   │   │   ├── dns_test.go
│   │   │   ├── http.go
│   │   │   ├── http_test.go
│   │   │   ├── tcp.go
│   │   │   ├── tcp_test.go
│   │   │   └── update.go
│   │   ├── cmd/
│   │   │   ├── private/
│   │   │   │   └── main.go
│   │   │   └── server/
│   │   │       └── main.go
│   │   ├── fly.toml
│   │   ├── go.mod
│   │   ├── go.sum
│   │   ├── handlers/
│   │   │   ├── checker.go
│   │   │   ├── checker_test.go
│   │   │   ├── dns.go
│   │   │   ├── dns_test.go
│   │   │   ├── handler.go
│   │   │   ├── ping.go
│   │   │   ├── ping_test.go
│   │   │   └── tcp.go
│   │   ├── justfile
│   │   ├── pkg/
│   │   │   ├── assertions/
│   │   │   │   ├── assertions.go
│   │   │   │   └── assertions_test.go
│   │   │   ├── job/
│   │   │   │   ├── dns_job.go
│   │   │   │   ├── http_job.go
│   │   │   │   ├── http_job_test.go
│   │   │   │   ├── job.go
│   │   │   │   ├── monitors.go
│   │   │   │   ├── tcp_job.go
│   │   │   │   └── tcp_job_test.go
│   │   │   ├── logger/
│   │   │   │   └── logger.go
│   │   │   ├── otel/
│   │   │   │   ├── otel.go
│   │   │   │   └── otel_test.go
│   │   │   ├── scheduler/
│   │   │   │   ├── scheduler.go
│   │   │   │   └── scheduler_test.go
│   │   │   └── tinybird/
│   │   │       ├── client.go
│   │   │       └── client_test.go
│   │   ├── private-location.Dockerfile
│   │   ├── proto/
│   │   │   └── private_location/
│   │   │       └── v1/
│   │   │           ├── assertions.pb.go
│   │   │           ├── dns_monitor.pb.go
│   │   │           ├── http_monitor.pb.go
│   │   │           ├── private_location.connect.go
│   │   │           ├── private_location.pb.go
│   │   │           └── tcp_monitor.pb.go
│   │   └── request/
│   │       └── request.go
│   ├── dashboard/
│   │   ├── .dockerignore
│   │   ├── .gitignore
│   │   ├── Dockerfile
│   │   ├── components.json
│   │   ├── docker-compose.yaml
│   │   ├── dofigen.yml
│   │   ├── env.ts
│   │   ├── instrumentation-client.ts
│   │   ├── next-env.d.ts
│   │   ├── next.config.ts
│   │   ├── package.json
│   │   ├── postcss.config.mjs
│   │   ├── public/
│   │   │   └── fonts/
│   │   │       ├── CommitMono-400-Italic.otf
│   │   │       ├── CommitMono-400-Regular.otf
│   │   │       ├── CommitMono-700-Italic.otf
│   │   │       └── CommitMono-700-Regular.otf
│   │   ├── sentry.edge.config.ts
│   │   ├── sentry.server.config.ts
│   │   ├── src/
│   │   │   ├── app/
│   │   │   │   ├── (dashboard)/
│   │   │   │   │   ├── agents/
│   │   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── cli/
│   │   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── invite/
│   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   └── search-params.tsx
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   ├── monitors/
│   │   │   │   │   │   ├── (list)/
│   │   │   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   └── search-params.ts
│   │   │   │   │   │   ├── [id]/
│   │   │   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   │   │   ├── constants.ts
│   │   │   │   │   │   │   ├── edit/
│   │   │   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── incidents/
│   │   │   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   │   ├── logs/
│   │   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   │   └── search-params.ts
│   │   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   │   ├── overview/
│   │   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   │   └── search-params.ts
│   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   ├── sidebar.tsx
│   │   │   │   │   │   │   └── tabs.tsx
│   │   │   │   │   │   └── create/
│   │   │   │   │   │       ├── breadcrumb.tsx
│   │   │   │   │   │       ├── layout.tsx
│   │   │   │   │   │       └── page.tsx
│   │   │   │   │   ├── notifications/
│   │   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   └── search-params.ts
│   │   │   │   │   ├── onboarding/
│   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   └── search-params.ts
│   │   │   │   │   ├── overview/
│   │   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   │   ├── data-table-status-reports.tsx
│   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── page.tsx
│   │   │   │   │   ├── private-locations/
│   │   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── settings/
│   │   │   │   │   │   ├── (list)/
│   │   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── account/
│   │   │   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── billing/
│   │   │   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   └── search-params.ts
│   │   │   │   │   │   ├── general/
│   │   │   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── integrations/
│   │   │   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   └── slack-card.tsx
│   │   │   │   │   │   └── tabs.tsx
│   │   │   │   │   └── status-pages/
│   │   │   │   │       ├── (list)/
│   │   │   │   │       │   ├── breadcrumb.tsx
│   │   │   │   │       │   ├── client.tsx
│   │   │   │   │       │   ├── layout.tsx
│   │   │   │   │       │   ├── nav-actions.tsx
│   │   │   │   │       │   └── page.tsx
│   │   │   │   │       ├── [id]/
│   │   │   │   │       │   ├── breadcrumb.tsx
│   │   │   │   │       │   ├── components/
│   │   │   │   │       │   │   ├── layout.tsx
│   │   │   │   │       │   │   └── page.tsx
│   │   │   │   │       │   ├── constants.ts
│   │   │   │   │       │   ├── edit/
│   │   │   │   │       │   │   └── page.tsx
│   │   │   │   │       │   ├── layout.tsx
│   │   │   │   │       │   ├── maintenances/
│   │   │   │   │       │   │   ├── layout.tsx
│   │   │   │   │       │   │   └── page.tsx
│   │   │   │   │       │   ├── nav-actions.tsx
│   │   │   │   │       │   ├── page.tsx
│   │   │   │   │       │   ├── sidebar.tsx
│   │   │   │   │       │   ├── status-reports/
│   │   │   │   │       │   │   ├── [reportId]/
│   │   │   │   │       │   │   │   ├── layout.tsx
│   │   │   │   │       │   │   │   └── page.tsx
│   │   │   │   │       │   │   ├── layout.tsx
│   │   │   │   │       │   │   └── page.tsx
│   │   │   │   │       │   ├── subscribers/
│   │   │   │   │       │   │   ├── layout.tsx
│   │   │   │   │       │   │   └── page.tsx
│   │   │   │   │       │   └── tabs.tsx
│   │   │   │   │       └── create/
│   │   │   │   │           ├── breadcrumb.tsx
│   │   │   │   │           ├── client.tsx
│   │   │   │   │           ├── layout.tsx
│   │   │   │   │           └── page.tsx
│   │   │   │   ├── api/
│   │   │   │   │   ├── auth/
│   │   │   │   │   │   └── [...nextauth]/
│   │   │   │   │   │       └── route.ts
│   │   │   │   │   └── trpc/
│   │   │   │   │       ├── edge/
│   │   │   │   │       │   └── [trpc]/
│   │   │   │   │       │       └── route.ts
│   │   │   │   │       └── lambda/
│   │   │   │   │           └── [trpc]/
│   │   │   │   │               └── route.ts
│   │   │   │   ├── global-error.tsx
│   │   │   │   ├── globals.css
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── login/
│   │   │   │   │   ├── _components/
│   │   │   │   │   │   ├── actions.ts
│   │   │   │   │   │   └── magic-link-form.tsx
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   ├── page.tsx
│   │   │   │   │   └── search-params.ts
│   │   │   │   ├── metadata.ts
│   │   │   │   ├── not-found.tsx
│   │   │   │   ├── react-table.d.ts
│   │   │   │   └── robots.ts
│   │   │   ├── components/
│   │   │   │   ├── chart/
│   │   │   │   │   ├── chart-area-latency.tsx
│   │   │   │   │   ├── chart-area-timing-phases.tsx
│   │   │   │   │   ├── chart-bar-uptime-light.tsx
│   │   │   │   │   ├── chart-bar-uptime.tsx
│   │   │   │   │   ├── chart-line-region.tsx
│   │   │   │   │   ├── chart-line-regions.tsx
│   │   │   │   │   └── chart-tooltip-number.tsx
│   │   │   │   ├── common/
│   │   │   │   │   ├── code.tsx
│   │   │   │   │   ├── hover-card-timestamp.tsx
│   │   │   │   │   ├── icon-cloud-provider.tsx
│   │   │   │   │   ├── input-with-addons.tsx
│   │   │   │   │   ├── kbd.tsx
│   │   │   │   │   ├── link.tsx
│   │   │   │   │   ├── note.tsx
│   │   │   │   │   └── wheel-picker.tsx
│   │   │   │   ├── content/
│   │   │   │   │   ├── action-card.tsx
│   │   │   │   │   ├── billing-addons.tsx
│   │   │   │   │   ├── billing-overlay.tsx
│   │   │   │   │   ├── billing-progress.tsx
│   │   │   │   │   ├── block-wrapper.tsx
│   │   │   │   │   ├── empty-state.tsx
│   │   │   │   │   ├── process-message.tsx
│   │   │   │   │   └── section.tsx
│   │   │   │   ├── controls-filter/
│   │   │   │   │   └── .gitkeep
│   │   │   │   ├── controls-search/
│   │   │   │   │   ├── button-reset.tsx
│   │   │   │   │   ├── command-region.tsx
│   │   │   │   │   ├── command-tags.tsx
│   │   │   │   │   ├── dropdown-interval.tsx
│   │   │   │   │   ├── dropdown-percentile.tsx
│   │   │   │   │   ├── dropdown-period.tsx
│   │   │   │   │   ├── dropdown-status.tsx
│   │   │   │   │   ├── dropdown-trigger.tsx
│   │   │   │   │   └── popover-date.tsx
│   │   │   │   ├── data-table/
│   │   │   │   │   ├── audit-logs/
│   │   │   │   │   │   ├── columns.tsx
│   │   │   │   │   │   └── wrapper.tsx
│   │   │   │   │   ├── billing/
│   │   │   │   │   │   └── data-table.tsx
│   │   │   │   │   ├── dable-cell-skeleton.tsx
│   │   │   │   │   ├── data-table-sheet.tsx
│   │   │   │   │   ├── incidents/
│   │   │   │   │   │   ├── columns.tsx
│   │   │   │   │   │   └── data-table-row-actions.tsx
│   │   │   │   │   ├── maintenances/
│   │   │   │   │   │   ├── columns.tsx
│   │   │   │   │   │   └── data-table-row-actions.tsx
│   │   │   │   │   ├── monitors/
│   │   │   │   │   │   ├── columns.tsx
│   │   │   │   │   │   ├── data-table-action-bar.tsx
│   │   │   │   │   │   ├── data-table-row-actions.tsx
│   │   │   │   │   │   └── data-table-toolbar.tsx
│   │   │   │   │   ├── notifications/
│   │   │   │   │   │   ├── columns.tsx
│   │   │   │   │   │   └── data-table-row-actions.tsx
│   │   │   │   │   ├── page-components/
│   │   │   │   │   │   ├── columns.tsx
│   │   │   │   │   │   └── data-table-row-actions.tsx
│   │   │   │   │   ├── private-locations/
│   │   │   │   │   │   ├── columns.tsx
│   │   │   │   │   │   └── data-table-row-actions.tsx
│   │   │   │   │   ├── response-logs/
│   │   │   │   │   │   ├── columns.tsx
│   │   │   │   │   │   ├── data-table-basics.tsx
│   │   │   │   │   │   ├── data-table-sheet-test.tsx
│   │   │   │   │   │   ├── data-table-sheet.tsx
│   │   │   │   │   │   ├── data-table-toolbar.tsx
│   │   │   │   │   │   └── regions/
│   │   │   │   │   │       └── columns.tsx
│   │   │   │   │   ├── settings/
│   │   │   │   │   │   ├── api-key/
│   │   │   │   │   │   │   └── data-table.tsx
│   │   │   │   │   │   ├── invitations/
│   │   │   │   │   │   │   └── data-table.tsx
│   │   │   │   │   │   └── members/
│   │   │   │   │   │       └── data-table.tsx
│   │   │   │   │   ├── status-pages/
│   │   │   │   │   │   ├── columns.tsx
│   │   │   │   │   │   └── data-table-row-actions.tsx
│   │   │   │   │   ├── status-report-updates/
│   │   │   │   │   │   ├── data-table-row-actions.tsx
│   │   │   │   │   │   └── data-table.tsx
│   │   │   │   │   ├── status-reports/
│   │   │   │   │   │   ├── columns.tsx
│   │   │   │   │   │   └── data-table-row-actions.tsx
│   │   │   │   │   ├── subscribers/
│   │   │   │   │   │   ├── columns.tsx
│   │   │   │   │   │   └── data-table-row-actions.tsx
│   │   │   │   │   ├── table-cell-badge.tsx
│   │   │   │   │   ├── table-cell-boolean.tsx
│   │   │   │   │   ├── table-cell-date.tsx
│   │   │   │   │   ├── table-cell-link.tsx
│   │   │   │   │   ├── table-cell-number.tsx
│   │   │   │   │   └── table-cell-unavailable.tsx
│   │   │   │   ├── date-picker.tsx
│   │   │   │   ├── development-indicator.tsx
│   │   │   │   ├── dialogs/
│   │   │   │   │   ├── export-code.tsx
│   │   │   │   │   └── upgrade.tsx
│   │   │   │   ├── domains/
│   │   │   │   │   ├── domain-configuration.tsx
│   │   │   │   │   ├── domain-status-icon.tsx
│   │   │   │   │   └── use-domain-status.ts
│   │   │   │   ├── dropdowns/
│   │   │   │   │   └── quick-actions.tsx
│   │   │   │   ├── forms/
│   │   │   │   │   ├── components/
│   │   │   │   │   │   ├── form-components.tsx
│   │   │   │   │   │   ├── form-import.tsx
│   │   │   │   │   │   ├── telegram-connection-flow.tsx
│   │   │   │   │   │   ├── telegram-form-actions.tsx
│   │   │   │   │   │   ├── telegram-manual-input.tsx
│   │   │   │   │   │   ├── telegram-qr-connection.tsx
│   │   │   │   │   │   ├── telegram-qrcode.tsx
│   │   │   │   │   │   └── update.tsx
│   │   │   │   │   ├── form-alert-dialog.tsx
│   │   │   │   │   ├── form-card.tsx
│   │   │   │   │   ├── form-sheet.tsx
│   │   │   │   │   ├── maintenance/
│   │   │   │   │   │   ├── form.tsx
│   │   │   │   │   │   └── sheet.tsx
│   │   │   │   │   ├── monitor/
│   │   │   │   │   │   ├── form-danger-zone.tsx
│   │   │   │   │   │   ├── form-follow-redirect.tsx
│   │   │   │   │   │   ├── form-general.tsx
│   │   │   │   │   │   ├── form-notifiers.tsx
│   │   │   │   │   │   ├── form-otel.tsx
│   │   │   │   │   │   ├── form-response-time.tsx
│   │   │   │   │   │   ├── form-retry.tsx
│   │   │   │   │   │   ├── form-scheduling-regions.tsx
│   │   │   │   │   │   ├── form-status-pages.tsx
│   │   │   │   │   │   ├── form-tags.tsx
│   │   │   │   │   │   ├── form-visibility.tsx
│   │   │   │   │   │   └── update.tsx
│   │   │   │   │   ├── monitor-tag/
│   │   │   │   │   │   ├── form-monitor-tag.tsx
│   │   │   │   │   │   └── sheet.tsx
│   │   │   │   │   ├── notifications/
│   │   │   │   │   │   ├── form-discord.tsx
│   │   │   │   │   │   ├── form-email.tsx
│   │   │   │   │   │   ├── form-google-chat.tsx
│   │   │   │   │   │   ├── form-grafana-oncall.tsx
│   │   │   │   │   │   ├── form-ntfy.tsx
│   │   │   │   │   │   ├── form-opsgenie.tsx
│   │   │   │   │   │   ├── form-pagerduty.tsx
│   │   │   │   │   │   ├── form-slack.tsx
│   │   │   │   │   │   ├── form-sms.tsx
│   │   │   │   │   │   ├── form-telegram.tsx
│   │   │   │   │   │   ├── form-webhook.tsx
│   │   │   │   │   │   ├── form-whatsapp.tsx
│   │   │   │   │   │   ├── form.tsx
│   │   │   │   │   │   └── sheet.tsx
│   │   │   │   │   ├── onboarding/
│   │   │   │   │   │   ├── create-monitor.tsx
│   │   │   │   │   │   ├── create-page.tsx
│   │   │   │   │   │   └── learn-from.tsx
│   │   │   │   │   ├── private-location/
│   │   │   │   │   │   ├── form.tsx
│   │   │   │   │   │   └── sheet.tsx
│   │   │   │   │   ├── settings/
│   │   │   │   │   │   ├── form-api-key.tsx
│   │   │   │   │   │   ├── form-members.tsx
│   │   │   │   │   │   ├── form-slug.tsx
│   │   │   │   │   │   └── form-workspace.tsx
│   │   │   │   │   ├── status-page/
│   │   │   │   │   │   ├── form-appearance.tsx
│   │   │   │   │   │   ├── form-configuration.tsx
│   │   │   │   │   │   ├── form-custom-domain.tsx
│   │   │   │   │   │   ├── form-danger-zone.tsx
│   │   │   │   │   │   ├── form-general.tsx
│   │   │   │   │   │   ├── form-links.tsx
│   │   │   │   │   │   ├── form-monitors.tsx
│   │   │   │   │   │   ├── form-page-access.tsx
│   │   │   │   │   │   └── update.tsx
│   │   │   │   │   ├── status-report/
│   │   │   │   │   │   ├── form.tsx
│   │   │   │   │   │   └── sheet.tsx
│   │   │   │   │   ├── status-report-update/
│   │   │   │   │   │   ├── form-status-report.tsx
│   │   │   │   │   │   ├── form.tsx
│   │   │   │   │   │   └── sheet.tsx
│   │   │   │   │   └── support-contact/
│   │   │   │   │       ├── dialog.tsx
│   │   │   │   │       └── form.tsx
│   │   │   │   ├── layout/
│   │   │   │   │   └── auth-layout.tsx
│   │   │   │   ├── metric/
│   │   │   │   │   ├── global-uptime/
│   │   │   │   │   │   └── section.tsx
│   │   │   │   │   └── metric-card.tsx
│   │   │   │   ├── nav/
│   │   │   │   │   ├── app-header.tsx
│   │   │   │   │   ├── app-sidebar.tsx
│   │   │   │   │   ├── nav-banner-checklist.tsx
│   │   │   │   │   ├── nav-banner-upgrade.tsx
│   │   │   │   │   ├── nav-banner.tsx
│   │   │   │   │   ├── nav-breadcrumb.tsx
│   │   │   │   │   ├── nav-feedback.tsx
│   │   │   │   │   ├── nav-help.tsx
│   │   │   │   │   ├── nav-main.tsx
│   │   │   │   │   ├── nav-monitors.tsx
│   │   │   │   │   ├── nav-overview.tsx
│   │   │   │   │   ├── nav-status-pages.tsx
│   │   │   │   │   ├── nav-tabs.tsx
│   │   │   │   │   ├── nav-user.tsx
│   │   │   │   │   ├── sidebar-metadata.tsx
│   │   │   │   │   ├── sidebar-right.tsx
│   │   │   │   │   └── workspace-switcher.tsx
│   │   │   │   ├── popovers/
│   │   │   │   │   ├── popover-quantile.tsx
│   │   │   │   │   └── popover-resolution.tsx
│   │   │   │   ├── tailwind-indicator.tsx
│   │   │   │   ├── theme-provider.tsx
│   │   │   │   ├── theme-toggle.tsx
│   │   │   │   └── ui/
│   │   │   │       ├── data-table/
│   │   │   │       │   ├── data-table-action-bar.tsx
│   │   │   │       │   ├── data-table-column-header.tsx
│   │   │   │       │   ├── data-table-faceted-filter.tsx
│   │   │   │       │   ├── data-table-pagination.tsx
│   │   │   │       │   ├── data-table-skeleton.tsx
│   │   │   │       │   ├── data-table-toobar.tsx
│   │   │   │       │   ├── data-table-view-options.tsx
│   │   │   │       │   └── data-table.tsx
│   │   │   │       └── sortable.tsx
│   │   │   ├── data/
│   │   │   │   ├── audit-logs.client.ts
│   │   │   │   ├── audit-logs.ts
│   │   │   │   ├── icons.ts
│   │   │   │   ├── incidents.client.ts
│   │   │   │   ├── incidents.ts
│   │   │   │   ├── invitations.ts
│   │   │   │   ├── maintenances.client.ts
│   │   │   │   ├── maintenances.ts
│   │   │   │   ├── members.ts
│   │   │   │   ├── metrics.client.ts
│   │   │   │   ├── monitor-tags.ts
│   │   │   │   ├── monitors.client.ts
│   │   │   │   ├── monitors.ts
│   │   │   │   ├── notifications.client.ts
│   │   │   │   ├── notifications.ts
│   │   │   │   ├── page-components.client.ts
│   │   │   │   ├── plans.ts
│   │   │   │   ├── region-metrics.client.ts
│   │   │   │   ├── region-metrics.ts
│   │   │   │   ├── regions.ts
│   │   │   │   ├── response-logs.ts
│   │   │   │   ├── status-codes.ts
│   │   │   │   ├── status-pages.client.ts
│   │   │   │   ├── status-pages.ts
│   │   │   │   ├── status-report-updates.client.ts
│   │   │   │   ├── status-reports.client.ts
│   │   │   │   ├── status-reports.ts
│   │   │   │   └── subscribers.ts
│   │   │   ├── hooks/
│   │   │   │   ├── use-feature.ts
│   │   │   │   └── use-telegram-connection.ts
│   │   │   ├── instrumentation.ts
│   │   │   ├── lib/
│   │   │   │   ├── auth/
│   │   │   │   │   ├── adapter.ts
│   │   │   │   │   ├── helpers.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── providers.ts
│   │   │   │   ├── composition.ts
│   │   │   │   ├── domains.ts
│   │   │   │   ├── formatter.ts
│   │   │   │   ├── middleware/
│   │   │   │   │   └── with-invitation.ts
│   │   │   │   ├── stripe.ts
│   │   │   │   ├── trpc/
│   │   │   │   │   ├── client.tsx
│   │   │   │   │   ├── query-client.ts
│   │   │   │   │   ├── server.tsx
│   │   │   │   │   └── shared.ts
│   │   │   │   └── utils.ts
│   │   │   ├── next-auth.d.ts
│   │   │   ├── proxy.ts
│   │   │   └── scripts/
│   │   │       ├── README.md
│   │   │       └── export-blog-post-metrics.ts
│   │   └── tsconfig.json
│   ├── docs/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── astro.config.mjs
│   │   ├── package.json
│   │   ├── public/
│   │   │   ├── fonts/
│   │   │   │   ├── CommitMono-400-Italic.otf
│   │   │   │   ├── CommitMono-400-Regular.otf
│   │   │   │   ├── CommitMono-700-Italic.otf
│   │   │   │   └── CommitMono-700-Regular.otf
│   │   │   └── robots.txt
│   │   ├── src/
│   │   │   ├── components/
│   │   │   │   ├── Footer.astro
│   │   │   │   ├── Head.astro
│   │   │   │   ├── Hero.astro
│   │   │   │   ├── SiteTitle.astro
│   │   │   │   ├── Status.astro
│   │   │   │   └── utils.ts
│   │   │   ├── content/
│   │   │   │   ├── config.ts
│   │   │   │   └── docs/
│   │   │   │       ├── 404.md
│   │   │   │       ├── concept/
│   │   │   │       │   ├── best-practices-status-page.mdx
│   │   │   │       │   ├── getting-started.mdx
│   │   │   │       │   ├── latency-vs-response-time.mdx
│   │   │   │       │   ├── uptime-calculation-and-values.mdx
│   │   │   │       │   ├── uptime-monitoring-as-code.mdx
│   │   │   │       │   └── uptime-monitoring.mdx
│   │   │   │       ├── guides/
│   │   │   │       │   ├── getting-started.mdx
│   │   │   │       │   ├── how-deploy-status-page-cf-pages.mdx
│   │   │   │       │   ├── how-to-add-svg-status-badge.mdx
│   │   │   │       │   ├── how-to-deploy-probes-cloudflare-containers.mdx
│   │   │   │       │   ├── how-to-export-metrics-to-otlp-endpoint.mdx
│   │   │   │       │   ├── how-to-monitor-mcp-server.mdx
│   │   │   │       │   ├── how-to-run-synthetic-test-github-action.mdx
│   │   │   │       │   ├── how-to-use-react-widget.mdx
│   │   │   │       │   ├── self-host-status-page-only.mdx
│   │   │   │       │   └── self-hosting-openstatus.mdx
│   │   │   │       ├── help/
│   │   │   │       │   └── support.mdx
│   │   │   │       ├── index.mdx
│   │   │   │       ├── monitoring/
│   │   │   │       │   └── overview.mdx
│   │   │   │       ├── reference/
│   │   │   │       │   ├── cli-reference.mdx
│   │   │   │       │   ├── dns-monitor.mdx
│   │   │   │       │   ├── http-monitor.mdx
│   │   │   │       │   ├── incident.mdx
│   │   │   │       │   ├── location.mdx
│   │   │   │       │   ├── notification.mdx
│   │   │   │       │   ├── page-components.mdx
│   │   │   │       │   ├── private-location.mdx
│   │   │   │       │   ├── status-page.mdx
│   │   │   │       │   ├── status-report.mdx
│   │   │   │       │   ├── subscriber.mdx
│   │   │   │       │   ├── tcp-monitor.mdx
│   │   │   │       │   └── terraform.mdx
│   │   │   │       ├── reference.mdx
│   │   │   │       ├── sdk/
│   │   │   │       │   └── nodejs/
│   │   │   │       │       ├── authentication.mdx
│   │   │   │       │       ├── error-handling.mdx
│   │   │   │       │       ├── getting-started.mdx
│   │   │   │       │       ├── health-service.mdx
│   │   │   │       │       ├── index.mdx
│   │   │   │       │       ├── maintenance-service.mdx
│   │   │   │       │       ├── monitor-service.mdx
│   │   │   │       │       ├── notification-service.mdx
│   │   │   │       │       ├── reference.mdx
│   │   │   │       │       ├── status-page-service.mdx
│   │   │   │       │       ├── status-report-service.mdx
│   │   │   │       │       └── typescript-tips.mdx
│   │   │   │       └── tutorial/
│   │   │   │           ├── get-started-with-openstatus-cli.mdx
│   │   │   │           ├── getting-started.mdx
│   │   │   │           ├── how-to-configure-status-page.mdx
│   │   │   │           ├── how-to-create-monitor.mdx
│   │   │   │           ├── how-to-create-private-location.mdx
│   │   │   │           ├── how-to-create-status-page.mdx
│   │   │   │           └── how-to-setup-slack-agent.mdx
│   │   │   ├── custom.css
│   │   │   ├── env.d.ts
│   │   │   └── global.css
│   │   └── tsconfig.json
│   ├── private-location/
│   │   ├── .air.toml
│   │   ├── .dockerignore
│   │   ├── .gitignore
│   │   ├── .golangci.yml
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── cmd/
│   │   │   └── server/
│   │   │       └── main.go
│   │   ├── dofigen.yml
│   │   ├── fly.toml
│   │   ├── go.mod
│   │   ├── go.sum
│   │   ├── internal/
│   │   │   ├── database/
│   │   │   │   ├── database.go
│   │   │   │   └── models.go
│   │   │   ├── logs/
│   │   │   │   ├── logs.go
│   │   │   │   └── logs_test.go
│   │   │   ├── models/
│   │   │   │   └── assertions.go
│   │   │   ├── server/
│   │   │   │   ├── db_testdata
│   │   │   │   ├── errors.go
│   │   │   │   ├── ingest_common.go
│   │   │   │   ├── ingest_dns.go
│   │   │   │   ├── ingest_dns_test.go
│   │   │   │   ├── ingest_http.go
│   │   │   │   ├── ingest_http_test.go
│   │   │   │   ├── ingest_tcp.go
│   │   │   │   ├── ingest_tcp_test.go
│   │   │   │   ├── monitors.go
│   │   │   │   ├── monitors_test.go
│   │   │   │   ├── routes.go
│   │   │   │   ├── server.go
│   │   │   │   ├── validation.go
│   │   │   │   └── validation_test.go
│   │   │   └── tinybird/
│   │   │       ├── client.go
│   │   │       └── client_test.go
│   │   ├── justfile
│   │   └── proto/
│   │       └── private_location/
│   │           └── v1/
│   │               ├── assertions.pb.go
│   │               ├── dns_monitor.pb.go
│   │               ├── http_monitor.pb.go
│   │               ├── private_location.connect.go
│   │               ├── private_location.pb.go
│   │               └── tcp_monitor.pb.go
│   ├── railway-proxy/
│   │   ├── Dockerfile
│   │   ├── go.mod
│   │   ├── go.sum
│   │   └── main.go
│   ├── screenshot-service/
│   │   ├── .dockerignore
│   │   ├── .gitignore
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── fly.toml
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── env.ts
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   ├── server/
│   │   ├── .dockerignore
│   │   ├── .gitignore
│   │   ├── CONNECTRPC_SPEC.md
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── bunfig.toml
│   │   ├── docker-compose.yaml
│   │   ├── dofigen.yml
│   │   ├── env.ts
│   │   ├── fly.sh
│   │   ├── fly.toml
│   │   ├── log/
│   │   │   └── fly.toml
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── env.ts
│   │   │   ├── index.ts
│   │   │   ├── libs/
│   │   │   │   ├── checker/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── clients.ts
│   │   │   │   ├── errors/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── openapi-error-responses.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── middlewares/
│   │   │   │   │   ├── auth.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── plan.ts
│   │   │   │   │   └── track.ts
│   │   │   │   └── test/
│   │   │   │       └── preload.ts
│   │   │   ├── routes/
│   │   │   │   ├── public/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── status.test.ts
│   │   │   │   │   ├── status.ts
│   │   │   │   │   └── unsubscribe.ts
│   │   │   │   ├── rpc/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── interceptors/
│   │   │   │   │   │   ├── auth.ts
│   │   │   │   │   │   ├── error.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── logging.ts
│   │   │   │   │   │   └── validation.ts
│   │   │   │   │   ├── router.ts
│   │   │   │   │   └── services/
│   │   │   │   │       ├── health/
│   │   │   │   │       │   └── index.ts
│   │   │   │   │       ├── maintenance/
│   │   │   │   │       │   ├── __tests__/
│   │   │   │   │       │   │   └── maintenance.test.ts
│   │   │   │   │       │   ├── converters.ts
│   │   │   │   │       │   ├── errors.ts
│   │   │   │   │       │   └── index.ts
│   │   │   │   │       ├── monitor/
│   │   │   │   │       │   ├── __tests__/
│   │   │   │   │       │   │   └── monitor.test.ts
│   │   │   │   │       │   ├── converters/
│   │   │   │   │       │   │   ├── assertions.ts
│   │   │   │   │       │   │   ├── comparators.ts
│   │   │   │   │       │   │   ├── defaults.ts
│   │   │   │   │       │   │   ├── enums.ts
│   │   │   │   │       │   │   ├── headers.ts
│   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │       │   │   ├── monitors.ts
│   │   │   │   │       │   │   └── regions.ts
│   │   │   │   │       │   ├── errors.ts
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── limits.ts
│   │   │   │   │       │   └── validators.ts
│   │   │   │   │       ├── notification/
│   │   │   │   │       │   ├── __tests__/
│   │   │   │   │       │   │   └── notification.test.ts
│   │   │   │   │       │   ├── converters.ts
│   │   │   │   │       │   ├── errors.ts
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── limits.ts
│   │   │   │   │       │   └── test-providers.ts
│   │   │   │   │       ├── status-page/
│   │   │   │   │       │   ├── __tests__/
│   │   │   │   │       │   │   └── status-page.test.ts
│   │   │   │   │       │   ├── converters.ts
│   │   │   │   │       │   ├── errors.ts
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   └── limits.ts
│   │   │   │   │       └── status-report/
│   │   │   │   │           ├── __tests__/
│   │   │   │   │           │   └── status-report.test.ts
│   │   │   │   │           ├── converters.ts
│   │   │   │   │           ├── errors.ts
│   │   │   │   │           └── index.ts
│   │   │   │   ├── slack/
│   │   │   │   │   ├── agent.test.ts
│   │   │   │   │   ├── agent.ts
│   │   │   │   │   ├── blocks.test.ts
│   │   │   │   │   ├── blocks.ts
│   │   │   │   │   ├── confirmation-store.test.ts
│   │   │   │   │   ├── confirmation-store.ts
│   │   │   │   │   ├── handler.test.ts
│   │   │   │   │   ├── handler.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── interactions.test.ts
│   │   │   │   │   ├── interactions.ts
│   │   │   │   │   ├── oauth.test.ts
│   │   │   │   │   ├── oauth.ts
│   │   │   │   │   ├── tools/
│   │   │   │   │   │   ├── add-status-report-update.ts
│   │   │   │   │   │   ├── create-maintenance.ts
│   │   │   │   │   │   ├── create-status-report.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── list-maintenances.ts
│   │   │   │   │   │   ├── list-status-pages.ts
│   │   │   │   │   │   ├── list-status-reports.ts
│   │   │   │   │   │   ├── resolve-status-report.ts
│   │   │   │   │   │   ├── tools.test.ts
│   │   │   │   │   │   └── update-status-report.ts
│   │   │   │   │   ├── verify.test.ts
│   │   │   │   │   ├── verify.ts
│   │   │   │   │   └── workspace-resolver.ts
│   │   │   │   └── v1/
│   │   │   │       ├── check/
│   │   │   │       │   ├── http/
│   │   │   │       │   │   ├── post.test.ts
│   │   │   │       │   │   ├── post.ts
│   │   │   │       │   │   └── schema.ts
│   │   │   │       │   └── index.ts
│   │   │   │       ├── incidents/
│   │   │   │       │   ├── get.test.ts
│   │   │   │       │   ├── get.ts
│   │   │   │       │   ├── get_all.test.ts
│   │   │   │       │   ├── get_all.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── put.test.ts
│   │   │   │       │   ├── put.ts
│   │   │   │       │   └── schema.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── maintenances/
│   │   │   │       │   ├── get.test.ts
│   │   │   │       │   ├── get.ts
│   │   │   │       │   ├── get_all.test.ts
│   │   │   │       │   ├── get_all.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── post.test.ts
│   │   │   │       │   ├── post.ts
│   │   │   │       │   ├── put.test.ts
│   │   │   │       │   ├── put.ts
│   │   │   │       │   └── schema.ts
│   │   │   │       ├── monitors/
│   │   │   │       │   ├── delete.test.ts
│   │   │   │       │   ├── delete.ts
│   │   │   │       │   ├── get.test.ts
│   │   │   │       │   ├── get.ts
│   │   │   │       │   ├── get_all.test.ts
│   │   │   │       │   ├── get_all.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── post.test.ts
│   │   │   │       │   ├── post.ts
│   │   │   │       │   ├── post_dns.test.ts
│   │   │   │       │   ├── post_dns.ts
│   │   │   │       │   ├── post_http.test.ts
│   │   │   │       │   ├── post_http.ts
│   │   │   │       │   ├── post_tcp.test.ts
│   │   │   │       │   ├── post_tcp.ts
│   │   │   │       │   ├── put.test.ts
│   │   │   │       │   ├── put.ts
│   │   │   │       │   ├── put_dns.test.ts
│   │   │   │       │   ├── put_dns.ts
│   │   │   │       │   ├── put_http.test.ts
│   │   │   │       │   ├── put_http.ts
│   │   │   │       │   ├── put_tcp.test.ts
│   │   │   │       │   ├── put_tcp.ts
│   │   │   │       │   ├── results/
│   │   │   │       │   │   ├── get.test.ts
│   │   │   │       │   │   └── get.ts
│   │   │   │       │   ├── run/
│   │   │   │       │   │   ├── post.test.ts
│   │   │   │       │   │   ├── post.ts
│   │   │   │       │   │   └── schema.ts
│   │   │   │       │   ├── schema.ts
│   │   │   │       │   ├── summary/
│   │   │   │       │   │   ├── get.test.ts
│   │   │   │       │   │   ├── get.ts
│   │   │   │       │   │   └── schema.ts
│   │   │   │       │   ├── trigger/
│   │   │   │       │   │   ├── post.test.ts
│   │   │   │       │   │   ├── post.ts
│   │   │   │       │   │   └── schema.ts
│   │   │   │       │   └── utils.ts
│   │   │   │       ├── notifications/
│   │   │   │       │   ├── get.test.ts
│   │   │   │       │   ├── get.ts
│   │   │   │       │   ├── get_all.test.ts
│   │   │   │       │   ├── get_all.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── post.test.ts
│   │   │   │       │   ├── post.ts
│   │   │   │       │   └── schema.ts
│   │   │   │       ├── pageSubscribers/
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── post.test.ts
│   │   │   │       │   ├── post.ts
│   │   │   │       │   └── schema.ts
│   │   │   │       ├── pages/
│   │   │   │       │   ├── get.test.ts
│   │   │   │       │   ├── get.ts
│   │   │   │       │   ├── get_all.test.ts
│   │   │   │       │   ├── get_all.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── post.test.ts
│   │   │   │       │   ├── post.ts
│   │   │   │       │   ├── put.test.ts
│   │   │   │       │   ├── put.ts
│   │   │   │       │   └── schema.ts
│   │   │   │       ├── statusReportUpdates/
│   │   │   │       │   ├── get.test.ts
│   │   │   │       │   ├── get.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── post.test.ts
│   │   │   │       │   ├── post.ts
│   │   │   │       │   └── schema.ts
│   │   │   │       ├── statusReports/
│   │   │   │       │   ├── delete.test.ts
│   │   │   │       │   ├── delete.ts
│   │   │   │       │   ├── get.test.ts
│   │   │   │       │   ├── get.ts
│   │   │   │       │   ├── get_all.test.ts
│   │   │   │       │   ├── get_all.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── post.test.ts
│   │   │   │       │   ├── post.ts
│   │   │   │       │   ├── schema.ts
│   │   │   │       │   ├── subscriber-filtering.integration.test.ts
│   │   │   │       │   └── update/
│   │   │   │       │       ├── post.test.ts
│   │   │   │       │       └── post.ts
│   │   │   │       ├── utils.ts
│   │   │   │       └── whoami/
│   │   │   │           ├── get.test.ts
│   │   │   │           ├── get.ts
│   │   │   │           ├── index.ts
│   │   │   │           └── schema.ts
│   │   │   ├── types/
│   │   │   │   └── index.ts
│   │   │   └── utils/
│   │   │       ├── audit-log.ts
│   │   │       ├── not-empty.ts
│   │   │       ├── page-component.ts
│   │   │       └── random-promise.ts
│   │   ├── static/
│   │   │   ├── openapi-v1.json
│   │   │   └── openapi.yaml
│   │   └── tsconfig.json
│   ├── ssh-server/
│   │   ├── .dockerignore
│   │   ├── .gitignore
│   │   ├── Dockerfile
│   │   ├── banner.txt
│   │   ├── fly.toml
│   │   ├── go.mod
│   │   ├── go.sum
│   │   └── main.go
│   ├── status-page/
│   │   ├── .dockerignore
│   │   ├── .gitignore
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── components.json
│   │   ├── docker-compose.yaml
│   │   ├── dofigen.yml
│   │   ├── env.ts
│   │   ├── instrumentation-client.ts
│   │   ├── next-env.d.ts
│   │   ├── next.config.ts
│   │   ├── package.json
│   │   ├── postcss.config.mjs
│   │   ├── public/
│   │   │   └── fonts/
│   │   │       ├── CommitMono-400-Italic.otf
│   │   │       ├── CommitMono-400-Regular.otf
│   │   │       ├── CommitMono-700-Italic.otf
│   │   │       └── CommitMono-700-Regular.otf
│   │   ├── sentry.edge.config.ts
│   │   ├── sentry.server.config.ts
│   │   ├── src/
│   │   │   ├── app/
│   │   │   │   ├── (public)/
│   │   │   │   │   ├── client.tsx
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   ├── page.tsx
│   │   │   │   │   └── search-params.ts
│   │   │   │   ├── (status-page)/
│   │   │   │   │   └── [domain]/
│   │   │   │   │       ├── (auth)/
│   │   │   │   │       │   ├── layout.tsx
│   │   │   │   │       │   └── login/
│   │   │   │   │       │       ├── _components/
│   │   │   │   │       │       │   ├── section-magic-link.tsx
│   │   │   │   │       │       │   └── section-password.tsx
│   │   │   │   │       │       ├── actions.ts
│   │   │   │   │       │       └── page.tsx
│   │   │   │   │       ├── (public)/
│   │   │   │   │       │   ├── badge/
│   │   │   │   │       │   │   ├── route.tsx
│   │   │   │   │       │   │   └── v2/
│   │   │   │   │       │   │       └── route.ts
│   │   │   │   │       │   ├── events/
│   │   │   │   │       │   │   ├── (list)/
│   │   │   │   │       │   │   │   ├── page.tsx
│   │   │   │   │       │   │   │   └── search-params.ts
│   │   │   │   │       │   │   ├── (view)/
│   │   │   │   │       │   │   │   ├── maintenance/
│   │   │   │   │       │   │   │   │   └── [id]/
│   │   │   │   │       │   │   │   │       ├── layout.tsx
│   │   │   │   │       │   │   │   │       └── page.tsx
│   │   │   │   │       │   │   │   └── report/
│   │   │   │   │       │   │   │       └── [id]/
│   │   │   │   │       │   │   │           ├── layout.tsx
│   │   │   │   │       │   │   │           └── page.tsx
│   │   │   │   │       │   │   └── layout.tsx
│   │   │   │   │       │   ├── feed/
│   │   │   │   │       │   │   ├── [type]/
│   │   │   │   │       │   │   │   └── route.ts
│   │   │   │   │       │   │   └── json/
│   │   │   │   │       │   │       └── route.ts
│   │   │   │   │       │   ├── layout.tsx
│   │   │   │   │       │   ├── manage/
│   │   │   │   │       │   │   ├── [token]/
│   │   │   │   │       │   │   │   ├── layout.tsx
│   │   │   │   │       │   │   │   └── page.tsx
│   │   │   │   │       │   │   └── layout.tsx
│   │   │   │   │       │   ├── monitors/
│   │   │   │   │       │   │   ├── [id]/
│   │   │   │   │       │   │   │   ├── page.tsx
│   │   │   │   │       │   │   │   └── search-params.ts
│   │   │   │   │       │   │   └── page.tsx
│   │   │   │   │       │   ├── page.tsx
│   │   │   │   │       │   ├── unsubscribe/
│   │   │   │   │       │   │   └── [token]/
│   │   │   │   │       │   │       ├── layout.tsx
│   │   │   │   │       │   │       └── page.tsx
│   │   │   │   │       │   └── verify/
│   │   │   │   │       │       └── [token]/
│   │   │   │   │       │           ├── layout.tsx
│   │   │   │   │       │           └── page.tsx
│   │   │   │   │       └── layout.tsx
│   │   │   │   ├── api/
│   │   │   │   │   ├── auth/
│   │   │   │   │   │   └── [...nextauth]/
│   │   │   │   │   │       └── route.ts
│   │   │   │   │   └── trpc/
│   │   │   │   │       ├── edge/
│   │   │   │   │       │   └── [trpc]/
│   │   │   │   │       │       └── route.ts
│   │   │   │   │       └── lambda/
│   │   │   │   │           └── [trpc]/
│   │   │   │   │               └── route.ts
│   │   │   │   ├── global-error.tsx
│   │   │   │   ├── globals.css
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── metadata.ts
│   │   │   │   ├── not-found.tsx
│   │   │   │   └── react-table.d.ts
│   │   │   ├── components/
│   │   │   │   ├── button/
│   │   │   │   │   ├── button-back.tsx
│   │   │   │   │   └── button-copy-link.tsx
│   │   │   │   ├── chart/
│   │   │   │   │   ├── chart-area-percentiles.tsx
│   │   │   │   │   ├── chart-bar-uptime.tsx
│   │   │   │   │   ├── chart-legend-badge.tsx
│   │   │   │   │   ├── chart-line-region.tsx
│   │   │   │   │   ├── chart-line-regions.tsx
│   │   │   │   │   └── chart-tooltip-number.tsx
│   │   │   │   ├── common/
│   │   │   │   │   ├── kbd.tsx
│   │   │   │   │   └── link.tsx
│   │   │   │   ├── content/
│   │   │   │   │   ├── empty-state.tsx
│   │   │   │   │   ├── metric-card.tsx
│   │   │   │   │   ├── process-message.tsx
│   │   │   │   │   ├── section.tsx
│   │   │   │   │   └── timestamp-hover-card.tsx
│   │   │   │   ├── date-picker.tsx
│   │   │   │   ├── forms/
│   │   │   │   │   ├── form-card.tsx
│   │   │   │   │   ├── form-email.tsx
│   │   │   │   │   ├── form-manage-subscription.tsx
│   │   │   │   │   ├── form-password.tsx
│   │   │   │   │   └── form-subscribe-email.tsx
│   │   │   │   ├── icons/
│   │   │   │   │   ├── discord.tsx
│   │   │   │   │   ├── github.tsx
│   │   │   │   │   ├── google.tsx
│   │   │   │   │   ├── opsgenie.tsx
│   │   │   │   │   ├── pagerduty.tsx
│   │   │   │   │   └── slack.tsx
│   │   │   │   ├── nav/
│   │   │   │   │   ├── footer.tsx
│   │   │   │   │   └── header.tsx
│   │   │   │   ├── password-wrapper.tsx
│   │   │   │   ├── popover/
│   │   │   │   │   └── popover-quantile.tsx
│   │   │   │   ├── status-page/
│   │   │   │   │   ├── floating-button.tsx
│   │   │   │   │   ├── floating-theme.tsx
│   │   │   │   │   ├── messages.ts
│   │   │   │   │   ├── status-banner.tsx
│   │   │   │   │   ├── status-blank.tsx
│   │   │   │   │   ├── status-charts.tsx
│   │   │   │   │   ├── status-events.tsx
│   │   │   │   │   ├── status-feed.tsx
│   │   │   │   │   ├── status-monitor-tabs.tsx
│   │   │   │   │   ├── status-monitor.tsx
│   │   │   │   │   ├── status-tracker-group.tsx
│   │   │   │   │   ├── status-tracker.tsx
│   │   │   │   │   ├── status-updates.tsx
│   │   │   │   │   ├── status.tsx
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── tailwind-indicator.tsx
│   │   │   │   ├── themes/
│   │   │   │   │   ├── theme-dropdown.tsx
│   │   │   │   │   ├── theme-palette-picker.tsx
│   │   │   │   │   ├── theme-provider.tsx
│   │   │   │   │   ├── theme-select.tsx
│   │   │   │   │   └── theme-sidebar.tsx
│   │   │   │   └── ui/
│   │   │   │       └── data-table/
│   │   │   │           ├── data-table-action-bar.tsx
│   │   │   │           ├── data-table-column-header.tsx
│   │   │   │           ├── data-table-faceted-filter.tsx
│   │   │   │           ├── data-table-pagination.tsx
│   │   │   │           ├── data-table-skeleton.tsx
│   │   │   │           ├── data-table-toobar.tsx
│   │   │   │           ├── data-table-view-options.tsx
│   │   │   │           └── data-table.tsx
│   │   │   ├── data/
│   │   │   │   ├── icons.ts
│   │   │   │   ├── incidents.client.ts
│   │   │   │   ├── incidents.ts
│   │   │   │   ├── invitations.ts
│   │   │   │   ├── maintenances.client.ts
│   │   │   │   ├── maintenances.ts
│   │   │   │   ├── members.ts
│   │   │   │   ├── metrics.client.ts
│   │   │   │   ├── monitor-tags.ts
│   │   │   │   ├── monitors.client.ts
│   │   │   │   ├── monitors.ts
│   │   │   │   ├── plans.ts
│   │   │   │   ├── region-metrics.client.ts
│   │   │   │   ├── region-metrics.ts
│   │   │   │   ├── region-percentile.ts
│   │   │   │   ├── regions.ts
│   │   │   │   ├── response-logs.ts
│   │   │   │   ├── status-codes.ts
│   │   │   │   ├── status-pages.client.ts
│   │   │   │   ├── status-pages.ts
│   │   │   │   ├── status-report-updates.client.ts
│   │   │   │   ├── status-reports.client.ts
│   │   │   │   └── status-reports.ts
│   │   │   ├── hooks/
│   │   │   │   └── use-pathname-prefix.ts
│   │   │   ├── instrumentation.ts
│   │   │   ├── lib/
│   │   │   │   ├── auth/
│   │   │   │   │   ├── adapter.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── providers.ts
│   │   │   │   ├── base-url.ts
│   │   │   │   ├── chart.ts
│   │   │   │   ├── composition.ts
│   │   │   │   ├── domain.ts
│   │   │   │   ├── formatter.ts
│   │   │   │   ├── protected.ts
│   │   │   │   ├── server-actions.ts
│   │   │   │   ├── trpc/
│   │   │   │   │   ├── client.tsx
│   │   │   │   │   ├── query-client.ts
│   │   │   │   │   ├── server.tsx
│   │   │   │   │   └── shared.ts
│   │   │   │   └── utils.ts
│   │   │   ├── next-auth.d.ts
│   │   │   └── proxy.ts
│   │   ├── tsconfig.json
│   │   └── turbo.json
│   ├── web/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── components.json
│   │   ├── env.ts
│   │   ├── instrumentation-client.ts
│   │   ├── next-env.d.ts
│   │   ├── next.config.ts
│   │   ├── package.json
│   │   ├── postcss.config.js
│   │   ├── public/
│   │   │   ├── assets/
│   │   │   │   └── posts/
│   │   │   │       ├── global-latency-monitoring-benchmark-hono-hetzner/
│   │   │   │       │   └── hetzner.json
│   │   │   │       ├── hono-vercel-fluid-compute/
│   │   │   │       │   ├── hono-cold.json
│   │   │   │       │   └── hono-warm.json
│   │   │   │       ├── monitoring-latency/
│   │   │   │       │   ├── cloudflare.json
│   │   │   │       │   ├── fly.json
│   │   │   │       │   ├── koyeb.json
│   │   │   │       │   ├── railway.json
│   │   │   │       │   └── render.json
│   │   │   │       └── monitoring-vercel/
│   │   │   │           ├── vercel-cold.json
│   │   │   │           ├── vercel-edge.json
│   │   │   │           ├── vercel-roulette.json
│   │   │   │           └── vercel-warm.json
│   │   │   └── llms.txt
│   │   ├── sentry.edge.config.ts
│   │   ├── sentry.server.config.ts
│   │   ├── src/
│   │   │   ├── app/
│   │   │   │   ├── (landing)/
│   │   │   │   │   ├── (redirect)/
│   │   │   │   │   │   ├── bsky/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── cal/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── discord/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── docs/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── github/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── linkedin/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── schema.json/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── twitter/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   └── youtube/
│   │   │   │   │   │       └── page.tsx
│   │   │   │   │   ├── [slug]/
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── blog/
│   │   │   │   │   │   ├── [slug]/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── category/
│   │   │   │   │   │   │   ├── [slug]/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── feed.xml/
│   │   │   │   │   │   │   └── route.ts
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── changelog/
│   │   │   │   │   │   ├── [slug]/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── category/
│   │   │   │   │   │   │   ├── [slug]/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── feed.xml/
│   │   │   │   │   │   │   └── route.ts
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── compare/
│   │   │   │   │   │   ├── [slug]/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── content-box.tsx
│   │   │   │   │   ├── content-category.tsx
│   │   │   │   │   ├── content-list.tsx
│   │   │   │   │   ├── content-metadata.tsx
│   │   │   │   │   ├── content-pagination.tsx
│   │   │   │   │   ├── guides/
│   │   │   │   │   │   ├── [slug]/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── category/
│   │   │   │   │   │   │   ├── [slug]/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   ├── oss-friends/
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── page.tsx
│   │   │   │   │   ├── play/
│   │   │   │   │   │   ├── checker/
│   │   │   │   │   │   │   ├── [slug]/
│   │   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── api/
│   │   │   │   │   │   │   │   └── route.ts
│   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   ├── search-params.ts
│   │   │   │   │   │   │   └── utils.ts
│   │   │   │   │   │   ├── curl/
│   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   ├── severity-matrix/
│   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   └── uptime-sla/
│   │   │   │   │   │       ├── client.tsx
│   │   │   │   │   │       └── page.tsx
│   │   │   │   │   ├── status/
│   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   └── utils.ts
│   │   │   │   │   └── use-case/
│   │   │   │   │       ├── [slug]/
│   │   │   │   │       │   └── page.tsx
│   │   │   │   │       └── page.tsx
│   │   │   │   ├── api/
│   │   │   │   │   ├── callback/
│   │   │   │   │   │   └── pagerduty/
│   │   │   │   │   │       └── route.ts
│   │   │   │   │   ├── checker/
│   │   │   │   │   │   ├── cron/
│   │   │   │   │   │   │   ├── 10m/
│   │   │   │   │   │   │   │   └── route.ts
│   │   │   │   │   │   │   ├── 1h/
│   │   │   │   │   │   │   │   └── route.ts
│   │   │   │   │   │   │   ├── 1m/
│   │   │   │   │   │   │   │   └── route.ts
│   │   │   │   │   │   │   ├── 30m/
│   │   │   │   │   │   │   │   └── route.ts
│   │   │   │   │   │   │   ├── 30s/
│   │   │   │   │   │   │   │   └── route.ts
│   │   │   │   │   │   │   ├── 5m/
│   │   │   │   │   │   │   │   └── route.ts
│   │   │   │   │   │   │   ├── _cron.ts
│   │   │   │   │   │   │   └── _sentry.ts
│   │   │   │   │   │   ├── test/
│   │   │   │   │   │   │   ├── http/
│   │   │   │   │   │   │   │   └── route.ts
│   │   │   │   │   │   │   └── tcp/
│   │   │   │   │   │   │       ├── route.ts
│   │   │   │   │   │   │       └── schema.ts
│   │   │   │   │   │   └── utils.ts
│   │   │   │   │   ├── internal/
│   │   │   │   │   │   └── email/
│   │   │   │   │   │       ├── feedback/
│   │   │   │   │   │       │   └── route.ts
│   │   │   │   │   │       ├── route.ts
│   │   │   │   │   │       └── team-invite/
│   │   │   │   │   │           └── route.ts
│   │   │   │   │   ├── markdown/
│   │   │   │   │   │   └── [[...path]]/
│   │   │   │   │   │       └── route.ts
│   │   │   │   │   ├── og/
│   │   │   │   │   │   ├── _components/
│   │   │   │   │   │   │   ├── background.tsx
│   │   │   │   │   │   │   ├── basic-layout.tsx
│   │   │   │   │   │   │   ├── status-check.tsx
│   │   │   │   │   │   │   └── tracker.tsx
│   │   │   │   │   │   ├── checker/
│   │   │   │   │   │   │   └── route.tsx
│   │   │   │   │   │   ├── monitor/
│   │   │   │   │   │   │   └── route.tsx
│   │   │   │   │   │   ├── page/
│   │   │   │   │   │   │   └── route.tsx
│   │   │   │   │   │   ├── post/
│   │   │   │   │   │   │   └── route.tsx
│   │   │   │   │   │   ├── route.tsx
│   │   │   │   │   │   ├── status/
│   │   │   │   │   │   │   └── route.tsx
│   │   │   │   │   │   └── utils.ts
│   │   │   │   │   ├── search/
│   │   │   │   │   │   └── route.ts
│   │   │   │   │   ├── test/
│   │   │   │   │   │   └── timeout/
│   │   │   │   │   │       └── route.ts
│   │   │   │   │   ├── trpc/
│   │   │   │   │   │   ├── edge/
│   │   │   │   │   │   │   └── [trpc]/
│   │   │   │   │   │   │       └── route.ts
│   │   │   │   │   │   └── lambda/
│   │   │   │   │   │       └── [trpc]/
│   │   │   │   │   │           └── route.ts
│   │   │   │   │   ├── upload/
│   │   │   │   │   │   └── route.ts
│   │   │   │   │   └── webhook/
│   │   │   │   │       └── stripe/
│   │   │   │   │           └── route.ts
│   │   │   │   ├── global-error.tsx
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── not-found.tsx
│   │   │   │   ├── robots.ts
│   │   │   │   └── sitemap.ts
│   │   │   ├── components/
│   │   │   │   ├── dev-mode-container.tsx
│   │   │   │   ├── icon-cloud-provider.tsx
│   │   │   │   ├── icons.tsx
│   │   │   │   ├── loading-animation.tsx
│   │   │   │   ├── tailwind-indicator.tsx
│   │   │   │   └── theme-provider.tsx
│   │   │   ├── config/
│   │   │   │   └── socials.ts
│   │   │   ├── content/
│   │   │   │   ├── cmdk.tsx
│   │   │   │   ├── component-highlighter.tsx
│   │   │   │   ├── convert.ts
│   │   │   │   ├── copy-button.tsx
│   │   │   │   ├── footer-status.tsx
│   │   │   │   ├── footer.tsx
│   │   │   │   ├── header.tsx
│   │   │   │   ├── highlight-text.tsx
│   │   │   │   ├── image-zoom.tsx
│   │   │   │   ├── latency-chart-table.tsx
│   │   │   │   ├── link.tsx
│   │   │   │   ├── listing.ts
│   │   │   │   ├── logo-with-context-menu.tsx
│   │   │   │   ├── mdx-components/
│   │   │   │   │   ├── button-link.tsx
│   │   │   │   │   ├── code.tsx
│   │   │   │   │   ├── custom-image.tsx
│   │   │   │   │   ├── custom-link.tsx
│   │   │   │   │   ├── details.tsx
│   │   │   │   │   ├── grid.tsx
│   │   │   │   │   ├── heading.tsx
│   │   │   │   │   ├── index.tsx
│   │   │   │   │   ├── pre.tsx
│   │   │   │   │   ├── status-page-example.tsx
│   │   │   │   │   ├── table.tsx
│   │   │   │   │   └── tweet.tsx
│   │   │   │   ├── mdx.tsx
│   │   │   │   ├── nav.tsx
│   │   │   │   ├── pages/
│   │   │   │   │   ├── blog/
│   │   │   │   │   │   ├── 2023-year-review.mdx
│   │   │   │   │   │   ├── 2026-roadmap.mdx
│   │   │   │   │   │   ├── data-table-redesign.mdx
│   │   │   │   │   │   ├── deploy-private-locations-raspberry-pi.mdx
│   │   │   │   │   │   ├── dynamic-breadcrumb-nextjs.mdx
│   │   │   │   │   │   ├── event-analytics-implementation.mdx
│   │   │   │   │   │   ├── global-latency-monitoring-benchmark-hono-hetzner.mdx
│   │   │   │   │   │   ├── hono-vercel-fluid-compute.mdx
│   │   │   │   │   │   ├── how-we-build-our-github-action.mdx
│   │   │   │   │   │   ├── introducing-goatstack.mdx
│   │   │   │   │   │   ├── introducing-openstatus-cli.mdx
│   │   │   │   │   │   ├── introducing-status-page-theme-explorer.mdx
│   │   │   │   │   │   ├── live-mode-infinite-query.mdx
│   │   │   │   │   │   ├── migrating-from-zod-openapi-to-connectrpc.mdx
│   │   │   │   │   │   ├── migration-auth-clerk-to-next-auth.mdx
│   │   │   │   │   │   ├── migration-backend-from-vercel-to-fly.mdx
│   │   │   │   │   │   ├── migration-planetscale-to-turso.mdx
│   │   │   │   │   │   ├── monitoring-latency-cf-workers-fly-koyeb-raylway-render.mdx
│   │   │   │   │   │   ├── monitoring-latency-vercel-edge-vs-serverless.mdx
│   │   │   │   │   │   ├── new-dashboard-we-are-so-back.mdx
│   │   │   │   │   │   ├── nobody-should-hand-code-a-data-table.mdx
│   │   │   │   │   │   ├── openstatus-infra.mdx
│   │   │   │   │   │   ├── openstatus-light-viewer.mdx
│   │   │   │   │   │   ├── openstatus-slack-agent.mdx
│   │   │   │   │   │   ├── our-new-pricing-explained.mdx
│   │   │   │   │   │   ├── our-producthunt-launch-brutal-reality.mdx
│   │   │   │   │   │   ├── pricing-update-july-2024.mdx
│   │   │   │   │   │   ├── product-strategy-a-reality-check.mdx
│   │   │   │   │   │   ├── q1-2024-update.mdx
│   │   │   │   │   │   ├── reflecting-1-year-building-openstatus.mdx
│   │   │   │   │   │   ├── rss-app-slack-feed.mdx
│   │   │   │   │   │   ├── same-pricing-more-monitors.mdx
│   │   │   │   │   │   ├── secure-api-with-unkey.mdx
│   │   │   │   │   │   ├── shadcn-component-registry.mdx
│   │   │   │   │   │   ├── status-page-addons.mdx
│   │   │   │   │   │   ├── status-page-components.mdx
│   │   │   │   │   │   ├── status-pages-is-politics.mdx
│   │   │   │   │   │   ├── telegram-group-qr-integration.mdx
│   │   │   │   │   │   ├── the-first-48-hours.mdx
│   │   │   │   │   │   └── vision-2025.mdx
│   │   │   │   │   ├── changelog/
│   │   │   │   │   │   ├── auto-resolved-incidents.mdx
│   │   │   │   │   │   ├── binary-payload.mdx
│   │   │   │   │   │   ├── check-run-api.mdx
│   │   │   │   │   │   ├── checker-playground.mdx
│   │   │   │   │   │   ├── cli-import-apply.mdx
│   │   │   │   │   │   ├── cli-improvement.mdx
│   │   │   │   │   │   ├── cli-monitor-template.mdx
│   │   │   │   │   │   ├── clone-monitor.mdx
│   │   │   │   │   │   ├── curl-builder-playground.mdx
│   │   │   │   │   │   ├── dark-theme-support.mdx
│   │   │   │   │   │   ├── dashboard-metrics-card.mdx
│   │   │   │   │   │   ├── dns-monitoring.mdx
│   │   │   │   │   │   ├── docker-checker.mdx
│   │   │   │   │   │   ├── follow-redirect.mdx
│   │   │   │   │   │   ├── github-action.mdx
│   │   │   │   │   │   ├── global-speed-checker-skills.mdx
│   │   │   │   │   │   ├── golang-monitor-checker.mdx
│   │   │   │   │   │   ├── google-chat-notifications.mdx
│   │   │   │   │   │   ├── grafana-oncall-integration.mdx
│   │   │   │   │   │   ├── grouped-monitors.mdx
│   │   │   │   │   │   ├── individual-status-report-page.mdx
│   │   │   │   │   │   ├── json-status-page.mdx
│   │   │   │   │   │   ├── latency-quantiles.mdx
│   │   │   │   │   │   ├── maintenance-status.mdx
│   │   │   │   │   │   ├── monitor-external-name.mdx
│   │   │   │   │   │   ├── monitor-tags.mdx
│   │   │   │   │   │   ├── monitor-threshold.mdx
│   │   │   │   │   │   ├── more-regions.mdx
│   │   │   │   │   │   ├── multi-cloud-fly-railway-koyeb.mdx
│   │   │   │   │   │   ├── multi-region-monitoring.mdx
│   │   │   │   │   │   ├── ntfy-sh-integration.mdx
│   │   │   │   │   │   ├── openstatus-cli.mdx
│   │   │   │   │   │   ├── openstatus-sdk.mdx
│   │   │   │   │   │   ├── opentelemetry.mdx
│   │   │   │   │   │   ├── pagerduty-integration.mdx
│   │   │   │   │   │   ├── password-protected-status-page.mdx
│   │   │   │   │   │   ├── play-checker-improvements.mdx
│   │   │   │   │   │   ├── private-location.mdx
│   │   │   │   │   │   ├── public-monitors.mdx
│   │   │   │   │   │   ├── raycast-integration.mdx
│   │   │   │   │   │   ├── request-assertions.mdx
│   │   │   │   │   │   ├── response-time-charts.mdx
│   │   │   │   │   │   ├── screenshot-incident.mdx
│   │   │   │   │   │   ├── slack-agent.mdx
│   │   │   │   │   │   ├── slack-discord-improvements.mdx
│   │   │   │   │   │   ├── slack-discord-notification.mdx
│   │   │   │   │   │   ├── sms-notification.mdx
│   │   │   │   │   │   ├── status-page-badge-v2.mdx
│   │   │   │   │   │   ├── status-page-badge.mdx
│   │   │   │   │   │   ├── status-page-colors-and-more.mdx
│   │   │   │   │   │   ├── status-page-component-subscription.mdx
│   │   │   │   │   │   ├── status-page-email-authentification.mdx
│   │   │   │   │   │   ├── status-page-feed.mdx
│   │   │   │   │   │   ├── status-page-monitor-order.mdx
│   │   │   │   │   │   ├── status-page-monitor-values-visibility.mdx
│   │   │   │   │   │   ├── status-page-redesign-beta.mdx
│   │   │   │   │   │   ├── status-page-slack-feed-subscribe.mdx
│   │   │   │   │   │   ├── status-page-subscribers.mdx
│   │   │   │   │   │   ├── status-page-unsubscribe.mdx
│   │   │   │   │   │   ├── status-page-white-label.mdx
│   │   │   │   │   │   ├── status-report-location-change.mdx
│   │   │   │   │   │   ├── status-update-subscriber.mdx
│   │   │   │   │   │   ├── status-widget.mdx
│   │   │   │   │   │   ├── tcp-monitoring.mdx
│   │   │   │   │   │   ├── team-invites.mdx
│   │   │   │   │   │   ├── telegram-bot-integration.mdx
│   │   │   │   │   │   ├── terraform-provider.mdx
│   │   │   │   │   │   ├── webhook-integration.mdx
│   │   │   │   │   │   └── whatsapp-notifications.mdx
│   │   │   │   │   ├── compare/
│   │   │   │   │   │   ├── atlassian-statuspage.mdx
│   │   │   │   │   │   ├── betterstack.mdx
│   │   │   │   │   │   ├── checkly.mdx
│   │   │   │   │   │   ├── incidentio.mdx
│   │   │   │   │   │   ├── instatus.mdx
│   │   │   │   │   │   ├── statusio.mdx
│   │   │   │   │   │   ├── uptime-kuma.mdx
│   │   │   │   │   │   └── uptime-robot.mdx
│   │   │   │   │   ├── guides/
│   │   │   │   │   │   ├── api-service-disruption.mdx
│   │   │   │   │   │   ├── best-opensource-status-page-2026.mdx
│   │   │   │   │   │   ├── boring-is-better-for-status-pages.mdx
│   │   │   │   │   │   ├── database-performance-degradation.mdx
│   │   │   │   │   │   ├── deployment-rollback.mdx
│   │   │   │   │   │   ├── feature-degradation.mdx
│   │   │   │   │   │   ├── http-headers.mdx
│   │   │   │   │   │   ├── incident-severity-matrix.mdx
│   │   │   │   │   │   ├── network-connectivity-issues.mdx
│   │   │   │   │   │   ├── public-postmortem-underrated-marketing.mdx
│   │   │   │   │   │   ├── public-vs-private-status-pages.mdx
│   │   │   │   │   │   ├── scheduled-maintenance.mdx
│   │   │   │   │   │   ├── security-incident-response.mdx
│   │   │   │   │   │   ├── sla-vs-slo-vs-sli.mdx
│   │   │   │   │   │   ├── top-five-atlassian-statuspage-alternatives.mdx
│   │   │   │   │   │   ├── why-every-saas-needs-a-status-page.mdx
│   │   │   │   │   │   └── why-uptime-percentage-is-misleading.mdx
│   │   │   │   │   ├── home.mdx
│   │   │   │   │   ├── product/
│   │   │   │   │   │   ├── status-page.mdx
│   │   │   │   │   │   └── uptime-monitoring.mdx
│   │   │   │   │   ├── tools/
│   │   │   │   │   │   ├── checker-slug.mdx
│   │   │   │   │   │   ├── checker.mdx
│   │   │   │   │   │   ├── curl.mdx
│   │   │   │   │   │   ├── severity-matrix.mdx
│   │   │   │   │   │   └── uptime-sla.mdx
│   │   │   │   │   ├── unrelated/
│   │   │   │   │   │   ├── about.mdx
│   │   │   │   │   │   ├── not-found.mdx
│   │   │   │   │   │   ├── pricing.mdx
│   │   │   │   │   │   ├── privacy.mdx
│   │   │   │   │   │   ├── registry.mdx
│   │   │   │   │   │   ├── subprocessors.mdx
│   │   │   │   │   │   └── terms.mdx
│   │   │   │   │   └── use-case/
│   │   │   │   │       ├── api-providers.mdx
│   │   │   │   │       ├── compliance.mdx
│   │   │   │   │       ├── crypto.mdx
│   │   │   │   │       └── open-source.mdx
│   │   │   │   ├── resolve.ts
│   │   │   │   ├── shadcn-registry-example.tsx
│   │   │   │   ├── simple-chart.tsx
│   │   │   │   ├── sub-nav.tsx
│   │   │   │   ├── theme-toggle.tsx
│   │   │   │   └── utils.ts
│   │   │   ├── data/
│   │   │   │   ├── author.ts
│   │   │   │   ├── code-dictionary.ts
│   │   │   │   ├── content.ts
│   │   │   │   ├── incidents-dictionary.ts
│   │   │   │   └── trigger-dictionary.ts
│   │   │   ├── env.ts
│   │   │   ├── instrumentation.ts
│   │   │   ├── lib/
│   │   │   │   ├── checker/
│   │   │   │   │   ├── mock.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── domains.ts
│   │   │   │   ├── github.ts
│   │   │   │   ├── image-dimensions.ts
│   │   │   │   ├── maintenances/
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── metadata/
│   │   │   │   │   ├── shared-metadata.ts
│   │   │   │   │   └── structured-data.ts
│   │   │   │   ├── monitor/
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── preferred-settings/
│   │   │   │   │   ├── client.ts
│   │   │   │   │   ├── server.ts
│   │   │   │   │   ├── shared.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── ratelimit.ts
│   │   │   │   ├── stream.ts
│   │   │   │   ├── stripe/
│   │   │   │   │   └── client.ts
│   │   │   │   ├── tb.ts
│   │   │   │   ├── timezone.ts
│   │   │   │   ├── toast.tsx
│   │   │   │   └── utils.ts
│   │   │   ├── public/
│   │   │   │   └── fonts/
│   │   │   │       ├── CommitMono-400-Italic.otf
│   │   │   │       ├── CommitMono-400-Regular.otf
│   │   │   │       ├── CommitMono-700-Italic.otf
│   │   │   │       └── CommitMono-700-Regular.otf
│   │   │   ├── react-table.d.ts
│   │   │   ├── styles/
│   │   │   │   └── globals.css
│   │   │   ├── trpc/
│   │   │   │   ├── client.ts
│   │   │   │   ├── query-client.ts
│   │   │   │   ├── rq-client.tsx
│   │   │   │   ├── rq-server.ts
│   │   │   │   ├── server.ts
│   │   │   │   └── shared.ts
│   │   │   └── types/
│   │   │       └── utils.ts
│   │   ├── tsconfig.json
│   │   ├── turbo.json
│   │   └── vercel.json
│   └── workflows/
│       ├── .dockerignore
│       ├── .gitignore
│       ├── Dockerfile
│       ├── README.md
│       ├── docker-compose.yaml
│       ├── dofigen.yml
│       ├── fly.toml
│       ├── package.json
│       ├── src/
│       │   ├── build-docker.ts
│       │   ├── checker/
│       │   │   ├── alerting.test.ts
│       │   │   ├── alerting.ts
│       │   │   ├── index.ts
│       │   │   └── utils.ts
│       │   ├── cron/
│       │   │   ├── checker.ts
│       │   │   ├── emails.ts
│       │   │   ├── index.ts
│       │   │   └── monitor.ts
│       │   ├── env.ts
│       │   ├── incident/
│       │   │   └── index.ts
│       │   ├── index.ts
│       │   ├── lib/
│       │   │   └── db.ts
│       │   ├── scripts/
│       │   │   └── tinybird.ts
│       │   └── utils/
│       │       └── audit-log.ts
│       ├── start.sh
│       └── tsconfig.json
├── biome.jsonc
├── bunfig.toml
├── config.openstatus.yaml
├── coolify-deployment.yaml
├── devbox.json
├── docker-compose-lightweight.yaml
├── docker-compose.github-packages.yaml
├── docker-compose.yaml
├── infra/
│   └── openstatus.yaml
├── knip.ts
├── package.json
├── packages/
│   ├── analytics/
│   │   ├── env.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── events.ts
│   │   │   ├── index.ts
│   │   │   ├── server.ts
│   │   │   └── utils.ts
│   │   └── tsconfig.json
│   ├── api/
│   │   ├── env.ts
│   │   ├── index.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── edge.ts
│   │   │   ├── env.ts
│   │   │   ├── lambda.ts
│   │   │   ├── root.ts
│   │   │   ├── router/
│   │   │   │   ├── apiKey.ts
│   │   │   │   ├── blob.ts
│   │   │   │   ├── checker.ts
│   │   │   │   ├── domain.ts
│   │   │   │   ├── email/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── feedback.ts
│   │   │   │   ├── import.test.ts
│   │   │   │   ├── import.ts
│   │   │   │   ├── incident.ts
│   │   │   │   ├── integration.ts
│   │   │   │   ├── invitation.ts
│   │   │   │   ├── maintenance.test.ts
│   │   │   │   ├── maintenance.ts
│   │   │   │   ├── member.ts
│   │   │   │   ├── monitor.test.ts
│   │   │   │   ├── monitor.ts
│   │   │   │   ├── monitorTag.ts
│   │   │   │   ├── notification.test.ts
│   │   │   │   ├── notification.ts
│   │   │   │   ├── page.ts
│   │   │   │   ├── pageComponent.test.ts
│   │   │   │   ├── pageComponent.ts
│   │   │   │   ├── pageSubscriber.ts
│   │   │   │   ├── privateLocation.test.ts
│   │   │   │   ├── privateLocation.ts
│   │   │   │   ├── statusPage.e2e.test.ts
│   │   │   │   ├── statusPage.ts
│   │   │   │   ├── statusPage.unsubscribe.test.ts
│   │   │   │   ├── statusPage.utils.test.ts
│   │   │   │   ├── statusPage.utils.ts
│   │   │   │   ├── statusReport.test.ts
│   │   │   │   ├── statusReport.ts
│   │   │   │   ├── stripe/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── shared.ts
│   │   │   │   │   ├── utils.ts
│   │   │   │   │   └── webhook.ts
│   │   │   │   ├── tinybird/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── user.ts
│   │   │   │   ├── utils.ts
│   │   │   │   ├── workspace.test.ts
│   │   │   │   └── workspace.ts
│   │   │   ├── service/
│   │   │   │   ├── apiKey.test.ts
│   │   │   │   ├── apiKey.ts
│   │   │   │   ├── import.test.ts
│   │   │   │   ├── import.ts
│   │   │   │   └── telegram-updates.ts
│   │   │   ├── test/
│   │   │   │   └── preload.ts
│   │   │   └── trpc.ts
│   │   └── tsconfig.json
│   ├── assertions/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── dictionary.ts
│   │   │   ├── index.ts
│   │   │   ├── serializing.ts
│   │   │   ├── type-guards.ts
│   │   │   ├── types.ts
│   │   │   └── v1.ts
│   │   └── tsconfig.json
│   ├── db/
│   │   ├── README.md
│   │   ├── drizzle/
│   │   │   ├── 0000_lively_master_chief.sql
│   │   │   ├── 0001_brainy_beast.sql
│   │   │   ├── 0002_luxuriant_ser_duncan.sql
│   │   │   ├── 0003_glamorous_living_mummy.sql
│   │   │   ├── 0004_fixed_dakota_north.sql
│   │   │   ├── 0005_even_baron_strucker.sql
│   │   │   ├── 0006_tired_anita_blake.sql
│   │   │   ├── 0007_complex_frog_thor.sql
│   │   │   ├── 0008_overjoyed_sunset_bain.sql
│   │   │   ├── 0009_small_maximus.sql
│   │   │   ├── 0010_lame_songbird.sql
│   │   │   ├── 0011_bright_jazinda.sql
│   │   │   ├── 0012_tan_magma.sql
│   │   │   ├── 0013_tired_paladin.sql
│   │   │   ├── 0014_adorable_skaar.sql
│   │   │   ├── 0015_bent_sister_grimm.sql
│   │   │   ├── 0016_certain_praxagora.sql
│   │   │   ├── 0017_loose_maggott.sql
│   │   │   ├── 0018_neat_orphan.sql
│   │   │   ├── 0019_dashing_malcolm_colcord.sql
│   │   │   ├── 0020_flat_bedlam.sql
│   │   │   ├── 0021_reflective_nico_minoru.sql
│   │   │   ├── 0022_chunky_rockslide.sql
│   │   │   ├── 0023_dry_blink.sql
│   │   │   ├── 0024_young_proudstar.sql
│   │   │   ├── 0025_strong_thunderball.sql
│   │   │   ├── 0026_giant_absorbing_man.sql
│   │   │   ├── 0027_bizarre_bastion.sql
│   │   │   ├── 0028_thin_power_pack.sql
│   │   │   ├── 0029_regular_marrow.sql
│   │   │   ├── 0030_elite_barracuda.sql
│   │   │   ├── 0031_lowly_gabe_jones.sql
│   │   │   ├── 0032_hot_swordsman.sql
│   │   │   ├── 0033_solid_colossus.sql
│   │   │   ├── 0034_serious_shard.sql
│   │   │   ├── 0035_open_the_professor.sql
│   │   │   ├── 0036_gifted_deathbird.sql
│   │   │   ├── 0037_equal_beyonder.sql
│   │   │   ├── 0038_foamy_stardust.sql
│   │   │   ├── 0039_lonely_jigsaw.sql
│   │   │   ├── 0040_narrow_anthem.sql
│   │   │   ├── 0041_nasty_jigsaw.sql
│   │   │   ├── 0042_great_epoch.sql
│   │   │   ├── 0043_low_lily_hollister.sql
│   │   │   ├── 0044_illegal_turbo.sql
│   │   │   ├── 0045_little_paladin.sql
│   │   │   ├── 0046_lucky_tarantula.sql
│   │   │   ├── 0047_nifty_roughhouse.sql
│   │   │   ├── 0048_neat_tempest.sql
│   │   │   ├── 0049_sloppy_inhumans.sql
│   │   │   ├── 0050_damp_xorn.sql
│   │   │   ├── 0051_fuzzy_red_hulk.sql
│   │   │   ├── 0052_illegal_killraven.sql
│   │   │   ├── 0053_dark_orphan.sql
│   │   │   ├── 0054_bitter_lilandra.sql
│   │   │   ├── 0055_spicy_bastion.sql
│   │   │   ├── 0056_violet_shotgun.sql
│   │   │   ├── 0057_curious_xorn.sql
│   │   │   ├── 0058_absent_chameleon.sql
│   │   │   └── meta/
│   │   │       ├── 0000_snapshot.json
│   │   │       ├── 0001_snapshot.json
│   │   │       ├── 0002_snapshot.json
│   │   │       ├── 0003_snapshot.json
│   │   │       ├── 0004_snapshot.json
│   │   │       ├── 0005_snapshot.json
│   │   │       ├── 0006_snapshot.json
│   │   │       ├── 0007_snapshot.json
│   │   │       ├── 0008_snapshot.json
│   │   │       ├── 0009_snapshot.json
│   │   │       ├── 0010_snapshot.json
│   │   │       ├── 0011_snapshot.json
│   │   │       ├── 0012_snapshot.json
│   │   │       ├── 0013_snapshot.json
│   │   │       ├── 0014_snapshot.json
│   │   │       ├── 0015_snapshot.json
│   │   │       ├── 0016_snapshot.json
│   │   │       ├── 0017_snapshot.json
│   │   │       ├── 0018_snapshot.json
│   │   │       ├── 0019_snapshot.json
│   │   │       ├── 0020_snapshot.json
│   │   │       ├── 0021_snapshot.json
│   │   │       ├── 0022_snapshot.json
│   │   │       ├── 0023_snapshot.json
│   │   │       ├── 0024_snapshot.json
│   │   │       ├── 0025_snapshot.json
│   │   │       ├── 0026_snapshot.json
│   │   │       ├── 0027_snapshot.json
│   │   │       ├── 0028_snapshot.json
│   │   │       ├── 0029_snapshot.json
│   │   │       ├── 0030_snapshot.json
│   │   │       ├── 0031_snapshot.json
│   │   │       ├── 0032_snapshot.json
│   │   │       ├── 0033_snapshot.json
│   │   │       ├── 0034_snapshot.json
│   │   │       ├── 0035_snapshot.json
│   │   │       ├── 0036_snapshot.json
│   │   │       ├── 0037_snapshot.json
│   │   │       ├── 0038_snapshot.json
│   │   │       ├── 0039_snapshot.json
│   │   │       ├── 0040_snapshot.json
│   │   │       ├── 0041_snapshot.json
│   │   │       ├── 0042_snapshot.json
│   │   │       ├── 0043_snapshot.json
│   │   │       ├── 0044_snapshot.json
│   │   │       ├── 0045_snapshot.json
│   │   │       ├── 0046_snapshot.json
│   │   │       ├── 0047_snapshot.json
│   │   │       ├── 0048_snapshot.json
│   │   │       ├── 0049_snapshot.json
│   │   │       ├── 0050_snapshot.json
│   │   │       ├── 0051_snapshot.json
│   │   │       ├── 0052_snapshot.json
│   │   │       ├── 0053_snapshot.json
│   │   │       ├── 0054_snapshot.json
│   │   │       ├── 0055_snapshot.json
│   │   │       ├── 0056_snapshot.json
│   │   │       ├── 0057_snapshot.json
│   │   │       ├── 0058_snapshot.json
│   │   │       └── _journal.json
│   │   ├── drizzle.config.ts
│   │   ├── env.mjs
│   │   ├── env.ts
│   │   ├── package.json
│   │   ├── script/
│   │   │   ├── region-migration.test.ts
│   │   │   └── region-migration.ts
│   │   ├── src/
│   │   │   ├── db.ts
│   │   │   ├── index.ts
│   │   │   ├── migrate.mts
│   │   │   ├── schema/
│   │   │   │   ├── api-keys/
│   │   │   │   │   ├── api_key.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── applications/
│   │   │   │   │   ├── application.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── check/
│   │   │   │   │   ├── check.ts
│   │   │   │   │   ├── constants.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── constants.ts
│   │   │   │   ├── incidents/
│   │   │   │   │   ├── incident.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── integration.ts
│   │   │   │   ├── invitations/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── invitation.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── maintenances/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── maintenance.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── monitor_groups/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── monitor_group.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── monitor_run/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── monitor_run.ts
│   │   │   │   ├── monitor_status/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── monitor_status.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── monitor_tags/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── monitor_tag.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── monitors/
│   │   │   │   │   ├── constants.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── monitor.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── notifications/
│   │   │   │   │   ├── constants.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── notification.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── page_component_groups/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── page_component_groups.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── page_components/
│   │   │   │   │   ├── constants.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── page_components.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── page_subscribers/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── page_subscriber_to_page_component.ts
│   │   │   │   │   ├── page_subscribers.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── pages/
│   │   │   │   │   ├── constants.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── page.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── plan/
│   │   │   │   │   ├── config.ts
│   │   │   │   │   ├── schema.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── private_locations/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── private_locations.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── shared.ts
│   │   │   │   ├── status_reports/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── status_reports.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── users/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── user.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── viewers/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── validation.ts
│   │   │   │   │   └── viewer.ts
│   │   │   │   └── workspaces/
│   │   │   │       ├── constants.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── validation.ts
│   │   │   │       └── workspace.ts
│   │   │   ├── seed.mts
│   │   │   ├── sync-db.ts
│   │   │   └── utils/
│   │   │       ├── api-key.test.ts
│   │   │       ├── api-key.ts
│   │   │       └── index.ts
│   │   └── tsconfig.json
│   ├── emails/
│   │   ├── emails/
│   │   │   ├── _components/
│   │   │   │   ├── footer.tsx
│   │   │   │   ├── layout.tsx
│   │   │   │   └── styles.ts
│   │   │   ├── feedback.tsx
│   │   │   ├── followup.tsx
│   │   │   ├── monitor-alert.tsx
│   │   │   ├── monitor-deactivation.tsx
│   │   │   ├── monitor-paused.tsx
│   │   │   ├── page-subscription.tsx
│   │   │   ├── slack-feedback.tsx
│   │   │   ├── status-page-magic-link.tsx
│   │   │   ├── status-report.tsx
│   │   │   ├── subscribe.tsx
│   │   │   ├── team-invitation.tsx
│   │   │   ├── team-invite-reminder.tsx
│   │   │   └── welcome.tsx
│   │   ├── hotfix/
│   │   │   ├── monitor-alert.ts
│   │   │   ├── monitor-deactivation.ts
│   │   │   └── monitor-paused.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── client.integration.test.tsx
│   │   │   ├── client.tsx
│   │   │   ├── env.ts
│   │   │   ├── index.ts
│   │   │   ├── send.ts
│   │   │   └── utils.ts
│   │   └── tsconfig.json
│   ├── error/
│   │   ├── index.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── base-error.ts
│   │   │   ├── error-code.ts
│   │   │   ├── http-error.ts
│   │   │   ├── schema-error.ts
│   │   │   └── utils.ts
│   │   └── tsconfig.json
│   ├── header-analysis/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── index.ts
│   │   │   ├── parser/
│   │   │   │   ├── cache-control.ts
│   │   │   │   ├── cf-cache-status.ts
│   │   │   │   ├── cf-ray.ts
│   │   │   │   ├── fly-request-id.ts
│   │   │   │   ├── x-vercel-cache.ts
│   │   │   │   └── x-vercel-id.ts
│   │   │   ├── regions/
│   │   │   │   ├── cloudflare.ts
│   │   │   │   ├── fly.ts
│   │   │   │   └── vercel.ts
│   │   │   └── types/
│   │   │       └── index.ts
│   │   └── tsconfig.json
│   ├── icons/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── discord.tsx
│   │   │   ├── fly.tsx
│   │   │   ├── github.tsx
│   │   │   ├── google.tsx
│   │   │   ├── grafana.tsx
│   │   │   ├── index.tsx
│   │   │   ├── koyeb.tsx
│   │   │   ├── markdown.tsx
│   │   │   ├── opsgenie.tsx
│   │   │   ├── pagerduty.tsx
│   │   │   ├── railway.tsx
│   │   │   ├── slack.tsx
│   │   │   ├── statuspage.tsx
│   │   │   ├── telegram.tsx
│   │   │   └── whatsapp.tsx
│   │   └── tsconfig.json
│   ├── importers/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── index.ts
│   │   │   ├── providers/
│   │   │   │   └── statuspage/
│   │   │   │       ├── api-types.ts
│   │   │   │       ├── client.test.ts
│   │   │   │       ├── client.ts
│   │   │   │       ├── fixtures.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── mapper.test.ts
│   │   │   │       ├── mapper.ts
│   │   │   │       ├── provider.test.ts
│   │   │   │       └── provider.ts
│   │   │   └── types.ts
│   │   └── tsconfig.json
│   ├── notifications/
│   │   ├── base/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── index.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── utils/
│   │   │   │       ├── colors.ts
│   │   │   │       ├── duration.test.ts
│   │   │   │       ├── duration.ts
│   │   │   │       ├── incident.test.ts
│   │   │   │       ├── incident.ts
│   │   │   │       ├── message.ts
│   │   │   │       └── timestamp.ts
│   │   │   └── tsconfig.json
│   │   ├── discord/
│   │   │   ├── .gitignore
│   │   │   ├── README.md
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── embeds.ts
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── mock.ts
│   │   │   └── tsconfig.json
│   │   ├── email/
│   │   │   ├── README.md
│   │   │   ├── env.ts
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── mock.ts
│   │   │   └── tsconfig.json
│   │   ├── google-chat/
│   │   │   ├── .gitignore
│   │   │   ├── README.md
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── mock.ts
│   │   │   └── tsconfig.json
│   │   ├── grafana-oncall/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   └── tsconfig.json
│   │   ├── ntfy/
│   │   │   ├── .gitignore
│   │   │   ├── README.md
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   └── tsconfig.json
│   │   ├── opsgenie/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   └── tsconfig.json
│   │   ├── pagerduty/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── env.ts
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema/
│   │   │   │       └── config.ts
│   │   │   └── tsconfig.json
│   │   ├── slack/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── blocks.ts
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── mock.ts
│   │   │   └── tsconfig.json
│   │   ├── telegram/
│   │   │   ├── .gitignore
│   │   │   ├── README.md
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   └── tsconfig.json
│   │   ├── twillio-sms/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── env.ts
│   │   │   │   ├── index.test.ts
│   │   │   │   └── index.ts
│   │   │   └── tsconfig.json
│   │   ├── twillio-whatsapp/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── env.ts
│   │   │   │   ├── index.test.ts
│   │   │   │   └── index.ts
│   │   │   └── tsconfig.json
│   │   └── webhook/
│   │       ├── .gitignore
│   │       ├── README.md
│   │       ├── package.json
│   │       ├── src/
│   │       │   ├── index.test.ts
│   │       │   ├── index.ts
│   │       │   └── schema.ts
│   │       └── tsconfig.json
│   ├── proto/
│   │   ├── api/
│   │   │   └── openstatus/
│   │   │       ├── health/
│   │   │       │   └── v1/
│   │   │       │       └── health.proto
│   │   │       ├── maintenance/
│   │   │       │   └── v1/
│   │   │       │       ├── maintenance.proto
│   │   │       │       └── service.proto
│   │   │       ├── monitor/
│   │   │       │   └── v1/
│   │   │       │       ├── assertions.proto
│   │   │       │       ├── dns_monitor.proto
│   │   │       │       ├── http_monitor.proto
│   │   │       │       ├── monitor.proto
│   │   │       │       ├── service.proto
│   │   │       │       └── tcp_monitor.proto
│   │   │       ├── notification/
│   │   │       │   └── v1/
│   │   │       │       ├── notification.proto
│   │   │       │       ├── providers.proto
│   │   │       │       └── service.proto
│   │   │       ├── status_page/
│   │   │       │   └── v1/
│   │   │       │       ├── page_component.proto
│   │   │       │       ├── page_subscriber.proto
│   │   │       │       ├── service.proto
│   │   │       │       └── status_page.proto
│   │   │       └── status_report/
│   │   │           └── v1/
│   │   │               ├── service.proto
│   │   │               └── status_report.proto
│   │   ├── base.openapi.yaml
│   │   ├── buf.gen.go.yaml
│   │   ├── buf.gen.openapi.yaml
│   │   ├── buf.gen.ts.yaml
│   │   ├── buf.yaml
│   │   ├── gen/
│   │   │   ├── openapi.yaml
│   │   │   └── ts/
│   │   │       ├── buf/
│   │   │       │   └── validate/
│   │   │       │       └── validate_pb.ts
│   │   │       ├── gnostic/
│   │   │       │   └── openapi/
│   │   │       │       └── v3/
│   │   │       │           ├── annotations_pb.ts
│   │   │       │           └── openapiv3_pb.ts
│   │   │       ├── index.ts
│   │   │       └── openstatus/
│   │   │           ├── health/
│   │   │           │   └── v1/
│   │   │           │       ├── health_pb.ts
│   │   │           │       └── index.ts
│   │   │           ├── maintenance/
│   │   │           │   └── v1/
│   │   │           │       ├── index.ts
│   │   │           │       ├── maintenance_pb.ts
│   │   │           │       └── service_pb.ts
│   │   │           ├── monitor/
│   │   │           │   └── v1/
│   │   │           │       ├── assertions_pb.ts
│   │   │           │       ├── dns_monitor_pb.ts
│   │   │           │       ├── http_monitor_pb.ts
│   │   │           │       ├── index.ts
│   │   │           │       ├── monitor_pb.ts
│   │   │           │       ├── service_pb.ts
│   │   │           │       └── tcp_monitor_pb.ts
│   │   │           ├── notification/
│   │   │           │   └── v1/
│   │   │           │       ├── index.ts
│   │   │           │       ├── notification_pb.ts
│   │   │           │       ├── providers_pb.ts
│   │   │           │       └── service_pb.ts
│   │   │           ├── status_page/
│   │   │           │   └── v1/
│   │   │           │       ├── index.ts
│   │   │           │       ├── page_component_pb.ts
│   │   │           │       ├── page_subscriber_pb.ts
│   │   │           │       ├── service_pb.ts
│   │   │           │       └── status_page_pb.ts
│   │   │           └── status_report/
│   │   │               └── v1/
│   │   │                   ├── index.ts
│   │   │                   ├── service_pb.ts
│   │   │                   └── status_report_pb.ts
│   │   ├── go.mod
│   │   ├── go.sum
│   │   ├── internal/
│   │   │   └── private_location/
│   │   │       └── v1/
│   │   │           ├── assertions.proto
│   │   │           ├── dns_monitor.proto
│   │   │           ├── http_monitor.proto
│   │   │           ├── private_location.proto
│   │   │           └── tcp_monitor.proto
│   │   ├── justfile
│   │   ├── package.json
│   │   ├── plan/
│   │   │   ├── PLAN.md
│   │   │   └── api.md
│   │   ├── scripts/
│   │   │   └── clean-openapi.ts
│   │   └── tsconfig.json
│   ├── react/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── index.ts
│   │   │   ├── styles.css
│   │   │   ├── utils.ts
│   │   │   └── widget.tsx
│   │   ├── tsconfig.json
│   │   └── tsup.config.js
│   ├── regions/
│   │   ├── index.ts
│   │   ├── package.json
│   │   └── tsconfig.json
│   ├── status-fetcher/
│   │   ├── README.md
│   │   ├── __tests__/
│   │   │   ├── fetch-utils.test.ts
│   │   │   ├── fetchers/
│   │   │   │   ├── atlassian.test.ts
│   │   │   │   ├── betterstack.test.ts
│   │   │   │   ├── custom.test.ts
│   │   │   │   ├── edge-cases.test.ts
│   │   │   │   ├── html.test.ts
│   │   │   │   ├── incidentio.test.ts
│   │   │   │   └── instatus.test.ts
│   │   │   ├── integration.test.ts
│   │   │   └── utils.test.ts
│   │   ├── package.json
│   │   ├── scripts/
│   │   │   └── test-fetchers.ts
│   │   ├── src/
│   │   │   ├── data/
│   │   │   │   ├── directory.ts
│   │   │   │   └── index.ts
│   │   │   ├── fetch-utils.ts
│   │   │   ├── fetchers/
│   │   │   │   ├── atlassian.ts
│   │   │   │   ├── betterstack.ts
│   │   │   │   ├── custom.ts
│   │   │   │   ├── html.ts
│   │   │   │   ├── incidentio.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── instatus.ts
│   │   │   ├── index.ts
│   │   │   ├── types.ts
│   │   │   └── utils.ts
│   │   └── tsconfig.json
│   ├── subscriptions/
│   │   ├── bunfig.toml
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── channels/
│   │   │   │   ├── email.test.ts
│   │   │   │   ├── email.ts
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── webhook.test.ts
│   │   │   │   └── webhook.ts
│   │   │   ├── dispatcher.test.ts
│   │   │   ├── dispatcher.ts
│   │   │   ├── index.ts
│   │   │   ├── service.test.ts
│   │   │   ├── service.ts
│   │   │   ├── test-preload.ts
│   │   │   └── types.ts
│   │   └── tsconfig.json
│   ├── theme-store/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── dracula.ts
│   │   │   ├── github.ts
│   │   │   ├── index.ts
│   │   │   ├── openstatus.ts
│   │   │   ├── supabase.ts
│   │   │   ├── types.ts
│   │   │   └── utils.ts
│   │   └── tsconfig.json
│   ├── tinybird/
│   │   ├── README.md
│   │   ├── datasources/
│   │   │   ├── audit_log__v0.datasource
│   │   │   ├── check_response.datasource
│   │   │   ├── check_response_http.datasource
│   │   │   ├── dns_response__v0.datasource
│   │   │   ├── external_status.datasource
│   │   │   ├── mv__dns_status_45d__v0.datasource
│   │   │   ├── mv__http_14d.datasource
│   │   │   ├── mv__http_14d__v0.datasource
│   │   │   ├── mv__http_14d__v1.datasource
│   │   │   ├── mv__http_1d__v0.datasource
│   │   │   ├── mv__http_1d__v1.datasource
│   │   │   ├── mv__http_30d__v0.datasource
│   │   │   ├── mv__http_30d__v1.datasource
│   │   │   ├── mv__http_7d__v0.datasource
│   │   │   ├── mv__http_7d__v1.datasource
│   │   │   ├── mv__http_full_14d__v0.datasource
│   │   │   ├── mv__http_full_30d__v0.datasource
│   │   │   ├── mv__http_status_14d__v0.datasource
│   │   │   ├── mv__http_status_45d__v0.datasource
│   │   │   ├── mv__http_status_45d__v1.datasource
│   │   │   ├── mv__http_status_7d__v0.datasource
│   │   │   ├── mv__http_timing_phases_14d.datasource
│   │   │   ├── mv__http_timing_phases_14d__v1.datasource
│   │   │   ├── mv__http_uptime_30d__v1.datasource
│   │   │   ├── mv__http_uptime_7d__v1.datasource
│   │   │   ├── mv__http_workspace_30d__v0.datasource
│   │   │   ├── mv__tcp_14d__v0.datasource
│   │   │   ├── mv__tcp_14d__v1.datasource
│   │   │   ├── mv__tcp_1d__v0.datasource
│   │   │   ├── mv__tcp_1d__v1.datasource
│   │   │   ├── mv__tcp_30d__v0.datasource
│   │   │   ├── mv__tcp_30d__v1.datasource
│   │   │   ├── mv__tcp_7d__v0.datasource
│   │   │   ├── mv__tcp_7d__v1.datasource
│   │   │   ├── mv__tcp_full_14d__v0.datasource
│   │   │   ├── mv__tcp_full_30d__v0.datasource
│   │   │   ├── mv__tcp_status_45d__v0.datasource
│   │   │   ├── mv__tcp_status_45d__v1.datasource
│   │   │   ├── mv__tcp_status_7d__v0.datasource
│   │   │   ├── mv__tcp_uptime_30d__v1.datasource
│   │   │   ├── mv__tcp_uptime_7d__v1.datasource
│   │   │   ├── mv__tcp_workspace_30d__v0.datasource
│   │   │   ├── mv_http_status_14d.datasource
│   │   │   ├── ping_response__v8.datasource
│   │   │   ├── tcp_response.datasource
│   │   │   └── tcp_response__v0.datasource
│   │   ├── endpoints/
│   │   │   ├── endpoint__audit_log.pipe
│   │   │   ├── endpoint__audit_log__v1.pipe
│   │   │   ├── endpoint__dns_get_14d__v0.pipe
│   │   │   ├── endpoint__dns_list_14d__v0.pipe
│   │   │   ├── endpoint__dns_metrics_14d__v0.pipe
│   │   │   ├── endpoint__dns_metrics_1d__v0.pipe
│   │   │   ├── endpoint__dns_metrics_7d__v0.pipe
│   │   │   ├── endpoint__dns_metrics_latency_1d_multi__v0.pipe
│   │   │   ├── endpoint__dns_metrics_latency_7d__v0.pipe
│   │   │   ├── endpoint__dns_metrics_regions_14d__v0.pipe
│   │   │   ├── endpoint__dns_status_45d__v0.pipe
│   │   │   ├── endpoint__dns_uptime_30d__v0.pipe
│   │   │   ├── endpoint__http_get_14d__v0.pipe
│   │   │   ├── endpoint__http_get_30d.pipe
│   │   │   ├── endpoint__http_list_14d.pipe
│   │   │   ├── endpoint__http_list_14d__v1.pipe
│   │   │   ├── endpoint__http_list_1d.pipe
│   │   │   ├── endpoint__http_list_1d__v1.pipe
│   │   │   ├── endpoint__http_list_7d.pipe
│   │   │   ├── endpoint__http_list_7d__v1.pipe
│   │   │   ├── endpoint__http_metrics_14d.pipe
│   │   │   ├── endpoint__http_metrics_14d__v1.pipe
│   │   │   ├── endpoint__http_metrics_1d.pipe
│   │   │   ├── endpoint__http_metrics_1d__v1.pipe
│   │   │   ├── endpoint__http_metrics_7d.pipe
│   │   │   ├── endpoint__http_metrics_7d__v1.pipe
│   │   │   ├── endpoint__http_metrics_by_interval_14d.pipe
│   │   │   ├── endpoint__http_metrics_by_interval_1d.pipe
│   │   │   ├── endpoint__http_metrics_by_interval_7d.pipe
│   │   │   ├── endpoint__http_metrics_by_region_14d.pipe
│   │   │   ├── endpoint__http_metrics_by_region_1d.pipe
│   │   │   ├── endpoint__http_metrics_by_region_7d.pipe
│   │   │   ├── endpoint__http_metrics_global_1d__v0.pipe
│   │   │   ├── endpoint__http_metrics_latency_1d__v1.pipe
│   │   │   ├── endpoint__http_metrics_latency_1d_multi__v1.pipe
│   │   │   ├── endpoint__http_metrics_latency_7d__v1.pipe
│   │   │   ├── endpoint__http_metrics_regions_14d__v0.pipe
│   │   │   ├── endpoint__http_metrics_regions_1d__v0.pipe
│   │   │   ├── endpoint__http_metrics_regions_7d__v0.pipe
│   │   │   ├── endpoint__http_status_14d.pipe
│   │   │   ├── endpoint__http_status_45d.pipe
│   │   │   ├── endpoint__http_status_45d__v1.pipe
│   │   │   ├── endpoint__http_status_7d.pipe
│   │   │   ├── endpoint__http_timing_phases_14d__v1.pipe
│   │   │   ├── endpoint__http_uptime_30d__v1.pipe
│   │   │   ├── endpoint__http_uptime_7d__v1.pipe
│   │   │   ├── endpoint__http_workspace_30d__v0.pipe
│   │   │   ├── endpoint__stats_global.pipe
│   │   │   ├── endpoint__tcp_get_14d__v0.pipe
│   │   │   ├── endpoint__tcp_get_30d.pipe
│   │   │   ├── endpoint__tcp_list_14d.pipe
│   │   │   ├── endpoint__tcp_list_14d__v1.pipe
│   │   │   ├── endpoint__tcp_list_1d.pipe
│   │   │   ├── endpoint__tcp_list_1d__v1.pipe
│   │   │   ├── endpoint__tcp_list_7d.pipe
│   │   │   ├── endpoint__tcp_list_7d__v1.pipe
│   │   │   ├── endpoint__tcp_metrics_14d.pipe
│   │   │   ├── endpoint__tcp_metrics_14d__v1.pipe
│   │   │   ├── endpoint__tcp_metrics_1d.pipe
│   │   │   ├── endpoint__tcp_metrics_1d__v1.pipe
│   │   │   ├── endpoint__tcp_metrics_7d.pipe
│   │   │   ├── endpoint__tcp_metrics_7d__v1.pipe
│   │   │   ├── endpoint__tcp_metrics_by_interval_14d.pipe
│   │   │   ├── endpoint__tcp_metrics_by_interval_1d.pipe
│   │   │   ├── endpoint__tcp_metrics_by_interval_7d.pipe
│   │   │   ├── endpoint__tcp_metrics_by_region_14d.pipe
│   │   │   ├── endpoint__tcp_metrics_by_region_1d.pipe
│   │   │   ├── endpoint__tcp_metrics_by_region_7d.pipe
│   │   │   ├── endpoint__tcp_metrics_global_1d.pipe
│   │   │   ├── endpoint__tcp_metrics_latency_1d__v1.pipe
│   │   │   ├── endpoint__tcp_metrics_latency_1d_multi__v1.pipe
│   │   │   ├── endpoint__tcp_metrics_latency_7d__v1.pipe
│   │   │   ├── endpoint__tcp_status_45d.pipe
│   │   │   ├── endpoint__tcp_status_45d__v1.pipe
│   │   │   ├── endpoint__tcp_status_7d.pipe
│   │   │   ├── endpoint__tcp_uptime_30d__v1.pipe
│   │   │   ├── endpoint__tcp_uptime_7d__v1.pipe
│   │   │   ├── endpoint__tcp_workspace_30d__v0.pipe
│   │   │   ├── endpoint_audit_log.pipe
│   │   │   └── endpoint_external_status.pipe
│   │   ├── package.json
│   │   ├── pipes/
│   │   │   ├── __ttl_45d_count_utc_get.pipe
│   │   │   ├── aggregate__dns_status_45d__v1.pipe
│   │   │   ├── aggregate__http_14d__v1.pipe
│   │   │   ├── aggregate__http_1d__v1.pipe
│   │   │   ├── aggregate__http_30d__v1.pipe
│   │   │   ├── aggregate__http_7d__v1.pipe
│   │   │   ├── aggregate__http_full_14d__v0.pipe
│   │   │   ├── aggregate__http_full_30d__v0.pipe
│   │   │   ├── aggregate__http_status_14d.pipe
│   │   │   ├── aggregate__http_status_45d.pipe
│   │   │   ├── aggregate__http_status_45d__v1.pipe
│   │   │   ├── aggregate__http_status_7d.pipe
│   │   │   ├── aggregate__http_timing_phases_14d.pipe
│   │   │   ├── aggregate__http_uptime_30d.pipe
│   │   │   ├── aggregate__http_uptime_7d__v1.pipe
│   │   │   ├── aggregate__http_workspace_30d__v0.pipe
│   │   │   ├── aggregate__tcp_14d.pipe
│   │   │   ├── aggregate__tcp_14d__v1.pipe
│   │   │   ├── aggregate__tcp_1d.pipe
│   │   │   ├── aggregate__tcp_1d__v1.pipe
│   │   │   ├── aggregate__tcp_30d.pipe
│   │   │   ├── aggregate__tcp_30d__v1.pipe
│   │   │   ├── aggregate__tcp_7d.pipe
│   │   │   ├── aggregate__tcp_7d__v1.pipe
│   │   │   ├── aggregate__tcp_full_14d__v0.pipe
│   │   │   ├── aggregate__tcp_full_30d__v0.pipe
│   │   │   ├── aggregate__tcp_status_45d.pipe
│   │   │   ├── aggregate__tcp_status_45d__v1.pipe
│   │   │   ├── aggregate__tcp_status_7d.pipe
│   │   │   ├── aggregate__tcp_uptime_30d__v1.pipe
│   │   │   ├── aggregate__tcp_uptime_7d__v1.pipe
│   │   │   ├── aggregate__tcp_workspace_30d__v0.pipe
│   │   │   ├── get_result_for_on_demand_check_http.pipe
│   │   │   ├── public_status.pipe
│   │   │   ├── response_details.pipe
│   │   │   ├── response_graph.pipe
│   │   │   ├── response_list.pipe
│   │   │   └── single_checks_get.pipe
│   │   ├── src/
│   │   │   ├── audit-log/
│   │   │   │   ├── README.md
│   │   │   │   ├── action-schema.ts
│   │   │   │   ├── action-validation.ts
│   │   │   │   ├── base-validation.ts
│   │   │   │   ├── client.ts
│   │   │   │   ├── examples.ts
│   │   │   │   └── index.ts
│   │   │   ├── client.ts
│   │   │   ├── index.ts
│   │   │   └── schema.ts
│   │   └── tsconfig.json
│   ├── tracker/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── blacklist.ts
│   │   │   ├── config.ts
│   │   │   ├── index.ts
│   │   │   ├── mock.ts
│   │   │   ├── tracker.ts
│   │   │   ├── types.ts
│   │   │   └── utils.ts
│   │   └── tsconfig.json
│   ├── tsconfig/
│   │   ├── base.json
│   │   ├── nextjs.json
│   │   ├── package.json
│   │   └── react-library.json
│   ├── ui/
│   │   ├── REGISTRY.md
│   │   ├── components.json
│   │   ├── package.json
│   │   ├── registry.json
│   │   ├── scripts/
│   │   │   ├── copy-to-web.mjs
│   │   │   └── transform-imports.mjs
│   │   ├── src/
│   │   │   ├── components/
│   │   │   │   ├── blocks/
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── status-banner.tsx
│   │   │   │   │   ├── status-bar.tsx
│   │   │   │   │   ├── status-blank.tsx
│   │   │   │   │   ├── status-component-group.tsx
│   │   │   │   │   ├── status-component.tsx
│   │   │   │   │   ├── status-events.tsx
│   │   │   │   │   ├── status-feed.tsx
│   │   │   │   │   ├── status-icon.tsx
│   │   │   │   │   ├── status-layout.tsx
│   │   │   │   │   ├── status-timestamp.tsx
│   │   │   │   │   ├── status.types.ts
│   │   │   │   │   └── status.utils.ts
│   │   │   │   └── ui/
│   │   │   │       ├── alert-dialog.tsx
│   │   │   │       ├── alert.tsx
│   │   │   │       ├── avatar.tsx
│   │   │   │       ├── badge.tsx
│   │   │   │       ├── breadcrumb.tsx
│   │   │   │       ├── button-group.tsx
│   │   │   │       ├── button.tsx
│   │   │   │       ├── calendar.tsx
│   │   │   │       ├── card.tsx
│   │   │   │       ├── chart.tsx
│   │   │   │       ├── checkbox.tsx
│   │   │   │       ├── collapsible.tsx
│   │   │   │       ├── command.tsx
│   │   │   │       ├── context-menu.tsx
│   │   │   │       ├── dialog.tsx
│   │   │   │       ├── dropdown-menu.tsx
│   │   │   │       ├── form.tsx
│   │   │   │       ├── hover-card.tsx
│   │   │   │       ├── input-group.tsx
│   │   │   │       ├── input.tsx
│   │   │   │       ├── kbd.tsx
│   │   │   │       ├── label.tsx
│   │   │   │       ├── popover.tsx
│   │   │   │       ├── progress.tsx
│   │   │   │       ├── qr-code.tsx
│   │   │   │       ├── radio-group.tsx
│   │   │   │       ├── select.tsx
│   │   │   │       ├── separator.tsx
│   │   │   │       ├── sheet.tsx
│   │   │   │       ├── sidebar.tsx
│   │   │   │       ├── skeleton.tsx
│   │   │   │       ├── slider.tsx
│   │   │   │       ├── sonner.tsx
│   │   │   │       ├── switch.tsx
│   │   │   │       ├── table.tsx
│   │   │   │       ├── tabs.tsx
│   │   │   │       ├── textarea.tsx
│   │   │   │       └── tooltip.tsx
│   │   │   ├── globals.css
│   │   │   ├── hooks/
│   │   │   │   ├── use-cookie-state.ts
│   │   │   │   ├── use-copy-to-clipboard.ts
│   │   │   │   ├── use-debounce-callback.ts
│   │   │   │   ├── use-debounce.ts
│   │   │   │   ├── use-media-query.ts
│   │   │   │   └── use-mobile.ts
│   │   │   └── lib/
│   │   │       ├── compose-refs.ts
│   │   │       └── utils.ts
│   │   └── tsconfig.json
│   ├── upstash/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── index.ts
│   │   │   └── redis/
│   │   │       └── client.ts
│   │   └── tsconfig.json
│   └── utils/
│       ├── index.ts
│       ├── package.json
│       └── tsconfig.json
├── pnpm-workspace.yaml
├── process-compose.yaml
├── ralph/
│   ├── .gitignore
│   ├── README.md
│   ├── afk-ralph.sh
│   └── ralph-once.sh
├── turbo.json
└── utils/
    └── api-bruno/
        ├── Monitor Summary.bru
        ├── OpenApi.bru
        ├── bruno.json
        ├── checker.bru
        ├── environments/
        │   ├── local.bru
        │   └── prod.bru
        ├── incident_update/
        │   └── Get Status Report Update.bru
        └── incidents/
            ├── All Status Reports.bru
            └── Get Status Report.bru

================================================
FILE CONTENTS
================================================

================================================
FILE: .claude/commands/ship.md
================================================
---
description: Create a new git branch, commit changes, and create a pull request
allowed-tools: Bash(git:*), Bash(gh:*)
---

# Current Git State

- Branch: !`git branch --show-current`
- Status: !`git status --porcelain`
- Recent commits: !`git log --oneline -5`

# Arguments

$ARGUMENTS - optional branch name

# Workflow

## 1. Validate

- Confirm there are uncommitted changes (from status above). If none, stop.
- Confirm current branch. If not on `main`, ask user before proceeding.
- Warn if any .env or credential files would be staged.
- Run `pnpm format:fix` in the root directory to fix formatting issues

## 2. Create Branch

- If `$ARGUMENTS` provided, use it as branch name
- Otherwise, generate from task context using conventional prefixes: `feat/`, `fix/`, `chore/`, `refactor/`, `docs/` in kebab-case

```bash
git checkout -b <branch-name>
```

## 3. Commit

1. Run `git diff` to review all changes
2. **Think about context**: What was the user trying to achieve? What problem does this solve?
3. Draft commit message:
   - Conventional commit format: `feat:`, `fix:`, `chore:`, `docs:`, `refactor:`
   - **Write at the outcome level, not implementation level**
   - Bad: "change timeout from 5000 to 10000 in checker/monitor.go"
   - Good: "increase monitor check timeout to handle slow API responses"
4. Stage relevant files (not .env/credentials)
5. Commit with heredoc format:

```bash
git commit -m "$(cat <<'EOF'
<message>

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
EOF
)"
```

6. Run `git status` to verify success

## 4. Push & Create PR

```bash
git push -u origin <branch-name>
```

Create PR with `gh`:

- Title from commit message (same high-level framing)
- Summary explains **outcomes**, not file changes
  - Bad: "Added `getMonitorStatus()` to monitor.ts, updated `Monitor` type"
  - Good: "Status pages now reflect real-time monitor degradation states"

```bash
gh pr create --title "<title>" --body "$(cat <<'EOF'
## Summary
- <outcome 1>
- <outcome 2>

🤖 Generated with [Claude Code](https://claude.com/claude-code)
EOF
)"
```

Return the PR URL.

## Error Handling

If any step fails, report the error and stop. Don't proceed to the next step.


================================================
FILE: .dockerignore
================================================
# Dependencies
**/node_modules
node_modules
**/.pnpm-store
.pnpm-store

# Build outputs
**/.next
**/.turbo
**/dist
**/build
**/.nuxt
**/.output
**/.cache

# Environment files
**/.env
**/.env.*
.env
.env.*
!.env.docker.example

# Development files
**/.vscode
**/.idea
**/.DS_Store
.DS_Store
**/*.log
**/npm-debug.log
**/yarn-debug.log
**/yarn-error.log
**/pnpm-debug.log

# Testing
**/coverage
**/.nyc_output
**/test-results
**/__tests__
**/tests
**/*.test.ts
**/*.test.tsx
**/*.test.js
**/*.spec.ts
**/*.spec.tsx
**/*.spec.js

# Git
**/.git
**/.gitignore
**/.gitattributes
.git
.gitignore

# Documentation
**/README.md
**/CHANGELOG.md
**/LICENSE
**/*.md
!packages/**/README.md

# CI/CD
**/.github
.github
**/.gitlab
**/.circleci
**/.drone.yml
**/.travis.yml

# Docker
**/.dockerignore
**/Dockerfile
**/docker-compose*.yml
**/docker-compose*.yaml
.dockerignore
docker-compose*.yml
docker-compose*.yaml

# Database files
openstatus.db
**/*.db
**/*.db-shm
**/*.db-wal

# Temporary files
**/tmp
**/temp
**/.temp
**/.tmp

# IDE
**/.vscode
**/.idea
**/.fleet

# OS
.DS_Store
**/Thumbs.db

# Other build artifacts
**/.contentlayer
**/public/build
**/.svelte-kit

================================================
FILE: .github/FUNDING.yml
================================================
github: openstatusHQ


================================================
FILE: .github/workflows/api-preview.yml
================================================
name: Fly Preview API server
on:
  workflow_dispatch:
    inputs:
      action:
        description: "Action to perform"
        required: true
        type: choice
        options:
          - deploy
          - destroy

permissions:
  contents: read
  deployments: write

env:
    FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
    FLY_REGION: ams
    FLY_ORG: openstatus
    APP_NAME: openstatus-api-preview-${{ github.ref_name }}

jobs:
  deploy:
    if: ${{ github.event.inputs.action == 'deploy' }}
    runs-on: depot-ubuntu-24.04-4
    timeout-minutes: 15
    concurrency:
      group: api-preview-${{ github.ref_name }}
    environment:
      name: api-preview-${{ github.ref_name }}
      url: https://${{ env.APP_NAME }}.fly.dev
    steps:
      - name: Get code
        uses: actions/checkout@v4

      - name: Setup Fly.io CLI
        uses: superfly/flyctl-actions/setup-flyctl@master

      - name: Create app if not exists
        run: flyctl apps create ${{ env.APP_NAME }} --org ${{ env.FLY_ORG }} || true

      - name: Set secrets
        run: |
          flyctl secrets set \
            DATABASE_URL="${{ secrets.STAGING_DB_URL }}" \
            DATABASE_AUTH_TOKEN="${{ secrets.STAGING_DB_AUTH_TOKEN }}" \
            RESEND_API_KEY="${{ secrets.STAGING_RESEND_API_KEY }}" \
            UPSTASH_REDIS_REST_URL=test \
            UPSTASH_REDIS_REST_TOKEN=test \
            GCP_PROJECT_ID=test \
            NEXT_PUBLIC_OPENPANEL_CLIENT_ID=test \
            OPENPANEL_CLIENT_SECRET=test \
            --app ${{ env.APP_NAME }}

      - name: Deploy to Fly.io
        run: |
          flyctl deploy \
            --config apps/server/fly.toml \
            --app ${{ env.APP_NAME }} \
            --region ${{ env.FLY_REGION }} \
            --vm-size shared-cpu-1x \
            --yes

  destroy:
    if: ${{ github.event.inputs.action == 'destroy' }}
    runs-on: ubuntu-latest
    timeout-minutes: 5
    steps:
      - name: Setup Fly.io CLI
        uses: superfly/flyctl-actions/setup-flyctl@master

      - name: Destroy app
        run: flyctl apps destroy ${{ env.APP_NAME }} --yes || true

      - name: Clean up GitHub environment
        uses: strumwolf/delete-deployment-environment@v2
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          environment: api-preview-${{ github.ref_name }}


================================================
FILE: .github/workflows/claude-code-review.yml
================================================
name: Claude Code Review

on:
  pull_request:
    types: [opened, synchronize, ready_for_review, reopened]
    # Optional: Only run on specific file changes
    # paths:
    #   - "src/**/*.ts"
    #   - "src/**/*.tsx"
    #   - "src/**/*.js"
    #   - "src/**/*.jsx"

jobs:
  claude-review:
    # Optional: Filter by PR author
    if: |
      github.event.pull_request.author_association == 'MEMBER' ||
      github.event.pull_request.author_association == 'OWNER'

    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: write
      issues: read
      id-token: write

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Run Claude Code Review
        id: claude-review
        uses: anthropics/claude-code-action@v1
        with:
          claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
          plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
          plugins: 'code-review@claude-code-plugins'
          prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
          # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
          # or https://code.claude.com/docs/en/cli-reference for available options


================================================
FILE: .github/workflows/claude.yml
================================================
name: Claude Code

on:
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]
  issues:
    types: [opened, assigned]
  pull_request_review:
    types: [submitted]

jobs:
  claude:
    if: |
      (
        github.event_name == 'issue_comment' &&
        contains(github.event.comment.body, '@claude') &&
        (github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'COLLABORATOR')
      ) ||
      (
        github.event_name == 'pull_request_review_comment' &&
        contains(github.event.comment.body, '@claude') &&
        (github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'COLLABORATOR')
      ) ||
      (
        github.event_name == 'pull_request_review' &&
        contains(github.event.review.body, '@claude') &&
        (github.event.review.author_association == 'OWNER' || github.event.review.author_association == 'MEMBER' || github.event.review.author_association == 'COLLABORATOR')
      ) ||
      (
        github.event_name == 'issues' &&
        (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')) &&
        (github.event.issue.author_association == 'OWNER' || github.event.issue.author_association == 'MEMBER' || github.event.issue.author_association == 'COLLABORATOR')
      )
    runs-on: ubuntu-latest
    timeout-minutes: 30
    permissions:
      contents: write
      pull-requests: write
      issues: write
      id-token: write
      actions: read # Required for Claude to read CI results on PRs
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Run Claude Code
        id: claude
        uses: anthropics/claude-code-action@v1
        with:
          claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}

          # This is an optional setting that allows Claude to read CI results on PRs
          additional_permissions: |
            actions: read

          # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
          # prompt: 'Update the pull request description to include a summary of changes.'

          # Optional: Add claude_args to customize behavior and configuration
          # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
          # or https://code.claude.com/docs/en/cli-reference for available options
          # claude_args: '--allowed-tools Bash(gh pr:*)'



================================================
FILE: .github/workflows/deploy-checker.yml
================================================
name: Fly Deploy Checker
on:
  push:
    branches:
      - main
    paths:
      - "apps/checker/**"
jobs:
  deploy-checker:
    name: Deploy Checker
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@v4
      - uses: superfly/flyctl-actions/setup-flyctl@master
      - working-directory: apps/checker
        name: Deploy Checker
        run: |
          flyctl deploy --remote-only --wait-timeout=500
        env:
          FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}


================================================
FILE: .github/workflows/deploy-private-location.yml
================================================
name: Fly Deploy Private Location
on:
  push:
    branches:
      - main
    paths:
      - "apps/private-location/**"
      - "apps/checker/**"
jobs:
  deploy-private-location:
    name: Deploy Private Location
    runs-on: ubuntu-latest
    timeout-minutes: 15
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@v4
      - uses: superfly/flyctl-actions/setup-flyctl@master
      - working-directory: apps/private-location
        name: Deploy Private Location
        run: |
          flyctl deploy --remote-only --wait-timeout=500
        env:
          FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}


================================================
FILE: .github/workflows/deploy-workflows.yml
================================================
name: Fly Deploy Workflows
on:
  push:
    branches:
      - main
    paths:
      - "apps/workflows/**"
      - "packages/db/**"
      - "packages/emails/**"
      - "packages/utils/**"
      - "packages/tsconfig/**"
      - "packages/notifications/**"
jobs:
  deploy-workflows:
    name: Deploy Workflows
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@v4
      - uses: superfly/flyctl-actions/setup-flyctl@master
      - run: flyctl deploy --config apps/workflows/fly.toml
          --dockerfile  apps/workflows/Dockerfile --remote-only --wait-timeout=500
        env:
          FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}


================================================
FILE: .github/workflows/deploy.yml
================================================
name: Fly Deploy
on:
  push:
    branches:
      - main
jobs:
  deploy:
    name: Deploy API
    runs-on: depot-ubuntu-24.04-4
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@v4
      - uses: superfly/flyctl-actions/setup-flyctl@master
      - run:
          flyctl deploy --config apps/server/fly.toml
          --dockerfile  apps/server/Dockerfile --remote-only --wait-timeout=500
        env:
          FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}


================================================
FILE: .github/workflows/docker-publish-dev.yml
================================================
name: Publish Docker Images (Development)

on:
  workflow_dispatch:

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: openstatus

jobs:
  build-and-push-dev:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
      packages: write
    
    strategy:
      matrix:
        service: [server, dashboard, workflows, private-location, status-page, checker]
        include:
          - service: server
            context: .
            dockerfile: apps/server/Dockerfile
            port: 3001
          - service: dashboard
            context: .
            dockerfile: apps/dashboard/Dockerfile
            port: 3002
          - service: workflows
            context: .
            dockerfile: apps/workflows/Dockerfile
            port: 3000
          - service: private-location
            context: apps/private-location
            dockerfile: apps/private-location/Dockerfile
            port: 8081
          - service: status-page
            context: .
            dockerfile: apps/status-page/Dockerfile
            port: 3003
          - service: checker
            context: apps/checker
            dockerfile: apps/checker/Dockerfile
            port: 8082

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}-${{ matrix.service }}
          tags: |
            type=ref,event=branch,suffix=-${{ matrix.service }}
            type=ref,event=pr,suffix=-${{ matrix.service }}
            type=sha,prefix=dev-,suffix=-${{ matrix.service }}
            type=raw,value=dev-latest,suffix=-${{ matrix.service }}

      - name: Build and push Docker image
        uses: docker/build-push-action@v5
        with:
          context: ${{ matrix.context }}
          file: ${{ matrix.dockerfile }}
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          platforms: linux/amd64
          cache-from: type=gha
          cache-to: type=gha,mode=max
          provenance: false

  test-images:
    runs-on: ubuntu-latest
    needs: build-and-push-dev
    if: github.event_name == 'pull_request'
    
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Docker Compose
        run: |
          sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
          sudo chmod +x /usr/local/bin/docker-compose

      - name: Create test compose file
        run: |
          cp docker-compose.github-packages.yaml docker-compose.test.yaml
          # Replace latest tags with dev-latest for testing
          sed -i 's/:latest/:dev-latest/g' docker-compose.test.yaml

      - name: Test service startup
        run: |
          # Start external services first
          docker-compose -f docker-compose.test.yaml up -d libsql tinybird-local
          
          # Wait for external services to be healthy
          timeout 120 bash -c 'until docker-compose -f docker-compose.test.yaml ps libsql | grep -q "healthy"; do sleep 5; done'
          timeout 120 bash -c 'until docker-compose -f docker-compose.test.yaml ps tinybird-local | grep -q "healthy"; do sleep 5; done'
          
          # Start one service for basic testing
          docker-compose -f docker-compose.test.yaml up -d workflows
          
          # Wait and check if it's running
          sleep 30
          if ! docker-compose -f docker-compose.test.yaml ps workflows | grep -q "Up"; then
            echo "Workflows service failed to start"
            docker-compose -f docker-compose.test.yaml logs workflows
            exit 1
          fi

      - name: Cleanup
        if: always()
        run: |
          docker-compose -f docker-compose.test.yaml down -v


================================================
FILE: .github/workflows/docker-publish.yml
================================================
name: Publish Docker Images

on:
  push:
    branches:
      - main
    paths:
      - "apps/server/**"
      - "apps/dashboard/**"
      - "apps/workflows/**"
      - "apps/private-location/**"
      - "apps/status-page/**"
      - "apps/checker/**"
      - "packages/**"
      - "docker-compose.yaml"
  workflow_dispatch:
    inputs:
      services:
        description: 'Services to build (comma-separated)'
        required: false
        default: 'server,dashboard,workflows,private-location,status-page,checker'
        type: string

concurrency:
  group: docker-${{ github.ref }}
  cancel-in-progress: true

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: openstatus

jobs:
  prepare:
    runs-on: ubuntu-latest
    outputs:
      services: ${{ steps.set-services.outputs.services }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 2

      - name: Determine services to build
        id: set-services
        run: |
          if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
            # Convert comma-separated input to JSON array
            SERVICES=$(echo "${{ inputs.services }}" | tr ',' '\n' | jq -R . | jq -sc .)
          else
            # Detect changed files
            CHANGED=$(git diff --name-only HEAD~1 HEAD)
            SERVICES_LIST=()

            # packages/** changes affect all services
            if echo "$CHANGED" | grep -q '^packages/'; then
              SERVICES_LIST=("server" "dashboard" "workflows" "private-location" "status-page" "checker")
            else
              for svc in server dashboard workflows private-location status-page checker; do
                if echo "$CHANGED" | grep -q "^apps/$svc/"; then
                  SERVICES_LIST+=("$svc")
                fi
              done
            fi

            SERVICES=$(printf '%s\n' "${SERVICES_LIST[@]}" | jq -R . | jq -sc .)
          fi

          echo "services=$SERVICES" >> "$GITHUB_OUTPUT"
          echo "Building services: $SERVICES"

  build-and-push:
    runs-on: ubuntu-latest
    needs: [prepare]
    if: needs.prepare.outputs.services != '[]'
    timeout-minutes: 30
    permissions:
      contents: read
      id-token: write
      packages: write

    strategy:
      fail-fast: false
      matrix:
        service: ${{ fromJson(needs.prepare.outputs.services) }}
        include:
          - service: server
            context: .
            dockerfile: apps/server/Dockerfile
          - service: dashboard
            context: .
            dockerfile: apps/dashboard/Dockerfile
          - service: workflows
            context: .
            dockerfile: apps/workflows/Dockerfile
          - service: private-location
            context: apps/private-location
            dockerfile: apps/private-location/Dockerfile
          - service: status-page
            context: .
            dockerfile: apps/status-page/Dockerfile
          - service: checker
            context: apps/checker
            dockerfile: apps/checker/Dockerfile

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Lowercase owner
        run: echo "OWNER_LC=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.OWNER_LC }}/${{ env.IMAGE_NAME }}-${{ matrix.service }}
          tags: |
            type=ref,event=branch
            type=ref,event=pr
            type=sha,prefix=
            type=raw,value=latest,enable={{is_default_branch}}

      - name: Build and push Docker image
        id: build
        uses: docker/build-push-action@v6
        with:
          context: ${{ matrix.context }}
          file: ${{ matrix.dockerfile }}
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          platforms: linux/amd64,linux/arm64
          cache-from: type=gha
          cache-to: type=gha,mode=max
          provenance: false

      - name: Generate SBOM
        uses: anchore/sbom-action@v0
        with:
          image: ${{ env.REGISTRY }}/${{ env.OWNER_LC }}/${{ env.IMAGE_NAME }}-${{ matrix.service }}@${{ steps.build.outputs.digest }}
          format: spdx-json
          output-file: sbom-${{ matrix.service }}.spdx.json

      - name: Upload SBOM
        uses: actions/upload-artifact@v4
        with:
          name: sbom-${{ matrix.service }}
          path: sbom-${{ matrix.service }}.spdx.json
          retention-days: 30


================================================
FILE: .github/workflows/dx.yml
================================================
# https://github.com/kentcdodds/kentcdodds.com/blob/main/.github/workflows/deployment.yml
name: DX Check
on:
  push:
    branches:
      - "main"
  pull_request:
    branches: [main]

jobs:
  dx:
    name: 🧑‍💻 DX checker
    runs-on: ubuntu-latest
    timeout-minutes: 15
    services:
      sqld:
        image: ghcr.io/tursodatabase/libsql-server:latest
        ports:
          - 8080:8080
        # env:
        #   SQLD_HTTP_AUTH: "basic:token"

    env:
      TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
      TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
      DATABASE_URL: http://127.0.0.1:8080
      DATABASE_AUTH_TOKEN: "basic:token"
    steps:
      - name: ⬇️ Checkout repo
        uses: actions/checkout@v4

      - name: Set up pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 10.26.0

      - name: ⎔ Setup node
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: "pnpm"

      - name: 📥 Download deps
        run: pnpm install

      - name: 🔥 Install bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest

      - name: 🔥  DX task
        run: pnpm dx


================================================
FILE: .github/workflows/go-tests.yml
================================================
name: Go Tests

on:
  push:
    branches:
      - master
    tags:
      - '*.*.*'
  pull_request:
    branches:
      - '**'
    paths:
      - "apps/checker/**"
      - "apps/private-location/**"

jobs:
  ci:
    name: Continuous Integration
    runs-on: ubuntu-latest
    timeout-minutes: 5
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with:
          go-version: '>=1.25.0'
      - name: Run test Checker
        run: go test -timeout 30s -race -count=1 ./...
        working-directory: apps/checker
      - name: Run test Private Location
        run: go test -timeout 30s -race -count=1 ./...
        working-directory: apps/private-location


================================================
FILE: .github/workflows/lint.yml
================================================
# https://github.com/kentcdodds/kentcdodds.com/blob/main/.github/workflows/deployment.yml
name: autofix.ci # needed to securely identify the workflow
on:
  pull_request:

concurrency:
  group: ${{ github.workflow }}-${{ github.event.number || github.ref }}
  cancel-in-progress: true

permissions:
  contents: read


jobs:
  autofix:
    name: autofix
    runs-on: ubuntu-latest
    steps:
      - name: ⬇️ Checkout repo
        uses: actions/checkout@v4

      - name: Set up pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 10.26.0

      - name: ⎔ Setup node
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: "pnpm"

      - name: 📥 Download deps
        run: pnpm install

      - name: 🔬 Lint
        run: pnpm format
      - name: Apply fixes
        uses: autofix-ci/action@dd55f44df8f7cdb7a6bf74c78677eb8acd40cd0a
        with:
          commit-message: 'ci: apply automated fixes'


================================================
FILE: .github/workflows/migrate.yml
================================================
name: Migrate DB
on:
  push:
    branches:
      - main
    paths:
      - "packages/db/drizzle/**"
jobs:
  migrate:
    name: 🗃️ Migrate DB
    runs-on: ubuntu-latest
    env:
      DATABASE_URL:  ${{ secrets.DATABASE_URL }}
      DATABASE_AUTH_TOKEN:  ${{ secrets.DATABASE_AUTH_TOKEN }}
    steps:
      - name: ⬇️ Checkout repo
        uses: actions/checkout@v4

      - name: Set up pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 10.26.0

      - name: ⎔ Setup node
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: "pnpm"

      - name: 🔥 Install bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest

      - name: 📥 Download deps
        run: pnpm install

      - name: 🗃️ Run migrations
        run: pnpm migrate
        working-directory: ./packages/db


================================================
FILE: .github/workflows/publish-checker.yml
================================================
name: Publish Checker
on:
  push:
    branches:
      - main
    paths:
      - "apps/checker/**"
env:
  REGISTRY: ghcr.io
  IMAGE_NAME: checker

jobs:
  build-checker:
    runs-on: ubuntu-latest
    # Permissions to use OIDC token authentication
    permissions:
      contents: read
      id-token: write
      # Allows pushing to the GitHub Container Registry
      packages: write
    steps:
      - uses: actions/checkout@v3
      - uses: depot/setup-action@v1
      - name: Log in to the Container registry
        uses: docker/login-action@v3
        with:
            registry: ${{ env.REGISTRY }}
            username: ${{ github.repository_owner }}
            password: ${{ secrets.GITHUB_TOKEN }}
      - name: Build and push
        uses: depot/build-push-action@v1
        with:
          project: 9cknw183m8
          context: apps/checker
          tags: ghcr.io/openstatushq/checker:latest
          platforms: linux/amd64,linux/arm64
          push: true
  build-private-location:
    runs-on: ubuntu-latest
    # Permissions to use OIDC token authentication
    permissions:
      contents: read
      id-token: write
      # Allows pushing to the GitHub Container Registry
      packages: write
    steps:
      - uses: actions/checkout@v3
      - uses: depot/setup-action@v1
      - name: Log in to the Container registry
        uses: docker/login-action@v3
        with:
            registry: ${{ env.REGISTRY }}
            username: ${{ github.repository_owner }}
            password: ${{ secrets.GITHUB_TOKEN }}
      - name: Build and push
        uses: depot/build-push-action@v1
        with:
          file: apps/checker/private-location.Dockerfile
          project: 9cknw183m8
          context: apps/checker
          tags: ghcr.io/openstatushq/private-location:latest
          platforms: linux/amd64,linux/arm64
          push: true


================================================
FILE: .github/workflows/synthetic.yml
================================================
name: Run OpenStatus Synthetics CI

on:
  workflow_run:
      workflows: ['Fly Deploy']
      types: [completed]
      branches:
        - main
  repository_dispatch:
      types:
        - 'vercel.deployment.success'
      branches:
        - main

jobs:
  synthetic_ci:
    runs-on: ubuntu-latest
    name: Run OpenStatus Synthetics CI
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Run OpenStatus Synthetics CI
        uses: openstatushq/openstatus-github-action@v1
        with:
          api_key: ${{ secrets.OPENSTATUS_API_KEY }}


================================================
FILE: .github/workflows/test.yml
================================================
# https://github.com/kentcdodds/kentcdodds.com/blob/main/.github/workflows/deployment.yml
name: Tests
on:
  push:
    branches:
      - "main"
  pull_request:
    branches: [main]

jobs:
  tests:
    name: 🧪 Tests
    runs-on: ubuntu-latest
    timeout-minutes: 15
    services:
      sqld:
        image: ghcr.io/tursodatabase/libsql-server:latest
        ports:
          - 8080:8080
        # env:
        #   SQLD_HTTP_AUTH: "basic:token"

    env:
      TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
      TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
      DATABASE_URL: http://127.0.0.1:8080
      DATABASE_AUTH_TOKEN: "basic:token"
    steps:
      - name: ⬇️ Checkout repo
        uses: actions/checkout@v6

      - name: Set up pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 10.26.0

      - name: ⎔ Setup node
        uses: actions/setup-node@v6
        with:
          node-version: 24
          cache: "pnpm"

      - name: 🔥 Install bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest

      - name: 📥 Download deps
        run: pnpm install

      - name: 🗃️ Run migrations
        run: pnpm migrate
        working-directory: ./packages/db

      - name: 💽  Seed database
        run: pnpm seed
        working-directory: ./packages/db

      - name: 🧪 Tests
        run: pnpm test


================================================
FILE: .github/workflows/workflow-preview.yml
================================================
name: Fly Preview Workflows
on:
  workflow_dispatch:
    inputs:
      action:
        description: "Action to perform"
        required: true
        type: choice
        options:
          - deploy
          - destroy

permissions:
  contents: read
  deployments: write

env:
    FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
    FLY_REGION: ams
    FLY_ORG: openstatus
    APP_NAME: openstatus-workflows-preview-${{ github.ref_name }}

jobs:
  deploy:
    if: ${{ github.event.inputs.action == 'deploy' }}
    runs-on: ubuntu-latest
    timeout-minutes: 15
    concurrency:
      group: workflows-preview-${{ github.ref_name }}
    environment:
      name: workflows-preview-${{ github.ref_name }}
      url: https://${{ env.APP_NAME }}.fly.dev
    steps:
      - name: Get code
        uses: actions/checkout@v4

      - name: Setup Fly.io CLI
        uses: superfly/flyctl-actions/setup-flyctl@master

      - name: Create app if not exists
        run: flyctl apps create ${{ env.APP_NAME }} --org ${{ env.FLY_ORG }} || true

      - name: Set secrets
        run: |
          flyctl secrets set \
            DATABASE_URL="${{ secrets.STAGING_DB_URL }}" \
            DATABASE_AUTH_TOKEN="${{ secrets.STAGING_DB_AUTH_TOKEN }}" \
            RESEND_API_KEY="${{ secrets.STAGING_RESEND_API_KEY }}" \
            UPSTASH_REDIS_REST_URL=test \
            UPSTASH_REDIS_REST_TOKEN=test \
            GCP_PROJECT_ID=test \
            --app ${{ env.APP_NAME }}

      - name: Deploy to Fly.io
        run: |
          flyctl deploy \
            --config apps/workflows/fly.toml \
            --app ${{ env.APP_NAME }} \
            --region ${{ env.FLY_REGION }} \
            --vm-size shared-cpu-1x \
            --yes

  destroy:
    if: ${{ github.event.inputs.action == 'destroy' }}
    runs-on: ubuntu-latest
    timeout-minutes: 5
    steps:
      - name: Setup Fly.io CLI
        uses: superfly/flyctl-actions/setup-flyctl@master

      - name: Destroy app
        run: flyctl apps destroy ${{ env.APP_NAME }} --yes || true

      - name: Clean up GitHub environment
        uses: strumwolf/delete-deployment-environment@v2
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          environment: workflows-preview-${{ github.ref_name }}


================================================
FILE: .gitignore
================================================
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
node_modules
.pnp
.pnp.js

# testing
coverage

# next.js
.next/
out/
build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
.env*.local

# turbo
.turbo

# vercel
.vercel
.venv
# packages
dist
packages/emails/.react-email
packages/db/database.db
packages/db/openstatus.db
packages/db/database.db-wal
packages/db/database.db-shm
packages/db/openstatus.db-shm
packages/db/openstatus.db-wal
openstatus.db-wal
openstatus.db
openstatus.db-shm

packages/tinybird/.tinyb
apps/web/tsconfig.tsbuildinfo
openstatus-test.db
openstatus-test.db-shm
openstatus-test.db-wal

#webstorm
.idea

.wrangler
apps/web/.env.dev
packages/db/.env.dev
openstatus-dev.db
openstatus-dev.db-wal
openstatus-dev.db-shm
apps/ingest-worker/.production.vars
apps/ingest-worker/.dev.vars
apps/alerting-engine/tmp/

.env.docker

# UI Registry build output
apps/web/public/r
packages/ui/public/r
# For vibing
research.md
plan.md

.zed

*.tsbuildinfo

.claude/skills/**
.agents/skills/**
skills-lock.json


================================================
FILE: .koyebignore
================================================
*
!.koyebignore

!/apps/checker/*


================================================
FILE: .npmrc
================================================
auto-install-peers = true


================================================
FILE: .oxlintrc.json
================================================
{
  "$schema": "./node_modules/oxlint/configuration_schema.json",
  "ignorePatterns": ["**/*.test.ts", "**/*_pb.ts"]
}


================================================
FILE: .prettierignore
================================================
**/.content-collections


================================================
FILE: .stacked.toml
================================================
mainBranch = "main"
draft = true


================================================
FILE: .vscode/settings.json
================================================
{
  "editor.codeActionsOnSave": {
    "source.organizeImports.biome": "explicit"
  },
  "editor.defaultFormatter": "biomejs.biome",
  "editor.formatOnSave": true,
  "typescript.tsdk": "node_modules/typescript/lib",

  "typescript.enablePromptUseWorkspaceTsdk": true,
  "[dotenv]": {
    "editor.defaultFormatter": "foxundermoon.shell-format"
  },
  "[dockerfile]": {
    "editor.defaultFormatter": "ms-azuretools.vscode-docker"
  },
  "[xml]": {
    "editor.defaultFormatter": "redhat.vscode-xml"
  },
  "[go]": {
    "editor.defaultFormatter": "golang.go"
  },
  "[ignore]": {
    "editor.defaultFormatter": "foxundermoon.shell-format"
  },
  "go.lintTool": "golangci-lint",
  "go.lintFlags": ["--fast"],
  "gopls": {
    "ui.diagnostic.analyses": {
      "fieldalignment": true
    }
  }
}


================================================
FILE: CLAUDE.md
================================================
# Agent.md

This file provides a comprehensive overview of the OpenStatus project, its architecture, and development conventions to be used as instructional context for future interactions.

## Project Overview

OpenStatus is an open-source synthetic monitoring platform. It allows users to monitor their websites and APIs from multiple locations and receive notifications when they are down or slow.

The project is a monorepo managed with pnpm workspaces and Turborepo. It consists of several applications and packages that work together to provide a complete monitoring solution.

### Core Technologies

-   **Frontend:**
    -   Next.js (with Turbopack)
    -   React
    -   Tailwind CSS
    -   shadcn/ui
    -   tRPC
-   **Backend:**
    -   Hono (Node.js framework)
    -   Go
-   **Database:**
    -   Turso (libSQL)
    -   Drizzle ORM
-   **Data Analytics:**
    -   Tinybird
-   **Authentication:**
    -   NextAuth.js
-   **Build System:**
    -   Turborepo

### Architecture

The OpenStatus platform is composed of three main applications:

-   **`apps/dashboard`**: A Next.js application that provides the main user interface for managing monitors, viewing status pages, and configuring notifications.
-   **`apps/server`**: A Hono-based backend server that provides the API for the dashboard application.
-   **`apps/checker`**: A Go application responsible for performing the actual monitoring checks from different locations.

These applications are supported by a collection of shared packages in the `packages/` directory, which provide common functionality such as database access, UI components, and utility functions.

## Building and Running

The project can be run using Docker (recommended) or a manual setup.

### With Docker

1.  Copy the example environment file:
    ```sh
    cp .env.docker.example .env.docker
    ```
2.  Start all services:
    ```sh
    docker compose up -d
    ```
3.  Access the applications:
    -   Dashboard: `http://localhost:3002`
    -   Status Pages: `http://localhost:3003`

### Manual Setup

1.  Install dependencies:
    ```sh
    pnpm install
    ```
2.  Initialize the development environment:
    ```sh
    pnpm dx
    ```
3.  Run a specific application:
    ```sh
    pnpm dev:dashboard
    pnpm dev:status-page
    pnpm dev:web
    ```

### Running Tests

To run the test suite, use the following command:

Before running the test you should launch turso dev in a separate terminal:
```sh
turso dev
```

Then, seed the database with test data:

```sh
cd packages/db
pnpm migrate 
pnpm seed
```

Then run the tests with:

```sh
pnpm test
```

## Development Conventions

-   **Monorepo:** The project is organized as a monorepo using pnpm workspaces. All applications and packages are located in the `apps/` and `packages/` directories, respectively.
-   **Build System:** Turborepo is used to manage the build process. The `turbo.json` file defines the build pipeline and dependencies between tasks.
-   **Linting and Formatting:** The project uses Biome for linting and formatting. The configuration can be found in the `biome.jsonc` file.
-   **Code Generation:** The project uses `drizzle-kit` for database schema migrations.
-   **API:** The backend API is built using Hono and tRPC. The API is documented using OpenAPI.


================================================
FILE: CONTRIBUTING.MD
================================================
# Contribution Guidelines

Thank you for considering contributing to this project! We appreciate your efforts to make it better.

To contribute to this project, please follow these guidelines:

## Table of Contents

- [Reporting Issues](#reporting-issues)
- [Feature Requests](#feature-requests)
- [Submitting Changes](#submitting-changes)
- [Coding Conventions](#coding-conventions)
- [Documentation](#documentation)


## Reporting Issues

If you encounter any problems or bugs while using this project, please report them by opening a GitHub issue. Before creating a new issue, please check if a similar one already exists to avoid duplicates. When reporting issues, provide a clear and concise description of the problem, including steps to reproduce it, expected behavior, and any relevant screenshots or error messages.

## Feature Requests

If you have ideas for new features or improvements, you can submit a GitHub issue as well. Clearly describe the feature or improvement you would like to see and provide any additional context or examples that might be helpful. Feature requests help us understand your needs and prioritize the project's development.

## Submitting Changes

To contribute code changes, follow these steps:

1. Fork the repository and create a new branch for your changes.
2. Ensure that your code follows the project's coding conventions and style guide.
3. Make commits with clear and descriptive messages. Each commit should have a single logical purpose.
4. Push your branch to your forked repository.
5. Open a pull request (PR) from your branch to the original repository's `main` branch.
6. Provide a detailed description of your changes in the PR, including any related issues or feature requests.

A project maintainer will review your PR, provide feedback if necessary, and merge it once it meets the project's standards.

## Coding Conventions

Please adhere to the existing coding conventions and style guide used in this project. Consistent coding styles improve code readability and maintainability. If you're unsure about any aspect of the coding conventions, feel free to ask for clarification in your PR.

## Documentation

Improvements to documentation are always welcome. If you find any inaccuracies, missing information, or have suggestions for improving the documentation, you can contribute by submitting a PR with your changes. Make sure to clearly explain the purpose of the documentation update and provide relevant examples, if applicable.



================================================
FILE: COOLIFY_DEPLOYMENT.md
================================================
# Coolify Deployment Guide

This guide explains how to deploy OpenStatus using Coolify with pre-built Docker images from GitHub Container Registry.

## Prerequisites

- Coolify instance (self-hosted or cloud)
- GitHub account with access to the repository
- Environment variables configured

## Available Docker Images

All images are published to `ghcr.io/openstatusHQ/openstatus-*`:

- `ghcr.io/openstatusHQ/openstatus-server:latest` - Main API server
- `ghcr.io/openstatusHQ/openstatus-dashboard:latest` - Web dashboard
- `ghcr.io/openstatusHQ/openstatus-workflows:latest` - Workflow engine
- `ghcr.io/openstatusHQ/openstatus-private-location:latest` - Private monitoring agent
- `ghcr.io/openstatusHQ/openstatus-status-page:latest` - Public status page
- `ghcr.io/openstatusHQ/openstatus-checker:latest` - Monitoring checker service

## Coolify Setup

### 1. Create a New Application

1. In Coolify, click "Add New" → "Application"
2. Choose "Docker" as the application type
3. Select "Public Repository" for the image source

### 2. Configure Each Service

#### Server Service
- **Image**: `ghcr.io/openstatusHQ/openstatus-server:latest`
- **Port**: 3000
- **Environment Variables**:
  ```yaml
  DATABASE_URL: http://libsql:8080
  PORT: 3000
  # Add other required variables from .env.docker
  ```

#### Dashboard Service
- **Image**: `ghcr.io/openstatusHQ/openstatus-dashboard:latest`
- **Port**: 3000
- **Environment Variables**:
  ```yaml
  DATABASE_URL: http://libsql:8080
  PORT: 3000
  HOSTNAME: 0.0.0.0
  AUTH_TRUST_HOST: true
  ```

#### Workflows Service
- **Image**: `ghcr.io/openstatusHQ/openstatus-workflows:latest`
- **Port**: 3000
- **Environment Variables**:
  ```yaml
  DATABASE_URL: http://libsql:8080
  PORT: 3000
  ```

#### Private Location Service
- **Image**: `ghcr.io/openstatusHQ/openstatus-private-location:latest`
- **Port**: 8080
- **Environment Variables**:
  ```yaml
  DB_URL: http://libsql:8080
  TINYBIRD_URL: http://tinybird-local:7181
  GIN_MODE: release
  PORT: 8080
  ```

#### Checker Service
- **Image**: `ghcr.io/openstatusHQ/openstatus-checker:latest`
- **Port**: 8080
- **Environment Variables**:
  ```yaml
  DATABASE_URL: http://libsql:8080
  PORT: 8080
  ```

#### Status Page Service
- **Image**: `ghcr.io/openstatusHQ/openstatus-status-page:latest`
- **Port**: 3000
- **Environment Variables**:
  ```yaml
  DATABASE_URL: http://libsql:8080
  PORT: 3000
  HOSTNAME: 0.0.0.0
  AUTH_TRUST_HOST: true
  ```

### 3. External Dependencies

#### LibSQL Database
- **Image**: `ghcr.io/tursodatabase/libsql-server:latest`
- **Port**: 8080
- **Environment Variables**:
  ```yaml
  SQLD_NODE: primary
  ```

#### TinyBird (Optional)
- **Image**: `tinybirdco/tinybird-local:latest`
- **Port**: 7181
- **Environment Variables**:
  ```yaml
  COMPATIBILITY_MODE: 1
  ```

### 4. Network Configuration

1. Create a shared network for all services
2. Ensure services can communicate using container names
3. Configure health checks for each service

### 5. Deployment Order

Deploy services in this order:
1. LibSQL (database)
2. TinyBird (if used)
3. Workflows
4. Server
5. Private Location
6. Checker
7. Dashboard
8. Status Page

## Environment Variables

Create a `.env` file with all required variables. Refer to `.env.docker.example` in the repository for the complete list.

## Health Checks

All images include built-in health checks:
- **Server/Workflows**: `curl -f http://localhost:3000/ping`
- **Dashboard/Status Page**: `curl -f http://localhost:3000/`
- **Private Location**: `wget --spider -q http://localhost:8080/health`
- **Checker**: `curl -f http://localhost:8080/health`

## Version Management

- `latest` tag points to the latest main branch build
- Specific commits are tagged with their SHA
- Use specific tags for production deployments

## Troubleshooting

### Image Pull Issues
Ensure Coolify has access to GitHub Container Registry:
1. Add GitHub token as a registry credential in Coolify
2. Use `GITHUB_TOKEN` with `packages: read` permissions

### Service Communication
- Verify all services are on the same network
- Check container names match the configuration
- Ensure ports are correctly mapped

### Database Connection
- Wait for LibSQL to be fully healthy before starting other services
- Verify the DATABASE_URL format: `http://libsql:8080`

## Updates

Images are automatically built and pushed when:
- Code is pushed to the main branch
- Manual workflow dispatch is triggered

To update in Coolify:
1. Pull new images
2. Redeploy services in the correct order
3. Verify health checks pass

## Support

- Check the GitHub Actions workflows for build status
- Review container logs in Coolify
- Open an issue for deployment problems


================================================
FILE: COOLIFY_ENVIRONMENT_GUIDE.md
================================================
# Coolify Environment Variables Setup Guide

This guide explains how to configure environment variables for OpenStatus deployment in Coolify.

## 🚀 Quick Setup

### Step 1: Import the Stack
1. In Coolify dashboard, click **"New Service"** → **"Docker Compose"**
2. Choose **"Import from URL"** and enter:
   ```
   https://raw.githubusercontent.com/openstatusHQ/openstatus/main/coolify-deployment.yaml
   ```
3. Click **"Deploy"**

### Step 2: Configure Environment Variables
1. After deployment, click on the **OpenStatus stack**
2. Go to **"Settings"** → **"Environment Variables"**
3. Add the required variables below

## 🔧 Required Environment Variables

### **Core Database & Authentication**
```bash
# Database Connection
DATABASE_URL=http://libsql:8080
DATABASE_AUTH_TOKEN=

# Authentication
AUTH_SECRET=your-32-character-secret-here
NEXT_PUBLIC_URL=https://your-domain.com
SELF_HOST=true
```

### **Email Service (Required for Login)**
```bash
RESEND_API_KEY=re_your_resend_api_key_here
```

## 🔧 Optional Environment Variables

### **Analytics (TinyBird)**
```bash
TINY_BIRD_API_KEY=your_tinybird_api_key
TINYBIRD_URL=http://tinybird:7181
```

### **OAuth Providers**
```bash
# GitHub OAuth
AUTH_GITHUB_ID=your_github_oauth_id
AUTH_GITHUB_SECRET=your_github_oauth_secret

# Google OAuth
AUTH_GOOGLE_ID=your_google_oauth_id
AUTH_GOOGLE_SECRET=your_google_oauth_secret
```

### **Redis & Queue (Optional)**
```bash
UPSTASH_REDIS_REST_URL=http://localhost:6379
UPSTASH_REDIS_REST_TOKEN=your_redis_token
QSTASH_CURRENT_SIGNING_KEY=your_qstash_key
QSTASH_NEXT_SIGNING_KEY=your_qstash_key
QSTASH_TOKEN=your_qstash_token
QSTASH_URL=https://qstash.upstash.io/v1/publish/
```

### **Google Cloud (Optional)**
```bash
GCP_PROJECT_ID=your_gcp_project_id
GCP_LOCATION=your_gcp_location
GCP_CLIENT_EMAIL=your_gcp_service_account
GCP_PRIVATE_KEY=your_gcp_private_key
CRON_SECRET=your_cron_secret
```

### **API Keys (Optional)**
```bash
UNKEY_API_ID=your_unkey_api_id
UNKEY_TOKEN=your_unkey_token
SUPER_ADMIN_TOKEN=your_super_admin_token
FLY_REGION=self-hosted
```

### **Stripe (Optional)**
```bash
STRIPE_SECRET_KEY=sk_test_your_stripe_secret
STRIPE_WEBHOOK_SECRET_KEY=whsec_your_webhook_secret
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_your_publishable_key
```

### **Vercel (Optional)**
```bash
PROJECT_ID_VERCEL=your_vercel_project_id
TEAM_ID_VERCEL=your_vercel_team_id
VERCEL_AUTH_BEARER_TOKEN=your_vercel_token
BLOB_READ_WRITE_TOKEN=your_vercel_blob_token
```

### **Observability (Optional)**
```bash
NEXT_PUBLIC_SENTRY_DSN=your_sentry_dsn
SENTRY_AUTH_TOKEN=your_sentry_auth_token
NEXT_PUBLIC_OPENPANEL_CLIENT_ID=your_openpanel_client_id
OPENPANEL_CLIENT_SECRET=your_openpanel_client_secret
PAGERDUTY_APP_ID=your_pagerduty_app_id
SLACK_SUPPORT_WEBHOOK_URL=your_slack_webhook_url
TELEGRAM_BOT_TOKEN=your_telegram_bot_token
```

### **External Services (Optional)**
```bash
OPENSTATUS_INGEST_URL=https://openstatus-private-location.fly.dev
SCREENSHOT_SERVICE_URL=your_screenshot_service_url
```

### **Development & Testing (Optional)**
```bash
TURBO_ENV_MODE=loose
PLAYGROUND_UNKEY_API_KEY=your_playground_key
WORKSPACES_LOOKBACK_30=true
WORKSPACES_HIDE_URL=false
```

## 🔍 Environment Variable Visibility in Coolify

### **Where to Find Environment Variables**
1. **Stack Settings**: Click on your OpenStatus stack
2. **Environment Tab**: Look for "Environment Variables" section
3. **Add Variables**: Click "Add Variable" for each required variable
4. **Apply Changes**: Save and redeploy the stack

### **Variable Categories in Coolify UI**
- **Database**: `DATABASE_URL`, `DATABASE_AUTH_TOKEN`
- **Authentication**: `AUTH_SECRET`, `NEXT_PUBLIC_URL`, `SELF_HOST`
- **Email**: `RESEND_API_KEY`
- **Analytics**: `TINY_BIRD_API_KEY`, `TINYBIRD_URL`
- **OAuth**: `AUTH_GITHUB_*`, `AUTH_GOOGLE_*`
- **Queue**: `UPSTASH_*`, `QSTASH_*`
- **Cloud**: `GCP_*`, `CRON_SECRET`
- **API Keys**: `UNKEY_*`, `SUPER_ADMIN_TOKEN`, `FLY_REGION`
- **Payments**: `STRIPE_*`, `NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY`
- **Vercel**: `PROJECT_ID_VERCEL`, `TEAM_ID_VERCEL`, `VERCEL_*`
- **Observability**: `NEXT_PUBLIC_SENTRY_DSN`, `SENTRY_*`, `OPENPANEL_*`
- **External**: `OPENSTATUS_INGEST_URL`, `SCREENSHOT_SERVICE_URL`
- **Development**: `TURBO_ENV_MODE`, `PLAYGROUND_*`, `WORKSPACES_*`

## 🚨 Troubleshooting

### **Environment Variables Not Working?**
1. **Check Stack Logs**: Look for environment variable errors
2. **Verify Variable Names**: Ensure exact match with this guide
3. **Redeploy**: Sometimes requires full stack restart
4. **Check Coolify Docs**: Some variables may need special handling

### **Common Issues**
- **DATABASE_URL**: Must be `http://libsql:8080` (internal container communication)
- **AUTH_SECRET**: Must be at least 32 characters
- **NEXT_PUBLIC_URL**: Must include protocol (http:// or https://)
- **RESEND_API_KEY**: Required for email login functionality

### **Getting Help**
- **Coolify Documentation**: Check Coolify's environment variables guide
- **OpenStatus Docs**: Visit [OpenStatus Documentation](https://github.com/openstatusHQ/openstatus)
- **Community Support**: Open an issue in the GitHub repository

## 🎯 Production Deployment

### **Minimum Required Variables**
For a basic working deployment, you only need:
```bash
DATABASE_URL=http://libsql:8080
DATABASE_AUTH_TOKEN=
AUTH_SECRET=your-32-char-secret
NEXT_PUBLIC_URL=https://your-domain.com
RESEND_API_KEY=your-resend-key
```

### **Testing Your Setup**
1. Deploy with minimum variables first
2. Check if services start correctly
3. Add optional variables incrementally
4. Test each feature as you add variables

This ensures a smooth, working deployment! 🚀


================================================
FILE: COOLIFY_SETUP.md
================================================
# Coolify Setup Guide

This guide provides step-by-step instructions for deploying OpenStatus on Coolify using pre-built Docker images.

## Quick Start

### Option 1: Import Complete Stack

1. In Coolify dashboard, click **"New Service"** → **"Docker Compose"**
2. Choose **"Import from URL"** and enter:
   ```
   https://raw.githubusercontent.com/openstatusHQ/openstatus/main/coolify-deployment.yaml
   ```
3. Configure your environment variables
4. Click **"Deploy"**

### Option 2: Manual Service Setup

Create each service individually using the configurations below.

## Environment Setup

### Setup

1. **Copy the example file**:
   ```bash
   cp .env.docker.example .env.docker
   ```
2. **Edit the file** with your values:
   ```bash
   nano .env.docker
   ```
3. **Required variables**:
   - `DATABASE_URL=http://libsql:8080`
   - `AUTH_SECRET=your-32-char-secret`
   - `RESEND_API_KEY=your-resend-key`
   - `NEXT_PUBLIC_URL=http://your-domain:3002`

## Service Configurations

### 1. Database Services

#### LibSQL Database
- **Image**: `ghcr.io/tursodatabase/libsql-server:latest`
- **Name**: `openstatus-libsql`
- **Port**: `8080`
- **Environment Variables**:
  ```
  SQLD_NODE=primary
  ```
- **Volumes**: `openstatus-libsql-data:/var/lib/sqld`
- **Health Check**: `curl -f http://localhost:8080`

#### TinyBird (Optional)
- **Image**: `tinybirdco/tinybird-local:latest`
- **Name**: `openstatus-tinybird`
- **Port**: `7181`
- **Environment Variables**:
  ```
  COMPATIBILITY_MODE=1
  ```

### 2. Core Services

#### Workflows Engine
- **Image**: `ghcr.io/openstatusHQ/openstatus-workflows:latest`
- **Name**: `openstatus-workflows`
- **Port**: `3000`
- **Environment Variables**:
  ```
  DATABASE_URL=http://libsql:8080
  PORT=3000
  NODE_ENV=production
  ```
- **Volumes**: `./data:/app/data`
- **Depends On**: `openstatus-libsql`

#### API Server
- **Image**: `ghcr.io/openstatusHQ/openstatus-server:latest`
- **Name**: `openstatus-server`
- **Port**: `3001`
- **Environment Variables**:
  ```
  DATABASE_URL=http://libsql:8080
  PORT=3000
  NODE_ENV=production
  ```
- **Depends On**: `openstatus-workflows`, `openstatus-libsql`

#### Private Location Agent
- **Image**: `ghcr.io/openstatusHQ/openstatus-private-location:latest`
- **Name**: `openstatus-private-location`
- **Port**: `8081`
- **Environment Variables**:
  ```
  DB_URL=http://libsql:8080
  TINYBIRD_URL=http://tinybird:7181
  GIN_MODE=release
  PORT=8080
  NODE_ENV=production
  ```
- **Depends On**: `openstatus-server`

#### Checker Service
- **Image**: `ghcr.io/openstatusHQ/openstatus-checker:latest`
- **Name**: `openstatus-checker`
- **Port**: `8082`
- **Environment Variables**:
  ```
  DATABASE_URL=http://libsql:8080
  PORT=8080
  NODE_ENV=production
  ```
- **Depends On**: `openstatus-server`

#### Web Dashboard
- **Image**: `ghcr.io/openstatusHQ/openstatus-dashboard:latest`
- **Name**: `openstatus-dashboard`
- **Port**: `3002`
- **Environment Variables**:
  ```
  DATABASE_URL=http://libsql:8080
  PORT=3000
  HOSTNAME=0.0.0.0
  AUTH_TRUST_HOST=true
  NODE_ENV=production
  ```
- **Depends On**: `openstatus-workflows`, `openstatus-libsql`, `openstatus-server`

#### Status Page
- **Image**: `ghcr.io/openstatusHQ/openstatus-status-page:latest`
- **Name**: `openstatus-status-page`
- **Port**: `3003`
- **Environment Variables**:
  ```
  DATABASE_URL=http://libsql:8080
  PORT=3000
  HOSTNAME=0.0.0.0
  AUTH_TRUST_HOST=true
  NODE_ENV=production
  ```
- **Depends On**: `openstatus-workflows`, `openstatus-libsql`, `openstatus-server`

## Environment Variables

Create a `.env.docker` file with the following variables:

```bash
# Database
DATABASE_URL=http://libsql:8080

# Authentication
NEXTAUTH_SECRET=your-secret-key-here
NEXTAUTH_URL=http://localhost:3002

# External Services
RESEND_API_KEY=your-resend-api-key
UPSTASH_REDIS_REST_URL=your-upstash-url
UPSTASH_REDIS_REST_TOKEN=your-upstash-token

# TinyBird
TINYBIRD_TOKEN=your-tinybird-token
TINYBIRD_URL=http://tinybird:7181

# Other
ENCRYPTION_KEY=your-encryption-key
```

## Network Configuration

1. **Create Network**: In Coolify, create a network named `openstatus`
2. **Attach Services**: Ensure all services are attached to this network
3. **Service Discovery**: Services can communicate using container names as hostnames

## Deployment Order

Deploy services in this sequence:

1. **libsql** (Database)
2. **tinybird** (Optional - Analytics)
3. **workflows** (Workflow Engine)
4. **server** (API Server)
5. **private-location** (Monitoring Agent)
6. **checker** (Health Checker)
7. **dashboard** (Web Interface)
8. **status-page** (Public Status)

## Resource Allocation

Recommended resource limits for each service:

| Service | Memory Limit | Memory Reservation |
|----------|---------------|-------------------|
| libsql | 512MB | 256MB |
| tinybird | 1GB | 512MB |
| workflows | 512MB | 256MB |
| server | 512MB | 256MB |
| private-location | 256MB | 128MB |
| checker | 256MB | 128MB |
| dashboard | 512MB | 256MB |
| status-page | 512MB | 256MB |

## Health Checks

All services include built-in health checks:

- **API Services**: `curl -f http://localhost:3000/ping`
- **Web Services**: `curl -f http://localhost:3000/`
- **Private Location**: `wget --spider -q http://localhost:8080/health`

## Access URLs

After deployment, access services at:

- **Dashboard**: `http://your-domain:3002`
- **API Server**: `http://your-domain:3001`
- **Status Page**: `http://your-domain:3003`
- **Workflows**: `http://your-domain:3000`

## Troubleshooting

### Common Issues

1. **Service Not Starting**
   - Check environment variables
   - Verify network connectivity
   - Review service logs

2. **Database Connection Failed**
   - Ensure libsql is healthy first
   - Check DATABASE_URL format
   - Verify network configuration

3. **Health Check Failing**
   - Wait for full startup (30-60 seconds)
   - Check if required ports are available
   - Review service dependencies

### Log Locations

In Coolify, access logs via:
1. Service → **Logs** tab
2. **Real-time** streaming logs
3. **Historical** log files

### Updates

To update services:
1. Pull new images in Coolify
2. Redeploy affected services
3. Verify health checks pass

## Production Considerations

1. **SSL/TLS**: Configure HTTPS in Coolify
2. **Backups**: Enable automated backups for database
3. **Monitoring**: Set up external monitoring
4. **Scaling**: Configure resource limits based on usage
5. **Security**: Update images regularly, use secrets management

## Support

- **Documentation**: [OpenStatus Docs](https://docs.openstatus.dev)
- **Issues**: [GitHub Issues](https://github.com/openstatusHQ/openstatus/issues)
- **Community**: [Discord](https://www.openstatus.dev/discord)


================================================
FILE: DOCKER.md
================================================
# Docker Setup Guide

Complete guide for running OpenStatus with Docker

## Quick Start

```bash
# 1. Copy environment file
cp .env.docker.example .env.docker

# 2. Configure required variables (see Configuration section)
vim .env.docker

# 3. Build and start services (migrations will run automatically)
export DOCKER_BUILDKIT=1
docker compose up -d

# 4. Check service health
docker compose ps

# 5. (Optional) Seed database with test data
docker run --rm --network openstatus \
  -e DATABASE_URL=http://libsql:8080 \
  $(docker build -q -f apps/workflows/Dockerfile --target build .) \
  sh -c "cd /app/packages/db && bun src/seed.mts"

# 6. (Optional) Deploy Tinybird local - requires tb CLI
cd packages/tinybird
tb --local deploy

# 7. Access the application
open http://localhost:3002  # Dashboard
open http://localhost:3003  # Status Page Theme Explorer
# Note: Status pages are accessed via subdomain/slug (e.g., http://localhost:3003/status)
```

## Cleanup

```bash
# Remove stopped containers
docker compose down

# Remove volumes
docker compose down -v

# Clean build cache
docker builder prune
```

## Services

| Service | Port | Purpose |
|---------|------|---------|
| workflows | 3000 | Background jobs |
| server | 3001 | API backend (tRPC) |
| dashboard | 3002 | Admin interface |
| status-page | 3003 | Public status pages |
| private-location | 8081 | Monitoring agent |
| libsql | 8080 | Database (HTTP) |
| libsql | 5001 | Database (gRPC) |
| tinybird-local | 7181 | Analytics |


## Architecture

```
┌─────────────┐     ┌─────────────┐
│  Dashboard  │────▶│   Server    │
│  (Next.js)  │     │   (Bun)     │
└─────────────┘     └─────────────┘
      │                    │
      ▼                    ▼
┌─────────────┐     ┌─────────────┐
│ Status Page │     │  Workflows  │
│  (Next.js)  │     │   (Bun)     │
└─────────────┘     └─────────────┘
      │                    │
      └────────┬───────────┘
               ▼
        ┌─────────────┐
        │   LibSQL    │
        │  (Database) │
        └─────────────┘
```

## Database Setup

### Automatic Migrations

Migrations run **automatically** when you start the stack with `docker compose up -d`.

**Verifying migrations:**
```bash
# Check workflows logs for migration output
docker compose logs workflows | grep -A 5 "Running database migrations"

# Should show:
# openstatus-workflows  | Running database migrations...
# openstatus-workflows  | Migrated successfully
# openstatus-workflows  | Starting workflows service...
```

**Manual migration:**

If you need to re-run migrations or troubleshoot:

```bash
# Run migrations using workflows container
docker compose exec workflows sh -c "cd /app/packages/db && bun src/migrate.mts"

# Or restart workflows to trigger migrations again
docker compose restart workflows
```

### Seeding Test Data (Optional)

**Note:** Migrations run automatically, but seeding does **not**. You must manually seed the database if you want test data.

After migrations complete, seed the database with sample data:

```bash
docker run --rm --network openstatus \
  -e DATABASE_URL=http://libsql:8080 \
  $(docker build -q -f apps/workflows/Dockerfile --target build .) \
  sh -c "cd /app/packages/db && bun src/seed.mts"
```

This creates:
- 3 workspaces (`love-openstatus`, `test2`, `test3`)
- 5 sample monitors and 1 status page with slug `status`
- Test user account: `ping@openstatus.dev`
- Sample incidents, status reports, and maintenance windows

**Verifying seeded data:**
```bash
# Check table counts via libsql HTTP API
curl -s http://localhost:8080/ -H "Content-Type: application/json" \
  -d '{"statements":["SELECT COUNT(*) FROM page"]}' | jq -r '.[0].results.rows[0][0]'

# Should output: 1
```

**Accessing Seeded Data:**

After seeding, you can access the test data:

**Dashboard:**
1. Navigate to http://localhost:3002/login
2. Use magic link authentication with email: `ping@openstatus.dev`
3. Check your console/logs for the magic link (with `SELF_HOST=true` in `.env.docker`)
4. After logging in, you'll see the `love-openstatus` workspace with all seeded monitors and status page

**Status Page:**
- The seeded status page has slug `status`
- Access it via subdomain routing: http://status.localhost:3003
- Or view theme explorer at: http://localhost:3003

**If you use a different email address**, the system will create a new empty workspace for you instead of showing the seeded data. To access seeded data with a different account, you must add your user to the seeded workspace using SQL:

  ```bash
  # First, find your user_id
  curl -X POST http://localhost:8080/ -H "Content-Type: application/json" \
    -d '{"statements":["SELECT id, email FROM user"]}'

  # Then add association (replace USER_ID with your id)
  curl -X POST http://localhost:8080/ -H "Content-Type: application/json" \
    -d '{"statements":["INSERT INTO users_to_workspaces (user_id, workspace_id, role) VALUES (USER_ID, 1, '\''owner'\'')"]}'
  ```


## Tinybird Setup (Optional)

Tinybird is used for analytics and monitoring metrics. The application will work without it, but analytics features will be unavailable.

If you want to enable analytics, you can:
1. Use Tinybird Cloud and configure `TINY_BIRD_API_KEY` in `.env.docker`
2. Manually configure Tinybird Local (requires additional setup beyond this guide)

## Configuration

### Required Environment Variables

Edit `.env.docker` and set:

```bash
# Authentication
AUTH_SECRET=your-secret-here

# Database
DATABASE_URL=http://libsql:8080
DATABASE_AUTH_TOKEN=basic:token

# Email
RESEND_API_KEY=test
```

### Optional Services

Configure these for full functionality:

```bash
# Redis
UPSTASH_REDIS_REST_URL=
UPSTASH_REDIS_REST_TOKEN=

# Analytics
TINY_BIRD_API_KEY=

# OAuth providers
AUTH_GITHUB_ID=
AUTH_GITHUB_SECRET=
AUTH_GOOGLE_ID=
AUTH_GOOGLE_SECRET=
```

See [.env.docker.example](.env.docker.example) for complete list.

## Development Workflow

### Common Commands

```bash
# View logs
docker compose logs -f [service-name]

# Restart service
docker compose restart [service-name]

# Rebuild after code changes
docker compose up -d --build [service-name]

# Stop all services
docker compose down

# Reset database (removes all data)
docker compose down -v
docker compose up -d
# Migrations run automatically on startup
```

### Authentication

**Magic Link**:

Set `SELF_HOST=true` in `.env.docker` to enable email-based magic link authentication. This allows users to sign in without configuring OAuth providers.

**OAuth Providers**:

Configure GitHub/Google OAuth credentials in `.env.docker` and set up callback URLs:
  - GitHub: `http://localhost:3002/api/auth/callback/github`
  - Google: `http://localhost:3002/api/auth/callback/google`

### Creating Status Pages

**Via Dashboard (Recommended)**:
1. Login to http://localhost:3002
2. Create a workspace
3. Create a status page with a slug
4. Access at http://localhost:3003/[slug]

**Via Database (Testing)**:
```bash
# Insert test data
curl -s http://localhost:8080/v2/pipeline \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "requests":[{
      "type":"execute",
      "stmt":{
        "sql":"INSERT INTO workspace (id, slug, name) VALUES (1, '\''test'\'', '\''Test Workspace'\'');"
      }
    }]
  }'
```

### Resource Limits

Add to `docker-compose.yaml`:

```yaml
services:
  dashboard:
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 512M
```

## Monitoring

### Health Checks

All services have automated health checks:

```bash
# View health status
docker compose ps

# Inspect specific service
docker inspect openstatus-dashboard --format='{{.State.Health.Status}}'
```

## Getting Help

- **Documentation**: [docs.openstatus.dev](https://docs.openstatus.dev)
- **Discord**: [openstatus.dev/discord](https://www.openstatus.dev/discord)
- **GitHub Issues**: [github.com/openstatusHQ/openstatus/issues](https://github.com/openstatusHQ/openstatus/issues)


================================================
FILE: LICENSE
================================================
                    GNU AFFERO GENERAL PUBLIC LICENSE
                       Version 3, 19 November 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.

  A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate.  Many developers of free software are heartened and
encouraged by the resulting cooperation.  However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.

  The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community.  It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server.  Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.

  An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals.  This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU Affero General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Remote Network Interaction; Use with the GNU General Public License.

  Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software.  This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time.  Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

  If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source.  For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code.  There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<https://www.gnu.org/licenses/>.


================================================
FILE: README.md
================================================
<p align="center" style="margin-top: 120px">

  <h3 align="center">openstatus</h3>

  <p align="center">The open-source status page and uptime monitoring platform.
    <br />
    <a href="https://www.openstatus.dev"><strong>Learn more »</strong></a>
    <br />
    <br />
    <a href="https://docs.openstatus.dev">Documentation</a>
    ·
    <a href="https://www.openstatus.dev">Website</a>
    ·
    <a href="https://www.openstatus.dev/discord">Discord</a>
  </p>

  <p align="center">
  <a href="https://status.openstatus.dev"><img src="https://status.openstatus.dev/badge/v2?variant=outline" alt="openstatus status"></a>

  </p>
  <p align="center">
      <a href="https://github.com/openstatushq/openstatus/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-AGPL--3.0-blue.svg" alt="License"></a>
      <a href="https://github.com/openstatushq/openstatus/stargazers"><img src="https://img.shields.io/github/stars/openstatushq/openstatus?style=social" alt="GitHub stars"></a>
      <a href="https://www.openstatus.dev/discord"><img src="https://img.shields.io/discord/1129008226264940625?color=7289da&logo=discord&logoColor=white" alt="Discord"></a>
</p>

## About openstatus

openstatus is an open-source platform that combines **status pages** and **uptime monitoring** in a single tool. Keep your users informed and your services reliable. Available as a managed service or self-hosted.

### Status pages

Beautiful, customizable status pages with custom domains, password protection, maintenance windows, and subscriber notifications via email and RSS. Build trust and keep your users informed during incidents.

### Synthetic monitoring

Monitor your servers, websites and APIs from 28 regions across multiple cloud providers globally. Get notified via Slack, Discord, PagerDuty, email, and more when your services are down or slow.

## Recognitions

<a href="https://trendshift.io/repositories/1780" target="_blank"><img src="https://trendshift.io/api/badge/repositories/1780" alt="openstatus | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
<a href="https://news.ycombinator.com/item?id=37740870"><img alt="Featured on Hacker News" src="https://hackerbadge.now.sh/api?id=37740870" style="width: 250px; height: 55px;" width="250" height="55" /></a>
<a href="https://www.producthunt.com/posts/openstatus-2?utm_source=badge-top-post-badge&utm_medium=badge" target="_blank"><img alt="openstatus - #2 Product of the Day on Product Hunt" src="https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=openstatus-2&theme=light&period=daily" style="width: 250px; height: 55px;" width="250" height="55" /></a>

## Getting Started

### With Docker (Recommended)

The fastest way to get started for both development and self-hosting:

```sh
# 1. Copy environment file
cp .env.docker.example .env.docker

# 2. Start all services
docker compose up -d

# 3. Access the application
open http://localhost:3002  # Dashboard
open http://localhost:3003  # Status Pages
```

Full guide: [DOCKER.md](DOCKER.md)

### Self-Hosting with Coolify

We provide pre-built Docker images for easy deployment:

```bash
ghcr.io/openstatushq/openstatus-server:latest
ghcr.io/openstatushq/openstatus-dashboard:latest
ghcr.io/openstatushq/openstatus-workflows:latest
ghcr.io/openstatushq/openstatus-private-location:latest
ghcr.io/openstatushq/openstatus-status-page:latest
ghcr.io/openstatushq/openstatus-checker:latest
```

[Complete Coolify Deployment Guide](./COOLIFY_DEPLOYMENT.md)

### Manual Setup

#### Requirements

- [Node.js](https://nodejs.org/en/) >= 20.0.0
- [pnpm](https://pnpm.io/) >= 8.6.2
- [Bun](https://bun.sh/)
- [Turso CLI](https://docs.turso.tech/quickstart)

#### Setup

1. Clone the repository

```sh
git clone https://github.com/openstatushq/openstatus.git
```

2. Install dependencies

```sh
pnpm install
```

3. Initialize the development environment

Launch the database in one terminal:

```sh
turso dev --db-file openstatus-dev.db
```

In another terminal, run the following command:

```sh
pnpm dx
```

4. Launch whatever app you wish to:

```sh
pnpm dev:web
pnpm dev:status-page
pnpm dev:dashboard
```

The above commands will automatically run the libSQL client on `8080` so you might want to kill the turso command from step 3.

5. See the results:

- open [http://localhost:3000](http://localhost:3000) (default port)

## Tech Stack

- [Next.js](https://nextjs.org/) - Dashboard
- [Hono](https://hono.dev/) - API server
- [Go](https://go.dev/) - Checker
- [Turso](https://turso.tech/) - Database
- [Drizzle](https://orm.drizzle.team/) - ORM
- [Tinybird](https://tinybird.co/?ref=openstatus.dev) - Analytics
- [Tailwind CSS](https://tailwindcss.com/) - Styling
- [shadcn/ui](https://ui.shadcn.com/) - UI components

## Contributing

If you want to help us build the best status page and monitoring platform, check our [contributing guidelines](https://github.com/openstatusHQ/openstatus/blob/main/CONTRIBUTING.MD).

<a href="https://github.com/openstatushq/openstatus/graphs/contributors">
  <img src="https://contrib.rocks/image?repo=openstatushq/openstatus" />
</a>

![openstatus repository activity](https://repobeats.axiom.co/api/embed/180eee159c0128f683a30f15f51ac35bdbd9fa44.svg "Repobeats analytics image")

## Contact

Interested in our enterprise plan or need special features? Email us at [ping@openstatus.dev](mailto:ping@openstatus.dev) or book a call.

<a href="https://cal.com/team/openstatus/30min"><img alt="Book us with Cal.com" src="https://cal.com/book-with-cal-dark.svg" /></a>

## License

Distributed under the [AGPL-3.0 License](LICENSE).


================================================
FILE: SECURITY.md
================================================
# Reporting Security Issues

The openstatus team takes security bugs in opnestatus seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.

To report a security issue, please  reach out to us via email at [ping@openstatus](mailto:ping@openstatus.dev) or on Discord




## Please do the following:

- Do not run automated scanners on our infrastructure or dashboard. If you wish to do this, contact us and we will set up a sandbox for you.
- Do not take advantage of the vulnerability or problem you have discovered, for example by downloading more data than necessary to demonstrate the vulnerability or deleting or modifying other people's data,
- Do not reveal the problem to others until it has been resolved,
- Do not use attacks on physical security, social engineering, distributed denial of service, spam or applications of third parties,
- Do provide sufficient information to reproduce the problem, so we will be able to resolve it as quickly as possible. Usually, the IP address or the URL of the affected system and a description of the vulnerability will be sufficient, but complex vulnerabilities may require further explanation.



## What we promise:

- We will respond to your report within 3 business days with our evaluation of the report and an expected resolution date,
- If you have followed the instructions above, we will not take any legal action against you in regard to the report,
- We will handle your report with strict confidentiality, and not pass on your personal details to third parties without your permission,
- We will keep you informed of the progress towards resolving the problem,
- In the public information concerning the problem reported, we will give your name as the discoverer of the problem (unless you desire otherwise), and
- We strive to resolve all problems as quickly as possible, and we would like to play an active role in the ultimate publication on the problem after it is resolved.


================================================
FILE: apps/README.md
================================================
# Apps

All openstatus apps


================================================
FILE: apps/checker/.gitignore
================================================
tmp


================================================
FILE: apps/checker/.golangci.yml
================================================
version: "2"

linters:
  default: fast


================================================
FILE: apps/checker/.private.air.toml
================================================
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"

[build]
    args_bin = []
    bin = "./tmp/main"
    cmd = "go build -o ./tmp/main ./cmd/private/main.go"
    delay = 1000
    exclude_dir = ["assets", "tmp", "vendor", "testdata"]
    exclude_file = []
    exclude_regex = ["_test.go"]
    exclude_unchanged = false
    follow_symlink = false
    full_bin = ""
    include_dir = []
    include_ext = ["go", "tpl", "tmpl", "html"]
    include_file = []
    kill_delay = "0s"
    log = "build-errors.log"
    poll = false
    poll_interval = 0
    post_cmd = []
    pre_cmd = []
    rerun = false
    rerun_delay = 500
    send_interrupt = false
    stop_on_error = false


[color]
  app = ""
  build = "yellow"
  main = "magenta"
  runner = "green"
  watcher = "cyan"

[log]
  main_only = false
  time = false

[misc]
  clean_on_exit = false

[screen]
  clear_on_rebuild = false
  keep_scroll = true


================================================
FILE: apps/checker/.probe.air.toml
================================================
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"

[build]
    args_bin = []
    bin = "./tmp/main"
    cmd = "go build -o ./tmp/main ./cmd/server/main.go"
    delay = 1000
    exclude_dir = ["assets", "tmp", "vendor", "testdata"]
    exclude_file = []
    exclude_regex = ["_test.go"]
    exclude_unchanged = false
    follow_symlink = false
    full_bin = ""
    include_dir = []
    include_ext = ["go", "tpl", "tmpl", "html"]
    include_file = []
    kill_delay = "0s"
    log = "build-errors.log"
    poll = false
    poll_interval = 0
    post_cmd = []
    pre_cmd = []
    rerun = false
    rerun_delay = 500
    send_interrupt = false
    stop_on_error = false


[color]
  app = ""
  build = "yellow"
  main = "magenta"
  runner = "green"
  watcher = "cyan"

[log]
  main_only = false
  time = false

[misc]
  clean_on_exit = false

[screen]
  clear_on_rebuild = false
  keep_scroll = true


================================================
FILE: apps/checker/Dockerfile
================================================
FROM golang:1.26-alpine as builder

WORKDIR /go/src/app
COPY ca/ca-bundle.crt /usr/local/share/ca-certificates/ca-bundle.crt

RUN apk update \
&& apk upgrade --available \
&& update-ca-certificates

RUN apk add --no-cache tzdata
ENV TZ=UTC

ENV CGO_ENABLED=0
ENV GOOS=linux
ENV GOARCH=amd64

COPY go.* .
RUN go mod download

COPY . .
RUN go build -trimpath -ldflags "-s -w" -o checker ./cmd/server/main.go

FROM scratch

WORKDIR /opt/bin

COPY --from=builder /usr/local/share/ca-certificates/ca-bundle.crt /etc/ssl/certs/ca-bundle.crt
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt



COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo

COPY --from=builder /go/src/app/checker/main /opt/bin/checker

ENV TZ=UTC
ENV USER=1000
ENV GIN_MODE=release

CMD [ "/opt/bin/checker" ]


================================================
FILE: apps/checker/README.md
================================================
# OpenStatus Checker

The checker service to ping external service.

It pings the service and save thedata to the tinybird

## How to run

```bash
go run cmd/main.go
```

you can also set the env variable

```fish
set CRON_SECRET YOLO
set CLOUD_PROVIDER local
set TINYBIRD_TOKEN random
```

## How to build

```bash
go build -o checker *.go
```

## How to run in docker

```bash
docker build -t checker .
docker run -p 8080:8080 checker
```

## How to deploy

```bash
fly deploy
```

## Deploy to all region

```bash
fly scale count 35 --region   ams,arn,atl,bog,bom,bos,cdg,den,dfw,ewr,eze,fra,gdl,gig,gru,hkg,iad,jnb,lax,lhr,mad,mia,nrt,ord,otp,phx,qro,scl,sjc,sea,sin,syd,waw,yul,yyz
```

## Deploy to your own infra

Use our docker image

<https://github.com/openstatusHQ/openstatus/pkgs/container/checker>


================================================
FILE: apps/checker/ca/ca-bundle.crt
================================================
-----BEGIN CERTIFICATE-----
MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG
A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do
lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc
AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICPTCCAaYCEQDNun9W8N/kvFT+IqyzcqpVMA0GCSqGSIb3DQEBAgUAMF8xCzAJ
BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xh
c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05
NjAxMjkwMDAwMDBaFw0yODA4MDEyMzU5NTlaMF8xCzAJBgNVBAYTAlVTMRcwFQYD
VQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMSBQdWJsaWMgUHJp
bWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOB
jQAwgYkCgYEA5Rm/baNWYS2ZSHH2Z965jeu3noaACpEO+jglr0aIguVzqKCbJF0N
H8xlbgyw0FaEGIeaBpsQoXPftFg5a27B9hXVqKg/qhIGjTGsf7A01480Z4gJzRQR
4k5FVmkfeAKA2txHkSm7NsljXMXg1y2He6G3MrB7MLoqLzGq7qNn2tsCAwEAATAN
BgkqhkiG9w0BAQIFAAOBgQBMP7iLxmjf7kMzDl3ppssHhE16M/+SG/Q2rdiVIjZo
EWx8QszznC7EBz8UsA9P/5CSdvnivErpj82ggAr3xSnxgiJduLHdgSOjeyUVRjB5
FvjqBUuUfx3CHMjjt/QQQDwTw18fU+hI5Ia0e6E1sHslurjTjqs/OJ0ANACY89Fx
lA==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICPDCCAaUCED9pHoGc8JpK83P/uUii5N0wDQYJKoZIhvcNAQEFBQAwXzELMAkG
A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
cyAxIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAxIFB1YmxpYyBQcmlt
YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
ADCBiQKBgQDlGb9to1ZhLZlIcfZn3rmN67eehoAKkQ76OCWvRoiC5XOooJskXQ0f
zGVuDLDQVoQYh5oGmxChc9+0WDlrbsH2FdWoqD+qEgaNMax/sDTXjzRniAnNFBHi
TkVWaR94AoDa3EeRKbs2yWNcxeDXLYd7obcysHswuiovMaruo2fa2wIDAQABMA0G
CSqGSIb3DQEBBQUAA4GBAFgVKTk8d6PaXCUDfGD67gmZPCcQcMgMCeazh88K4hiW
NWLMv5sneYlfycQJ9M61Hd8qveXbhpxoJeUwfLaJFf5n0a3hUKw8fGJLj7qE1xIV
Gx/KXQ/BUpQqEZnae88MNhPVNdwQGVnqlMEAv3WP2fr9dgTbYruQagPZRjXZ+Hxb
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICPDCCAaUCEC0b/EoXjaOR6+f/9YtFvgswDQYJKoZIhvcNAQECBQAwXzELMAkG
A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
cyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAyIFB1YmxpYyBQcmlt
YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
ADCBiQKBgQC2WoujDWojg4BrzzmH9CETMwZMJaLtVRKXxaeAufqDwSCg+i8VDXyh
YGt+eSz6Bg86rvYbb7HS/y8oUl+DfUvEerf4Zh+AVPy3wo5ZShRXRtGak75BkQO7
FYCTXOvnzAhsPz6zSvz/S2wj1VCCJkQZjiPDceoZJEcEnnW/yKYAHwIDAQABMA0G
CSqGSIb3DQEBAgUAA4GBAIobK/o5wXTXXtgZZKJYSi034DNHD6zt96rbHuSLBlxg
J8pFUs4W7z8GZOeUaHxgMxURaa+dYo2jA1Rrpr7l7gUYYAS/QoD90KioHgE796Nc
r6Pc5iaAIzy4RHT3Cq5Ji2F4zCS/iIqnDupzGUH9TQPwiNHleI2lKk/2lw0Xd8rY
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICPDCCAaUCEAq6HgBiMui0NiZdH3zNiWYwDQYJKoZIhvcNAQEFBQAwXzELMAkG
A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
cyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAyIFB1YmxpYyBQcmlt
YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
ADCBiQKBgQC2WoujDWojg4BrzzmH9CETMwZMJaLtVRKXxaeAufqDwSCg+i8VDXyh
YGt+eSz6Bg86rvYbb7HS/y8oUl+DfUvEerf4Zh+AVPy3wo5ZShRXRtGak75BkQO7
FYCTXOvnzAhsPz6zSvz/S2wj1VCCJkQZjiPDceoZJEcEnnW/yKYAHwIDAQABMA0G
CSqGSIb3DQEBBQUAA4GBAIDToA+IyeVoW4R7gB+nt+MjWBEc9RTwWBKMi99x2ZAk
EXyge8N6GRm9cr0gvwA63/rVeszC42JFi8tJg5jBcGnQnl6CjDVHjk8btB9jAa3k
ltax7nosZm4XNq8afjgGhixrTcsnkm54vwDVAcCxB8MJqmSFKPKdc57PYDoKHUpI
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkG
A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
CSqGSIb3DQEBBQUAA4GBABByUqkFFBkyCEHwxWsKzH4PIRnN5GfcX6kb5sroc50i
2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWXbj9T/UWZYB2oK0z5XqcJ
2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/D/xwzoiQ
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJ
BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh
c3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy
MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp
emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X
DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw
FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMg
UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo
YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5
MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB
AQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4
pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg0
13gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwID
AQABMA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSk
U01UbSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i
F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpY
oJ2daZH9
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDAjCCAmsCEDKIjprS9esTR/h/xCA3JfgwDQYJKoZIhvcNAQEFBQAwgcExCzAJ
BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh
c3MgNCBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy
MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp
emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X
DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw
FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgNCBQdWJsaWMg
UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo
YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5
MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB
AQUAA4GNADCBiQKBgQC68OTP+cSuhVS5B1f5j8V/aBH4xBewRNzjMHPVKmIquNDM
HO0oW369atyzkSTKQWI8/AIBvxwWMZQFl3Zuoq29YRdsTjCG8FE3KlDHqGKB3FtK
qsGgtG7rL+VXxbErQHDbWk2hjh+9Ax/YA9SPTJlxvOKCzFjomDqG04Y48wApHwID
AQABMA0GCSqGSIb3DQEBBQUAA4GBAIWMEsGnuVAVess+rLhDityq3RS6iYF+ATwj
cSGIL4LcY/oCRaxFWdcqWERbt5+BO5JoPeI3JPV7bI92NZYJqFmduc4jq3TWg/0y
cyfYaT5DdPauxYma51N86Xv2S/PBZYPejYqcPIiNOVn8qj8ijaHBZlCBckztImRP
T8qAkbYp
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDAjCCAmsCEEzH6qqYPnHTkxD4PTqJkZIwDQYJKoZIhvcNAQEFBQAwgcExCzAJ
BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh
c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy
MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp
emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X
DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw
FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMg
UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo
YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5
MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB
AQUAA4GNADCBiQKBgQCq0Lq+Fi24g9TK0g+8djHKlNgdk4xWArzZbxpvUjZudVYK
VdPfQ4chEWWKfo+9Id5rMj8bhDSVBZ1BNeuS65bdqlk/AVNtmU/t5eIqWpDBucSm
Fc/IReumXY6cPvBkJHalzasab7bYe1FhbqZ/h8jit+U03EGI6glAvnOSPWvndQID
AQABMA0GCSqGSIb3DQEBBQUAA4GBAKlPww3HZ74sy9mozS11534Vnjty637rXC0J
h9ZrbWB85a7FkCMMXErQr7Fd88e2CtvgFZMN3QO8x3aKtd1Pw5sTdbgBwObJW2ul
uIncrKTdcu1OofdPvAbT6shkdHvClUGcZXNY8ZCaPGqxmMnEh7zPRW1F4m4iP/68
DzFc6PLZ
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDAzCCAmwCEQC5L2DMiJ+hekYJuFtwbIqvMA0GCSqGSIb3DQEBBQUAMIHBMQsw
CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0Ns
YXNzIDIgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH
MjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9y
aXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazAe
Fw05ODA1MTgwMDAwMDBaFw0yODA4MDEyMzU5NTlaMIHBMQswCQYDVQQGEwJVUzEX
MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGlj
IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMx
KGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
eTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazCBnzANBgkqhkiG9w0B
AQEFAAOBjQAwgYkCgYEAp4gBIXQs5xoD8JjhlzwPIQjxnNuX6Zr8wgQGE75fUsjM
HiwSViy4AWkszJkfrbCWrnkE8hM5wXuYuggs6MKEEyyqaekJ9MepAqRCwiNPStjw
DqL7MWzJ5m+ZJwf15vRMeJ5t60aG+rmGyVTyssSv1EYcWskVMP8NbPUtDm3Of3cC
AwEAATANBgkqhkiG9w0BAQUFAAOBgQByLvl/0fFx+8Se9sVeUYpAmLho+Jscg9ji
nb3/7aHmZuovCfTK1+qlK5X2JGCGTUQug6XELaDTrnhpb3LabK4I8GOSN+a7xDAX
rXfMSTWqz9iP0b63GJZHc2pUIjRkLbYWm1lbtFFZOrMLFPQS32eg9K0yZF6xRnIn
jBJ7xUS0rg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQsw
CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
aWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
IENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1
GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ
+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0Gbd
U6LM8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLm
NxdLMEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY
ufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/
ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1WrIhVZPMq1
CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXttmhwwjIDLk5Mq
g6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm
fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c
2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/
bLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw
CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b
N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t
KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu
kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm
CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ
Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu
imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te
2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe
DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p
F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt
TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQsw
CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
aWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
IENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN2E1Lm0+afY8wR4
nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/EbRrsC+MO
8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjV
ojYJrKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjb
PG7PoBMAGrgnoeS+Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP2
6KbqxzcSXKMpHgLZ2x87tNcPVkeBFQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vr
n5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAq2aN17O6x5q25lXQBfGfMY1a
qtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/Ny9Sn2WCVhDr4
wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3
ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrs
pSCAaWihT37ha88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4
E1Z5T21Q6huwtVexN2ZYI/PcD98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJ
BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVy
aVNpZ24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24s
IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNp
Z24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJBgNV
BAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNp
Z24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIElu
Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24g
Q2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt
IEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArwoNwtUs22e5LeWU
J92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6tW8UvxDO
JxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUY
wZF7C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9o
koqQHgiBVrKtaaNS0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjN
qWm6o+sdDZykIKbBoMXRRkwXbdKsZj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/E
Srg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0JhU8wI1NQ0kdvekhktdmnLfe
xbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf0xwLRtxyID+u
7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU
sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RI
sH/7NiXaldDxJBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTP
cjnhsUPgKM+351psE2tJs//jGHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3
MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq
K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe
sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX
MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT
XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/
HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub
j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo
U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf
zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b
u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+
bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er
fF6adulZkMV8gzURZVE=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDtTCCAp2gAwIBAgIIBhDCeat3PfIwDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UE
BhMCQ0gxEjAQBgNVBAoTCVN3aXNzU2lnbjEyMDAGA1UEAxMpU3dpc3NTaWduIENB
IChSU0EgSUsgTWF5IDYgMTk5OSAxODowMDo1OCkxHzAdBgkqhkiG9w0BCQEWEGNh
QFN3aXNzU2lnbi5jb20wHhcNMDAxMTI2MjMyNzQxWhcNMzExMTI2MjMyNzQxWjB2
MQswCQYDVQQGEwJDSDESMBAGA1UEChMJU3dpc3NTaWduMTIwMAYDVQQDEylTd2lz
c1NpZ24gQ0EgKFJTQSBJSyBNYXkgNiAxOTk5IDE4OjAwOjU4KTEfMB0GCSqGSIb3
DQEJARYQY2FAU3dpc3NTaWduLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAKw5fjnmNneLQlUCQG8jQLwwfbrOZoUwNX8cbNqhxK03/xUloFVgAt+S
Te2RxNXaCAXLBPn5ZST35TLV57aLmbHCtifv3YZqaaQGvjedltIBMJihJhZ+h3LY
SKsUb+xEJ3x5ZUf8jP+Q1g57y1s8SnBFWN/ni5NkF1Y1y31VwOi9wiOf/VISL+uu
SC4i1CP1Kbz3BDs6Hht1GpRYCbJ/K0bc9oJSpWpT5PGONsGIawqMbJuyoDghsXQ1
pbn2e8K64BSscGZVZTNooSGgNiHmACNJBYXiWVWrwXPF4l6SddmC3Rj0aKXjgECc
FkHLDQcsM5JsK2ZLryTDUsQFbxVP2ikCAwEAAaNHMEUwCwYDVR0PBAQDAgEGMAwG
A1UdEwQFMAMBAf8wHQYDVR0OBBYEFJbXcc05KtT8iLGKq1N4ae+PR34WMAkGA1Ud
IwQCMAAwDQYJKoZIhvcNAQEFBQADggEBAKMy6W8HvZdS1fBpEUzl6Lvw50bgE1Xc
HU1JypSBG9mhdcXZo5AlPB4sCvx9Dmfwhyrdsshc0TP2V3Vh6eQqnEF5qB4lVziT
Bko9mW6Ot+pPnwsy4SHpx3rw6jCYnOqfUcZjWqqqRrq/3P1waz+Mn4cLMVEg3Xaz
qYov/khvSqS0JniwjRlo2H6f/1oVUKZvP+dUhpQepfZrOqMAWZW4otp6FolyQyeU
NN6UCRNiUKl5vTijbKwUUwfER/1Vci3M1/O1QCfttQ4vRN4Buc0xqYtGL3cd5WiO
vWzyhlTzAI6VUdNkQhhHJSAyTpj6dmXDRzrryoFGa2PjgESxz7XBaSI=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6
MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJp
dHkgMjA0OCBWMzAeFw0wMTAyMjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAX
BgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJTQSBTZWN1cml0eSAy
MDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt49VcdKA3Xtp
eafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7Jylg
/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGl
wSMiuLgbWhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnh
AMFRD0xS+ARaqn1y07iHKrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2
PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpu
AWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
BjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4EFgQUB8NR
MKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYc
HnmYv/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/
Zb5gEydxiKRz44Rj0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+
f00/FGj1EVDVwfSQpQgdMWD/YIwjVAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVO
rSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395nzIlQnQFgCi/vcEkllgVsRch
6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kApKnXwiJPZ9d3
7CAFYd4=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc
MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP
bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2
MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft
ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg
Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lk
hsmj76CGv2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym
1BW32J/X3HGrfpq/m44zDyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsW
OqMFf6Dch9Wc/HKpoH145LcxVR5lu9RhsCFg7RAycsWSJR74kEoYeEfffjA3PlAb
2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP8c9GsEsPPt2IYriMqQko
O3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0TAQH/BAUw
AwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAU
AK3Zo/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB
BQUAA4IBAQB8itEfGDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkF
Zu90821fnZmv9ov761KyBZiibyrFVL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAb
LjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft3OJvx8Fi8eNy1gTIdGcL+oir
oQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43gKd8hdIaC2y+C
MMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds
sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc
MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP
bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2
MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft
ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg
Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIP
ADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC
206B89enfHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFci
KtZHgVdEglZTvYYUAQv8f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2
JxhP7JsowtS013wMPgwr38oE18aO6lhOqKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9
BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JNRvCAOVIyD+OEsnpD8l7e
Xz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0gBe4lL8B
PeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67
Xnfn6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEq
Z8A9W6Wa6897GqidFEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZ
o2C7HK2JNDJiuEMhBnIMoVxtRsX6Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3
+L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnjB453cMor9H124HhnAgMBAAGj
YzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3OpaaEg5+31IqEj
FNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE
AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmn
xPBUlgtk87FYT15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2
LHo1YGwRgJfMqZJS5ivmae2p+DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzccc
obGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXgJXUjhx5c3LqdsKyzadsXg8n33gy8
CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//ZoyzH1kUQ7rVyZ2OuMe
IjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgOZtMA
DjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2F
AjgQ5ANh1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUX
Om/9riW99XJZZLF0KjhfGEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPb
AZO1XB4Y3WRayhgoPmMEEf0cjQAPuDffZ4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQl
Zvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuPcX/9XhmgD0uRuMRUvAaw
RY8mkaKO/qk=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIID5jCCAs6gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzELMAkGA1UEBhMCVVMx
HTAbBgNVBAoTFEFPTCBUaW1lIFdhcm5lciBJbmMuMRwwGgYDVQQLExNBbWVyaWNh
IE9ubGluZSBJbmMuMTcwNQYDVQQDEy5BT0wgVGltZSBXYXJuZXIgUm9vdCBDZXJ0
aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyOTA2MDAwMFoXDTM3MTEyMDE1
MDMwMFowgYMxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRBT0wgVGltZSBXYXJuZXIg
SW5jLjEcMBoGA1UECxMTQW1lcmljYSBPbmxpbmUgSW5jLjE3MDUGA1UEAxMuQU9M
IFRpbWUgV2FybmVyIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnej8Mlo2k06AX3dLm/WpcZuS+U
0pPlLYnKhHw/EEMbjIt8hFj4JHxIzyr9wBXZGH6EGhfT257XyuTZ16pYUYfw8ItI
TuLCxFlpMGK2MKKMCxGZYTVtfu/FsRkGIBKOQuHfD5YQUqjPnF+VFNivO3ULMSAf
RC+iYkGzuxgh28pxPIzstrkNn+9R7017EvILDOGsQI93f7DKeHEMXRZxcKLXwjqF
zQ6axOAAsNUl6twr5JQtOJyJQVdkKGUZHLZEtMgxa44Be3ZZJX8VHIQIfHNlIAqh
BC4aMqiaILGcLCFZ5/vP7nAtCMpjPiybkxlqpMKX/7eGV4iFbJ4VFitNLLMCAwEA
AaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUoTYwFsuGkABFgFOxj8jY
PXy+XxIwHwYDVR0jBBgwFoAUoTYwFsuGkABFgFOxj8jYPXy+XxIwDgYDVR0PAQH/
BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IBAQCKIBilvrMvtKaEAEAwKfq0FHNMeUWn
9nDg6H5kHgqVfGphwu9OH77/yZkfB2FK4V1Mza3u0FIy2VkyvNp5ctZ7CegCgTXT
Ct8RHcl5oIBN/lrXVtbtDyqvpxh1MwzqwWEFT2qaifKNuZ8u77BfWgDrvq2g+EQF
Z7zLBO+eZMXpyD8Fv8YvBxzDNnGGyjhmSs3WuEvGbKeXO/oTLW4jYYehY0KswsuX
n2Fozy1MBJ3XJU8KDk2QixhWqJNIV9xvrr2eZ1d3iVCzvhGbRWeDhhmH05i9CBoW
H1iCC+GWaQVLjuyDUTEH1dSf/1l7qG6Fz9NLqUmwX7A5KGgOc90lmt4S
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIF5jCCA86gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzELMAkGA1UEBhMCVVMx
HTAbBgNVBAoTFEFPTCBUaW1lIFdhcm5lciBJbmMuMRwwGgYDVQQLExNBbWVyaWNh
IE9ubGluZSBJbmMuMTcwNQYDVQQDEy5BT0wgVGltZSBXYXJuZXIgUm9vdCBDZXJ0
aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyOTA2MDAwMFoXDTM3MDkyODIz
NDMwMFowgYMxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRBT0wgVGltZSBXYXJuZXIg
SW5jLjEcMBoGA1UECxMTQW1lcmljYSBPbmxpbmUgSW5jLjE3MDUGA1UEAxMuQU9M
IFRpbWUgV2FybmVyIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIw
DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALQ3WggWmRToVbEbJGv8x4vmh6mJ
7ouZzU9AhqS2TcnZsdw8TQ2FTBVsRotSeJ/4I/1n9SQ6aF3Q92RhQVSji6UI0ilb
m2BPJoPRYxJWSXakFsKlnUWsi4SVqBax7J/qJBrvuVdcmiQhLE0OcR+mrF1FdAOY
xFSMFkpBd4aVdQxHAWZg/BXxD+r1FHjHDtdugRxev17nOirYlxcwfACtCJ0zr7iZ
YYCLqJV+FNwSbKTQ2O9ASQI2+W6p1h2WVgSysy0WVoaP2SBXgM1nEG2wTPDaRrbq
JS5Gr42whTg0ixQmgiusrpkLjhTXUr2eacOGAgvqdnUxCc4zGSGFQ+aJLZ8lN2fx
I2rSAG2X+Z/nKcrdH9cG6rjJuQkhn8g/BsXS6RJGAE57COtCPStIbp1n3UsC5ETz
kxmlJ85per5n0/xQpCyrw2u544BMzwVhSyvcG7mm0tCq9Stz+86QNZ8MUhy/XCFh
EVsVS6kkUfykXPcXnbDS+gfpj1bkGoxoigTTfFrjnqKhynFbotSg5ymFXQNoKk/S
Btc9+cMDLz9l+WceR0DTYw/j1Y75hauXTLPXJuuWCpTehTacyH+BCQJJKg71ZDIM
gtG6aoIbs0t0EfOMd9afv9w3pKdVBC/UMejTRrkDfNoSTllkt1ExMVCgyhwn2RAu
rda9EGYrw7AiShJbAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
FE9pbQN+nZ8HGEO8txBO1b+pxCAoMB8GA1UdIwQYMBaAFE9pbQN+nZ8HGEO8txBO
1b+pxCAoMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAO/Ouyugu
h4X7ZVnnrREUpVe8WJ8kEle7+z802u6teio0cnAxa8cZmIDJgt43d15Ui47y6mdP
yXSEkVYJ1eV6moG2gcKtNuTxVBFT8zRFASbI5Rq8NEQh3q0l/HYWdyGQgJhXnU7q
7C+qPBR7V8F+GBRn7iTGvboVsNIYvbdVgaxTwOjdaRITQrcCtQVBynlQboIOcXKT
RuidDV29rs4prWPVVRaAMCf/drr3uNZK49m1+VLQTkCpx+XCMseqdiThawVQ68W/
ClTluUI8JPu3B5wwn3la5uBAUhX0/Kr0VvlEl4ftDmVyXr4m+02kLQgH3thcoNyB
M5kYJRF3p+v9WAksmWsbivNSPxpNSGDxoPYzAlOL7SUJuA0t7Zdz7NeWH45gDtoQ
my8YJPamTQr5O8t1wswvziRpyQoijlmn94IM19drNZxDAGrElWe6nEXLuA4399xO
AU++CrYD062KRffaJ00psUjf5BHklka9bAI+1lHIlRcBFanyqqryvy9lG2/QuRqT
9Y41xICHPpQvZuTpqP9BnHAqTyo5GJUefvthATxRCC4oGKQWDzH9OmwjkyB24f0H
hdFbP9IcczLd+rn4jM8Ch3qaluTtT4mNU0OrDhPAARW0eTjb/G49nlG2uBOLZ8/5
fNkiHfZdxRwBL5joeiQYvITX+txyW/fBOmg=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM
MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
QTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM
MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6xwS7TT3zNJc4YPk/E
jG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdLkKWo
ePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GI
ULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapu
Ob7kky/ZR6By6/qmW6/KUz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUg
AKpoC6EahQGcxEZjgoi2IrHu/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7
HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA
uI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQa
TOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTg
xSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q
CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x
O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs
6GAqm4VKQPNriiTsBhYscw==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/
MQswCQYDVQQGEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5MB4XDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1ow
PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp
Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
AJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qNw8XR
IePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1q
gQdW8or5BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKy
yhwOeYHWtXBiCAEuTk8O1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAts
F/tnyMKtsc2AtJfcdgEWFelq16TheEfOhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2
jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wovJ5pGfaENda1UhhXcSTvx
ls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7Q3hub/FC
VGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHK
YS1tB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoH
EgKXTiCQ8P8NHuJBO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThN
Xo+EHWbNxWCWtFJaBYmOlXqYwZE8lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1Ud
DgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNVHRMEBTADAQH/MDkGBGcqBwAE
MTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg209yewDL7MTqK
UWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ
TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyf
qzvS/3WXy6TjZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaK
ZEk9GhiHkASfQlK3T8v+R0F2Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFE
JPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlUD7gsL0u8qV1bYH+Mh6XgUmMqvtg7
hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6QzDxARvBMB1uUO07+1
EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+HbkZ6Mm
nD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WX
udpVBrkk7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44Vbnz
ssQwmSNOXfJIoRIM3BKQCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDe
LMDDav7v3Aun+kbfYNucpllQdSNpc5Oy+fwC00fmcc4QAu4njIT/rEUNE1yDMuAl
pYYsfPQS
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB
8zELMAkGA1UEBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2Vy
dGlmaWNhY2lvIChOSUYgUS0wODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1
YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYDVQQLEyxWZWdldSBodHRwczovL3d3
dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UECxMsSmVyYXJxdWlh
IEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMTBkVD
LUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQG
EwJFUzE7MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8g
KE5JRiBRLTA4MDExNzYtSSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBD
ZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZlZ2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQu
bmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJhcnF1aWEgRW50aXRhdHMg
ZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUNDMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R
85iKw5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm
4CgPukLjbo73FCeTae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaV
HMf5NLWUhdWZXqBIoH7nF2W4onW4HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNd
QlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0aE9jD2z3Il3rucO2n5nzbcc8t
lGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw0JDnJwIDAQAB
o4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E
BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4
opvpXY0wfwYDVR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBo
dHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidW
ZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAwDQYJKoZIhvcN
AQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJlF7W2u++AVtd0x7Y
/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNaAl6k
SBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhy
Rp/7SNVel+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOS
Agu+TGbrIP65y7WZf+a2E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xl
nJ2lYJU6Un/10asIbvPuW/mIPX64b24D5EI=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFGTCCBAGgAwIBAgIEPki9xDANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJE
SzEMMAoGA1UEChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTAeFw0wMzAyMTEw
ODM5MzBaFw0zNzAyMTEwOTA5MzBaMDExCzAJBgNVBAYTAkRLMQwwCgYDVQQKEwNU
REMxFDASBgNVBAMTC1REQyBPQ0VTIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEArGL2YSCyz8DGhdfjeebM7fI5kqSXLmSjhFuHnEz9pPPEXyG9VhDr
2y5h7JNp46PMvZnDBfwGuMo2HP6QjklMxFaaL1a8z3sM8W9Hpg1DTeLpHTk0zY0s
2RKY+ePhwUp8hjjEqcRhiNJerxomTdXkoCJHhNlktxmW/OwZ5LKXJk5KTMuPJItU
GBxIYXvViGjaXbXqzRowwYCDdlCqT9HU3Tjw7xb04QxQBr/q+3pJoSgrHPb8FTKj
dGqPqcNiKXEx5TukYBdedObaE+3pHx8b0bJoc8YQNHVGEBDjkAB2QMuLt0MJIf+r
TpPGWOmlgtt3xDqZsXKVSQTwtyv6e1mO3QIDAQABo4ICNzCCAjMwDwYDVR0TAQH/
BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgewGA1UdIASB5DCB4TCB3gYIKoFQgSkB
AQEwgdEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2VydGlmaWthdC5kay9yZXBv
c2l0b3J5MIGdBggrBgEFBQcCAjCBkDAKFgNUREMwAwIBARqBgUNlcnRpZmlrYXRl
ciBmcmEgZGVubmUgQ0EgdWRzdGVkZXMgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEu
MS4xLiBDZXJ0aWZpY2F0ZXMgZnJvbSB0aGlzIENBIGFyZSBpc3N1ZWQgdW5kZXIg
T0lEIDEuMi4yMDguMTY5LjEuMS4xLjARBglghkgBhvhCAQEEBAMCAAcwgYEGA1Ud
HwR6MHgwSKBGoESkQjBAMQswCQYDVQQGEwJESzEMMAoGA1UEChMDVERDMRQwEgYD
VQQDEwtUREMgT0NFUyBDQTENMAsGA1UEAxMEQ1JMMTAsoCqgKIYmaHR0cDovL2Ny
bC5vY2VzLmNlcnRpZmlrYXQuZGsvb2Nlcy5jcmwwKwYDVR0QBCQwIoAPMjAwMzAy
MTEwODM5MzBagQ8yMDM3MDIxMTA5MDkzMFowHwYDVR0jBBgwFoAUYLWF7FZkfhIZ
J2cdUBVLc647+RIwHQYDVR0OBBYEFGC1hexWZH4SGSdnHVAVS3OuO/kSMB0GCSqG
SIb2fQdBAAQQMA4bCFY2LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEACrom
JkbTc6gJ82sLMJn9iuFXehHTuJTXCRBuo7E4A9G28kNBKWKnctj7fAXmMXAnVBhO
inxO5dHKjHiIzxvTkIvmI/gLDjNDfZziChmPyQE+dF10yYscA+UYyAFMP8uXBV2Y
caaYb7Z8vTd/vuGTJW1v8AqtFxjhA7wHKcitJuj4YfD9IQl+mo6paH1IYnK9AOoB
mbgGglGBTvH1tJFUuSN6AJqfXY3gPGS5GhKSKseCRHI53OI8xthV9RVOyAUO28bQ
YqbsFbS1AoLbrIyigfCbmTH1ICCoiGEKB5+U/NDXG8wuF/MEJ3Zn61SD/aSQfgY9
BKNDLdr8C2LqL19iUw==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn
MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL
ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg
b2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAxNjEzNDNaFw0zNzA5MzAxNjEzNDRa
MH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBB
ODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIw
IAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0B
AQEFAAOCAQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtb
unXF/KGIJPov7coISjlUxFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0d
BmpAPrMMhe5cG3nCYsS4No41XQEMIwRHNaqbYE6gZj3LJgqcQKH0XZi/caulAGgq
7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jWDA+wWFjbw2Y3npuRVDM3
0pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFVd9oKDMyX
roDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIG
A1UdEwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5j
aGFtYmVyc2lnbi5vcmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p
26EpW1eLTXYGduHRooowDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIA
BzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24ub3JnMCcGA1Ud
EgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYDVR0gBFEwTzBN
BgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz
aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEB
AAxBl8IahsAifJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZd
p0AJPaxJRUXcLo0waLIJuvvDL8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi
1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wNUPf6s+xCX6ndbcj0dc97wXImsQEc
XCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/nADydb47kMgkdTXg0
eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1erfu
tGWaIZDgqtCYvDi1czyL+Nw=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEn
MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL
ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENo
YW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYxNDE4WhcNMzcwOTMwMTYxNDE4WjB9
MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgy
NzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4G
A1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUA
A4IBDQAwggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0
Mi+ITaFgCPS3CU6gSS9J1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/s
QJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8Oby4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpV
eAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl6DJWk0aJqCWKZQbua795
B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c8lCrEqWh
z0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0T
AQH/BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1i
ZXJzaWduLm9yZy9jaGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4w
TcbOX60Qq+UDpfqpFDAOBgNVHQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAH
MCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBjaGFtYmVyc2lnbi5vcmcwKgYD
VR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9yZzBbBgNVHSAE
VDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh
bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0B
AQUFAAOCAQEAPDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUM
bKGKfKX0j//U2K0X1S0E0T9YgOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXi
ryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJPJ7oKXqJ1/6v/2j1pReQvayZzKWG
VwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4IBHNfTIzSJRUTN3c
ecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/
AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEb
MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRp
ZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVow
fjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAiBgNV
BAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPM
cm3ye5drswfxdySRXyWP9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3S
HpR7LZQdqnXXs5jLrLxkU0C8j6ysNstcrbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996
CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rCoznl2yY4rYsK7hljxxwk
3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3Vp6ea5EQz
6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNV
HQ4EFgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1Ud
EwEB/wQFMAMBAf8wgYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2Rv
Y2EuY29tL1NlY3VyZUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRw
Oi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmww
DQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm4J4oqF7Tt/Q0
5qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj
Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtI
gKvcnDe4IRRLDXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJ
aD61JlfutuC23bkpgHl9j6PwpCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDl
izeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1HRR3B7Hzs/Sk=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEb
MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0
aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEwMDAwMDBaFw0yODEyMzEyMzU5NTla
MH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
BgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUwIwYD
VQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWW
fnJSoBVC21ndZHoa0Lh73TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMt
TGo87IvDktJTdyR0nAducPy9C1t2ul/y/9c3S0pgePfw+spwtOpZqqPOSC+pw7IL
fhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6juljatEPmsbS9Is6FARW
1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsSivnkBbA7
kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0G
A1UdDgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYD
VR0TAQH/BAUwAwEB/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21v
ZG9jYS5jb20vVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRo
dHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMu
Y3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8NtwuleGFTQQuS9/
HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32
pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxIS
jBc/lDb+XbDABHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+
xqFx7D+gIIxmOom0jtTYsU0lR+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/Atyjcn
dBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O9y5Xt5hwXsjEeLBi
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDhDCCAmygAwIBAgIBCTANBgkqhkiG9w0BAQUFADAzMQswCQYDVQQGEwJDTjER
MA8GA1UEChMIVW5pVHJ1c3QxETAPBgNVBAMTCFVDQSBSb290MB4XDTA0MDEwMTAw
MDAwMFoXDTI5MTIzMTAwMDAwMFowMzELMAkGA1UEBhMCQ04xETAPBgNVBAoTCFVu
aVRydXN0MREwDwYDVQQDEwhVQ0EgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBALNdB8qGJn1r4vs4CQ7MgsJqGgCiFV/W6dQBt1YDAVmP9ThpJHbC
XivF9iu/r/tB/Q9a/KvXg3BNMJjRnrJ2u5LWu+kQKGkoNkTo8SzXWHwk1n8COvCB
a2FgP/Qz3m3l6ihST/ypHWN8C7rqrsRoRuTej8GnsrZYWm0dLNmMOreIy4XU9+gD
Xv2yTVDo1h//rgI/i0+WITyb1yXJHT/7mLFZ5PCpO6+zzYUs4mBGzG+OoOvwNMXx
QhhgrhLtRnUc5dipllq+3lrWeGeWW5N3UPJuG96WUUqm1ktDdSFmjXfsAoR2XEQQ
th1hbOSjIH23jboPkXXHjd+8AmCoKai9PUMCAwEAAaOBojCBnzALBgNVHQ8EBAMC
AQYwDAYDVR0TBAUwAwEB/zBjBgNVHSUEXDBaBggrBgEFBQcDAQYIKwYBBQUHAwIG
CCsGAQUFBwMDBggrBgEFBQcDBAYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEFBQcD
BwYIKwYBBQUHAwgGCCsGAQUFBwMJMB0GA1UdDgQWBBTbHzXza0z/QjFkm827Wh4d
SBC37jANBgkqhkiG9w0BAQUFAAOCAQEAOGy3iPGt+lg3dNHocN6cJ1nL5BXXoMNg
14iABMUwTD3UGusGXllH5rxmy+AI/Og17GJ9ysDawXiv5UZv+4mCI4/211NmVaDe
JRI7cTYWVRJ2+z34VFsxugAG+H1V5ad2g6pcSpemKijfvcZsCyOVjjN/Hl5AHxNU
LJzltQ7dFyiuawHTUin1Ih+QOfTcYmjwPIZH7LgFRbu3DJaUxmfLI3HQjnQi1kHr
A6i26r7EARK1s11AdgYg1GS4KUYGis4fk5oQ7vuqWrTcL9Ury/bXBYSYBZELhPc9
+tb5evosFeo2gkO3t7jj83EB7UNDogVFwygFBzXjAaU4HoDU18PZ3g==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW
MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy
c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE
BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0
IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV
VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8
cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT
QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh
F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v
c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w
mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd
VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX
teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ
f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe
Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+
nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB
/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY
MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG
9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc
aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX
IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn
ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z
uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN
Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja
QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW
koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9
ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt
DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm
bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW
MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy
c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD
VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1
c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81
WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG
FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq
XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL
se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb
KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd
IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73
y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt
hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc
QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4
Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV
HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ
KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z
dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ
L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr
Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo
ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY
T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz
GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m
1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV
OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH
6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX
QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDkzCCAnugAwIBAgIQFBOWgxRVjOp7Y+X8NId3RDANBgkqhkiG9w0BAQUFADA0
MRMwEQYDVQQDEwpDb21TaWduIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQG
EwJJTDAeFw0wNDAzMjQxMTMyMThaFw0yOTAzMTkxNTAyMThaMDQxEzARBgNVBAMT
CkNvbVNpZ24gQ0ExEDAOBgNVBAoTB0NvbVNpZ24xCzAJBgNVBAYTAklMMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8ORUaSvTx49qROR+WCf4C9DklBKK
8Rs4OC8fMZwG1Cyn3gsqrhqg455qv588x26i+YtkbDqthVVRVKU4VbirgwTyP2Q2
98CNQ0NqZtH3FyrV7zb6MBBC11PN+fozc0yz6YQgitZBJzXkOPqUm7h65HkfM/sb
2CEJKHxNGGleZIp6GZPKfuzzcuc3B1hZKKxC+cX/zT/npfo4sdAMx9lSGlPWgcxC
ejVb7Us6eva1jsz/D3zkYDaHL63woSV9/9JLEYhwVKZBqGdTUkJe5DSe5L6j7Kpi
Xd3DTKaCQeQzC6zJMw9kglcq/QytNuEMrkvF7zuZ2SOzW120V+x0cAwqTwIDAQAB
o4GgMIGdMAwGA1UdEwQFMAMBAf8wPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDovL2Zl
ZGlyLmNvbXNpZ24uY28uaWwvY3JsL0NvbVNpZ25DQS5jcmwwDgYDVR0PAQH/BAQD
AgGGMB8GA1UdIwQYMBaAFEsBmz5WGmU2dst7l6qSBe4y5ygxMB0GA1UdDgQWBBRL
AZs+VhplNnbLe5eqkgXuMucoMTANBgkqhkiG9w0BAQUFAAOCAQEA0Nmlfv4pYEWd
foPPbrxHbvUanlR2QnG0PFg/LUAlQvaBnPGJEMgOqnhPOAlXsDzACPw1jvFIUY0M
cXS6hMTXcpuEfDhOZAYnKuGntewImbQKDdSFc8gS4TXt8QUxHXOZDOuWyt3T5oWq
8Ir7dcHyCTxlZWTzTNity4hp8+SDtwy9F1qWF8pb/627HOkthIDYIb6FUtnUdLlp
hbpN7Sgy6/lhSuTENh4Z3G+EER+V9YMoGKgzkkMn3V0TBEVPh9VGzT2ouvDzuFYk
Res3x+F2T3I5GN9+dHLHcy056mDmrRGiVod7w2ia/viMcKjfZTL0pECMocJEAw6U
AGegcQCCSA==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAw
PDEbMBkGA1UEAxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWdu
MQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwx
GzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjEL
MAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGtWhf
HZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs49oh
gHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sW
v+bznkqH7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ue
Mv5WJDmyVIRD9YTC2LxBkMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr
9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d19guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt
6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUwAwEB/zBEBgNVHR8EPTA7
MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29tU2lnblNl
Y3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58
ADsAj8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkq
hkiG9w0BAQUFAAOCAQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7p
iL1DRYHjZiM/EoZNGeQFsOY3wo3aBijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtC
dsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtpFhpFfTMDZflScZAmlaxMDPWL
kz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP51qJThRv4zdL
hfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz
OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDQzCCAiugAwIBAgIQX/h7KCtU3I1CoxW1aMmt/zANBgkqhkiG9w0BAQUFADA1
MRYwFAYDVQQKEw1DaXNjbyBTeXN0ZW1zMRswGQYDVQQDExJDaXNjbyBSb290IENB
IDIwNDgwHhcNMDQwNTE0MjAxNzEyWhcNMjkwNTE0MjAyNTQyWjA1MRYwFAYDVQQK
Ew1DaXNjbyBTeXN0ZW1zMRswGQYDVQQDExJDaXNjbyBSb290IENBIDIwNDgwggEg
MA0GCSqGSIb3DQEBAQUAA4IBDQAwggEIAoIBAQCwmrmrp68Kd6ficba0ZmKUeIhH
xmJVhEAyv8CrLqUccda8bnuoqrpu0hWISEWdovyD0My5jOAmaHBKeN8hF570YQXJ
FcjPFto1YYmUQ6iEqDGYeJu5Tm8sUxJszR2tKyS7McQr/4NEb7Y9JHcJ6r8qqB9q
VvYgDxFUl4F1pyXOWWqCZe+36ufijXWLbvLdT6ZeYpzPEApk0E5tzivMW/VgpSdH
jWn0f84bcN5wGyDWbs2mAag8EtKpP6BrXruOIIt6keO1aO6g58QBdKhTCytKmg9l
Eg6CTY5j/e/rmxrbU6YTYK/CfdfHbBcl1HP7R2RQgYCUTOG/rksc35LtLgXfAgED
o1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUJ/PI
FR5umgIJFq0roIlgX9p7L6owEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEF
BQADggEBAJ2dhISjQal8dwy3U8pORFBi71R803UXHOjgxkhLtv5MOhmBVrBW7hmW
Yqpao2TB9k5UM8Z3/sUcuuVdJcr18JOagxEu5sv4dEX+5wW4q+ffy0vhN4TauYuX
cB7w4ovXsNgOnbFp1iqRe6lJT37mjpXYgyc81WhJDtSd9i7rp77rMKSsH0T8lasz
Bvt9YAretIpjsJyp8qS5UwGH0GikJ3+r/+n6yUA4iGe0OcaEb1fJU9u6ju7AQ7L4
CYNu/2bPPu8Xs1gYJQk0XuPL1hS27PKSb3TkL4Eq1ZKR4OCXPDJoBYVL0fdX4lId
kxpUnwVwwEpxYB5DC2Ae/qPOgRnhCzU=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICmDCCAgGgAwIBAgIBDjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJVUzEY
MBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNFQ0ExFDASBgNVBAMT
C0VDQSBSb290IENBMB4XDTA0MDYxNDEwMjAwOVoXDTQwMDYxNDEwMjAwOVowSzEL
MAkGA1UEBhMCVVMxGDAWBgNVBAoTD1UuUy4gR292ZXJubWVudDEMMAoGA1UECxMD
RUNBMRQwEgYDVQQDEwtFQ0EgUm9vdCBDQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
gYkCgYEArkr2eXIS6oAKIpDkOlcQZdMGdncoygCEIU+ktqY3of5SVVXU7/it7kJ1
EUzR4ii2vthQtbww9aAnpQxcEmXZk8eEyiGEPy+cCQMllBY+efOtKgjbQNDZ3lB9
19qzUJwBl2BMxslU1XsJQw9SK10lPbQm4asa8E8e5zTUknZBWnECAwEAAaOBizCB
iDAfBgNVHSMEGDAWgBT2uAQnDlYW2blj2f2hVGVBoAhILzAdBgNVHQ4EFgQU9rgE
Jw5WFtm5Y9n9oVRlQaAISC8wDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB
Af8wJQYDVR0gBB4wHDAMBgpghkgBZQMCAQwBMAwGCmCGSAFlAwIBDAIwDQYJKoZI
hvcNAQEFBQADgYEAHh0EQY2cZ209aBb5q0wW1ER0dc4OGzsLyqjHfaQ4TEaMmUwL
AJRta/c4KVWLiwbODsvgJk+CaWmSL03gRW/ciVb/qDV7qh9Pyd1cOlanZTAnPog2
i82yL3i2fK9DCC84uoxEQbgqK2jx9bIjFTwlAqITk9fGAm5mdT84IEwq1Gw=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
ReYNnyicsbkqWletNw+vHX/bvZ8=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB
gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk
MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY
UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx
NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3
dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy
dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6
38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP
KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q
DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4
qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa
JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi
PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P
BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs
jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0
eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD
ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR
vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa
IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy
i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ
O+7ETPTsJ3xCwnR8gooJybQDJbw=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDcDCCAligAwIBAgIBBTANBgkqhkiG9w0BAQUFADBbMQswCQYDVQQGEwJVUzEY
MBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxDDAKBgNVBAsT
A1BLSTEWMBQGA1UEAxMNRG9EIFJvb3QgQ0EgMjAeFw0wNDEyMTMxNTAwMTBaFw0y
OTEyMDUxNTAwMTBaMFsxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdvdmVy
bm1lbnQxDDAKBgNVBAsTA0RvRDEMMAoGA1UECxMDUEtJMRYwFAYDVQQDEw1Eb0Qg
Um9vdCBDQSAyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwCzB9o07
rP8/PNZxvrh0IgfscEEV/KtA4weqwcPYn/7aTDq/P8jYKHtLNgHArEUlw9IOCo+F
GGQQPRoTcCpvjtfcjZOzQQ84Ic2tq8I9KgXTVxE3Dc2MUfmT48xGSSGOFLTNyxQ+
OM1yMe6rEvJl6jQuVl3/7mN1y226kTT8nvP0LRy+UMRC31mI/2qz+qhsPctWcXEF
lrufgOWARVlnQbDrw61gpIB1BhecDvRD4JkOG/t/9bPMsoGCsf0ywbi+QaRktWA6
WlEwjM7eQSwZR1xJEGS5dKmHQa99brrBuKG/ZTE6BGf5tbuOkooAY7ix5ow4X4P/
UNU7ol1rshDMYwIDAQABoz8wPTAdBgNVHQ4EFgQUSXS7DF66ev4CVO97oMaVxgmA
cJYwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
ggEBAJiRjT+JyLv1wGlzKTs1rLqzCHY9cAmS6YREIQF9FHYb7lFsHY0VNy17MWn0
mkS4r0bMNPojywMnGdKDIXUr5+AbmSbchECV6KjSzPZYXGbvP0qXEIIdugqi3VsG
K52nZE7rLgE1pLQ/E61V5NVzqGmbEfGY8jEeb0DU+HifjpGgb3AEkGaqBivO4XqS
tX3h4NGW56E6LcyxnR8FRO2HmdNNGnA5wQQM5X7Z8a/XIA7xInolpHOZzD+kByeW
qKKV7YK5FtOeC4fCwfKI9WLfaN/HvGlR7bFc3FRUKQ8JOZqsA8HbDE2ubwp6Fknx
v5HSOJTT9pUst2zJQraNypCNhdk=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe
MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0
ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw
IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL
SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF
AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH
SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh
ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X
DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1
TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ
fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA
sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU
WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS
nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH
dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip
NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC
AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF
MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH
ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB
uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl
PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP
JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/
gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2
j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6
5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB
o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS
/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z
Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE
W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D
hNQ+IIX3Sj0rnP0qCglN6oH4EZw=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEvDCCA6SgAwIBAgIQAJCLMk/BkBrOtMM4Cc3P5DANBgkqhkiG9w0BAQUFADB5
MQswCQYDVQQGEwJFUzE2MDQGA1UEChMtQ29uc2VqbyBHZW5lcmFsIGRlIGxhIEFi
b2dhY2lhIE5JRjpRLTI4NjMwMDZJMTIwMAYDVQQDEylBdXRvcmlkYWQgZGUgQ2Vy
dGlmaWNhY2lvbiBkZSBsYSBBYm9nYWNpYTAeFw0wNTA2MTMyMjAwMDBaFw0zMDA2
MTMyMjAwMDBaMHkxCzAJBgNVBAYTAkVTMTYwNAYDVQQKEy1Db25zZWpvIEdlbmVy
YWwgZGUgbGEgQWJvZ2FjaWEgTklGOlEtMjg2MzAwNkkxMjAwBgNVBAMTKUF1dG9y
aWRhZCBkZSBDZXJ0aWZpY2FjaW9uIGRlIGxhIEFib2dhY2lhMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtLJX7oXwI+gN+7KAhPEQZ6uy+UnfXN5b5I8p
GVPJ1egcUGthAoyH8I88wUWSC6yZocYahdY9rX4mph24PbKzPorFCjLTS5HvSXV+
Vvf+oAhiRivO6vJRn2DeMsjtGqfPdVzrPcC9mkilhpTOWFAU6mrhmvSMZZXhYBUl
lRL2uniLssDt5myXJFod5HRDyjjENZRYjvWKsGg8KCxElgm/CVtyCudnPJC5VDh0
VLttLWpDyLzvCawfI+hSVl41F18ru17NZVKlFHw7sqrp3Se1NyM7Bg0se4262m9m
F4anttceB10ebBmXyOUjc3jRrvkeuqGuSSLtZXEff/dadESNQwIDAQABo4IBPjCC
ATowNwYDVR0RBDAwLoERYWNAYWNhYm9nYWNpYS5vcmeGGWh0dHA6Ly93d3cuYWNh
Ym9nYWNpYS5vcmcwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwEQYJ
YIZIAYb4QgEBBAQDAgAHMB0GA1UdDgQWBBT8iEyObQShIJDT+Byas2cEX3mAxjCB
qwYDVR0gBIGjMIGgMIGdBgsrBgEEAYGBFQoBATCBjTApBggrBgEFBQcCARYdaHR0
cDovL3d3dy5hY2Fib2dhY2lhLm9yZy9kb2MwYAYIKwYBBQUHAgIwVBpSQ29uc3Vs
dGUgbGEgZGVjbGFyYWNpb24gZGUgcHJhY3RpY2FzIGRlIGNlcnRpZmljYWNpb24g
ZW4gaHR0cDovL3d3dy5hY2Fib2dhY2lhLm9yZzANBgkqhkiG9w0BAQUFAAOCAQEA
mKf6ObVzESZ/vIk/tGslMzEKhjhryR4VlxTg0kwthfQ8dJuNKBH7zA4muYCDFtH5
Rpi2RgeOZoVtcMC6TIDzpPDVN1Qrr2aEcnP5SC8JzuGFAcqP4IfeoJfQlLQNtU0O
ZyzIYMQylMBBgQeNur+p6AxAmkJ4BV2B62Ic5E8UCj0LPh/p9M197kW7vN5d85iX
JnvGEyn4K38a1Or6sm4gntoX6qGSvTfpDru7kdUl9mBdhSFQW/9UXfVLO7TDKRFY
AvYl5OGCgruijeeRJF5AkZ5HB4wzV9RiMVF2dYVDbwmrEaUlKbnY/1+l9z/rZTsd
74blFiLVHsoyaX1+BdcwJw==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEezCCA2OgAwIBAgIQNxkY5lNUfBq1uMtZWts1tzANBgkqhkiG9w0BAQUFADCB
rjELMAkGA1UEBhMCREUxIDAeBgNVBAgTF0JhZGVuLVd1ZXJ0dGVtYmVyZyAoQlcp
MRIwEAYDVQQHEwlTdHV0dGdhcnQxKTAnBgNVBAoTIERldXRzY2hlciBTcGFya2Fz
c2VuIFZlcmxhZyBHbWJIMT4wPAYDVQQDEzVTLVRSVVNUIEF1dGhlbnRpY2F0aW9u
IGFuZCBFbmNyeXB0aW9uIFJvb3QgQ0EgMjAwNTpQTjAeFw0wNTA2MjIwMDAwMDBa
Fw0zMDA2MjEyMzU5NTlaMIGuMQswCQYDVQQGEwJERTEgMB4GA1UECBMXQmFkZW4t
V3VlcnR0ZW1iZXJnIChCVykxEjAQBgNVBAcTCVN0dXR0Z2FydDEpMCcGA1UEChMg
RGV1dHNjaGVyIFNwYXJrYXNzZW4gVmVybGFnIEdtYkgxPjA8BgNVBAMTNVMtVFJV
U1QgQXV0aGVudGljYXRpb24gYW5kIEVuY3J5cHRpb24gUm9vdCBDQSAyMDA1OlBO
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2bVKwdMz6tNGs9HiTNL1
toPQb9UY6ZOvJ44TzbUlNlA0EmQpoVXhOmCTnijJ4/Ob4QSwI7+Vio5bG0F/WsPo
TUzVJBY+h0jUJ67m91MduwwA7z5hca2/OnpYH5Q9XIHV1W/fuJvS9eXLg3KSwlOy
ggLrra1fFi2SU3bxibYs9cEv4KdKb6AwajLrmnQDaHgTncovmwsdvs91DSaXm8f1
XgqfeN+zvOyauu9VjxuapgdjKRdZYgkqeQd3peDRF2npW932kKvimAoA0SVtnteF
hy+S8dF2g08LOlk3KC8zpxdQ1iALCvQm+Z845y2kuJuJja2tyWp9iRe79n+Ag3rm
7QIDAQABo4GSMIGPMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEG
MCkGA1UdEQQiMCCkHjAcMRowGAYDVQQDExFTVFJvbmxpbmUxLTIwNDgtNTAdBgNV
HQ4EFgQUD8oeXHngovMpttKFswtKtWXsa1IwHwYDVR0jBBgwFoAUD8oeXHngovMp
ttKFswtKtWXsa1IwDQYJKoZIhvcNAQEFBQADggEBAK8B8O0ZPCjoTVy7pWMciDMD
pwCHpB8gq9Yc4wYfl35UvbfRssnV2oDsF9eK9XvCAPbpEW+EoFolMeKJ+aQAPzFo
LtU96G7m1R08P7K9n3frndOMusDXtk3sU5wPBG7qNWdX4wple5A64U8+wwCSersF
iXOMy6ZNwPv2AtawB6MDwidAnwzkhYItr5pCHdDHjfhA7p0GVxzZotiAFP7hYy0y
h9WUUpY6RsZxlj33mA6ykaqP2vROJAA5VeitF7nTNCtKqUDMFypVZUF0Qn71wK/I
k63yGFs9iQzbRzkk+OBM8h+wPQrKBU6JIRrjKpms/H+h8Q8bHz2eBIPdltkdOpQ=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIE5zCCA8+gAwIBAgIBADANBgkqhkiG9w0BAQUFADCBjTELMAkGA1UEBhMCQ0Ex
EDAOBgNVBAgTB09udGFyaW8xEDAOBgNVBAcTB1Rvcm9udG8xHTAbBgNVBAoTFEVj
aG93b3J4IENvcnBvcmF0aW9uMR8wHQYDVQQLExZDZXJ0aWZpY2F0aW9uIFNlcnZp
Y2VzMRowGAYDVQQDExFFY2hvd29yeCBSb290IENBMjAeFw0wNTEwMDYxMDQ5MTNa
Fw0zMDEwMDcxMDQ5MTNaMIGNMQswCQYDVQQGEwJDQTEQMA4GA1UECBMHT250YXJp
bzEQMA4GA1UEBxMHVG9yb250bzEdMBsGA1UEChMURWNob3dvcnggQ29ycG9yYXRp
b24xHzAdBgNVBAsTFkNlcnRpZmljYXRpb24gU2VydmljZXMxGjAYBgNVBAMTEUVj
aG93b3J4IFJvb3QgQ0EyMIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEA
utU/5BkV15UBf+s+JQruKQxr77s3rjp/RpOtmhHILIiO5gsEWP8MMrfrVEiidjI6
Qh6ans0KAWc2Dw0/j4qKAQzOSyAZgjcdypNTBZ7muv212DA2Pu41rXqwMrlBrVi/
KTghfdLlNRu6JrC5y8HarrnRFSKF1Thbzz921kLDRoCi+FVs5eVuK5LvIfkhNAqA
byrTgO3T9zfZgk8upmEkANPDL1+8y7dGPB/d6lk0I5mv8PESKX02TlvwgRSIiTHR
k8++iOPLBWlGp7ZfqTEXkPUZhgrQQvxcrwCUo6mk8TqgxCDP5FgPoHFiPLef5szP
ZLBJDWp7GLyE1PmkQI6WiwIBA6OCAVAwggFMMA8GA1UdEwEB/wQFMAMBAf8wCwYD
VR0PBAQDAgEGMB0GA1UdDgQWBBQ74YEboKs/OyGC1eISrq5QqxSlEzCBugYDVR0j
BIGyMIGvgBQ74YEboKs/OyGC1eISrq5QqxSlE6GBk6SBkDCBjTELMAkGA1UEBhMC
Q0ExEDAOBgNVBAgTB09udGFyaW8xEDAOBgNVBAcTB1Rvcm9udG8xHTAbBgNVBAoT
FEVjaG93b3J4IENvcnBvcmF0aW9uMR8wHQYDVQQLExZDZXJ0aWZpY2F0aW9uIFNl
cnZpY2VzMRowGAYDVQQDExFFY2hvd29yeCBSb290IENBMoIBADBQBgNVHSAESTBH
MEUGCysGAQQB+REKAQMBMDYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuZWNob3dv
cnguY29tL2NhL3Jvb3QyL2Nwcy5wZGYwDQYJKoZIhvcNAQEFBQADggEBAG+nrPi/
0RpfEzrj02C6JGPUar4nbjIhcY6N7DWNeqBoUulBSIH/PYGNHYx7/lnJefiixPGE
7TQ5xPgElxb9bK8zoAApO7U33OubqZ7M7DlHnFeCoOoIAZnG1kuwKwD5CXKB2a74
HzcqNnFW0IsBFCYqrVh/rQgJOzDA8POGbH0DeD0xjwBBooAolkKT+7ZItJF1Pb56
QpDL9G+16F7GkmnKlAIYT3QTS3yFGYChnJcd+6txUPhKi9sSOOmAIaKHnkH9Scz+
A2cSi4A3wUYXVatuVNHpRb2lygfH3SuCX9MU8Ure3zBlSU1LALtMqI4JmcQmQpIq
zIzvO2jHyu9PQqo=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB
ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly
aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl
ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w
NTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G
A1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD
VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX
SVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR
VVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2
w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF
mQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg
4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9
4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw
DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw
EAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx
SPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2
ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8
vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa
hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi
Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ
/L7fCg0=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjEL
MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV
BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0
Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYwMTEyMTQzODQzWhcNMjUxMjMxMjI1
OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i
SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UEAxMc
VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jf
tMjWQ+nEdVl//OEd+DFwIxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKg
uNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2J
XjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQXa7pIXSSTYtZgo+U4+lK
8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7uSNQZu+99
5OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1Ud
EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3
kUrL84J6E1wIqzCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy
dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6
Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz
JTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290
Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iS
GNn3Bzn1LL4GdXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprt
ZjluS5TmVfwLG4t3wVMTZonZKNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8
au0WOB9/WIFaGusyiC2y8zl3gK9etmF1KdsjTYjKUCjLhdLTEKJZbtOTVAB6okaV
hgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kPJOzHdiEoZa5X6AeI
dUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfkvQ==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjEL
MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV
BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0
Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYwMTEyMTQ0MTU3WhcNMjUxMjMxMjI1
OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i
SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UEAxMc
VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJW
Ht4bNwcwIi9v8Qbxq63WyKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+Q
Vl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo6SI7dYnWRBpl8huXJh0obazovVkdKyT2
1oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZuV3bOx4a+9P/FRQI2Alq
ukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk2ZyqBwi1
Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1Ud
EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NX
XAek0CSnwPIA1DCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy
dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6
Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz
JTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290
Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlN
irTzwppVMXzEO2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8
TtXqluJucsG7Kv5sbviRmEb8yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6
g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9IJqDnxrcOfHFcqMRA/07QlIp2+gB
95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal092Y+tTmBvTwtiBj
S+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc5A==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFvzCCA6egAwIBAgIQANKFcP2up9ZfEYQVxjG1yzANBgkqhkiG9w0BAQUFADBd
MQswCQYDVQQGEwJFUzEoMCYGA1UECgwfRElSRUNDSU9OIEdFTkVSQUwgREUgTEEg
UE9MSUNJQTENMAsGA1UECwwERE5JRTEVMBMGA1UEAwwMQUMgUkFJWiBETklFMB4X
DTA2MDIxNjEwMzcyNVoXDTM2MDIwODIyNTk1OVowXTELMAkGA1UEBhMCRVMxKDAm
BgNVBAoMH0RJUkVDQ0lPTiBHRU5FUkFMIERFIExBIFBPTElDSUExDTALBgNVBAsM
BEROSUUxFTATBgNVBAMMDEFDIFJBSVogRE5JRTCCAiIwDQYJKoZIhvcNAQEBBQAD
ggIPADCCAgoCggIBAIAArQzDoyAHo2P/9zSgze5qVAgXXbEBFafmuV+Kcf8Mwh3q
N/Pek3/WBU2EstXXHAz0xJFwQA5ayJikgOgNM8AH87f1rKE4esBmVCT8UswwKvLD
xKEsdr/BwL+C8ZvwaHoTQMiXvBwlBwgKt5bvzClU4OZlLeqyLrEJaRJOMNXY+LwA
gC9Nkw/NLlcbM7ufME7Epct5p/viNBi2IJ4bn12nyTqtRWSzGM4REpxtHlVFKISc
V2dN+cvii49YCdQ5/8g20jjiDGV/FQ59wQfdqSLfkQDEbHE0dNw56upPRGl/WNtY
ClJxK+ypHVB0M/kpavr+mfTnzEVFbcpaJaIS487XOAU58BoJ9XZZzmJvejQNLNG8
BBLsPVPI+tACy849IbXF4DkzZc85U8mbRvmdM/NZgAhBvm9LoPpKzqR2HIXir68U
nWWs93+X5DNJpq++zis38S7BcwWcnGBMnTANl1SegWK75+Av9xQHFKl3kenckZWO
04iQM0dvccMUafqmLQEeG+rTLuJ/C9zP5yLw8UGjAZLlgNO+qWKoVYgLNDTs3CEV
qu/WIl6J9VGSEypvgBbZsQ3ZLvgQuML+UkUznB04fNwVaTRzv6AsuxF7lM34Ny1v
Pe+DWsYem3RJj9nCjb4WdlDIWtElFvb2zIycWjCeZb7QmkiT1/poDXUxh/n3AgMB
AAGjezB5MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQW
BBSORfSfc8X/LxsF2wFHYBsDioG3ujA3BgNVHSAEMDAuMCwGBFUdIAAwJDAiBggr
BgEFBQcCARYWaHR0cDovL3d3dy5kbmllLmVzL2RwYzANBgkqhkiG9w0BAQUFAAOC
AgEAdeVzyVFRL4sZoIfp/642Nqb8QR/jHtdxYBnGb5oCML1ica1z/pEtTuQmQESp
rngmIzFp3Jpzlh5JUQvg78G4Q+9xnO5Bt8VQHzKEniKG8fcfj9mtK07alyiXu5aa
Gvix2XoE81SZEhmWFYBnOf8CX3r8VUJQWua5ov+4qGIeFM3ZP76jZUjFO9c3zg36
KJDav/njUUclfUrTZ02HqmK8Xux6gER8958KvWVXlMryEWbWUn/kOnB1BM07l9Q2
cvdRVr809dJB4bTaqEP+axJJErRdzyJClowIIyaMshBOXapT7gEvdeW5ohEzxNdq
/fgOym6C2ee7WSNOtfkRHS9rI/V7ESDqQRKQMkbbMTupwVtzaDpGG4z+l7dWuWGZ
zE7wg/o38d4cnRxxiwOTw8Rzgi6omB1kopqM91QITc/qgcv1WwmZY691jJb4eTXV
3OtBgXk4hF5v8W9idtuRzlqFYDkdW+IqL0Ml28J6JNMVsKLxjKB9a0gJE/+iTGaK
7HBSCVOMMMy41bok3DCZPqFet9+BrOw3vk6bJ1jefqGbVH8Gti/kMlD95xC7qM3a
GBvUY2Y96lFxOfScPt9a9NrHTCbti7UhujR5AnNhENqYMahgy34Hp9C3BUOJW82F
JtmwUa/3jFKqEqdY35KbZ/Kd8ub0aTH0Fufed1se3ZoFAa0=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIHxDCCBaygAwIBAgIIGq+SbI+Tr2AwDQYJKoZIhvcNAQEFBQAwgZUxgZIwCQYD
VQQGDAJCRzAVBgNVBAoMDkluZm9Ob3RhcnkgUExDMBUGCgmSJomT8ixkARkWB3Jv
b3QtY2EwGgYDVQQDDBNJbmZvTm90YXJ5IENTUCBSb290MBoGA1UECwwTSW5mb05v
dGFyeSBDU1AgUm9vdDAfBgkqhkiG9w0BCQEWEmNzcEBpbmZvbm90YXJ5LmNvbTAi
GA8yMDA2MDMwNjE3MzMwNVoYDzIwMjYwMzA2MTczMzA1WjCBlTGBkjAJBgNVBAYM
AkJHMBUGA1UECgwOSW5mb05vdGFyeSBQTEMwFQYKCZImiZPyLGQBGRYHcm9vdC1j
YTAaBgNVBAMME0luZm9Ob3RhcnkgQ1NQIFJvb3QwGgYDVQQLDBNJbmZvTm90YXJ5
IENTUCBSb290MB8GCSqGSIb3DQEJARYSY3NwQGluZm9ub3RhcnkuY29tMIICIjAN
BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnM2kXh+kfgiCT4B2wSeMRxZgn3Os
yZF/LRBsO5RJnEIzX5TxgyEJkfeStw84RYuUB0qr/j82NVvR1VI4QkboR8dKUDPI
5OBztpCauqOIONMrQsBu36ITF/JPuefyId1l+qb9UsJgsstPN72vJ45pazJAU1n1
8jF2iAZtaJ8wvLeBHI5nY8MFZfcz9lmpq7OKRwsUE8c23SL7+EQ0NUEowIG6TrVx
E68DqEkKLqSbYXdrHSTSpfEt0Udegv9Ig7AVmEfedvtPTsC/VElmvE8B0Xw6Zf7F
rHBbxRUbcqV9pls7F8O+wz9dEn9nLXZHDIu/FiO1g3LNgM3ouq9eaDM41JDtbtLp
VgQkofm+bF7KniMgkiuaDUtN46JIj77tqg6Mvqk4cLkQfzJdgCdaA+DURzMlWnap
g9mYQO1/dQLv7mGRrDE+gNM0S/DCTjUwSV63Keh9IbD/KnmcNDEZZjMgYRovsILV
sWdTkA2dKpcobrdmPxp/psSaaJbmZlt6N99adxXg2eN8s7LQ1WjbPh1YH47KmHRj
v9R9Nmju0C+kKvKIL3fDEj+NqCUsBGlYpsu0OfGI0Kbels5zQkbTo/nx2I6KnW6K
wFJPRbdw/hx7PQ2W3PmQlm3GGKFCwrbc2SMfl5ObDxn5sLc/JXS9glPsDS9t1j9S
L9h20CW90Ln1vQ8CAwEAAaOCAhAwggIMMA4GA1UdDwEB/wQEAwIBBjBEBggrBgEF
BQcBAQQ4MDYwNAYIKwYBBQUHMAGGKGh0dHA6Ly9vY3NwLmluZm9ub3RhcnkuY29t
L3Jlc3BvbmRlci5jZ2kwVgYIKwYBBQUHAQsESjBIMEYGCCsGAQUFBzAFhjpsZGFw
Oi8vbGRhcC5pbmZvbm90YXJ5LmNvbS9kYz1yb290LWNhLGRjPWluZm9ub3Rhcnks
ZGM9Y29tMIGqBgNVHSAEgaIwgZ8wbwYJKwYBBAGBrQABMGIwOgYIKwYBBQUHAgEW
Lmh0dHA6Ly9yZXBvc2l0b3J5LmluZm9ub3RhcnkuY29tL2Nwcy9xY3BzLmh0bWww
JAYIKwYBBQUHAgIwGBoWSW5mb05vdGFyeSBDU1AgUm9vdCBDQTAsBgkrBgEEAYGt
AAAwHzAdBggrBgEFBQcCARYRaHR0cDovL3d3dy5jcmMuYmcwDwYDVR0TAQH/BAUw
AwEB/zB/BgNVHREEeDB2pHQwcjFwMAsGA1UEEQwEMTAwMDAMBgNVBAcMBVNvZmlh
MBMGA1UEFAwMKzM1OTI5ODc1NzE3MBsGBlUECmQBAQwRMTMxMjc2ODI3OkJVTFNU
QVQwIQYJKoZIhvcNAQkIDBQxNiBJdmFuIFZhc292IFN0cmVldDAdBgNVHQ4EFgQU
3dROZ0M/0+pi6NqJbo47bgu7lZ8wDQYJKoZIhvcNAQEFBQADggIBABib/A3B+HGs
1MwUtScJwVhKNEDmm2XK4PGLUj2Wfoke3qgV+t2ULoPGNl0bIak2Dlw9SYgMUyFd
H21JNm+cUOvbZM+Juq9erRREh2LvMHzAlt9wOcs7Ue4r/AgFh1bNMyXggBrgpucN
Q0wAI0NWog4ZVOKN0Q0WuVpvm3flHKmDiyjx4TJ2X0ewmjbqsm/dhjFY/gZpsMNg
pvvYKNQI3fFuThq9zbesviKHFkmxOADVjEMp5ylrKxJiWapD8LRyiDjWAl8f2iSS
jY18/B99OJBYCx8ctxy7NictWhzHMd20K529R6ExtwkR4s1vp270uKMpj/Ngv6cd
4E+XJSUKMEnH/no5RNTTZe+IXf/Z7lM5vDpEqDE7JZd7mr/R3Wvi1xJq+zK70diO
85azj5DqeFjBCtulJb6KAx/lktK8f6Ry5OtWeqn6fLjxoL8m/ko0zyWqZMS7e+0Y
5Uwsb0Fl7eC7PSx1VW/kFQbFS2yT9g9VzJN1hWEmA9LMlct6ECAnVnq/dVjc9Q2W
2UoHhNgimxDR1gZuFgcDs69546AXurhDCEKdPDsnzHwR1H4x82ZRAhFyOqPpcr2V
XaEVf0cTOZWyta728WF0MHjHZgHTsnCXCMkNJPREKnCmnS8SZAZuio0g437a8VS/
DRSsKb59f3+5a0UCUWcVWaIOISfJgmcx
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTEL
MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV
BAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1
c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcNMDYwMzIyMTU1NDI4WhcNMjUxMjMx
MjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIg
R21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYwJAYD
VQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSR
JJZ4Hgmgm5qVSkr1YnwCqMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3T
fCZdzHd55yx4Oagmcw6iXSVphU9VDprvxrlE4Vc93x9UIuVvZaozhDrzznq+VZeu
jRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtwag+1m7Z3W0hZneTvWq3z
wZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9OgdwZu5GQ
fezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYD
VR0jBBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAO
BgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0G
CSqGSIb3DQEBBQUAA4IBAQAo0uCG1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X1
7caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/CyvwbZ71q+s2IhtNerNXxTPqYn
8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3ghUJGooWMNjs
ydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT
ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/
2TYcuiUaUj0a7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIF3zCCA8egAwIBAgIOGTMAAQACKBqaBLzyVUUwDQYJKoZIhvcNAQEFBQAwejEL
MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV
BAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEnMCUGA1UEAxMeVEMgVHJ1
c3RDZW50ZXIgVW5pdmVyc2FsIENBIElJMB4XDTA2MDMyMjE1NTgzNFoXDTMwMTIz
MTIyNTk1OVowejELMAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVy
IEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEnMCUG
A1UEAxMeVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIElJMIICIjANBgkqhkiG
9w0BAQEFAAOCAg8AMIICCgKCAgEAi9R3azRs5TbYalxeOO781R15Azt7g2JEgk6I
7d6D/+7MUGIFBZWZdpj2ufJf2AaRksL2LWYXH/1TA+iojWOpbuHWG4y8mLOLO9Tk
Lsp9hUkmW3m4GotAnn+7yT9jLM/RWny6KCJBElpN+Rd3/IX9wkngKhh/6aAsnPlE
/AxoOUL1JwW+jhV6YJ3wO8c85j4WvK923mq3ouGrRkXrjGV90ZfzlxElq1nroCLZ
gt2Y7X7i+qBhCkoy3iwX921E6oFHWZdXNwM53V6CItQzuPomCba8OYgvURVOm8M7
3xOCiN1LNPIz1pDp81PcNXzAw9l8eLPNcD+NauCjgUjkKa1juPD8KGQ7mbN9/pqd
iPaZIgiRRxaJNXhdd6HPv0nh/SSUK2k2e+gc5iqQilvVOzRZQtxtz7sPQRxVzfUN
Wy4WIibvYR6X/OJTyM9bo8ep8boOhhLLE8oVx+zkNo3aXBM9ZdIOXXB03L+PemrB
Lg/Txl4PK1lszGFs/sBhTtnmT0ayWuIZFHCE+CAA7QGnl37DvRJckiMXoKUdRRcV
I5qSCLUiiI3cKyTr4LEXaNOvYb3ZhXj2jbp4yjeNY77nrB/fpUcJucglMVRGURFV
DYlcjdrSGC1z8rjVJ/VIIjfRYvd7Dcg4i6FKsPzQ8eu3hmPn4A5zf/1yUbXpfeJV
BWR4Z38CAwEAAaNjMGEwHwYDVR0jBBgwFoAUzdeQoW6jv9sw1toyJZAM5jkegGUw
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFM3XkKFu
o7/bMNbaMiWQDOY5HoBlMA0GCSqGSIb3DQEBBQUAA4ICAQB+FojoEw42zG4qhQc4
xlaJeuNHIWZMUAgxWlHQ/KZeFHXeTDvs8e3MfhEHSmHu6rOOOqQzxu2KQmZP8Tx7
yaUFQZmx7Cxb7tyW0ohTS3g0uW7muw/FeqZ8Dhjfbw90TNGp8aHp2FRkzF6WeKJW
GsFzshXGVwXf2vdIJIqOf2qp+U3pPmrOYCx9LZAI9mOPFdAtnIz/8f38DBZQVhT7
upeG7rRJA1TuG1l/MDoCgoYhrv7wFfLfToPmmcW6NfcgkIw47XXP4S73BDD7Ua2O
giRAyn0pXdXZ92Vk/KqfdLh9kl3ShCngE+qK99CrxK7vFcXCifJ7tjtJmGHzTnKR
N4xJkunI7Cqg90lufA0kxmts8jgvynAF5X/fxisrgIDV2m/LQLvYG/AkyRDIRAJ+
LtOYqqIN8SvQ2vqOHP9U6OFKbt2o1ni1N6WsZNUUI8cOpevhCTjXwHxgpV2Yj4wC
1dxWqPNNWKkL1HxkdAEy8t8PSoqpAqKiHYR3wvHMl700GXRd4nQ+dSf3r7/ufA5t
VIimVuImrTESPB5BeW0X6hNeH/Vcn0lZo7Ivo0LD+qh+v6WfSMlgYmIK371F3uNC
tVGW/cT1Gpm4UqJEzS1hjBWPgdVdotSQPYxuQGHDWV3Y2eH2dEcieXR92sqjbzcV
NvAsGnE8EXbfXRo+VGN4a2V+Hw==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDtjCCAp6gAwIBAgIOBcAAAQACQdAGCk3OdRAwDQYJKoZIhvcNAQEFBQAwdjEL
MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV
BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDQgQ0ExJTAjBgNVBAMTHFRDIFRydXN0
Q2VudGVyIENsYXNzIDQgQ0EgSUkwHhcNMDYwMzIzMTQxMDIzWhcNMjUxMjMxMjI1
OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i
SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgNCBDQTElMCMGA1UEAxMc
VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgNCBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBALXNTJytrlG7fEjFDSmGehSt2VA9CXIgDRS2Y8b+WJ7gIV7z
jyIZ3E6RIM1viCmis8GsKnK6i1S4QF/yqvhDhsIwXMynXX/GCEnkDjkvjhjWkd0j
FnmA22xIHbzB3ygQY9GB493fL3l1oht48pQB5hBiecugfQLANIJ7x8CtHUzXapZ2
W78mhEj9h/aECqqSB5lIPGG8ToVYx5ct/YFKocabEvVCUNFkPologiJw3fX64yhC
L04y87OjNopq1mJcrPoBbbTgci6VaLTxkwzGioLSHVPqfOA/QrcSWrjN2qUGZ8uh
d32llvCSHmcOHUJG5vnt+0dTf1cERh9GX8eu4I8CAwEAAaNCMEAwDwYDVR0TAQH/
BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFB/quz4lGwa9pd1iBX7G
TFq/6A9DMA0GCSqGSIb3DQEBBQUAA4IBAQBYpCubTPfkpJKknGWYGWIi/HIy6QRd
xMRwLVpG3kxHiiW5ot3u6hKvSI3vK2fbO8w0mCr3CEf/Iq978fTr4jgCMxh1KBue
dmWsiANy8jhHHYz1nwqIUxAUu4DlDLNdjRfuHhkcho0UZ3iMksseIUn3f9MYv5x5
+F0IebWqak2SNmy8eesOPXmK2PajVnBd3ttPedJ60pVchidlvqDTB4FAVd0Qy+BL
iILAkH0457+W4Ze6mqtCD9Of2J4VMxHL94J59bXAQVaS4d9VA61Iz9PyLrHHLVZM
ZHQqMc7cdalUR6SnQnIJ5+ECpkeyBM1CE+FhDOB4OiIgohxgQoaH96Xm
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEuzCCA6OgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJVUzET
MBEGA1UEChMKQXBwbGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlv
biBBdXRob3JpdHkxFjAUBgNVBAMTDUFwcGxlIFJvb3QgQ0EwHhcNMDYwNDI1MjE0
MDM2WhcNMzUwMjA5MjE0MDM2WjBiMQswCQYDVQQGEwJVUzETMBEGA1UEChMKQXBw
bGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx
FjAUBgNVBAMTDUFwcGxlIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQDkkakJH5HbHkdQ6wXtXnmELes2oldMVeyLGYne+Uts9QerIjAC6Bg+
+FAJ039BqJj50cpmnCRrEdCju+QbKsMflZ56DKRHi1vUFjczy8QPTc4UadHJGXL1
XQ7Vf1+b8iUDulWPTV0N8WQ1IxVLFVkds5T39pyez1C6wVhQZ48ItCD3y6wsIG9w
tj8BMIy3Q88PnT3zK0koGsj+zrW5DtleHNbLPbU6rfQPDgCSC7EhFi501TwN22IW
q6NxkkdTVcGvL0Gz+PvjcM3mo0xFfh9Ma1CWQYnEdGILEINBhzOKgbEwWOxaBDKM
aLOPHd5lc/9nXmW8Sdh2nzMUZaF3lMktAgMBAAGjggF6MIIBdjAOBgNVHQ8BAf8E
BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUK9BpR5R2Cf70a40uQKb3
R01/CF4wHwYDVR0jBBgwFoAUK9BpR5R2Cf70a40uQKb3R01/CF4wggERBgNVHSAE
ggEIMIIBBDCCAQAGCSqGSIb3Y2QFATCB8jAqBggrBgEFBQcCARYeaHR0cHM6Ly93
d3cuYXBwbGUuY29tL2FwcGxlY2EvMIHDBggrBgEFBQcCAjCBthqBs1JlbGlhbmNl
IG9uIHRoaXMgY2VydGlmaWNhdGUgYnkgYW55IHBhcnR5IGFzc3VtZXMgYWNjZXB0
YW5jZSBvZiB0aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5kYXJkIHRlcm1zIGFuZCBj
b25kaXRpb25zIG9mIHVzZSwgY2VydGlmaWNhdGUgcG9saWN5IGFuZCBjZXJ0aWZp
Y2F0aW9uIHByYWN0aWNlIHN0YXRlbWVudHMuMA0GCSqGSIb3DQEBBQUAA4IBAQBc
NplMLXi37Yyb3PN3m/J20ncwT8EfhYOFG5k9RzfyqZtAjizUsZAS2L70c5vu0mQP
y3lPNNiiPvl4/2vIB+x9OYOLUyDTOMSxv5pPCmv/K/xZpwUJfBdAVhEedNO3iyM7
R6PVbyTi69G3cN8PReEnyvFteO3ntRcXqNx+IjXKJdXZD9Zr1KIkIxH3oayPc4Fg
xhtbCS+SsvhESPBgOJ4V9T0mZyCKM2r3DYLP3uujL/lTaltkwGMzd/c6ByxW69oP
IQ7aunMZT7XZNn/Bh1XZp5m5MkL72NVxnn6hUrcbvZNCJBIqxw8dtk2cXmPIS4AX
UKqK1drk/NAJBzewdXUh
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFbjCCA1agAwIBAgIPQupbClERJnzYJ3S3339xMA0GCSqGSIb3DQEBBQUAMDMx
CzAJBgNVBAYTAlBUMQ0wCwYDVQQKDARTQ0VFMRUwEwYDVQQDDAxFQ1JhaXpFc3Rh
ZG8wHhcNMDYwNjIzMTM0MTI3WhcNMzAwNjIzMTM0MTI3WjAzMQswCQYDVQQGEwJQ
VDENMAsGA1UECgwEU0NFRTEVMBMGA1UEAwwMRUNSYWl6RXN0YWRvMIICIjANBgkq
hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA2++iQ27Iqf1u19+sopKEochZoAyaU/7v
rswZDXKKpMIzI+/nBnLqbUs6QVIPyUgOLee6ZO6iOkxjXGYpi9+piMW96PH3jkv8
ATxEEjkqcKLA28Wi31/HS8ao3D1hfEpYwUQyk95wmaEjJlY/o+HqXzBG2Hj1MKOW
CYmwPfGGkwW2EmoYjfClZDsrh2RePReOC27mmMyXODggjHBaaSu9ZY3NN1lcbNFy
dFkGTsi3Add3v/BIhqizGl1B1DcXERBfSm6NdcUDQH0hrgDw2/yfbDpmpN/3yt+A
ZlrZ2H8UoiYZ9K4LIeDKPgXdFth+WdqhsGnDnTQT+mVJOYfudi+NvTwnGQNOrQ4L
KyzGLnETNSlX6XDcG1HqzZfxlY2yhvomBi+AGpXxmDvu9uWGpc4bAeX06TPKD1VE
X2iKLMdbZijdlkuDnV4dfhjV/rJg+5pRaMOWjB9oS1BSCzbmMSfk1ykMG9obL+EE
U7jUeUmwO4FeCIgid+IpwK5yqqu0clK9bLv1unjZnLggbzCNSp0y+fQB5mJ5mEJA
BXpvHCo/tfvfzRhAjuUQxDlbVvE8VwWr0jlNP/iLI8druUCx4v7/sxwKaR+bjA+0
H+AK3kj9jV+PmfUBdgU2XY7cM45RbhHiQf3Mt40qXz6S5fKx4KQj4qK3xo0YmylK
0UZ/9GQgGN0CAwEAAaN/MH0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
AQYwHQYDVR0OBBYEFHF/Nd71d3FtHRKc4ZCkuvCpg4+AMDsGA1UdIAQ0MDIwMAYE
VR0gADAoMCYGCCsGAQUFBwIBFhpodHRwOi8vd3d3LmVjZWUuZ292LnB0L2RwYzAN
BgkqhkiG9w0BAQUFAAOCAgEAjK2ccqW1Z3ZnOIfpOoz+nVk1vpDxAwCgWNiY0b/8
/PNQ3LRl1dq68IwufA3mCZFfTaP2XXicWF1qcJSjr9svAMkDQGvfUQMWGYwrvJk2
9sCtkhgTjKftHdLfA5AF7LCTmJv3TVoT+Oeb9zZ23nwm+BE4T0lOs3MfXydb4Z4y
HvbAmBvZICxclo2GyQtF15Ktir3qV6KjVrYgPOyyxzl+sID+vVErKrTDcmnD+Ucu
bv+ch+3cdcsQiOC0zi4OUx0L6G4eQkzQvjl4dckU3ieRc6rsaoDw8BeWYk++BMvi
p+VdD5NFy1lIJhPe3bH1CtoWsagdj35YG7fVCd6Ia86EPqi+UmLK0qGhx8s8FuB2
VjA/5g9rBnf+ZJ1aanN87t4h6ZpJlze2hH+ikT5F+9daBsWHNdy6SEyGAQhHNrY4
UJURmXPRN0kK+kJPLxBU00GQ+sjcuxHcDcx9fJvcDpFxhk248hWaKzgXEaHynqhs
nOPOruLmS4vyigY7B3cCEe6D6p1mhsrwYqnVV4OkFfFFFP4adX+lD9xSdFl1Cvj7
VUGpXI0xRN3NlE4z0RtBqtvXoTzwxUhtRUE1tXmD5vlN8VY4179AIvsggOMcwllG
B2MCYQA7m1C7Q8Ow6QqauHb0R2FVZHBPN9mcEaMTsuHdQEK7mNegBovmaFdLDjho
f7o=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT
AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD
QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP
MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do
0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ
UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d
RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ
OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv
JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C
AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O
BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ
LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY
MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ
44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I
Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw
i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN
9u6wWk5JRFRYX0KD
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIH/jCCBeagAwIBAgIBADANBgkqhkiG9w0BAQUFADCB1DELMAkGA1UEBhMCQVQx
DzANBgNVBAcTBlZpZW5uYTEQMA4GA1UECBMHQXVzdHJpYTE6MDgGA1UEChMxQVJH
RSBEQVRFTiAtIEF1c3R
Download .txt
gitextract_l155h8jc/

├── .claude/
│   └── commands/
│       └── ship.md
├── .dockerignore
├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       ├── api-preview.yml
│       ├── claude-code-review.yml
│       ├── claude.yml
│       ├── deploy-checker.yml
│       ├── deploy-private-location.yml
│       ├── deploy-workflows.yml
│       ├── deploy.yml
│       ├── docker-publish-dev.yml
│       ├── docker-publish.yml
│       ├── dx.yml
│       ├── go-tests.yml
│       ├── lint.yml
│       ├── migrate.yml
│       ├── publish-checker.yml
│       ├── synthetic.yml
│       ├── test.yml
│       └── workflow-preview.yml
├── .gitignore
├── .koyebignore
├── .npmrc
├── .oxlintrc.json
├── .prettierignore
├── .stacked.toml
├── .vscode/
│   └── settings.json
├── CLAUDE.md
├── CONTRIBUTING.MD
├── COOLIFY_DEPLOYMENT.md
├── COOLIFY_ENVIRONMENT_GUIDE.md
├── COOLIFY_SETUP.md
├── DOCKER.md
├── LICENSE
├── README.md
├── SECURITY.md
├── apps/
│   ├── README.md
│   ├── checker/
│   │   ├── .gitignore
│   │   ├── .golangci.yml
│   │   ├── .private.air.toml
│   │   ├── .probe.air.toml
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── ca/
│   │   │   └── ca-bundle.crt
│   │   ├── checker/
│   │   │   ├── dns.go
│   │   │   ├── dns_test.go
│   │   │   ├── http.go
│   │   │   ├── http_test.go
│   │   │   ├── tcp.go
│   │   │   ├── tcp_test.go
│   │   │   └── update.go
│   │   ├── cmd/
│   │   │   ├── private/
│   │   │   │   └── main.go
│   │   │   └── server/
│   │   │       └── main.go
│   │   ├── fly.toml
│   │   ├── go.mod
│   │   ├── go.sum
│   │   ├── handlers/
│   │   │   ├── checker.go
│   │   │   ├── checker_test.go
│   │   │   ├── dns.go
│   │   │   ├── dns_test.go
│   │   │   ├── handler.go
│   │   │   ├── ping.go
│   │   │   ├── ping_test.go
│   │   │   └── tcp.go
│   │   ├── justfile
│   │   ├── pkg/
│   │   │   ├── assertions/
│   │   │   │   ├── assertions.go
│   │   │   │   └── assertions_test.go
│   │   │   ├── job/
│   │   │   │   ├── dns_job.go
│   │   │   │   ├── http_job.go
│   │   │   │   ├── http_job_test.go
│   │   │   │   ├── job.go
│   │   │   │   ├── monitors.go
│   │   │   │   ├── tcp_job.go
│   │   │   │   └── tcp_job_test.go
│   │   │   ├── logger/
│   │   │   │   └── logger.go
│   │   │   ├── otel/
│   │   │   │   ├── otel.go
│   │   │   │   └── otel_test.go
│   │   │   ├── scheduler/
│   │   │   │   ├── scheduler.go
│   │   │   │   └── scheduler_test.go
│   │   │   └── tinybird/
│   │   │       ├── client.go
│   │   │       └── client_test.go
│   │   ├── private-location.Dockerfile
│   │   ├── proto/
│   │   │   └── private_location/
│   │   │       └── v1/
│   │   │           ├── assertions.pb.go
│   │   │           ├── dns_monitor.pb.go
│   │   │           ├── http_monitor.pb.go
│   │   │           ├── private_location.connect.go
│   │   │           ├── private_location.pb.go
│   │   │           └── tcp_monitor.pb.go
│   │   └── request/
│   │       └── request.go
│   ├── dashboard/
│   │   ├── .dockerignore
│   │   ├── .gitignore
│   │   ├── Dockerfile
│   │   ├── components.json
│   │   ├── docker-compose.yaml
│   │   ├── dofigen.yml
│   │   ├── env.ts
│   │   ├── instrumentation-client.ts
│   │   ├── next-env.d.ts
│   │   ├── next.config.ts
│   │   ├── package.json
│   │   ├── postcss.config.mjs
│   │   ├── public/
│   │   │   └── fonts/
│   │   │       ├── CommitMono-400-Italic.otf
│   │   │       ├── CommitMono-400-Regular.otf
│   │   │       ├── CommitMono-700-Italic.otf
│   │   │       └── CommitMono-700-Regular.otf
│   │   ├── sentry.edge.config.ts
│   │   ├── sentry.server.config.ts
│   │   ├── src/
│   │   │   ├── app/
│   │   │   │   ├── (dashboard)/
│   │   │   │   │   ├── agents/
│   │   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── cli/
│   │   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── invite/
│   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   └── search-params.tsx
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   ├── monitors/
│   │   │   │   │   │   ├── (list)/
│   │   │   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   └── search-params.ts
│   │   │   │   │   │   ├── [id]/
│   │   │   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   │   │   ├── constants.ts
│   │   │   │   │   │   │   ├── edit/
│   │   │   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── incidents/
│   │   │   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   │   ├── logs/
│   │   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   │   └── search-params.ts
│   │   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   │   ├── overview/
│   │   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   │   └── search-params.ts
│   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   ├── sidebar.tsx
│   │   │   │   │   │   │   └── tabs.tsx
│   │   │   │   │   │   └── create/
│   │   │   │   │   │       ├── breadcrumb.tsx
│   │   │   │   │   │       ├── layout.tsx
│   │   │   │   │   │       └── page.tsx
│   │   │   │   │   ├── notifications/
│   │   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   └── search-params.ts
│   │   │   │   │   ├── onboarding/
│   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   └── search-params.ts
│   │   │   │   │   ├── overview/
│   │   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   │   ├── data-table-status-reports.tsx
│   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── page.tsx
│   │   │   │   │   ├── private-locations/
│   │   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── settings/
│   │   │   │   │   │   ├── (list)/
│   │   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── account/
│   │   │   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── billing/
│   │   │   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   └── search-params.ts
│   │   │   │   │   │   ├── general/
│   │   │   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── integrations/
│   │   │   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   │   ├── nav-actions.tsx
│   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   └── slack-card.tsx
│   │   │   │   │   │   └── tabs.tsx
│   │   │   │   │   └── status-pages/
│   │   │   │   │       ├── (list)/
│   │   │   │   │       │   ├── breadcrumb.tsx
│   │   │   │   │       │   ├── client.tsx
│   │   │   │   │       │   ├── layout.tsx
│   │   │   │   │       │   ├── nav-actions.tsx
│   │   │   │   │       │   └── page.tsx
│   │   │   │   │       ├── [id]/
│   │   │   │   │       │   ├── breadcrumb.tsx
│   │   │   │   │       │   ├── components/
│   │   │   │   │       │   │   ├── layout.tsx
│   │   │   │   │       │   │   └── page.tsx
│   │   │   │   │       │   ├── constants.ts
│   │   │   │   │       │   ├── edit/
│   │   │   │   │       │   │   └── page.tsx
│   │   │   │   │       │   ├── layout.tsx
│   │   │   │   │       │   ├── maintenances/
│   │   │   │   │       │   │   ├── layout.tsx
│   │   │   │   │       │   │   └── page.tsx
│   │   │   │   │       │   ├── nav-actions.tsx
│   │   │   │   │       │   ├── page.tsx
│   │   │   │   │       │   ├── sidebar.tsx
│   │   │   │   │       │   ├── status-reports/
│   │   │   │   │       │   │   ├── [reportId]/
│   │   │   │   │       │   │   │   ├── layout.tsx
│   │   │   │   │       │   │   │   └── page.tsx
│   │   │   │   │       │   │   ├── layout.tsx
│   │   │   │   │       │   │   └── page.tsx
│   │   │   │   │       │   ├── subscribers/
│   │   │   │   │       │   │   ├── layout.tsx
│   │   │   │   │       │   │   └── page.tsx
│   │   │   │   │       │   └── tabs.tsx
│   │   │   │   │       └── create/
│   │   │   │   │           ├── breadcrumb.tsx
│   │   │   │   │           ├── client.tsx
│   │   │   │   │           ├── layout.tsx
│   │   │   │   │           └── page.tsx
│   │   │   │   ├── api/
│   │   │   │   │   ├── auth/
│   │   │   │   │   │   └── [...nextauth]/
│   │   │   │   │   │       └── route.ts
│   │   │   │   │   └── trpc/
│   │   │   │   │       ├── edge/
│   │   │   │   │       │   └── [trpc]/
│   │   │   │   │       │       └── route.ts
│   │   │   │   │       └── lambda/
│   │   │   │   │           └── [trpc]/
│   │   │   │   │               └── route.ts
│   │   │   │   ├── global-error.tsx
│   │   │   │   ├── globals.css
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── login/
│   │   │   │   │   ├── _components/
│   │   │   │   │   │   ├── actions.ts
│   │   │   │   │   │   └── magic-link-form.tsx
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   ├── page.tsx
│   │   │   │   │   └── search-params.ts
│   │   │   │   ├── metadata.ts
│   │   │   │   ├── not-found.tsx
│   │   │   │   ├── react-table.d.ts
│   │   │   │   └── robots.ts
│   │   │   ├── components/
│   │   │   │   ├── chart/
│   │   │   │   │   ├── chart-area-latency.tsx
│   │   │   │   │   ├── chart-area-timing-phases.tsx
│   │   │   │   │   ├── chart-bar-uptime-light.tsx
│   │   │   │   │   ├── chart-bar-uptime.tsx
│   │   │   │   │   ├── chart-line-region.tsx
│   │   │   │   │   ├── chart-line-regions.tsx
│   │   │   │   │   └── chart-tooltip-number.tsx
│   │   │   │   ├── common/
│   │   │   │   │   ├── code.tsx
│   │   │   │   │   ├── hover-card-timestamp.tsx
│   │   │   │   │   ├── icon-cloud-provider.tsx
│   │   │   │   │   ├── input-with-addons.tsx
│   │   │   │   │   ├── kbd.tsx
│   │   │   │   │   ├── link.tsx
│   │   │   │   │   ├── note.tsx
│   │   │   │   │   └── wheel-picker.tsx
│   │   │   │   ├── content/
│   │   │   │   │   ├── action-card.tsx
│   │   │   │   │   ├── billing-addons.tsx
│   │   │   │   │   ├── billing-overlay.tsx
│   │   │   │   │   ├── billing-progress.tsx
│   │   │   │   │   ├── block-wrapper.tsx
│   │   │   │   │   ├── empty-state.tsx
│   │   │   │   │   ├── process-message.tsx
│   │   │   │   │   └── section.tsx
│   │   │   │   ├── controls-filter/
│   │   │   │   │   └── .gitkeep
│   │   │   │   ├── controls-search/
│   │   │   │   │   ├── button-reset.tsx
│   │   │   │   │   ├── command-region.tsx
│   │   │   │   │   ├── command-tags.tsx
│   │   │   │   │   ├── dropdown-interval.tsx
│   │   │   │   │   ├── dropdown-percentile.tsx
│   │   │   │   │   ├── dropdown-period.tsx
│   │   │   │   │   ├── dropdown-status.tsx
│   │   │   │   │   ├── dropdown-trigger.tsx
│   │   │   │   │   └── popover-date.tsx
│   │   │   │   ├── data-table/
│   │   │   │   │   ├── audit-logs/
│   │   │   │   │   │   ├── columns.tsx
│   │   │   │   │   │   └── wrapper.tsx
│   │   │   │   │   ├── billing/
│   │   │   │   │   │   └── data-table.tsx
│   │   │   │   │   ├── dable-cell-skeleton.tsx
│   │   │   │   │   ├── data-table-sheet.tsx
│   │   │   │   │   ├── incidents/
│   │   │   │   │   │   ├── columns.tsx
│   │   │   │   │   │   └── data-table-row-actions.tsx
│   │   │   │   │   ├── maintenances/
│   │   │   │   │   │   ├── columns.tsx
│   │   │   │   │   │   └── data-table-row-actions.tsx
│   │   │   │   │   ├── monitors/
│   │   │   │   │   │   ├── columns.tsx
│   │   │   │   │   │   ├── data-table-action-bar.tsx
│   │   │   │   │   │   ├── data-table-row-actions.tsx
│   │   │   │   │   │   └── data-table-toolbar.tsx
│   │   │   │   │   ├── notifications/
│   │   │   │   │   │   ├── columns.tsx
│   │   │   │   │   │   └── data-table-row-actions.tsx
│   │   │   │   │   ├── page-components/
│   │   │   │   │   │   ├── columns.tsx
│   │   │   │   │   │   └── data-table-row-actions.tsx
│   │   │   │   │   ├── private-locations/
│   │   │   │   │   │   ├── columns.tsx
│   │   │   │   │   │   └── data-table-row-actions.tsx
│   │   │   │   │   ├── response-logs/
│   │   │   │   │   │   ├── columns.tsx
│   │   │   │   │   │   ├── data-table-basics.tsx
│   │   │   │   │   │   ├── data-table-sheet-test.tsx
│   │   │   │   │   │   ├── data-table-sheet.tsx
│   │   │   │   │   │   ├── data-table-toolbar.tsx
│   │   │   │   │   │   └── regions/
│   │   │   │   │   │       └── columns.tsx
│   │   │   │   │   ├── settings/
│   │   │   │   │   │   ├── api-key/
│   │   │   │   │   │   │   └── data-table.tsx
│   │   │   │   │   │   ├── invitations/
│   │   │   │   │   │   │   └── data-table.tsx
│   │   │   │   │   │   └── members/
│   │   │   │   │   │       └── data-table.tsx
│   │   │   │   │   ├── status-pages/
│   │   │   │   │   │   ├── columns.tsx
│   │   │   │   │   │   └── data-table-row-actions.tsx
│   │   │   │   │   ├── status-report-updates/
│   │   │   │   │   │   ├── data-table-row-actions.tsx
│   │   │   │   │   │   └── data-table.tsx
│   │   │   │   │   ├── status-reports/
│   │   │   │   │   │   ├── columns.tsx
│   │   │   │   │   │   └── data-table-row-actions.tsx
│   │   │   │   │   ├── subscribers/
│   │   │   │   │   │   ├── columns.tsx
│   │   │   │   │   │   └── data-table-row-actions.tsx
│   │   │   │   │   ├── table-cell-badge.tsx
│   │   │   │   │   ├── table-cell-boolean.tsx
│   │   │   │   │   ├── table-cell-date.tsx
│   │   │   │   │   ├── table-cell-link.tsx
│   │   │   │   │   ├── table-cell-number.tsx
│   │   │   │   │   └── table-cell-unavailable.tsx
│   │   │   │   ├── date-picker.tsx
│   │   │   │   ├── development-indicator.tsx
│   │   │   │   ├── dialogs/
│   │   │   │   │   ├── export-code.tsx
│   │   │   │   │   └── upgrade.tsx
│   │   │   │   ├── domains/
│   │   │   │   │   ├── domain-configuration.tsx
│   │   │   │   │   ├── domain-status-icon.tsx
│   │   │   │   │   └── use-domain-status.ts
│   │   │   │   ├── dropdowns/
│   │   │   │   │   └── quick-actions.tsx
│   │   │   │   ├── forms/
│   │   │   │   │   ├── components/
│   │   │   │   │   │   ├── form-components.tsx
│   │   │   │   │   │   ├── form-import.tsx
│   │   │   │   │   │   ├── telegram-connection-flow.tsx
│   │   │   │   │   │   ├── telegram-form-actions.tsx
│   │   │   │   │   │   ├── telegram-manual-input.tsx
│   │   │   │   │   │   ├── telegram-qr-connection.tsx
│   │   │   │   │   │   ├── telegram-qrcode.tsx
│   │   │   │   │   │   └── update.tsx
│   │   │   │   │   ├── form-alert-dialog.tsx
│   │   │   │   │   ├── form-card.tsx
│   │   │   │   │   ├── form-sheet.tsx
│   │   │   │   │   ├── maintenance/
│   │   │   │   │   │   ├── form.tsx
│   │   │   │   │   │   └── sheet.tsx
│   │   │   │   │   ├── monitor/
│   │   │   │   │   │   ├── form-danger-zone.tsx
│   │   │   │   │   │   ├── form-follow-redirect.tsx
│   │   │   │   │   │   ├── form-general.tsx
│   │   │   │   │   │   ├── form-notifiers.tsx
│   │   │   │   │   │   ├── form-otel.tsx
│   │   │   │   │   │   ├── form-response-time.tsx
│   │   │   │   │   │   ├── form-retry.tsx
│   │   │   │   │   │   ├── form-scheduling-regions.tsx
│   │   │   │   │   │   ├── form-status-pages.tsx
│   │   │   │   │   │   ├── form-tags.tsx
│   │   │   │   │   │   ├── form-visibility.tsx
│   │   │   │   │   │   └── update.tsx
│   │   │   │   │   ├── monitor-tag/
│   │   │   │   │   │   ├── form-monitor-tag.tsx
│   │   │   │   │   │   └── sheet.tsx
│   │   │   │   │   ├── notifications/
│   │   │   │   │   │   ├── form-discord.tsx
│   │   │   │   │   │   ├── form-email.tsx
│   │   │   │   │   │   ├── form-google-chat.tsx
│   │   │   │   │   │   ├── form-grafana-oncall.tsx
│   │   │   │   │   │   ├── form-ntfy.tsx
│   │   │   │   │   │   ├── form-opsgenie.tsx
│   │   │   │   │   │   ├── form-pagerduty.tsx
│   │   │   │   │   │   ├── form-slack.tsx
│   │   │   │   │   │   ├── form-sms.tsx
│   │   │   │   │   │   ├── form-telegram.tsx
│   │   │   │   │   │   ├── form-webhook.tsx
│   │   │   │   │   │   ├── form-whatsapp.tsx
│   │   │   │   │   │   ├── form.tsx
│   │   │   │   │   │   └── sheet.tsx
│   │   │   │   │   ├── onboarding/
│   │   │   │   │   │   ├── create-monitor.tsx
│   │   │   │   │   │   ├── create-page.tsx
│   │   │   │   │   │   └── learn-from.tsx
│   │   │   │   │   ├── private-location/
│   │   │   │   │   │   ├── form.tsx
│   │   │   │   │   │   └── sheet.tsx
│   │   │   │   │   ├── settings/
│   │   │   │   │   │   ├── form-api-key.tsx
│   │   │   │   │   │   ├── form-members.tsx
│   │   │   │   │   │   ├── form-slug.tsx
│   │   │   │   │   │   └── form-workspace.tsx
│   │   │   │   │   ├── status-page/
│   │   │   │   │   │   ├── form-appearance.tsx
│   │   │   │   │   │   ├── form-configuration.tsx
│   │   │   │   │   │   ├── form-custom-domain.tsx
│   │   │   │   │   │   ├── form-danger-zone.tsx
│   │   │   │   │   │   ├── form-general.tsx
│   │   │   │   │   │   ├── form-links.tsx
│   │   │   │   │   │   ├── form-monitors.tsx
│   │   │   │   │   │   ├── form-page-access.tsx
│   │   │   │   │   │   └── update.tsx
│   │   │   │   │   ├── status-report/
│   │   │   │   │   │   ├── form.tsx
│   │   │   │   │   │   └── sheet.tsx
│   │   │   │   │   ├── status-report-update/
│   │   │   │   │   │   ├── form-status-report.tsx
│   │   │   │   │   │   ├── form.tsx
│   │   │   │   │   │   └── sheet.tsx
│   │   │   │   │   └── support-contact/
│   │   │   │   │       ├── dialog.tsx
│   │   │   │   │       └── form.tsx
│   │   │   │   ├── layout/
│   │   │   │   │   └── auth-layout.tsx
│   │   │   │   ├── metric/
│   │   │   │   │   ├── global-uptime/
│   │   │   │   │   │   └── section.tsx
│   │   │   │   │   └── metric-card.tsx
│   │   │   │   ├── nav/
│   │   │   │   │   ├── app-header.tsx
│   │   │   │   │   ├── app-sidebar.tsx
│   │   │   │   │   ├── nav-banner-checklist.tsx
│   │   │   │   │   ├── nav-banner-upgrade.tsx
│   │   │   │   │   ├── nav-banner.tsx
│   │   │   │   │   ├── nav-breadcrumb.tsx
│   │   │   │   │   ├── nav-feedback.tsx
│   │   │   │   │   ├── nav-help.tsx
│   │   │   │   │   ├── nav-main.tsx
│   │   │   │   │   ├── nav-monitors.tsx
│   │   │   │   │   ├── nav-overview.tsx
│   │   │   │   │   ├── nav-status-pages.tsx
│   │   │   │   │   ├── nav-tabs.tsx
│   │   │   │   │   ├── nav-user.tsx
│   │   │   │   │   ├── sidebar-metadata.tsx
│   │   │   │   │   ├── sidebar-right.tsx
│   │   │   │   │   └── workspace-switcher.tsx
│   │   │   │   ├── popovers/
│   │   │   │   │   ├── popover-quantile.tsx
│   │   │   │   │   └── popover-resolution.tsx
│   │   │   │   ├── tailwind-indicator.tsx
│   │   │   │   ├── theme-provider.tsx
│   │   │   │   ├── theme-toggle.tsx
│   │   │   │   └── ui/
│   │   │   │       ├── data-table/
│   │   │   │       │   ├── data-table-action-bar.tsx
│   │   │   │       │   ├── data-table-column-header.tsx
│   │   │   │       │   ├── data-table-faceted-filter.tsx
│   │   │   │       │   ├── data-table-pagination.tsx
│   │   │   │       │   ├── data-table-skeleton.tsx
│   │   │   │       │   ├── data-table-toobar.tsx
│   │   │   │       │   ├── data-table-view-options.tsx
│   │   │   │       │   └── data-table.tsx
│   │   │   │       └── sortable.tsx
│   │   │   ├── data/
│   │   │   │   ├── audit-logs.client.ts
│   │   │   │   ├── audit-logs.ts
│   │   │   │   ├── icons.ts
│   │   │   │   ├── incidents.client.ts
│   │   │   │   ├── incidents.ts
│   │   │   │   ├── invitations.ts
│   │   │   │   ├── maintenances.client.ts
│   │   │   │   ├── maintenances.ts
│   │   │   │   ├── members.ts
│   │   │   │   ├── metrics.client.ts
│   │   │   │   ├── monitor-tags.ts
│   │   │   │   ├── monitors.client.ts
│   │   │   │   ├── monitors.ts
│   │   │   │   ├── notifications.client.ts
│   │   │   │   ├── notifications.ts
│   │   │   │   ├── page-components.client.ts
│   │   │   │   ├── plans.ts
│   │   │   │   ├── region-metrics.client.ts
│   │   │   │   ├── region-metrics.ts
│   │   │   │   ├── regions.ts
│   │   │   │   ├── response-logs.ts
│   │   │   │   ├── status-codes.ts
│   │   │   │   ├── status-pages.client.ts
│   │   │   │   ├── status-pages.ts
│   │   │   │   ├── status-report-updates.client.ts
│   │   │   │   ├── status-reports.client.ts
│   │   │   │   ├── status-reports.ts
│   │   │   │   └── subscribers.ts
│   │   │   ├── hooks/
│   │   │   │   ├── use-feature.ts
│   │   │   │   └── use-telegram-connection.ts
│   │   │   ├── instrumentation.ts
│   │   │   ├── lib/
│   │   │   │   ├── auth/
│   │   │   │   │   ├── adapter.ts
│   │   │   │   │   ├── helpers.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── providers.ts
│   │   │   │   ├── composition.ts
│   │   │   │   ├── domains.ts
│   │   │   │   ├── formatter.ts
│   │   │   │   ├── middleware/
│   │   │   │   │   └── with-invitation.ts
│   │   │   │   ├── stripe.ts
│   │   │   │   ├── trpc/
│   │   │   │   │   ├── client.tsx
│   │   │   │   │   ├── query-client.ts
│   │   │   │   │   ├── server.tsx
│   │   │   │   │   └── shared.ts
│   │   │   │   └── utils.ts
│   │   │   ├── next-auth.d.ts
│   │   │   ├── proxy.ts
│   │   │   └── scripts/
│   │   │       ├── README.md
│   │   │       └── export-blog-post-metrics.ts
│   │   └── tsconfig.json
│   ├── docs/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── astro.config.mjs
│   │   ├── package.json
│   │   ├── public/
│   │   │   ├── fonts/
│   │   │   │   ├── CommitMono-400-Italic.otf
│   │   │   │   ├── CommitMono-400-Regular.otf
│   │   │   │   ├── CommitMono-700-Italic.otf
│   │   │   │   └── CommitMono-700-Regular.otf
│   │   │   └── robots.txt
│   │   ├── src/
│   │   │   ├── components/
│   │   │   │   ├── Footer.astro
│   │   │   │   ├── Head.astro
│   │   │   │   ├── Hero.astro
│   │   │   │   ├── SiteTitle.astro
│   │   │   │   ├── Status.astro
│   │   │   │   └── utils.ts
│   │   │   ├── content/
│   │   │   │   ├── config.ts
│   │   │   │   └── docs/
│   │   │   │       ├── 404.md
│   │   │   │       ├── concept/
│   │   │   │       │   ├── best-practices-status-page.mdx
│   │   │   │       │   ├── getting-started.mdx
│   │   │   │       │   ├── latency-vs-response-time.mdx
│   │   │   │       │   ├── uptime-calculation-and-values.mdx
│   │   │   │       │   ├── uptime-monitoring-as-code.mdx
│   │   │   │       │   └── uptime-monitoring.mdx
│   │   │   │       ├── guides/
│   │   │   │       │   ├── getting-started.mdx
│   │   │   │       │   ├── how-deploy-status-page-cf-pages.mdx
│   │   │   │       │   ├── how-to-add-svg-status-badge.mdx
│   │   │   │       │   ├── how-to-deploy-probes-cloudflare-containers.mdx
│   │   │   │       │   ├── how-to-export-metrics-to-otlp-endpoint.mdx
│   │   │   │       │   ├── how-to-monitor-mcp-server.mdx
│   │   │   │       │   ├── how-to-run-synthetic-test-github-action.mdx
│   │   │   │       │   ├── how-to-use-react-widget.mdx
│   │   │   │       │   ├── self-host-status-page-only.mdx
│   │   │   │       │   └── self-hosting-openstatus.mdx
│   │   │   │       ├── help/
│   │   │   │       │   └── support.mdx
│   │   │   │       ├── index.mdx
│   │   │   │       ├── monitoring/
│   │   │   │       │   └── overview.mdx
│   │   │   │       ├── reference/
│   │   │   │       │   ├── cli-reference.mdx
│   │   │   │       │   ├── dns-monitor.mdx
│   │   │   │       │   ├── http-monitor.mdx
│   │   │   │       │   ├── incident.mdx
│   │   │   │       │   ├── location.mdx
│   │   │   │       │   ├── notification.mdx
│   │   │   │       │   ├── page-components.mdx
│   │   │   │       │   ├── private-location.mdx
│   │   │   │       │   ├── status-page.mdx
│   │   │   │       │   ├── status-report.mdx
│   │   │   │       │   ├── subscriber.mdx
│   │   │   │       │   ├── tcp-monitor.mdx
│   │   │   │       │   └── terraform.mdx
│   │   │   │       ├── reference.mdx
│   │   │   │       ├── sdk/
│   │   │   │       │   └── nodejs/
│   │   │   │       │       ├── authentication.mdx
│   │   │   │       │       ├── error-handling.mdx
│   │   │   │       │       ├── getting-started.mdx
│   │   │   │       │       ├── health-service.mdx
│   │   │   │       │       ├── index.mdx
│   │   │   │       │       ├── maintenance-service.mdx
│   │   │   │       │       ├── monitor-service.mdx
│   │   │   │       │       ├── notification-service.mdx
│   │   │   │       │       ├── reference.mdx
│   │   │   │       │       ├── status-page-service.mdx
│   │   │   │       │       ├── status-report-service.mdx
│   │   │   │       │       └── typescript-tips.mdx
│   │   │   │       └── tutorial/
│   │   │   │           ├── get-started-with-openstatus-cli.mdx
│   │   │   │           ├── getting-started.mdx
│   │   │   │           ├── how-to-configure-status-page.mdx
│   │   │   │           ├── how-to-create-monitor.mdx
│   │   │   │           ├── how-to-create-private-location.mdx
│   │   │   │           ├── how-to-create-status-page.mdx
│   │   │   │           └── how-to-setup-slack-agent.mdx
│   │   │   ├── custom.css
│   │   │   ├── env.d.ts
│   │   │   └── global.css
│   │   └── tsconfig.json
│   ├── private-location/
│   │   ├── .air.toml
│   │   ├── .dockerignore
│   │   ├── .gitignore
│   │   ├── .golangci.yml
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── cmd/
│   │   │   └── server/
│   │   │       └── main.go
│   │   ├── dofigen.yml
│   │   ├── fly.toml
│   │   ├── go.mod
│   │   ├── go.sum
│   │   ├── internal/
│   │   │   ├── database/
│   │   │   │   ├── database.go
│   │   │   │   └── models.go
│   │   │   ├── logs/
│   │   │   │   ├── logs.go
│   │   │   │   └── logs_test.go
│   │   │   ├── models/
│   │   │   │   └── assertions.go
│   │   │   ├── server/
│   │   │   │   ├── db_testdata
│   │   │   │   ├── errors.go
│   │   │   │   ├── ingest_common.go
│   │   │   │   ├── ingest_dns.go
│   │   │   │   ├── ingest_dns_test.go
│   │   │   │   ├── ingest_http.go
│   │   │   │   ├── ingest_http_test.go
│   │   │   │   ├── ingest_tcp.go
│   │   │   │   ├── ingest_tcp_test.go
│   │   │   │   ├── monitors.go
│   │   │   │   ├── monitors_test.go
│   │   │   │   ├── routes.go
│   │   │   │   ├── server.go
│   │   │   │   ├── validation.go
│   │   │   │   └── validation_test.go
│   │   │   └── tinybird/
│   │   │       ├── client.go
│   │   │       └── client_test.go
│   │   ├── justfile
│   │   └── proto/
│   │       └── private_location/
│   │           └── v1/
│   │               ├── assertions.pb.go
│   │               ├── dns_monitor.pb.go
│   │               ├── http_monitor.pb.go
│   │               ├── private_location.connect.go
│   │               ├── private_location.pb.go
│   │               └── tcp_monitor.pb.go
│   ├── railway-proxy/
│   │   ├── Dockerfile
│   │   ├── go.mod
│   │   ├── go.sum
│   │   └── main.go
│   ├── screenshot-service/
│   │   ├── .dockerignore
│   │   ├── .gitignore
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── fly.toml
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── env.ts
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   ├── server/
│   │   ├── .dockerignore
│   │   ├── .gitignore
│   │   ├── CONNECTRPC_SPEC.md
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── bunfig.toml
│   │   ├── docker-compose.yaml
│   │   ├── dofigen.yml
│   │   ├── env.ts
│   │   ├── fly.sh
│   │   ├── fly.toml
│   │   ├── log/
│   │   │   └── fly.toml
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── env.ts
│   │   │   ├── index.ts
│   │   │   ├── libs/
│   │   │   │   ├── checker/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── clients.ts
│   │   │   │   ├── errors/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── openapi-error-responses.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── middlewares/
│   │   │   │   │   ├── auth.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── plan.ts
│   │   │   │   │   └── track.ts
│   │   │   │   └── test/
│   │   │   │       └── preload.ts
│   │   │   ├── routes/
│   │   │   │   ├── public/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── status.test.ts
│   │   │   │   │   ├── status.ts
│   │   │   │   │   └── unsubscribe.ts
│   │   │   │   ├── rpc/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── interceptors/
│   │   │   │   │   │   ├── auth.ts
│   │   │   │   │   │   ├── error.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── logging.ts
│   │   │   │   │   │   └── validation.ts
│   │   │   │   │   ├── router.ts
│   │   │   │   │   └── services/
│   │   │   │   │       ├── health/
│   │   │   │   │       │   └── index.ts
│   │   │   │   │       ├── maintenance/
│   │   │   │   │       │   ├── __tests__/
│   │   │   │   │       │   │   └── maintenance.test.ts
│   │   │   │   │       │   ├── converters.ts
│   │   │   │   │       │   ├── errors.ts
│   │   │   │   │       │   └── index.ts
│   │   │   │   │       ├── monitor/
│   │   │   │   │       │   ├── __tests__/
│   │   │   │   │       │   │   └── monitor.test.ts
│   │   │   │   │       │   ├── converters/
│   │   │   │   │       │   │   ├── assertions.ts
│   │   │   │   │       │   │   ├── comparators.ts
│   │   │   │   │       │   │   ├── defaults.ts
│   │   │   │   │       │   │   ├── enums.ts
│   │   │   │   │       │   │   ├── headers.ts
│   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │       │   │   ├── monitors.ts
│   │   │   │   │       │   │   └── regions.ts
│   │   │   │   │       │   ├── errors.ts
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── limits.ts
│   │   │   │   │       │   └── validators.ts
│   │   │   │   │       ├── notification/
│   │   │   │   │       │   ├── __tests__/
│   │   │   │   │       │   │   └── notification.test.ts
│   │   │   │   │       │   ├── converters.ts
│   │   │   │   │       │   ├── errors.ts
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── limits.ts
│   │   │   │   │       │   └── test-providers.ts
│   │   │   │   │       ├── status-page/
│   │   │   │   │       │   ├── __tests__/
│   │   │   │   │       │   │   └── status-page.test.ts
│   │   │   │   │       │   ├── converters.ts
│   │   │   │   │       │   ├── errors.ts
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   └── limits.ts
│   │   │   │   │       └── status-report/
│   │   │   │   │           ├── __tests__/
│   │   │   │   │           │   └── status-report.test.ts
│   │   │   │   │           ├── converters.ts
│   │   │   │   │           ├── errors.ts
│   │   │   │   │           └── index.ts
│   │   │   │   ├── slack/
│   │   │   │   │   ├── agent.test.ts
│   │   │   │   │   ├── agent.ts
│   │   │   │   │   ├── blocks.test.ts
│   │   │   │   │   ├── blocks.ts
│   │   │   │   │   ├── confirmation-store.test.ts
│   │   │   │   │   ├── confirmation-store.ts
│   │   │   │   │   ├── handler.test.ts
│   │   │   │   │   ├── handler.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── interactions.test.ts
│   │   │   │   │   ├── interactions.ts
│   │   │   │   │   ├── oauth.test.ts
│   │   │   │   │   ├── oauth.ts
│   │   │   │   │   ├── tools/
│   │   │   │   │   │   ├── add-status-report-update.ts
│   │   │   │   │   │   ├── create-maintenance.ts
│   │   │   │   │   │   ├── create-status-report.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── list-maintenances.ts
│   │   │   │   │   │   ├── list-status-pages.ts
│   │   │   │   │   │   ├── list-status-reports.ts
│   │   │   │   │   │   ├── resolve-status-report.ts
│   │   │   │   │   │   ├── tools.test.ts
│   │   │   │   │   │   └── update-status-report.ts
│   │   │   │   │   ├── verify.test.ts
│   │   │   │   │   ├── verify.ts
│   │   │   │   │   └── workspace-resolver.ts
│   │   │   │   └── v1/
│   │   │   │       ├── check/
│   │   │   │       │   ├── http/
│   │   │   │       │   │   ├── post.test.ts
│   │   │   │       │   │   ├── post.ts
│   │   │   │       │   │   └── schema.ts
│   │   │   │       │   └── index.ts
│   │   │   │       ├── incidents/
│   │   │   │       │   ├── get.test.ts
│   │   │   │       │   ├── get.ts
│   │   │   │       │   ├── get_all.test.ts
│   │   │   │       │   ├── get_all.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── put.test.ts
│   │   │   │       │   ├── put.ts
│   │   │   │       │   └── schema.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── maintenances/
│   │   │   │       │   ├── get.test.ts
│   │   │   │       │   ├── get.ts
│   │   │   │       │   ├── get_all.test.ts
│   │   │   │       │   ├── get_all.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── post.test.ts
│   │   │   │       │   ├── post.ts
│   │   │   │       │   ├── put.test.ts
│   │   │   │       │   ├── put.ts
│   │   │   │       │   └── schema.ts
│   │   │   │       ├── monitors/
│   │   │   │       │   ├── delete.test.ts
│   │   │   │       │   ├── delete.ts
│   │   │   │       │   ├── get.test.ts
│   │   │   │       │   ├── get.ts
│   │   │   │       │   ├── get_all.test.ts
│   │   │   │       │   ├── get_all.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── post.test.ts
│   │   │   │       │   ├── post.ts
│   │   │   │       │   ├── post_dns.test.ts
│   │   │   │       │   ├── post_dns.ts
│   │   │   │       │   ├── post_http.test.ts
│   │   │   │       │   ├── post_http.ts
│   │   │   │       │   ├── post_tcp.test.ts
│   │   │   │       │   ├── post_tcp.ts
│   │   │   │       │   ├── put.test.ts
│   │   │   │       │   ├── put.ts
│   │   │   │       │   ├── put_dns.test.ts
│   │   │   │       │   ├── put_dns.ts
│   │   │   │       │   ├── put_http.test.ts
│   │   │   │       │   ├── put_http.ts
│   │   │   │       │   ├── put_tcp.test.ts
│   │   │   │       │   ├── put_tcp.ts
│   │   │   │       │   ├── results/
│   │   │   │       │   │   ├── get.test.ts
│   │   │   │       │   │   └── get.ts
│   │   │   │       │   ├── run/
│   │   │   │       │   │   ├── post.test.ts
│   │   │   │       │   │   ├── post.ts
│   │   │   │       │   │   └── schema.ts
│   │   │   │       │   ├── schema.ts
│   │   │   │       │   ├── summary/
│   │   │   │       │   │   ├── get.test.ts
│   │   │   │       │   │   ├── get.ts
│   │   │   │       │   │   └── schema.ts
│   │   │   │       │   ├── trigger/
│   │   │   │       │   │   ├── post.test.ts
│   │   │   │       │   │   ├── post.ts
│   │   │   │       │   │   └── schema.ts
│   │   │   │       │   └── utils.ts
│   │   │   │       ├── notifications/
│   │   │   │       │   ├── get.test.ts
│   │   │   │       │   ├── get.ts
│   │   │   │       │   ├── get_all.test.ts
│   │   │   │       │   ├── get_all.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── post.test.ts
│   │   │   │       │   ├── post.ts
│   │   │   │       │   └── schema.ts
│   │   │   │       ├── pageSubscribers/
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── post.test.ts
│   │   │   │       │   ├── post.ts
│   │   │   │       │   └── schema.ts
│   │   │   │       ├── pages/
│   │   │   │       │   ├── get.test.ts
│   │   │   │       │   ├── get.ts
│   │   │   │       │   ├── get_all.test.ts
│   │   │   │       │   ├── get_all.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── post.test.ts
│   │   │   │       │   ├── post.ts
│   │   │   │       │   ├── put.test.ts
│   │   │   │       │   ├── put.ts
│   │   │   │       │   └── schema.ts
│   │   │   │       ├── statusReportUpdates/
│   │   │   │       │   ├── get.test.ts
│   │   │   │       │   ├── get.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── post.test.ts
│   │   │   │       │   ├── post.ts
│   │   │   │       │   └── schema.ts
│   │   │   │       ├── statusReports/
│   │   │   │       │   ├── delete.test.ts
│   │   │   │       │   ├── delete.ts
│   │   │   │       │   ├── get.test.ts
│   │   │   │       │   ├── get.ts
│   │   │   │       │   ├── get_all.test.ts
│   │   │   │       │   ├── get_all.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── post.test.ts
│   │   │   │       │   ├── post.ts
│   │   │   │       │   ├── schema.ts
│   │   │   │       │   ├── subscriber-filtering.integration.test.ts
│   │   │   │       │   └── update/
│   │   │   │       │       ├── post.test.ts
│   │   │   │       │       └── post.ts
│   │   │   │       ├── utils.ts
│   │   │   │       └── whoami/
│   │   │   │           ├── get.test.ts
│   │   │   │           ├── get.ts
│   │   │   │           ├── index.ts
│   │   │   │           └── schema.ts
│   │   │   ├── types/
│   │   │   │   └── index.ts
│   │   │   └── utils/
│   │   │       ├── audit-log.ts
│   │   │       ├── not-empty.ts
│   │   │       ├── page-component.ts
│   │   │       └── random-promise.ts
│   │   ├── static/
│   │   │   ├── openapi-v1.json
│   │   │   └── openapi.yaml
│   │   └── tsconfig.json
│   ├── ssh-server/
│   │   ├── .dockerignore
│   │   ├── .gitignore
│   │   ├── Dockerfile
│   │   ├── banner.txt
│   │   ├── fly.toml
│   │   ├── go.mod
│   │   ├── go.sum
│   │   └── main.go
│   ├── status-page/
│   │   ├── .dockerignore
│   │   ├── .gitignore
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── components.json
│   │   ├── docker-compose.yaml
│   │   ├── dofigen.yml
│   │   ├── env.ts
│   │   ├── instrumentation-client.ts
│   │   ├── next-env.d.ts
│   │   ├── next.config.ts
│   │   ├── package.json
│   │   ├── postcss.config.mjs
│   │   ├── public/
│   │   │   └── fonts/
│   │   │       ├── CommitMono-400-Italic.otf
│   │   │       ├── CommitMono-400-Regular.otf
│   │   │       ├── CommitMono-700-Italic.otf
│   │   │       └── CommitMono-700-Regular.otf
│   │   ├── sentry.edge.config.ts
│   │   ├── sentry.server.config.ts
│   │   ├── src/
│   │   │   ├── app/
│   │   │   │   ├── (public)/
│   │   │   │   │   ├── client.tsx
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   ├── page.tsx
│   │   │   │   │   └── search-params.ts
│   │   │   │   ├── (status-page)/
│   │   │   │   │   └── [domain]/
│   │   │   │   │       ├── (auth)/
│   │   │   │   │       │   ├── layout.tsx
│   │   │   │   │       │   └── login/
│   │   │   │   │       │       ├── _components/
│   │   │   │   │       │       │   ├── section-magic-link.tsx
│   │   │   │   │       │       │   └── section-password.tsx
│   │   │   │   │       │       ├── actions.ts
│   │   │   │   │       │       └── page.tsx
│   │   │   │   │       ├── (public)/
│   │   │   │   │       │   ├── badge/
│   │   │   │   │       │   │   ├── route.tsx
│   │   │   │   │       │   │   └── v2/
│   │   │   │   │       │   │       └── route.ts
│   │   │   │   │       │   ├── events/
│   │   │   │   │       │   │   ├── (list)/
│   │   │   │   │       │   │   │   ├── page.tsx
│   │   │   │   │       │   │   │   └── search-params.ts
│   │   │   │   │       │   │   ├── (view)/
│   │   │   │   │       │   │   │   ├── maintenance/
│   │   │   │   │       │   │   │   │   └── [id]/
│   │   │   │   │       │   │   │   │       ├── layout.tsx
│   │   │   │   │       │   │   │   │       └── page.tsx
│   │   │   │   │       │   │   │   └── report/
│   │   │   │   │       │   │   │       └── [id]/
│   │   │   │   │       │   │   │           ├── layout.tsx
│   │   │   │   │       │   │   │           └── page.tsx
│   │   │   │   │       │   │   └── layout.tsx
│   │   │   │   │       │   ├── feed/
│   │   │   │   │       │   │   ├── [type]/
│   │   │   │   │       │   │   │   └── route.ts
│   │   │   │   │       │   │   └── json/
│   │   │   │   │       │   │       └── route.ts
│   │   │   │   │       │   ├── layout.tsx
│   │   │   │   │       │   ├── manage/
│   │   │   │   │       │   │   ├── [token]/
│   │   │   │   │       │   │   │   ├── layout.tsx
│   │   │   │   │       │   │   │   └── page.tsx
│   │   │   │   │       │   │   └── layout.tsx
│   │   │   │   │       │   ├── monitors/
│   │   │   │   │       │   │   ├── [id]/
│   │   │   │   │       │   │   │   ├── page.tsx
│   │   │   │   │       │   │   │   └── search-params.ts
│   │   │   │   │       │   │   └── page.tsx
│   │   │   │   │       │   ├── page.tsx
│   │   │   │   │       │   ├── unsubscribe/
│   │   │   │   │       │   │   └── [token]/
│   │   │   │   │       │   │       ├── layout.tsx
│   │   │   │   │       │   │       └── page.tsx
│   │   │   │   │       │   └── verify/
│   │   │   │   │       │       └── [token]/
│   │   │   │   │       │           ├── layout.tsx
│   │   │   │   │       │           └── page.tsx
│   │   │   │   │       └── layout.tsx
│   │   │   │   ├── api/
│   │   │   │   │   ├── auth/
│   │   │   │   │   │   └── [...nextauth]/
│   │   │   │   │   │       └── route.ts
│   │   │   │   │   └── trpc/
│   │   │   │   │       ├── edge/
│   │   │   │   │       │   └── [trpc]/
│   │   │   │   │       │       └── route.ts
│   │   │   │   │       └── lambda/
│   │   │   │   │           └── [trpc]/
│   │   │   │   │               └── route.ts
│   │   │   │   ├── global-error.tsx
│   │   │   │   ├── globals.css
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── metadata.ts
│   │   │   │   ├── not-found.tsx
│   │   │   │   └── react-table.d.ts
│   │   │   ├── components/
│   │   │   │   ├── button/
│   │   │   │   │   ├── button-back.tsx
│   │   │   │   │   └── button-copy-link.tsx
│   │   │   │   ├── chart/
│   │   │   │   │   ├── chart-area-percentiles.tsx
│   │   │   │   │   ├── chart-bar-uptime.tsx
│   │   │   │   │   ├── chart-legend-badge.tsx
│   │   │   │   │   ├── chart-line-region.tsx
│   │   │   │   │   ├── chart-line-regions.tsx
│   │   │   │   │   └── chart-tooltip-number.tsx
│   │   │   │   ├── common/
│   │   │   │   │   ├── kbd.tsx
│   │   │   │   │   └── link.tsx
│   │   │   │   ├── content/
│   │   │   │   │   ├── empty-state.tsx
│   │   │   │   │   ├── metric-card.tsx
│   │   │   │   │   ├── process-message.tsx
│   │   │   │   │   ├── section.tsx
│   │   │   │   │   └── timestamp-hover-card.tsx
│   │   │   │   ├── date-picker.tsx
│   │   │   │   ├── forms/
│   │   │   │   │   ├── form-card.tsx
│   │   │   │   │   ├── form-email.tsx
│   │   │   │   │   ├── form-manage-subscription.tsx
│   │   │   │   │   ├── form-password.tsx
│   │   │   │   │   └── form-subscribe-email.tsx
│   │   │   │   ├── icons/
│   │   │   │   │   ├── discord.tsx
│   │   │   │   │   ├── github.tsx
│   │   │   │   │   ├── google.tsx
│   │   │   │   │   ├── opsgenie.tsx
│   │   │   │   │   ├── pagerduty.tsx
│   │   │   │   │   └── slack.tsx
│   │   │   │   ├── nav/
│   │   │   │   │   ├── footer.tsx
│   │   │   │   │   └── header.tsx
│   │   │   │   ├── password-wrapper.tsx
│   │   │   │   ├── popover/
│   │   │   │   │   └── popover-quantile.tsx
│   │   │   │   ├── status-page/
│   │   │   │   │   ├── floating-button.tsx
│   │   │   │   │   ├── floating-theme.tsx
│   │   │   │   │   ├── messages.ts
│   │   │   │   │   ├── status-banner.tsx
│   │   │   │   │   ├── status-blank.tsx
│   │   │   │   │   ├── status-charts.tsx
│   │   │   │   │   ├── status-events.tsx
│   │   │   │   │   ├── status-feed.tsx
│   │   │   │   │   ├── status-monitor-tabs.tsx
│   │   │   │   │   ├── status-monitor.tsx
│   │   │   │   │   ├── status-tracker-group.tsx
│   │   │   │   │   ├── status-tracker.tsx
│   │   │   │   │   ├── status-updates.tsx
│   │   │   │   │   ├── status.tsx
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── tailwind-indicator.tsx
│   │   │   │   ├── themes/
│   │   │   │   │   ├── theme-dropdown.tsx
│   │   │   │   │   ├── theme-palette-picker.tsx
│   │   │   │   │   ├── theme-provider.tsx
│   │   │   │   │   ├── theme-select.tsx
│   │   │   │   │   └── theme-sidebar.tsx
│   │   │   │   └── ui/
│   │   │   │       └── data-table/
│   │   │   │           ├── data-table-action-bar.tsx
│   │   │   │           ├── data-table-column-header.tsx
│   │   │   │           ├── data-table-faceted-filter.tsx
│   │   │   │           ├── data-table-pagination.tsx
│   │   │   │           ├── data-table-skeleton.tsx
│   │   │   │           ├── data-table-toobar.tsx
│   │   │   │           ├── data-table-view-options.tsx
│   │   │   │           └── data-table.tsx
│   │   │   ├── data/
│   │   │   │   ├── icons.ts
│   │   │   │   ├── incidents.client.ts
│   │   │   │   ├── incidents.ts
│   │   │   │   ├── invitations.ts
│   │   │   │   ├── maintenances.client.ts
│   │   │   │   ├── maintenances.ts
│   │   │   │   ├── members.ts
│   │   │   │   ├── metrics.client.ts
│   │   │   │   ├── monitor-tags.ts
│   │   │   │   ├── monitors.client.ts
│   │   │   │   ├── monitors.ts
│   │   │   │   ├── plans.ts
│   │   │   │   ├── region-metrics.client.ts
│   │   │   │   ├── region-metrics.ts
│   │   │   │   ├── region-percentile.ts
│   │   │   │   ├── regions.ts
│   │   │   │   ├── response-logs.ts
│   │   │   │   ├── status-codes.ts
│   │   │   │   ├── status-pages.client.ts
│   │   │   │   ├── status-pages.ts
│   │   │   │   ├── status-report-updates.client.ts
│   │   │   │   ├── status-reports.client.ts
│   │   │   │   └── status-reports.ts
│   │   │   ├── hooks/
│   │   │   │   └── use-pathname-prefix.ts
│   │   │   ├── instrumentation.ts
│   │   │   ├── lib/
│   │   │   │   ├── auth/
│   │   │   │   │   ├── adapter.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── providers.ts
│   │   │   │   ├── base-url.ts
│   │   │   │   ├── chart.ts
│   │   │   │   ├── composition.ts
│   │   │   │   ├── domain.ts
│   │   │   │   ├── formatter.ts
│   │   │   │   ├── protected.ts
│   │   │   │   ├── server-actions.ts
│   │   │   │   ├── trpc/
│   │   │   │   │   ├── client.tsx
│   │   │   │   │   ├── query-client.ts
│   │   │   │   │   ├── server.tsx
│   │   │   │   │   └── shared.ts
│   │   │   │   └── utils.ts
│   │   │   ├── next-auth.d.ts
│   │   │   └── proxy.ts
│   │   ├── tsconfig.json
│   │   └── turbo.json
│   ├── web/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── components.json
│   │   ├── env.ts
│   │   ├── instrumentation-client.ts
│   │   ├── next-env.d.ts
│   │   ├── next.config.ts
│   │   ├── package.json
│   │   ├── postcss.config.js
│   │   ├── public/
│   │   │   ├── assets/
│   │   │   │   └── posts/
│   │   │   │       ├── global-latency-monitoring-benchmark-hono-hetzner/
│   │   │   │       │   └── hetzner.json
│   │   │   │       ├── hono-vercel-fluid-compute/
│   │   │   │       │   ├── hono-cold.json
│   │   │   │       │   └── hono-warm.json
│   │   │   │       ├── monitoring-latency/
│   │   │   │       │   ├── cloudflare.json
│   │   │   │       │   ├── fly.json
│   │   │   │       │   ├── koyeb.json
│   │   │   │       │   ├── railway.json
│   │   │   │       │   └── render.json
│   │   │   │       └── monitoring-vercel/
│   │   │   │           ├── vercel-cold.json
│   │   │   │           ├── vercel-edge.json
│   │   │   │           ├── vercel-roulette.json
│   │   │   │           └── vercel-warm.json
│   │   │   └── llms.txt
│   │   ├── sentry.edge.config.ts
│   │   ├── sentry.server.config.ts
│   │   ├── src/
│   │   │   ├── app/
│   │   │   │   ├── (landing)/
│   │   │   │   │   ├── (redirect)/
│   │   │   │   │   │   ├── bsky/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── cal/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── discord/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── docs/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── github/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── linkedin/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── schema.json/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── twitter/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   └── youtube/
│   │   │   │   │   │       └── page.tsx
│   │   │   │   │   ├── [slug]/
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── blog/
│   │   │   │   │   │   ├── [slug]/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── category/
│   │   │   │   │   │   │   ├── [slug]/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── feed.xml/
│   │   │   │   │   │   │   └── route.ts
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── changelog/
│   │   │   │   │   │   ├── [slug]/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── category/
│   │   │   │   │   │   │   ├── [slug]/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── feed.xml/
│   │   │   │   │   │   │   └── route.ts
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── compare/
│   │   │   │   │   │   ├── [slug]/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── content-box.tsx
│   │   │   │   │   ├── content-category.tsx
│   │   │   │   │   ├── content-list.tsx
│   │   │   │   │   ├── content-metadata.tsx
│   │   │   │   │   ├── content-pagination.tsx
│   │   │   │   │   ├── guides/
│   │   │   │   │   │   ├── [slug]/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── category/
│   │   │   │   │   │   │   ├── [slug]/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   ├── oss-friends/
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   ├── page.tsx
│   │   │   │   │   ├── play/
│   │   │   │   │   │   ├── checker/
│   │   │   │   │   │   │   ├── [slug]/
│   │   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── api/
│   │   │   │   │   │   │   │   └── route.ts
│   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   ├── search-params.ts
│   │   │   │   │   │   │   └── utils.ts
│   │   │   │   │   │   ├── curl/
│   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   ├── severity-matrix/
│   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   └── uptime-sla/
│   │   │   │   │   │       ├── client.tsx
│   │   │   │   │   │       └── page.tsx
│   │   │   │   │   ├── status/
│   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   └── utils.ts
│   │   │   │   │   └── use-case/
│   │   │   │   │       ├── [slug]/
│   │   │   │   │       │   └── page.tsx
│   │   │   │   │       └── page.tsx
│   │   │   │   ├── api/
│   │   │   │   │   ├── callback/
│   │   │   │   │   │   └── pagerduty/
│   │   │   │   │   │       └── route.ts
│   │   │   │   │   ├── checker/
│   │   │   │   │   │   ├── cron/
│   │   │   │   │   │   │   ├── 10m/
│   │   │   │   │   │   │   │   └── route.ts
│   │   │   │   │   │   │   ├── 1h/
│   │   │   │   │   │   │   │   └── route.ts
│   │   │   │   │   │   │   ├── 1m/
│   │   │   │   │   │   │   │   └── route.ts
│   │   │   │   │   │   │   ├── 30m/
│   │   │   │   │   │   │   │   └── route.ts
│   │   │   │   │   │   │   ├── 30s/
│   │   │   │   │   │   │   │   └── route.ts
│   │   │   │   │   │   │   ├── 5m/
│   │   │   │   │   │   │   │   └── route.ts
│   │   │   │   │   │   │   ├── _cron.ts
│   │   │   │   │   │   │   └── _sentry.ts
│   │   │   │   │   │   ├── test/
│   │   │   │   │   │   │   ├── http/
│   │   │   │   │   │   │   │   └── route.ts
│   │   │   │   │   │   │   └── tcp/
│   │   │   │   │   │   │       ├── route.ts
│   │   │   │   │   │   │       └── schema.ts
│   │   │   │   │   │   └── utils.ts
│   │   │   │   │   ├── internal/
│   │   │   │   │   │   └── email/
│   │   │   │   │   │       ├── feedback/
│   │   │   │   │   │       │   └── route.ts
│   │   │   │   │   │       ├── route.ts
│   │   │   │   │   │       └── team-invite/
│   │   │   │   │   │           └── route.ts
│   │   │   │   │   ├── markdown/
│   │   │   │   │   │   └── [[...path]]/
│   │   │   │   │   │       └── route.ts
│   │   │   │   │   ├── og/
│   │   │   │   │   │   ├── _components/
│   │   │   │   │   │   │   ├── background.tsx
│   │   │   │   │   │   │   ├── basic-layout.tsx
│   │   │   │   │   │   │   ├── status-check.tsx
│   │   │   │   │   │   │   └── tracker.tsx
│   │   │   │   │   │   ├── checker/
│   │   │   │   │   │   │   └── route.tsx
│   │   │   │   │   │   ├── monitor/
│   │   │   │   │   │   │   └── route.tsx
│   │   │   │   │   │   ├── page/
│   │   │   │   │   │   │   └── route.tsx
│   │   │   │   │   │   ├── post/
│   │   │   │   │   │   │   └── route.tsx
│   │   │   │   │   │   ├── route.tsx
│   │   │   │   │   │   ├── status/
│   │   │   │   │   │   │   └── route.tsx
│   │   │   │   │   │   └── utils.ts
│   │   │   │   │   ├── search/
│   │   │   │   │   │   └── route.ts
│   │   │   │   │   ├── test/
│   │   │   │   │   │   └── timeout/
│   │   │   │   │   │       └── route.ts
│   │   │   │   │   ├── trpc/
│   │   │   │   │   │   ├── edge/
│   │   │   │   │   │   │   └── [trpc]/
│   │   │   │   │   │   │       └── route.ts
│   │   │   │   │   │   └── lambda/
│   │   │   │   │   │       └── [trpc]/
│   │   │   │   │   │           └── route.ts
│   │   │   │   │   ├── upload/
│   │   │   │   │   │   └── route.ts
│   │   │   │   │   └── webhook/
│   │   │   │   │       └── stripe/
│   │   │   │   │           └── route.ts
│   │   │   │   ├── global-error.tsx
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── not-found.tsx
│   │   │   │   ├── robots.ts
│   │   │   │   └── sitemap.ts
│   │   │   ├── components/
│   │   │   │   ├── dev-mode-container.tsx
│   │   │   │   ├── icon-cloud-provider.tsx
│   │   │   │   ├── icons.tsx
│   │   │   │   ├── loading-animation.tsx
│   │   │   │   ├── tailwind-indicator.tsx
│   │   │   │   └── theme-provider.tsx
│   │   │   ├── config/
│   │   │   │   └── socials.ts
│   │   │   ├── content/
│   │   │   │   ├── cmdk.tsx
│   │   │   │   ├── component-highlighter.tsx
│   │   │   │   ├── convert.ts
│   │   │   │   ├── copy-button.tsx
│   │   │   │   ├── footer-status.tsx
│   │   │   │   ├── footer.tsx
│   │   │   │   ├── header.tsx
│   │   │   │   ├── highlight-text.tsx
│   │   │   │   ├── image-zoom.tsx
│   │   │   │   ├── latency-chart-table.tsx
│   │   │   │   ├── link.tsx
│   │   │   │   ├── listing.ts
│   │   │   │   ├── logo-with-context-menu.tsx
│   │   │   │   ├── mdx-components/
│   │   │   │   │   ├── button-link.tsx
│   │   │   │   │   ├── code.tsx
│   │   │   │   │   ├── custom-image.tsx
│   │   │   │   │   ├── custom-link.tsx
│   │   │   │   │   ├── details.tsx
│   │   │   │   │   ├── grid.tsx
│   │   │   │   │   ├── heading.tsx
│   │   │   │   │   ├── index.tsx
│   │   │   │   │   ├── pre.tsx
│   │   │   │   │   ├── status-page-example.tsx
│   │   │   │   │   ├── table.tsx
│   │   │   │   │   └── tweet.tsx
│   │   │   │   ├── mdx.tsx
│   │   │   │   ├── nav.tsx
│   │   │   │   ├── pages/
│   │   │   │   │   ├── blog/
│   │   │   │   │   │   ├── 2023-year-review.mdx
│   │   │   │   │   │   ├── 2026-roadmap.mdx
│   │   │   │   │   │   ├── data-table-redesign.mdx
│   │   │   │   │   │   ├── deploy-private-locations-raspberry-pi.mdx
│   │   │   │   │   │   ├── dynamic-breadcrumb-nextjs.mdx
│   │   │   │   │   │   ├── event-analytics-implementation.mdx
│   │   │   │   │   │   ├── global-latency-monitoring-benchmark-hono-hetzner.mdx
│   │   │   │   │   │   ├── hono-vercel-fluid-compute.mdx
│   │   │   │   │   │   ├── how-we-build-our-github-action.mdx
│   │   │   │   │   │   ├── introducing-goatstack.mdx
│   │   │   │   │   │   ├── introducing-openstatus-cli.mdx
│   │   │   │   │   │   ├── introducing-status-page-theme-explorer.mdx
│   │   │   │   │   │   ├── live-mode-infinite-query.mdx
│   │   │   │   │   │   ├── migrating-from-zod-openapi-to-connectrpc.mdx
│   │   │   │   │   │   ├── migration-auth-clerk-to-next-auth.mdx
│   │   │   │   │   │   ├── migration-backend-from-vercel-to-fly.mdx
│   │   │   │   │   │   ├── migration-planetscale-to-turso.mdx
│   │   │   │   │   │   ├── monitoring-latency-cf-workers-fly-koyeb-raylway-render.mdx
│   │   │   │   │   │   ├── monitoring-latency-vercel-edge-vs-serverless.mdx
│   │   │   │   │   │   ├── new-dashboard-we-are-so-back.mdx
│   │   │   │   │   │   ├── nobody-should-hand-code-a-data-table.mdx
│   │   │   │   │   │   ├── openstatus-infra.mdx
│   │   │   │   │   │   ├── openstatus-light-viewer.mdx
│   │   │   │   │   │   ├── openstatus-slack-agent.mdx
│   │   │   │   │   │   ├── our-new-pricing-explained.mdx
│   │   │   │   │   │   ├── our-producthunt-launch-brutal-reality.mdx
│   │   │   │   │   │   ├── pricing-update-july-2024.mdx
│   │   │   │   │   │   ├── product-strategy-a-reality-check.mdx
│   │   │   │   │   │   ├── q1-2024-update.mdx
│   │   │   │   │   │   ├── reflecting-1-year-building-openstatus.mdx
│   │   │   │   │   │   ├── rss-app-slack-feed.mdx
│   │   │   │   │   │   ├── same-pricing-more-monitors.mdx
│   │   │   │   │   │   ├── secure-api-with-unkey.mdx
│   │   │   │   │   │   ├── shadcn-component-registry.mdx
│   │   │   │   │   │   ├── status-page-addons.mdx
│   │   │   │   │   │   ├── status-page-components.mdx
│   │   │   │   │   │   ├── status-pages-is-politics.mdx
│   │   │   │   │   │   ├── telegram-group-qr-integration.mdx
│   │   │   │   │   │   ├── the-first-48-hours.mdx
│   │   │   │   │   │   └── vision-2025.mdx
│   │   │   │   │   ├── changelog/
│   │   │   │   │   │   ├── auto-resolved-incidents.mdx
│   │   │   │   │   │   ├── binary-payload.mdx
│   │   │   │   │   │   ├── check-run-api.mdx
│   │   │   │   │   │   ├── checker-playground.mdx
│   │   │   │   │   │   ├── cli-import-apply.mdx
│   │   │   │   │   │   ├── cli-improvement.mdx
│   │   │   │   │   │   ├── cli-monitor-template.mdx
│   │   │   │   │   │   ├── clone-monitor.mdx
│   │   │   │   │   │   ├── curl-builder-playground.mdx
│   │   │   │   │   │   ├── dark-theme-support.mdx
│   │   │   │   │   │   ├── dashboard-metrics-card.mdx
│   │   │   │   │   │   ├── dns-monitoring.mdx
│   │   │   │   │   │   ├── docker-checker.mdx
│   │   │   │   │   │   ├── follow-redirect.mdx
│   │   │   │   │   │   ├── github-action.mdx
│   │   │   │   │   │   ├── global-speed-checker-skills.mdx
│   │   │   │   │   │   ├── golang-monitor-checker.mdx
│   │   │   │   │   │   ├── google-chat-notifications.mdx
│   │   │   │   │   │   ├── grafana-oncall-integration.mdx
│   │   │   │   │   │   ├── grouped-monitors.mdx
│   │   │   │   │   │   ├── individual-status-report-page.mdx
│   │   │   │   │   │   ├── json-status-page.mdx
│   │   │   │   │   │   ├── latency-quantiles.mdx
│   │   │   │   │   │   ├── maintenance-status.mdx
│   │   │   │   │   │   ├── monitor-external-name.mdx
│   │   │   │   │   │   ├── monitor-tags.mdx
│   │   │   │   │   │   ├── monitor-threshold.mdx
│   │   │   │   │   │   ├── more-regions.mdx
│   │   │   │   │   │   ├── multi-cloud-fly-railway-koyeb.mdx
│   │   │   │   │   │   ├── multi-region-monitoring.mdx
│   │   │   │   │   │   ├── ntfy-sh-integration.mdx
│   │   │   │   │   │   ├── openstatus-cli.mdx
│   │   │   │   │   │   ├── openstatus-sdk.mdx
│   │   │   │   │   │   ├── opentelemetry.mdx
│   │   │   │   │   │   ├── pagerduty-integration.mdx
│   │   │   │   │   │   ├── password-protected-status-page.mdx
│   │   │   │   │   │   ├── play-checker-improvements.mdx
│   │   │   │   │   │   ├── private-location.mdx
│   │   │   │   │   │   ├── public-monitors.mdx
│   │   │   │   │   │   ├── raycast-integration.mdx
│   │   │   │   │   │   ├── request-assertions.mdx
│   │   │   │   │   │   ├── response-time-charts.mdx
│   │   │   │   │   │   ├── screenshot-incident.mdx
│   │   │   │   │   │   ├── slack-agent.mdx
│   │   │   │   │   │   ├── slack-discord-improvements.mdx
│   │   │   │   │   │   ├── slack-discord-notification.mdx
│   │   │   │   │   │   ├── sms-notification.mdx
│   │   │   │   │   │   ├── status-page-badge-v2.mdx
│   │   │   │   │   │   ├── status-page-badge.mdx
│   │   │   │   │   │   ├── status-page-colors-and-more.mdx
│   │   │   │   │   │   ├── status-page-component-subscription.mdx
│   │   │   │   │   │   ├── status-page-email-authentification.mdx
│   │   │   │   │   │   ├── status-page-feed.mdx
│   │   │   │   │   │   ├── status-page-monitor-order.mdx
│   │   │   │   │   │   ├── status-page-monitor-values-visibility.mdx
│   │   │   │   │   │   ├── status-page-redesign-beta.mdx
│   │   │   │   │   │   ├── status-page-slack-feed-subscribe.mdx
│   │   │   │   │   │   ├── status-page-subscribers.mdx
│   │   │   │   │   │   ├── status-page-unsubscribe.mdx
│   │   │   │   │   │   ├── status-page-white-label.mdx
│   │   │   │   │   │   ├── status-report-location-change.mdx
│   │   │   │   │   │   ├── status-update-subscriber.mdx
│   │   │   │   │   │   ├── status-widget.mdx
│   │   │   │   │   │   ├── tcp-monitoring.mdx
│   │   │   │   │   │   ├── team-invites.mdx
│   │   │   │   │   │   ├── telegram-bot-integration.mdx
│   │   │   │   │   │   ├── terraform-provider.mdx
│   │   │   │   │   │   ├── webhook-integration.mdx
│   │   │   │   │   │   └── whatsapp-notifications.mdx
│   │   │   │   │   ├── compare/
│   │   │   │   │   │   ├── atlassian-statuspage.mdx
│   │   │   │   │   │   ├── betterstack.mdx
│   │   │   │   │   │   ├── checkly.mdx
│   │   │   │   │   │   ├── incidentio.mdx
│   │   │   │   │   │   ├── instatus.mdx
│   │   │   │   │   │   ├── statusio.mdx
│   │   │   │   │   │   ├── uptime-kuma.mdx
│   │   │   │   │   │   └── uptime-robot.mdx
│   │   │   │   │   ├── guides/
│   │   │   │   │   │   ├── api-service-disruption.mdx
│   │   │   │   │   │   ├── best-opensource-status-page-2026.mdx
│   │   │   │   │   │   ├── boring-is-better-for-status-pages.mdx
│   │   │   │   │   │   ├── database-performance-degradation.mdx
│   │   │   │   │   │   ├── deployment-rollback.mdx
│   │   │   │   │   │   ├── feature-degradation.mdx
│   │   │   │   │   │   ├── http-headers.mdx
│   │   │   │   │   │   ├── incident-severity-matrix.mdx
│   │   │   │   │   │   ├── network-connectivity-issues.mdx
│   │   │   │   │   │   ├── public-postmortem-underrated-marketing.mdx
│   │   │   │   │   │   ├── public-vs-private-status-pages.mdx
│   │   │   │   │   │   ├── scheduled-maintenance.mdx
│   │   │   │   │   │   ├── security-incident-response.mdx
│   │   │   │   │   │   ├── sla-vs-slo-vs-sli.mdx
│   │   │   │   │   │   ├── top-five-atlassian-statuspage-alternatives.mdx
│   │   │   │   │   │   ├── why-every-saas-needs-a-status-page.mdx
│   │   │   │   │   │   └── why-uptime-percentage-is-misleading.mdx
│   │   │   │   │   ├── home.mdx
│   │   │   │   │   ├── product/
│   │   │   │   │   │   ├── status-page.mdx
│   │   │   │   │   │   └── uptime-monitoring.mdx
│   │   │   │   │   ├── tools/
│   │   │   │   │   │   ├── checker-slug.mdx
│   │   │   │   │   │   ├── checker.mdx
│   │   │   │   │   │   ├── curl.mdx
│   │   │   │   │   │   ├── severity-matrix.mdx
│   │   │   │   │   │   └── uptime-sla.mdx
│   │   │   │   │   ├── unrelated/
│   │   │   │   │   │   ├── about.mdx
│   │   │   │   │   │   ├── not-found.mdx
│   │   │   │   │   │   ├── pricing.mdx
│   │   │   │   │   │   ├── privacy.mdx
│   │   │   │   │   │   ├── registry.mdx
│   │   │   │   │   │   ├── subprocessors.mdx
│   │   │   │   │   │   └── terms.mdx
│   │   │   │   │   └── use-case/
│   │   │   │   │       ├── api-providers.mdx
│   │   │   │   │       ├── compliance.mdx
│   │   │   │   │       ├── crypto.mdx
│   │   │   │   │       └── open-source.mdx
│   │   │   │   ├── resolve.ts
│   │   │   │   ├── shadcn-registry-example.tsx
│   │   │   │   ├── simple-chart.tsx
│   │   │   │   ├── sub-nav.tsx
│   │   │   │   ├── theme-toggle.tsx
│   │   │   │   └── utils.ts
│   │   │   ├── data/
│   │   │   │   ├── author.ts
│   │   │   │   ├── code-dictionary.ts
│   │   │   │   ├── content.ts
│   │   │   │   ├── incidents-dictionary.ts
│   │   │   │   └── trigger-dictionary.ts
│   │   │   ├── env.ts
│   │   │   ├── instrumentation.ts
│   │   │   ├── lib/
│   │   │   │   ├── checker/
│   │   │   │   │   ├── mock.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── domains.ts
│   │   │   │   ├── github.ts
│   │   │   │   ├── image-dimensions.ts
│   │   │   │   ├── maintenances/
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── metadata/
│   │   │   │   │   ├── shared-metadata.ts
│   │   │   │   │   └── structured-data.ts
│   │   │   │   ├── monitor/
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── preferred-settings/
│   │   │   │   │   ├── client.ts
│   │   │   │   │   ├── server.ts
│   │   │   │   │   ├── shared.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── ratelimit.ts
│   │   │   │   ├── stream.ts
│   │   │   │   ├── stripe/
│   │   │   │   │   └── client.ts
│   │   │   │   ├── tb.ts
│   │   │   │   ├── timezone.ts
│   │   │   │   ├── toast.tsx
│   │   │   │   └── utils.ts
│   │   │   ├── public/
│   │   │   │   └── fonts/
│   │   │   │       ├── CommitMono-400-Italic.otf
│   │   │   │       ├── CommitMono-400-Regular.otf
│   │   │   │       ├── CommitMono-700-Italic.otf
│   │   │   │       └── CommitMono-700-Regular.otf
│   │   │   ├── react-table.d.ts
│   │   │   ├── styles/
│   │   │   │   └── globals.css
│   │   │   ├── trpc/
│   │   │   │   ├── client.ts
│   │   │   │   ├── query-client.ts
│   │   │   │   ├── rq-client.tsx
│   │   │   │   ├── rq-server.ts
│   │   │   │   ├── server.ts
│   │   │   │   └── shared.ts
│   │   │   └── types/
│   │   │       └── utils.ts
│   │   ├── tsconfig.json
│   │   ├── turbo.json
│   │   └── vercel.json
│   └── workflows/
│       ├── .dockerignore
│       ├── .gitignore
│       ├── Dockerfile
│       ├── README.md
│       ├── docker-compose.yaml
│       ├── dofigen.yml
│       ├── fly.toml
│       ├── package.json
│       ├── src/
│       │   ├── build-docker.ts
│       │   ├── checker/
│       │   │   ├── alerting.test.ts
│       │   │   ├── alerting.ts
│       │   │   ├── index.ts
│       │   │   └── utils.ts
│       │   ├── cron/
│       │   │   ├── checker.ts
│       │   │   ├── emails.ts
│       │   │   ├── index.ts
│       │   │   └── monitor.ts
│       │   ├── env.ts
│       │   ├── incident/
│       │   │   └── index.ts
│       │   ├── index.ts
│       │   ├── lib/
│       │   │   └── db.ts
│       │   ├── scripts/
│       │   │   └── tinybird.ts
│       │   └── utils/
│       │       └── audit-log.ts
│       ├── start.sh
│       └── tsconfig.json
├── biome.jsonc
├── bunfig.toml
├── config.openstatus.yaml
├── coolify-deployment.yaml
├── devbox.json
├── docker-compose-lightweight.yaml
├── docker-compose.github-packages.yaml
├── docker-compose.yaml
├── infra/
│   └── openstatus.yaml
├── knip.ts
├── package.json
├── packages/
│   ├── analytics/
│   │   ├── env.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── events.ts
│   │   │   ├── index.ts
│   │   │   ├── server.ts
│   │   │   └── utils.ts
│   │   └── tsconfig.json
│   ├── api/
│   │   ├── env.ts
│   │   ├── index.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── edge.ts
│   │   │   ├── env.ts
│   │   │   ├── lambda.ts
│   │   │   ├── root.ts
│   │   │   ├── router/
│   │   │   │   ├── apiKey.ts
│   │   │   │   ├── blob.ts
│   │   │   │   ├── checker.ts
│   │   │   │   ├── domain.ts
│   │   │   │   ├── email/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── feedback.ts
│   │   │   │   ├── import.test.ts
│   │   │   │   ├── import.ts
│   │   │   │   ├── incident.ts
│   │   │   │   ├── integration.ts
│   │   │   │   ├── invitation.ts
│   │   │   │   ├── maintenance.test.ts
│   │   │   │   ├── maintenance.ts
│   │   │   │   ├── member.ts
│   │   │   │   ├── monitor.test.ts
│   │   │   │   ├── monitor.ts
│   │   │   │   ├── monitorTag.ts
│   │   │   │   ├── notification.test.ts
│   │   │   │   ├── notification.ts
│   │   │   │   ├── page.ts
│   │   │   │   ├── pageComponent.test.ts
│   │   │   │   ├── pageComponent.ts
│   │   │   │   ├── pageSubscriber.ts
│   │   │   │   ├── privateLocation.test.ts
│   │   │   │   ├── privateLocation.ts
│   │   │   │   ├── statusPage.e2e.test.ts
│   │   │   │   ├── statusPage.ts
│   │   │   │   ├── statusPage.unsubscribe.test.ts
│   │   │   │   ├── statusPage.utils.test.ts
│   │   │   │   ├── statusPage.utils.ts
│   │   │   │   ├── statusReport.test.ts
│   │   │   │   ├── statusReport.ts
│   │   │   │   ├── stripe/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── shared.ts
│   │   │   │   │   ├── utils.ts
│   │   │   │   │   └── webhook.ts
│   │   │   │   ├── tinybird/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── user.ts
│   │   │   │   ├── utils.ts
│   │   │   │   ├── workspace.test.ts
│   │   │   │   └── workspace.ts
│   │   │   ├── service/
│   │   │   │   ├── apiKey.test.ts
│   │   │   │   ├── apiKey.ts
│   │   │   │   ├── import.test.ts
│   │   │   │   ├── import.ts
│   │   │   │   └── telegram-updates.ts
│   │   │   ├── test/
│   │   │   │   └── preload.ts
│   │   │   └── trpc.ts
│   │   └── tsconfig.json
│   ├── assertions/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── dictionary.ts
│   │   │   ├── index.ts
│   │   │   ├── serializing.ts
│   │   │   ├── type-guards.ts
│   │   │   ├── types.ts
│   │   │   └── v1.ts
│   │   └── tsconfig.json
│   ├── db/
│   │   ├── README.md
│   │   ├── drizzle/
│   │   │   ├── 0000_lively_master_chief.sql
│   │   │   ├── 0001_brainy_beast.sql
│   │   │   ├── 0002_luxuriant_ser_duncan.sql
│   │   │   ├── 0003_glamorous_living_mummy.sql
│   │   │   ├── 0004_fixed_dakota_north.sql
│   │   │   ├── 0005_even_baron_strucker.sql
│   │   │   ├── 0006_tired_anita_blake.sql
│   │   │   ├── 0007_complex_frog_thor.sql
│   │   │   ├── 0008_overjoyed_sunset_bain.sql
│   │   │   ├── 0009_small_maximus.sql
│   │   │   ├── 0010_lame_songbird.sql
│   │   │   ├── 0011_bright_jazinda.sql
│   │   │   ├── 0012_tan_magma.sql
│   │   │   ├── 0013_tired_paladin.sql
│   │   │   ├── 0014_adorable_skaar.sql
│   │   │   ├── 0015_bent_sister_grimm.sql
│   │   │   ├── 0016_certain_praxagora.sql
│   │   │   ├── 0017_loose_maggott.sql
│   │   │   ├── 0018_neat_orphan.sql
│   │   │   ├── 0019_dashing_malcolm_colcord.sql
│   │   │   ├── 0020_flat_bedlam.sql
│   │   │   ├── 0021_reflective_nico_minoru.sql
│   │   │   ├── 0022_chunky_rockslide.sql
│   │   │   ├── 0023_dry_blink.sql
│   │   │   ├── 0024_young_proudstar.sql
│   │   │   ├── 0025_strong_thunderball.sql
│   │   │   ├── 0026_giant_absorbing_man.sql
│   │   │   ├── 0027_bizarre_bastion.sql
│   │   │   ├── 0028_thin_power_pack.sql
│   │   │   ├── 0029_regular_marrow.sql
│   │   │   ├── 0030_elite_barracuda.sql
│   │   │   ├── 0031_lowly_gabe_jones.sql
│   │   │   ├── 0032_hot_swordsman.sql
│   │   │   ├── 0033_solid_colossus.sql
│   │   │   ├── 0034_serious_shard.sql
│   │   │   ├── 0035_open_the_professor.sql
│   │   │   ├── 0036_gifted_deathbird.sql
│   │   │   ├── 0037_equal_beyonder.sql
│   │   │   ├── 0038_foamy_stardust.sql
│   │   │   ├── 0039_lonely_jigsaw.sql
│   │   │   ├── 0040_narrow_anthem.sql
│   │   │   ├── 0041_nasty_jigsaw.sql
│   │   │   ├── 0042_great_epoch.sql
│   │   │   ├── 0043_low_lily_hollister.sql
│   │   │   ├── 0044_illegal_turbo.sql
│   │   │   ├── 0045_little_paladin.sql
│   │   │   ├── 0046_lucky_tarantula.sql
│   │   │   ├── 0047_nifty_roughhouse.sql
│   │   │   ├── 0048_neat_tempest.sql
│   │   │   ├── 0049_sloppy_inhumans.sql
│   │   │   ├── 0050_damp_xorn.sql
│   │   │   ├── 0051_fuzzy_red_hulk.sql
│   │   │   ├── 0052_illegal_killraven.sql
│   │   │   ├── 0053_dark_orphan.sql
│   │   │   ├── 0054_bitter_lilandra.sql
│   │   │   ├── 0055_spicy_bastion.sql
│   │   │   ├── 0056_violet_shotgun.sql
│   │   │   ├── 0057_curious_xorn.sql
│   │   │   ├── 0058_absent_chameleon.sql
│   │   │   └── meta/
│   │   │       ├── 0000_snapshot.json
│   │   │       ├── 0001_snapshot.json
│   │   │       ├── 0002_snapshot.json
│   │   │       ├── 0003_snapshot.json
│   │   │       ├── 0004_snapshot.json
│   │   │       ├── 0005_snapshot.json
│   │   │       ├── 0006_snapshot.json
│   │   │       ├── 0007_snapshot.json
│   │   │       ├── 0008_snapshot.json
│   │   │       ├── 0009_snapshot.json
│   │   │       ├── 0010_snapshot.json
│   │   │       ├── 0011_snapshot.json
│   │   │       ├── 0012_snapshot.json
│   │   │       ├── 0013_snapshot.json
│   │   │       ├── 0014_snapshot.json
│   │   │       ├── 0015_snapshot.json
│   │   │       ├── 0016_snapshot.json
│   │   │       ├── 0017_snapshot.json
│   │   │       ├── 0018_snapshot.json
│   │   │       ├── 0019_snapshot.json
│   │   │       ├── 0020_snapshot.json
│   │   │       ├── 0021_snapshot.json
│   │   │       ├── 0022_snapshot.json
│   │   │       ├── 0023_snapshot.json
│   │   │       ├── 0024_snapshot.json
│   │   │       ├── 0025_snapshot.json
│   │   │       ├── 0026_snapshot.json
│   │   │       ├── 0027_snapshot.json
│   │   │       ├── 0028_snapshot.json
│   │   │       ├── 0029_snapshot.json
│   │   │       ├── 0030_snapshot.json
│   │   │       ├── 0031_snapshot.json
│   │   │       ├── 0032_snapshot.json
│   │   │       ├── 0033_snapshot.json
│   │   │       ├── 0034_snapshot.json
│   │   │       ├── 0035_snapshot.json
│   │   │       ├── 0036_snapshot.json
│   │   │       ├── 0037_snapshot.json
│   │   │       ├── 0038_snapshot.json
│   │   │       ├── 0039_snapshot.json
│   │   │       ├── 0040_snapshot.json
│   │   │       ├── 0041_snapshot.json
│   │   │       ├── 0042_snapshot.json
│   │   │       ├── 0043_snapshot.json
│   │   │       ├── 0044_snapshot.json
│   │   │       ├── 0045_snapshot.json
│   │   │       ├── 0046_snapshot.json
│   │   │       ├── 0047_snapshot.json
│   │   │       ├── 0048_snapshot.json
│   │   │       ├── 0049_snapshot.json
│   │   │       ├── 0050_snapshot.json
│   │   │       ├── 0051_snapshot.json
│   │   │       ├── 0052_snapshot.json
│   │   │       ├── 0053_snapshot.json
│   │   │       ├── 0054_snapshot.json
│   │   │       ├── 0055_snapshot.json
│   │   │       ├── 0056_snapshot.json
│   │   │       ├── 0057_snapshot.json
│   │   │       ├── 0058_snapshot.json
│   │   │       └── _journal.json
│   │   ├── drizzle.config.ts
│   │   ├── env.mjs
│   │   ├── env.ts
│   │   ├── package.json
│   │   ├── script/
│   │   │   ├── region-migration.test.ts
│   │   │   └── region-migration.ts
│   │   ├── src/
│   │   │   ├── db.ts
│   │   │   ├── index.ts
│   │   │   ├── migrate.mts
│   │   │   ├── schema/
│   │   │   │   ├── api-keys/
│   │   │   │   │   ├── api_key.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── applications/
│   │   │   │   │   ├── application.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── check/
│   │   │   │   │   ├── check.ts
│   │   │   │   │   ├── constants.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── constants.ts
│   │   │   │   ├── incidents/
│   │   │   │   │   ├── incident.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── integration.ts
│   │   │   │   ├── invitations/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── invitation.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── maintenances/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── maintenance.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── monitor_groups/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── monitor_group.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── monitor_run/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── monitor_run.ts
│   │   │   │   ├── monitor_status/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── monitor_status.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── monitor_tags/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── monitor_tag.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── monitors/
│   │   │   │   │   ├── constants.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── monitor.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── notifications/
│   │   │   │   │   ├── constants.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── notification.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── page_component_groups/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── page_component_groups.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── page_components/
│   │   │   │   │   ├── constants.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── page_components.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── page_subscribers/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── page_subscriber_to_page_component.ts
│   │   │   │   │   ├── page_subscribers.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── pages/
│   │   │   │   │   ├── constants.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── page.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── plan/
│   │   │   │   │   ├── config.ts
│   │   │   │   │   ├── schema.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── private_locations/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── private_locations.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── shared.ts
│   │   │   │   ├── status_reports/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── status_reports.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── users/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── user.ts
│   │   │   │   │   └── validation.ts
│   │   │   │   ├── viewers/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── validation.ts
│   │   │   │   │   └── viewer.ts
│   │   │   │   └── workspaces/
│   │   │   │       ├── constants.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── validation.ts
│   │   │   │       └── workspace.ts
│   │   │   ├── seed.mts
│   │   │   ├── sync-db.ts
│   │   │   └── utils/
│   │   │       ├── api-key.test.ts
│   │   │       ├── api-key.ts
│   │   │       └── index.ts
│   │   └── tsconfig.json
│   ├── emails/
│   │   ├── emails/
│   │   │   ├── _components/
│   │   │   │   ├── footer.tsx
│   │   │   │   ├── layout.tsx
│   │   │   │   └── styles.ts
│   │   │   ├── feedback.tsx
│   │   │   ├── followup.tsx
│   │   │   ├── monitor-alert.tsx
│   │   │   ├── monitor-deactivation.tsx
│   │   │   ├── monitor-paused.tsx
│   │   │   ├── page-subscription.tsx
│   │   │   ├── slack-feedback.tsx
│   │   │   ├── status-page-magic-link.tsx
│   │   │   ├── status-report.tsx
│   │   │   ├── subscribe.tsx
│   │   │   ├── team-invitation.tsx
│   │   │   ├── team-invite-reminder.tsx
│   │   │   └── welcome.tsx
│   │   ├── hotfix/
│   │   │   ├── monitor-alert.ts
│   │   │   ├── monitor-deactivation.ts
│   │   │   └── monitor-paused.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── client.integration.test.tsx
│   │   │   ├── client.tsx
│   │   │   ├── env.ts
│   │   │   ├── index.ts
│   │   │   ├── send.ts
│   │   │   └── utils.ts
│   │   └── tsconfig.json
│   ├── error/
│   │   ├── index.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── base-error.ts
│   │   │   ├── error-code.ts
│   │   │   ├── http-error.ts
│   │   │   ├── schema-error.ts
│   │   │   └── utils.ts
│   │   └── tsconfig.json
│   ├── header-analysis/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── index.ts
│   │   │   ├── parser/
│   │   │   │   ├── cache-control.ts
│   │   │   │   ├── cf-cache-status.ts
│   │   │   │   ├── cf-ray.ts
│   │   │   │   ├── fly-request-id.ts
│   │   │   │   ├── x-vercel-cache.ts
│   │   │   │   └── x-vercel-id.ts
│   │   │   ├── regions/
│   │   │   │   ├── cloudflare.ts
│   │   │   │   ├── fly.ts
│   │   │   │   └── vercel.ts
│   │   │   └── types/
│   │   │       └── index.ts
│   │   └── tsconfig.json
│   ├── icons/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── discord.tsx
│   │   │   ├── fly.tsx
│   │   │   ├── github.tsx
│   │   │   ├── google.tsx
│   │   │   ├── grafana.tsx
│   │   │   ├── index.tsx
│   │   │   ├── koyeb.tsx
│   │   │   ├── markdown.tsx
│   │   │   ├── opsgenie.tsx
│   │   │   ├── pagerduty.tsx
│   │   │   ├── railway.tsx
│   │   │   ├── slack.tsx
│   │   │   ├── statuspage.tsx
│   │   │   ├── telegram.tsx
│   │   │   └── whatsapp.tsx
│   │   └── tsconfig.json
│   ├── importers/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── index.ts
│   │   │   ├── providers/
│   │   │   │   └── statuspage/
│   │   │   │       ├── api-types.ts
│   │   │   │       ├── client.test.ts
│   │   │   │       ├── client.ts
│   │   │   │       ├── fixtures.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── mapper.test.ts
│   │   │   │       ├── mapper.ts
│   │   │   │       ├── provider.test.ts
│   │   │   │       └── provider.ts
│   │   │   └── types.ts
│   │   └── tsconfig.json
│   ├── notifications/
│   │   ├── base/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── index.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── utils/
│   │   │   │       ├── colors.ts
│   │   │   │       ├── duration.test.ts
│   │   │   │       ├── duration.ts
│   │   │   │       ├── incident.test.ts
│   │   │   │       ├── incident.ts
│   │   │   │       ├── message.ts
│   │   │   │       └── timestamp.ts
│   │   │   └── tsconfig.json
│   │   ├── discord/
│   │   │   ├── .gitignore
│   │   │   ├── README.md
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── embeds.ts
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── mock.ts
│   │   │   └── tsconfig.json
│   │   ├── email/
│   │   │   ├── README.md
│   │   │   ├── env.ts
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── mock.ts
│   │   │   └── tsconfig.json
│   │   ├── google-chat/
│   │   │   ├── .gitignore
│   │   │   ├── README.md
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── mock.ts
│   │   │   └── tsconfig.json
│   │   ├── grafana-oncall/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   └── tsconfig.json
│   │   ├── ntfy/
│   │   │   ├── .gitignore
│   │   │   ├── README.md
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   └── tsconfig.json
│   │   ├── opsgenie/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   └── tsconfig.json
│   │   ├── pagerduty/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── env.ts
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema/
│   │   │   │       └── config.ts
│   │   │   └── tsconfig.json
│   │   ├── slack/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── blocks.ts
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── mock.ts
│   │   │   └── tsconfig.json
│   │   ├── telegram/
│   │   │   ├── .gitignore
│   │   │   ├── README.md
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── schema.ts
│   │   │   └── tsconfig.json
│   │   ├── twillio-sms/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── env.ts
│   │   │   │   ├── index.test.ts
│   │   │   │   └── index.ts
│   │   │   └── tsconfig.json
│   │   ├── twillio-whatsapp/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── env.ts
│   │   │   │   ├── index.test.ts
│   │   │   │   └── index.ts
│   │   │   └── tsconfig.json
│   │   └── webhook/
│   │       ├── .gitignore
│   │       ├── README.md
│   │       ├── package.json
│   │       ├── src/
│   │       │   ├── index.test.ts
│   │       │   ├── index.ts
│   │       │   └── schema.ts
│   │       └── tsconfig.json
│   ├── proto/
│   │   ├── api/
│   │   │   └── openstatus/
│   │   │       ├── health/
│   │   │       │   └── v1/
│   │   │       │       └── health.proto
│   │   │       ├── maintenance/
│   │   │       │   └── v1/
│   │   │       │       ├── maintenance.proto
│   │   │       │       └── service.proto
│   │   │       ├── monitor/
│   │   │       │   └── v1/
│   │   │       │       ├── assertions.proto
│   │   │       │       ├── dns_monitor.proto
│   │   │       │       ├── http_monitor.proto
│   │   │       │       ├── monitor.proto
│   │   │       │       ├── service.proto
│   │   │       │       └── tcp_monitor.proto
│   │   │       ├── notification/
│   │   │       │   └── v1/
│   │   │       │       ├── notification.proto
│   │   │       │       ├── providers.proto
│   │   │       │       └── service.proto
│   │   │       ├── status_page/
│   │   │       │   └── v1/
│   │   │       │       ├── page_component.proto
│   │   │       │       ├── page_subscriber.proto
│   │   │       │       ├── service.proto
│   │   │       │       └── status_page.proto
│   │   │       └── status_report/
│   │   │           └── v1/
│   │   │               ├── service.proto
│   │   │               └── status_report.proto
│   │   ├── base.openapi.yaml
│   │   ├── buf.gen.go.yaml
│   │   ├── buf.gen.openapi.yaml
│   │   ├── buf.gen.ts.yaml
│   │   ├── buf.yaml
│   │   ├── gen/
│   │   │   ├── openapi.yaml
│   │   │   └── ts/
│   │   │       ├── buf/
│   │   │       │   └── validate/
│   │   │       │       └── validate_pb.ts
│   │   │       ├── gnostic/
│   │   │       │   └── openapi/
│   │   │       │       └── v3/
│   │   │       │           ├── annotations_pb.ts
│   │   │       │           └── openapiv3_pb.ts
│   │   │       ├── index.ts
│   │   │       └── openstatus/
│   │   │           ├── health/
│   │   │           │   └── v1/
│   │   │           │       ├── health_pb.ts
│   │   │           │       └── index.ts
│   │   │           ├── maintenance/
│   │   │           │   └── v1/
│   │   │           │       ├── index.ts
│   │   │           │       ├── maintenance_pb.ts
│   │   │           │       └── service_pb.ts
│   │   │           ├── monitor/
│   │   │           │   └── v1/
│   │   │           │       ├── assertions_pb.ts
│   │   │           │       ├── dns_monitor_pb.ts
│   │   │           │       ├── http_monitor_pb.ts
│   │   │           │       ├── index.ts
│   │   │           │       ├── monitor_pb.ts
│   │   │           │       ├── service_pb.ts
│   │   │           │       └── tcp_monitor_pb.ts
│   │   │           ├── notification/
│   │   │           │   └── v1/
│   │   │           │       ├── index.ts
│   │   │           │       ├── notification_pb.ts
│   │   │           │       ├── providers_pb.ts
│   │   │           │       └── service_pb.ts
│   │   │           ├── status_page/
│   │   │           │   └── v1/
│   │   │           │       ├── index.ts
│   │   │           │       ├── page_component_pb.ts
│   │   │           │       ├── page_subscriber_pb.ts
│   │   │           │       ├── service_pb.ts
│   │   │           │       └── status_page_pb.ts
│   │   │           └── status_report/
│   │   │               └── v1/
│   │   │                   ├── index.ts
│   │   │                   ├── service_pb.ts
│   │   │                   └── status_report_pb.ts
│   │   ├── go.mod
│   │   ├── go.sum
│   │   ├── internal/
│   │   │   └── private_location/
│   │   │       └── v1/
│   │   │           ├── assertions.proto
│   │   │           ├── dns_monitor.proto
│   │   │           ├── http_monitor.proto
│   │   │           ├── private_location.proto
│   │   │           └── tcp_monitor.proto
│   │   ├── justfile
│   │   ├── package.json
│   │   ├── plan/
│   │   │   ├── PLAN.md
│   │   │   └── api.md
│   │   ├── scripts/
│   │   │   └── clean-openapi.ts
│   │   └── tsconfig.json
│   ├── react/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── index.ts
│   │   │   ├── styles.css
│   │   │   ├── utils.ts
│   │   │   └── widget.tsx
│   │   ├── tsconfig.json
│   │   └── tsup.config.js
│   ├── regions/
│   │   ├── index.ts
│   │   ├── package.json
│   │   └── tsconfig.json
│   ├── status-fetcher/
│   │   ├── README.md
│   │   ├── __tests__/
│   │   │   ├── fetch-utils.test.ts
│   │   │   ├── fetchers/
│   │   │   │   ├── atlassian.test.ts
│   │   │   │   ├── betterstack.test.ts
│   │   │   │   ├── custom.test.ts
│   │   │   │   ├── edge-cases.test.ts
│   │   │   │   ├── html.test.ts
│   │   │   │   ├── incidentio.test.ts
│   │   │   │   └── instatus.test.ts
│   │   │   ├── integration.test.ts
│   │   │   └── utils.test.ts
│   │   ├── package.json
│   │   ├── scripts/
│   │   │   └── test-fetchers.ts
│   │   ├── src/
│   │   │   ├── data/
│   │   │   │   ├── directory.ts
│   │   │   │   └── index.ts
│   │   │   ├── fetch-utils.ts
│   │   │   ├── fetchers/
│   │   │   │   ├── atlassian.ts
│   │   │   │   ├── betterstack.ts
│   │   │   │   ├── custom.ts
│   │   │   │   ├── html.ts
│   │   │   │   ├── incidentio.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── instatus.ts
│   │   │   ├── index.ts
│   │   │   ├── types.ts
│   │   │   └── utils.ts
│   │   └── tsconfig.json
│   ├── subscriptions/
│   │   ├── bunfig.toml
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── channels/
│   │   │   │   ├── email.test.ts
│   │   │   │   ├── email.ts
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── webhook.test.ts
│   │   │   │   └── webhook.ts
│   │   │   ├── dispatcher.test.ts
│   │   │   ├── dispatcher.ts
│   │   │   ├── index.ts
│   │   │   ├── service.test.ts
│   │   │   ├── service.ts
│   │   │   ├── test-preload.ts
│   │   │   └── types.ts
│   │   └── tsconfig.json
│   ├── theme-store/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── dracula.ts
│   │   │   ├── github.ts
│   │   │   ├── index.ts
│   │   │   ├── openstatus.ts
│   │   │   ├── supabase.ts
│   │   │   ├── types.ts
│   │   │   └── utils.ts
│   │   └── tsconfig.json
│   ├── tinybird/
│   │   ├── README.md
│   │   ├── datasources/
│   │   │   ├── audit_log__v0.datasource
│   │   │   ├── check_response.datasource
│   │   │   ├── check_response_http.datasource
│   │   │   ├── dns_response__v0.datasource
│   │   │   ├── external_status.datasource
│   │   │   ├── mv__dns_status_45d__v0.datasource
│   │   │   ├── mv__http_14d.datasource
│   │   │   ├── mv__http_14d__v0.datasource
│   │   │   ├── mv__http_14d__v1.datasource
│   │   │   ├── mv__http_1d__v0.datasource
│   │   │   ├── mv__http_1d__v1.datasource
│   │   │   ├── mv__http_30d__v0.datasource
│   │   │   ├── mv__http_30d__v1.datasource
│   │   │   ├── mv__http_7d__v0.datasource
│   │   │   ├── mv__http_7d__v1.datasource
│   │   │   ├── mv__http_full_14d__v0.datasource
│   │   │   ├── mv__http_full_30d__v0.datasource
│   │   │   ├── mv__http_status_14d__v0.datasource
│   │   │   ├── mv__http_status_45d__v0.datasource
│   │   │   ├── mv__http_status_45d__v1.datasource
│   │   │   ├── mv__http_status_7d__v0.datasource
│   │   │   ├── mv__http_timing_phases_14d.datasource
│   │   │   ├── mv__http_timing_phases_14d__v1.datasource
│   │   │   ├── mv__http_uptime_30d__v1.datasource
│   │   │   ├── mv__http_uptime_7d__v1.datasource
│   │   │   ├── mv__http_workspace_30d__v0.datasource
│   │   │   ├── mv__tcp_14d__v0.datasource
│   │   │   ├── mv__tcp_14d__v1.datasource
│   │   │   ├── mv__tcp_1d__v0.datasource
│   │   │   ├── mv__tcp_1d__v1.datasource
│   │   │   ├── mv__tcp_30d__v0.datasource
│   │   │   ├── mv__tcp_30d__v1.datasource
│   │   │   ├── mv__tcp_7d__v0.datasource
│   │   │   ├── mv__tcp_7d__v1.datasource
│   │   │   ├── mv__tcp_full_14d__v0.datasource
│   │   │   ├── mv__tcp_full_30d__v0.datasource
│   │   │   ├── mv__tcp_status_45d__v0.datasource
│   │   │   ├── mv__tcp_status_45d__v1.datasource
│   │   │   ├── mv__tcp_status_7d__v0.datasource
│   │   │   ├── mv__tcp_uptime_30d__v1.datasource
│   │   │   ├── mv__tcp_uptime_7d__v1.datasource
│   │   │   ├── mv__tcp_workspace_30d__v0.datasource
│   │   │   ├── mv_http_status_14d.datasource
│   │   │   ├── ping_response__v8.datasource
│   │   │   ├── tcp_response.datasource
│   │   │   └── tcp_response__v0.datasource
│   │   ├── endpoints/
│   │   │   ├── endpoint__audit_log.pipe
│   │   │   ├── endpoint__audit_log__v1.pipe
│   │   │   ├── endpoint__dns_get_14d__v0.pipe
│   │   │   ├── endpoint__dns_list_14d__v0.pipe
│   │   │   ├── endpoint__dns_metrics_14d__v0.pipe
│   │   │   ├── endpoint__dns_metrics_1d__v0.pipe
│   │   │   ├── endpoint__dns_metrics_7d__v0.pipe
│   │   │   ├── endpoint__dns_metrics_latency_1d_multi__v0.pipe
│   │   │   ├── endpoint__dns_metrics_latency_7d__v0.pipe
│   │   │   ├── endpoint__dns_metrics_regions_14d__v0.pipe
│   │   │   ├── endpoint__dns_status_45d__v0.pipe
│   │   │   ├── endpoint__dns_uptime_30d__v0.pipe
│   │   │   ├── endpoint__http_get_14d__v0.pipe
│   │   │   ├── endpoint__http_get_30d.pipe
│   │   │   ├── endpoint__http_list_14d.pipe
│   │   │   ├── endpoint__http_list_14d__v1.pipe
│   │   │   ├── endpoint__http_list_1d.pipe
│   │   │   ├── endpoint__http_list_1d__v1.pipe
│   │   │   ├── endpoint__http_list_7d.pipe
│   │   │   ├── endpoint__http_list_7d__v1.pipe
│   │   │   ├── endpoint__http_metrics_14d.pipe
│   │   │   ├── endpoint__http_metrics_14d__v1.pipe
│   │   │   ├── endpoint__http_metrics_1d.pipe
│   │   │   ├── endpoint__http_metrics_1d__v1.pipe
│   │   │   ├── endpoint__http_metrics_7d.pipe
│   │   │   ├── endpoint__http_metrics_7d__v1.pipe
│   │   │   ├── endpoint__http_metrics_by_interval_14d.pipe
│   │   │   ├── endpoint__http_metrics_by_interval_1d.pipe
│   │   │   ├── endpoint__http_metrics_by_interval_7d.pipe
│   │   │   ├── endpoint__http_metrics_by_region_14d.pipe
│   │   │   ├── endpoint__http_metrics_by_region_1d.pipe
│   │   │   ├── endpoint__http_metrics_by_region_7d.pipe
│   │   │   ├── endpoint__http_metrics_global_1d__v0.pipe
│   │   │   ├── endpoint__http_metrics_latency_1d__v1.pipe
│   │   │   ├── endpoint__http_metrics_latency_1d_multi__v1.pipe
│   │   │   ├── endpoint__http_metrics_latency_7d__v1.pipe
│   │   │   ├── endpoint__http_metrics_regions_14d__v0.pipe
│   │   │   ├── endpoint__http_metrics_regions_1d__v0.pipe
│   │   │   ├── endpoint__http_metrics_regions_7d__v0.pipe
│   │   │   ├── endpoint__http_status_14d.pipe
│   │   │   ├── endpoint__http_status_45d.pipe
│   │   │   ├── endpoint__http_status_45d__v1.pipe
│   │   │   ├── endpoint__http_status_7d.pipe
│   │   │   ├── endpoint__http_timing_phases_14d__v1.pipe
│   │   │   ├── endpoint__http_uptime_30d__v1.pipe
│   │   │   ├── endpoint__http_uptime_7d__v1.pipe
│   │   │   ├── endpoint__http_workspace_30d__v0.pipe
│   │   │   ├── endpoint__stats_global.pipe
│   │   │   ├── endpoint__tcp_get_14d__v0.pipe
│   │   │   ├── endpoint__tcp_get_30d.pipe
│   │   │   ├── endpoint__tcp_list_14d.pipe
│   │   │   ├── endpoint__tcp_list_14d__v1.pipe
│   │   │   ├── endpoint__tcp_list_1d.pipe
│   │   │   ├── endpoint__tcp_list_1d__v1.pipe
│   │   │   ├── endpoint__tcp_list_7d.pipe
│   │   │   ├── endpoint__tcp_list_7d__v1.pipe
│   │   │   ├── endpoint__tcp_metrics_14d.pipe
│   │   │   ├── endpoint__tcp_metrics_14d__v1.pipe
│   │   │   ├── endpoint__tcp_metrics_1d.pipe
│   │   │   ├── endpoint__tcp_metrics_1d__v1.pipe
│   │   │   ├── endpoint__tcp_metrics_7d.pipe
│   │   │   ├── endpoint__tcp_metrics_7d__v1.pipe
│   │   │   ├── endpoint__tcp_metrics_by_interval_14d.pipe
│   │   │   ├── endpoint__tcp_metrics_by_interval_1d.pipe
│   │   │   ├── endpoint__tcp_metrics_by_interval_7d.pipe
│   │   │   ├── endpoint__tcp_metrics_by_region_14d.pipe
│   │   │   ├── endpoint__tcp_metrics_by_region_1d.pipe
│   │   │   ├── endpoint__tcp_metrics_by_region_7d.pipe
│   │   │   ├── endpoint__tcp_metrics_global_1d.pipe
│   │   │   ├── endpoint__tcp_metrics_latency_1d__v1.pipe
│   │   │   ├── endpoint__tcp_metrics_latency_1d_multi__v1.pipe
│   │   │   ├── endpoint__tcp_metrics_latency_7d__v1.pipe
│   │   │   ├── endpoint__tcp_status_45d.pipe
│   │   │   ├── endpoint__tcp_status_45d__v1.pipe
│   │   │   ├── endpoint__tcp_status_7d.pipe
│   │   │   ├── endpoint__tcp_uptime_30d__v1.pipe
│   │   │   ├── endpoint__tcp_uptime_7d__v1.pipe
│   │   │   ├── endpoint__tcp_workspace_30d__v0.pipe
│   │   │   ├── endpoint_audit_log.pipe
│   │   │   └── endpoint_external_status.pipe
│   │   ├── package.json
│   │   ├── pipes/
│   │   │   ├── __ttl_45d_count_utc_get.pipe
│   │   │   ├── aggregate__dns_status_45d__v1.pipe
│   │   │   ├── aggregate__http_14d__v1.pipe
│   │   │   ├── aggregate__http_1d__v1.pipe
│   │   │   ├── aggregate__http_30d__v1.pipe
│   │   │   ├── aggregate__http_7d__v1.pipe
│   │   │   ├── aggregate__http_full_14d__v0.pipe
│   │   │   ├── aggregate__http_full_30d__v0.pipe
│   │   │   ├── aggregate__http_status_14d.pipe
│   │   │   ├── aggregate__http_status_45d.pipe
│   │   │   ├── aggregate__http_status_45d__v1.pipe
│   │   │   ├── aggregate__http_status_7d.pipe
│   │   │   ├── aggregate__http_timing_phases_14d.pipe
│   │   │   ├── aggregate__http_uptime_30d.pipe
│   │   │   ├── aggregate__http_uptime_7d__v1.pipe
│   │   │   ├── aggregate__http_workspace_30d__v0.pipe
│   │   │   ├── aggregate__tcp_14d.pipe
│   │   │   ├── aggregate__tcp_14d__v1.pipe
│   │   │   ├── aggregate__tcp_1d.pipe
│   │   │   ├── aggregate__tcp_1d__v1.pipe
│   │   │   ├── aggregate__tcp_30d.pipe
│   │   │   ├── aggregate__tcp_30d__v1.pipe
│   │   │   ├── aggregate__tcp_7d.pipe
│   │   │   ├── aggregate__tcp_7d__v1.pipe
│   │   │   ├── aggregate__tcp_full_14d__v0.pipe
│   │   │   ├── aggregate__tcp_full_30d__v0.pipe
│   │   │   ├── aggregate__tcp_status_45d.pipe
│   │   │   ├── aggregate__tcp_status_45d__v1.pipe
│   │   │   ├── aggregate__tcp_status_7d.pipe
│   │   │   ├── aggregate__tcp_uptime_30d__v1.pipe
│   │   │   ├── aggregate__tcp_uptime_7d__v1.pipe
│   │   │   ├── aggregate__tcp_workspace_30d__v0.pipe
│   │   │   ├── get_result_for_on_demand_check_http.pipe
│   │   │   ├── public_status.pipe
│   │   │   ├── response_details.pipe
│   │   │   ├── response_graph.pipe
│   │   │   ├── response_list.pipe
│   │   │   └── single_checks_get.pipe
│   │   ├── src/
│   │   │   ├── audit-log/
│   │   │   │   ├── README.md
│   │   │   │   ├── action-schema.ts
│   │   │   │   ├── action-validation.ts
│   │   │   │   ├── base-validation.ts
│   │   │   │   ├── client.ts
│   │   │   │   ├── examples.ts
│   │   │   │   └── index.ts
│   │   │   ├── client.ts
│   │   │   ├── index.ts
│   │   │   └── schema.ts
│   │   └── tsconfig.json
│   ├── tracker/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── blacklist.ts
│   │   │   ├── config.ts
│   │   │   ├── index.ts
│   │   │   ├── mock.ts
│   │   │   ├── tracker.ts
│   │   │   ├── types.ts
│   │   │   └── utils.ts
│   │   └── tsconfig.json
│   ├── tsconfig/
│   │   ├── base.json
│   │   ├── nextjs.json
│   │   ├── package.json
│   │   └── react-library.json
│   ├── ui/
│   │   ├── REGISTRY.md
│   │   ├── components.json
│   │   ├── package.json
│   │   ├── registry.json
│   │   ├── scripts/
│   │   │   ├── copy-to-web.mjs
│   │   │   └── transform-imports.mjs
│   │   ├── src/
│   │   │   ├── components/
│   │   │   │   ├── blocks/
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── status-banner.tsx
│   │   │   │   │   ├── status-bar.tsx
│   │   │   │   │   ├── status-blank.tsx
│   │   │   │   │   ├── status-component-group.tsx
│   │   │   │   │   ├── status-component.tsx
│   │   │   │   │   ├── status-events.tsx
│   │   │   │   │   ├── status-feed.tsx
│   │   │   │   │   ├── status-icon.tsx
│   │   │   │   │   ├── status-layout.tsx
│   │   │   │   │   ├── status-timestamp.tsx
│   │   │   │   │   ├── status.types.ts
│   │   │   │   │   └── status.utils.ts
│   │   │   │   └── ui/
│   │   │   │       ├── alert-dialog.tsx
│   │   │   │       ├── alert.tsx
│   │   │   │       ├── avatar.tsx
│   │   │   │       ├── badge.tsx
│   │   │   │       ├── breadcrumb.tsx
│   │   │   │       ├── button-group.tsx
│   │   │   │       ├── button.tsx
│   │   │   │       ├── calendar.tsx
│   │   │   │       ├── card.tsx
│   │   │   │       ├── chart.tsx
│   │   │   │       ├── checkbox.tsx
│   │   │   │       ├── collapsible.tsx
│   │   │   │       ├── command.tsx
│   │   │   │       ├── context-menu.tsx
│   │   │   │       ├── dialog.tsx
│   │   │   │       ├── dropdown-menu.tsx
│   │   │   │       ├── form.tsx
│   │   │   │       ├── hover-card.tsx
│   │   │   │       ├── input-group.tsx
│   │   │   │       ├── input.tsx
│   │   │   │       ├── kbd.tsx
│   │   │   │       ├── label.tsx
│   │   │   │       ├── popover.tsx
│   │   │   │       ├── progress.tsx
│   │   │   │       ├── qr-code.tsx
│   │   │   │       ├── radio-group.tsx
│   │   │   │       ├── select.tsx
│   │   │   │       ├── separator.tsx
│   │   │   │       ├── sheet.tsx
│   │   │   │       ├── sidebar.tsx
│   │   │   │       ├── skeleton.tsx
│   │   │   │       ├── slider.tsx
│   │   │   │       ├── sonner.tsx
│   │   │   │       ├── switch.tsx
│   │   │   │       ├── table.tsx
│   │   │   │       ├── tabs.tsx
│   │   │   │       ├── textarea.tsx
│   │   │   │       └── tooltip.tsx
│   │   │   ├── globals.css
│   │   │   ├── hooks/
│   │   │   │   ├── use-cookie-state.ts
│   │   │   │   ├── use-copy-to-clipboard.ts
│   │   │   │   ├── use-debounce-callback.ts
│   │   │   │   ├── use-debounce.ts
│   │   │   │   ├── use-media-query.ts
│   │   │   │   └── use-mobile.ts
│   │   │   └── lib/
│   │   │       ├── compose-refs.ts
│   │   │       └── utils.ts
│   │   └── tsconfig.json
│   ├── upstash/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── index.ts
│   │   │   └── redis/
│   │   │       └── client.ts
│   │   └── tsconfig.json
│   └── utils/
│       ├── index.ts
│       ├── package.json
│       └── tsconfig.json
├── pnpm-workspace.yaml
├── process-compose.yaml
├── ralph/
│   ├── .gitignore
│   ├── README.md
│   ├── afk-ralph.sh
│   └── ralph-once.sh
├── turbo.json
└── utils/
    └── api-bruno/
        ├── Monitor Summary.bru
        ├── OpenApi.bru
        ├── bruno.json
        ├── checker.bru
        ├── environments/
        │   ├── local.bru
        │   └── prod.bru
        ├── incident_update/
        │   └── Get Status Report Update.bru
        └── incidents/
            ├── All Status Reports.bru
            └── Get Status Report.bru
Download .txt
Showing preview only (404K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (4125 symbols across 1101 files)

FILE: apps/checker/checker/dns.go
  type DnsResponse (line 13) | type DnsResponse struct
  function Dns (line 22) | func Dns(ctx context.Context, host string) (*DnsResponse, error) {
  function lookupCNAME (line 70) | func lookupCNAME(domain string) (string, error) {
  function lookupMX (line 79) | func lookupMX(domain string) ([]string) {
  function lookupNS (line 90) | func lookupNS(domain string) ([]string, error) {
  function lookupTXT (line 108) | func lookupTXT(domain string) ([]string) {
  function isSubdomain (line 122) | func isSubdomain(domain string) bool {

FILE: apps/checker/checker/dns_test.go
  function TestPingDNS (line 10) | func TestPingDNS(t *testing.T) {

FILE: apps/checker/checker/http.go
  type Timing (line 21) | type Timing struct
  type Response (line 34) | type Response struct
  function decodeBase64Body (line 47) | func decodeBase64Body(body string) ([]byte, error) {
  function Http (line 56) | func Http(ctx context.Context, client *http.Client, inputData request.Ht...

FILE: apps/checker/checker/http_test.go
  type RoundTripFunc (line 17) | type RoundTripFunc
    method RoundTrip (line 20) | func (f RoundTripFunc) RoundTrip(req *http.Request) (*http.Response, e...
  function NewTestClient (line 25) | func NewTestClient(fn RoundTripFunc) *http.Client {
  function Test_ping (line 31) | func Test_ping(t *testing.T) {

FILE: apps/checker/checker/tcp.go
  type TCPData (line 10) | type TCPData struct
  type TCPResponseTiming (line 16) | type TCPResponseTiming struct
  type TCPResponse (line 21) | type TCPResponse struct
  function PingTCP (line 34) | func PingTCP(timeout int, url string) (TCPResponseTiming, error) {

FILE: apps/checker/checker/tcp_test.go
  function TestPingTcp (line 9) | func TestPingTcp(t *testing.T) {

FILE: apps/checker/checker/update.go
  type UpdateData (line 19) | type UpdateData struct
  function UpdateStatus (line 29) | func UpdateStatus(ctx context.Context, updateData UpdateData) error {

FILE: apps/checker/cmd/private/main.go
  constant configRefreshInterval (line 22) | configRefreshInterval = 10 * time.Minute
  function main (line 25) | func main() {
  function getEnv (line 62) | func getEnv(key, fallback string) string {
  function getClient (line 69) | func getClient(apiKey string) v1.PrivateLocationServiceClient {
  function NewAuthInterceptor (line 82) | func NewAuthInterceptor(token string) connect.UnaryInterceptorFunc {

FILE: apps/checker/cmd/server/main.go
  function shouldSample (line 32) | func shouldSample(event map[string]any) bool {
  function MapToAttrs (line 61) | func MapToAttrs(m map[string]any) []slog.Attr {
  function toAttr (line 69) | func toAttr(key string, value any) slog.Attr {
  function mapToAny (line 92) | func mapToAny(m map[string]any) []any {
  function Logger (line 100) | func Logger() gin.HandlerFunc {
  function main (line 158) | func main() {
  function env (line 274) | func env(key, fallback string) string {

FILE: apps/checker/handlers/checker.go
  type statusCode (line 20) | type statusCode
    method IsSuccessful (line 22) | func (s statusCode) IsSuccessful() bool {
  type PingData (line 26) | type PingData struct
  method HTTPCheckerHandler (line 47) | func (h Handler) HTTPCheckerHandler(c *gin.Context) {
  function EvaluateHTTPAssertions (line 334) | func EvaluateHTTPAssertions(raw []json.RawMessage, data PingData, res ch...

FILE: apps/checker/handlers/checker_test.go
  function TestHandler_HTTPCheckerHandler (line 21) | func TestHandler_HTTPCheckerHandler(t *testing.T) {
  function TestEvaluateAssertions_raw (line 112) | func TestEvaluateAssertions_raw(t *testing.T) {

FILE: apps/checker/handlers/dns.go
  type DNSResponse (line 20) | type DNSResponse struct
  method DNSHandler (line 41) | func (h Handler) DNSHandler(c *gin.Context) {
  method DNSHandlerRegion (line 222) | func (h Handler) DNSHandlerRegion(c *gin.Context) {
  function FormatDNSResult (line 342) | func FormatDNSResult(result *checker.DnsResponse) map[string][]string {
  function EvaluateDNSAssertions (line 376) | func EvaluateDNSAssertions(rawAssertions []json.RawMessage, response *ch...

FILE: apps/checker/handlers/dns_test.go
  type DNSResult (line 15) | type DNSResult struct
  function TestFormatDNSResult (line 24) | func TestFormatDNSResult(t *testing.T) {
  function TestEvaluateDNSAssertions (line 106) | func TestEvaluateDNSAssertions(t *testing.T) {

FILE: apps/checker/handlers/handler.go
  type Handler (line 9) | type Handler struct
  function NewHTTPClient (line 18) | func NewHTTPClient() *http.Client {

FILE: apps/checker/handlers/ping.go
  type PingResponse (line 16) | type PingResponse struct
  type Response (line 28) | type Response struct
  method PingRegionHandler (line 42) | func (h Handler) PingRegionHandler(c *gin.Context) {

FILE: apps/checker/handlers/ping_test.go
  type RoundTripFunc (line 20) | type RoundTripFunc
    method RoundTrip (line 22) | func (f RoundTripFunc) RoundTrip(req *http.Request) (*http.Response, e...
  function TestHandler_PingRegion (line 26) | func TestHandler_PingRegion(t *testing.T) {

FILE: apps/checker/handlers/tcp.go
  type TCPData (line 20) | type TCPData struct
  method TCPHandler (line 39) | func (h Handler) TCPHandler(c *gin.Context) {
  method TCPHandlerRegion (line 252) | func (h Handler) TCPHandlerRegion(c *gin.Context) {

FILE: apps/checker/pkg/assertions/assertions.go
  type BodyString (line 12) | type BodyString struct
  type StatusTarget (line 18) | type StatusTarget struct
    method StatusEvaluate (line 88) | func (target StatusTarget) StatusEvaluate(value int64) bool {
  type HeaderTarget (line 24) | type HeaderTarget struct
    method HeaderEvaluate (line 69) | func (target HeaderTarget) HeaderEvaluate(s string) bool {
  type StringTargetType (line 31) | type StringTargetType struct
    method StringEvaluate (line 42) | func (target StringTargetType) StringEvaluate(s string) bool {
  type RecordTarget (line 36) | type RecordTarget struct
    method RecordEvaluate (line 122) | func (target RecordTarget) RecordEvaluate(s []string) bool {

FILE: apps/checker/pkg/assertions/assertions_test.go
  function TestIntTarget_IntEvaluate (line 9) | func TestIntTarget_IntEvaluate(t *testing.T) {
  function TestHeaderTarget_HeaderEvaluate (line 87) | func TestHeaderTarget_HeaderEvaluate(t *testing.T) {
  function TestRecordTarget_RecordEvaluate (line 122) | func TestRecordTarget_RecordEvaluate(t *testing.T) {

FILE: apps/checker/pkg/job/dns_job.go
  type DNSPrivateRegionData (line 9) | type DNSPrivateRegionData struct
  method DNSJob (line 11) | func (jobRunner) DNSJob(ctx context.Context, monitor *v1.DNSMonitor) ( *...

FILE: apps/checker/pkg/job/http_job.go
  function ProtoNumberAssertionToComparator (line 18) | func ProtoNumberAssertionToComparator(assertion v1.NumberComparator) (re...
  function ProtoStringAssertionToComparator (line 38) | func ProtoStringAssertionToComparator(assertion v1.StringComparator) (re...
  method HTTPJob (line 56) | func (jr jobRunner) HTTPJob(ctx context.Context, monitor *v1.HTTPMonitor...

FILE: apps/checker/pkg/job/http_job_test.go
  function TestHTTPJob_Success (line 15) | func TestHTTPJob_Success(t *testing.T) {
  function TestHTTPJob_Failure (line 38) | func TestHTTPJob_Failure(t *testing.T) {
  function TestProtoStringAssertionToComparator (line 56) | func TestProtoStringAssertionToComparator(t *testing.T) {
  function TestProtoNumberAssertionToComparator (line 120) | func TestProtoNumberAssertionToComparator(t *testing.T) {

FILE: apps/checker/pkg/job/job.go
  type statusCode (line 9) | type statusCode
    method IsSuccessful (line 11) | func (s statusCode) IsSuccessful() bool {
  type HttpPrivateRegionData (line 15) | type HttpPrivateRegionData struct
  type JobRunner (line 30) | type JobRunner interface
  type jobRunner (line 36) | type jobRunner struct
  function NewJobRunner (line 38) | func NewJobRunner() JobRunner {

FILE: apps/checker/pkg/job/monitors.go
  type Monitor (line 3) | type Monitor struct
  type Header (line 22) | type Header struct
  type Assertion (line 27) | type Assertion struct
  type Timing (line 34) | type Timing struct

FILE: apps/checker/pkg/job/tcp_job.go
  type AssertionResult (line 15) | type AssertionResult struct
  type TCPPrivateRegionData (line 22) | type TCPPrivateRegionData struct
  method TCPJob (line 36) | func (jobRunner) TCPJob(ctx context.Context, monitor *v1.TCPMonitor) (*T...

FILE: apps/checker/pkg/job/tcp_job_test.go
  function TestTCPJob_Success (line 11) | func TestTCPJob_Success(t *testing.T) {
  function TestTCPJob_Failure (line 30) | func TestTCPJob_Failure(t *testing.T) {

FILE: apps/checker/pkg/logger/logger.go
  function Configure (line 8) | func Configure(logLevel string) {

FILE: apps/checker/pkg/otel/otel.go
  function setupOTelSDK (line 21) | func setupOTelSDK(ctx context.Context, url string, headers map[string]st...
  function newResource (line 37) | func newResource() (*resource.Resource, error) {
  function newMeterProvider (line 45) | func newMeterProvider(
  function withMeter (line 67) | func withMeter(ctx context.Context, endpoint string, headers map[string]...
  function recordGauge (line 84) | func recordGauge(ctx context.Context, meter metric.Meter, name, descript...
  function recordErrorCounter (line 96) | func recordErrorCounter(ctx context.Context, meter metric.Meter, att met...
  function RecordHTTPMetrics (line 106) | func RecordHTTPMetrics(ctx context.Context, req request.HttpCheckerReque...
  function RecordTCPMetrics (line 147) | func RecordTCPMetrics(ctx context.Context, req request.TCPCheckerRequest...

FILE: apps/checker/pkg/otel/otel_test.go
  function newTestMeter (line 19) | func newTestMeter(t *testing.T) (metric.Meter, *sdkMetrics.ManualReader) {
  function collectMetrics (line 29) | func collectMetrics(t *testing.T, reader *sdkMetrics.ManualReader) metri...
  function newOTLPTestServer (line 36) | func newOTLPTestServer(t *testing.T) *httptest.Server {
  function TestRecordGauge (line 47) | func TestRecordGauge(t *testing.T) {
  function TestRecordGauge_MultipleMetrics (line 77) | func TestRecordGauge_MultipleMetrics(t *testing.T) {
  function TestRecordErrorCounter (line 103) | func TestRecordErrorCounter(t *testing.T) {
  function TestSetupOTelSDK (line 125) | func TestSetupOTelSDK(t *testing.T) {
  function TestSetupOTelSDK_InvalidURL (line 135) | func TestSetupOTelSDK_InvalidURL(t *testing.T) {
  function TestWithMeter (line 149) | func TestWithMeter(t *testing.T) {
  function TestWithMeter_InvalidEndpoint (line 161) | func TestWithMeter_InvalidEndpoint(t *testing.T) {
  function TestRecordHTTPMetrics_Success (line 176) | func TestRecordHTTPMetrics_Success(t *testing.T) {
  function TestRecordHTTPMetrics_Error (line 206) | func TestRecordHTTPMetrics_Error(t *testing.T) {
  function TestRecordHTTPMetrics_SetupFailure (line 224) | func TestRecordHTTPMetrics_SetupFailure(t *testing.T) {
  function TestRecordTCPMetrics_Success (line 242) | func TestRecordTCPMetrics_Success(t *testing.T) {
  function TestRecordTCPMetrics_Error (line 263) | func TestRecordTCPMetrics_Error(t *testing.T) {
  function TestRecordTCPMetrics_SetupFailure (line 280) | func TestRecordTCPMetrics_SetupFailure(t *testing.T) {

FILE: apps/checker/pkg/scheduler/scheduler.go
  constant Interval10s (line 16) | Interval10s = "10s"
  constant Interval30s (line 17) | Interval30s = "30s"
  constant Interval1m (line 18) | Interval1m  = "1m"
  constant Interval5m (line 19) | Interval5m  = "5m"
  constant Interval10m (line 20) | Interval10m = "10m"
  constant Interval30m (line 21) | Interval30m = "30m"
  constant Interval1h (line 22) | Interval1h  = "1h"
  type MonitorManager (line 25) | type MonitorManager struct
    method UpdateMonitors (line 33) | func (mm *MonitorManager) UpdateMonitors(ctx context.Context) {
  function intervalToSecond (line 216) | func intervalToSecond(interval string) int {

FILE: apps/checker/pkg/scheduler/scheduler_test.go
  type mockJobRunner (line 19) | type mockJobRunner struct
    method HTTPJob (line 26) | func (m *mockJobRunner) HTTPJob(ctx context.Context, monitor *v1.HTTPM...
    method TCPJob (line 30) | func (m *mockJobRunner) TCPJob(ctx context.Context, monitor *v1.TCPMon...
    method DNSJob (line 36) | func (m *mockJobRunner) DNSJob(ctx context.Context, monitor *v1.DNSMon...
  type mockClient (line 42) | type mockClient struct
    method Monitors (line 49) | func (m *mockClient) Monitors(ctx context.Context, req *connect.Reques...
    method IngestHTTP (line 52) | func (m *mockClient) IngestHTTP(ctx context.Context, req *connect.Requ...
    method IngestTCP (line 55) | func (m *mockClient) IngestTCP(ctx context.Context, req *connect.Reque...
    method IngestDNS (line 58) | func (m *mockClient) IngestDNS(ctx context.Context, req *connect.Reque...
  function TestMonitorManager_StartAndStopJobs_WithJobRunner (line 62) | func TestMonitorManager_StartAndStopJobs_WithJobRunner(t *testing.T) {

FILE: apps/checker/pkg/tinybird/client.go
  function getBaseURL (line 15) | func getBaseURL() string {
  type Client (line 24) | type Client interface
  type client (line 28) | type client struct
    method SendEvent (line 42) | func (c client) SendEvent(ctx context.Context, event any, dataSourceNa...
  function NewClient (line 34) | func NewClient(httpClient *http.Client, apiKey string) Client {

FILE: apps/checker/pkg/tinybird/client_test.go
  type interceptorHTTPClient (line 12) | type interceptorHTTPClient struct
    method RoundTrip (line 16) | func (i *interceptorHTTPClient) RoundTrip(req *http.Request) (*http.Re...
    method GetHTTPClient (line 20) | func (i *interceptorHTTPClient) GetHTTPClient() *http.Client {
  function TestSendEvent (line 26) | func TestSendEvent(t *testing.T) {

FILE: apps/checker/proto/private_location/v1/assertions.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  type NumberComparator (line 24) | type NumberComparator
    method Enum (line 58) | func (x NumberComparator) Enum() *NumberComparator {
    method String (line 64) | func (x NumberComparator) String() string {
    method Descriptor (line 68) | func (NumberComparator) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 72) | func (NumberComparator) Type() protoreflect.EnumType {
    method Number (line 76) | func (x NumberComparator) Number() protoreflect.EnumNumber {
    method EnumDescriptor (line 81) | func (NumberComparator) EnumDescriptor() ([]byte, []int) {
  constant NumberComparator_NUMBER_COMPARATOR_UNSPECIFIED (line 27) | NumberComparator_NUMBER_COMPARATOR_UNSPECIFIED           NumberComparato...
  constant NumberComparator_NUMBER_COMPARATOR_EQUAL (line 28) | NumberComparator_NUMBER_COMPARATOR_EQUAL                 NumberComparato...
  constant NumberComparator_NUMBER_COMPARATOR_NOT_EQUAL (line 29) | NumberComparator_NUMBER_COMPARATOR_NOT_EQUAL             NumberComparato...
  constant NumberComparator_NUMBER_COMPARATOR_GREATER_THAN (line 30) | NumberComparator_NUMBER_COMPARATOR_GREATER_THAN          NumberComparato...
  constant NumberComparator_NUMBER_COMPARATOR_GREATER_THAN_OR_EQUAL (line 31) | NumberComparator_NUMBER_COMPARATOR_GREATER_THAN_OR_EQUAL NumberComparato...
  constant NumberComparator_NUMBER_COMPARATOR_LESS_THAN (line 32) | NumberComparator_NUMBER_COMPARATOR_LESS_THAN             NumberComparato...
  constant NumberComparator_NUMBER_COMPARATOR_LESS_THAN_OR_EQUAL (line 33) | NumberComparator_NUMBER_COMPARATOR_LESS_THAN_OR_EQUAL    NumberComparato...
  type StringComparator (line 85) | type StringComparator
    method Enum (line 131) | func (x StringComparator) Enum() *StringComparator {
    method String (line 137) | func (x StringComparator) String() string {
    method Descriptor (line 141) | func (StringComparator) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 145) | func (StringComparator) Type() protoreflect.EnumType {
    method Number (line 149) | func (x StringComparator) Number() protoreflect.EnumNumber {
    method EnumDescriptor (line 154) | func (StringComparator) EnumDescriptor() ([]byte, []int) {
  constant StringComparator_STRING_COMPARATOR_UNSPECIFIED (line 88) | StringComparator_STRING_COMPARATOR_UNSPECIFIED           StringComparato...
  constant StringComparator_STRING_COMPARATOR_CONTAINS (line 89) | StringComparator_STRING_COMPARATOR_CONTAINS              StringComparato...
  constant StringComparator_STRING_COMPARATOR_NOT_CONTAINS (line 90) | StringComparator_STRING_COMPARATOR_NOT_CONTAINS          StringComparato...
  constant StringComparator_STRING_COMPARATOR_EQUAL (line 91) | StringComparator_STRING_COMPARATOR_EQUAL                 StringComparato...
  constant StringComparator_STRING_COMPARATOR_NOT_EQUAL (line 92) | StringComparator_STRING_COMPARATOR_NOT_EQUAL             StringComparato...
  constant StringComparator_STRING_COMPARATOR_EMPTY (line 93) | StringComparator_STRING_COMPARATOR_EMPTY                 StringComparato...
  constant StringComparator_STRING_COMPARATOR_NOT_EMPTY (line 94) | StringComparator_STRING_COMPARATOR_NOT_EMPTY             StringComparato...
  constant StringComparator_STRING_COMPARATOR_GREATER_THAN (line 95) | StringComparator_STRING_COMPARATOR_GREATER_THAN          StringComparato...
  constant StringComparator_STRING_COMPARATOR_GREATER_THAN_OR_EQUAL (line 96) | StringComparator_STRING_COMPARATOR_GREATER_THAN_OR_EQUAL StringComparato...
  constant StringComparator_STRING_COMPARATOR_LESS_THAN (line 97) | StringComparator_STRING_COMPARATOR_LESS_THAN             StringComparato...
  constant StringComparator_STRING_COMPARATOR_LESS_THAN_OR_EQUAL (line 98) | StringComparator_STRING_COMPARATOR_LESS_THAN_OR_EQUAL    StringComparato...
  type RecordComparator (line 158) | type RecordComparator
    method Enum (line 186) | func (x RecordComparator) Enum() *RecordComparator {
    method String (line 192) | func (x RecordComparator) String() string {
    method Descriptor (line 196) | func (RecordComparator) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 200) | func (RecordComparator) Type() protoreflect.EnumType {
    method Number (line 204) | func (x RecordComparator) Number() protoreflect.EnumNumber {
    method EnumDescriptor (line 209) | func (RecordComparator) EnumDescriptor() ([]byte, []int) {
  constant RecordComparator_RECORD_COMPARATOR_UNSPECIFIED (line 161) | RecordComparator_RECORD_COMPARATOR_UNSPECIFIED  RecordComparator = 0
  constant RecordComparator_RECORD_COMPARATOR_EQUAL (line 162) | RecordComparator_RECORD_COMPARATOR_EQUAL        RecordComparator = 1
  constant RecordComparator_RECORD_COMPARATOR_NOT_EQUAL (line 163) | RecordComparator_RECORD_COMPARATOR_NOT_EQUAL    RecordComparator = 2
  constant RecordComparator_RECORD_COMPARATOR_CONTAINS (line 164) | RecordComparator_RECORD_COMPARATOR_CONTAINS     RecordComparator = 3
  constant RecordComparator_RECORD_COMPARATOR_NOT_CONTAINS (line 165) | RecordComparator_RECORD_COMPARATOR_NOT_CONTAINS RecordComparator = 4
  type StatusCodeAssertion (line 213) | type StatusCodeAssertion struct
    method Reset (line 221) | func (x *StatusCodeAssertion) Reset() {
    method String (line 228) | func (x *StatusCodeAssertion) String() string {
    method ProtoMessage (line 232) | func (*StatusCodeAssertion) ProtoMessage() {}
    method ProtoReflect (line 234) | func (x *StatusCodeAssertion) ProtoReflect() protoreflect.Message {
    method Descriptor (line 247) | func (*StatusCodeAssertion) Descriptor() ([]byte, []int) {
    method GetTarget (line 251) | func (x *StatusCodeAssertion) GetTarget() int64 {
    method GetComparator (line 258) | func (x *StatusCodeAssertion) GetComparator() NumberComparator {
  type BodyAssertion (line 265) | type BodyAssertion struct
    method Reset (line 273) | func (x *BodyAssertion) Reset() {
    method String (line 280) | func (x *BodyAssertion) String() string {
    method ProtoMessage (line 284) | func (*BodyAssertion) ProtoMessage() {}
    method ProtoReflect (line 286) | func (x *BodyAssertion) ProtoReflect() protoreflect.Message {
    method Descriptor (line 299) | func (*BodyAssertion) Descriptor() ([]byte, []int) {
    method GetTarget (line 303) | func (x *BodyAssertion) GetTarget() string {
    method GetComparator (line 310) | func (x *BodyAssertion) GetComparator() StringComparator {
  type HeaderAssertion (line 317) | type HeaderAssertion struct
    method Reset (line 326) | func (x *HeaderAssertion) Reset() {
    method String (line 333) | func (x *HeaderAssertion) String() string {
    method ProtoMessage (line 337) | func (*HeaderAssertion) ProtoMessage() {}
    method ProtoReflect (line 339) | func (x *HeaderAssertion) ProtoReflect() protoreflect.Message {
    method Descriptor (line 352) | func (*HeaderAssertion) Descriptor() ([]byte, []int) {
    method GetTarget (line 356) | func (x *HeaderAssertion) GetTarget() string {
    method GetComparator (line 363) | func (x *HeaderAssertion) GetComparator() StringComparator {
    method GetKey (line 370) | func (x *HeaderAssertion) GetKey() string {
  type RecordAssertion (line 377) | type RecordAssertion struct
    method Reset (line 386) | func (x *RecordAssertion) Reset() {
    method String (line 393) | func (x *RecordAssertion) String() string {
    method ProtoMessage (line 397) | func (*RecordAssertion) ProtoMessage() {}
    method ProtoReflect (line 399) | func (x *RecordAssertion) ProtoReflect() protoreflect.Message {
    method Descriptor (line 412) | func (*RecordAssertion) Descriptor() ([]byte, []int) {
    method GetRecord (line 416) | func (x *RecordAssertion) GetRecord() string {
    method GetComparator (line 423) | func (x *RecordAssertion) GetComparator() RecordComparator {
    method GetTarget (line 430) | func (x *RecordAssertion) GetTarget() string {
  constant file_private_location_v1_assertions_proto_rawDesc (line 439) | file_private_location_v1_assertions_proto_rawDesc = "" +
  function file_private_location_v1_assertions_proto_rawDescGZIP (line 497) | func file_private_location_v1_assertions_proto_rawDescGZIP() []byte {
  function init (line 527) | func init() { file_private_location_v1_assertions_proto_init() }
  function file_private_location_v1_assertions_proto_init (line 528) | func file_private_location_v1_assertions_proto_init() {

FILE: apps/checker/proto/private_location/v1/dns_monitor.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  type DNSMonitor (line 24) | type DNSMonitor struct
    method Reset (line 37) | func (x *DNSMonitor) Reset() {
    method String (line 44) | func (x *DNSMonitor) String() string {
    method ProtoMessage (line 48) | func (*DNSMonitor) ProtoMessage() {}
    method ProtoReflect (line 50) | func (x *DNSMonitor) ProtoReflect() protoreflect.Message {
    method Descriptor (line 63) | func (*DNSMonitor) Descriptor() ([]byte, []int) {
    method GetId (line 67) | func (x *DNSMonitor) GetId() string {
    method GetUri (line 74) | func (x *DNSMonitor) GetUri() string {
    method GetTimeout (line 81) | func (x *DNSMonitor) GetTimeout() int64 {
    method GetDegradedAt (line 88) | func (x *DNSMonitor) GetDegradedAt() int64 {
    method GetPeriodicity (line 95) | func (x *DNSMonitor) GetPeriodicity() string {
    method GetRetry (line 102) | func (x *DNSMonitor) GetRetry() int64 {
    method GetRecordAssertions (line 109) | func (x *DNSMonitor) GetRecordAssertions() []*RecordAssertion {
  constant file_private_location_v1_dns_monitor_proto_rawDesc (line 118) | file_private_location_v1_dns_monitor_proto_rawDesc = "" +
  function file_private_location_v1_dns_monitor_proto_rawDescGZIP (line 138) | func file_private_location_v1_dns_monitor_proto_rawDescGZIP() []byte {
  function init (line 159) | func init() { file_private_location_v1_dns_monitor_proto_init() }
  function file_private_location_v1_dns_monitor_proto_init (line 160) | func file_private_location_v1_dns_monitor_proto_init() {

FILE: apps/checker/proto/private_location/v1/http_monitor.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  type Headers (line 24) | type Headers struct
    method Reset (line 32) | func (x *Headers) Reset() {
    method String (line 39) | func (x *Headers) String() string {
    method ProtoMessage (line 43) | func (*Headers) ProtoMessage() {}
    method ProtoReflect (line 45) | func (x *Headers) ProtoReflect() protoreflect.Message {
    method Descriptor (line 58) | func (*Headers) Descriptor() ([]byte, []int) {
    method GetKey (line 62) | func (x *Headers) GetKey() string {
    method GetValue (line 69) | func (x *Headers) GetValue() string {
  type HTTPMonitor (line 76) | type HTTPMonitor struct
    method Reset (line 95) | func (x *HTTPMonitor) Reset() {
    method String (line 102) | func (x *HTTPMonitor) String() string {
    method ProtoMessage (line 106) | func (*HTTPMonitor) ProtoMessage() {}
    method ProtoReflect (line 108) | func (x *HTTPMonitor) ProtoReflect() protoreflect.Message {
    method Descriptor (line 121) | func (*HTTPMonitor) Descriptor() ([]byte, []int) {
    method GetId (line 125) | func (x *HTTPMonitor) GetId() string {
    method GetUrl (line 132) | func (x *HTTPMonitor) GetUrl() string {
    method GetPeriodicity (line 139) | func (x *HTTPMonitor) GetPeriodicity() string {
    method GetMethod (line 146) | func (x *HTTPMonitor) GetMethod() string {
    method GetBody (line 153) | func (x *HTTPMonitor) GetBody() string {
    method GetTimeout (line 160) | func (x *HTTPMonitor) GetTimeout() int64 {
    method GetDegradedAt (line 167) | func (x *HTTPMonitor) GetDegradedAt() int64 {
    method GetRetry (line 174) | func (x *HTTPMonitor) GetRetry() int64 {
    method GetFollowRedirects (line 181) | func (x *HTTPMonitor) GetFollowRedirects() bool {
    method GetHeaders (line 188) | func (x *HTTPMonitor) GetHeaders() []*Headers {
    method GetStatusCodeAssertions (line 195) | func (x *HTTPMonitor) GetStatusCodeAssertions() []*StatusCodeAssertion {
    method GetBodyAssertions (line 202) | func (x *HTTPMonitor) GetBodyAssertions() []*BodyAssertion {
    method GetHeaderAssertions (line 209) | func (x *HTTPMonitor) GetHeaderAssertions() []*HeaderAssertion {
  constant file_private_location_v1_http_monitor_proto_rawDesc (line 218) | file_private_location_v1_http_monitor_proto_rawDesc = "" +
  function file_private_location_v1_http_monitor_proto_rawDescGZIP (line 247) | func file_private_location_v1_http_monitor_proto_rawDescGZIP() []byte {
  function init (line 274) | func init() { file_private_location_v1_http_monitor_proto_init() }
  function file_private_location_v1_http_monitor_proto_init (line 275) | func file_private_location_v1_http_monitor_proto_init() {

FILE: apps/checker/proto/private_location/v1/private_location.connect.go
  constant _ (line 20) | _ = connect.IsAtLeastVersion1_13_0
  constant PrivateLocationServiceName (line 24) | PrivateLocationServiceName = "private_location.v1.PrivateLocationService"
  constant PrivateLocationServiceMonitorsProcedure (line 37) | PrivateLocationServiceMonitorsProcedure = "/private_location.v1.PrivateL...
  constant PrivateLocationServiceIngestTCPProcedure (line 40) | PrivateLocationServiceIngestTCPProcedure = "/private_location.v1.Private...
  constant PrivateLocationServiceIngestHTTPProcedure (line 43) | PrivateLocationServiceIngestHTTPProcedure = "/private_location.v1.Privat...
  constant PrivateLocationServiceIngestDNSProcedure (line 46) | PrivateLocationServiceIngestDNSProcedure = "/private_location.v1.Private...
  type PrivateLocationServiceClient (line 51) | type PrivateLocationServiceClient interface
  function NewPrivateLocationServiceClient (line 65) | func NewPrivateLocationServiceClient(httpClient connect.HTTPClient, base...
  type privateLocationServiceClient (line 97) | type privateLocationServiceClient struct
    method Monitors (line 105) | func (c *privateLocationServiceClient) Monitors(ctx context.Context, r...
    method IngestTCP (line 110) | func (c *privateLocationServiceClient) IngestTCP(ctx context.Context, ...
    method IngestHTTP (line 115) | func (c *privateLocationServiceClient) IngestHTTP(ctx context.Context,...
    method IngestDNS (line 120) | func (c *privateLocationServiceClient) IngestDNS(ctx context.Context, ...
  type PrivateLocationServiceHandler (line 126) | type PrivateLocationServiceHandler interface
  function NewPrivateLocationServiceHandler (line 138) | func NewPrivateLocationServiceHandler(svc PrivateLocationServiceHandler,...
  type UnimplementedPrivateLocationServiceHandler (line 181) | type UnimplementedPrivateLocationServiceHandler struct
    method Monitors (line 183) | func (UnimplementedPrivateLocationServiceHandler) Monitors(context.Con...
    method IngestTCP (line 187) | func (UnimplementedPrivateLocationServiceHandler) IngestTCP(context.Co...
    method IngestHTTP (line 191) | func (UnimplementedPrivateLocationServiceHandler) IngestHTTP(context.C...
    method IngestDNS (line 195) | func (UnimplementedPrivateLocationServiceHandler) IngestDNS(context.Co...

FILE: apps/checker/proto/private_location/v1/private_location.pb.go
  constant _ (line 20) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 22) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  type MonitorsRequest (line 25) | type MonitorsRequest struct
    method Reset (line 31) | func (x *MonitorsRequest) Reset() {
    method String (line 38) | func (x *MonitorsRequest) String() string {
    method ProtoMessage (line 42) | func (*MonitorsRequest) ProtoMessage() {}
    method ProtoReflect (line 44) | func (x *MonitorsRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 57) | func (*MonitorsRequest) Descriptor() ([]byte, []int) {
  type MonitorsResponse (line 61) | type MonitorsResponse struct
    method Reset (line 70) | func (x *MonitorsResponse) Reset() {
    method String (line 77) | func (x *MonitorsResponse) String() string {
    method ProtoMessage (line 81) | func (*MonitorsResponse) ProtoMessage() {}
    method ProtoReflect (line 83) | func (x *MonitorsResponse) ProtoReflect() protoreflect.Message {
    method Descriptor (line 96) | func (*MonitorsResponse) Descriptor() ([]byte, []int) {
    method GetHttpMonitors (line 100) | func (x *MonitorsResponse) GetHttpMonitors() []*HTTPMonitor {
    method GetTcpMonitors (line 107) | func (x *MonitorsResponse) GetTcpMonitors() []*TCPMonitor {
    method GetDnsMonitors (line 114) | func (x *MonitorsResponse) GetDnsMonitors() []*DNSMonitor {
  type IngestTCPRequest (line 121) | type IngestTCPRequest struct
    method Reset (line 137) | func (x *IngestTCPRequest) Reset() {
    method String (line 144) | func (x *IngestTCPRequest) String() string {
    method ProtoMessage (line 148) | func (*IngestTCPRequest) ProtoMessage() {}
    method ProtoReflect (line 150) | func (x *IngestTCPRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 163) | func (*IngestTCPRequest) Descriptor() ([]byte, []int) {
    method GetId (line 167) | func (x *IngestTCPRequest) GetId() string {
    method GetMonitorId (line 174) | func (x *IngestTCPRequest) GetMonitorId() string {
    method GetLatency (line 181) | func (x *IngestTCPRequest) GetLatency() int64 {
    method GetTimestamp (line 188) | func (x *IngestTCPRequest) GetTimestamp() int64 {
    method GetCronTimestamp (line 195) | func (x *IngestTCPRequest) GetCronTimestamp() int64 {
    method GetUri (line 202) | func (x *IngestTCPRequest) GetUri() string {
    method GetMessage (line 209) | func (x *IngestTCPRequest) GetMessage() string {
    method GetRequestStatus (line 216) | func (x *IngestTCPRequest) GetRequestStatus() string {
    method GetError (line 223) | func (x *IngestTCPRequest) GetError() int64 {
    method GetTiming (line 230) | func (x *IngestTCPRequest) GetTiming() string {
  type IngestTCPResponse (line 237) | type IngestTCPResponse struct
    method Reset (line 243) | func (x *IngestTCPResponse) Reset() {
    method String (line 250) | func (x *IngestTCPResponse) String() string {
    method ProtoMessage (line 254) | func (*IngestTCPResponse) ProtoMessage() {}
    method ProtoReflect (line 256) | func (x *IngestTCPResponse) ProtoReflect() protoreflect.Message {
    method Descriptor (line 269) | func (*IngestTCPResponse) Descriptor() ([]byte, []int) {
  type IngestHTTPRequest (line 273) | type IngestHTTPRequest struct
    method Reset (line 292) | func (x *IngestHTTPRequest) Reset() {
    method String (line 299) | func (x *IngestHTTPRequest) String() string {
    method ProtoMessage (line 303) | func (*IngestHTTPRequest) ProtoMessage() {}
    method ProtoReflect (line 305) | func (x *IngestHTTPRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 318) | func (*IngestHTTPRequest) Descriptor() ([]byte, []int) {
    method GetId (line 322) | func (x *IngestHTTPRequest) GetId() string {
    method GetMonitorId (line 329) | func (x *IngestHTTPRequest) GetMonitorId() string {
    method GetLatency (line 336) | func (x *IngestHTTPRequest) GetLatency() int64 {
    method GetTimestamp (line 343) | func (x *IngestHTTPRequest) GetTimestamp() int64 {
    method GetCronTimestamp (line 350) | func (x *IngestHTTPRequest) GetCronTimestamp() int64 {
    method GetUrl (line 357) | func (x *IngestHTTPRequest) GetUrl() string {
    method GetRequestStatus (line 364) | func (x *IngestHTTPRequest) GetRequestStatus() string {
    method GetMessage (line 371) | func (x *IngestHTTPRequest) GetMessage() string {
    method GetBody (line 378) | func (x *IngestHTTPRequest) GetBody() string {
    method GetHeaders (line 385) | func (x *IngestHTTPRequest) GetHeaders() string {
    method GetTiming (line 392) | func (x *IngestHTTPRequest) GetTiming() string {
    method GetStatusCode (line 399) | func (x *IngestHTTPRequest) GetStatusCode() int64 {
    method GetError (line 406) | func (x *IngestHTTPRequest) GetError() int64 {
  type IngestHTTPResponse (line 413) | type IngestHTTPResponse struct
    method Reset (line 419) | func (x *IngestHTTPResponse) Reset() {
    method String (line 426) | func (x *IngestHTTPResponse) String() string {
    method ProtoMessage (line 430) | func (*IngestHTTPResponse) ProtoMessage() {}
    method ProtoReflect (line 432) | func (x *IngestHTTPResponse) ProtoReflect() protoreflect.Message {
    method Descriptor (line 445) | func (*IngestHTTPResponse) Descriptor() ([]byte, []int) {
  type Records (line 449) | type Records struct
    method Reset (line 456) | func (x *Records) Reset() {
    method String (line 463) | func (x *Records) String() string {
    method ProtoMessage (line 467) | func (*Records) ProtoMessage() {}
    method ProtoReflect (line 469) | func (x *Records) ProtoReflect() protoreflect.Message {
    method Descriptor (line 482) | func (*Records) Descriptor() ([]byte, []int) {
    method GetRecord (line 486) | func (x *Records) GetRecord() []string {
  type IngestDNSRequest (line 493) | type IngestDNSRequest struct
    method Reset (line 510) | func (x *IngestDNSRequest) Reset() {
    method String (line 517) | func (x *IngestDNSRequest) String() string {
    method ProtoMessage (line 521) | func (*IngestDNSRequest) ProtoMessage() {}
    method ProtoReflect (line 523) | func (x *IngestDNSRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 536) | func (*IngestDNSRequest) Descriptor() ([]byte, []int) {
    method GetId (line 540) | func (x *IngestDNSRequest) GetId() string {
    method GetMonitorId (line 547) | func (x *IngestDNSRequest) GetMonitorId() string {
    method GetLatency (line 554) | func (x *IngestDNSRequest) GetLatency() int64 {
    method GetTimestamp (line 561) | func (x *IngestDNSRequest) GetTimestamp() int64 {
    method GetCronTimestamp (line 568) | func (x *IngestDNSRequest) GetCronTimestamp() int64 {
    method GetUri (line 575) | func (x *IngestDNSRequest) GetUri() string {
    method GetRequestStatus (line 582) | func (x *IngestDNSRequest) GetRequestStatus() string {
    method GetMessage (line 589) | func (x *IngestDNSRequest) GetMessage() string {
    method GetRecords (line 596) | func (x *IngestDNSRequest) GetRecords() map[string]*Records {
    method GetTiming (line 603) | func (x *IngestDNSRequest) GetTiming() string {
    method GetError (line 610) | func (x *IngestDNSRequest) GetError() int64 {
  type IngestDNSResponse (line 617) | type IngestDNSResponse struct
    method Reset (line 623) | func (x *IngestDNSResponse) Reset() {
    method String (line 630) | func (x *IngestDNSResponse) String() string {
    method ProtoMessage (line 634) | func (*IngestDNSResponse) ProtoMessage() {}
    method ProtoReflect (line 636) | func (x *IngestDNSResponse) ProtoReflect() protoreflect.Message {
    method Descriptor (line 649) | func (*IngestDNSResponse) Descriptor() ([]byte, []int) {
  constant file_private_location_v1_private_location_proto_rawDesc (line 655) | file_private_location_v1_private_location_proto_rawDesc = "" +
  function file_private_location_v1_private_location_proto_rawDescGZIP (line 725) | func file_private_location_v1_private_location_proto_rawDescGZIP() []byte {
  function init (line 769) | func init() { file_private_location_v1_private_location_proto_init() }
  function file_private_location_v1_private_location_proto_init (line 770) | func file_private_location_v1_private_location_proto_init() {

FILE: apps/checker/proto/private_location/v1/tcp_monitor.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  type TCPMonitor (line 24) | type TCPMonitor struct
    method Reset (line 36) | func (x *TCPMonitor) Reset() {
    method String (line 43) | func (x *TCPMonitor) String() string {
    method ProtoMessage (line 47) | func (*TCPMonitor) ProtoMessage() {}
    method ProtoReflect (line 49) | func (x *TCPMonitor) ProtoReflect() protoreflect.Message {
    method Descriptor (line 62) | func (*TCPMonitor) Descriptor() ([]byte, []int) {
    method GetId (line 66) | func (x *TCPMonitor) GetId() string {
    method GetUri (line 73) | func (x *TCPMonitor) GetUri() string {
    method GetTimeout (line 80) | func (x *TCPMonitor) GetTimeout() int64 {
    method GetDegradedAt (line 87) | func (x *TCPMonitor) GetDegradedAt() int64 {
    method GetPeriodicity (line 94) | func (x *TCPMonitor) GetPeriodicity() string {
    method GetRetry (line 101) | func (x *TCPMonitor) GetRetry() int64 {
  constant file_private_location_v1_tcp_monitor_proto_rawDesc (line 110) | file_private_location_v1_tcp_monitor_proto_rawDesc = "" +
  function file_private_location_v1_tcp_monitor_proto_rawDescGZIP (line 129) | func file_private_location_v1_tcp_monitor_proto_rawDescGZIP() []byte {
  function init (line 148) | func init() { file_private_location_v1_tcp_monitor_proto_init() }
  function file_private_location_v1_tcp_monitor_proto_init (line 149) | func file_private_location_v1_tcp_monitor_proto_init() {

FILE: apps/checker/request/request.go
  type AssertionType (line 7) | type AssertionType
  constant AssertionHeader (line 10) | AssertionHeader    AssertionType = "header"
  constant AssertionTextBody (line 11) | AssertionTextBody  AssertionType = "textBody"
  constant AssertionStatus (line 12) | AssertionStatus    AssertionType = "status"
  constant AssertionJsonBody (line 13) | AssertionJsonBody  AssertionType = "jsonBody"
  constant AssertionDnsRecord (line 14) | AssertionDnsRecord AssertionType = "dnsRecord"
  type StringComparator (line 17) | type StringComparator
  constant StringContains (line 20) | StringContains         StringComparator = "contains"
  constant StringNotContains (line 21) | StringNotContains      StringComparator = "not_contains"
  constant StringEquals (line 22) | StringEquals           StringComparator = "eq"
  constant StringNotEquals (line 23) | StringNotEquals        StringComparator = "not_eq"
  constant StringEmpty (line 24) | StringEmpty            StringComparator = "empty"
  constant StringNotEmpty (line 25) | StringNotEmpty         StringComparator = "not_empty"
  constant StringGreaterThan (line 26) | StringGreaterThan      StringComparator = "gt"
  constant StringGreaterThanEqual (line 27) | StringGreaterThanEqual StringComparator = "gte"
  constant StringLowerThan (line 28) | StringLowerThan        StringComparator = "lt"
  constant StringLowerThanEqual (line 29) | StringLowerThanEqual   StringComparator = "lte"
  type NumberComparator (line 32) | type NumberComparator
  constant NumberEquals (line 35) | NumberEquals           NumberComparator = "eq"
  constant NumberNotEquals (line 36) | NumberNotEquals        NumberComparator = "not_eq"
  constant NumberGreaterThan (line 37) | NumberGreaterThan      NumberComparator = "gt"
  constant NumberGreaterThanEqual (line 38) | NumberGreaterThanEqual NumberComparator = "gte"
  constant NumberLowerThan (line 39) | NumberLowerThan        NumberComparator = "lt"
  constant NumberLowerThanEqual (line 40) | NumberLowerThanEqual   NumberComparator = "lte"
  type RecordComparator (line 43) | type RecordComparator
  constant RecordEquals (line 46) | RecordEquals      RecordComparator = "eq"
  constant RecordNotEquals (line 47) | RecordNotEquals   RecordComparator = "not_eq"
  constant RecordContains (line 48) | RecordContains    RecordComparator = "contains"
  constant RecordNotContains (line 49) | RecordNotContains RecordComparator = "not_contains"
  type Record (line 52) | type Record
  constant RecordA (line 55) | RecordA     Record = "A"
  constant RecordAAAA (line 56) | RecordAAAA  Record = "AAAA"
  constant RecordCNAME (line 57) | RecordCNAME Record = "CNAME"
  constant RecordMX (line 58) | RecordMX    Record = "MX"
  constant RecordNS (line 59) | RecordNS    Record = "NS"
  constant RecordTXT (line 60) | RecordTXT   Record = "TXT"
  type Assertion (line 63) | type Assertion struct
  type HttpCheckerRequest (line 69) | type HttpCheckerRequest struct
  type TCPCheckerRequest (line 93) | type TCPCheckerRequest struct
  type TCPRequest (line 111) | type TCPRequest struct
  type PingRequest (line 119) | type PingRequest struct
  type DNSCheckerRequest (line 128) | type DNSCheckerRequest struct

FILE: apps/dashboard/sentry.edge.config.ts
  constant IGNORED_TRPC_CODES (line 9) | const IGNORED_TRPC_CODES: TRPCError["code"][] = [
  method beforeSend (line 25) | beforeSend(event, hint) {

FILE: apps/dashboard/sentry.server.config.ts
  constant IGNORED_TRPC_CODES (line 9) | const IGNORED_TRPC_CODES: TRPCError["code"][] = [
  method beforeSend (line 25) | beforeSend(event, hint) {

FILE: apps/dashboard/src/app/(dashboard)/agents/breadcrumb.tsx
  function Breadcrumb (line 6) | function Breadcrumb() {

FILE: apps/dashboard/src/app/(dashboard)/agents/layout.tsx
  function Layout (line 11) | function Layout({ children }: { children: React.ReactNode }) {

FILE: apps/dashboard/src/app/(dashboard)/agents/nav-actions.tsx
  function NavActions (line 11) | function NavActions() {

FILE: apps/dashboard/src/app/(dashboard)/agents/page.tsx
  function Page (line 40) | function Page() {

FILE: apps/dashboard/src/app/(dashboard)/cli/breadcrumb.tsx
  function Breadcrumb (line 6) | function Breadcrumb() {

FILE: apps/dashboard/src/app/(dashboard)/cli/layout.tsx
  function Layout (line 11) | function Layout({ children }: { children: React.ReactNode }) {

FILE: apps/dashboard/src/app/(dashboard)/cli/nav-actions.tsx
  function NavActions (line 11) | function NavActions() {

FILE: apps/dashboard/src/app/(dashboard)/cli/page.tsx
  function Page (line 131) | function Page() {

FILE: apps/dashboard/src/app/(dashboard)/invite/client.tsx
  function Client (line 19) | function Client() {

FILE: apps/dashboard/src/app/(dashboard)/invite/layout.tsx
  function Layout (line 10) | function Layout({ children }: { children: React.ReactNode }) {

FILE: apps/dashboard/src/app/(dashboard)/invite/nav-actions.tsx
  function NavActions (line 3) | function NavActions() {

FILE: apps/dashboard/src/app/(dashboard)/invite/page.tsx
  function InvitePage (line 7) | async function InvitePage(props: {

FILE: apps/dashboard/src/app/(dashboard)/layout.tsx
  function Layout (line 9) | async function Layout({
  function HydrateSidebar (line 30) | async function HydrateSidebar({ children }: { children: React.ReactNode ...

FILE: apps/dashboard/src/app/(dashboard)/monitors/(list)/breadcrumb.tsx
  function Breadcrumb (line 6) | function Breadcrumb() {

FILE: apps/dashboard/src/app/(dashboard)/monitors/(list)/client.tsx
  function Client (line 43) | function Client() {

FILE: apps/dashboard/src/app/(dashboard)/monitors/(list)/layout.tsx
  function Layout (line 10) | function Layout({ children }: { children: React.ReactNode }) {

FILE: apps/dashboard/src/app/(dashboard)/monitors/(list)/nav-actions.tsx
  function NavActions (line 11) | function NavActions() {

FILE: apps/dashboard/src/app/(dashboard)/monitors/(list)/page.tsx
  function Page (line 6) | async function Page({

FILE: apps/dashboard/src/app/(dashboard)/monitors/(list)/search-params.ts
  method parse (line 8) | parse(queryValue) {
  method serialize (line 13) | serialize(value) {

FILE: apps/dashboard/src/app/(dashboard)/monitors/[id]/breadcrumb.tsx
  function Breadcrumb (line 10) | function Breadcrumb() {

FILE: apps/dashboard/src/app/(dashboard)/monitors/[id]/constants.ts
  constant MONITOR_TABS (line 4) | const MONITOR_TABS: {

FILE: apps/dashboard/src/app/(dashboard)/monitors/[id]/edit/layout.tsx
  function Layout (line 3) | async function Layout({

FILE: apps/dashboard/src/app/(dashboard)/monitors/[id]/edit/page.tsx
  function Page (line 15) | function Page() {

FILE: apps/dashboard/src/app/(dashboard)/monitors/[id]/incidents/layout.tsx
  function Layout (line 5) | async function Layout({

FILE: apps/dashboard/src/app/(dashboard)/monitors/[id]/incidents/page.tsx
  function Page (line 22) | function Page() {

FILE: apps/dashboard/src/app/(dashboard)/monitors/[id]/layout.tsx
  function Layout (line 12) | async function Layout({

FILE: apps/dashboard/src/app/(dashboard)/monitors/[id]/logs/client.tsx
  function Client (line 38) | function Client() {
  function BillingPlaceholder (line 153) | function BillingPlaceholder() {

FILE: apps/dashboard/src/app/(dashboard)/monitors/[id]/logs/page.tsx
  function Page (line 5) | async function Page({

FILE: apps/dashboard/src/app/(dashboard)/monitors/[id]/nav-actions.tsx
  type TestTCP (line 24) | type TestTCP = RouterOutputs["checker"]["testTcp"];
  type TestHTTP (line 25) | type TestHTTP = RouterOutputs["checker"]["testHttp"];
  type TestDNS (line 26) | type TestDNS = RouterOutputs["checker"]["testDns"];
  function NavActions (line 28) | function NavActions() {

FILE: apps/dashboard/src/app/(dashboard)/monitors/[id]/overview/client.tsx
  constant TIMELINE_INTERVAL (line 44) | const TIMELINE_INTERVAL = 30;
  function Client (line 46) | function Client() {

FILE: apps/dashboard/src/app/(dashboard)/monitors/[id]/overview/layout.tsx
  function Layout (line 4) | function Layout({ children }: { children: React.ReactNode }) {

FILE: apps/dashboard/src/app/(dashboard)/monitors/[id]/overview/page.tsx
  function Page (line 5) | async function Page({

FILE: apps/dashboard/src/app/(dashboard)/monitors/[id]/overview/search-params.ts
  constant PERIOD (line 10) | const PERIOD = ["1d", "7d", "14d"] as const;
  constant PERCENTILE (line 11) | const PERCENTILE = ["p50", "p75", "p90", "p95", "p99"] as const;

FILE: apps/dashboard/src/app/(dashboard)/monitors/[id]/page.tsx
  function Page (line 3) | async function Page({

FILE: apps/dashboard/src/app/(dashboard)/monitors/[id]/sidebar.tsx
  function Sidebar (line 14) | function Sidebar() {

FILE: apps/dashboard/src/app/(dashboard)/monitors/[id]/tabs.tsx
  function Tabs (line 7) | function Tabs() {

FILE: apps/dashboard/src/app/(dashboard)/monitors/create/breadcrumb.tsx
  function Breadcrumb (line 6) | function Breadcrumb() {

FILE: apps/dashboard/src/app/(dashboard)/monitors/create/layout.tsx
  function Layout (line 5) | function Layout({ children }: { children: React.ReactNode }) {

FILE: apps/dashboard/src/app/(dashboard)/monitors/create/page.tsx
  function Page (line 19) | function Page() {

FILE: apps/dashboard/src/app/(dashboard)/notifications/breadcrumb.tsx
  function Breadcrumb (line 6) | function Breadcrumb() {

FILE: apps/dashboard/src/app/(dashboard)/notifications/client.tsx
  constant BASE_URL (line 32) | const BASE_URL =
  function Client (line 37) | function Client() {

FILE: apps/dashboard/src/app/(dashboard)/notifications/layout.tsx
  function Layout (line 11) | async function Layout({

FILE: apps/dashboard/src/app/(dashboard)/notifications/nav-actions.tsx
  function NavActions (line 3) | function NavActions() {

FILE: apps/dashboard/src/app/(dashboard)/notifications/page.tsx
  function Page (line 5) | async function Page({

FILE: apps/dashboard/src/app/(dashboard)/onboarding/client.tsx
  function Client (line 90) | function Client() {

FILE: apps/dashboard/src/app/(dashboard)/onboarding/layout.tsx
  function Layout (line 10) | function Layout({ children }: { children: React.ReactNode }) {

FILE: apps/dashboard/src/app/(dashboard)/onboarding/nav-actions.tsx
  function NavActions (line 3) | function NavActions() {

FILE: apps/dashboard/src/app/(dashboard)/onboarding/page.tsx
  function Page (line 6) | async function Page({

FILE: apps/dashboard/src/app/(dashboard)/onboarding/search-params.ts
  constant STEPS (line 7) | const STEPS = ["1", "2", "next"] as const;

FILE: apps/dashboard/src/app/(dashboard)/overview/breadcrumb.tsx
  function Breadcrumb (line 6) | function Breadcrumb() {

FILE: apps/dashboard/src/app/(dashboard)/overview/data-table-status-reports.tsx
  type StatusReport (line 8) | type StatusReport = RouterOutputs["statusReport"]["list"][number];
  function DataTableStatusReports (line 10) | function DataTableStatusReports({

FILE: apps/dashboard/src/app/(dashboard)/overview/layout.tsx
  function Layout (line 12) | async function Layout({

FILE: apps/dashboard/src/app/(dashboard)/overview/nav-actions.tsx
  function NavActions (line 3) | function NavActions() {

FILE: apps/dashboard/src/app/(dashboard)/overview/page.tsx
  function Page (line 38) | function Page() {

FILE: apps/dashboard/src/app/(dashboard)/page.tsx
  function Page (line 3) | function Page() {

FILE: apps/dashboard/src/app/(dashboard)/private-locations/breadcrumb.tsx
  function Breadcrumb (line 6) | function Breadcrumb() {

FILE: apps/dashboard/src/app/(dashboard)/private-locations/client.tsx
  constant EXAMPLES (line 25) | const EXAMPLES = [
  function Client (line 50) | function Client() {

FILE: apps/dashboard/src/app/(dashboard)/private-locations/layout.tsx
  function Layout (line 11) | async function Layout({

FILE: apps/dashboard/src/app/(dashboard)/private-locations/nav-actions.tsx
  function NavActions (line 11) | function NavActions() {

FILE: apps/dashboard/src/app/(dashboard)/private-locations/page.tsx
  function Page (line 3) | async function Page() {

FILE: apps/dashboard/src/app/(dashboard)/settings/(list)/layout.tsx
  function Layout (line 11) | function Layout({ children }: { children: React.ReactNode }) {

FILE: apps/dashboard/src/app/(dashboard)/settings/(list)/nav-actions.tsx
  function NavActions (line 3) | function NavActions() {

FILE: apps/dashboard/src/app/(dashboard)/settings/(list)/page.tsx
  function Page (line 39) | function Page() {

FILE: apps/dashboard/src/app/(dashboard)/settings/account/breadcrumb.tsx
  function Breadcrumb (line 6) | function Breadcrumb() {

FILE: apps/dashboard/src/app/(dashboard)/settings/account/layout.tsx
  function Layout (line 13) | async function Layout({

FILE: apps/dashboard/src/app/(dashboard)/settings/account/nav-actions.tsx
  function NavActions (line 3) | function NavActions() {

FILE: apps/dashboard/src/app/(dashboard)/settings/account/page.tsx
  function Page (line 31) | function Page() {

FILE: apps/dashboard/src/app/(dashboard)/settings/billing/breadcrumb.tsx
  function Breadcrumb (line 6) | function Breadcrumb() {

FILE: apps/dashboard/src/app/(dashboard)/settings/billing/client.tsx
  constant BASE_URL (line 39) | const BASE_URL =
  function calculateTotalRequests (line 44) | function calculateTotalRequests(limits: Limits) {
  function Client (line 76) | function Client() {

FILE: apps/dashboard/src/app/(dashboard)/settings/billing/layout.tsx
  function Layout (line 12) | function Layout({ children }: { children: React.ReactNode }) {

FILE: apps/dashboard/src/app/(dashboard)/settings/billing/nav-actions.tsx
  function NavActions (line 3) | function NavActions() {

FILE: apps/dashboard/src/app/(dashboard)/settings/billing/page.tsx
  function Page (line 5) | async function Page({

FILE: apps/dashboard/src/app/(dashboard)/settings/general/breadcrumb.tsx
  function Breadcrumb (line 6) | function Breadcrumb() {

FILE: apps/dashboard/src/app/(dashboard)/settings/general/layout.tsx
  function Layout (line 13) | async function Layout({

FILE: apps/dashboard/src/app/(dashboard)/settings/general/nav-actions.tsx
  function NavActions (line 3) | function NavActions() {

FILE: apps/dashboard/src/app/(dashboard)/settings/general/page.tsx
  constant BASE_URL (line 18) | const BASE_URL = "https://app.openstatus.dev/invite";
  function Page (line 20) | function Page() {

FILE: apps/dashboard/src/app/(dashboard)/settings/integrations/breadcrumb.tsx
  function Breadcrumb (line 6) | function Breadcrumb() {

FILE: apps/dashboard/src/app/(dashboard)/settings/integrations/layout.tsx
  function Layout (line 13) | async function Layout({

FILE: apps/dashboard/src/app/(dashboard)/settings/integrations/nav-actions.tsx
  function NavActions (line 3) | function NavActions() {

FILE: apps/dashboard/src/app/(dashboard)/settings/integrations/page.tsx
  function Page (line 15) | function Page() {

FILE: apps/dashboard/src/app/(dashboard)/settings/integrations/slack-card.tsx
  constant SERVER_URL (line 21) | const SERVER_URL =
  type SlackIntegrationCardProps (line 26) | interface SlackIntegrationCardProps {
  function SlackIntegrationCard (line 35) | function SlackIntegrationCard({

FILE: apps/dashboard/src/app/(dashboard)/settings/tabs.tsx
  function Tabs (line 6) | function Tabs() {

FILE: apps/dashboard/src/app/(dashboard)/status-pages/(list)/breadcrumb.tsx
  function Breadcrumb (line 6) | function Breadcrumb() {

FILE: apps/dashboard/src/app/(dashboard)/status-pages/(list)/client.tsx
  function Client (line 18) | function Client() {

FILE: apps/dashboard/src/app/(dashboard)/status-pages/(list)/layout.tsx
  function Layout (line 11) | function Layout({ children }: { children: React.ReactNode }) {

FILE: apps/dashboard/src/app/(dashboard)/status-pages/(list)/nav-actions.tsx
  function NavActions (line 11) | function NavActions() {

FILE: apps/dashboard/src/app/(dashboard)/status-pages/(list)/page.tsx
  function Page (line 4) | async function Page() {

FILE: apps/dashboard/src/app/(dashboard)/status-pages/[id]/breadcrumb.tsx
  function Breadcrumb (line 10) | function Breadcrumb() {

FILE: apps/dashboard/src/app/(dashboard)/status-pages/[id]/components/layout.tsx
  function Layout (line 5) | async function Layout({

FILE: apps/dashboard/src/app/(dashboard)/status-pages/[id]/components/page.tsx
  function Page (line 15) | function Page() {

FILE: apps/dashboard/src/app/(dashboard)/status-pages/[id]/constants.ts
  constant STATUS_PAGE_TABS (line 4) | const STATUS_PAGE_TABS: {

FILE: apps/dashboard/src/app/(dashboard)/status-pages/[id]/edit/page.tsx
  function Page (line 15) | function Page() {

FILE: apps/dashboard/src/app/(dashboard)/status-pages/[id]/layout.tsx
  function Layout (line 15) | async function Layout({

FILE: apps/dashboard/src/app/(dashboard)/status-pages/[id]/maintenances/layout.tsx
  function Layout (line 5) | async function Layout({

FILE: apps/dashboard/src/app/(dashboard)/status-pages/[id]/maintenances/page.tsx
  function Page (line 21) | function Page() {

FILE: apps/dashboard/src/app/(dashboard)/status-pages/[id]/nav-actions.tsx
  function NavActions (line 19) | function NavActions() {

FILE: apps/dashboard/src/app/(dashboard)/status-pages/[id]/page.tsx
  function Page (line 3) | async function Page({

FILE: apps/dashboard/src/app/(dashboard)/status-pages/[id]/sidebar.tsx
  function Sidebar (line 18) | function Sidebar() {

FILE: apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/[reportId]/layout.tsx
  function Layout (line 3) | async function Layout({

FILE: apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/[reportId]/page.tsx
  function Page (line 27) | function Page() {

FILE: apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/layout.tsx
  function Layout (line 5) | async function Layout({

FILE: apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/page.tsx
  function Page (line 22) | function Page() {

FILE: apps/dashboard/src/app/(dashboard)/status-pages/[id]/subscribers/layout.tsx
  function Layout (line 3) | async function Layout({

FILE: apps/dashboard/src/app/(dashboard)/status-pages/[id]/subscribers/page.tsx
  type Subscriber (line 33) | type Subscriber = RouterOutputs["pageSubscriber"]["list"][number];
  constant EXAMPLES (line 35) | const EXAMPLES = [
  function Page (line 62) | function Page() {

FILE: apps/dashboard/src/app/(dashboard)/status-pages/[id]/tabs.tsx
  function Tabs (line 7) | function Tabs() {

FILE: apps/dashboard/src/app/(dashboard)/status-pages/create/breadcrumb.tsx
  function Breadcrumb (line 6) | function Breadcrumb() {

FILE: apps/dashboard/src/app/(dashboard)/status-pages/create/client.tsx
  function Client (line 20) | function Client() {

FILE: apps/dashboard/src/app/(dashboard)/status-pages/create/layout.tsx
  function Layout (line 6) | function Layout({ children }: { children: React.ReactNode }) {

FILE: apps/dashboard/src/app/(dashboard)/status-pages/create/page.tsx
  function Page (line 3) | function Page() {

FILE: apps/dashboard/src/app/global-error.tsx
  function GlobalError (line 7) | function GlobalError({

FILE: apps/dashboard/src/app/layout.tsx
  function RootLayout (line 75) | async function RootLayout({

FILE: apps/dashboard/src/app/login/_components/actions.ts
  function signInWithResendAction (line 5) | async function signInWithResendAction(formData: FormData) {

FILE: apps/dashboard/src/app/login/_components/magic-link-form.tsx
  function MagicLinkForm (line 14) | function MagicLinkForm() {

FILE: apps/dashboard/src/app/login/layout.tsx
  function Layout (line 6) | async function Layout({

FILE: apps/dashboard/src/app/login/page.tsx
  function Page (line 26) | async function Page(props: {

FILE: apps/dashboard/src/app/metadata.ts
  constant TITLE (line 3) | const TITLE = "openstatus";
  constant DESCRIPTION (line 4) | const DESCRIPTION =
  constant OG_TITLE (line 7) | const OG_TITLE = "openstatus";
  constant OG_DESCRIPTION (line 8) | const OG_DESCRIPTION = "Monitor your services and keep your users inform...
  constant FOOTER (line 9) | const FOOTER = "app.openstatus.dev";
  constant IMAGE (line 10) | const IMAGE = "assets/og/dashboard-v2.png";

FILE: apps/dashboard/src/app/not-found.tsx
  function NotFound (line 8) | function NotFound() {

FILE: apps/dashboard/src/app/react-table.d.ts
  type ColumnMeta (line 4) | interface ColumnMeta {

FILE: apps/dashboard/src/app/robots.ts
  function robots (line 3) | function robots(): MetadataRoute.Robots {

FILE: apps/dashboard/src/components/chart/chart-area-latency.tsx
  function ChartAreaLatency (line 37) | function ChartAreaLatency({

FILE: apps/dashboard/src/components/chart/chart-area-timing-phases.tsx
  function ChartAreaTimingPhases (line 58) | function ChartAreaTimingPhases({

FILE: apps/dashboard/src/components/chart/chart-bar-uptime-light.tsx
  function ChartBarUptimeLight (line 33) | function ChartBarUptimeLight({

FILE: apps/dashboard/src/components/chart/chart-bar-uptime.tsx
  function ChartBarUptime (line 39) | function ChartBarUptime({

FILE: apps/dashboard/src/components/chart/chart-line-region.tsx
  type TrendPoint (line 21) | type TrendPoint = {
  function ChartLineRegion (line 26) | function ChartLineRegion({

FILE: apps/dashboard/src/components/chart/chart-line-regions.tsx
  function getChartConfig (line 21) | function getChartConfig(privateLocations?: PrivateLocation[]) {
  type TrendPoint (line 45) | type TrendPoint = {
  function ChartLineRegions (line 50) | function ChartLineRegions({

FILE: apps/dashboard/src/components/chart/chart-tooltip-number.tsx
  type ChartTooltipNumberProps (line 8) | interface ChartTooltipNumberProps {
  function ChartTooltipNumber (line 14) | function ChartTooltipNumber({
  function ChartTooltipNumberRaw (line 32) | function ChartTooltipNumberRaw({

FILE: apps/dashboard/src/components/common/code.tsx
  function Code (line 8) | function Code({

FILE: apps/dashboard/src/components/common/hover-card-timestamp.tsx
  type HoverCardContentProps (line 17) | type HoverCardContentProps = ComponentPropsWithoutRef<typeof HoverCardCo...
  type HoverCardTimestampProps (line 19) | interface HoverCardTimestampProps {
  function HoverCardTimestamp (line 28) | function HoverCardTimestamp({
  function Row (line 62) | function Row({ value, label }: { value: string; label: string }) {

FILE: apps/dashboard/src/components/common/icon-cloud-provider.tsx
  function IconCloudProvider (line 11) | function IconCloudProvider({
  function IconCloudProviderTooltip (line 29) | function IconCloudProviderTooltip(

FILE: apps/dashboard/src/components/common/input-with-addons.tsx
  type InputWithAddonsProps (line 6) | interface InputWithAddonsProps

FILE: apps/dashboard/src/components/common/kbd.tsx
  function Kbd (line 21) | function Kbd({

FILE: apps/dashboard/src/components/common/link.tsx
  function Link (line 6) | function Link({

FILE: apps/dashboard/src/components/common/note.tsx
  function Note (line 33) | function Note({
  function NoteButton (line 52) | function NoteButton({

FILE: apps/dashboard/src/components/common/wheel-picker.tsx
  type WheelPickerContextValue (line 10) | interface WheelPickerContextValue {
  type WheelPickerProps (line 37) | interface WheelPickerProps extends React.HTMLAttributes<HTMLDivElement> {
  type WheelPickerSelectProps (line 91) | type WheelPickerSelectProps = React.HTMLAttributes<HTMLDivElement>;
  type WheelPickerOptionsProps (line 167) | type WheelPickerOptionsProps = React.HTMLAttributes<HTMLDivElement>;
  type PlaceholderPosition (line 249) | type PlaceholderPosition = "first" | "last";
  type WheelPickerEmptyProps (line 251) | interface WheelPickerEmptyProps

FILE: apps/dashboard/src/components/content/action-card.tsx
  function ActionCard (line 11) | function ActionCard({
  function ActionCardHeader (line 26) | function ActionCardHeader({
  function ActionCardGroup (line 38) | function ActionCardGroup({
  function ActionCardTitle (line 50) | function ActionCardTitle({
  function ActionCardDescription (line 57) | function ActionCardDescription({
  function ActionCardContent (line 64) | function ActionCardContent({
  function ActionCardFooter (line 76) | function ActionCardFooter({

FILE: apps/dashboard/src/components/content/billing-addons.tsx
  type Workspace (line 29) | type Workspace = RouterOutputs["workspace"]["get"];
  type BillingAddonsProps (line 31) | interface BillingAddonsProps {
  type PriceConfig (line 38) | interface PriceConfig {
  function BillingAddons (line 44) | function BillingAddons({
  function formatPrice (line 185) | function formatPrice(price: PriceConfig | null) {
  function getButtonLabel (line 193) | function getButtonLabel(
  function getDialogDescription (line 212) | function getDialogDescription(
  function QuantityControl (line 235) | function QuantityControl({

FILE: apps/dashboard/src/components/content/billing-overlay.tsx
  function BillingOverlayContainer (line 4) | function BillingOverlayContainer({
  function BillingOverlay (line 16) | function BillingOverlay({
  function BillingOverlayButton (line 34) | function BillingOverlayButton({
  function BillingOverlayDescription (line 45) | function BillingOverlayDescription({

FILE: apps/dashboard/src/components/content/billing-progress.tsx
  type BillingProgressProps (line 3) | interface BillingProgressProps {
  function BillingProgress (line 9) | function BillingProgress({ label, value, max }: BillingProgressProps) {

FILE: apps/dashboard/src/components/content/block-wrapper.tsx
  function BlockWrapper (line 13) | function BlockWrapper({

FILE: apps/dashboard/src/components/content/empty-state.tsx
  function EmptyStateContainer (line 3) | function EmptyStateContainer({
  function EmptyStateTitle (line 21) | function EmptyStateTitle({
  function EmptyStateDescription (line 33) | function EmptyStateDescription({

FILE: apps/dashboard/src/components/content/process-message.tsx
  function ProcessMessage (line 9) | function ProcessMessage({ value }: { value: string }) {

FILE: apps/dashboard/src/components/content/section.tsx
  function Section (line 3) | function Section({
  function SectionHeader (line 15) | function SectionHeader({
  function SectionHeaderRow (line 27) | function SectionHeaderRow({
  function SectionDescription (line 45) | function SectionDescription({
  function SectionTitle (line 63) | function SectionTitle({
  function SectionGroup (line 75) | function SectionGroup({
  function SectionGroupHeader (line 90) | function SectionGroupHeader({
  function SectionGroupTitle (line 102) | function SectionGroupTitle({

FILE: apps/dashboard/src/components/controls-search/button-reset.tsx
  function ButtonReset (line 7) | function ButtonReset({ only }: { only?: string[] }) {

FILE: apps/dashboard/src/components/controls-search/command-region.tsx
  function CommandRegion (line 33) | function CommandRegion({

FILE: apps/dashboard/src/components/controls-search/command-tags.tsx
  function CommandTags (line 23) | function CommandTags() {

FILE: apps/dashboard/src/components/controls-search/dropdown-interval.tsx
  constant MAPPING (line 16) | const MAPPING = {
  function DropdownInterval (line 29) | function DropdownInterval() {

FILE: apps/dashboard/src/components/controls-search/dropdown-percentile.tsx
  function DropdownPercentile (line 19) | function DropdownPercentile() {

FILE: apps/dashboard/src/components/controls-search/dropdown-period.tsx
  constant PERIOD_VALUES (line 17) | const PERIOD_VALUES = [
  function DropdownPeriod (line 34) | function DropdownPeriod() {

FILE: apps/dashboard/src/components/controls-search/dropdown-status.tsx
  function DropdownStatus (line 19) | function DropdownStatus() {

FILE: apps/dashboard/src/components/controls-search/dropdown-trigger.tsx
  function DropdownTrigger (line 19) | function DropdownTrigger() {

FILE: apps/dashboard/src/components/controls-search/popover-date.tsx
  function PopoverDate (line 14) | function PopoverDate() {

FILE: apps/dashboard/src/components/data-table/audit-logs/columns.tsx
  type AuditLog (line 11) | type AuditLog = RouterOutputs["tinybird"]["auditLog"]["data"][number];
  function getColumns (line 13) | function getColumns(
  function Pill (line 104) | function Pill({ label, value }: { label: string; value?: string }) {

FILE: apps/dashboard/src/components/data-table/audit-logs/wrapper.tsx
  function AuditLogsWrapper (line 18) | function AuditLogsWrapper({

FILE: apps/dashboard/src/components/data-table/billing/data-table.tsx
  constant BASE_URL (line 31) | const BASE_URL =
  function DataTable (line 36) | function DataTable({ restrictTo }: { restrictTo?: WorkspacePlan[] }) {

FILE: apps/dashboard/src/components/data-table/dable-cell-skeleton.tsx
  function TableCellSkeleton (line 4) | function TableCellSkeleton({

FILE: apps/dashboard/src/components/data-table/data-table-sheet.tsx
  function DataTableSheetContent (line 16) | function DataTableSheetContent({
  function DataTableSheetHeader (line 28) | function DataTableSheetHeader({
  function DataTableSheetFooter (line 43) | function DataTableSheetFooter({
  function DataTableSheetFooterInfo (line 58) | function DataTableSheetFooterInfo({

FILE: apps/dashboard/src/components/data-table/incidents/columns.tsx
  type Incident (line 12) | type Incident = RouterOutputs["incident"]["list"][number];

FILE: apps/dashboard/src/components/data-table/incidents/data-table-row-actions.tsx
  type Incident (line 24) | type Incident = RouterOutputs["incident"]["list"][number];
  type DataTableRowActionsProps (line 26) | interface DataTableRowActionsProps {
  function DataTableRowActions (line 30) | function DataTableRowActions({ row }: DataTableRowActionsProps) {

FILE: apps/dashboard/src/components/data-table/maintenances/columns.tsx
  type Maintenance (line 12) | type Maintenance = RouterOutputs["maintenance"]["list"][number];

FILE: apps/dashboard/src/components/data-table/maintenances/data-table-row-actions.tsx
  type Maintenance (line 13) | type Maintenance = RouterOutputs["maintenance"]["list"][number];
  type DataTableRowActionsProps (line 15) | interface DataTableRowActionsProps {
  function DataTableRowActions (line 19) | function DataTableRowActions({ row }: DataTableRowActionsProps) {

FILE: apps/dashboard/src/components/data-table/monitors/columns.tsx
  type Monitor (line 17) | type Monitor = RouterOutputs["monitor"]["list"][number] & {

FILE: apps/dashboard/src/components/data-table/monitors/data-table-action-bar.tsx
  type Monitor (line 41) | type Monitor = RouterOutputs["monitor"]["list"][number];
  constant ACTIVE (line 43) | const ACTIVE = [
  type MonitorDataTableActionBarProps (line 48) | interface MonitorDataTableActionBarProps {
  function MonitorDataTableActionBar (line 52) | function MonitorDataTableActionBar({

FILE: apps/dashboard/src/components/data-table/monitors/data-table-row-actions.tsx
  type Monitor (line 14) | type Monitor = RouterOutputs["monitor"]["list"][number];
  type DataTableRowActionsProps (line 15) | interface DataTableRowActionsProps {
  function DataTableRowActions (line 19) | function DataTableRowActions({ row }: DataTableRowActionsProps) {

FILE: apps/dashboard/src/components/data-table/monitors/data-table-toolbar.tsx
  type Monitor (line 12) | type Monitor = RouterOutputs["monitor"]["list"][number];
  type MonitorTag (line 13) | type MonitorTag = RouterOutputs["monitorTag"]["list"][number];
  type MonitorDataTableToolbarProps (line 15) | interface MonitorDataTableToolbarProps {
  function MonitorDataTableToolbar (line 20) | function MonitorDataTableToolbar({

FILE: apps/dashboard/src/components/data-table/notifications/columns.tsx
  type Notifier (line 12) | type Notifier = RouterOutputs["notification"]["list"][number];

FILE: apps/dashboard/src/components/data-table/notifications/data-table-row-actions.tsx
  type Notifier (line 12) | type Notifier = RouterOutputs["notification"]["list"][number];
  type DataTableRowActionsProps (line 14) | interface DataTableRowActionsProps {
  function DataTableRowActions (line 18) | function DataTableRowActions(props: DataTableRowActionsProps) {

FILE: apps/dashboard/src/components/data-table/page-components/columns.tsx
  type PageComponent (line 8) | type PageComponent = RouterOutputs["pageComponent"]["list"][number];

FILE: apps/dashboard/src/components/data-table/page-components/data-table-row-actions.tsx
  type PageComponent (line 10) | type PageComponent = RouterOutputs["pageComponent"]["list"][number];
  type DataTableRowActionsProps (line 12) | interface DataTableRowActionsProps {
  function DataTableRowActions (line 16) | function DataTableRowActions({ row }: DataTableRowActionsProps) {

FILE: apps/dashboard/src/components/data-table/private-locations/columns.tsx
  type PrivateLocation (line 11) | type PrivateLocation = RouterOutputs["privateLocation"]["list"][number];

FILE: apps/dashboard/src/components/data-table/private-locations/data-table-row-actions.tsx
  type PrivateLocation (line 12) | type PrivateLocation = RouterOutputs["privateLocation"]["list"][number];
  type DataTableRowActionsProps (line 14) | interface DataTableRowActionsProps {
  function DataTableRowActions (line 18) | function DataTableRowActions(props: DataTableRowActionsProps) {

FILE: apps/dashboard/src/components/data-table/response-logs/columns.tsx
  type ResponseLog (line 25) | type ResponseLog = RouterOutputs["tinybird"]["list"]["data"][number];
  function getColumns (line 28) | function getColumns(
  function HoverCardTiming (line 172) | function HoverCardTiming({
  function HoverCardTimingContent (line 205) | function HoverCardTimingContent({

FILE: apps/dashboard/src/components/data-table/response-logs/data-table-basics.tsx
  type ResponseLog (line 28) | type ResponseLog = RouterOutputs["tinybird"]["get"]["data"][number];
  function DataTableBasics (line 30) | function DataTableBasics({
  function DataTableBasicsHTTP (line 55) | function DataTableBasicsHTTP({
  function DataTableBasicsTCP (line 333) | function DataTableBasicsTCP({
  function DataTableBasicsDNS (line 469) | function DataTableBasicsDNS({

FILE: apps/dashboard/src/components/data-table/response-logs/data-table-sheet-test.tsx
  type TestTCP (line 12) | type TestTCP = RouterOutputs["checker"]["testTcp"];
  type TestHTTP (line 13) | type TestHTTP = RouterOutputs["checker"]["testHttp"];
  type TestDNS (line 14) | type TestDNS = RouterOutputs["checker"]["testDns"];
  type Monitor (line 15) | type Monitor = NonNullable<RouterOutputs["monitor"]["get"]>;
  function DataTableSheetTest (line 17) | function DataTableSheetTest({
  function mapping (line 45) | function mapping(data: TestTCP | TestHTTP | TestDNS, monitor: Monitor) {

FILE: apps/dashboard/src/components/data-table/response-logs/data-table-sheet.tsx
  type ResponseLog (line 18) | type ResponseLog = RouterOutputs["tinybird"]["get"]["data"][number];
  function Sheet (line 20) | function Sheet({

FILE: apps/dashboard/src/components/data-table/response-logs/data-table-toolbar.tsx
  type ResponseLog (line 13) | type ResponseLog = RouterOutputs["tinybird"]["list"]["data"][number];
  type ResponseLogsDataTableToolbarProps (line 15) | interface ResponseLogsDataTableToolbarProps {
  function ResponseLogsDataTableToolbar (line 19) | function ResponseLogsDataTableToolbar({

FILE: apps/dashboard/src/components/data-table/response-logs/regions/columns.tsx
  function TrendCell (line 21) | function TrendCell({ trend }: { trend: RegionMetric["trend"] }) {
  function getColumns (line 25) | function getColumns(

FILE: apps/dashboard/src/components/data-table/settings/api-key/data-table.tsx
  type ApiKey (line 15) | type ApiKey = RouterOutputs["apiKeyRouter"]["getAll"][number];
  function DataTable (line 17) | function DataTable({

FILE: apps/dashboard/src/components/data-table/settings/invitations/data-table.tsx
  function DataTable (line 19) | function DataTable() {

FILE: apps/dashboard/src/components/data-table/settings/members/data-table.tsx
  function DataTable (line 14) | function DataTable() {

FILE: apps/dashboard/src/components/data-table/status-pages/columns.tsx
  type StatusPage (line 9) | type StatusPage = RouterOutputs["page"]["list"][number];

FILE: apps/dashboard/src/components/data-table/status-pages/data-table-row-actions.tsx
  type StatusPage (line 12) | type StatusPage = RouterOutputs["page"]["list"][number];
  type DataTableRowActionsProps (line 14) | interface DataTableRowActionsProps {
  function DataTableRowActions (line 18) | function DataTableRowActions({ row }: DataTableRowActionsProps) {

FILE: apps/dashboard/src/components/data-table/status-report-updates/data-table-row-actions.tsx
  type StatusReportUpdate (line 12) | type StatusReportUpdate =
  type DataTableRowActionsProps (line 15) | interface DataTableRowActionsProps {
  function DataTableRowActions (line 19) | function DataTableRowActions({ row }: DataTableRowActionsProps) {

FILE: apps/dashboard/src/components/data-table/status-report-updates/data-table.tsx
  type StatusReportUpdates (line 31) | type StatusReportUpdates =
  function DataTable (line 34) | function DataTable({

FILE: apps/dashboard/src/components/data-table/status-reports/columns.tsx
  type StatusReport (line 17) | type StatusReport = RouterOutputs["statusReport"]["list"][number];

FILE: apps/dashboard/src/components/data-table/status-reports/data-table-row-actions.tsx
  type StatusReport (line 14) | type StatusReport = RouterOutputs["statusReport"]["list"][number];
  type DataTableRowActionsProps (line 16) | interface DataTableRowActionsProps {
  function DataTableRowActions (line 23) | function DataTableRowActions({ row }: DataTableRowActionsProps) {

FILE: apps/dashboard/src/components/data-table/subscribers/columns.tsx
  type Subscriber (line 9) | type Subscriber = RouterOutputs["pageSubscriber"]["list"][number];

FILE: apps/dashboard/src/components/data-table/subscribers/data-table-row-actions.tsx
  type Subscriber (line 9) | type Subscriber = RouterOutputs["pageSubscriber"]["list"][number];
  type DataTableRowActionsProps (line 11) | interface DataTableRowActionsProps {
  function DataTableRowActions (line 15) | function DataTableRowActions({ row }: DataTableRowActionsProps) {

FILE: apps/dashboard/src/components/data-table/table-cell-badge.tsx
  function TableCellBadge (line 11) | function TableCellBadge({

FILE: apps/dashboard/src/components/data-table/table-cell-boolean.tsx
  function TableCellBoolean (line 3) | function TableCellBoolean({

FILE: apps/dashboard/src/components/data-table/table-cell-date.tsx
  function TableCellDate (line 5) | function TableCellDate({

FILE: apps/dashboard/src/components/data-table/table-cell-link.tsx
  function TableCellLink (line 5) | function TableCellLink({

FILE: apps/dashboard/src/components/data-table/table-cell-number.tsx
  function TableCellNumber (line 3) | function TableCellNumber({

FILE: apps/dashboard/src/components/data-table/table-cell-unavailable.tsx
  function TableCellUnavailable (line 3) | function TableCellUnavailable({

FILE: apps/dashboard/src/components/date-picker.tsx
  type DatePickerProps (line 15) | type DatePickerProps = {
  function DatePicker (line 21) | function DatePicker({ range, onSelect, presets }: DatePickerProps) {

FILE: apps/dashboard/src/components/development-indicator.tsx
  function DevelopmentIndicator (line 13) | function DevelopmentIndicator() {

FILE: apps/dashboard/src/components/dialogs/export-code.tsx
  constant YML (line 21) | const YML = `openstatus-marketing:
  function ExportCodeDialog (line 33) | function ExportCodeDialog(props: DialogProps) {

FILE: apps/dashboard/src/components/dialogs/upgrade.tsx
  constant PLANS (line 22) | const PLANS = {
  function UpgradeDialog (line 28) | function UpgradeDialog(

FILE: apps/dashboard/src/components/domains/domain-configuration.tsx
  function DomainConfiguration (line 38) | function DomainConfiguration({ domain }: { domain: string }) {

FILE: apps/dashboard/src/components/domains/domain-status-icon.tsx
  function DomainStatusIcon (line 7) | function DomainStatusIcon({

FILE: apps/dashboard/src/components/domains/use-domain-status.ts
  function useDomainStatus (line 7) | function useDomainStatus(domain?: string) {

FILE: apps/dashboard/src/components/dropdowns/quick-actions.tsx
  type QuickActionsProps (line 41) | interface QuickActionsProps extends React.ComponentProps<typeof Button> {
  function QuickActions (line 60) | function QuickActions({

FILE: apps/dashboard/src/components/forms/components/form-components.tsx
  type PageComponent (line 93) | type PageComponent = RouterOutputs["pageComponent"]["list"][number];
  type Monitor (line 94) | type Monitor = RouterOutputs["monitor"]["list"][number];
  type Workspace (line 95) | type Workspace = RouterOutputs["workspace"]["get"];
  type ComponentGroup (line 97) | type ComponentGroup = {
  type FormValues (line 257) | type FormValues = z.infer<typeof schema>;
  function FormComponents (line 259) | function FormComponents({
  type ComponentRowProps (line 707) | interface ComponentRowProps
  function ComponentRow (line 716) | function ComponentRow({
  type ComponentGroupRowProps (line 888) | interface ComponentGroupRowProps
  function ComponentGroupRow (line 899) | function ComponentGroupRow({
  function ComponentAttachments (line 1229) | function ComponentAttachments({

FILE: apps/dashboard/src/components/forms/components/form-import.tsx
  type ImportFormValues (line 51) | type ImportFormValues = z.input<typeof schema>;
  function getPhaseCount (line 53) | function getPhaseCount(preview: ImportSummary, phase: string): number {
  constant PHASE_LABELS (line 57) | const PHASE_LABELS: Record<string, string> = {
  function FormImport (line 65) | function FormImport({

FILE: apps/dashboard/src/components/forms/components/telegram-connection-flow.tsx
  type TelegramConnectionFlowProps (line 15) | interface TelegramConnectionFlowProps {
  function TelegramConnectionFlow (line 21) | function TelegramConnectionFlow({

FILE: apps/dashboard/src/components/forms/components/telegram-form-actions.tsx
  type TelegramFormActionsProps (line 12) | interface TelegramFormActionsProps {
  function TelegramFormActions (line 17) | function TelegramFormActions({

FILE: apps/dashboard/src/components/forms/components/telegram-manual-input.tsx
  type TelegramManualInputProps (line 16) | interface TelegramManualInputProps {
  function TelegramManualInput (line 22) | function TelegramManualInput({

FILE: apps/dashboard/src/components/forms/components/telegram-qr-connection.tsx
  type TelegramQRConnectionProps (line 9) | interface TelegramQRConnectionProps {
  function TelegramQRConnection (line 22) | function TelegramQRConnection({

FILE: apps/dashboard/src/components/forms/components/telegram-qrcode.tsx
  function TelegramQRCode (line 5) | function TelegramQRCode({

FILE: apps/dashboard/src/components/forms/components/update.tsx
  function FormComponentsUpdate (line 12) | function FormComponentsUpdate() {

FILE: apps/dashboard/src/components/forms/form-alert-dialog.tsx
  type FormAlertDialogProps (line 22) | interface FormAlertDialogProps {
  function FormAlertDialog (line 28) | function FormAlertDialog({

FILE: apps/dashboard/src/components/forms/form-card.tsx
  function FormCard (line 33) | function FormCard({
  function FormCardHeader (line 46) | function FormCardHeader({
  function FormCardTitle (line 64) | function FormCardTitle({ children }: { children: React.ReactNode }) {
  function FormCardDescription (line 68) | function FormCardDescription({
  function FormCardContent (line 76) | function FormCardContent({
  function FormCardSeparator (line 95) | function FormCardSeparator({
  function FormCardFooter (line 117) | function FormCardFooter({
  function FormCardFooterInfo (line 133) | function FormCardFooterInfo({
  function FormCardGroup (line 149) | function FormCardGroup({
  function FormCardUpgrade (line 165) | function FormCardUpgrade({
  function FormCardContentUpgrade (line 183) | function FormCardContentUpgrade({
  function FormCardEmpty (line 199) | function FormCardEmpty({

FILE: apps/dashboard/src/components/forms/form-sheet.tsx
  function FormSheetContent (line 31) | function FormSheetContent({
  function FormSheetHeader (line 43) | function FormSheetHeader({
  function FormSheetFooter (line 58) | function FormSheetFooter({
  function FormSheetFooterInfo (line 73) | function FormSheetFooterInfo({
  function FormSheetTrigger (line 85) | function FormSheetTrigger({
  function FormSheetAlertDialog (line 106) | function FormSheetAlertDialog({
  function useFormSheetDirty (line 137) | function useFormSheetDirty() {
  function FormSheetWithDirtyProtection (line 147) | function FormSheetWithDirtyProtection({

FILE: apps/dashboard/src/components/forms/maintenance/form.tsx
  type FormValues (line 63) | type FormValues = z.infer<typeof schema>;
  function FormMaintenance (line 65) | function FormMaintenance({

FILE: apps/dashboard/src/components/forms/maintenance/sheet.tsx
  function FormSheetMaintenance (line 21) | function FormSheetMaintenance({

FILE: apps/dashboard/src/components/forms/monitor-tag/form-monitor-tag.tsx
  type FormValues (line 34) | type FormValues = z.infer<typeof schema>;
  function FormMonitorTag (line 37) | function FormMonitorTag({

FILE: apps/dashboard/src/components/forms/monitor-tag/sheet.tsx
  function FormSheetMonitorTag (line 24) | function FormSheetMonitorTag({

FILE: apps/dashboard/src/components/forms/monitor/form-danger-zone.tsx
  function FormDangerZone (line 12) | function FormDangerZone({

FILE: apps/dashboard/src/components/forms/monitor/form-follow-redirect.tsx
  constant FOLLOW_REDIRECTS_DEFAULT (line 29) | const FOLLOW_REDIRECTS_DEFAULT = true;
  type FormValues (line 35) | type FormValues = z.input<typeof schema>;
  function FormFollowRedirect (line 37) | function FormFollowRedirect({

FILE: apps/dashboard/src/components/forms/monitor/form-general.tsx
  constant TYPES (line 74) | const TYPES = ["http", "tcp", "dns"] as const;
  constant HTTP_ASSERTION_TYPES (line 75) | const HTTP_ASSERTION_TYPES = ["status", "header", "textBody"] as const;
  constant DNS_ASSERTION_TYPES (line 76) | const DNS_ASSERTION_TYPES = dnsRecords;
  type FormValues (line 104) | type FormValues = z.input<typeof schema>;
  function FormGeneral (line 106) | function FormGeneral({

FILE: apps/dashboard/src/components/forms/monitor/form-notifiers.tsx
  type FormValues (line 40) | type FormValues = z.infer<typeof schema>;
  function FormNotifiers (line 42) | function FormNotifiers({

FILE: apps/dashboard/src/components/forms/monitor/form-otel.tsx
  type FormValues (line 41) | type FormValues = z.input<typeof schema>;
  function FormOtel (line 43) | function FormOtel({

FILE: apps/dashboard/src/components/forms/monitor/form-response-time.tsx
  constant DEGRADED (line 29) | const DEGRADED = 30_000;
  constant TIMEOUT (line 30) | const TIMEOUT = 45_000;
  type FormValues (line 37) | type FormValues = z.input<typeof schema>;
  function FormResponseTime (line 39) | function FormResponseTime({

FILE: apps/dashboard/src/components/forms/monitor/form-retry.tsx
  constant RETRY_MIN (line 30) | const RETRY_MIN = 1;
  constant RETRY_MAX (line 31) | const RETRY_MAX = 10;
  constant RETRY_DEFAULT (line 32) | const RETRY_DEFAULT = 3;
  type FormValues (line 42) | type FormValues = z.input<typeof schema>;
  function FormRetry (line 44) | function FormRetry({

FILE: apps/dashboard/src/components/forms/monitor/form-scheduling-regions.tsx
  constant DEFAULT_PERIODICITY (line 49) | const DEFAULT_PERIODICITY = "10m";
  constant DEFAULT_REGIONS (line 50) | const DEFAULT_REGIONS = ["ams", "fra", "iad", "syd", "jnb", "gru"];
  constant PERIODICITY (line 51) | const PERIODICITY = monitorPeriodicity.filter((p) => p !== "other");
  constant DEFAULT_PRIVATE_LOCATIONS (line 52) | const DEFAULT_PRIVATE_LOCATIONS = [] satisfies { id: number; name: strin...
  type FormValues (line 60) | type FormValues = z.infer<typeof schema>;
  function FormSchedulingRegions (line 62) | function FormSchedulingRegions({

FILE: apps/dashboard/src/components/forms/monitor/form-status-pages.tsx
  type FormValues (line 43) | type FormValues = z.infer<typeof schema>;
  function FormStatusPages (line 45) | function FormStatusPages({

FILE: apps/dashboard/src/components/forms/monitor/form-tags.tsx
  type FormValues (line 57) | type FormValues = z.infer<typeof schema>;
  function FormTags (line 59) | function FormTags({

FILE: apps/dashboard/src/components/forms/monitor/form-visibility.tsx
  type FormValues (line 36) | type FormValues = z.infer<typeof schema>;
  function FormVisibility (line 38) | function FormVisibility({

FILE: apps/dashboard/src/components/forms/monitor/update.tsx
  function FormMonitorUpdate (line 22) | function FormMonitorUpdate() {

FILE: apps/dashboard/src/components/forms/notifications/form-discord.tsx
  type FormValues (line 39) | type FormValues = z.infer<typeof schema>;
  function FormDiscord (line 41) | function FormDiscord({

FILE: apps/dashboard/src/components/forms/notifications/form-email.tsx
  type FormValues (line 36) | type FormValues = z.infer<typeof schema>;
  function FormEmail (line 38) | function FormEmail({

FILE: apps/dashboard/src/components/forms/notifications/form-google-chat.tsx
  type FormValues (line 40) | type FormValues = z.infer<typeof schema>;
  function FormGoogleChat (line 42) | function FormGoogleChat({

FILE: apps/dashboard/src/components/forms/notifications/form-grafana-oncall.tsx
  type FormValues (line 40) | type FormValues = z.infer<typeof schema>;
  function FormGrafanaOncall (line 42) | function FormGrafanaOncall({

FILE: apps/dashboard/src/components/forms/notifications/form-ntfy.tsx
  type FormValues (line 38) | type FormValues = z.infer<typeof schema>;
  function FormNtfy (line 40) | function FormNtfy({

FILE: apps/dashboard/src/components/forms/notifications/form-opsgenie.tsx
  type FormValues (line 44) | type FormValues = z.infer<typeof schema>;
  function FormOpsGenie (line 46) | function FormOpsGenie({

FILE: apps/dashboard/src/components/forms/notifications/form-pagerduty.tsx
  type FormValues (line 40) | type FormValues = z.infer<typeof schema>;
  function FormPagerDuty (line 42) | function FormPagerDuty({

FILE: apps/dashboard/src/components/forms/notifications/form-slack.tsx
  type FormValues (line 39) | type FormValues = z.infer<typeof schema>;
  function FormSlack (line 41) | function FormSlack({

FILE: apps/dashboard/src/components/forms/notifications/form-sms.tsx
  type FormValues (line 35) | type FormValues = z.infer<typeof schema>;
  function FormSms (line 37) | function FormSms({

FILE: apps/dashboard/src/components/forms/notifications/form-telegram.tsx
  type FormValues (line 41) | type FormValues = z.infer<typeof schema>;
  function FormTelegram (line 43) | function FormTelegram({

FILE: apps/dashboard/src/components/forms/notifications/form-webhook.tsx
  type FormValues (line 39) | type FormValues = z.infer<typeof schema>;
  function FormWebhook (line 41) | function FormWebhook({

FILE: apps/dashboard/src/components/forms/notifications/form-whatsapp.tsx
  type FormValues (line 40) | type FormValues = z.infer<typeof schema>;
  function FormWhatsApp (line 42) | function FormWhatsApp({

FILE: apps/dashboard/src/components/forms/notifications/form.tsx
  type FormValues (line 43) | type FormValues = z.infer<typeof schema>;
  function NotifierForm (line 45) | function NotifierForm({

FILE: apps/dashboard/src/components/forms/notifications/sheet.tsx
  function FormSheetNotifier (line 18) | function FormSheetNotifier({

FILE: apps/dashboard/src/components/forms/onboarding/create-monitor.tsx
  type FormValues (line 24) | type FormValues = z.infer<typeof schema>;
  function CreateMonitorForm (line 26) | function CreateMonitorForm({

FILE: apps/dashboard/src/components/forms/onboarding/create-page.tsx
  constant SLUG_UNIQUE_ERROR_MESSAGE (line 24) | const SLUG_UNIQUE_ERROR_MESSAGE =
  type FormValues (line 31) | type FormValues = z.infer<typeof schema>;
  function CreatePageForm (line 33) | function CreatePageForm({

FILE: apps/dashboard/src/components/forms/onboarding/learn-from.tsx
  type FormValues (line 50) | type FormValues = z.infer<typeof schema>;
  function LearnFromForm (line 52) | function LearnFromForm({

FILE: apps/dashboard/src/components/forms/private-location/form.tsx
  type FormValues (line 46) | type FormValues = z.infer<typeof schema>;
  function FormPrivateLocation (line 48) | function FormPrivateLocation({

FILE: apps/dashboard/src/components/forms/private-location/sheet.tsx
  function FormSheetPrivateLocation (line 20) | function FormSheetPrivateLocation({

FILE: apps/dashboard/src/components/forms/settings/form-api-key.tsx
  type FormValues (line 74) | type FormValues = z.infer<typeof schema>;
  function FormApiKey (line 76) | function FormApiKey() {

FILE: apps/dashboard/src/components/forms/settings/form-members.tsx
  type FormValues (line 48) | type FormValues = z.infer<typeof schema>;
  function FormMembers (line 50) | function FormMembers({

FILE: apps/dashboard/src/components/forms/settings/form-slug.tsx
  type FormValues (line 23) | type FormValues = z.infer<typeof schema>;
  function FormSlug (line 25) | function FormSlug({ defaultValues }: { defaultValues?: FormValues }) {

FILE: apps/dashboard/src/components/forms/settings/form-workspace.tsx
  type FormValues (line 31) | type FormValues = z.infer<typeof schema>;
  function FormWorkspace (line 33) | function FormWorkspace({

FILE: apps/dashboard/src/components/forms/status-page/form-appearance.tsx
  type FormValues (line 62) | type FormValues = z.infer<typeof schema>;
  function FormAppearance (line 64) | function FormAppearance({

FILE: apps/dashboard/src/components/forms/status-page/form-configuration.tsx
  type FormValues (line 75) | type FormValues = z.infer<typeof schema>;
  function FormConfiguration (line 77) | function FormConfiguration({
  function FormConfigurationDialog (line 352) | function FormConfigurationDialog({

FILE: apps/dashboard/src/components/forms/status-page/form-custom-domain.tsx
  type FormValues (line 43) | type FormValues = z.infer<typeof schema>;
  function FormCustomDomain (line 45) | function FormCustomDomain({

FILE: apps/dashboard/src/components/forms/status-page/form-danger-zone.tsx
  function FormDangerZone (line 12) | function FormDangerZone({

FILE: apps/dashboard/src/components/forms/status-page/form-general.tsx
  constant SLUG_UNIQUE_ERROR_MESSAGE (line 38) | const SLUG_UNIQUE_ERROR_MESSAGE =
  function formatSlug (line 41) | function formatSlug(title: string) {
  type FormValues (line 55) | type FormValues = z.infer<typeof schema>;
  function fileToBase64 (line 58) | async function fileToBase64(file: File): Promise<string> {
  function FormGeneral (line 71) | function FormGeneral({

FILE: apps/dashboard/src/components/forms/status-page/form-links.tsx
  type FormValues (line 35) | type FormValues = z.infer<typeof schema>;
  function FormLinks (line 37) | function FormLinks({

FILE: apps/dashboard/src/components/forms/status-page/form-monitors.tsx
  type Monitor (line 79) | type Monitor = {
  type MonitorGroup (line 87) | type MonitorGroup = {
  type FormValues (line 165) | type FormValues = z.infer<typeof schema>;
  function FormMonitors (line 167) | function FormMonitors({
  type MonitorRowProps (line 532) | interface MonitorRowProps
  function MonitorRow (line 538) | function MonitorRow({ monitor, className, ...props }: MonitorRowProps) {
  type MonitorGroupProps (line 573) | interface MonitorGroupProps
  function MonitorGroup (line 582) | function MonitorGroup({

FILE: apps/dashboard/src/components/forms/status-page/form-page-access.tsx
  type FormValues (line 58) | type FormValues = z.infer<typeof schema>;
  function FormPageAccess (line 60) | function FormPageAccess({

FILE: apps/dashboard/src/components/forms/status-page/update.tsx
  function FormStatusPageUpdate (line 15) | function FormStatusPageUpdate() {

FILE: apps/dashboard/src/components/forms/status-report-update/form-status-report.tsx
  type FormValues (line 72) | type FormValues = z.infer<typeof schema>;
  function FormStatusReportUpdateCard (line 74) | function FormStatusReportUpdateCard({

FILE: apps/dashboard/src/components/forms/status-report-update/form.tsx
  type FormValues (line 61) | type FormValues = z.infer<typeof schema>;
  function FormStatusReportUpdate (line 63) | function FormStatusReportUpdate({

FILE: apps/dashboard/src/components/forms/status-report-update/sheet.tsx
  function FormSheetStatusReportUpdate (line 20) | function FormSheetStatusReportUpdate({

FILE: apps/dashboard/src/components/forms/status-report/form.tsx
  type FormValues (line 76) | type FormValues = z.infer<typeof schema> | z.infer<typeof updateSchema>;
  function FormStatusReport (line 78) | function FormStatusReport({

FILE: apps/dashboard/src/components/forms/status-report/sheet.tsx
  function FormSheetStatusReport (line 22) | function FormSheetStatusReport({

FILE: apps/dashboard/src/components/forms/support-contact/dialog.tsx
  function FormDialogSupportContact (line 16) | function FormDialogSupportContact({

FILE: apps/dashboard/src/components/forms/support-contact/form.tsx
  type FormValues (line 68) | type FormValues = z.infer<typeof schema>;
  type ContactFormProps (line 70) | interface ContactFormProps {
  function ContactForm (line 76) | function ContactForm({

FILE: apps/dashboard/src/components/layout/auth-layout.tsx
  function AuthLayout (line 3) | function AuthLayout({ children }: { children: React.ReactNode }) {

FILE: apps/dashboard/src/components/metric/global-uptime/section.tsx
  type Metric (line 23) | type Metric = {
  function GlobalUptimeSection (line 33) | function GlobalUptimeSection({

FILE: apps/dashboard/src/components/metric/metric-card.tsx
  function MetricCard (line 29) | function MetricCard({
  function MetricCardTitle (line 46) | function MetricCardTitle({
  function MetricCardHeader (line 64) | function MetricCardHeader({
  function MetricCardValue (line 85) | function MetricCardValue({
  function MetricCardGroup (line 97) | function MetricCardGroup({
  function MetricCardBadge (line 130) | function MetricCardBadge({
  function MetricCardButton (line 167) | function MetricCardButton({
  function MetricCardSkeleton (line 188) | function MetricCardSkeleton({

FILE: apps/dashboard/src/components/nav/app-header.tsx
  function AppHeader (line 3) | function AppHeader({
  function AppHeaderContent (line 21) | function AppHeaderContent({
  function AppHeaderActions (line 36) | function AppHeaderActions({

FILE: apps/dashboard/src/components/nav/app-sidebar.tsx
  constant SIDEBAR_KEYBOARD_SHORTCUT (line 39) | const SIDEBAR_KEYBOARD_SHORTCUT = "[";
  function AppSidebar (line 92) | function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
  function AppSidebarTrigger (line 115) | function AppSidebarTrigger() {

FILE: apps/dashboard/src/components/nav/nav-banner-checklist.tsx
  function NavBannerChecklist (line 15) | function NavBannerChecklist({

FILE: apps/dashboard/src/components/nav/nav-banner-upgrade.tsx
  function NavBannerUpgrade (line 17) | function NavBannerUpgrade({ handleClose }: { handleClose: () => void }) {

FILE: apps/dashboard/src/components/nav/nav-banner.tsx
  constant EXPIRES_IN (line 9) | const EXPIRES_IN = 7 * 24 * 60 * 60 * 1000;
  function NavBanner (line 11) | function NavBanner() {

FILE: apps/dashboard/src/components/nav/nav-breadcrumb.tsx
  type NavBreadcrumbProps (line 15) | interface NavBreadcrumbProps {
  function NavBreadcrumb (line 31) | function NavBreadcrumb({ items }: NavBreadcrumbProps) {

FILE: apps/dashboard/src/components/nav/nav-feedback.tsx
  function NavFeedback (line 32) | function NavFeedback() {

FILE: apps/dashboard/src/components/nav/nav-help.tsx
  function NavHelp (line 30) | function NavHelp() {

FILE: apps/dashboard/src/components/nav/nav-main.tsx
  function NavMain (line 22) | function NavMain({

FILE: apps/dashboard/src/components/nav/nav-monitors.tsx
  constant STATUS (line 36) | const STATUS = {
  function NavMonitors (line 43) | function NavMonitors() {

FILE: apps/dashboard/src/components/nav/nav-overview.tsx
  function NavOverview (line 16) | function NavOverview({

FILE: apps/dashboard/src/components/nav/nav-status-pages.tsx
  constant STATUS (line 34) | const STATUS = {
  function NavStatusPages (line 40) | function NavStatusPages() {

FILE: apps/dashboard/src/components/nav/nav-tabs.tsx
  type NavTabsProps (line 9) | interface NavTabsProps {
  function NavTabs (line 18) | function NavTabs({ items }: NavTabsProps) {

FILE: apps/dashboard/src/components/nav/nav-user.tsx
  function NavUser (line 44) | function NavUser() {

FILE: apps/dashboard/src/components/nav/sidebar-metadata.tsx
  type SidebarMetadataProps (line 35) | type SidebarMetadataProps = {
  function SidebarMetadata (line 44) | function SidebarMetadata({ label, items }: SidebarMetadataProps) {
  function SidebarMetadataTable (line 73) | function SidebarMetadataTable({
  function SidebarMetadataTableCell (line 110) | function SidebarMetadataTableCell({

FILE: apps/dashboard/src/components/nav/sidebar-right.tsx
  constant SIDEBAR_KEYBOARD_SHORTCUT (line 31) | const SIDEBAR_KEYBOARD_SHORTCUT = "]";
  constant SIDEBAR_WIDTH (line 32) | const SIDEBAR_WIDTH = "18rem";
  constant SIDEBAR_WIDTH_2XL (line 33) | const SIDEBAR_WIDTH_2XL = "24rem";
  constant SIDEBAR_WIDTH_MOBILE (line 34) | const SIDEBAR_WIDTH_MOBILE = "18rem";
  type SidebarRightProps (line 36) | type SidebarRightProps = React.ComponentProps<typeof Sidebar> & {
  function SidebarRight (line 42) | function SidebarRight({
  function SidebarTrigger (line 113) | function SidebarTrigger({

FILE: apps/dashboard/src/components/nav/workspace-switcher.tsx
  function WorkspaceSwitcher (line 23) | function WorkspaceSwitcher() {

FILE: apps/dashboard/src/components/popovers/popover-quantile.tsx
  function PopoverQuantile (line 9) | function PopoverQuantile({

FILE: apps/dashboard/src/components/popovers/popover-resolution.tsx
  function PopoverResolution (line 9) | function PopoverResolution({

FILE: apps/dashboard/src/components/tailwind-indicator.tsx
  function TailwindIndicator (line 1) | function TailwindIndicator() {

FILE: apps/dashboard/src/components/theme-provider.tsx
  function ThemeProvider (line 6) | function ThemeProvider({

FILE: apps/dashboard/src/components/theme-toggle.tsx
  function ThemeToggle (line 18) | function ThemeToggle({

FILE: apps/dashboard/src/components/ui/data-table/data-table-action-bar.tsx
  type DataTableActionBarProps (line 16) | interface DataTableActionBarProps<TData>
  function DataTableActionBar (line 23) | function DataTableActionBar<TData>({
  type DataTableActionBarActionProps (line 76) | interface DataTableActionBarActionProps
  function DataTableActionBarAction (line 82) | function DataTableActionBarAction({
  type DataTableActionBarSelectionProps (line 122) | interface DataTableActionBarSelectionProps<TData> {
  function DataTableActionBarSelection (line 126) | function DataTableActionBarSelection<TData>({

FILE: apps/dashboard/src/components/ui/data-table/data-table-column-header.tsx
  type DataTableColumnHeaderProps (line 8) | interface DataTableColumnHeaderProps<TData, TValue>
  function DataTableColumnHeader (line 14) | function DataTableColumnHeader<TData, TValue>({

FILE: apps/dashboard/src/components/ui/data-table/data-table-faceted-filter.tsx
  type DataTableFacetedFilterProps (line 24) | interface DataTableFacetedFilterProps<TData, TValue> {
  function DataTableFacetedFilter (line 34) | function DataTableFacetedFilter<TData, TValue>({

FILE: apps/dashboard/src/components/ui/data-table/data-table-pagination.tsx
  type DataTablePaginationProps (line 18) | interface DataTablePaginationProps<TData> {
  function DataTablePagination (line 22) | function DataTablePagination<TData>({
  function DataTablePaginationSimple (line 99) | function DataTablePaginationSimple<TData>({

FILE: apps/dashboard/src/components/ui/data-table/data-table-skeleton.tsx
  type DataTableSkeletonProps (line 11) | interface DataTableSkeletonProps {
  function DataTableSkeleton (line 21) | function DataTableSkeleton({ rows = 3 }: DataTableSkeletonProps) {

FILE: apps/dashboard/src/components/ui/data-table/data-table-toobar.tsx
  type DataTableToolbarProps (line 12) | interface DataTableToolbarProps<TData> {
  function DataTableToolbar (line 16) | function DataTableToolbar<TData>({

FILE: apps/dashboard/src/components/ui/data-table/data-table-view-options.tsx
  type DataTableViewOptionsProps (line 16) | interface DataTableViewOptionsProps<TData> {
  function DataTableViewOptions (line 20) | function DataTableViewOptions<TData>({

FILE: apps/dashboard/src/components/ui/data-table/data-table.tsx
  type DataTableProps (line 35) | interface DataTableProps<TData, TValue> {
  function DataTable (line 58) | function DataTable<TData, TValue>({

FILE: apps/dashboard/src/components/ui/sortable.tsx
  constant ROOT_NAME (line 62) | const ROOT_NAME = "Sortable";
  constant CONTENT_NAME (line 63) | const CONTENT_NAME = "SortableContent";
  constant ITEM_NAME (line 64) | const ITEM_NAME = "SortableItem";
  constant ITEM_HANDLE_NAME (line 65) | const ITEM_HANDLE_NAME = "SortableItemHandle";
  constant OVERLAY_NAME (line 66) | const OVERLAY_NAME = "SortableOverlay";
  constant SORTABLE_ERRORS (line 68) | const SORTABLE_ERRORS = {
  type SortableRootContextValue (line 76) | interface SortableRootContextValue<T> {
  function useSortableContext (line 91) | function useSortableContext(name: keyof typeof SORTABLE_ERRORS) {
  type GetItemValue (line 99) | interface GetItemValue<T> {
  type SortableProps (line 107) | type SortableProps<T> = DndContextProps & {
  function Sortable (line 118) | function Sortable<T>(props: SortableProps<T>) {
  type SortableContentProps (line 312) | interface SortableContentProps extends React.ComponentPropsWithoutRef<"d...
  type SortableItemContextValue (line 352) | interface SortableItemContextValue {
  type SortableItemProps (line 365) | interface SortableItemProps extends React.ComponentPropsWithoutRef<"div"> {
  type SortableItemHandleProps (line 464) | interface SortableItemHandleProps
  type SortableOverlayProps (line 524) | interface SortableOverlayProps
  function SortableOverlay (line 532) | function SortableOverlay(props: SortableOverlayProps) {

FILE: apps/dashboard/src/data/audit-logs.ts
  type AuditLog (line 90) | type AuditLog = (typeof auditLogs)[number];

FILE: apps/dashboard/src/data/incidents.client.ts
  type IncidentAction (line 24) | type IncidentAction = (typeof actions)[number];

FILE: apps/dashboard/src/data/incidents.ts
  type Incident (line 11) | type Incident = (typeof incidents)[number];

FILE: apps/dashboard/src/data/invitations.ts
  type Invitation (line 12) | type Invitation = (typeof invitations)[number];

FILE: apps/dashboard/src/data/maintenances.client.ts
  type MaintenanceAction (line 18) | type MaintenanceAction = (typeof actions)[number];

FILE: apps/dashboard/src/data/maintenances.ts
  type Maintenance (line 13) | type Maintenance = (typeof maintenances)[number];

FILE: apps/dashboard/src/data/members.ts
  type Member (line 11) | type Member = (typeof members)[number];

FILE: apps/dashboard/src/data/metrics.client.ts
  constant STATUS (line 10) | const STATUS = ["success", "error", "degraded"] as const;
  constant PERIODS (line 11) | const PERIODS = ["1d", "7d", "14d"] as const;
  constant REGIONS (line 12) | const REGIONS =
  constant PERCENTILES (line 14) | const PERCENTILES = ["p50", "p75", "p90", "p95", "p99"] as const;
  constant INTERVALS (line 15) | const INTERVALS = [5, 15, 30, 60, 120, 240, 480, 1440] as const;
  constant TRIGGER (line 16) | const TRIGGER = ["api", "cron"] as const;
  constant PERCENTILE_MAP (line 18) | const PERCENTILE_MAP = {
  function mapMetrics (line 28) | function mapMetrics(metrics: RouterOutputs["tinybird"]["metrics"]) {
  function mapUptime (line 94) | function mapUptime(status: RouterOutputs["tinybird"]["uptime"]) {
  function mapRegionMetrics (line 110) | function mapRegionMetrics(
  function mapGlobalMetrics (line 184) | function mapGlobalMetrics(
  type MonitorListMetric (line 200) | type MonitorListMetric = {
  function getMonitorListMetrics (line 247) | function getMonitorListMetrics(
  function mapLatency (line 300) | function mapLatency(
  function mapTimingPhases (line 312) | function mapTimingPhases(

FILE: apps/dashboard/src/data/monitor-tags.ts
  type MonitorTag (line 34) | type MonitorTag = (typeof monitorTags)[number];

FILE: apps/dashboard/src/data/monitors.client.ts
  type MonitorAction (line 62) | type MonitorAction = (typeof actions)[number];

FILE: apps/dashboard/src/data/monitors.ts
  type Monitor (line 88) | type Monitor = (typeof monitors)[number];

FILE: apps/dashboard/src/data/notifications.client.ts
  type NotifierAction (line 56) | type NotifierAction = (typeof actions)[number];
  type NotifierProvider (line 146) | type NotifierProvider = keyof typeof config;

FILE: apps/dashboard/src/data/notifications.ts
  type Notification (line 10) | type Notification = (typeof notifications)[number];

FILE: apps/dashboard/src/data/page-components.client.ts
  type PageComponentAction (line 12) | type PageComponentAction = (typeof actions)[number];

FILE: apps/dashboard/src/data/region-metrics.client.ts
  type RegionMetricAction (line 18) | type RegionMetricAction = (typeof actions)[number];

FILE: apps/dashboard/src/data/region-metrics.ts
  type RegionMetric (line 37) | type RegionMetric = (typeof regionMetrics)[number];

FILE: apps/dashboard/src/data/regions.ts
  type Region (line 316) | type Region = (typeof regions)[number]["code"];
  function getRegionColor (line 380) | function getRegionColor(region: string) {

FILE: apps/dashboard/src/data/response-logs.ts
  type ResponseLog (line 5) | type ResponseLog = RouterOutputs["tinybird"]["list"]["data"][number];

FILE: apps/dashboard/src/data/status-codes.ts
  type StatusCode (line 16) | type StatusCode = (typeof statusCodes)[number]["code"];

FILE: apps/dashboard/src/data/status-pages.client.ts
  type StatusPageAction (line 30) | type StatusPageAction = (typeof actions)[number];

FILE: apps/dashboard/src/data/status-pages.ts
  type StatusPage (line 17) | type StatusPage = (typeof statusPages)[number];

FILE: apps/dashboard/src/data/status-report-updates.client.ts
  type StatusReportUpdateAction (line 19) | type StatusReportUpdateAction = (typeof actions)[number];
  function getNextStatus (line 50) | function getNextStatus(currentStatus: string): StatusReportStatus {

FILE: apps/dashboard/src/data/status-reports.client.ts
  type StatusReportUpdateAction (line 30) | type StatusReportUpdateAction = (typeof actions)[number];

FILE: apps/dashboard/src/data/status-reports.ts
  type StatusReport (line 60) | type StatusReport = (typeof statusReports)[number];

FILE: apps/dashboard/src/data/subscribers.ts
  type Subscriber (line 16) | type Subscriber = (typeof subscribers)[number];

FILE: apps/dashboard/src/hooks/use-feature.ts
  function useFeature (line 11) | function useFeature(feature: keyof typeof features) {

FILE: apps/dashboard/src/hooks/use-telegram-connection.ts
  type UseTelegramConnectionProps (line 10) | interface UseTelegramConnectionProps {
  type TelegramConnectionState (line 15) | interface TelegramConnectionState {
  type TelegramConnectionAction (line 23) | type TelegramConnectionAction =
  function telegramConnectionReducer (line 50) | function telegramConnectionReducer(
  function useTelegramConnection (line 83) | function useTelegramConnection({

FILE: apps/dashboard/src/instrumentation.ts
  function register (line 3) | async function register() {

FILE: apps/dashboard/src/lib/auth/helpers.ts
  function createUser (line 7) | async function createUser(data: AdapterUser) {
  function getUser (line 55) | async function getUser(id: string) {

FILE: apps/dashboard/src/lib/auth/index.ts
  method signIn (line 23) | async signIn(params) {
  method session (line 72) | async session(params) {
  method createUser (line 78) | async createUser(params) {
  method signIn (line 103) | async signIn(params) {

FILE: apps/dashboard/src/lib/auth/providers.ts
  method sendVerificationRequest (line 23) | async sendVerificationRequest(params) {

FILE: apps/dashboard/src/lib/composition.ts
  function composeEventHandlers (line 7) | function composeEventHandlers<E>(
  type PossibleRef (line 28) | type PossibleRef<T> = React.Ref<T> | undefined;
  function setRef (line 34) | function setRef<T>(ref: PossibleRef<T>, value: T) {
  function composeRefs (line 48) | function composeRefs<T>(...refs: PossibleRef<T>[]): React.RefCallback<T> {
  function useComposedRefs (line 82) | function useComposedRefs<T>(...refs: PossibleRef<T>[]): React.RefCallbac...

FILE: apps/dashboard/src/lib/domains.ts
  function extractDomain (line 23) | function extractDomain(url: string) {

FILE: apps/dashboard/src/lib/formatter.ts
  function formatMilliseconds (line 3) | function formatMilliseconds(ms: number) {
  function formatPercentage (line 18) | function formatPercentage(value: number) {
  function formatNumber (line 27) | function formatNumber(value: number) {
  function formatDate (line 33) | function formatDate(date: Date) {
  function formatDateTime (line 41) | function formatDateTime(date: Date) {
  function formatTime (line 50) | function formatTime(date: Date) {
  function formatDateRange (line 57) | function formatDateRange(from?: Date, to?: Date) {
  function formatDateForInput (line 86) | function formatDateForInput(date: Date): string {

FILE: apps/dashboard/src/lib/trpc/client.tsx
  function makeQueryClient (line 14) | function makeQueryClient() {
  function getQueryClient (line 26) | function getQueryClient() {
  function TRPCReactProvider (line 39) | function TRPCReactProvider({ children }: { children: React.ReactNode }) {

FILE: apps/dashboard/src/lib/trpc/query-client.ts
  function makeQueryClient (line 6) | function makeQueryClient() {

FILE: apps/dashboard/src/lib/trpc/server.tsx
  function HydrateClient (line 50) | function HydrateClient(props: { children: React.ReactNode }) {
  function prefetch (line 61) | function prefetch<T extends ReturnType<TRPCQueryOptions<any>>>(
  function batchPrefetch (line 75) | function batchPrefetch<T extends ReturnType<TRPCQueryOptions<any>>>(

FILE: apps/dashboard/src/lib/utils.ts
  function cn (line 4) | function cn(...inputs: ClassValue[]) {

FILE: apps/dashboard/src/next-auth.d.ts
  type User (line 5) | interface User extends DefaultUserSchema {}

FILE: apps/dashboard/src/scripts/export-blog-post-metrics.ts
  constant MONITOR_ID (line 10) | const MONITOR_ID = "7002";
  constant PERIOD (line 11) | const PERIOD = "7d" as const;
  constant INTERVAL (line 12) | const INTERVAL = 60;
  constant TYPE (line 13) | const TYPE = "http" as const;
  constant OUTPUT_FILE (line 14) | const OUTPUT_FILE = "blog-post-metrics.json";
  constant PERCENTILE (line 15) | const PERCENTILE = "p50";
  function main (line 17) | async function main() {

FILE: apps/docs/src/components/utils.ts
  type Status (line 1) | type Status =
  type StatusResponse (line 10) | type StatusResponse = { status: Status };
  function getStatus (line 46) | async function getStatus(slug: string): Promise<StatusResponse> {

FILE: apps/private-location/cmd/server/main.go
  function gracefulShutdown (line 15) | func gracefulShutdown(apiServer *http.Server, cleanup func(context.Conte...
  function main (line 43) | func main() {

FILE: apps/private-location/internal/database/database.go
  function New (line 20) | func New() *sqlx.DB {
  function Close (line 40) | func Close() error {

FILE: apps/private-location/internal/database/models.go
  type JobType (line 6) | type JobType
  constant JobTypeTCP (line 9) | JobTypeTCP  JobType = "tcp"
  constant JobTypeUDP (line 10) | JobTypeUDP  JobType = "udp"
  constant JobTypeHTTP (line 11) | JobTypeHTTP JobType = "http"
  constant JobTypeDNS (line 12) | JobTypeDNS  JobType = "dns"
  type Monitor (line 15) | type Monitor struct
  type PrivateLocation (line 43) | type PrivateLocation struct

FILE: apps/private-location/internal/logs/logs.go
  function ShouldSample (line 9) | func ShouldSample(event map[string]any) bool {
  function MapToAttrs (line 37) | func MapToAttrs(m map[string]any) []slog.Attr {
  function toAttr (line 45) | func toAttr(key string, value any) slog.Attr {
  function MapToAny (line 68) | func MapToAny(m map[string]any) []any {

FILE: apps/private-location/internal/logs/logs_test.go
  function TestShouldSample (line 11) | func TestShouldSample(t *testing.T) {
  function TestShouldSample_RandomSampling (line 105) | func TestShouldSample_RandomSampling(t *testing.T) {
  function TestShouldSample_EmptyEvent (line 131) | func TestShouldSample_EmptyEvent(t *testing.T) {
  function TestShouldSample_MissingFields (line 139) | func TestShouldSample_MissingFields(t *testing.T) {
  function TestMapToAttrs (line 150) | func TestMapToAttrs(t *testing.T) {
  function TestMapToAttrs_TypeConversions (line 189) | func TestMapToAttrs_TypeConversions(t *testing.T) {
  function TestMapToAttrs_NestedMap (line 247) | func TestMapToAttrs_NestedMap(t *testing.T) {
  function TestMapToAttrs_UnknownType (line 270) | func TestMapToAttrs_UnknownType(t *testing.T) {
  function TestMapToAny (line 294) | func TestMapToAny(t *testing.T) {
  function TestMapToAny_EmptyMap (line 315) | func TestMapToAny_EmptyMap(t *testing.T) {

FILE: apps/private-location/internal/models/assertions.go
  type AssertionType (line 5) | type AssertionType
  constant AssertionHeader (line 8) | AssertionHeader    AssertionType = "header"
  constant AssertionTextBody (line 9) | AssertionTextBody  AssertionType = "textBody"
  constant AssertionStatus (line 10) | AssertionStatus    AssertionType = "status"
  constant AssertionJsonBody (line 11) | AssertionJsonBody  AssertionType = "jsonBody"
  constant AssertionDnsRecord (line 12) | AssertionDnsRecord AssertionType = "dnsRecord"
  type StringComparator (line 15) | type StringComparator
    method String (line 17) | func (c StringComparator) String() string {
  constant StringContains (line 26) | StringContains         StringComparator = "contains"
  constant StringNotContains (line 27) | StringNotContains      StringComparator = "not_contains"
  constant StringEquals (line 28) | StringEquals           StringComparator = "eq"
  constant StringNotEquals (line 29) | StringNotEquals        StringComparator = "not_eq"
  constant StringEmpty (line 30) | StringEmpty            StringComparator = "empty"
  constant StringNotEmpty (line 31) | StringNotEmpty         StringComparator = "not_empty"
  constant StringGreaterThan (line 32) | StringGreaterThan      StringComparator = "gt"
  constant StringGreaterThanEqual (line 33) | StringGreaterThanEqual StringComparator = "gte"
  constant StringLowerThan (line 34) | StringLowerThan        StringComparator = "lt"
  constant StringLowerThanEqual (line 35) | StringLowerThanEqual   StringComparator = "lte"
  type NumberComparator (line 38) | type NumberComparator
    method String (line 21) | func (c NumberComparator) String() string {
  constant NumberEquals (line 41) | NumberEquals           NumberComparator = "eq"
  constant NumberNotEquals (line 42) | NumberNotEquals        NumberComparator = "not_eq"
  constant NumberGreaterThan (line 43) | NumberGreaterThan      NumberComparator = "gt"
  constant NumberGreaterThanEqual (line 44) | NumberGreaterThanEqual NumberComparator = "gte"
  constant NumberLowerThan (line 45) | NumberLowerThan        NumberComparator = "lt"
  constant NumberLowerThanEqual (line 46) | NumberLowerThanEqual   NumberComparator = "lte"
  type Assertion (line 49) | type Assertion struct
  type StatusTarget (line 55) | type StatusTarget struct
  type HeaderTarget (line 61) | type HeaderTarget struct
  type StringTargetType (line 68) | type StringTargetType struct
  type BodyString (line 73) | type BodyString struct
  type RecordComparator (line 79) | type RecordComparator
  constant RecordEquals (line 82) | RecordEquals      RecordComparator = "eq"
  constant RecordNotEquals (line 83) | RecordNotEquals   RecordComparator = "not_eq"
  constant RecordContains (line 84) | RecordContains    RecordComparator = "contains"
  constant RecordNotContains (line 85) | RecordNotContains RecordComparator = "not_contains"
  type RecordTarget (line 88) | type RecordTarget struct

FILE: apps/private-location/internal/server/ingest_common.go
  type ingestContext (line 11) | type ingestContext struct
  method getIngestContext (line 17) | func (h *privateLocationHandler) getIngestContext(ctx context.Context, t...
  method sendEventAndUpdateLastSeen (line 51) | func (h *privateLocationHandler) sendEventAndUpdateLastSeen(ctx context....

FILE: apps/private-location/internal/server/ingest_dns.go
  type DNSResponse (line 12) | type DNSResponse struct
  method IngestDNS (line 32) | func (h *privateLocationHandler) IngestDNS(ctx context.Context, req *con...

FILE: apps/private-location/internal/server/ingest_dns_test.go
  function TestIngestDNS_Unauthenticated (line 14) | func TestIngestDNS_Unauthenticated(t *testing.T) {
  function TestIngestDNS_ValidationError_EmptyID (line 31) | func TestIngestDNS_ValidationError_EmptyID(t *testing.T) {
  function TestIngestDNS_ValidationError_InvalidTimestamp (line 52) | func TestIngestDNS_ValidationError_InvalidTimestamp(t *testing.T) {
  function TestIngestDNS_ValidationError_NegativeLatency (line 73) | func TestIngestDNS_ValidationError_NegativeLatency(t *testing.T) {
  function TestIngestDNS_DBError (line 95) | func TestIngestDNS_DBError(t *testing.T) {
  function TestIngestDNS_MonitorNotExist (line 116) | func TestIngestDNS_MonitorNotExist(t *testing.T) {
  function TestIngestDNS_MonitorExist (line 137) | func TestIngestDNS_MonitorExist(t *testing.T) {
  function TestIngestDNS_WithRecords (line 160) | func TestIngestDNS_WithRecords(t *testing.T) {
  function TestIngestDNS_WithError (line 190) | func TestIngestDNS_WithError(t *testing.T) {

FILE: apps/private-location/internal/server/ingest_http.go
  type EventHolder (line 12) | type EventHolder struct
  type PingData (line 16) | type PingData struct
  method IngestHTTP (line 37) | func (h *privateLocationHandler) IngestHTTP(ctx context.Context, req *co...

FILE: apps/private-location/internal/server/ingest_http_test.go
  function testDB (line 18) | func testDB() *sqlx.DB {
  type interceptorHTTPClient (line 34) | type interceptorHTTPClient struct
    method RoundTrip (line 38) | func (i *interceptorHTTPClient) RoundTrip(req *http.Request) (*http.Re...
    method GetHTTPClient (line 42) | func (i *interceptorHTTPClient) GetHTTPClient() *http.Client {
  function getTBClient (line 48) | func getTBClient(ctx context.Context) tinybird.Client {
  function TestIngestHTTP_Unauthenticated (line 61) | func TestIngestHTTP_Unauthenticated(t *testing.T) {
  function TestIngestHTTP_DBError (line 78) | func TestIngestHTTP_DBError(t *testing.T) {
  function TestIngestHTTP_MonitorNotExist (line 98) | func TestIngestHTTP_MonitorNotExist(t *testing.T) {
  function TestIngestHTTP_MonitorExist (line 118) | func TestIngestHTTP_MonitorExist(t *testing.T) {
  function TestIngestHTTP_ValidationError_EmptyMonitorID (line 136) | func TestIngestHTTP_ValidationError_EmptyMonitorID(t *testing.T) {
  function TestIngestHTTP_ValidationError_InvalidTimestamp (line 157) | func TestIngestHTTP_ValidationError_InvalidTimestamp(t *testing.T) {
  function TestIngestHTTP_ValidationError_NegativeLatency (line 178) | func TestIngestHTTP_ValidationError_NegativeLatency(t *testing.T) {
  function TestIngestHTTP_WithFullData (line 200) | func TestIngestHTTP_WithFullData(t *testing.T) {
  function TestIngestHTTP_WithError (line 226) | func TestIngestHTTP_WithError(t *testing.T) {

FILE: apps/private-location/internal/server/ingest_tcp.go
  type TCPData (line 12) | type TCPData struct
  method IngestTCP (line 31) | func (h *privateLocationHandler) IngestTCP(ctx context.Context, req *con...

FILE: apps/private-location/internal/server/ingest_tcp_test.go
  function TestIngestTCP_Unauthenticated (line 15) | func TestIngestTCP_Unauthenticated(t *testing.T) {
  function TestIngestTCP_DBError (line 32) | func TestIngestTCP_DBError(t *testing.T) {
  function TestIngestTCP_ValidationError_EmptyID (line 51) | func TestIngestTCP_ValidationError_EmptyID(t *testing.T) {
  function TestIngestTCP_ValidationError_InvalidTimestamp (line 72) | func TestIngestTCP_ValidationError_InvalidTimestamp(t *testing.T) {
  function TestIngestTCP_ValidationError_NegativeLatency (line 93) | func TestIngestTCP_ValidationError_NegativeLatency(t *testing.T) {
  function TestIngestTCP_MonitorNotExist (line 115) | func TestIngestTCP_MonitorNotExist(t *testing.T) {
  function TestIngestTCP_MonitorExist (line 136) | func TestIngestTCP_MonitorExist(t *testing.T) {
  function TestIngestTCP_WithError (line 158) | func TestIngestTCP_WithError(t *testing.T) {

FILE: apps/private-location/internal/server/monitors.go
  function convertNumberComparator (line 16) | func convertNumberComparator(m models.NumberComparator) private_location...
  function convertStringComparator (line 36) | func convertStringComparator(m models.StringComparator) private_location...
  function convertRecordComparator (line 56) | func convertRecordComparator(m models.RecordComparator) private_location...
  function addParseError (line 72) | func addParseError(ctx context.Context, errorType string, err error) {
  function ParseAssertions (line 87) | func ParseAssertions(ctx context.Context, assertions sql.NullString) (
  function ParseRecordAssertions (line 144) | func ParseRecordAssertions(ctx context.Context, assertions sql.NullStrin...
  method Monitors (line 176) | func (h *privateLocationHandler) Monitors(ctx context.Context, req *conn...

FILE: apps/private-location/internal/server/monitors_test.go
  function TestParseAssertions_TextBodyContains (line 13) | func TestParseAssertions_TextBodyContains(t *testing.T) {
  function TestParseAssertions_HttpStatusEquals (line 37) | func TestParseAssertions_HttpStatusEquals(t *testing.T) {
  function TestParseAssertions_InvalidJSON (line 61) | func TestParseAssertions_InvalidJSON(t *testing.T) {
  function TestParseAssertions_NullString (line 75) | func TestParseAssertions_NullString(t *testing.T) {
  function TestParseAssertions_HeaderAssertion (line 89) | func TestParseAssertions_HeaderAssertion(t *testing.T) {
  function TestParseAssertions_MultipleAssertions (line 114) | func TestParseAssertions_MultipleAssertions(t *testing.T) {
  function TestMonitors_Unauthenticated (line 138) | func TestMonitors_Unauthenticated(t *testing.T) {
  function TestMonitors_InvalidToken (line 155) | func TestMonitors_InvalidToken(t *testing.T) {
  function TestMonitors_ReturnsHTTPTCPAndDNSMonitors (line 179) | func TestMonitors_ReturnsHTTPTCPAndDNSMonitors(t *testing.T) {
  function TestMonitors_HTTPMonitorFields (line 209) | func TestMonitors_HTTPMonitorFields(t *testing.T) {
  function TestMonitors_TCPMonitorFields (line 241) | func TestMonitors_TCPMonitorFields(t *testing.T) {
  function TestParseRecordAssertions_DnsRecordContains (line 276) | func TestParseRecordAssertions_DnsRecordContains(t *testing.T) {
  function TestParseRecordAssertions_DnsRecordEquals (line 301) | func TestParseRecordAssertions_DnsRecordEquals(t *testing.T) {
  function TestParseRecordAssertions_MultipleRecordTypes (line 326) | func TestParseRecordAssertions_MultipleRecordTypes(t *testing.T) {
  function TestParseRecordAssertions_InvalidJSON (line 368) | func TestParseRecordAssertions_InvalidJSON(t *testing.T) {
  function TestParseRecordAssertions_NullString (line 381) | func TestParseRecordAssertions_NullString(t *testing.T) {
  function TestParseRecordAssertions_MixedAssertionTypes (line 394) | func TestParseRecordAssertions_MixedAssertionTypes(t *testing.T) {
  function TestMonitors_DNSMonitorFields (line 417) | func TestMonitors_DNSMonitorFields(t *testing.T) {
  function TestParseRecordAssertions_EmptyArray (line 452) | func TestParseRecordAssertions_EmptyArray(t *testing.T) {
  function TestParseRecordAssertions_UnknownComparator (line 465) | func TestParseRecordAssertions_UnknownComparator(t *testing.T) {
  function TestParseRecordAssertions_UnknownRecordType (line 484) | func TestParseRecordAssertions_UnknownRecordType(t *testing.T) {
  function TestParseRecordAssertions_MissingRequiredFields (line 504) | func TestParseRecordAssertions_MissingRequiredFields(t *testing.T) {
  function TestMonitors_DNSMonitorWithRecordAssertions (line 560) | func TestMonitors_DNSMonitorWithRecordAssertions(t *testing.T) {

FILE: apps/private-location/internal/server/routes.go
  type contextKey (line 20) | type contextKey
  constant requestIDKey (line 23) | requestIDKey contextKey = "request_id"
  constant eventKey (line 24) | eventKey     contextKey = "event"
  type responseWriter (line 28) | type responseWriter struct
    method WriteHeader (line 33) | func (rw *responseWriter) WriteHeader(code int) {
    method Write (line 38) | func (rw *responseWriter) Write(b []byte) (int, error) {
  function Logger (line 46) | func Logger() func(next http.Handler) http.Handler {
  function GetRequestID (line 116) | func GetRequestID(ctx context.Context) string {
  function GetEvent (line 124) | func GetEvent(ctx context.Context) *EventHolder {
  type privateLocationHandler (line 131) | type privateLocationHandler struct
  function NewPrivateLocationServer (line 136) | func NewPrivateLocationServer(db *sqlx.DB, tbClient tinybird.Client) *pr...
  method RegisterRoutes (line 144) | func (s *Server) RegisterRoutes() http.Handler {
  method healthHandler (line 169) | func (s *Server) healthHandler(w http.ResponseWriter, r *http.Request) {

FILE: apps/private-location/internal/server/server.go
  type Server (line 27) | type Server struct
  function NewServer (line 38) | func NewServer() (*http.Server, func(context.Context)) {
  function setupLogger (line 86) | func setupLogger() (*slog.Logger, *sdklog.LoggerProvider) {
  function env (line 134) | func env(key, fallback string) string {

FILE: apps/private-location/internal/server/validation.go
  function ValidateIngestHTTPRequest (line 20) | func ValidateIngestHTTPRequest(req *private_locationv1.IngestHTTPRequest...
  function ValidateIngestTCPRequest (line 34) | func ValidateIngestTCPRequest(req *private_locationv1.IngestTCPRequest) ...
  function ValidateIngestDNSRequest (line 48) | func ValidateIngestDNSRequest(req *private_locationv1.IngestDNSRequest) ...
  function NewValidationError (line 62) | func NewValidationError(err error) *connect.Error {

FILE: apps/private-location/internal/server/validation_test.go
  function TestValidateIngestHTTPRequest (line 11) | func TestValidateIngestHTTPRequest(t *testing.T) {
  function TestValidateIngestTCPRequest (line 83) | func TestValidateIngestTCPRequest(t *testing.T) {
  function TestValidateIngestDNSRequest (line 155) | func TestValidateIngestDNSRequest(t *testing.T) {
  function TestNewValidationError (line 227) | func TestNewValidationError(t *testing.T) {

FILE: apps/private-location/internal/tinybird/client.go
  constant DatasourceHTTP (line 15) | DatasourceHTTP = "ping_response__v8"
  constant DatasourceTCP (line 16) | DatasourceTCP  = "tcp_response__v0"
  constant DatasourceDNS (line 17) | DatasourceDNS  = "tcp_dns__v0"
  function getBaseURL (line 20) | func getBaseURL() string {
  type Client (line 29) | type Client interface
  type client (line 33) | type client struct
    method SendEvent (line 47) | func (c client) SendEvent(ctx context.Context, event any, dataSourceNa...
  function NewClient (line 39) | func NewClient(httpClient *http.Client, apiKey string) Client {

FILE: apps/private-location/internal/tinybird/client_test.go
  type interceptorHTTPClient (line 12) | type interceptorHTTPClient struct
    method RoundTrip (line 16) | func (i *interceptorHTTPClient) RoundTrip(req *http.Request) (*http.Re...
    method GetHTTPClient (line 20) | func (i *interceptorHTTPClient) GetHTTPClient() *http.Client {
  function TestSendEvent (line 26) | func TestSendEvent(t *testing.T) {

FILE: apps/private-location/proto/private_location/v1/assertions.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  type NumberComparator (line 24) | type NumberComparator
    method Enum (line 58) | func (x NumberComparator) Enum() *NumberComparator {
    method String (line 64) | func (x NumberComparator) String() string {
    method Descriptor (line 68) | func (NumberComparator) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 72) | func (NumberComparator) Type() protoreflect.EnumType {
    method Number (line 76) | func (x NumberComparator) Number() protoreflect.EnumNumber {
    method EnumDescriptor (line 81) | func (NumberComparator) EnumDescriptor() ([]byte, []int) {
  constant NumberComparator_NUMBER_COMPARATOR_UNSPECIFIED (line 27) | NumberComparator_NUMBER_COMPARATOR_UNSPECIFIED           NumberComparato...
  constant NumberComparator_NUMBER_COMPARATOR_EQUAL (line 28) | NumberComparator_NUMBER_COMPARATOR_EQUAL                 NumberComparato...
  constant NumberComparator_NUMBER_COMPARATOR_NOT_EQUAL (line 29) | NumberComparator_NUMBER_COMPARATOR_NOT_EQUAL             NumberComparato...
  constant NumberComparator_NUMBER_COMPARATOR_GREATER_THAN (line 30) | NumberComparator_NUMBER_COMPARATOR_GREATER_THAN          NumberComparato...
  constant NumberComparator_NUMBER_COMPARATOR_GREATER_THAN_OR_EQUAL (line 31) | NumberComparator_NUMBER_COMPARATOR_GREATER_THAN_OR_EQUAL NumberComparato...
  constant NumberComparator_NUMBER_COMPARATOR_LESS_THAN (line 32) | NumberComparator_NUMBER_COMPARATOR_LESS_THAN             NumberComparato...
  constant NumberComparator_NUMBER_COMPARATOR_LESS_THAN_OR_EQUAL (line 33) | NumberComparator_NUMBER_COMPARATOR_LESS_THAN_OR_EQUAL    NumberComparato...
  type StringComparator (line 85) | type StringComparator
    method Enum (line 131) | func (x StringComparator) Enum() *StringComparator {
    method String (line 137) | func (x StringComparator) String() string {
    method Descriptor (line 141) | func (StringComparator) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 145) | func (StringComparator) Type() protoreflect.EnumType {
    method Number (line 149) | func (x StringComparator) Number() protoreflect.EnumNumber {
    method EnumDescriptor (line 154) | func (StringComparator) EnumDescriptor() ([]byte, []int) {
  constant StringComparator_STRING_COMPARATOR_UNSPECIFIED (line 88) | StringComparator_STRING_COMPARATOR_UNSPECIFIED           StringComparato...
  constant StringComparator_STRING_COMPARATOR_CONTAINS (line 89) | StringComparator_STRING_COMPARATOR_CONTAINS              StringComparato...
  constant StringComparator_STRING_COMPARATOR_NOT_CONTAINS (line 90) | StringComparator_STRING_COMPARATOR_NOT_CONTAINS          StringComparato...
  constant StringComparator_STRING_COMPARATOR_EQUAL (line 91) | StringComparator_STRING_COMPARATOR_EQUAL                 StringComparato...
  constant StringComparator_STRING_COMPARATOR_NOT_EQUAL (line 92) | StringComparator_STRING_COMPARATOR_NOT_EQUAL             StringComparato...
  constant StringComparator_STRING_COMPARATOR_EMPTY (line 93) | StringComparator_STRING_COMPARATOR_EMPTY                 StringComparato...
  constant StringComparator_STRING_COMPARATOR_NOT_EMPTY (line 94) | StringComparator_STRING_COMPARATOR_NOT_EMPTY             StringComparato...
  constant StringComparator_STRING_COMPARATOR_GREATER_THAN (line 95) | StringComparator_STRING_COMPARATOR_GREATER_THAN          StringComparato...
  constant StringComparator_STRING_COMPARATOR_GREATER_THAN_OR_EQUAL (line 96) | StringComparator_STRING_COMPARATOR_GREATER_THAN_OR_EQUAL StringComparato...
  constant StringComparator_STRING_COMPARATOR_LESS_THAN (line 97) | StringComparator_STRING_COMPARATOR_LESS_THAN             StringComparato...
  constant StringComparator_STRING_COMPARATOR_LESS_THAN_OR_EQUAL (line 98) | StringComparator_STRING_COMPARATOR_LESS_THAN_OR_EQUAL    StringComparato...
  type RecordComparator (line 158) | type RecordComparator
    method Enum (line 186) | func (x RecordComparator) Enum() *RecordComparator {
    method String (line 192) | func (x RecordComparator) String() string {
    method Descriptor (line 196) | func (RecordComparator) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 200) | func (RecordComparator) Type() protoreflect.EnumType {
    method Number (line 204) | func (x RecordComparator) Number() protoreflect.EnumNumber {
    method EnumDescriptor (line 209) | func (RecordComparator) EnumDescriptor() ([]byte, []int) {
  constant RecordComparator_RECORD_COMPARATOR_UNSPECIFIED (line 161) | RecordComparator_RECORD_COMPARATOR_UNSPECIFIED  RecordComparator = 0
  constant RecordComparator_RECORD_COMPARATOR_EQUAL (line 162) | RecordComparator_RECORD_COMPARATOR_EQUAL        RecordComparator = 1
  constant RecordComparator_RECORD_COMPARATOR_NOT_EQUAL (line 163) | RecordComparator_RECORD_COMPARATOR_NOT_EQUAL    RecordComparator = 2
  constant RecordComparator_RECORD_COMPARATOR_CONTAINS (line 164) | RecordComparator_RECORD_COMPARATOR_CONTAINS     RecordComparator = 3
  constant RecordComparator_RECORD_COMPARATOR_NOT_CONTAINS (line 165) | RecordComparator_RECORD_COMPARATOR_NOT_CONTAINS RecordComparator = 4
  type StatusCodeAssertion (line 213) | type StatusCodeAssertion struct
    method Reset (line 221) | func (x *StatusCodeAssertion) Reset() {
    method String (line 228) | func (x *StatusCodeAssertion) String() string {
    method ProtoMessage (line 232) | func (*StatusCodeAssertion) ProtoMessage() {}
    method ProtoReflect (line 234) | func (x *StatusCodeAssertion) ProtoReflect() protoreflect.Message {
    method Descriptor (line 247) | func (*StatusCodeAssertion) Descriptor() ([]byte, []int) {
    method GetTarget (line 251) | func (x *StatusCodeAssertion) GetTarget() int64 {
    method GetComparator (line 258) | func (x *StatusCodeAssertion) GetComparator() NumberComparator {
  type BodyAssertion (line 265) | type BodyAssertion struct
    method Reset (line 273) | func (x *BodyAssertion) Reset() {
    method String (line 280) | func (x *BodyAssertion) String() string {
    method ProtoMessage (line 284) | func (*BodyAssertion) ProtoMessage() {}
    method ProtoReflect (line 286) | func (x *BodyAssertion) ProtoReflect() protoreflect.Message {
    method Descriptor (line 299) | func (*BodyAssertion) Descriptor() ([]byte, []int) {
    method GetTarget (line 303) | func (x *BodyAssertion) GetTarget() string {
    method GetComparator (line 310) | func (x *BodyAssertion) GetComparator() StringComparator {
  type HeaderAssertion (line 317) | type HeaderAssertion struct
    method Reset (line 326) | func (x *HeaderAssertion) Reset() {
    method String (line 333) | func (x *HeaderAssertion) String() string {
    method ProtoMessage (line 337) | func (*HeaderAssertion) ProtoMessage() {}
    method ProtoReflect (line 339) | func (x *HeaderAssertion) ProtoReflect() protoreflect.Message {
    method Descriptor (line 352) | func (*HeaderAssertion) Descriptor() ([]byte, []int) {
    method GetTarget (line 356) | func (x *HeaderAssertion) GetTarget() string {
    method GetComparator (line 363) | func (x *HeaderAssertion) GetComparator() StringComparator {
    method GetKey (line 370) | func (x *HeaderAssertion) GetKey() string {
  type RecordAssertion (line 377) | type RecordAssertion struct
    method Reset (line 386) | func (x *RecordAssertion) Reset() {
    method String (line 393) | func (x *RecordAssertion) String() string {
    method ProtoMessage (line 397) | func (*RecordAssertion) ProtoMessage() {}
    method ProtoReflect (line 399) | func (x *RecordAssertion) ProtoReflect() protoreflect.Message {
    method Descriptor (line 412) | func (*RecordAssertion) Descriptor() ([]byte, []int) {
    method GetRecord (line 416) | func (x *RecordAssertion) GetRecord() string {
    method GetComparator (line 423) | func (x *RecordAssertion) GetComparator() RecordComparator {
    method GetTarget (line 430) | func (x *RecordAssertion) GetTarget() string {
  constant file_private_location_v1_assertions_proto_rawDesc (line 439) | file_private_location_v1_assertions_proto_rawDesc = "" +
  function file_private_location_v1_assertions_proto_rawDescGZIP (line 497) | func file_private_location_v1_assertions_proto_rawDescGZIP() []byte {
  function init (line 527) | func init() { file_private_location_v1_assertions_proto_init() }
  function file_private_location_v1_assertions_proto_init (line 528) | func file_private_location_v1_assertions_proto_init() {

FILE: apps/private-location/proto/private_location/v1/dns_monitor.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  type DNSMonitor (line 24) | type DNSMonitor struct
    method Reset (line 37) | func (x *DNSMonitor) Reset() {
    method String (line 44) | func (x *DNSMonitor) String() string {
    method ProtoMessage (line 48) | func (*DNSMonitor) ProtoMessage() {}
    method ProtoReflect (line 50) | func (x *DNSMonitor) ProtoReflect() protoreflect.Message {
    method Descriptor (line 63) | func (*DNSMonitor) Descriptor() ([]byte, []int) {
    method GetId (line 67) | func (x *DNSMonitor) GetId() string {
    method GetUri (line 74) | func (x *DNSMonitor) GetUri() string {
    method GetTimeout (line 81) | func (x *DNSMonitor) GetTimeout() int64 {
    method GetDegradedAt (line 88) | func (x *DNSMonitor) GetDegradedAt() int64 {
    method GetPeriodicity (line 95) | func (x *DNSMonitor) GetPeriodicity() string {
    method GetRetry (line 102) | func (x *DNSMonitor) GetRetry() int64 {
    method GetRecordAssertions (line 109) | func (x *DNSMonitor) GetRecordAssertions() []*RecordAssertion {
  constant file_private_location_v1_dns_monitor_proto_rawDesc (line 118) | file_private_location_v1_dns_monitor_proto_rawDesc = "" +
  function file_private_location_v1_dns_monitor_proto_rawDescGZIP (line 138) | func file_private_location_v1_dns_monitor_proto_rawDescGZIP() []byte {
  function init (line 159) | func init() { file_private_location_v1_dns_monitor_proto_init() }
  function file_private_location_v1_dns_monitor_proto_init (line 160) | func file_private_location_v1_dns_monitor_proto_init() {

FILE: apps/private-location/proto/private_location/v1/http_monitor.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  type Headers (line 24) | type Headers struct
    method Reset (line 32) | func (x *Headers) Reset() {
    method String (line 39) | func (x *Headers) String() string {
    method ProtoMessage (line 43) | func (*Headers) ProtoMessage() {}
    method ProtoReflect (line 45) | func (x *Headers) ProtoReflect() protoreflect.Message {
    method Descriptor (line 58) | func (*Headers) Descriptor() ([]byte, []int) {
    method GetKey (line 62) | func (x *Headers) GetKey() string {
    method GetValue (line 69) | func (x *Headers) GetValue() string {
  type HTTPMonitor (line 76) | type HTTPMonitor struct
    method Reset (line 95) | func (x *HTTPMonitor) Reset() {
    method String (line 102) | func (x *HTTPMonitor) String() string {
    method ProtoMessage (line 106) | func (*HTTPMonitor) ProtoMessage() {}
    method ProtoReflect (line 108) | func (x *HTTPMonitor) ProtoReflect() protoreflect.Message {
    method Descriptor (line 121) | func (*HTTPMonitor) Descriptor() ([]byte, []int) {
    method GetId (line 125) | func (x *HTTPMonitor) GetId() string {
    method GetUrl (line 132) | func (x *HTTPMonitor) GetUrl() string {
    method GetPeriodicity (line 139) | func (x *HTTPMonitor) GetPeriodicity() string {
    method GetMethod (line 146) | func (x *HTTPMonitor) GetMethod() string {
    method GetBody (line 153) | func (x *HTTPMonitor) GetBody() string {
    method GetTimeout (line 160) | func (x *HTTPMonitor) GetTimeout() int64 {
    method GetDegradedAt (line 167) | func (x *HTTPMonitor) GetDegradedAt() int64 {
    method GetRetry (line 174) | func (x *HTTPMonitor) GetRetry() int64 {
    method GetFollowRedirects (line 181) | func (x *HTTPMonitor) GetFollowRedirects() bool {
    method GetHeaders (line 188) | func (x *HTTPMonitor) GetHeaders() []*Headers {
    method GetStatusCodeAssertions (line 195) | func (x *HTTPMonitor) GetStatusCodeAssertions() []*StatusCodeAssertion {
    method GetBodyAssertions (line 202) | func (x *HTTPMonitor) GetBodyAssertions() []*BodyAssertion {
    method GetHeaderAssertions (line 209) | func (x *HTTPMonitor) GetHeaderAssertions() []*HeaderAssertion {
  constant file_private_location_v1_http_monitor_proto_rawDesc (line 218) | file_private_location_v1_http_monitor_proto_rawDesc = "" +
  function file_private_location_v1_http_monitor_proto_rawDescGZIP (line 247) | func file_private_location_v1_http_monitor_proto_rawDescGZIP() []byte {
  function init (line 274) | func init() { file_private_location_v1_http_monitor_proto_init() }
  function file_private_location_v1_http_monitor_proto_init (line 275) | func file_private_location_v1_http_monitor_proto_init() {

FILE: apps/private-location/proto/private_location/v1/private_location.connect.go
  constant _ (line 20) | _ = connect.IsAtLeastVersion1_13_0
  constant PrivateLocationServiceName (line 24) | PrivateLocationServiceName = "private_location.v1.PrivateLocationService"
  constant PrivateLocationServiceMonitorsProcedure (line 37) | PrivateLocationServiceMonitorsProcedure = "/private_location.v1.PrivateL...
  constant PrivateLocationServiceIngestTCPProcedure (line 40) | PrivateLocationServiceIngestTCPProcedure = "/private_location.v1.Private...
  constant PrivateLocationServiceIngestHTTPProcedure (line 43) | PrivateLocationServiceIngestHTTPProcedure = "/private_location.v1.Privat...
  constant PrivateLocationServiceIngestDNSProcedure (line 46) | PrivateLocationServiceIngestDNSProcedure = "/private_location.v1.Private...
  type PrivateLocationServiceClient (line 51) | type PrivateLocationServiceClient interface
  function NewPrivateLocationServiceClient (line 65) | func NewPrivateLocationServiceClient(httpClient connect.HTTPClient, base...
  type privateLocationServiceClient (line 97) | type privateLocationServiceClient struct
    method Monitors (line 105) | func (c *privateLocationServiceClient) Monitors(ctx context.Context, r...
    method IngestTCP (line 110) | func (c *privateLocationServiceClient) IngestTCP(ctx context.Context, ...
    method IngestHTTP (line 115) | func (c *privateLocationServiceClient) IngestHTTP(ctx context.Context,...
    method IngestDNS (line 120) | func (c *privateLocationServiceClient) IngestDNS(ctx context.Context, ...
  type PrivateLocationServiceHandler (line 126) | type PrivateLocationServiceHandler interface
  function NewPrivateLocationServiceHandler (line 138) | func NewPrivateLocationServiceHandler(svc PrivateLocationServiceHandler,...
  type UnimplementedPrivateLocationServiceHandler (line 181) | type UnimplementedPrivateLocationServiceHandler struct
    method Monitors (line 183) | func (UnimplementedPrivateLocationServiceHandler) Monitors(context.Con...
    method IngestTCP (line 187) | func (UnimplementedPrivateLocationServiceHandler) IngestTCP(context.Co...
    method IngestHTTP (line 191) | func (UnimplementedPrivateLocationServiceHandler) IngestHTTP(context.C...
    method IngestDNS (line 195) | func (UnimplementedPrivateLocationServiceHandler) IngestDNS(context.Co...

FILE: apps/private-location/proto/private_location/v1/private_location.pb.go
  constant _ (line 20) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 22) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  type MonitorsRequest (line 25) | type MonitorsRequest struct
    method Reset (line 31) | func (x *MonitorsRequest) Reset() {
    method String (line 38) | func (x *MonitorsRequest) String() string {
    method ProtoMessage (line 42) | func (*MonitorsRequest) ProtoMessage() {}
    method ProtoReflect (line 44) | func (x *MonitorsRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 57) | func (*MonitorsRequest) Descriptor() ([]byte, []int) {
  type MonitorsResponse (line 61) | type MonitorsResponse struct
    method Reset (line 70) | func (x *MonitorsResponse) Reset() {
    method String (line 77) | func (x *MonitorsResponse) String() string {
    method ProtoMessage (line 81) | func (*MonitorsResponse) ProtoMessage() {}
    method ProtoReflect (line 83) | func (x *MonitorsResponse) ProtoReflect() protoreflect.Message {
    method Descriptor (line 96) | func (*MonitorsResponse) Descriptor() ([]byte, []int) {
    method GetHttpMonitors (line 100) | func (x *MonitorsResponse) GetHttpMonitors() []*HTTPMonitor {
    method GetTcpMonitors (line 107) | func (x *MonitorsResponse) GetTcpMonitors() []*TCPMonitor {
    method GetDnsMonitors (line 114) | func (x *MonitorsResponse) GetDnsMonitors() []*DNSMonitor {
  type IngestTCPRequest (line 121) | type IngestTCPRequest struct
    method Reset (line 137) | func (x *IngestTCPRequest) Reset() {
    method String (line 144) | func (x *IngestTCPRequest) String() string {
    method ProtoMessage (line 148) | func (*IngestTCPRequest) ProtoMessage() {}
    method ProtoReflect (line 150) | func (x *IngestTCPRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 163) | func (*IngestTCPRequest) Descriptor() ([]byte, []int) {
    method GetId (line 167) | func (x *IngestTCPRequest) GetId() string {
    method GetMonitorId (line 174) | func (x *IngestTCPRequest) GetMonitorId() string {
    method GetLatency (line 181) | func (x *IngestTCPRequest) GetLatency() int64 {
    method GetTimestamp (line 188) | func (x *IngestTCPRequest) GetTimestamp() int64 {
    method GetCronTimestamp (line 195) | func (x *IngestTCPRequest) GetCronTimestamp() int64 {
    method GetUri (line 202) | func (x *IngestTCPRequest) GetUri() string {
    method GetMessage (line 209) | func (x *IngestTCPRequest) GetMessage() string {
    method GetRequestStatus (line 216) | func (x *IngestTCPRequest) GetRequestStatus() string {
    method GetError (line 223) | func (x *IngestTCPRequest) GetError() int64 {
    method GetTiming (line 230) | func (x *IngestTCPRequest) GetTiming() string {
  type IngestTCPResponse (line 237) | type IngestTCPResponse struct
    method Reset (line 243) | func (x *IngestTCPResponse) Reset() {
    method String (line 250) | func (x *IngestTCPResponse) String() string {
    method ProtoMessage (line 254) | func (*IngestTCPResponse) ProtoMessage() {}
    method ProtoReflect (line 256) | func (x *IngestTCPResponse) ProtoReflect() protoreflect.Message {
    method Descriptor (line 269) | func (*IngestTCPResponse) Descriptor() ([]byte, []int) {
  type IngestHTTPRequest (line 273) | type IngestHTTPRequest struct
    method Reset (line 292) | func (x *IngestHTTPRequest) Reset() {
    method String (line 299) | func (x *IngestHTTPRequest) String() string {
    method ProtoMessage (line 303) | func (*IngestHTTPRequest) ProtoMessage() {}
    method ProtoReflect (line 305) | func (x *IngestHTTPRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 318) | func (*IngestHTTPRequest) Descriptor() ([]byte, []int) {
    method GetId (line 322) | func (x *IngestHTTPRequest) GetId() string {
    method GetMonitorId (line 329) | func (x *IngestHTTPRequest) GetMonitorId() string {
    method GetLatency (line 336) | func (x *IngestHTTPRequest) GetLatency() int64 {
    method GetTimestamp (line 343) | func (x *IngestHTTPRequest) GetTimestamp() int64 {
    method GetCronTimestamp (line 350) | func (x *IngestHTTPRequest) GetCronTimestamp() int64 {
    method GetUrl (line 357) | func (x *IngestHTTPRequest) GetUrl() string {
    method GetRequestStatus (line 364) | func (x *IngestHTTPRequest) GetRequestStatus() string {
    method GetMessage (line 371) | func (x *IngestHTTPRequest) GetMessage() string {
    method GetBody (line 378) | func (x *IngestHTTPRequest) GetBody() string {
    method GetHeaders (line 385) | func (x *IngestHTTPRequest) GetHeaders() string {
    method GetTiming (line 392) | func (x *IngestHTTPRequest) GetTiming() string {
    method GetStatusCode (line 399) | func (x *IngestHTTPRequest) GetStatusCode() int64 {
    method GetError (line 406) | func (x *IngestHTTPRequest) GetError() int64 {
  type IngestHTTPResponse (line 413) | type IngestHTTPResponse struct
    method Reset (line 419) | func (x *IngestHTTPResponse) Reset() {
    method String (line 426) | func (x *IngestHTTPResponse) String() string {
    method ProtoMessage (line 430) | func (*IngestHTTPResponse) ProtoMessage() {}
    method ProtoReflect (line 432) | func (x *IngestHTTPResponse) ProtoReflect() protoreflect.Message {
    method Descriptor (line 445) | func (*IngestHTTPResponse) Descriptor() ([]byte, []int) {
  type Records (line 449) | type Records struct
    method Reset (line 456) | func (x *Records) Reset() {
    method String (line 463) | func (x *Records) String() string {
    method ProtoMessage (line 467) | func (*Records) ProtoMessage() {}
    method ProtoReflect (line 469) | func (x *Records) ProtoReflect() protoreflect.Message {
    method Descriptor (line 482) | func (*Records) Descriptor() ([]byte, []int) {
    method GetRecord (line 486) | func (x *Records) GetRecord() []string {
  type IngestDNSRequest (line 493) | type IngestDNSRequest struct
    method Reset (line 510) | func (x *IngestDNSRequest) Reset() {
    method String (line 517) | func (x *IngestDNSRequest) String() string {
    method ProtoMessage (line 521) | func (*IngestDNSRequest) ProtoMessage() {}
    method ProtoReflect (line 523) | func (x *IngestDNSRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 536) | func (*IngestDNSRequest) Descriptor() ([]byte, []int) {
    method GetId (line 540) | func (x *IngestDNSRequest) GetId() string {
    method GetMonitorId (line 547) | func (x *IngestDNSRequest) GetMonitorId() string {
    method GetLatency (line 554) | func (x *IngestDNSRequest) GetLatency() int64 {
    method GetTimestamp (line 561) | func (x *IngestDNSRequest) GetTimestamp() int64 {
    method GetCronTimestamp (line 568) | func (x *IngestDNSRequest) GetCronTimestamp() int64 {
    method GetUri (line 575) | func (x *IngestDNSRequest) GetUri() string {
    method GetRequestStatus (line 582) | func (x *IngestDNSRequest) GetRequestStatus() string {
    method GetMessage (line 589) | func (x *IngestDNSRequest) GetMessage() string {
    method GetRecords (line 596) | func (x *IngestDNSRequest) GetRecords() map[string]*Records {
    method GetTiming (line 603) | func (x *IngestDNSRequest) GetTiming() string {
    method GetError (line 610) | func (x *IngestDNSRequest) GetError() int64 {
  type IngestDNSResponse (line 617) | type IngestDNSResponse struct
    method Reset (line 623) | func (x *IngestDNSResponse) Reset() {
    method String (line 630) | func (x *IngestDNSResponse) String() string {
    method ProtoMessage (line 634) | func (*IngestDNSResponse) ProtoMessage() {}
    method ProtoReflect (line 636) | func (x *IngestDNSResponse) ProtoReflect() protoreflect.Message {
    method Descriptor (line 649) | func (*IngestDNSResponse) Descriptor() ([]byte, []int) {
  constant file_private_location_v1_private_location_proto_rawDesc (line 655) | file_private_location_v1_private_location_proto_rawDesc = "" +
  function file_private_location_v1_private_location_proto_rawDescGZIP (line 725) | func file_private_location_v1_private_location_proto_rawDescGZIP() []byte {
  function init (line 769) | func init() { file_private_location_v1_private_location_proto_init() }
  function file_private_location_v1_private_location_proto_init (line 770) | func file_private_location_v1_private_location_proto_init() {

FILE: apps/private-location/proto/private_location/v1/tcp_monitor.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  type TCPMonitor (line 24) | type TCPMonitor struct
    method Reset (line 36) | func (x *TCPMonitor) Reset() {
    method String (line 43) | func (x *TCPMonitor) String() string {
    method ProtoMessage (line 47) | func (*TCPMonitor) ProtoMessage() {}
    method ProtoReflect (line 49) | func (x *TCPMonitor) ProtoReflect() protoreflect.Message {
    method Descriptor (line 62) | func (*TCPMonitor) Descriptor() ([]byte, []int) {
    method GetId (line 66) | func (x *TCPMonitor) GetId() string {
    method GetUri (line 73) | func (x *TCPMonitor) GetUri() string {
    method GetTimeout (line 80) | func (x *TCPMonitor) GetTimeout() int64 {
    method GetDegradedAt (line 87) | func (x *TCPMonitor) GetDegradedAt() int64 {
    method GetPeriodicity (line 94) | func (x *TCPMonitor) GetPeriodicity() string {
    method GetRetry (line 101) | func (x *TCPMonitor) GetRetry() int64 {
  constant file_private_location_v1_tcp_monitor_proto_rawDesc (line 110) | file_private_location_v1_tcp_monitor_proto_rawDesc = "" +
  function file_private_location_v1_tcp_monitor_proto_rawDescGZIP (line 129) | func file_private_location_v1_tcp_monitor_proto_rawDescGZIP() []byte {
  function init (line 148) | func init() { file_private_location_v1_tcp_monitor_proto_init() }
  function file_private_location_v1_tcp_monitor_proto_init (line 149) | func file_private_location_v1_tcp_monitor_proto_init() {

FILE: apps/railway-proxy/main.go
  function proxy (line 18) | func proxy(c *gin.Context) {
  function main (line 48) | func main() {
  function env (line 91) | func env(key, fallback string) string {

FILE: apps/server/src/index.ts
  type Env (line 30) | type Env = {
  function shouldSample (line 89) | function shouldSample(event: Record<string, any>): boolean {

FILE: apps/server/src/libs/checker/utils.ts
  function getCheckerPayload (line 10) | function getCheckerPayload(
  function getCheckerUrl (line 68) | function getCheckerUrl(

FILE: apps/server/src/libs/errors/utils.ts
  class OpenStatusApiError (line 18) | class OpenStatusApiError extends HTTPException {
    method constructor (line 21) | constructor({
  function handleError (line 34) | function handleError(err: Error, c: Context): Response {
  function handleZodError (line 110) | function handleZodError(
  function createErrorSchema (line 136) | function createErrorSchema(code: ErrorCode) {
  type ErrorSchema (line 158) | type ErrorSchema = z.infer<ReturnType<typeof createErrorSchema>>;

FILE: apps/server/src/libs/middlewares/auth.ts
  function lookupWorkspace (line 23) | async function lookupWorkspace(workspaceId: number) {
  function authMiddleware (line 49) | async function authMiddleware(
  function validateKey (line 100) | async function validateKey(key: string): Promise<{

FILE: apps/server/src/libs/middlewares/plan.ts
  function minPlanMiddleware (line 12) | function minPlanMiddleware({ plan }: { plan: Workspace["plan"] }) {

FILE: apps/server/src/libs/middlewares/track.ts
  function trackMiddleware (line 12) | function trackMiddleware(event: EventProps, eventProps?: string[]) {

FILE: apps/server/src/libs/test/preload.ts
  method fromEnv (line 22) | fromEnv() {
  method legacy_httpStatus45d (line 49) | get legacy_httpStatus45d() {
  method legacy_tcpStatus45d (line 52) | get legacy_tcpStatus45d() {
  method httpMetricsDaily (line 56) | get httpMetricsDaily() {
  method httpMetricsWeekly (line 59) | get httpMetricsWeekly() {
  method httpMetricsBiweekly (line 62) | get httpMetricsBiweekly() {
  method tcpMetricsDaily (line 66) | get tcpMetricsDaily() {
  method tcpMetricsWeekly (line 69) | get tcpMetricsWeekly() {
  method tcpMetricsBiweekly (line 72) | get tcpMetricsBiweekly() {
  method dnsMetricsDaily (line 76) | get dnsMetricsDaily() {
  method dnsMetricsWeekly (line 79) | get dnsMetricsWeekly() {
  method dnsMetricsBiweekly (line 82) | get dnsMetricsBiweekly() {

FILE: apps/server/src/routes/public/status.test.ts
  constant TEST_PREFIX (line 36) | const TEST_PREFIX = "status-test";

FILE: apps/server/src/routes/rpc/index.ts
  function mountRpcRoutes (line 19) | function mountRpcRoutes(

FILE: apps/server/src/routes/rpc/interceptors/auth.ts
  type RpcContext (line 16) | interface RpcContext {
  constant RPC_CONTEXT_KEY (line 24) | const RPC_CONTEXT_KEY = createContextKey<RpcContext | undefined>(
  function authInterceptor (line 33) | function authInterceptor(): Interceptor {
  function getRpcContext (line 88) | function getRpcContext(ctx: {

FILE: apps/server/src/routes/rpc/interceptors/error.ts
  constant ERROR_CODE_MAP (line 13) | const ERROR_CODE_MAP: Record<ErrorCode, Code> = {
  function errorInterceptor (line 30) | function errorInterceptor(): Interceptor {

FILE: apps/server/src/routes/rpc/interceptors/logging.ts
  function loggingInterceptor (line 14) | function loggingInterceptor(): Interceptor {

FILE: apps/server/src/routes/rpc/interceptors/validation.ts
  constant SKIP_VALIDATION_METHODS (line 6) | const SKIP_VALIDATION_METHODS = new Set([
  function validationInterceptor (line 25) | function validationInterceptor(): Interceptor {

FILE: apps/server/src/routes/rpc/services/health/index.ts
  method check (line 12) | async check(_req) {

FILE: apps/server/src/routes/rpc/services/maintenance/__tests__/maintenance.test.ts
  function connectRequest (line 23) | async function connectRequest(
  constant TEST_PREFIX (line 41) | const TEST_PREFIX = "rpc-maintenance-test";

FILE: apps/server/src/routes/rpc/services/maintenance/converters.ts
  type DBMaintenance (line 6) | type DBMaintenance = {
  function dbMaintenanceToProtoSummary (line 21) | function dbMaintenanceToProtoSummary(
  function dbMaintenanceToProto (line 42) | function dbMaintenanceToProto(

FILE: apps/server/src/routes/rpc/services/maintenance/errors.ts
  type ErrorReason (line 19) | type ErrorReason = (typeof ErrorReason)[keyof typeof ErrorReason];
  constant DOMAIN (line 21) | const DOMAIN = "openstatus.dev";
  function createError (line 26) | function createError(
  function maintenanceNotFoundError (line 49) | function maintenanceNotFoundError(maintenanceId: string): ConnectError {
  function maintenanceIdRequiredError (line 61) | function maintenanceIdRequiredError(): ConnectError {
  function maintenanceCreateFailedError (line 72) | function maintenanceCreateFailedError(): ConnectError {
  function maintenanceUpdateFailedError (line 83) | function maintenanceUpdateFailedError(
  function pageComponentNotFoundError (line 97) | function pageComponentNotFoundError(
  function pageComponentsMixedPagesError (line 111) | function pageComponentsMixedPagesError(): ConnectError {
  function pageNotFoundError (line 122) | function pageNotFoundError(pageId: string): ConnectError {
  function invalidDateFormatError (line 136) | function invalidDateFormatError(dateValue: string): ConnectError {
  function invalidDateRangeError (line 148) | function invalidDateRangeError(from: string, to: string): ConnectError {
  function pageIdComponentMismatchError (line 160) | function pageIdComponentMismatchError(

FILE: apps/server/src/routes/rpc/services/maintenance/index.ts
  type DB (line 33) | type DB = typeof db;
  type Transaction (line 34) | type Transaction = Parameters<Parameters<DB["transaction"]>[0]>[0];
  function getMaintenanceById (line 39) | async function getMaintenanceById(id: number, workspaceId: number) {
  function getPageComponentIdsForMaintenance (line 52) | async function getPageComponentIdsForMaintenance(maintenanceId: number) {
  type ValidatedPageComponents (line 65) | interface ValidatedPageComponents {
  function validatePageComponentIds (line 74) | async function validatePageComponentIds(
  function updatePageComponentAssociations (line 122) | async function updatePageComponentAssociations(
  function parseDate (line 147) | function parseDate(dateString: string): Date {
  function validateDateRange (line 158) | function validateDateRange(
  function validatePageExists (line 172) | async function validatePageExists(
  function sendMaintenanceNotification (line 192) | async function sendMaintenanceNotification(params: {
  method createMaintenance (line 209) | async createMaintenance(req, ctx) {
  method getMaintenance (line 284) | async getMaintenance(req, ctx) {
  method listMaintenances (line 304) | async listMaintenances(req, ctx) {
  method updateMaintenance (line 354) | async updateMaintenance(req, ctx) {
  method deleteMaintenance (line 463) | async deleteMaintenance(req, ctx) {

FILE: apps/server/src/routes/rpc/services/monitor/__tests__/monitor.test.ts
  function connectRequest (line 12) | async function connectRequest(
  constant TEST_PREFIX (line 27) | const TEST_PREFIX = "rpc-monitor-test";

FILE: apps/server/src/routes/rpc/services/monitor/converters/assertions.ts
  type HttpAssertions (line 32) | interface HttpAssertions {
  function parseHttpAssertions (line 41) | function parseHttpAssertions(
  function parseDnsAssertions (line 105) | function parseDnsAssertions(
  function httpAssertionsToDbJson (line 147) | function httpAssertionsToDbJson(
  function dnsAssertionsToDbJson (line 189) | function dnsAssertionsToDbJson(

FILE: apps/server/src/routes/rpc/services/monitor/converters/comparators.ts
  constant DB_TO_NUMBER_COMPARATOR (line 11) | const DB_TO_NUMBER_COMPARATOR: Record<string, NumberComparator> = {
  constant DB_TO_STRING_COMPARATOR (line 20) | const DB_TO_STRING_COMPARATOR: Record<string, StringComparator> = {
  constant DB_TO_RECORD_COMPARATOR (line 33) | const DB_TO_RECORD_COMPARATOR: Record<string, RecordComparator> = {
  function compareToNumberComparator (line 40) | function compareToNumberComparator(compare: string): NumberComparator {
  function compareToStringComparator (line 44) | function compareToStringComparator(compare: string): StringComparator {
  function compareToRecordComparator (line 48) | function compareToRecordComparator(compare: string): RecordComparator {
  constant NUMBER_COMPARATOR_TO_DB (line 56) | const NUMBER_COMPARATOR_TO_DB: Record<NumberComparator, string> = {
  constant STRING_COMPARATOR_TO_DB (line 66) | const STRING_COMPARATOR_TO_DB: Record<StringComparator, string> = {
  constant RECORD_COMPARATOR_TO_DB (line 80) | const RECORD_COMPARATOR_TO_DB: Record<RecordComparator, string> = {
  function numberComparatorToString (line 88) | function numberComparatorToString(comp: NumberComparator): string {
  function stringComparatorToString (line 92) | function stringComparatorToString(comp: StringComparator): string {
  function recordComparatorToString (line 96) | function recordComparatorToString(comp: RecordComparator): string {

FILE: apps/server/src/routes/rpc/services/monitor/converters/defaults.ts
  constant MONITOR_DEFAULTS (line 4) | const MONITOR_DEFAULTS = {

FILE: apps/server/src/routes/rpc/services/monitor/converters/enums.ts
  constant DB_TO_PERIODICITY (line 15) | const DB_TO_PERIODICITY: Record<string, Periodicity> = {
  constant PERIODICITY_TO_DB (line 24) | const PERIODICITY_TO_DB: Record<
  function stringToPeriodicity (line 37) | function stringToPeriodicity(value: string): Periodicity {
  function periodicityToString (line 41) | function periodicityToString(value: Periodicity) {
  constant DB_TO_HTTP_METHOD (line 49) | const DB_TO_HTTP_METHOD: Record<string, HTTPMethod> = {
  constant HTTP_METHOD_TO_DB (line 61) | const HTTP_METHOD_TO_DB: Record<HTTPMethod, string> = {
  function stringToHttpMethod (line 74) | function stringToHttpMethod(value: string | undefined): HTTPMethod {
  function httpMethodToString (line 81) | function httpMethodToString(value: HTTPMethod): string {
  constant DB_TO_MONITOR_STATUS (line 89) | const DB_TO_MONITOR_STATUS: Record<string, MonitorStatus> = {
  function stringToMonitorStatus (line 95) | function stringToMonitorStatus(value: string): MonitorStatus {
  type TimeRangeKey (line 103) | type TimeRangeKey = "1d" | "7d" | "14d";
  constant TIME_RANGE_TO_KEY (line 105) | const TIME_RANGE_TO_KEY: Record<TimeRange, TimeRangeKey> = {
  function timeRangeToKey (line 112) | function timeRangeToKey(value: TimeRange): TimeRangeKey {

FILE: apps/server/src/routes/rpc/services/monitor/converters/headers.ts
  function toProtoHeaders (line 13) | function toProtoHeaders(
  function parseOpenTelemetry (line 30) | function parseOpenTelemetry(
  function headersToDbJson (line 52) | function headersToDbJson(headers: Headers[]): string | undefined {
  function openTelemetryToDb (line 63) | function openTelemetryToDb(config: OpenTelemetryConfig | undefined): {

FILE: apps/server/src/routes/rpc/services/monitor/converters/monitors.ts
  function dbMonitorToHttpProto (line 21) | function dbMonitorToHttpProto(dbMon: Monitor): HTTPMonitor {
  function dbMonitorToTcpProto (line 52) | function dbMonitorToTcpProto(dbMon: Monitor): TCPMonitor {
  function dbMonitorToDnsProto (line 74) | function dbMonitorToDnsProto(dbMon: Monitor): DNSMonitor {

FILE: apps/server/src/routes/rpc/services/monitor/converters/regions.ts
  constant DB_TO_REGION (line 7) | const DB_TO_REGION: Record<string, Region> = {
  constant REGION_TO_DB (line 44) | const REGION_TO_DB: Record<Region, string> = {
  function stringToRegion (line 83) | function stringToRegion(value: string): Region {
  function regionToString (line 90) | function regionToString(value: Region): string {
  function stringsToRegions (line 97) | function stringsToRegions(values: string[]): Region[] {
  function regionsToStrings (line 104) | function regionsToStrings(values: Region[]): string[] {
  function regionsToDbString (line 111) | function regionsToDbString(regions: string[]): string {
  function validateRegions (line 119) | function validateRegions(regions: string[]): string[] {

FILE: apps/server/src/routes/rpc/services/monitor/errors.ts
  type ErrorReason (line 19) | type ErrorReason = (typeof ErrorReason)[keyof typeof ErrorReason];
  constant DOMAIN (line 21) | const DOMAIN = "openstatus.dev";
  function createError (line 29) | function createError(
  function monitorNotFoundError (line 52) | function monitorNotFoundError(monitorId: string): ConnectError {
  function monitorRequiredError (line 64) | function monitorRequiredError(): ConnectError {
  function monitorIdRequiredError (line 75) | function monitorIdRequiredError(): ConnectError {
  function monitorCreateFailedError (line 86) | function monitorCreateFailedError(): ConnectError {
  function monitorUpdateFailedError (line 97) | function monitorUpdateFailedError(monitorId: string): ConnectError {
  function monitorTypeMismatchError (line 109) | function monitorTypeMismatchError(
  function monitorParseFailedError (line 129) | function monitorParseFailedError(monitorId?: string): ConnectError {
  function monitorRunCreateFailedError (line 141) | function monitorRunCreateFailedError(monitorId: string): ConnectError {
  function monitorInvalidDataError (line 153) | function monitorInvalidDataError(monitorId: string): ConnectError {
  function rateLimitExceededError (line 165) | function rateLimitExceededError(

FILE: apps/server/src/routes/rpc/services/monitor/index.ts
  function getMonitorById (line 67) | async function getMonitorById(id: number, workspaceId: number) {
  type DBMonitor (line 81) | type DBMonitor = NonNullable<Awaited<ReturnType<typeof getMonitorById>>>;
  function validateAndGetMonitor (line 87) | async function validateAndGetMonitor(
  type ParsedMonitor (line 108) | type ParsedMonitor = ReturnType<typeof selectMonitorSchema.parse>;
  function performUpdateAndReturn (line 113) | async function performUpdateAndReturn<T>(
  method createHTTPMonitor (line 142) | async createHTTPMonitor(req, ctx) {
  method createTCPMonitor (line 203) | async createTCPMonitor(req, ctx) {
  method createDNSMonitor (line 250) | async createDNSMonitor(req, ctx) {
  method updateHTTPMonitor (line 301) | async updateHTTPMonitor(req, ctx) {
  method updateTCPMonitor (line 378) | async updateTCPMonitor(req, ctx) {
  method updateDNSMonitor (line 426) | async updateDNSMonitor(req, ctx) {
  method triggerMonitor (line 479) | async triggerMonitor(req, ctx) {
  method deleteMonitor (line 562) | async deleteMonitor(req, ctx) {
  method listMonitors (line 595) | async listMonitors(req, ctx) {
  method getMonitorStatus (line 659) | async getMonitorStatus(req, ctx) {
  method getMonitor (line 700) | async getMonitor(req, ctx) {
  method getMonitorSummary (line 756) | async getMonitorSummary(req, ctx) {
  function getMetricsByTypeAndRange (line 845) | async function getMetricsByTypeAndRange(

FILE: apps/server/src/routes/rpc/services/monitor/limits.ts
  function checkMonitorLimits (line 15) | async function checkMonitorLimits(

FILE: apps/server/src/routes/rpc/services/monitor/validators.ts
  type MonitorPeriodicity (line 15) | type MonitorPeriodicity = (typeof monitorPeriodicity)[number];
  type MonitorMethod (line 16) | type MonitorMethod = (typeof monitorMethods)[number];
  function toValidPeriodicity (line 21) | function toValidPeriodicity(
  function toValidMethod (line 34) | function toValidMethod(value: string | undefined): MonitorMethod {
  function validateCommonMonitorFields (line 48) | function validateCommonMonitorFields(mon: {
  function getCommonDbValues (line 66) | function getCommonDbValues(mon: {
  function getCommonDbValuesForUpdate (line 105) | function getCommonDbValuesForUpdate(mon: {

FILE: apps/server/src/routes/rpc/services/notification/__tests__/notification.test.ts
  function connectRequest (line 14) | async function connectRequest(
  constant TEST_PREFIX (line 32) | const TEST_PREFIX = "rpc-notification-test";

FILE: apps/server/src/routes/rpc/services/notification/converters.ts
  type DBNotification (line 16) | type DBNotification = {
  function dbProviderToProto (line 29) | function dbProviderToProto(
  function getExpectedDataCase (line 52) | function getExpectedDataCase(
  function validateProviderDataConsistency (line 76) | function validateProviderDataConsistency(
  function protoProviderToDb (line 104) | function protoProviderToDb(
  function dbDataToProto (line 127) | function dbDataToProto(
  function protoDataToDb (line 301) | function protoDataToDb(
  function dbNotificationToProto (line 365) | function dbNotificationToProto(
  function dbNotificationToProtoSummary (line 383) | function dbNotificationToProtoSummary(

FILE: apps/server/src/routes/rpc/services/notification/errors.ts
  type ErrorReason (line 19) | type ErrorReason = (typeof ErrorReason)[keyof typeof ErrorReason];
  constant DOMAIN (line 21) | const DOMAIN = "openstatus.dev";
  function createError (line 26) | function createError(
  function notificationNotFoundError (line 49) | function notificationNotFoundError(
  function notificationIdRequiredError (line 63) | function notificationIdRequiredError(): ConnectError {
  function notificationCreateFailedError (line 74) | function notificationCreateFailedError(): ConnectError {
  function notificationUpdateFailedError (line 85) | function notificationUpdateFailedError(
  function notificationLimitReachedError (line 99) | function notificationLimitReachedError(): ConnectError {
  function providerNotAllowedError (line 110) | function providerNotAllowedError(provider: string): ConnectError {
  function providerNotSupportedError (line 122) | function providerNotSupportedError(provider: string): ConnectError {
  function invalidNotificationDataError (line 134) | function invalidNotificationDataError(details: string): ConnectError {
  function monitorNotFoundError (line 146) | function monitorNotFoundError(monitorId: string): ConnectError {
  function testNotificationFailedError (line 158) | function testNotificationFailedError(message: string): ConnectError {

FILE: apps/server/src/routes/rpc/services/notification/index.ts
  type DB (line 38) | type DB = typeof db;
  type Transaction (line 39) | type Transaction = Parameters<Parameters<DB["transaction"]>[0]>[0];
  function getNotificationById (line 44) | async function getNotificationById(id: number, workspaceId: number) {
  function getMonitorIdsForNotification (line 57) | async function getMonitorIdsForNotification(
  function getMonitorCountForNotification (line 72) | async function getMonitorCountForNotification(
  function validateMonitorIds (line 88) | async function validateMonitorIds(
  function updateMonitorAssociations (line 124) | async function updateMonitorAssociations(
  method createNotification (line 150) | async createNotification(req, ctx) {
  method getNotification (line 209) | async getNotification(req, ctx) {
  method listNotifications (line 229) | async listNotifications(req, ctx) {
  method updateNotification (line 269) | async updateNotification(req, ctx) {
  method deleteNotification (line 371) | async deleteNotification(req, ctx) {
  method sendTestNotification (line 390) | async sendTestNotification(req, _ctx) {
  method checkNotificationLimit (line 395) | async checkNotificationLimit(_req, ctx) {

FILE: apps/server/src/routes/rpc/services/notification/limits.ts
  constant LIMITED_PROVIDERS (line 13) | const LIMITED_PROVIDERS = new Set([
  function providerToLimitKey (line 24) | function providerToLimitKey(
  function providerToDisplayName (line 46) | function providerToDisplayName(provider: NotificationProvider): string {
  function checkNotificationLimit (line 81) | async function checkNotificationLimit(
  function checkProviderAllowed (line 104) | function checkProviderAllowed(
  function getNotificationLimitInfo (line 126) | async function getNotificationLimitInfo(

FILE: apps/server/src/routes/rpc/services/notification/test-providers.ts
  function sendTestNotification (line 26) | async function sendTestNotification(

FILE: apps/server/src/routes/rpc/services/status-page/__tests__/status-page.test.ts
  function connectRequest (line 19) | async function connectRequest(
  constant TEST_PREFIX (line 37) | const TEST_PREFIX = "rpc-status-page-test";

FILE: apps/server/src/routes/rpc/services/status-page/converters.ts
  type DBPage (line 18) | type DBPage = {
  type DBPageComponent (line 34) | type DBPageComponent = {
  type DBPageComponentGroup (line 48) | type DBPageComponentGroup = {
  type DBPageSubscriber (line 56) | type DBPageSubscriber = {
  function dbAccessTypeToProto (line 69) | function dbAccessTypeToProto(
  function protoAccessTypeToDb (line 87) | function protoAccessTypeToDb(
  function dbThemeToProto (line 105) | function dbThemeToProto(theme: "system" | "light" | "dark"): PageTheme {
  function protoThemeToDb (line 121) | function protoThemeToDb(theme: PageTheme): "system" | "light" | "dark" {
  function dbComponentTypeToProto (line 137) | function dbComponentTypeToProto(
  function protoComponentTypeToDb (line 153) | function protoComponentTypeToDb(
  function dbPageToProto (line 169) | function dbPageToProto(page: DBPage): StatusPage {
  function dbPageToProtoSummary (line 191) | function dbPageToProtoSummary(page: DBPage): StatusPageSummary {
  function dbComponentToProto (line 206) | function dbComponentToProto(component: DBPageComponent): PageComponent {
  function dbGroupToProto (line 226) | function dbGroupToProto(
  function dbSubscriberToProto (line 242) | function dbSubscriberToProto(
  function getOverallStatusValue (line 262) | function getOverallStatusValue(): OverallStatus {

FILE: apps/server/src/routes/rpc/services/status-page/errors.ts
  type ErrorReason (line 26) | type ErrorReason = (typeof ErrorReason)[keyof typeof ErrorReason];
  constant DOMAIN (line 28) | const DOMAIN = "openstatus.dev";
  function createError (line 33) | function createError(
  function statusPageNotFoundError (line 56) | function statusPageNotFoundError(pageId: string): ConnectError {
  function statusPageIdRequiredError (line 68) | function statusPageIdRequiredError(): ConnectError {
  function statusPageCreateFailedError (line 79) | function statusPageCreateFailedError(): ConnectError {
  function statusPageUpdateFailedError (line 90) | function statusPageUpdateFailedError(pageId: string): ConnectError {
  function slugAlreadyExistsError (line 102) | function slugAlreadyExistsError(slug: string): ConnectError {
  function statusPageNotPublishedError (line 115) | function statusPageNotPublishedError(slug: string): ConnectError {
  function statusPageAccessDeniedError (line 128) | function statusPageAccessDeniedError(
  function pageComponentNotFoundError (line 143) | function pageComponentNotFoundError(componentId: string): ConnectError {
  function pageComponentCreateFailedError (line 155) | function pageComponentCreateFailedError(): ConnectError {
  function pageComponentUpdateFailedError (line 166) | function pageComponentUpdateFailedError(
  function componentGroupNotFoundError (line 180) | function componentGroupNotFoundError(groupId: string): ConnectError {
  function componentGroupCreateFailedError (line 192) | function componentGroupCreateFailedError(): ConnectError {
  function componentGroupUpdateFailedError (line 203) | function componentGroupUpdateFailedError(groupId: string): ConnectError {
  function monitorNotFoundError (line 215) | function monitorNotFoundError(monitorId: string): ConnectError {
  function subscriberNotFoundError (line 227) | function subscriberNotFoundError(identifier: string): ConnectError {
  function subscriberCreateFailedError (line 239) | function subscriberCreateFailedError(): ConnectError {
  function identifierRequiredError (line 250) | function identifierRequiredError(): ConnectError {

FILE: apps/server/src/routes/rpc/services/status-page/index.ts
  function getPageById (line 61) | async function getPageById(id: number, workspaceId: number) {
  function getPageBySlug (line 73) | async function getPageBySlug(slug: string) {
  function validatePublicAccess (line 83) | function validatePublicAccess(
  function getComponentById (line 101) | async function getComponentById(id: number, workspaceId: number) {
  function getGroupById (line 114) | async function getGroupById(id: number, workspaceId: number) {
  function getMonitorById (line 130) | async function getMonitorById(id: number, workspaceId: number) {
  method createStatusPage (line 146) | async createStatusPage(req, ctx) {
  method getStatusPage (line 185) | async getStatusPage(req, ctx) {
  method listStatusPages (line 204) | async listStatusPages(req, ctx) {
  method updateStatusPage (line 236) | async updateStatusPage(req, ctx) {
  method deleteStatusPage (line 295) | async deleteStatusPage(req, ctx) {
  method addMonitorComponent (line 319) | async addMonitorComponent(req, ctx) {
  method addStaticComponent (line 375) | async addStaticComponent(req, ctx) {
  method removeComponent (line 422) | async removeComponent(req, ctx) {
  method updateComponent (line 442) | async updateComponent(req, ctx) {
  method createComponentGroup (line 506) | async createComponentGroup(req, ctx) {
  method deleteComponentGroup (line 536) | async deleteComponentGroup(req, ctx) {
  method updateComponentGroup (line 558) | async updateComponentGroup(req, ctx) {
  method subscribeToPage (line 601) | async subscribeToPage(req, ctx) {
  method unsubscribeFromPage (line 676) | async unsubscribeFromPage(req, ctx) {
  method listSubscribers (line 738) | async listSubscribers(req, ctx) {
  method getStatusPageContent (line 786) | async getStatusPageContent(req, ctx) {
  method getOverallStatus (line 958) | async getOverallStatus(req, ctx) {

FILE: apps/server/src/routes/rpc/services/status-page/limits.ts
  function checkStatusPageLimits (line 10) | async function checkStatusPageLimits(
  function checkCustomDomainLimit (line 34) | function checkCustomDomainLimit(limits: Limits): void {
  function checkPasswordProtectionLimit (line 44) | function checkPasswordProtectionLimit(limits: Limits): void {
  function checkEmailDomainProtectionLimit (line 57) | function checkEmailDomainProtectionLimit(limits: Limits): void {
  function checkPageComponentLimits (line 70) | async function checkPageComponentLimits(

FILE: apps/server/src/routes/rpc/services/status-report/__tests__/status-report.test.ts
  function connectRequest (line 26) | async function connectRequest(
  constant TEST_PREFIX (line 44) | const TEST_PREFIX = "rpc-status-report-test";

FILE: apps/server/src/routes/rpc/services/status-report/converters.ts
  type DBStatusReport (line 9) | type DBStatusReport = {
  type DBStatusReportUpdate (line 19) | type DBStatusReportUpdate = {
  function dbStatusToProto (line 32) | function dbStatusToProto(
  function protoStatusToDb (line 52) | function protoStatusToDb(
  function dbUpdateToProto (line 74) | function dbUpdateToProto(
  function dbReportToProtoSummary (line 90) | function dbReportToProtoSummary(
  function dbReportToProto (line 108) | function dbReportToProto(

FILE: apps/server/src/routes/rpc/services/status-report/errors.ts
  type ErrorReason (line 18) | type ErrorReason = (typeof ErrorReason)[keyof typeof ErrorReason];
  constant DOMAIN (line 20) | const DOMAIN = "openstatus.dev";
  function createError (line 25) | function createError(
  function statusReportNotFoundError (line 48) | function statusReportNotFoundError(
  function statusReportIdRequiredError (line 62) | function statusReportIdRequiredError(): ConnectError {
  function statusReportCreateFailedError (line 73) | function statusReportCreateFailedError(): ConnectError {
  function statusReportUpdateFailedError (line 84) | function statusReportUpdateFailedError(
  function pageComponentNotFoundError (line 98) | function pageComponentNotFoundError(
  function pageComponentsMixedPagesError (line 112) | function pageComponentsMixedPagesError(): ConnectError {
  function invalidDateFormatError (line 123) | function invalidDateFormatError(dateValue: string): ConnectError {
  function invalidStatusError (line 135) | function invalidStatusError(statusValue: number): ConnectError {
  function pageIdComponentMismatchError (line 147) | function pageIdComponentMismatchError(

FILE: apps/server/src/routes/rpc/services/status-report/index.ts
  type DB (line 5) | type DB = typeof db;
  type Transaction (line 6) | type Transaction = Parameters<Parameters<DB["transaction"]>[0]>[0];
  function sendStatusReportNotification (line 40) | async function sendStatusReportNotification(params: {
  function getStatusReportById (line 56) | async function getStatusReportById(id: number, workspaceId: number) {
  function getPageComponentIdsForReport (line 69) | async function getPageComponentIdsForReport(statusReportId: number) {
  function getUpdatesForReport (line 82) | async function getUpdatesForReport(statusReportId: number) {
  type ValidatedPageComponents (line 94) | interface ValidatedPageComponents {
  function validatePageComponentIds (line 103) | async function validatePageComponentIds(
  function updatePageComponentAssociations (line 151) | async function updatePageComponentAssociations(
  function parseDate (line 176) | function parseDate(dateString: string): Date {
  method createStatusReport (line 189) | async createStatusReport(req, ctx) {
  method getStatusReport (line 284) | async getStatusReport(req, ctx) {
  method listStatusReports (line 305) | async listStatusReports(req, ctx) {
  method updateStatusReport (line 360) | async updateStatusReport(req, ctx) {
  method deleteStatusReport (line 427) | async deleteStatusReport(req, ctx) {
  method addStatusReportUpdate (line 446) | async addStatusReportUpdate(req, ctx) {

FILE: apps/server/src/routes/slack/agent.ts
  type SlackThreadMessage (line 6) | interface SlackThreadMessage {
  type AgentResult (line 12) | interface AgentResult {
  function buildSystemPrompt (line 17) | function buildSystemPrompt(workspaceName: string): string {
  function convertThreadToMessages (line 63) | function convertThreadToMessages(
  function runAgent (line 84) | async function runAgent(

FILE: apps/server/src/routes/slack/blocks.ts
  type TextObject (line 3) | interface TextObject {
  type SectionBlock (line 9) | interface SectionBlock {
  type ActionsBlock (line 14) | interface ActionsBlock {
  type DividerBlock (line 19) | interface DividerBlock {
  type ButtonElement (line 23) | interface ButtonElement {
  type Block (line 31) | type Block = SectionBlock | ActionsBlock | DividerBlock;
  function buildConfirmationBlocks (line 33) | function buildConfirmationBlocks(
  function formatDate (line 237) | function formatDate(iso: string): string {
  function capitalize (line 251) | function capitalize(s: string): string {

FILE: apps/server/src/routes/slack/confirmation-store.test.ts
  function makePendingInput (line 14) | function makePendingInput(): Omit<PendingAction, "id" | "createdAt"> {

FILE: apps/server/src/routes/slack/confirmation-store.ts
  type PendingAction (line 83) | type PendingAction = z.infer<typeof pendingActionSchema>;
  constant TTL_SECONDS (line 85) | const TTL_SECONDS = 5 * 60;
  constant ACTION_PREFIX (line 86) | const ACTION_PREFIX = "slack:action:";
  constant THREAD_PREFIX (line 87) | const THREAD_PREFIX = "slack:thread:";
  function parse (line 89) | function parse(raw: unknown): PendingAction | undefined {
  function store (line 99) | async function store(
  function get (line 117) | async function get(
  function consume (line 125) | async function consume(
  function findByThread (line 141) | async function findByThread(
  function replace (line 156) | async function replace(

FILE: apps/server/src/routes/slack/handler.test.ts
  constant SIGNING_SECRET (line 5) | const SIGNING_SECRET = "test-signing-secret";
  function createTestApp (line 78) | function createTestApp() {
  function signAndPost (line 84) | function signAndPost(

FILE: apps/server/src/routes/slack/handler.ts
  function dedup (line 17) | function dedup(eventId: string): boolean {
  type SlackEvent (line 47) | type SlackEvent = z.infer<typeof slackEventSchema>;
  type ThreadMessage (line 56) | type ThreadMessage = z.infer<typeof threadMessageSchema>;
  function isSlackPlatformError (line 65) | function isSlackPlatformError(err: unknown, errorCode: string): boolean {
  function handleSlackEvent (line 70) | async function handleSlackEvent(c: Context) {
  function processEvent (line 97) | async function processEvent(body: SlackEvent) {
  function handleConfirmation (line 300) | async function handleConfirmation(
  function getConfirmationText (line 358) | function getConfirmationText(action: PendingAction["action"]): string {

FILE: apps/server/src/routes/slack/index.test.ts
  constant SIGNING_SECRET (line 5) | const SIGNING_SECRET = "test-signing-secret";
  function signRequest (line 7) | function signRequest(body: string, timestamp: number): string {
  function makeInstallToken (line 16) | function makeInstallToken(workspaceId: number): string {

FILE: apps/server/src/routes/slack/index.ts
  type SlackEnv (line 8) | type SlackEnv = {

FILE: apps/server/src/routes/slack/interactions.test.ts
  constant SIGNING_SECRET (line 5) | const SIGNING_SECRET = "test-signing-secret";
  function createTestApp (line 63) | function createTestApp() {
  function seedPendingAction (line 69) | function seedPendingAction() {
  function signAndPost (line 74) | function signAndPost(
  function seedMaintenanceAction (line 302) | function seedMaintenanceAction(overrides: Record<string, unknown> = {}) {

FILE: apps/server/src/routes/slack/interactions.ts
  type SlackInteractionPayload (line 23) | interface SlackInteractionPayload {
  function handleSlackInteraction (line 32) | async function handleSlackInteraction(c: Context) {
  function getPageUrl (line 129) | async function getPageUrl(pageId: number): Promise<string | null> {
  function getReportUrl (line 143) | async function getReportUrl(pageId: number, reportId: number): Promise<s...
  function executeAction (line 156) | async function executeAction(

FILE: apps/server/src/routes/slack/oauth.test.ts
  constant SIGNING_SECRET (line 6) | const SIGNING_SECRET =
  function createTestApp (line 14) | function createTestApp() {
  function signToken (line 21) | function signToken(data: { workspaceId: number; ts: number }): string {
  function encodeState (line 30) | function encodeState(state: { workspaceId: number; ts: number }): string {
  function makeInstallToken (line 34) | function makeInstallToken(workspaceId: number): string {

FILE: apps/server/src/routes/slack/oauth.ts
  constant SLACK_OAUTH_URL (line 7) | const SLACK_OAUTH_URL = "https://slack.com/oauth/v2/authorize";
  constant SLACK_TOKEN_URL (line 8) | const SLACK_TOKEN_URL = "https://slack.com/api/oauth.v2.access";
  constant BOT_SCOPES (line 10) | const BOT_SCOPES = [
  type OAuthState (line 23) | interface OAuthState {
  type SlackOAuthResponse (line 28) | interface SlackOAuthResponse {
  function handleSlackInstall (line 41) | async function handleSlackInstall(c: Context) {
  function handleSlackOAuthCallback (line 71) | async function handleSlackOAuthCallback(c: Context) {
  function getRedirectUri (line 157) | function getRedirectUri(c: Context): string {
  function getDashboardUrl (line 163) | function getDashboardUrl(): string {
  function encodeState (line 169) | function encodeState(state: OAuthState): string {
  function decodeState (line 175) | function decodeState(encoded: string): OAuthState | null {
  function computeHmac (line 192) | function computeHmac(payload: string): string {
  function verifyHmac (line 198) | function verifyHmac(payload: string, signature: string): boolean {
  constant INSTALL_TOKEN_TTL_MS (line 204) | const INSTALL_TOKEN_TTL_MS = 5 * 60 * 1000;
  function verifyInstallToken (line 206) | function verifyInstallToken(token: string): { workspaceId: number } | nu...

FILE: apps/server/src/routes/slack/tools/add-status-report-update.ts
  function createAddStatusReportUpdateTool (line 4) | function createAddStatusReportUpdateTool() {

FILE: apps/server/src/routes/slack/tools/create-maintenance.ts
  function createCreateMaintenanceTool (line 4) | function createCreateMaintenanceTool() {

FILE: apps/server/src/routes/slack/tools/create-status-report.ts
  function createCreateStatusReportTool (line 4) | function createCreateStatusReportTool() {

FILE: apps/server/src/routes/slack/tools/index.ts
  function createTools (line 11) | function createTools(workspace: Workspace) {

FILE: apps/server/src/routes/slack/tools/list-maintenances.ts
  function createListMaintenancesTool (line 6) | function createListMaintenancesTool(workspaceId: number) {

FILE: apps/server/src/routes/slack/tools/list-status-pages.ts
  function createListStatusPagesTool (line 6) | function createListStatusPagesTool(workspaceId: number) {

FILE: apps/server/src/routes/slack/tools/list-status-reports.ts
  function createListStatusReportsTool (line 6) | function createListStatusReportsTool(workspaceId: number) {

FILE: apps/server/src/routes/slack/tools/resolve-status-report.ts
  function createResolveStatusReportTool (line 4) | function createResolveStatusReportTool() {

FILE: apps/server/src/routes/slack/tools/update-status-report.ts
  function createUpdateStatusReportTool (line 4) | function createUpdateStatusReportTool() {

FILE: apps/server/src/routes/slack/verify.test.ts
  constant SIGNING_SECRET (line 6) | const SIGNING_SECRET = "test-signing-secret";
  function signRequest (line 9) | function signRequest(body: string, timestamp: number): string {
  function createTestApp (line 18) | function createTestApp() {

FILE: apps/server/src/routes/slack/workspace-resolver.ts
  type SlackWorkspace (line 9) | interface SlackWorkspace {
  type IntegrationCredential (line 15) | interface IntegrationCredential {
  function resolveWorkspace (line 20) | async function resolveWorkspace(

FILE: apps/server/src/routes/v1/check/http/post.ts
  function registerHTTPPostCheck (line 48) | function registerHTTPPostCheck(api: typeof checkApi) {
  type ReturnGetTiming (line 156) | type ReturnGetTiming = Record<
  function getTiming (line 161) | function getTiming(data: z.infer<typeof ResponseSchema>[]): ReturnGetTim...
  function getAggregate (line 187) | function getAggregate(data: number[]) {

FILE: apps/server/src/routes/v1/incidents/get.ts
  function registerGetIncident (line 31) | function registerGetIncident(app: typeof incidentsApi) {

FILE: apps/server/src/routes/v1/incidents/get_all.test.ts
  constant TEST_PREFIX (line 8) | const TEST_PREFIX = "v1-incident-getall-test";

FILE: apps/server/src/routes/v1/incidents/get_all.ts
  function registerGetAllIncidents (line 29) | function registerGetAllIncidents(app: typeof incidentsApi) {

FILE: apps/server/src/routes/v1/incidents/put.ts
  function registerPutIncident (line 53) | function registerPutIncident(app: typeof incidentsApi) {

FILE: apps/server/src/routes/v1/incidents/schema.ts
  type IncidentSchema (line 46) | type IncidentSchema = z.infer<typeof IncidentSchema>;

FILE: apps/server/src/routes/v1/index.ts
  type Variables (line 20) | type Variables = RequestIdVariables & {

FILE: apps/server/src/routes/v1/maintenances/get.ts
  function registerGetMaintenance (line 30) | function registerGetMaintenance(api: typeof maintenancesApi) {

FILE: apps/server/src/routes/v1/maintenances/get_all.test.ts
  constant TEST_PREFIX (line 13) | const TEST_PREFIX = "v1-maint-getall-test";

FILE: apps/server/src/routes/v1/maintenances/get_all.ts
  function registerGetAllMaintenances (line 28) | function registerGetAllMaintenances(api: typeof maintenancesApi) {

FILE: apps/server/src/routes/v1/maintenances/post.ts
  function registerPostMaintenance (line 44) | function registerPostMaintenance(api: typeof maintenancesApi) {

FILE: apps/server/src/routes/v1/maintenances/put.ts
  function registerPutMaintenance (line 44) | function registerPutMaintenance(api: typeof maintenancesApi) {

FILE: apps/server/src/routes/v1/maintenances/schema.ts
  type MaintenanceSchema (line 52) | type MaintenanceSchema = z.infer<typeof MaintenanceSchema>;

FILE: apps/server/src/routes/v1/monitors/delete.ts
  function registerDeleteMonitor (line 34) | function registerDeleteMonitor(app: typeof monitorsApi) {

FILE: apps/server/src/routes/v1/monitors/get.ts
  function registerGetMonitor (line 31) | function registerGetMonitor(api: typeof monitorsApi) {

FILE: apps/server/src/routes/v1/monitors/get_all.ts
  function registerGetAllMonitors (line 29) | function registerGetAllMonitors(app: typeof monitorsApi) {

FILE: apps/server/src/routes/v1/monitors/post.ts
  function registerPostMonitor (line 44) | function registerPostMonitor(api: typeof monitorsApi) {

FILE: apps/server/src/routes/v1/monitors/post_dns.ts
  function registerPostMonitorDNS (line 44) | function registerPostMonitorDNS(api: typeof monitorsApi) {

FILE: apps/server/src/routes/v1/monitors/post_http.ts
  function registerPostMonitorHTTP (line 44) | function registerPostMonitorHTTP(api: typeof monitorsApi) {

FILE: apps/server/src/routes/v1/monitors/post_tcp.ts
  function registerPostMonitorTCP (line 41) | function registerPostMonitorTCP(api: typeof monitorsApi) {

FILE: apps/server/src/routes/v1/monitors/put.ts
  function registerPutMonitor (line 44) | function registerPutMonitor(api: typeof monitorsApi) {

FILE: apps/server/src/routes/v1/monitors/put_dns.ts
  function registerPutDNSMonitor (line 42) | function registerPutDNSMonitor(api: typeof monitorsApi) {

FILE: apps/server/src/routes/v1/monitors/put_http.ts
  function registerPutHTTPMonitor (line 44) | function registerPutHTTPMonitor(api: typeof monitorsApi) {

FILE: apps/server/src/routes/v1/monitors/put_tcp.ts
  function registerPutTCPMonitor (line 42) | function registerPutTCPMonitor(api: typeof monitorsApi) {

FILE: apps/server/src/routes/v1/monitors/results/get.ts
  function registerGetMonitorResult (line 39) | function registerGetMonitorResult(api: typeof monitorsApi) {

FILE: apps/server/src/routes/v1/monitors/run/post.ts
  function registerRunMonitor (line 44) | function registerRunMonitor(api: typeof monitorsApi) {

FILE: apps/server/src/routes/v1/monitors/schema.ts
  type MonitorSchema (line 262) | type MonitorSchema = z.infer<typeof MonitorSchema>;

FILE: apps/server/src/routes/v1/monitors/summary/get.ts
  function registerGetMonitorSummary (line 41) | function registerGetMonitorSummary(api: typeof monitorsApi) {

FILE: apps/server/src/routes/v1/monitors/summary/schema.ts
  type SummarySchema (line 17) | type SummarySchema = z.infer<typeof SummarySchema>;

FILE: apps/server/src/routes/v1/monitors/trigger/post.ts
  function re
Copy disabled (too large) Download .json
Condensed preview — 2223 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (13,022K chars).
[
  {
    "path": ".claude/commands/ship.md",
    "chars": 2197,
    "preview": "---\ndescription: Create a new git branch, commit changes, and create a pull request\nallowed-tools: Bash(git:*), Bash(gh:"
  },
  {
    "path": ".dockerignore",
    "chars": 1154,
    "preview": "# Dependencies\n**/node_modules\nnode_modules\n**/.pnpm-store\n.pnpm-store\n\n# Build outputs\n**/.next\n**/.turbo\n**/dist\n**/bu"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 21,
    "preview": "github: openstatusHQ\n"
  },
  {
    "path": ".github/workflows/api-preview.yml",
    "chars": 2331,
    "preview": "name: Fly Preview API server\non:\n  workflow_dispatch:\n    inputs:\n      action:\n        description: \"Action to perform\""
  },
  {
    "path": ".github/workflows/claude-code-review.yml",
    "chars": 1337,
    "preview": "name: Claude Code Review\n\non:\n  pull_request:\n    types: [opened, synchronize, ready_for_review, reopened]\n    # Optiona"
  },
  {
    "path": ".github/workflows/claude.yml",
    "chars": 2720,
    "preview": "name: Claude Code\n\non:\n  issue_comment:\n    types: [created]\n  pull_request_review_comment:\n    types: [created]\n  issue"
  },
  {
    "path": ".github/workflows/deploy-checker.yml",
    "chars": 512,
    "preview": "name: Fly Deploy Checker\non:\n  push:\n    branches:\n      - main\n    paths:\n      - \"apps/checker/**\"\njobs:\n  deploy-chec"
  },
  {
    "path": ".github/workflows/deploy-private-location.yml",
    "chars": 630,
    "preview": "name: Fly Deploy Private Location\non:\n  push:\n    branches:\n      - main\n    paths:\n      - \"apps/private-location/**\"\n "
  },
  {
    "path": ".github/workflows/deploy-workflows.yml",
    "chars": 671,
    "preview": "name: Fly Deploy Workflows\non:\n  push:\n    branches:\n      - main\n    paths:\n      - \"apps/workflows/**\"\n      - \"packag"
  },
  {
    "path": ".github/workflows/deploy.yml",
    "chars": 468,
    "preview": "name: Fly Deploy\non:\n  push:\n    branches:\n      - main\njobs:\n  deploy:\n    name: Deploy API\n    runs-on: depot-ubuntu-2"
  },
  {
    "path": ".github/workflows/docker-publish-dev.yml",
    "chars": 4301,
    "preview": "name: Publish Docker Images (Development)\n\non:\n  workflow_dispatch:\n\nenv:\n  REGISTRY: ghcr.io\n  IMAGE_NAME: openstatus\n\n"
  },
  {
    "path": ".github/workflows/docker-publish.yml",
    "chars": 4890,
    "preview": "name: Publish Docker Images\n\non:\n  push:\n    branches:\n      - main\n    paths:\n      - \"apps/server/**\"\n      - \"apps/da"
  },
  {
    "path": ".github/workflows/dx.yml",
    "chars": 1153,
    "preview": "# https://github.com/kentcdodds/kentcdodds.com/blob/main/.github/workflows/deployment.yml\nname: DX Check\non:\n  push:\n   "
  },
  {
    "path": ".github/workflows/go-tests.yml",
    "chars": 690,
    "preview": "name: Go Tests\n\non:\n  push:\n    branches:\n      - master\n    tags:\n      - '*.*.*'\n  pull_request:\n    branches:\n      -"
  },
  {
    "path": ".github/workflows/lint.yml",
    "chars": 958,
    "preview": "# https://github.com/kentcdodds/kentcdodds.com/blob/main/.github/workflows/deployment.yml\nname: autofix.ci # needed to s"
  },
  {
    "path": ".github/workflows/migrate.yml",
    "chars": 862,
    "preview": "name: Migrate DB\non:\n  push:\n    branches:\n      - main\n    paths:\n      - \"packages/db/drizzle/**\"\njobs:\n  migrate:\n   "
  },
  {
    "path": ".github/workflows/publish-checker.yml",
    "chars": 1869,
    "preview": "name: Publish Checker\non:\n  push:\n    branches:\n      - main\n    paths:\n      - \"apps/checker/**\"\nenv:\n  REGISTRY: ghcr."
  },
  {
    "path": ".github/workflows/synthetic.yml",
    "chars": 571,
    "preview": "name: Run OpenStatus Synthetics CI\n\non:\n  workflow_run:\n      workflows: ['Fly Deploy']\n      types: [completed]\n      b"
  },
  {
    "path": ".github/workflows/test.yml",
    "chars": 1341,
    "preview": "# https://github.com/kentcdodds/kentcdodds.com/blob/main/.github/workflows/deployment.yml\nname: Tests\non:\n  push:\n    br"
  },
  {
    "path": ".github/workflows/workflow-preview.yml",
    "chars": 2256,
    "preview": "name: Fly Preview Workflows\non:\n  workflow_dispatch:\n    inputs:\n      action:\n        description: \"Action to perform\"\n"
  },
  {
    "path": ".gitignore",
    "chars": 1195,
    "preview": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\n.pnp\n"
  },
  {
    "path": ".koyebignore",
    "chars": 34,
    "preview": "*\n!.koyebignore\n\n!/apps/checker/*\n"
  },
  {
    "path": ".npmrc",
    "chars": 26,
    "preview": "auto-install-peers = true\n"
  },
  {
    "path": ".oxlintrc.json",
    "chars": 119,
    "preview": "{\n  \"$schema\": \"./node_modules/oxlint/configuration_schema.json\",\n  \"ignorePatterns\": [\"**/*.test.ts\", \"**/*_pb.ts\"]\n}\n"
  },
  {
    "path": ".prettierignore",
    "chars": 24,
    "preview": "**/.content-collections\n"
  },
  {
    "path": ".stacked.toml",
    "chars": 33,
    "preview": "mainBranch = \"main\"\ndraft = true\n"
  },
  {
    "path": ".vscode/settings.json",
    "chars": 792,
    "preview": "{\n  \"editor.codeActionsOnSave\": {\n    \"source.organizeImports.biome\": \"explicit\"\n  },\n  \"editor.defaultFormatter\": \"biom"
  },
  {
    "path": "CLAUDE.md",
    "chars": 3293,
    "preview": "# Agent.md\n\nThis file provides a comprehensive overview of the OpenStatus project, its architecture, and development con"
  },
  {
    "path": "CONTRIBUTING.MD",
    "chars": 2496,
    "preview": "# Contribution Guidelines\n\nThank you for considering contributing to this project! We appreciate your efforts to make it"
  },
  {
    "path": "COOLIFY_DEPLOYMENT.md",
    "chars": 4702,
    "preview": "# Coolify Deployment Guide\n\nThis guide explains how to deploy OpenStatus using Coolify with pre-built Docker images from"
  },
  {
    "path": "COOLIFY_ENVIRONMENT_GUIDE.md",
    "chars": 5639,
    "preview": "# Coolify Environment Variables Setup Guide\n\nThis guide explains how to configure environment variables for OpenStatus d"
  },
  {
    "path": "COOLIFY_SETUP.md",
    "chars": 6718,
    "preview": "# Coolify Setup Guide\n\nThis guide provides step-by-step instructions for deploying OpenStatus on Coolify using pre-built"
  },
  {
    "path": "DOCKER.md",
    "chars": 8023,
    "preview": "# Docker Setup Guide\n\nComplete guide for running OpenStatus with Docker\n\n## Quick Start\n\n```bash\n# 1. Copy environment f"
  },
  {
    "path": "LICENSE",
    "chars": 34523,
    "preview": "                    GNU AFFERO GENERAL PUBLIC LICENSE\n                       Version 3, 19 November 2007\n\n Copyright (C)"
  },
  {
    "path": "README.md",
    "chars": 5637,
    "preview": "<p align=\"center\" style=\"margin-top: 120px\">\n\n  <h3 align=\"center\">openstatus</h3>\n\n  <p align=\"center\">The open-source "
  },
  {
    "path": "SECURITY.md",
    "chars": 2022,
    "preview": "# Reporting Security Issues\n\nThe openstatus team takes security bugs in opnestatus seriously. We appreciate your efforts"
  },
  {
    "path": "apps/README.md",
    "chars": 28,
    "preview": "# Apps\n\nAll openstatus apps\n"
  },
  {
    "path": "apps/checker/.gitignore",
    "chars": 4,
    "preview": "tmp\n"
  },
  {
    "path": "apps/checker/.golangci.yml",
    "chars": 39,
    "preview": "version: \"2\"\n\nlinters:\n  default: fast\n"
  },
  {
    "path": "apps/checker/.private.air.toml",
    "chars": 903,
    "preview": "root = \".\"\ntestdata_dir = \"testdata\"\ntmp_dir = \"tmp\"\n\n[build]\n    args_bin = []\n    bin = \"./tmp/main\"\n    cmd = \"go bui"
  },
  {
    "path": "apps/checker/.probe.air.toml",
    "chars": 902,
    "preview": "root = \".\"\ntestdata_dir = \"testdata\"\ntmp_dir = \"tmp\"\n\n[build]\n    args_bin = []\n    bin = \"./tmp/main\"\n    cmd = \"go bui"
  },
  {
    "path": "apps/checker/Dockerfile",
    "chars": 826,
    "preview": "FROM golang:1.26-alpine as builder\n\nWORKDIR /go/src/app\nCOPY ca/ca-bundle.crt /usr/local/share/ca-certificates/ca-bundle"
  },
  {
    "path": "apps/checker/README.md",
    "chars": 811,
    "preview": "# OpenStatus Checker\n\nThe checker service to ping external service.\n\nIt pings the service and save thedata to the tinybi"
  },
  {
    "path": "apps/checker/ca/ca-bundle.crt",
    "chars": 582677,
    "preview": "-----BEGIN CERTIFICATE-----\nMIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG\nA1UEBhMCVVMxFzAVBgNVBAoTDlZ"
  },
  {
    "path": "apps/checker/checker/dns.go",
    "chars": 2408,
    "preview": "package checker\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"strings\"\n\n\t\"github.com/rs/zerolog/log\"\n)\n\n\ntype DnsResponse struct "
  },
  {
    "path": "apps/checker/checker/dns_test.go",
    "chars": 332,
    "preview": "package checker_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/openstatushq/openstatus/apps/checker/checker\"\n)\n\n\nfunc TestPingD"
  },
  {
    "path": "apps/checker/checker/http.go",
    "chars": 5035,
    "preview": "package checker\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/tls\"\n\t\"encoding/base64\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/"
  },
  {
    "path": "apps/checker/checker/http_test.go",
    "chars": 3077,
    "preview": "package checker_test\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n"
  },
  {
    "path": "apps/checker/checker/tcp.go",
    "chars": 1505,
    "preview": "package checker\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"strings\"\n\t\"time\"\n)\n\ntype TCPData struct {\n\tWorkspaceID string `json:\"workspace"
  },
  {
    "path": "apps/checker/checker/tcp_test.go",
    "chars": 927,
    "preview": "package checker_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/openstatushq/openstatus/apps/checker/checker\"\n)\n\nfunc TestPingTc"
  },
  {
    "path": "apps/checker/checker/update.go",
    "chars": 2657,
    "preview": "package checker\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/rs/zerolog/log\"\n\t\"g"
  },
  {
    "path": "apps/checker/cmd/private/main.go",
    "chars": 2153,
    "preview": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"connectrpc.com/connect\"\n\t"
  },
  {
    "path": "apps/checker/cmd/server/main.go",
    "chars": 7183,
    "preview": "package main\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"math/rand/v2\"\n\t\"net/http\"\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\""
  },
  {
    "path": "apps/checker/fly.toml",
    "chars": 755,
    "preview": "# fly.toml app configuration file generated for openstatus-checker on 2023-11-30T20:23:20+01:00\n#\n# See https://fly.io/d"
  },
  {
    "path": "apps/checker/go.mod",
    "chars": 3893,
    "preview": "module github.com/openstatushq/openstatus/apps/checker\n\ngo 1.25.2\n\nrequire (\n\tcloud.google.com/go/auth v0.18.2\n\tcloud.go"
  },
  {
    "path": "apps/checker/go.sum",
    "chars": 18949,
    "preview": "cloud.google.com/go/auth v0.18.2 h1:+Nbt5Ev0xEqxlNjd6c+yYUeosQ5TtEUaNcN/3FozlaM=\ncloud.google.com/go/auth v0.18.2/go.mod"
  },
  {
    "path": "apps/checker/handlers/checker.go",
    "chars": 10368,
    "preview": "package handlers\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/cenkalti/backoff/v4\"\n\t\"github.com/g"
  },
  {
    "path": "apps/checker/handlers/checker_test.go",
    "chars": 7445,
    "preview": "package handlers_test\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"strings\"\n\t\"testing\"\n\n\t\""
  },
  {
    "path": "apps/checker/handlers/dns.go",
    "chars": 10849,
    "preview": "package handlers\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/gin-gonic/gin\"\n\t\"github."
  },
  {
    "path": "apps/checker/handlers/dns_test.go",
    "chars": 4628,
    "preview": "package handlers_test\n\nimport (\n\t\"encoding/json\"\n\t\"reflect\"\n\t\"testing\"\n\n\t// Adjust the import path if necessary to point"
  },
  {
    "path": "apps/checker/handlers/handler.go",
    "chars": 338,
    "preview": "package handlers\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/openstatushq/openstatus/apps/checker/pkg/tinybird\"\n)\n\ntype Handler "
  },
  {
    "path": "apps/checker/handlers/ping.go",
    "chars": 3980,
    "preview": "package handlers\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/cenkalti/backoff/v4\"\n\t\"github.com/g"
  },
  {
    "path": "apps/checker/handlers/ping_test.go",
    "chars": 3060,
    "preview": "package handlers_test\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"strings\"\n\t\"testing\"\n\n\t\""
  },
  {
    "path": "apps/checker/handlers/tcp.go",
    "chars": 8631,
    "preview": "package handlers\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/cenkalti/backoff/v4\"\n\t\"g"
  },
  {
    "path": "apps/checker/justfile",
    "chars": 294,
    "preview": "build-probe:\n    go build -o probe ./cmd/server/main.go\n\nbuild-private:\n    go build -o provider ./cmd/private/main.go\n\n"
  },
  {
    "path": "apps/checker/pkg/assertions/assertions.go",
    "chars": 3483,
    "preview": "package assertions\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"slices\"\n\t\"strings\"\n\n\t\"github.com/openstatushq/openstatus/apps/che"
  },
  {
    "path": "apps/checker/pkg/assertions/assertions_test.go",
    "chars": 6668,
    "preview": "package assertions\n\nimport (\n\t\"testing\"\n\n\t\"github.com/openstatushq/openstatus/apps/checker/request\"\n)\n\nfunc TestIntTarge"
  },
  {
    "path": "apps/checker/pkg/job/dns_job.go",
    "chars": 276,
    "preview": "package job\n\nimport (\n\t\"context\"\n\n\tv1 \"github.com/openstatushq/openstatus/apps/checker/proto/private_location/v1\"\n)\n\ntyp"
  },
  {
    "path": "apps/checker/pkg/job/http_job.go",
    "chars": 6716,
    "preview": "package job\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/cenkalti/backoff/v5\"\n\t\"github"
  },
  {
    "path": "apps/checker/pkg/job/http_job_test.go",
    "chars": 3885,
    "preview": "package job_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/openstatushq/openstatus/apps/checker/pkg/job\"\n\tv1 \"github"
  },
  {
    "path": "apps/checker/pkg/job/job.go",
    "chars": 1145,
    "preview": "package job\n\nimport (\n\t\"context\"\n\n\tv1 \"github.com/openstatushq/openstatus/apps/checker/proto/private_location/v1\"\n)\n\ntyp"
  },
  {
    "path": "apps/checker/pkg/job/monitors.go",
    "chars": 1497,
    "preview": "package job\n\ntype Monitor struct {\n\tID            int         `json:\"id\"`\n\tName          string      `json:\"name\"`\n\tURL "
  },
  {
    "path": "apps/checker/pkg/job/tcp_job.go",
    "chars": 2979,
    "preview": "package job\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/cenkalti/backoff/v5\"\n\t\"github.com/google/uuid\"\n\t\""
  },
  {
    "path": "apps/checker/pkg/job/tcp_job_test.go",
    "chars": 1113,
    "preview": "package job_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/openstatushq/openstatus/apps/checker/pkg/job\"\n\tv1 \"github"
  },
  {
    "path": "apps/checker/pkg/logger/logger.go",
    "chars": 362,
    "preview": "package logger\n\nimport (\n\t\"github.com/rs/zerolog\"\n\t\"github.com/rs/zerolog/log\"\n)\n\nfunc Configure(logLevel string) {\n\tlev"
  },
  {
    "path": "apps/checker/pkg/otel/otel.go",
    "chars": 5570,
    "preview": "package otel\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/openstatushq/openstatus/apps/checker/checker\"\n\t\"github.com/opens"
  },
  {
    "path": "apps/checker/pkg/otel/otel_test.go",
    "chars": 7441,
    "preview": "package otel\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\t\"github.com/openstatushq/openstatus/apps"
  },
  {
    "path": "apps/checker/pkg/scheduler/scheduler.go",
    "chars": 6912,
    "preview": "package scheduler\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"sync\"\n\t\"time\"\n\n\t\"connectrpc.com/connect\"\n\t\"github.com/madflojo/tasks\"\n\t\""
  },
  {
    "path": "apps/checker/pkg/scheduler/scheduler_test.go",
    "chars": 4492,
    "preview": "package scheduler_test\n\nimport (\n\t\"context\"\n\t\"sync/atomic\"\n\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"connectrpc.com/connect\"\n\t\"gith"
  },
  {
    "path": "apps/checker/pkg/tinybird/client.go",
    "chars": 2079,
    "preview": "package tinybird\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\n\t\"github.com/rs/zer"
  },
  {
    "path": "apps/checker/pkg/tinybird/client_test.go",
    "chars": 1896,
    "preview": "package tinybird_test\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"testing\"\n\n\t\"github.com/openstatushq/openstatus/apps/checker/pkg/tin"
  },
  {
    "path": "apps/checker/private-location.Dockerfile",
    "chars": 587,
    "preview": "FROM --platform=$BUILDPLATFORM golang:1.25-alpine as builder\n\nWORKDIR /go/src/app\n\nRUN apk add --no-cache tzdata\nENV TZ="
  },
  {
    "path": "apps/checker/proto/private_location/v1/assertions.pb.go",
    "chars": 19407,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.36.11\n// \tprotoc        (unknown)\n// "
  },
  {
    "path": "apps/checker/proto/private_location/v1/dns_monitor.pb.go",
    "chars": 6377,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.36.11\n// \tprotoc        (unknown)\n// "
  },
  {
    "path": "apps/checker/proto/private_location/v1/http_monitor.pb.go",
    "chars": 10373,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.36.11\n// \tprotoc        (unknown)\n// "
  },
  {
    "path": "apps/checker/proto/private_location/v1/private_location.connect.go",
    "chars": 10407,
    "preview": "// Code generated by protoc-gen-connect-go. DO NOT EDIT.\n//\n// Source: private_location/v1/private_location.proto\n\npacka"
  },
  {
    "path": "apps/checker/proto/private_location/v1/private_location.pb.go",
    "chars": 26473,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.36.11\n// \tprotoc        (unknown)\n// "
  },
  {
    "path": "apps/checker/proto/private_location/v1/tcp_monitor.pb.go",
    "chars": 5692,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.36.11\n// \tprotoc        (unknown)\n// "
  },
  {
    "path": "apps/checker/request/request.go",
    "chars": 4989,
    "preview": "package request\n\nimport (\n\t\"encoding/json\"\n)\n\ntype AssertionType string\n\nconst (\n\tAssertionHeader    AssertionType = \"he"
  },
  {
    "path": "apps/dashboard/.dockerignore",
    "chars": 86,
    "preview": "# This file is generated by Dofigen v2.5.1\n# See https://github.com/lenra-io/dofigen\n\n"
  },
  {
    "path": "apps/dashboard/.gitignore",
    "chars": 8,
    "preview": ".vercel\n"
  },
  {
    "path": "apps/dashboard/Dockerfile",
    "chars": 2440,
    "preview": "# syntax=docker/dockerfile:1.11\n# This file is generated by Dofigen v2.5.1\n# See https://github.com/lenra-io/dofigen\n\n# "
  },
  {
    "path": "apps/dashboard/components.json",
    "chars": 431,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema.json\",\n  \"style\": \"new-york\",\n  \"rsc\": true,\n  \"tsx\": true,\n  \"tailwind\": {"
  },
  {
    "path": "apps/dashboard/docker-compose.yaml",
    "chars": 254,
    "preview": "name: server\nservices:\n    server:\n        build:\n         context: ../..\n         dockerfile: apps/dashboard/Dockerfile"
  },
  {
    "path": "apps/dashboard/dofigen.yml",
    "chars": 2123,
    "preview": "builders:\n  # Stage 1: Next.js build with Node.js\n  builder:\n    fromImage: node:24-slim\n    workdir: /app\n    copy:\n   "
  },
  {
    "path": "apps/dashboard/env.ts",
    "chars": 74,
    "preview": "const file = Bun.file(\"./.env.example\");\nawait Bun.write(\"./.env\", file);\n"
  },
  {
    "path": "apps/dashboard/instrumentation-client.ts",
    "chars": 1162,
    "preview": "// This file configures the initialization of Sentry on the client.\n// The config you add here will be used whenever a u"
  },
  {
    "path": "apps/dashboard/next-env.d.ts",
    "chars": 247,
    "preview": "/// <reference types=\"next\" />\n/// <reference types=\"next/image-types/global\" />\nimport \"./.next/types/routes.d.ts\";\n\n//"
  },
  {
    "path": "apps/dashboard/next.config.ts",
    "chars": 1399,
    "preview": "import { withSentryConfig } from \"@sentry/nextjs\";\nimport type { NextConfig } from \"next\";\n\nconst nextConfig: NextConfig"
  },
  {
    "path": "apps/dashboard/package.json",
    "chars": 3620,
    "preview": "{\n  \"name\": \"@openstatus/dashboard\",\n  \"version\": \"1.0.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"dev\": \"next dev --turb"
  },
  {
    "path": "apps/dashboard/postcss.config.mjs",
    "chars": 81,
    "preview": "const config = {\n  plugins: [\"@tailwindcss/postcss\"],\n};\n\nexport default config;\n"
  },
  {
    "path": "apps/dashboard/sentry.edge.config.ts",
    "chars": 1212,
    "preview": "// This file configures the initialization of Sentry for edge features (middleware, edge routes, and so on).\n// The conf"
  },
  {
    "path": "apps/dashboard/sentry.server.config.ts",
    "chars": 1060,
    "preview": "// This file configures the initialization of Sentry on the server.\n// The config you add here will be used whenever the"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/agents/breadcrumb.tsx",
    "chars": 243,
    "preview": "\"use client\";\n\nimport { NavBreadcrumb } from \"@/components/nav/nav-breadcrumb\";\nimport { Bot } from \"lucide-react\";\n\nexp"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/agents/layout.tsx",
    "chars": 657,
    "preview": "import {\n  AppHeader,\n  AppHeaderActions,\n  AppHeaderContent,\n} from \"@/components/nav/app-header\";\nimport { AppSidebarT"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/agents/nav-actions.tsx",
    "chars": 1022,
    "preview": "import { NavFeedback } from \"@/components/nav/nav-feedback\";\nimport { Button } from \"@openstatus/ui/components/ui/button"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/agents/page.tsx",
    "chars": 3125,
    "preview": "\"use client\";\n\nimport { Code } from \"@/components/common/code\";\nimport { Link } from \"@/components/common/link\";\nimport "
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/cli/breadcrumb.tsx",
    "chars": 250,
    "preview": "\"use client\";\n\nimport { NavBreadcrumb } from \"@/components/nav/nav-breadcrumb\";\nimport { Terminal } from \"lucide-react\";"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/cli/layout.tsx",
    "chars": 657,
    "preview": "import {\n  AppHeader,\n  AppHeaderActions,\n  AppHeaderContent,\n} from \"@/components/nav/app-header\";\nimport { AppSidebarT"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/cli/nav-actions.tsx",
    "chars": 1022,
    "preview": "import { NavFeedback } from \"@/components/nav/nav-feedback\";\nimport { Button } from \"@openstatus/ui/components/ui/button"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/cli/page.tsx",
    "chars": 8525,
    "preview": "import { Code } from \"@/components/common/code\";\nimport { Link } from \"@/components/common/link\";\nimport {\n  SectionDesc"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/invite/client.tsx",
    "chars": 3117,
    "preview": "\"use client\";\n\nimport {\n  Section,\n  SectionDescription,\n  SectionGroup,\n  SectionHeader,\n  SectionTitle,\n} from \"@/comp"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/invite/layout.tsx",
    "chars": 725,
    "preview": "import {\n  AppHeader,\n  AppHeaderActions,\n  AppHeaderContent,\n} from \"@/components/nav/app-header\";\nimport { AppSidebarT"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/invite/nav-actions.tsx",
    "chars": 198,
    "preview": "import { NavFeedback } from \"@/components/nav/nav-feedback\";\n\nexport function NavActions() {\n  return (\n    <div classNa"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/invite/page.tsx",
    "chars": 666,
    "preview": "import { HydrateClient, getQueryClient, trpc } from \"@/lib/trpc/server\";\nimport { redirect } from \"next/navigation\";\nimp"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/invite/search-params.tsx",
    "chars": 215,
    "preview": "import { createSearchParamsCache, parseAsString } from \"nuqs/server\";\n\nexport const searchParamsParsers = {\n  token: par"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/layout.tsx",
    "chars": 1197,
    "preview": "import { AppSidebar } from \"@/components/nav/app-sidebar\";\nimport { HydrateClient, getQueryClient, trpc } from \"@/lib/tr"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/(list)/breadcrumb.tsx",
    "chars": 265,
    "preview": "\"use client\";\n\nimport { NavBreadcrumb } from \"@/components/nav/nav-breadcrumb\";\nimport { Activity } from \"lucide-react\";"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/(list)/client.tsx",
    "chars": 6873,
    "preview": "\"use client\";\n\nimport {\n  Section,\n  SectionDescription,\n  SectionGroup,\n  SectionHeader,\n  SectionTitle,\n} from \"@/comp"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/(list)/layout.tsx",
    "chars": 656,
    "preview": "import {\n  AppHeader,\n  AppHeaderActions,\n  AppHeaderContent,\n} from \"@/components/nav/app-header\";\nimport { AppSidebarT"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/(list)/nav-actions.tsx",
    "chars": 1298,
    "preview": "\"use client\";\n\nimport { UpgradeDialog } from \"@/components/dialogs/upgrade\";\nimport { NavFeedback } from \"@/components/n"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/(list)/page.tsx",
    "chars": 612,
    "preview": "import { HydrateClient, getQueryClient, trpc } from \"@/lib/trpc/server\";\nimport type { SearchParams } from \"nuqs\";\nimpor"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/(list)/search-params.ts",
    "chars": 591,
    "preview": "import {\n  createParser,\n  createSearchParamsCache,\n  parseAsStringEnum,\n} from \"nuqs/server\";\n\nexport const parseAsSort"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/[id]/breadcrumb.tsx",
    "chars": 1206,
    "preview": "\"use client\";\n\nimport { NavBreadcrumb } from \"@/components/nav/nav-breadcrumb\";\nimport { useTRPC } from \"@/lib/trpc/clie"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/[id]/constants.ts",
    "chars": 424,
    "preview": "import type { LucideIcon } from \"lucide-react\";\nimport { Cog, LayoutGrid, Logs, Siren } from \"lucide-react\";\n\nexport con"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/[id]/edit/layout.tsx",
    "chars": 408,
    "preview": "import { HydrateClient, getQueryClient, trpc } from \"@/lib/trpc/server\";\n\nexport default async function Layout({\n  child"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/[id]/edit/page.tsx",
    "chars": 898,
    "preview": "\"use client\";\n\nimport {\n  Section,\n  SectionDescription,\n  SectionGroup,\n  SectionHeader,\n  SectionTitle,\n} from \"@/comp"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/[id]/incidents/layout.tsx",
    "chars": 699,
    "preview": "import { getQueryClient, trpc } from \"@/lib/trpc/server\";\nimport { SidebarProvider } from \"@openstatus/ui/components/ui/"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/[id]/incidents/page.tsx",
    "chars": 1971,
    "preview": "\"use client\";\n\nimport {\n  EmptyStateContainer,\n  EmptyStateDescription,\n  EmptyStateTitle,\n} from \"@/components/content/"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/[id]/layout.tsx",
    "chars": 1220,
    "preview": "import {\n  AppHeader,\n  AppHeaderActions,\n  AppHeaderContent,\n} from \"@/components/nav/app-header\";\nimport { AppSidebarT"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/[id]/logs/client.tsx",
    "chars": 6084,
    "preview": "\"use client\";\n\nimport { Link } from \"@/components/common/link\";\nimport {\n  BillingOverlay,\n  BillingOverlayButton,\n  Bil"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/[id]/logs/page.tsx",
    "chars": 378,
    "preview": "import type { SearchParams } from \"nuqs/server\";\nimport { Client } from \"./client\";\nimport { searchParamsCache } from \"."
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/[id]/logs/search-params.ts",
    "chars": 842,
    "preview": "import { PERIODS, STATUS, TRIGGER } from \"@/data/metrics.client\";\nimport { endOfDay } from \"date-fns\";\nimport { startOfD"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/[id]/nav-actions.tsx",
    "chars": 7058,
    "preview": "\"use client\";\n\nimport { DataTableSheetTest } from \"@/components/data-table/response-logs/data-table-sheet-test\";\nimport "
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/[id]/overview/client.tsx",
    "chars": 9040,
    "preview": "\"use client\";\n\nimport { ChartAreaLatency } from \"@/components/chart/chart-area-latency\";\nimport { ChartAreaTimingPhases "
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/[id]/overview/layout.tsx",
    "chars": 422,
    "preview": "import { SidebarProvider } from \"@openstatus/ui/components/ui/sidebar\";\nimport { Sidebar } from \"../sidebar\";\n\nexport de"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/[id]/overview/page.tsx",
    "chars": 378,
    "preview": "import type { SearchParams } from \"nuqs/server\";\nimport { Client } from \"./client\";\nimport { searchParamsCache } from \"."
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/[id]/overview/search-params.ts",
    "chars": 652,
    "preview": "import { INTERVALS } from \"@/data/metrics.client\";\nimport {\n  createSearchParamsCache,\n  parseAsArrayOf,\n  parseAsNumber"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/[id]/page.tsx",
    "chars": 210,
    "preview": "import { redirect } from \"next/navigation\";\n\nexport default async function Page({\n  params,\n}: {\n  params: Promise<{ id:"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/[id]/sidebar.tsx",
    "chars": 7307,
    "preview": "\"use client\";\n\nimport { TableCellLink } from \"@/components/data-table/table-cell-link\";\nimport { SidebarRight } from \"@/"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/[id]/tabs.tsx",
    "chars": 383,
    "preview": "\"use client\";\n\nimport { NavTabs } from \"@/components/nav/nav-tabs\";\nimport { useParams } from \"next/navigation\";\nimport "
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/create/breadcrumb.tsx",
    "chars": 401,
    "preview": "\"use client\";\n\nimport { NavBreadcrumb } from \"@/components/nav/nav-breadcrumb\";\nimport { Activity } from \"lucide-react\";"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/create/layout.tsx",
    "chars": 507,
    "preview": "import { AppHeader, AppHeaderContent } from \"@/components/nav/app-header\";\nimport { AppSidebarTrigger } from \"@/componen"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/monitors/create/page.tsx",
    "chars": 2395,
    "preview": "\"use client\";\n\nimport {\n  EmptyStateContainer,\n  EmptyStateTitle,\n} from \"@/components/content/empty-state\";\nimport { Em"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/notifications/breadcrumb.tsx",
    "chars": 262,
    "preview": "\"use client\";\n\nimport { NavBreadcrumb } from \"@/components/nav/nav-breadcrumb\";\nimport { Bell } from \"lucide-react\";\n\nex"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/notifications/client.tsx",
    "chars": 6767,
    "preview": "\"use client\";\n\nimport { Link } from \"@/components/common/link\";\nimport {\n  ActionCard,\n  ActionCardDescription,\n  Action"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/notifications/layout.tsx",
    "chars": 875,
    "preview": "import {\n  AppHeader,\n  AppHeaderActions,\n  AppHeaderContent,\n} from \"@/components/nav/app-header\";\nimport { AppSidebarT"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/notifications/nav-actions.tsx",
    "chars": 198,
    "preview": "import { NavFeedback } from \"@/components/nav/nav-feedback\";\n\nexport function NavActions() {\n  return (\n    <div classNa"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/notifications/page.tsx",
    "chars": 303,
    "preview": "import type { SearchParams } from \"nuqs\";\nimport { Client } from \"./client\";\nimport { searchParamsCache } from \"./search"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/notifications/search-params.ts",
    "chars": 287,
    "preview": "import {\n  createSearchParamsCache,\n  parseAsString,\n  parseAsStringEnum,\n} from \"nuqs/server\";\n\nexport const searchPara"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/onboarding/client.tsx",
    "chars": 10807,
    "preview": "\"use client\";\n\nimport {\n  ActionCard,\n  ActionCardDescription,\n  ActionCardGroup,\n  ActionCardHeader,\n  ActionCardTitle,"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/onboarding/layout.tsx",
    "chars": 729,
    "preview": "import {\n  AppHeader,\n  AppHeaderActions,\n  AppHeaderContent,\n} from \"@/components/nav/app-header\";\nimport { AppSidebarT"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/onboarding/nav-actions.tsx",
    "chars": 198,
    "preview": "import { NavFeedback } from \"@/components/nav/nav-feedback\";\n\nexport function NavActions() {\n  return (\n    <div classNa"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/onboarding/page.tsx",
    "chars": 305,
    "preview": "import { Client } from \"./client\";\nimport { searchParamsCache } from \"./search-params\";\n\nimport type { SearchParams } fr"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/onboarding/search-params.ts",
    "chars": 348,
    "preview": "import {\n  createSearchParamsCache,\n  parseAsString,\n  parseAsStringLiteral,\n} from \"nuqs/server\";\n\nconst STEPS = [\"1\", "
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/overview/breadcrumb.tsx",
    "chars": 269,
    "preview": "\"use client\";\n\nimport { NavBreadcrumb } from \"@/components/nav/nav-breadcrumb\";\nimport { LayoutGrid } from \"lucide-react"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/overview/data-table-status-reports.tsx",
    "chars": 870,
    "preview": "\"use client\";\n\nimport { DataTable as UpdatesDataTable } from \"@/components/data-table/status-report-updates/data-table\";"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/overview/layout.tsx",
    "chars": 1306,
    "preview": "import {\n  AppHeader,\n  AppHeaderActions,\n  AppHeaderContent,\n} from \"@/components/nav/app-header\";\nimport { AppSidebarT"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/overview/nav-actions.tsx",
    "chars": 198,
    "preview": "import { NavFeedback } from \"@/components/nav/nav-feedback\";\n\nexport function NavActions() {\n  return (\n    <div classNa"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/overview/page.tsx",
    "chars": 6661,
    "preview": "\"use client\";\n\nimport {\n  SectionDescription,\n  SectionGroup,\n  SectionHeader,\n  SectionTitle,\n} from \"@/components/cont"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/page.tsx",
    "chars": 105,
    "preview": "import { redirect } from \"next/navigation\";\n\nexport default function Page() {\n  redirect(\"/overview\");\n}\n"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/private-locations/breadcrumb.tsx",
    "chars": 268,
    "preview": "\"use client\";\n\nimport { NavBreadcrumb } from \"@/components/nav/nav-breadcrumb\";\nimport { Globe } from \"lucide-react\";\n\ne"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/private-locations/client.tsx",
    "chars": 3202,
    "preview": "\"use client\";\nimport { Link } from \"@/components/common/link\";\nimport {\n  BillingOverlay,\n  BillingOverlayButton,\n  Bill"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/private-locations/layout.tsx",
    "chars": 952,
    "preview": "import {\n  AppHeader,\n  AppHeaderActions,\n  AppHeaderContent,\n} from \"@/components/nav/app-header\";\nimport { AppSidebarT"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/private-locations/nav-actions.tsx",
    "chars": 2037,
    "preview": "\"use client\";\n\nimport { UpgradeDialog } from \"@/components/dialogs/upgrade\";\nimport { FormSheetPrivateLocation } from \"@"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/private-locations/page.tsx",
    "chars": 98,
    "preview": "import { Client } from \"./client\";\n\nexport default async function Page() {\n  return <Client />;\n}\n"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/settings/(list)/layout.tsx",
    "chars": 728,
    "preview": "import {\n  AppHeader,\n  AppHeaderActions,\n  AppHeaderContent,\n} from \"@/components/nav/app-header\";\nimport { AppSidebarT"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/settings/(list)/nav-actions.tsx",
    "chars": 198,
    "preview": "import { NavFeedback } from \"@/components/nav/nav-feedback\";\n\nexport function NavActions() {\n  return (\n    <div classNa"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/settings/(list)/page.tsx",
    "chars": 1714,
    "preview": "import { Link } from \"@/components/common/link\";\nimport {\n  ActionCard,\n  ActionCardDescription,\n  ActionCardGroup,\n  Ac"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/settings/account/breadcrumb.tsx",
    "chars": 410,
    "preview": "\"use client\";\n\nimport { NavBreadcrumb } from \"@/components/nav/nav-breadcrumb\";\nimport { Cog, User } from \"lucide-react\""
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/settings/account/layout.tsx",
    "chars": 965,
    "preview": "import {\n  AppHeader,\n  AppHeaderActions,\n  AppHeaderContent,\n} from \"@/components/nav/app-header\";\nimport { AppSidebarT"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/settings/account/nav-actions.tsx",
    "chars": 198,
    "preview": "import { NavFeedback } from \"@/components/nav/nav-feedback\";\n\nexport function NavActions() {\n  return (\n    <div classNa"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/settings/account/page.tsx",
    "chars": 4760,
    "preview": "\"use client\";\n\nimport { Link } from \"@/components/common/link\";\nimport {\n  Section,\n  SectionGroup,\n  SectionHeader,\n  S"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/settings/billing/breadcrumb.tsx",
    "chars": 422,
    "preview": "\"use client\";\n\nimport { NavBreadcrumb } from \"@/components/nav/nav-breadcrumb\";\nimport { Cog, CreditCard } from \"lucide-"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/settings/billing/client.tsx",
    "chars": 8660,
    "preview": "\"use client\";\n\nimport { BillingAddons } from \"@/components/content/billing-addons\";\nimport { BillingProgress } from \"@/c"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/settings/billing/layout.tsx",
    "chars": 704,
    "preview": "import {\n  AppHeader,\n  AppHeaderActions,\n  AppHeaderContent,\n} from \"@/components/nav/app-header\";\nimport { AppSidebarT"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/settings/billing/nav-actions.tsx",
    "chars": 198,
    "preview": "import { NavFeedback } from \"@/components/nav/nav-feedback\";\n\nexport function NavActions() {\n  return (\n    <div classNa"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/settings/billing/page.tsx",
    "chars": 304,
    "preview": "import type { SearchParams } from \"nuqs\";\nimport { Client } from \"./client\";\nimport { searchParamsCache } from \"./search"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/settings/billing/search-params.ts",
    "chars": 219,
    "preview": "import { createSearchParamsCache, parseAsBoolean } from \"nuqs/server\";\n\nexport const searchParamsParsers = {\n  success: "
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/settings/general/breadcrumb.tsx",
    "chars": 436,
    "preview": "\"use client\";\n\nimport { NavBreadcrumb } from \"@/components/nav/nav-breadcrumb\";\nimport { Cog, SlidersHorizontal } from \""
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/settings/general/layout.tsx",
    "chars": 1113,
    "preview": "import {\n  AppHeader,\n  AppHeaderActions,\n  AppHeaderContent,\n} from \"@/components/nav/app-header\";\nimport { AppSidebarT"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/settings/general/nav-actions.tsx",
    "chars": 198,
    "preview": "import { NavFeedback } from \"@/components/nav/nav-feedback\";\n\nexport function NavActions() {\n  return (\n    <div classNa"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/settings/general/page.tsx",
    "chars": 2777,
    "preview": "\"use client\";\n\nimport {\n  Section,\n  SectionDescription,\n  SectionGroup,\n  SectionHeader,\n  SectionTitle,\n} from \"@/comp"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/settings/integrations/breadcrumb.tsx",
    "chars": 419,
    "preview": "\"use client\";\n\nimport { NavBreadcrumb } from \"@/components/nav/nav-breadcrumb\";\nimport { Blocks, Cog } from \"lucide-reac"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/settings/integrations/layout.tsx",
    "chars": 1046,
    "preview": "import {\n  AppHeader,\n  AppHeaderActions,\n  AppHeaderContent,\n} from \"@/components/nav/app-header\";\nimport { AppSidebarT"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/settings/integrations/nav-actions.tsx",
    "chars": 198,
    "preview": "import { NavFeedback } from \"@/components/nav/nav-feedback\";\n\nexport function NavActions() {\n  return (\n    <div classNa"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/settings/integrations/page.tsx",
    "chars": 1571,
    "preview": "\"use client\";\n\nimport {\n  Section,\n  SectionDescription,\n  SectionGroup,\n  SectionHeader,\n  SectionTitle,\n} from \"@/comp"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/settings/integrations/slack-card.tsx",
    "chars": 3839,
    "preview": "\"use client\";\n\nimport { Link } from \"@/components/common/link\";\nimport {\n  FormCard,\n  FormCardContent,\n  FormCardDescri"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/settings/tabs.tsx",
    "chars": 784,
    "preview": "\"use client\";\n\nimport { NavTabs } from \"@/components/nav/nav-tabs\";\nimport { Blocks, Cog, CreditCard, User } from \"lucid"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/status-pages/(list)/breadcrumb.tsx",
    "chars": 269,
    "preview": "\"use client\";\n\nimport { NavBreadcrumb } from \"@/components/nav/nav-breadcrumb\";\nimport { PanelTop } from \"lucide-react\";"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/status-pages/(list)/client.tsx",
    "chars": 1470,
    "preview": "\"use client\";\n\nimport { Note, NoteButton } from \"@/components/common/note\";\nimport {\n  SectionDescription,\n  SectionGrou"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/status-pages/(list)/layout.tsx",
    "chars": 657,
    "preview": "import {\n  AppHeader,\n  AppHeaderActions,\n  AppHeaderContent,\n} from \"@/components/nav/app-header\";\nimport { AppSidebarT"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/status-pages/(list)/nav-actions.tsx",
    "chars": 1374,
    "preview": "\"use client\";\n\nimport { UpgradeDialog } from \"@/components/dialogs/upgrade\";\nimport { NavFeedback } from \"@/components/n"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/status-pages/(list)/page.tsx",
    "chars": 332,
    "preview": "import { HydrateClient, getQueryClient, trpc } from \"@/lib/trpc/server\";\nimport { Client } from \"./client\";\n\nexport defa"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/status-pages/[id]/breadcrumb.tsx",
    "chars": 1292,
    "preview": "\"use client\";\n\nimport { NavBreadcrumb } from \"@/components/nav/nav-breadcrumb\";\nimport { useTRPC } from \"@/lib/trpc/clie"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/status-pages/[id]/components/layout.tsx",
    "chars": 964,
    "preview": "import { HydrateClient, getQueryClient, trpc } from \"@/lib/trpc/server\";\nimport { SidebarProvider } from \"@openstatus/ui"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/status-pages/[id]/components/page.tsx",
    "chars": 946,
    "preview": "\"use client\";\n\nimport {\n  Section,\n  SectionDescription,\n  SectionGroup,\n  SectionHeader,\n  SectionTitle,\n} from \"@/comp"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/status-pages/[id]/constants.ts",
    "chars": 548,
    "preview": "import type { LucideIcon } from \"lucide-react\";\nimport { Cog, Hammer, LayoutTemplate, Megaphone, Users } from \"lucide-re"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/status-pages/[id]/edit/page.tsx",
    "chars": 919,
    "preview": "\"use client\";\n\nimport {\n  Section,\n  SectionDescription,\n  SectionGroup,\n  SectionHeader,\n  SectionTitle,\n} from \"@/comp"
  },
  {
    "path": "apps/dashboard/src/app/(dashboard)/status-pages/[id]/layout.tsx",
    "chars": 1255,
    "preview": "import { redirect } from \"next/navigation\";\n\nimport {\n  AppHeader,\n  AppHeaderActions,\n  AppHeaderContent,\n} from \"@/com"
  }
]

// ... and 2023 more files (download for full content)

About this extraction

This page contains the full source code of the openstatusHQ/openstatus GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 2223 files (11.4 MB), approximately 3.1M tokens, and a symbol index with 4125 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!