@adalo/metrics 0.1.0

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/.eslintignore ADDED
@@ -0,0 +1,3 @@
1
+ /lib
2
+ /node_modules
3
+ babel.config.js
package/.eslintrc ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "extends": [
3
+ "airbnb-base",
4
+ "airbnb-typescript/base",
5
+ "prettier" // Prettier must always be last as it overrides all other configs (https://github.com/prettier/eslint-config-prettier)
6
+ ],
7
+ "parser": "@typescript-eslint/parser",
8
+ "parserOptions": {
9
+ "project": "./tsconfig.json"
10
+ },
11
+ "plugins": ["@typescript-eslint"],
12
+ "env": {
13
+ "browser": true,
14
+ "commonjs": true,
15
+ "es6": true,
16
+ "node": true
17
+ },
18
+ "settings": {
19
+ "import/resolver": {
20
+ "typescript": {} // this loads <rootdir>/tsconfig.json
21
+ }
22
+ },
23
+ "overrides": [
24
+ {
25
+ "files": ["**/*.test.js"],
26
+ "env": {
27
+ "jest": true
28
+ }
29
+ }
30
+ ],
31
+ "rules": {
32
+ "curly": ["error", "multi-line"],
33
+ "lines-between-class-members": [
34
+ "error",
35
+ "always",
36
+ {
37
+ "exceptAfterSingleLine": true
38
+ }
39
+ ],
40
+ "@typescript-eslint/no-unused-vars": [
41
+ "error",
42
+ {
43
+ "vars": "all",
44
+ "args": "none",
45
+ "ignoreRestSiblings": true
46
+ }
47
+ ],
48
+
49
+ // Disabled rules
50
+ "arrow-body-style": "off",
51
+ "import/prefer-default-export": "off",
52
+ "no-param-reassign": "off",
53
+ "no-restricted-syntax": "off",
54
+ "@typescript-eslint/no-shadow": "off",
55
+ "no-underscore-dangle": "off",
56
+ "class-methods-use-this": "off",
57
+ "no-await-in-loop": "off",
58
+ "no-console": "off"
59
+ }
60
+ }
@@ -0,0 +1,14 @@
1
+ ## Problem
2
+ *Describe the specific bug or product issue that's being fixed.*
3
+
4
+ ## Solution
5
+ *What did you do to fix it? Remember gif's or video of frontend fixes.*
6
+
7
+ ## Additional Notes (optional)
8
+
9
+ - Link to Tech Spec in Notion
10
+
11
+
12
+ ## Related PR's (optional)
13
+
14
+ ## New Packages, Environment Variables (optional)
@@ -0,0 +1,29 @@
1
+ name: Check Prettier and ESLint conformance
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches:
7
+ - main
8
+
9
+ jobs:
10
+ prettier:
11
+ runs-on: ubuntu-latest
12
+
13
+ steps:
14
+ - name: Check out repo
15
+ uses: actions/checkout@v3
16
+
17
+ - name: Setup Node.js
18
+ uses: actions/setup-node@v3
19
+ with:
20
+ node-version: '18.x'
21
+
22
+ - name: Installing dependencies
23
+ run: yarn install --frozen-lockfile
24
+
25
+ - name: Run Prettier checks
26
+ run: yarn prettier:check
27
+
28
+ - name: Run ESLint checks
29
+ run: yarn lint:check
@@ -0,0 +1,29 @@
1
+ name: Deploy Production
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ jobs:
9
+ build:
10
+ if: "!contains(github.event.head_commit.message, 'skip ci')"
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v3
14
+ with:
15
+ fetch-depth: 0 # Fetch all commits across all branches. Default behaviour is efficient but breaks merge-release.
16
+ - name: Setup Node.js
17
+ uses: actions/setup-node@v3
18
+ with:
19
+ node-version: '18.x'
20
+ registry-url: 'https://registry.npmjs.org'
21
+ - name: Installing dependencies
22
+ run: yarn install --frozen-lockfile
23
+ - name: Build lib
24
+ run: yarn run build
25
+ - name: Publish to NPM
26
+ uses: AdaloHQ/npm-publish@v1
27
+ env:
28
+ GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
29
+ NODE_AUTH_TOKEN: ${{secrets.NPM_AUTH_TOKEN}}
@@ -0,0 +1,17 @@
1
+ name: CI
2
+
3
+ on: pull_request
4
+
5
+ jobs:
6
+ test:
7
+ runs-on: ubuntu-latest
8
+ steps:
9
+ - uses: actions/checkout@v3
10
+ - name: Setup Node.js
11
+ uses: actions/setup-node@v3
12
+ with:
13
+ node-version: '18.x'
14
+ - name: Installing dependencies
15
+ run: yarn install --frozen-lockfile
16
+ - name: Running tests
17
+ run: yarn test
@@ -0,0 +1,91 @@
1
+ <component name="ProjectCodeStyleConfiguration">
2
+ <code_scheme name="Project" version="173">
3
+ <option name="OTHER_INDENT_OPTIONS">
4
+ <value>
5
+ <option name="INDENT_SIZE" value="2" />
6
+ <option name="TAB_SIZE" value="2" />
7
+ </value>
8
+ </option>
9
+ <HTMLCodeStyleSettings>
10
+ <option name="HTML_SPACE_INSIDE_EMPTY_TAG" value="true" />
11
+ </HTMLCodeStyleSettings>
12
+ <JSCodeStyleSettings version="0">
13
+ <option name="USE_SEMICOLON_AFTER_STATEMENT" value="false" />
14
+ <option name="FORCE_SEMICOLON_STYLE" value="true" />
15
+ <option name="SPACE_WITHIN_ARRAY_INITIALIZER_BRACKETS" value="true" />
16
+ <option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
17
+ <option name="USE_DOUBLE_QUOTES" value="false" />
18
+ <option name="FORCE_QUOTE_STYlE" value="true" />
19
+ <option name="ENFORCE_TRAILING_COMMA" value="WhenMultiline" />
20
+ <option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
21
+ <option name="SPACES_WITHIN_IMPORTS" value="true" />
22
+ <option name="SPACES_WITHIN_INTERPOLATION_EXPRESSIONS" value="true" />
23
+ </JSCodeStyleSettings>
24
+ <TypeScriptCodeStyleSettings version="0">
25
+ <option name="USE_SEMICOLON_AFTER_STATEMENT" value="false" />
26
+ <option name="FORCE_SEMICOLON_STYLE" value="true" />
27
+ <option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
28
+ <option name="USE_DOUBLE_QUOTES" value="false" />
29
+ <option name="FORCE_QUOTE_STYlE" value="true" />
30
+ <option name="ENFORCE_TRAILING_COMMA" value="WhenMultiline" />
31
+ <option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
32
+ <option name="SPACES_WITHIN_IMPORTS" value="true" />
33
+ </TypeScriptCodeStyleSettings>
34
+ <VueCodeStyleSettings>
35
+ <option name="INTERPOLATION_NEW_LINE_AFTER_START_DELIMITER" value="false" />
36
+ <option name="INTERPOLATION_NEW_LINE_BEFORE_END_DELIMITER" value="false" />
37
+ </VueCodeStyleSettings>
38
+ <codeStyleSettings language="CSS">
39
+ <indentOptions>
40
+ <option name="INDENT_SIZE" value="2" />
41
+ <option name="CONTINUATION_INDENT_SIZE" value="4" />
42
+ <option name="TAB_SIZE" value="2" />
43
+ </indentOptions>
44
+ </codeStyleSettings>
45
+ <codeStyleSettings language="Gherkin">
46
+ <indentOptions>
47
+ <option name="TAB_SIZE" value="2" />
48
+ </indentOptions>
49
+ </codeStyleSettings>
50
+ <codeStyleSettings language="HTML">
51
+ <option name="SOFT_MARGINS" value="80" />
52
+ <indentOptions>
53
+ <option name="INDENT_SIZE" value="2" />
54
+ <option name="CONTINUATION_INDENT_SIZE" value="2" />
55
+ <option name="TAB_SIZE" value="2" />
56
+ </indentOptions>
57
+ </codeStyleSettings>
58
+ <codeStyleSettings language="JSON">
59
+ <indentOptions>
60
+ <option name="CONTINUATION_INDENT_SIZE" value="4" />
61
+ </indentOptions>
62
+ </codeStyleSettings>
63
+ <codeStyleSettings language="JavaScript">
64
+ <option name="SOFT_MARGINS" value="80" />
65
+ <indentOptions>
66
+ <option name="INDENT_SIZE" value="2" />
67
+ <option name="CONTINUATION_INDENT_SIZE" value="2" />
68
+ <option name="TAB_SIZE" value="2" />
69
+ </indentOptions>
70
+ </codeStyleSettings>
71
+ <codeStyleSettings language="LESS">
72
+ <indentOptions>
73
+ <option name="TAB_SIZE" value="2" />
74
+ </indentOptions>
75
+ </codeStyleSettings>
76
+ <codeStyleSettings language="TypeScript">
77
+ <option name="SOFT_MARGINS" value="80" />
78
+ <indentOptions>
79
+ <option name="INDENT_SIZE" value="2" />
80
+ <option name="CONTINUATION_INDENT_SIZE" value="2" />
81
+ <option name="TAB_SIZE" value="2" />
82
+ </indentOptions>
83
+ </codeStyleSettings>
84
+ <codeStyleSettings language="Vue">
85
+ <option name="SOFT_MARGINS" value="80" />
86
+ <indentOptions>
87
+ <option name="CONTINUATION_INDENT_SIZE" value="2" />
88
+ </indentOptions>
89
+ </codeStyleSettings>
90
+ </code_scheme>
91
+ </component>
@@ -0,0 +1,5 @@
1
+ <component name="ProjectCodeStyleConfiguration">
2
+ <state>
3
+ <option name="USE_PER_PROJECT_SETTINGS" value="true" />
4
+ </state>
5
+ </component>
@@ -0,0 +1,15 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="GitToolBoxProjectSettings">
4
+ <option name="commitMessageIssueKeyValidationOverride">
5
+ <BoolValueOverride>
6
+ <option name="enabled" value="true" />
7
+ </BoolValueOverride>
8
+ </option>
9
+ <option name="commitMessageValidationEnabledOverride">
10
+ <BoolValueOverride>
11
+ <option name="enabled" value="true" />
12
+ </BoolValueOverride>
13
+ </option>
14
+ </component>
15
+ </project>
@@ -0,0 +1,6 @@
1
+ <component name="InspectionProjectProfileManager">
2
+ <profile version="1.0">
3
+ <option name="myName" value="Project Default" />
4
+ <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
5
+ </profile>
6
+ </component>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="JavaScriptLibraryMappings">
4
+ <includedPredefinedLibrary name="Node.js Core" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="WEB_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$">
5
+ <excludeFolder url="file://$MODULE_DIR$/.tmp" />
6
+ <excludeFolder url="file://$MODULE_DIR$/temp" />
7
+ <excludeFolder url="file://$MODULE_DIR$/tmp" />
8
+ </content>
9
+ <orderEntry type="inheritedJdk" />
10
+ <orderEntry type="sourceFolder" forTests="false" />
11
+ </component>
12
+ </module>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/utils.iml" filepath="$PROJECT_DIR$/.idea/utils.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="PrettierConfiguration">
4
+ <option name="myConfigurationMode" value="AUTOMATIC" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="WEB_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$">
5
+ <excludeFolder url="file://$MODULE_DIR$/.tmp" />
6
+ <excludeFolder url="file://$MODULE_DIR$/temp" />
7
+ <excludeFolder url="file://$MODULE_DIR$/tmp" />
8
+ </content>
9
+ <orderEntry type="inheritedJdk" />
10
+ <orderEntry type="sourceFolder" forTests="false" />
11
+ </component>
12
+ </module>
package/.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="" vcs="Git" />
5
+ </component>
6
+ </project>
package/.prettierrc ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "printWidth": 80,
3
+ "tabWidth": 2,
4
+ "singleQuote": true,
5
+ "trailingComma": "es5",
6
+ "semi": false,
7
+ "bracketSpacing": true,
8
+ "bracketSameLine": false,
9
+ "arrowParens": "avoid"
10
+ }
package/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # @adalo/metrics-js
2
+ Utility library for Prometheus metrics and HTTP request counting in Node.js applications.
3
+
4
+ ## Constructor
5
+ ```ts
6
+ new MetricsClient({
7
+ appName, // defaults: process.env.METRICS_APP_NAME || 'unknown-app'
8
+ dynoId, // defaults: process.env.HOSTNAME || 'unknown-dyno'
9
+ processType, // defaults: process.env.BUILD_DYNO_PROCESS_TYPE || 'undefined_build_dyno_type'
10
+ enabled, // defaults: process.env.METRICS_ENABLED === 'true'
11
+ logValues, // defaults: process.env.METRICS_LOG_VALUES === 'true'
12
+ pushgatewayUrl, // defaults: process.env.METRICS_PUSHGATEWAY_URL || ''
13
+ pushgatewayUser, // defaults: process.env.METRICS_PUSHGATEWAY_USER || ''
14
+ pushgatewayPassword,// defaults: process.env.METRICS_PUSHGATEWAY_PASSWORD || ''
15
+ intervalSec // defaults: process.env.METRICS_INTERVAL_SEC || 15
16
+ })
17
+ ```
18
+ ## Example Usage
19
+ ```ts
20
+ import { MetricsClient } from '@adalo/metrics-js'
21
+
22
+ const metrics = new MetricsClient({ appName: 'my-app', enabled: true })
23
+
24
+ // Express middleware
25
+ app.use(metrics.countHttpRequestMiddleware)
26
+
27
+
28
+ // Start metrics push
29
+ metrics.startPush()
@@ -0,0 +1,20 @@
1
+ const include = ['./src']
2
+ const ignore = ['./lib']
3
+
4
+ // This env var is set when running with jest
5
+ if (process.env.NODE_ENV !== 'test') {
6
+ ignore.push('**/*.test.js', '**/*.test.ts', '**/__tests__/*')
7
+ }
8
+
9
+ const presets = [
10
+ [
11
+ '@babel/preset-env',
12
+ {
13
+ targets: { node: '22' },
14
+ useBuiltIns: 'usage',
15
+ },
16
+ ],
17
+ '@babel/preset-typescript',
18
+ ]
19
+
20
+ module.exports = { include, ignore, presets }
package/lib/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './metricsClient';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA"}
package/lib/index.js ADDED
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ var _metricsClient = require("./metricsClient");
7
+ Object.keys(_metricsClient).forEach(function (key) {
8
+ if (key === "default" || key === "__esModule") return;
9
+ if (key in exports && exports[key] === _metricsClient[key]) return;
10
+ Object.defineProperty(exports, key, {
11
+ enumerable: true,
12
+ get: function () {
13
+ return _metricsClient[key];
14
+ }
15
+ });
16
+ });
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["_metricsClient","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get"],"sources":["../src/index.ts"],"sourcesContent":["export * from './metricsClient'\n\n"],"mappings":";;;;;AAAA,IAAAA,cAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,cAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,cAAA,CAAAK,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAT,cAAA,CAAAK,GAAA;IAAA;EAAA;AAAA","ignoreList":[]}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * MetricsClient handles Prometheus metrics collection and push.
3
+ * Supports gauges, counters, default metrics, and custom metrics.
4
+ */
5
+ export class MetricsClient {
6
+ /**
7
+ * @param {Object} config
8
+ * @param {string} [config.appName] Name of the application
9
+ * @param {string} [config.dynoId] Dyno/instance ID
10
+ * @param {string} [config.processType] Process type (web, worker, etc.)
11
+ * @param {boolean} [config.enabled] Enable metrics collection
12
+ * @param {boolean} [config.logValues] Log metrics values to console
13
+ * @param {string} [config.pushgatewayUrl] PushGateway URL
14
+ * @param {string} [config.pushgatewayUser] PushGateway username
15
+ * @param {string} [config.pushgatewayPassword] PushGateway password
16
+ * @param {number} [config.intervalSec] Interval in seconds for pushing metrics
17
+ */
18
+ constructor(config?: {
19
+ appName?: string | undefined;
20
+ dynoId?: string | undefined;
21
+ processType?: string | undefined;
22
+ enabled?: boolean | undefined;
23
+ logValues?: boolean | undefined;
24
+ pushgatewayUrl?: string | undefined;
25
+ pushgatewayUser?: string | undefined;
26
+ pushgatewayPassword?: string | undefined;
27
+ intervalSec?: number | undefined;
28
+ });
29
+ appName: string;
30
+ dynoId: string;
31
+ processType: string;
32
+ enabled: boolean;
33
+ logValues: boolean;
34
+ pushgatewayUrl: string;
35
+ pushgatewayUser: string;
36
+ pushgatewayPassword: string;
37
+ intervalSec: number;
38
+ prefixLogs: string;
39
+ registry: client.Registry<"text/plain; version=0.0.4; charset=utf-8">;
40
+ defaultLabels: {
41
+ app: string;
42
+ dyno_id: string;
43
+ process_type: string;
44
+ };
45
+ gateway: client.Pushgateway<"text/plain; version=0.0.4; charset=utf-8">;
46
+ gauges: {};
47
+ counters: {};
48
+ /** @type {Object<string, function(): number | Promise<number>>} */
49
+ gaugeUpdaters: {
50
+ [x: string]: () => number | Promise<number>;
51
+ };
52
+ /** @type {Object<string, function(data?: object, value?: number): void>} */
53
+ counterUpdaters: any;
54
+ _lastUsageMicros: number;
55
+ _lastCheckTime: number;
56
+ /**
57
+ * Register default gauges and counters.
58
+ * @private
59
+ */
60
+ private _initDefaultMetrics;
61
+ /**
62
+ * Create a gauge metric.
63
+ * @param {string} name
64
+ * @param {string} help
65
+ * @param {function(): number|Promise<number>} [updateFn] Optional function returning value
66
+ * @param {string[]} [labelNames]
67
+ * @returns {client.Gauge}
68
+ */
69
+ createGauge: (name: string, help: string, updateFn?: (() => number | Promise<number>) | undefined, labelNames?: string[] | undefined) => client.Gauge;
70
+ /**
71
+ * Create a counter metric.
72
+ * Returns a trigger function to increment the counter manually.
73
+ * @param {string} name
74
+ * @param {string} help
75
+ * @param {string[]} [labelNames]
76
+ * @returns {function(data?: object, value?: number): void} triggerFn
77
+ */
78
+ createCounter(name: string, help: string, labelNames?: string[] | undefined): (arg0: data | null, arg1: object, arg2: value | null, arg3: number) => void;
79
+ /**
80
+ * Get CPU usage percent (cgroup-aware)
81
+ * @returns {number}
82
+ */
83
+ getCpuUsagePercent: () => number;
84
+ /**
85
+ * Get available CPU cores.
86
+ * @returns {number}
87
+ */
88
+ getAvailableCPUs(): number;
89
+ /**
90
+ * Get container memory usage in bytes.
91
+ * @returns {number}
92
+ */
93
+ getContainerMemoryUsage(): number;
94
+ /**
95
+ * Get container memory limit in bytes.
96
+ * @returns {number}
97
+ */
98
+ getContainerMemoryLimit(): number;
99
+ /**
100
+ * Measure event loop lag in ms.
101
+ * @returns {Promise<number>}
102
+ */
103
+ measureLag(): Promise<number>;
104
+ /**
105
+ * Express middleware to count HTTP requests.
106
+ * Increments the `app_http_requests_total` counter.
107
+ */
108
+ countHttpRequestMiddleware: (req: any, res: any, next: any) => void;
109
+ /**
110
+ * Push all gauges and counters to PushGateway and optionally log.
111
+ */
112
+ pushMetrics: () => Promise<void>;
113
+ /**
114
+ * Start automatic periodic push of metrics.
115
+ * @param {number} [interval] Interval in seconds
116
+ */
117
+ startPush: (interval?: number | undefined) => void;
118
+ }
119
+ import client = require("prom-client");
120
+ //# sourceMappingURL=metricsClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metricsClient.d.ts","sourceRoot":"","sources":["../src/metricsClient.js"],"names":[],"mappings":"AAOA;;;GAGG;AACH;IACE;;;;;;;;;;;OAWG;IACH;QAV2B,OAAO;QACP,MAAM;QACN,WAAW;QACV,OAAO;QACP,SAAS;QACV,cAAc;QACd,eAAe;QACf,mBAAmB;QACnB,WAAW;OA6DrC;IA1DC,gBACiE;IACjE,eAAqE;IACrE,oBAG6B;IAC7B,iBAAuE;IACvE,mBAC+D;IAC/D,uBACoE;IACpE,wBACsE;IACtE,4BAGI;IACJ,oBAGI;IAEJ,mBAAyF;IAEzF,sEAAqC;IAGrC;;;;MAIC;IAKD,wEAOC;IAED,WAAgB;IAChB,aAAkB;IAElB,mEAAmE;IACnE;YADkB,MAAM,SAAc,MAAM,GAAG,QAAQ,MAAM,CAAC;MACvC;IACvB,4EAA4E;IAC5E,qBAAyB;IAEzB,yBAAyB;IACzB,uBAAgC;IAKlC;;;OAGG;IACH,4BA8CC;IAED;;;;;;;OAOG;IACH,oBANW,MAAM,QACN,MAAM,oBACM,MAAM,GAAC,QAAQ,MAAM,CAAC,qDAEhC,OAAO,KAAK,CAqBxB;IAED;;;;;;;OAOG;IACH,oBALW,MAAM,QACN,MAAM,gEAEY,MAAM,4BAAU,MAAM,KAAG,IAAI,CAmBzD;IAED;;;OAGG;IACH,0BAFa,MAAM,CA2BlB;IAED;;;OAGG;IACH,oBAFa,MAAM,CAiBlB;IAED;;;OAGG;IACH,2BAFa,MAAM,CAWlB;IAED;;;OAGG;IACH,2BAFa,MAAM,CAgBlB;IAED;;;OAGG;IACH,cAFa,QAAQ,MAAM,CAAC,CAO3B;IAED;;;OAGG;IACH,oEA0BC;IAED;;OAEG;IACH,iCAgCC;IAED;;;OAGG;IACH,mDAYC;CACF"}