@intentius/chant-lexicon-otel 0.124.46 → 0.124.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/build/capability-plugin.d.ts +10 -0
- package/dist/build/capability-plugin.d.ts.map +1 -0
- package/dist/build/capability-plugin.js +19 -0
- package/dist/build/ocb-build.d.ts +38 -0
- package/dist/build/ocb-build.d.ts.map +1 -0
- package/dist/build/ocb-build.js +49 -0
- package/dist/clickhouse-tables.d.ts +73 -0
- package/dist/clickhouse-tables.d.ts.map +1 -0
- package/dist/clickhouse-tables.js +199 -0
- package/dist/codegen/docs.d.ts.map +1 -1
- package/dist/codegen/docs.js +4 -2
- package/dist/codegen/generate.d.ts +29 -10
- package/dist/codegen/generate.d.ts.map +1 -1
- package/dist/codegen/generate.js +82 -17
- package/dist/components/common.d.ts +3 -1
- package/dist/components/common.d.ts.map +1 -1
- package/dist/components/common.js +2 -0
- package/dist/components/connectors.d.ts +25 -90
- package/dist/components/connectors.d.ts.map +1 -1
- package/dist/components/connectors.js +3 -0
- package/dist/components/exporters.d.ts +78 -34
- package/dist/components/exporters.d.ts.map +1 -1
- package/dist/components/exporters.js +26 -1
- package/dist/components/extensions.d.ts +16 -33
- package/dist/components/extensions.d.ts.map +1 -1
- package/dist/components/filtering.d.ts +13 -60
- package/dist/components/filtering.d.ts.map +1 -1
- package/dist/components/k8s-receivers.d.ts +5 -53
- package/dist/components/k8s-receivers.d.ts.map +1 -1
- package/dist/components/overlay.d.ts +25 -0
- package/dist/components/overlay.d.ts.map +1 -0
- package/dist/components/overlay.js +19 -0
- package/dist/components/processors.d.ts +18 -79
- package/dist/components/processors.d.ts.map +1 -1
- package/dist/components/receivers.d.ts +17 -71
- package/dist/components/receivers.d.ts.map +1 -1
- package/dist/components/receivers.js +3 -1
- package/dist/components/sampling.d.ts +19 -35
- package/dist/components/sampling.d.ts.map +1 -1
- package/dist/config-hygiene.d.ts +10 -8
- package/dist/config-hygiene.d.ts.map +1 -1
- package/dist/config-hygiene.js +36 -13
- package/dist/coverage.d.ts +50 -0
- package/dist/coverage.d.ts.map +1 -0
- package/dist/coverage.js +92 -0
- package/dist/define.d.ts +8 -5
- package/dist/define.d.ts.map +1 -1
- package/dist/define.js +10 -6
- package/dist/distribution.d.ts +125 -0
- package/dist/distribution.d.ts.map +1 -0
- package/dist/distribution.js +227 -0
- package/dist/generated/index.d.ts +4234 -0
- package/dist/generated/index.d.ts.map +1 -0
- package/dist/generated/index.js +23 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/init-templates.js +2 -2
- package/dist/integrity.json +11 -9
- package/dist/lint/audit-catalog.d.ts +3 -0
- package/dist/lint/audit-catalog.d.ts.map +1 -1
- package/dist/lint/audit-catalog.js +5 -0
- package/dist/lint/post-synth/index.d.ts.map +1 -1
- package/dist/lint/post-synth/index.js +4 -0
- package/dist/lint/post-synth/otel-helpers.d.ts +2 -1
- package/dist/lint/post-synth/otel-helpers.d.ts.map +1 -1
- package/dist/lint/post-synth/otel-helpers.js +1 -1
- package/dist/lint/post-synth/otel119.d.ts +1 -1
- package/dist/lint/post-synth/otel119.js +1 -1
- package/dist/lint/post-synth/otel125.d.ts +1 -1
- package/dist/lint/post-synth/otel125.js +1 -1
- package/dist/lint/post-synth/otel126.d.ts +1 -1
- package/dist/lint/post-synth/otel126.js +1 -1
- package/dist/lint/post-synth/otel127.d.ts +1 -1
- package/dist/lint/post-synth/otel127.js +1 -1
- package/dist/lint/post-synth/otel128.d.ts +8 -0
- package/dist/lint/post-synth/otel128.d.ts.map +1 -0
- package/dist/lint/post-synth/otel128.js +17 -0
- package/dist/lint/post-synth/otel129.d.ts +15 -0
- package/dist/lint/post-synth/otel129.d.ts.map +1 -0
- package/dist/lint/post-synth/otel129.js +92 -0
- package/dist/lsp/completions.d.ts +10 -1
- package/dist/lsp/completions.d.ts.map +1 -1
- package/dist/lsp/completions.js +29 -1
- package/dist/lsp/hover.d.ts +5 -1
- package/dist/lsp/hover.d.ts.map +1 -1
- package/dist/lsp/hover.js +16 -3
- package/dist/lsp/properties.d.ts +34 -0
- package/dist/lsp/properties.d.ts.map +1 -0
- package/dist/lsp/properties.js +135 -0
- package/dist/manifest.json +1 -1
- package/dist/meta.json +5 -0
- package/dist/metric-names.d.ts +36 -8
- package/dist/metric-names.d.ts.map +1 -1
- package/dist/metric-names.js +42 -9
- package/dist/model.d.ts +1 -1
- package/dist/model.js +1 -1
- package/dist/okf/index.md +3 -0
- package/dist/okf/rules/OTEL128.md +11 -0
- package/dist/okf/rules/OTEL129.md +11 -0
- package/dist/okf/types/ClickHouseExporter.md +9 -0
- package/dist/op/activities/collector-audit.d.ts +18 -6
- package/dist/op/activities/collector-audit.d.ts.map +1 -1
- package/dist/op/activities/collector-audit.js +37 -21
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +51 -8
- package/dist/rules/otel-helpers.ts +1 -1
- package/dist/rules/otel119.ts +1 -1
- package/dist/rules/otel125.ts +1 -1
- package/dist/rules/otel126.ts +1 -1
- package/dist/rules/otel127.ts +1 -1
- package/dist/rules/otel128.ts +22 -0
- package/dist/rules/otel129.ts +99 -0
- package/dist/serializer.d.ts +3 -0
- package/dist/serializer.d.ts.map +1 -1
- package/dist/serializer.js +12 -2
- package/dist/spec/builtins.d.ts +17 -0
- package/dist/spec/builtins.d.ts.map +1 -0
- package/dist/spec/builtins.js +45 -0
- package/dist/spec/fetch.d.ts +120 -0
- package/dist/spec/fetch.d.ts.map +1 -0
- package/dist/spec/fetch.js +282 -0
- package/dist/spec/parse.d.ts +77 -0
- package/dist/spec/parse.d.ts.map +1 -0
- package/dist/spec/parse.js +337 -0
- package/dist/spec/pin.d.ts +82 -0
- package/dist/spec/pin.d.ts.map +1 -0
- package/dist/spec/pin.js +126 -0
- package/dist/spec/snapshot-cli.d.ts +13 -0
- package/dist/spec/snapshot-cli.d.ts.map +1 -0
- package/dist/spec/snapshot-cli.js +31 -0
- package/dist/spec/snapshot.d.ts +9 -0
- package/dist/spec/snapshot.d.ts.map +1 -0
- package/dist/spec/snapshot.js +14 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/validate-config.d.ts +1 -1
- package/dist/validate-config.d.ts.map +1 -1
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +1 -0
- package/dist/workspace-links.d.ts +25 -0
- package/dist/workspace-links.d.ts.map +1 -0
- package/dist/workspace-links.js +49 -0
- package/package.json +3 -2
- package/src/build/capability-plugin.ts +30 -0
- package/src/build/ocb-build.ts +73 -0
- package/src/clickhouse-exporter.e2e.test.ts +208 -0
- package/src/clickhouse-tables.test.ts +216 -0
- package/src/clickhouse-tables.ts +223 -0
- package/src/codegen/docs.ts +4 -2
- package/src/codegen/generate.ts +95 -19
- package/src/components/common.ts +4 -2
- package/src/components/connectors.ts +30 -77
- package/src/components/exporters.ts +128 -61
- package/src/components/extensions.ts +22 -36
- package/src/components/filtering.ts +17 -58
- package/src/components/k8s-receivers.test.ts +1 -1
- package/src/components/k8s-receivers.ts +3 -45
- package/src/components/overlay.ts +24 -0
- package/src/components/processors.ts +18 -63
- package/src/components/receivers.ts +20 -60
- package/src/components/sampling.ts +24 -37
- package/src/config-hygiene.ts +36 -13
- package/src/coverage.test.ts +37 -0
- package/src/coverage.ts +121 -0
- package/src/define.test.ts +2 -0
- package/src/define.ts +10 -6
- package/src/distribution.test.ts +250 -0
- package/src/distribution.ts +305 -0
- package/src/generated/index.ts +4576 -0
- package/src/generated/lexicon-otel.json +5 -0
- package/src/generated/properties.json +1 -0
- package/src/import/roundtrip.test.ts +16 -0
- package/src/import/testdata/clickhouse.yaml +37 -0
- package/src/import/testdata/fixtures.ts +17 -2
- package/src/import/testdata/upstream/clickhouse-exporter.yaml +60 -0
- package/src/index.ts +69 -0
- package/src/init-templates.ts +2 -2
- package/src/lint/audit-catalog.ts +15 -0
- package/src/lint/post-synth/index.ts +4 -0
- package/src/lint/post-synth/otel-helpers.ts +1 -1
- package/src/lint/post-synth/otel119.ts +1 -1
- package/src/lint/post-synth/otel125.ts +1 -1
- package/src/lint/post-synth/otel126.ts +1 -1
- package/src/lint/post-synth/otel127.ts +1 -1
- package/src/lint/post-synth/otel128.ts +22 -0
- package/src/lint/post-synth/otel129.ts +99 -0
- package/src/lsp/completions.ts +30 -1
- package/src/lsp/hover.ts +14 -3
- package/src/lsp/properties.test.ts +72 -0
- package/src/lsp/properties.ts +141 -0
- package/src/metric-names.test.ts +11 -0
- package/src/metric-names.ts +64 -16
- package/src/model.ts +1 -1
- package/src/op/activities/collector-audit.test.ts +29 -22
- package/src/op/activities/collector-audit.ts +38 -18
- package/src/plugin.test.ts +2 -0
- package/src/plugin.ts +57 -6
- package/src/serializer.ts +11 -2
- package/src/spec/builtins.ts +56 -0
- package/src/spec/fetch.ts +332 -0
- package/src/spec/otel-schemas.snapshot.json +13932 -0
- package/src/spec/parse.ts +364 -0
- package/src/spec/pin.ts +155 -0
- package/src/spec/snapshot-cli.ts +32 -0
- package/src/spec/snapshot.ts +19 -0
- package/src/spec/spec.test.ts +144 -0
- package/src/validate-config.ts +4 -3
- package/src/validate.ts +1 -0
- package/src/workspace-links.e2e.test.ts +91 -0
- package/src/workspace-links.ts +50 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The upstream collector schemas, read at the pinned tags (#3361).
|
|
3
|
+
*
|
|
4
|
+
* Three repositories, all read at git tags:
|
|
5
|
+
*
|
|
6
|
+
* - opentelemetry-collector-releases, for each distribution's builder manifest
|
|
7
|
+
* (`distributions/<name>/manifest.yaml`): which component modules a given
|
|
8
|
+
* `otelcol` binary is built from, and at which version;
|
|
9
|
+
* - opentelemetry-collector (`go.opentelemetry.io/collector/...`) and
|
|
10
|
+
* opentelemetry-collector-contrib, for each component's `metadata.yaml` (its
|
|
11
|
+
* collector type, and the deprecated type it still answers to) and its
|
|
12
|
+
* `config.schema.yaml`, plus every schema document those reach through
|
|
13
|
+
* `$ref` (the shared `config/*` packages, `exporterhelper`, contrib's
|
|
14
|
+
* `internal/*` and `pkg/*`).
|
|
15
|
+
*
|
|
16
|
+
* Downloads go through core's `fetchWithCache` under `~/.chant/otel-spec/<tag>`,
|
|
17
|
+
* with a long TTL, because a tag's content never moves. This module only runs
|
|
18
|
+
* when the snapshot is refreshed (`just snapshot`); generation reads the
|
|
19
|
+
* committed snapshot and never touches the network.
|
|
20
|
+
*
|
|
21
|
+
* ## `$ref` forms
|
|
22
|
+
*
|
|
23
|
+
* `schemagen` writes four:
|
|
24
|
+
*
|
|
25
|
+
* - `name`, a definition in the same document's `$defs`;
|
|
26
|
+
* - `./internal/metadata.name`, a package below the referring document's;
|
|
27
|
+
* - `/config/configgrpc.client_config`, a package path from the root of the
|
|
28
|
+
* referring document's repository;
|
|
29
|
+
* - `go.opentelemetry.io/collector/config/configopaque.string`, a full Go
|
|
30
|
+
* import path.
|
|
31
|
+
*
|
|
32
|
+
* Every form ends in `.<definition>`; {@link resolveRef} turns each into a
|
|
33
|
+
* document key (the Go import path of the package) and a definition name.
|
|
34
|
+
*/
|
|
35
|
+
import type { ComponentKind } from "../model.js";
|
|
36
|
+
export declare const CORE_MODULE = "go.opentelemetry.io/collector";
|
|
37
|
+
export declare const CONTRIB_MODULE = "github.com/open-telemetry/opentelemetry-collector-contrib";
|
|
38
|
+
/** The distributions whose manifests scope the lexicon. */
|
|
39
|
+
export declare const DISTRIBUTIONS: readonly ["otelcol-contrib", "otelcol-k8s"];
|
|
40
|
+
export type DistributionName = (typeof DISTRIBUTIONS)[number];
|
|
41
|
+
/** One component module a distribution is built from. */
|
|
42
|
+
export interface ManifestModule {
|
|
43
|
+
kind: ComponentKind;
|
|
44
|
+
/** The Go module path, e.g. `go.opentelemetry.io/collector/receiver/otlpreceiver`. */
|
|
45
|
+
module: string;
|
|
46
|
+
/** The module version the manifest names, e.g. `v0.162.0`. */
|
|
47
|
+
version: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The component modules a builder manifest lists. `providers` (confmap URI
|
|
51
|
+
* schemes) are not components and are left out.
|
|
52
|
+
*/
|
|
53
|
+
export declare function parseManifest(text: string): ManifestModule[];
|
|
54
|
+
/** The repository and tag a module's files are read from, or undefined for a module outside the two collector repos. */
|
|
55
|
+
export declare function locate(pkg: string, tags: {
|
|
56
|
+
core: string;
|
|
57
|
+
contrib: string;
|
|
58
|
+
}): {
|
|
59
|
+
repo: string;
|
|
60
|
+
tag: string;
|
|
61
|
+
path: string;
|
|
62
|
+
root: string;
|
|
63
|
+
} | undefined;
|
|
64
|
+
/** The repository root module a package belongs to, for resolving `/path` refs. */
|
|
65
|
+
export declare function repoRoot(pkg: string): string | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* Resolve a `$ref` written in document `from` (a Go package path) to the
|
|
68
|
+
* document it names and the definition inside it. A local ref returns `from`
|
|
69
|
+
* itself.
|
|
70
|
+
*/
|
|
71
|
+
export declare function resolveRef(from: string, ref: string): {
|
|
72
|
+
doc: string;
|
|
73
|
+
def: string;
|
|
74
|
+
};
|
|
75
|
+
/** Every `$ref` string inside a schema document, in order. */
|
|
76
|
+
export declare function refsIn(node: unknown, out?: string[]): string[];
|
|
77
|
+
/** One component in a distribution's index. */
|
|
78
|
+
export interface IndexedComponent {
|
|
79
|
+
kind: ComponentKind;
|
|
80
|
+
/** The collector type its factory registers, from `metadata.yaml`. Absent for a module outside the collector repos. */
|
|
81
|
+
type?: string;
|
|
82
|
+
/** The older type the factory still accepts, when it was renamed. */
|
|
83
|
+
deprecatedType?: string;
|
|
84
|
+
module: string;
|
|
85
|
+
version: string;
|
|
86
|
+
/** The document key of its config schema, when upstream ships one. */
|
|
87
|
+
schema?: string;
|
|
88
|
+
}
|
|
89
|
+
/** What `fetchUpstreamSpec` returns, and what the committed snapshot holds. */
|
|
90
|
+
export interface OtelSpecSnapshot {
|
|
91
|
+
versions: {
|
|
92
|
+
"otelcol-contrib": string;
|
|
93
|
+
"otelcol-k8s": string;
|
|
94
|
+
core: string;
|
|
95
|
+
contrib: string;
|
|
96
|
+
};
|
|
97
|
+
distributions: Record<DistributionName, IndexedComponent[]>;
|
|
98
|
+
/** Schema documents keyed by Go package path. */
|
|
99
|
+
schemas: Record<string, unknown>;
|
|
100
|
+
/** `$ref`ed documents that could not be read, and who asked for them. */
|
|
101
|
+
unresolved: Record<string, string[]>;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Fetch both manifests at their tags, index every component they list, and
|
|
105
|
+
* collect the schema documents reachable from the components in `keep` (by
|
|
106
|
+
* collector type and kind). Other components are indexed (type, schema or
|
|
107
|
+
* not) but their schemas are not carried, so the snapshot stays the size of
|
|
108
|
+
* what the lexicon generates from.
|
|
109
|
+
*/
|
|
110
|
+
export declare function fetchUpstreamSpec(options: {
|
|
111
|
+
contribVersion: string;
|
|
112
|
+
k8sVersion: string;
|
|
113
|
+
keep: ReadonlyArray<{
|
|
114
|
+
kind: ComponentKind;
|
|
115
|
+
type: string;
|
|
116
|
+
}>;
|
|
117
|
+
force?: boolean;
|
|
118
|
+
log?: (message: string) => void;
|
|
119
|
+
}): Promise<OtelSpecSnapshot>;
|
|
120
|
+
//# sourceMappingURL=fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/spec/fetch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,eAAO,MAAM,WAAW,kCAAkC,CAAC;AAC3D,eAAO,MAAM,cAAc,8DAA8D,CAAC;AAO1F,2DAA2D;AAC3D,eAAO,MAAM,aAAa,YAAI,iBAAiB,EAAE,aAAa,CAAU,CAAC;AACzE,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAe9D,yDAAyD;AACzD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,aAAa,CAAC;IACpB,sFAAsF;IACtF,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;CACjB;AAUD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,EAAE,CAY5D;AAID,wHAAwH;AACxH,wBAAgB,MAAM,CACpB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAOvE;AAED,mFAAmF;AACnF,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAExD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAYlF;AAED,8DAA8D;AAC9D,wBAAgB,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,GAAE,MAAM,EAAO,GAAG,MAAM,EAAE,CAUlE;AAmBD,+CAA+C;AAC/C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,aAAa,CAAC;IACpB,uHAAuH;IACvH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,+EAA+E;AAC/E,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE;QAAE,iBAAiB,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9F,aAAa,EAAE,MAAM,CAAC,gBAAgB,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAC5D,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,yEAAyE;IACzE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACtC;AAyBD;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE;IAC/C,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,aAAa,CAAC;QAAE,IAAI,EAAE,aAAa,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3D,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAsG5B"}
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The upstream collector schemas, read at the pinned tags (#3361).
|
|
3
|
+
*
|
|
4
|
+
* Three repositories, all read at git tags:
|
|
5
|
+
*
|
|
6
|
+
* - opentelemetry-collector-releases, for each distribution's builder manifest
|
|
7
|
+
* (`distributions/<name>/manifest.yaml`): which component modules a given
|
|
8
|
+
* `otelcol` binary is built from, and at which version;
|
|
9
|
+
* - opentelemetry-collector (`go.opentelemetry.io/collector/...`) and
|
|
10
|
+
* opentelemetry-collector-contrib, for each component's `metadata.yaml` (its
|
|
11
|
+
* collector type, and the deprecated type it still answers to) and its
|
|
12
|
+
* `config.schema.yaml`, plus every schema document those reach through
|
|
13
|
+
* `$ref` (the shared `config/*` packages, `exporterhelper`, contrib's
|
|
14
|
+
* `internal/*` and `pkg/*`).
|
|
15
|
+
*
|
|
16
|
+
* Downloads go through core's `fetchWithCache` under `~/.chant/otel-spec/<tag>`,
|
|
17
|
+
* with a long TTL, because a tag's content never moves. This module only runs
|
|
18
|
+
* when the snapshot is refreshed (`just snapshot`); generation reads the
|
|
19
|
+
* committed snapshot and never touches the network.
|
|
20
|
+
*
|
|
21
|
+
* ## `$ref` forms
|
|
22
|
+
*
|
|
23
|
+
* `schemagen` writes four:
|
|
24
|
+
*
|
|
25
|
+
* - `name`, a definition in the same document's `$defs`;
|
|
26
|
+
* - `./internal/metadata.name`, a package below the referring document's;
|
|
27
|
+
* - `/config/configgrpc.client_config`, a package path from the root of the
|
|
28
|
+
* referring document's repository;
|
|
29
|
+
* - `go.opentelemetry.io/collector/config/configopaque.string`, a full Go
|
|
30
|
+
* import path.
|
|
31
|
+
*
|
|
32
|
+
* Every form ends in `.<definition>`; {@link resolveRef} turns each into a
|
|
33
|
+
* document key (the Go import path of the package) and a definition name.
|
|
34
|
+
*/
|
|
35
|
+
import { homedir } from "os";
|
|
36
|
+
import { join } from "path";
|
|
37
|
+
import yaml from "js-yaml";
|
|
38
|
+
import { fetchWithCache } from "@intentius/chant/codegen/fetch";
|
|
39
|
+
export const CORE_MODULE = "go.opentelemetry.io/collector";
|
|
40
|
+
export const CONTRIB_MODULE = "github.com/open-telemetry/opentelemetry-collector-contrib";
|
|
41
|
+
const REPOS = [
|
|
42
|
+
{ module: CONTRIB_MODULE, repo: "open-telemetry/opentelemetry-collector-contrib" },
|
|
43
|
+
{ module: CORE_MODULE, repo: "open-telemetry/opentelemetry-collector" },
|
|
44
|
+
];
|
|
45
|
+
/** The distributions whose manifests scope the lexicon. */
|
|
46
|
+
export const DISTRIBUTIONS = ["otelcol-contrib", "otelcol-k8s"];
|
|
47
|
+
/** A tag's content never moves, so a cached copy stays good for a year. */
|
|
48
|
+
const TAG_TTL_MS = 365 * 24 * 60 * 60 * 1000;
|
|
49
|
+
function cacheFile(repo, tag, path) {
|
|
50
|
+
return join(homedir(), ".chant", "otel-spec", repo.split("/")[1], tag, ...path.split("/"));
|
|
51
|
+
}
|
|
52
|
+
function rawUrl(repo, tag, path) {
|
|
53
|
+
return `https://raw.githubusercontent.com/${repo}/${tag}/${path}`;
|
|
54
|
+
}
|
|
55
|
+
const SECTION_KIND = {
|
|
56
|
+
receivers: "receiver",
|
|
57
|
+
processors: "processor",
|
|
58
|
+
exporters: "exporter",
|
|
59
|
+
connectors: "connector",
|
|
60
|
+
extensions: "extension",
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* The component modules a builder manifest lists. `providers` (confmap URI
|
|
64
|
+
* schemes) are not components and are left out.
|
|
65
|
+
*/
|
|
66
|
+
export function parseManifest(text) {
|
|
67
|
+
const doc = yaml.load(text);
|
|
68
|
+
const out = [];
|
|
69
|
+
for (const [section, kind] of Object.entries(SECTION_KIND)) {
|
|
70
|
+
const entries = doc[section];
|
|
71
|
+
if (!Array.isArray(entries))
|
|
72
|
+
continue;
|
|
73
|
+
for (const entry of entries) {
|
|
74
|
+
const [module, version] = (entry.gomod ?? "").trim().split(/\s+/);
|
|
75
|
+
if (module && version)
|
|
76
|
+
out.push({ kind, module, version });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return out;
|
|
80
|
+
}
|
|
81
|
+
// ── Where a Go package lives ────────────────────────────────────────
|
|
82
|
+
/** The repository and tag a module's files are read from, or undefined for a module outside the two collector repos. */
|
|
83
|
+
export function locate(pkg, tags) {
|
|
84
|
+
for (const { module, repo } of REPOS) {
|
|
85
|
+
if (pkg === module || pkg.startsWith(`${module}/`)) {
|
|
86
|
+
return { repo, tag: module === CORE_MODULE ? tags.core : tags.contrib, path: pkg.slice(module.length + 1), root: module };
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
/** The repository root module a package belongs to, for resolving `/path` refs. */
|
|
92
|
+
export function repoRoot(pkg) {
|
|
93
|
+
return REPOS.find(({ module }) => pkg === module || pkg.startsWith(`${module}/`))?.module;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Resolve a `$ref` written in document `from` (a Go package path) to the
|
|
97
|
+
* document it names and the definition inside it. A local ref returns `from`
|
|
98
|
+
* itself.
|
|
99
|
+
*/
|
|
100
|
+
export function resolveRef(from, ref) {
|
|
101
|
+
const dot = ref.lastIndexOf(".");
|
|
102
|
+
const slash = ref.lastIndexOf("/");
|
|
103
|
+
// `name`: no package part.
|
|
104
|
+
if (slash < 0 && !ref.startsWith("."))
|
|
105
|
+
return { doc: from, def: ref };
|
|
106
|
+
const pkgPart = dot > slash ? ref.slice(0, dot) : ref;
|
|
107
|
+
const def = dot > slash ? ref.slice(dot + 1) : "";
|
|
108
|
+
let doc;
|
|
109
|
+
if (pkgPart.startsWith("./"))
|
|
110
|
+
doc = `${from}/${pkgPart.slice(2)}`;
|
|
111
|
+
else if (pkgPart.startsWith("/"))
|
|
112
|
+
doc = `${repoRoot(from) ?? ""}${pkgPart}`;
|
|
113
|
+
else
|
|
114
|
+
doc = pkgPart;
|
|
115
|
+
return { doc, def };
|
|
116
|
+
}
|
|
117
|
+
/** Every `$ref` string inside a schema document, in order. */
|
|
118
|
+
export function refsIn(node, out = []) {
|
|
119
|
+
if (Array.isArray(node)) {
|
|
120
|
+
for (const n of node)
|
|
121
|
+
refsIn(n, out);
|
|
122
|
+
}
|
|
123
|
+
else if (node !== null && typeof node === "object") {
|
|
124
|
+
for (const [k, v] of Object.entries(node)) {
|
|
125
|
+
if (k === "$ref" && typeof v === "string")
|
|
126
|
+
out.push(v);
|
|
127
|
+
else
|
|
128
|
+
refsIn(v, out);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return out;
|
|
132
|
+
}
|
|
133
|
+
// ── Fetching ────────────────────────────────────────────────────────
|
|
134
|
+
async function fetchText(repo, tag, path, force) {
|
|
135
|
+
try {
|
|
136
|
+
const buf = await fetchWithCache({ url: rawUrl(repo, tag, path), cacheFile: cacheFile(repo, tag, path), cacheTtlMs: TAG_TTL_MS }, force);
|
|
137
|
+
return buf.toString("utf-8");
|
|
138
|
+
}
|
|
139
|
+
catch (err) {
|
|
140
|
+
// A missing file is an answer (this component ships no schema); anything
|
|
141
|
+
// else is not, and must not be read as one.
|
|
142
|
+
if (err instanceof Error && /returned 404\b/.test(err.message))
|
|
143
|
+
return undefined;
|
|
144
|
+
throw err;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
async function pool(items, size, fn) {
|
|
148
|
+
const out = new Array(items.length);
|
|
149
|
+
let next = 0;
|
|
150
|
+
await Promise.all(Array.from({ length: Math.min(size, items.length) }, async () => {
|
|
151
|
+
while (next < items.length) {
|
|
152
|
+
const i = next++;
|
|
153
|
+
out[i] = await fn(items[i]);
|
|
154
|
+
}
|
|
155
|
+
}));
|
|
156
|
+
return out;
|
|
157
|
+
}
|
|
158
|
+
/** The version a manifest uses for the modules of one repository, the most common one listed. */
|
|
159
|
+
function repoTag(modules, root) {
|
|
160
|
+
const counts = new Map();
|
|
161
|
+
for (const m of modules)
|
|
162
|
+
if (m.module.startsWith(`${root}/`))
|
|
163
|
+
counts.set(m.version, (counts.get(m.version) ?? 0) + 1);
|
|
164
|
+
const best = [...counts].sort((a, b) => b[1] - a[1])[0];
|
|
165
|
+
if (!best)
|
|
166
|
+
throw new Error(`no ${root} module in the manifest`);
|
|
167
|
+
return best[0];
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Fetch both manifests at their tags, index every component they list, and
|
|
171
|
+
* collect the schema documents reachable from the components in `keep` (by
|
|
172
|
+
* collector type and kind). Other components are indexed (type, schema or
|
|
173
|
+
* not) but their schemas are not carried, so the snapshot stays the size of
|
|
174
|
+
* what the lexicon generates from.
|
|
175
|
+
*/
|
|
176
|
+
export async function fetchUpstreamSpec(options) {
|
|
177
|
+
const log = options.log ?? (() => { });
|
|
178
|
+
const releases = "open-telemetry/opentelemetry-collector-releases";
|
|
179
|
+
const manifests = {};
|
|
180
|
+
const distTags = { "otelcol-contrib": options.contribVersion, "otelcol-k8s": options.k8sVersion };
|
|
181
|
+
for (const dist of DISTRIBUTIONS) {
|
|
182
|
+
const text = await fetchText(releases, distTags[dist], `distributions/${dist}/manifest.yaml`, options.force);
|
|
183
|
+
if (text === undefined)
|
|
184
|
+
throw new Error(`no manifest for ${dist} at ${distTags[dist]}`);
|
|
185
|
+
manifests[dist] = parseManifest(text);
|
|
186
|
+
log(`${dist} ${distTags[dist]}: ${manifests[dist].length} components`);
|
|
187
|
+
}
|
|
188
|
+
const contribManifest = manifests["otelcol-contrib"];
|
|
189
|
+
const tags = { core: repoTag(contribManifest, CORE_MODULE), contrib: repoTag(contribManifest, CONTRIB_MODULE) };
|
|
190
|
+
// Index each distinct module once: its type, and where its schema is.
|
|
191
|
+
const modules = new Map();
|
|
192
|
+
for (const dist of DISTRIBUTIONS)
|
|
193
|
+
for (const m of manifests[dist])
|
|
194
|
+
modules.set(m.module, m);
|
|
195
|
+
const docs = new Map();
|
|
196
|
+
const info = new Map();
|
|
197
|
+
await pool([...modules.values()], 16, async (m) => {
|
|
198
|
+
const where = locate(m.module, tags);
|
|
199
|
+
if (!where) {
|
|
200
|
+
info.set(m.module, {});
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
const meta = await fetchText(where.repo, where.tag, `${where.path}/metadata.yaml`, options.force);
|
|
204
|
+
const parsed = meta ? yaml.load(meta) : {};
|
|
205
|
+
// Most components keep their config in the module root; a few
|
|
206
|
+
// (signaltometrics) in a `config` package below it.
|
|
207
|
+
let schemaDoc;
|
|
208
|
+
let schema;
|
|
209
|
+
for (const sub of ["", "/config"]) {
|
|
210
|
+
const text = await fetchText(where.repo, where.tag, `${where.path}${sub}/config.schema.yaml`, options.force);
|
|
211
|
+
if (text !== undefined) {
|
|
212
|
+
schemaDoc = `${m.module}${sub}`;
|
|
213
|
+
schema = yaml.load(text);
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
info.set(m.module, { type: parsed.type, deprecatedType: parsed.deprecated_type, schemaDoc, schema });
|
|
218
|
+
});
|
|
219
|
+
const distributions = {};
|
|
220
|
+
for (const dist of DISTRIBUTIONS) {
|
|
221
|
+
distributions[dist] = manifests[dist]
|
|
222
|
+
.map((m) => {
|
|
223
|
+
const i = info.get(m.module);
|
|
224
|
+
const entry = { kind: m.kind, module: m.module, version: m.version };
|
|
225
|
+
if (i.type)
|
|
226
|
+
entry.type = i.type;
|
|
227
|
+
if (i.deprecatedType)
|
|
228
|
+
entry.deprecatedType = i.deprecatedType;
|
|
229
|
+
if (i.schemaDoc)
|
|
230
|
+
entry.schema = i.schemaDoc;
|
|
231
|
+
return entry;
|
|
232
|
+
})
|
|
233
|
+
.sort((a, b) => a.kind.localeCompare(b.kind) || (a.type ?? a.module).localeCompare(b.type ?? b.module));
|
|
234
|
+
}
|
|
235
|
+
// The documents the kept components reach, transitively.
|
|
236
|
+
const unresolved = {};
|
|
237
|
+
const queue = [];
|
|
238
|
+
for (const want of options.keep) {
|
|
239
|
+
const hit = distributions["otelcol-contrib"].find((c) => c.kind === want.kind && (c.type === want.type || c.deprecatedType === want.type));
|
|
240
|
+
if (!hit?.schema)
|
|
241
|
+
continue;
|
|
242
|
+
docs.set(hit.schema, info.get(hit.module).schema);
|
|
243
|
+
queue.push(hit.schema);
|
|
244
|
+
}
|
|
245
|
+
const seen = new Set();
|
|
246
|
+
while (queue.length > 0) {
|
|
247
|
+
const batch = queue.splice(0).filter((d) => !seen.has(d));
|
|
248
|
+
for (const d of batch)
|
|
249
|
+
seen.add(d);
|
|
250
|
+
const wanted = new Map();
|
|
251
|
+
for (const d of batch) {
|
|
252
|
+
for (const ref of refsIn(docs.get(d))) {
|
|
253
|
+
const { doc } = resolveRef(d, ref);
|
|
254
|
+
if (doc === d || docs.has(doc) || seen.has(doc))
|
|
255
|
+
continue;
|
|
256
|
+
wanted.set(doc, [...(wanted.get(doc) ?? []), d]);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
await pool([...wanted.keys()], 16, async (doc) => {
|
|
260
|
+
const where = locate(doc, tags);
|
|
261
|
+
const text = where ? await fetchText(where.repo, where.tag, `${where.path}/config.schema.yaml`, options.force) : undefined;
|
|
262
|
+
if (text === undefined) {
|
|
263
|
+
unresolved[doc] = [...new Set(wanted.get(doc))].sort();
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
docs.set(doc, yaml.load(text));
|
|
267
|
+
queue.push(doc);
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
const schemas = {};
|
|
271
|
+
for (const key of [...docs.keys()].sort())
|
|
272
|
+
schemas[key] = docs.get(key);
|
|
273
|
+
const sortedUnresolved = {};
|
|
274
|
+
for (const key of Object.keys(unresolved).sort())
|
|
275
|
+
sortedUnresolved[key] = unresolved[key];
|
|
276
|
+
return {
|
|
277
|
+
versions: { "otelcol-contrib": options.contribVersion, "otelcol-k8s": options.k8sVersion, ...tags },
|
|
278
|
+
distributions,
|
|
279
|
+
schemas,
|
|
280
|
+
unresolved: sortedUnresolved,
|
|
281
|
+
};
|
|
282
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `config.schema.yaml` to TypeScript (#3361).
|
|
3
|
+
*
|
|
4
|
+
* `schemagen` writes a small JSON Schema dialect: `type`, `properties`,
|
|
5
|
+
* `items`, `additionalProperties`, `enum`, `allOf` (an embedded struct,
|
|
6
|
+
* `mapstructure:",squash"`), `$ref` and `$defs`, `format: duration`, and three
|
|
7
|
+
* extensions:
|
|
8
|
+
*
|
|
9
|
+
* - `x-customType`, the Go type when the JSON type alone loses it (`int64`,
|
|
10
|
+
* `component.ID`, `time.Duration`, or a type from outside the collector);
|
|
11
|
+
* - `x-optional`, a `configoptional.Optional`: the key may be written with no
|
|
12
|
+
* value (`grpc:`) to turn the section on with its defaults, so it also takes
|
|
13
|
+
* `null`;
|
|
14
|
+
* - `x-pointer`, a Go pointer, which changes nothing in YAML.
|
|
15
|
+
*
|
|
16
|
+
* It writes no `required`, so every generated property is optional; what a
|
|
17
|
+
* component cannot start without is its definition's `validate` overlay.
|
|
18
|
+
*
|
|
19
|
+
* Every definition reached from a built-in becomes one named type alias,
|
|
20
|
+
* `<document><Definition>`, so recursive definitions (tail_sampling's `and`
|
|
21
|
+
* and `not` policies) are expressible. A `$ref` to a document upstream does
|
|
22
|
+
* not publish, or to a definition it lacks, becomes `unknown` and is listed in
|
|
23
|
+
* {@link GeneratedTypes.unresolved}.
|
|
24
|
+
*/
|
|
25
|
+
/** One node of a schema document. */
|
|
26
|
+
export interface SchemaNode {
|
|
27
|
+
type?: string | string[];
|
|
28
|
+
description?: string;
|
|
29
|
+
format?: string;
|
|
30
|
+
enum?: unknown[];
|
|
31
|
+
pattern?: string;
|
|
32
|
+
default?: unknown;
|
|
33
|
+
properties?: Record<string, SchemaNode>;
|
|
34
|
+
additionalProperties?: SchemaNode | boolean;
|
|
35
|
+
items?: SchemaNode;
|
|
36
|
+
allOf?: SchemaNode[];
|
|
37
|
+
$ref?: string;
|
|
38
|
+
$defs?: Record<string, SchemaNode>;
|
|
39
|
+
"x-customType"?: string;
|
|
40
|
+
"x-optional"?: boolean;
|
|
41
|
+
"x-pointer"?: boolean;
|
|
42
|
+
}
|
|
43
|
+
/** The TypeScript for one `x-customType`, or undefined when the JSON type should decide. */
|
|
44
|
+
export declare function customType(name: string): string | undefined;
|
|
45
|
+
/** The type-name prefix for a document: its package path below the repository, PascalCased, with `Collector` for core packages. */
|
|
46
|
+
export declare function documentAlias(doc: string): string;
|
|
47
|
+
/** A description that says the field is deprecated, as Go comments do. */
|
|
48
|
+
export declare function isDeprecated(description: string | undefined): boolean;
|
|
49
|
+
export interface GeneratedTypes {
|
|
50
|
+
/** The `type X = …` declarations, in name order. */
|
|
51
|
+
declarations: string;
|
|
52
|
+
/** The type name of each requested root document. */
|
|
53
|
+
roots: Map<string, string>;
|
|
54
|
+
/** `$ref`s that could not be followed, as `doc.def` → the documents that wrote them. */
|
|
55
|
+
unresolved: Map<string, Set<string>>;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Generate TypeScript for the root documents in `roots` and every definition
|
|
59
|
+
* they reach. `docs` holds every available document, keyed by Go package path.
|
|
60
|
+
*/
|
|
61
|
+
export declare function generateTypes(docs: Readonly<Record<string, unknown>>, roots: readonly string[]): GeneratedTypes;
|
|
62
|
+
/** One property as completion and hover show it. */
|
|
63
|
+
export interface PropertyDoc {
|
|
64
|
+
description?: string;
|
|
65
|
+
/** A short type label, e.g. `string`, `duration`, `object`, `boolean[]`. */
|
|
66
|
+
type: string;
|
|
67
|
+
deprecated?: boolean;
|
|
68
|
+
/** For object-valued properties, their own properties. */
|
|
69
|
+
properties?: Record<string, PropertyDoc>;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The property tree of a root document, for completion and hover: each
|
|
73
|
+
* property's description and a short type label, nested objects expanded to
|
|
74
|
+
* `depth` levels, embedded structs (`allOf`) flattened in.
|
|
75
|
+
*/
|
|
76
|
+
export declare function propertyDocs(docs: Readonly<Record<string, unknown>>, root: string, depth?: number): Record<string, PropertyDoc>;
|
|
77
|
+
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/spec/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAIH,qCAAqC;AACrC,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACxC,oBAAoB,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;IAC5C,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AA8CD,4FAA4F;AAC5F,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE3D;AAUD,mIAAmI;AACnI,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIjD;AAiBD,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAGrE;AAaD,MAAM,WAAW,cAAc;IAC7B,oDAAoD;IACpD,YAAY,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B,wFAAwF;IACxF,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;CACtC;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,cAAc,CA8H/G;AAID,oDAAoD;AACpD,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CAC1C;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CA+D1H"}
|