@knpkv/alchemy-console 0.3.2 → 0.4.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/README.md +78 -23
- package/dist/api.d.ts +16 -2
- package/dist/api.d.ts.map +1 -1
- package/dist/client/assets/empty-state-creature-CWMFWDpa.svg +60 -0
- package/dist/client/assets/index-C5EGKyzJ.js +58 -0
- package/dist/client/assets/{index-CrA-MUdX.css → index-CHwWf6VU.css} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/resource-identity.d.ts +7 -0
- package/dist/internal/resource-identity.d.ts.map +1 -0
- package/dist/internal/resource-identity.js +180 -0
- package/dist/internal/resource-identity.js.map +1 -0
- package/dist/local-state.d.ts.map +1 -1
- package/dist/local-state.js +11 -1
- package/dist/local-state.js.map +1 -1
- package/dist/outputs.d.ts +5 -0
- package/dist/outputs.d.ts.map +1 -0
- package/dist/outputs.js +15 -0
- package/dist/outputs.js.map +1 -0
- package/dist/presentation/ResourceDetailView.d.ts +13 -0
- package/dist/presentation/ResourceDetailView.d.ts.map +1 -0
- package/dist/presentation/ResourceDetailView.js +12 -0
- package/dist/presentation/ResourceDetailView.js.map +1 -0
- package/dist/presentation/ResourceTree.d.ts +18 -0
- package/dist/presentation/ResourceTree.d.ts.map +1 -0
- package/dist/presentation/ResourceTree.js +36 -0
- package/dist/presentation/ResourceTree.js.map +1 -0
- package/dist/presentation/StackDetailView.d.ts +15 -0
- package/dist/presentation/StackDetailView.d.ts.map +1 -0
- package/dist/presentation/StackDetailView.js +36 -0
- package/dist/presentation/StackDetailView.js.map +1 -0
- package/dist/presentation/StackListView.d.ts +4 -2
- package/dist/presentation/StackListView.d.ts.map +1 -1
- package/dist/presentation/StackListView.js +4 -4
- package/dist/presentation/StackListView.js.map +1 -1
- package/dist/presentation/detail-model.d.ts +40 -0
- package/dist/presentation/detail-model.d.ts.map +1 -0
- package/dist/presentation/detail-model.js +2 -0
- package/dist/presentation/detail-model.js.map +1 -0
- package/dist/presentation/detail-parts.d.ts +28 -0
- package/dist/presentation/detail-parts.d.ts.map +1 -0
- package/dist/presentation/detail-parts.js +42 -0
- package/dist/presentation/detail-parts.js.map +1 -0
- package/dist/presentation/resource-graph.d.ts +4 -0
- package/dist/presentation/resource-graph.d.ts.map +1 -0
- package/dist/presentation/resource-graph.js +25 -0
- package/dist/presentation/resource-graph.js.map +1 -0
- package/dist/s3-live.d.ts +1 -0
- package/dist/s3-live.d.ts.map +1 -1
- package/dist/s3-live.js +20 -14
- package/dist/s3-live.js.map +1 -1
- package/dist/s3-reader.d.ts +2 -1
- package/dist/s3-reader.d.ts.map +1 -1
- package/dist/s3-reader.js.map +1 -1
- package/dist/s3-state.d.ts.map +1 -1
- package/dist/s3-state.js +13 -1
- package/dist/s3-state.js.map +1 -1
- package/dist/schema.d.ts +22 -3
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +16 -5
- package/dist/schema.js.map +1 -1
- package/dist/server/Catalog.d.ts.map +1 -1
- package/dist/server/Catalog.js +15 -2
- package/dist/server/Catalog.js.map +1 -1
- package/dist/state.d.ts +2 -0
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +8 -8
- package/dist/state.js.map +1 -1
- package/dist/views/empty-state-creature.svg +60 -0
- package/dist/views/index.js +705 -105
- package/dist/views/style.css +1 -1
- package/dist/views.d.ts +5 -0
- package/dist/views.d.ts.map +1 -1
- package/dist/views.js +2 -1
- package/dist/views.js.map +1 -1
- package/package.json +3 -3
- package/dist/client/assets/index-CNQi3IQH.js +0 -58
package/README.md
CHANGED
|
@@ -12,8 +12,12 @@ The browser shows stacks grouped by app, with desktop columns and compact phone
|
|
|
12
12
|
rows. Read again starts a fresh discovery request and clears the previous rows.
|
|
13
13
|
Loading, empty, incomplete discovery and owner sign-in failures are explicit.
|
|
14
14
|
Missing metadata reads Unknown; zero resources remains zero. No polling, cached
|
|
15
|
-
rows, plan, apply or destroy runs. Stage names and resource counts
|
|
16
|
-
|
|
15
|
+
rows, plan, apply or destroy runs. Stage names and known resource counts open the
|
|
16
|
+
stack UI. Resources lists actual returned resource metadata; State groups the
|
|
17
|
+
same resources by their returned construct parent and exact type. Resource rows
|
|
18
|
+
open identity and dependency details. Outputs distinguishes Hidden values, proven
|
|
19
|
+
empty state and unavailable formats. No raw JSON click target, Plan tab or Preview
|
|
20
|
+
changes action is present.
|
|
17
21
|
|
|
18
22
|
The standalone wrapper shows Alchemy console, the actual local listener address
|
|
19
23
|
and owner session status. It adds no Relay host inventory or shell navigation.
|
|
@@ -55,7 +59,7 @@ process-scoped identifiers with no encoded locator. They remain stable across
|
|
|
55
59
|
scans while a stack remains present, then expire when it disappears or the server
|
|
56
60
|
restarts. They are normalized, authenticated client-visible identifiers; the
|
|
57
61
|
server never persists them. Do not emit them or stack metadata through public
|
|
58
|
-
routes or telemetry. Browsers must not persist
|
|
62
|
+
routes or telemetry. Browsers must not persist provider coordinates or authenticated stack/resource metadata.
|
|
59
63
|
|
|
60
64
|
Discovery reports sanitized reason codes for failed projects, SSO profiles and
|
|
61
65
|
buckets while continuing other sources. A discovered entrypoint with no state
|
|
@@ -76,13 +80,18 @@ requests. Listener and request Host are restricted to the bound loopback address
|
|
|
76
80
|
|
|
77
81
|
## Browser views
|
|
78
82
|
|
|
79
|
-
Import `StackListView` from `@knpkv/alchemy-console/views` and its stylesheet from
|
|
80
|
-
`@knpkv/alchemy-console/views/style.css`. Mount
|
|
83
|
+
Import `StackListView`, `StackDetailView` and `ResourceDetailView` from `@knpkv/alchemy-console/views` and its stylesheet from
|
|
84
|
+
`@knpkv/alchemy-console/views/style.css`. Mount them inside a Rly style/theme boundary.
|
|
81
85
|
Views consumers supply the optional React, React DOM and Rly peers; the standalone
|
|
82
86
|
browser shell already bundles them.
|
|
83
|
-
The application supplies
|
|
84
|
-
|
|
85
|
-
|
|
87
|
+
The application supplies normalized presentation data, a product label, host
|
|
88
|
+
sign-in instruction, read actions and real UI destinations. `StackListView` accepts
|
|
89
|
+
optional `stackHref`; without a destination, stages and counts remain text.
|
|
90
|
+
`StackDetailView` has controlled Resources/Outputs/State tabs and `resourceHref`.
|
|
91
|
+
`ResourceDetailView` accepts `stackHref` and `resourceHref`. Views fetch nothing,
|
|
92
|
+
read no configuration and persist no data. The standalone detail wrapper adds
|
|
93
|
+
breadcrumbs and Read again outside the referenced module content. Phone list
|
|
94
|
+
links use separated stage/count lines to keep their 44px targets disjoint. `Ready.checkedAt` describes the actual completed
|
|
86
95
|
request. Replace state with `Loading` before reading; failures and unauthorized
|
|
87
96
|
states contain no previous rows. Only normalized authenticated client-visible
|
|
88
97
|
stack metadata belongs here, never raw provider locators or credentials.
|
|
@@ -90,9 +99,15 @@ stack metadata belongs here, never raw provider locators or credentials.
|
|
|
90
99
|
The standalone client uses the typed API and sends same-origin cookies with
|
|
91
100
|
no-store requests. The fragment is removed from history before its bootstrap
|
|
92
101
|
POST. Tokens never enter storage, logs or telemetry. CSS and font assets are
|
|
93
|
-
served from the same listener with a self-only CSP
|
|
102
|
+
served from the same listener with a self-only CSP and no application-authored inline
|
|
103
|
+
style markup. Pinned Rly/Radix tabs assign `outline: none` on their tab list and
|
|
104
|
+
`animation-duration: 0s` on an initially mounted panel through trusted CSSOM
|
|
105
|
+
properties. Those framework effects require no CSP relaxation; serialized inline
|
|
106
|
+
style markup remains blocked. The
|
|
94
107
|
decorative empty-state SVG uses the approved Stacks illustration from this MIT
|
|
95
|
-
repository, with presentation attributes rather than inline styles.
|
|
108
|
+
repository, with presentation attributes rather than inline styles. The State empty panel uses
|
|
109
|
+
the original decorative 56px Stacks2c procedural creature from the same MIT repo;
|
|
110
|
+
both SVGs remain external same-origin assets.
|
|
96
111
|
|
|
97
112
|
## Data readers
|
|
98
113
|
|
|
@@ -113,7 +128,7 @@ unresolved Alchemy version return `null`. Invalid lockfiles fail explicitly.
|
|
|
113
128
|
`.alchemy/state/<app>/<stage>/<encoded-fqn>.json` for beta.74 and beta.77. Other
|
|
114
129
|
versions, including unknown versions, fail with `unsupported-version`. Resource
|
|
115
130
|
metadata includes FQN, logical ID, type, status, and namespace parent. Action rows
|
|
116
|
-
are validated and excluded.
|
|
131
|
+
are validated and excluded. Temporary files are ignored. Missing
|
|
117
132
|
state returns `available: false`; an existing empty stage returns an empty resource
|
|
118
133
|
list with `available: true`. JSON names must match the stored FQN encoding.
|
|
119
134
|
|
|
@@ -148,10 +163,11 @@ An API can report these failures per profile while continuing other profiles.
|
|
|
148
163
|
keys. `listS3Versions(bucket, prefix)` returns persisted object version coordinates
|
|
149
164
|
and deletion markers. Both S3 continuation markers are retained; repeated markers
|
|
150
165
|
fail. `readS3State(stack, alchemyVersion?)` reads each latest non-deleted resource
|
|
151
|
-
using its listed version ID.
|
|
166
|
+
using its listed version ID. Temporary files are excluded; supported-version stack outputs use their selected
|
|
167
|
+
current version and the key-only decoder below.
|
|
152
168
|
`readS3Resource(stack, key, versionId)` reads one historical version after checking
|
|
153
169
|
that the key belongs to that stack. JSON names must match the resource FQN.
|
|
154
|
-
Latest deletion markers never resurrect an older resource. Null versions from
|
|
170
|
+
Latest deletion markers never resurrect an older resource or output dictionary. Null versions from
|
|
155
171
|
unversioned or suspended buckets are supported. Multiple resource reads are not
|
|
156
172
|
an atomic snapshot of a deployment.
|
|
157
173
|
|
|
@@ -168,10 +184,41 @@ Read-only IAM access needs `s3:ListAllMyBuckets`, `s3:ListBucketVersions`, and
|
|
|
168
184
|
and [object reading](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html)
|
|
169
185
|
references. No live AWS or Alchemy stack is used by the tests.
|
|
170
186
|
|
|
171
|
-
The flat resource list retains
|
|
172
|
-
own resource row.
|
|
173
|
-
|
|
174
|
-
|
|
187
|
+
The flat resource list retains construct parents, including parents without their
|
|
188
|
+
own resource row. Resource-own identity is selected only from documented beta.74
|
|
189
|
+
and beta.77 `attr` fields. The AWS allowlist is Lambda Function, S3 Bucket,
|
|
190
|
+
DynamoDB Table, SQS Queue, IAM Role/Policy, CloudFront Distribution, Logs LogGroup,
|
|
191
|
+
ACM Certificate and CloudWatch Alarm/Dashboard. Commercial `aws` ARNs must match
|
|
192
|
+
the exact resource type and own name. Console links use the AWS-owned
|
|
193
|
+
[toolkit resource resolver](https://github.com/aws/aws-toolkit-vscode/blob/e1b0f9bc573bac1830f0b9aa7ced25a6c69bb477/packages/core/src/awsService/cloudformation/consoleLinksUtils.ts).
|
|
194
|
+
Other partitions and unknown/custom types have no link. S3 resource region/account
|
|
195
|
+
must come from that resource, never the backend bucket or SSO selector.
|
|
196
|
+
|
|
197
|
+
`Cloudflare.Worker` uses its own validated account, worker ID and worker name in
|
|
198
|
+
the documented service route. Local/dev identities, dispatch namespaces and
|
|
199
|
+
parent-owned versions have no regular service link. R2 Bucket and DNS Record may
|
|
200
|
+
expose validated own identity but have no console link when an official route or
|
|
201
|
+
required own routing identity is unproven. DNS `modifiedOn` alone supplies Last
|
|
202
|
+
updated, preserving valid complete UTC precision. No other generic updated time
|
|
203
|
+
or successful deployment time is inferred. Missing metadata remains null.
|
|
204
|
+
Absent provider mode can represent legacy cloud state; explicit local or invalid
|
|
205
|
+
modes never authorize a provider link.
|
|
206
|
+
|
|
207
|
+
`downstream` records dependents, not dependencies. The view builds a bounded
|
|
208
|
+
reverse index for the complete returned stack. Missing edges, missing rows,
|
|
209
|
+
duplicates or an incomplete graph make dependency knowledge unavailable rather
|
|
210
|
+
than inventing an empty dependency list. Local file timestamps never prove a
|
|
211
|
+
successful deployment.
|
|
212
|
+
|
|
213
|
+
The supported stack output file is a JSON root dictionary. Only validated keys
|
|
214
|
+
cross normalization; each value is `Hidden`, with a null description. Plaintext,
|
|
215
|
+
including a URL, never proves safety. Exact successfully read `{}` proves no
|
|
216
|
+
outputs. Missing, unreadable, malformed, scalar/array or root encoding-marker
|
|
217
|
+
state is unavailable, including reserved envelopes with sibling fields. Unknown
|
|
218
|
+
remote version cannot establish an output format. Output values are never
|
|
219
|
+
traversed or transported. The pure exported view additionally accepts `SafeText`
|
|
220
|
+
with `proof: "explicit-non-sensitive"` only from a trusted host projection with
|
|
221
|
+
independent proof. The persisted readers and standalone API never produce it.
|
|
175
222
|
|
|
176
223
|
## Private data and redaction
|
|
177
224
|
|
|
@@ -183,23 +230,31 @@ appear on unauthenticated routes or public telemetry.
|
|
|
183
230
|
|
|
184
231
|
Persisted Alchemy state can contain plaintext secret payloads inside
|
|
185
232
|
`__redacted__` marker objects. This package never invokes Alchemy's reviver or
|
|
186
|
-
decrypts anything. It discards props, attrs, old state, action inputs
|
|
233
|
+
decrypts anything. It discards raw props, attrs, old state, action inputs and output values. Only the
|
|
234
|
+
explicit resource-own attr allowlist and output keys are normalized.
|
|
187
235
|
Marker objects in metadata become `<redacted>`, including sibling fields. Parsing
|
|
188
236
|
errors include only a tagged reason, never raw contents or parser diagnostics.
|
|
189
|
-
Reads are capped at 8 MiB per file and directory listings at 50,000 entries.
|
|
237
|
+
Reads are capped at 8 MiB per file and directory listings at 50,000 entries. Resource identities are bounded to 1024
|
|
238
|
+
characters, dependency graphs to 100,000 edges, and output dictionaries to 1000
|
|
239
|
+
keys of at most 256 characters.
|
|
190
240
|
|
|
191
241
|
SSO profiles retain server-private names, config paths, account/role selectors,
|
|
192
242
|
session names, start URLs, and routing regions. S3 bucket names, state prefixes,
|
|
193
243
|
object keys, version IDs, and pagination markers are also server-private. Their
|
|
194
244
|
persisted representation is AWS config or S3 object coordinates; console code
|
|
195
245
|
holds them in server memory only. They must not cross HTTP, browser storage,
|
|
196
|
-
logs, telemetry, or public errors. Only normalized `StackState` and
|
|
197
|
-
|
|
246
|
+
logs, telemetry, or public errors. Only normalized `StackState`, `ResourceSummary` and `OutputSummary` fields may
|
|
247
|
+
cross the authenticated owner API. Resource FQNs, construct parents, provider IDs,
|
|
248
|
+
own account/region, allowlisted console URLs, documented updated timestamps,
|
|
249
|
+
downstream identities and output keys are authenticated client-visible metadata.
|
|
250
|
+
Stack IDs and resource FQNs also appear in validated UI query routes and browser
|
|
251
|
+
history. They are not backend locators. Never emit them on public routes, in logs
|
|
252
|
+
or telemetry, or persist them in browser storage. Credential-bearing
|
|
198
253
|
`SsoCredentials` results remain solely inside the signing boundary. S3 reads have
|
|
199
254
|
the same 8 MiB payload cap and a 50,000-entry / 100-page listing cap.
|
|
200
255
|
|
|
201
|
-
Cloudflare
|
|
202
|
-
|
|
256
|
+
Cloudflare profile configuration remains server-side. This phase has no plan,
|
|
257
|
+
apply or destroy execution.
|
|
203
258
|
|
|
204
259
|
## Format references
|
|
205
260
|
|
package/dist/api.d.ts
CHANGED
|
@@ -49,12 +49,19 @@ export declare const StackDetail: Schema.Struct<{
|
|
|
49
49
|
readonly logicalId: Schema.NonEmptyString;
|
|
50
50
|
readonly resourceType: Schema.NonEmptyString;
|
|
51
51
|
readonly status: Schema.Literals<readonly ["creating", "created", "updating", "updated", "deleting", "replacing", "replaced"]>;
|
|
52
|
-
readonly parent: Schema.NullOr<Schema.
|
|
52
|
+
readonly parent: Schema.NullOr<Schema.NonEmptyString>;
|
|
53
53
|
readonly providerId: Schema.NullOr<Schema.String>;
|
|
54
54
|
readonly account: Schema.NullOr<Schema.String>;
|
|
55
55
|
readonly region: Schema.NullOr<Schema.String>;
|
|
56
56
|
readonly consoleUrl: Schema.NullOr<Schema.String>;
|
|
57
|
+
readonly updatedAt: Schema.NullOr<Schema.String>;
|
|
58
|
+
readonly downstream: Schema.NullOr<Schema.$Array<Schema.NonEmptyString>>;
|
|
57
59
|
}>>;
|
|
60
|
+
readonly outputs: Schema.NullOr<Schema.$Array<Schema.Struct<{
|
|
61
|
+
readonly key: Schema.NonEmptyString;
|
|
62
|
+
readonly value: Schema.TaggedStruct<"Hidden", {}>;
|
|
63
|
+
readonly description: Schema.Null;
|
|
64
|
+
}>>>;
|
|
58
65
|
}>;
|
|
59
66
|
}>;
|
|
60
67
|
export type StackDetail = typeof StackDetail.Type;
|
|
@@ -112,12 +119,19 @@ declare const AlchemyConsoleApi_base: HttpApi.HttpApi<"AlchemyConsoleApi", HttpA
|
|
|
112
119
|
readonly logicalId: Schema.NonEmptyString;
|
|
113
120
|
readonly resourceType: Schema.NonEmptyString;
|
|
114
121
|
readonly status: Schema.Literals<readonly ["creating", "created", "updating", "updated", "deleting", "replacing", "replaced"]>;
|
|
115
|
-
readonly parent: Schema.NullOr<Schema.
|
|
122
|
+
readonly parent: Schema.NullOr<Schema.NonEmptyString>;
|
|
116
123
|
readonly providerId: Schema.NullOr<Schema.String>;
|
|
117
124
|
readonly account: Schema.NullOr<Schema.String>;
|
|
118
125
|
readonly region: Schema.NullOr<Schema.String>;
|
|
119
126
|
readonly consoleUrl: Schema.NullOr<Schema.String>;
|
|
127
|
+
readonly updatedAt: Schema.NullOr<Schema.String>;
|
|
128
|
+
readonly downstream: Schema.NullOr<Schema.$Array<Schema.NonEmptyString>>;
|
|
120
129
|
}>>;
|
|
130
|
+
readonly outputs: Schema.NullOr<Schema.$Array<Schema.Struct<{
|
|
131
|
+
readonly key: Schema.NonEmptyString;
|
|
132
|
+
readonly value: Schema.TaggedStruct<"Hidden", {}>;
|
|
133
|
+
readonly description: Schema.Null;
|
|
134
|
+
}>>>;
|
|
121
135
|
}>;
|
|
122
136
|
}>>, Schema.toCodecJson<typeof CatalogReadError | typeof StackNotFound>, OwnerAuth, never>, false>>;
|
|
123
137
|
export declare class AlchemyConsoleApi extends AlchemyConsoleApi_base {
|
package/dist/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,8GAA8G;AAC9G,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAG3F,0GAA0G;AAC1G,eAAO,MAAM,OAAO,eAAuC,CAAA;AAC3D,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AAEzC,eAAO,MAAM,mBAAmB,oOAc9B,CAAA;AAEF,eAAO,MAAM,cAAc;;;EAGzB,CAAA;AACF,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAC,IAAI,CAAA;AAEvD,eAAO,MAAM,YAAY;;;;;;;;EAQvB,CAAA;AACF,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAA;AAEnD,eAAO,MAAM,SAAS;;;;;;;;;;;;;;EAA8F,CAAA;AACpH,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC,IAAI,CAAA;AAC7C,eAAO,MAAM,WAAW
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,8GAA8G;AAC9G,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAG3F,0GAA0G;AAC1G,eAAO,MAAM,OAAO,eAAuC,CAAA;AAC3D,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AAEzC,eAAO,MAAM,mBAAmB,oOAc9B,CAAA;AAEF,eAAO,MAAM,cAAc;;;EAGzB,CAAA;AACF,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAC,IAAI,CAAA;AAEvD,eAAO,MAAM,YAAY;;;;;;;;EAQvB,CAAA;AACF,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAA;AAEnD,eAAO,MAAM,SAAS;;;;;;;;;;;;;;EAA8F,CAAA;AACpH,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC,IAAI,CAAA;AAC7C,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAoD,CAAA;AAC5E,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC,IAAI,CAAA;;;;AAEjD,qBAAa,gBAAiB,SAAQ,qBAEZ;CAAG;;AAE7B,qBAAa,aAAc,SAAQ,kBAAgF;CAAG;;AAEtH,qBAAa,YAAa,SAAQ,iBAA8E;CAAG;;AAEnH,qBAAa,SAAU,SAAQ,cAAwE;CAAG;;;;;;;;;AAE1G,6EAA6E;AAC7E,qBAAa,SAAU,SAAQ,cAE7B;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWL,qBAAa,iBAAkB,SAAQ,sBAAmE;CAAG"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="56" height="56" aria-hidden="true" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter">
|
|
2
|
+
<defs fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter">
|
|
3
|
+
<radialGradient id="bpkgsrc-56-dc-38" cx="38%" cy="30%" r="80%" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><stop offset="0" stop-color="oklch(0.86 0.12 273)" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /><stop offset="0.55" stop-color="oklch(0.66 0.17 273)" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /><stop offset="1" stop-color="oklch(0.46 0.17 291)" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /></radialGradient>
|
|
4
|
+
<radialGradient id="spkgsrc-56-dc-38" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><stop offset="0" stop-color="black" stop-opacity="0.28" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /><stop offset="1" stop-color="black" stop-opacity="0" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /></radialGradient>
|
|
5
|
+
<radialGradient id="cpkgsrc-56-dc-38" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><stop offset="0" stop-color="oklch(0.95 0.1 264)" stop-opacity="0.95" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /><stop offset="1" stop-color="oklch(0.75 0.15 264)" stop-opacity="0" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /></radialGradient>
|
|
6
|
+
<radialGradient id="gpkgsrc-56-dc-38" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><stop offset="0" stop-color="white" stop-opacity="0.55" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /><stop offset="1" stop-color="white" stop-opacity="0" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /></radialGradient>
|
|
7
|
+
<linearGradient id="dpkgsrc-56-dc-38" x1="0" x2="0" y1="0" y2="1" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><stop offset="0.55" stop-color="oklch(0.3 0.12 291)" stop-opacity="0" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /><stop offset="1" stop-color="oklch(0.3 0.12 291)" stop-opacity="0.45" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /></linearGradient>
|
|
8
|
+
<radialGradient id="wpkgsrc-56-dc-38" cy="40%" r="60%" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><stop offset="0.6" stop-color="oklch(0.99 0.006 264)" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /><stop offset="1" stop-color="oklch(0.86 0.03 264)" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /></radialGradient>
|
|
9
|
+
<radialGradient id="ipkgsrc-56-dc-38" cy="72%" r="70%" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><stop offset="0" stop-color="oklch(0.62 0.15 264)" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /><stop offset="1" stop-color="oklch(0.3 0.09 264)" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /></radialGradient>
|
|
10
|
+
<clipPath id="kpkgsrc-56-dc-38" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><path d="M89.0 58.1C88.9 61.1 88.9 64.0 88.3 66.9C87.8 69.8 87.2 73.0 85.7 75.7C84.2 78.5 82.0 81.2 79.3 83.2C76.6 85.1 73.0 86.4 69.7 87.2C66.3 88.0 62.6 87.9 59.4 88.0C56.1 88.1 53.1 87.7 50.0 87.7C46.9 87.6 44.0 87.8 40.7 87.6C37.5 87.5 33.9 87.6 30.6 86.9C27.2 86.1 23.5 85.0 20.7 83.2C17.9 81.3 15.4 78.6 13.8 76.0C12.3 73.3 11.7 70.0 11.2 67.0C10.7 64.0 10.9 61.1 11.0 58.1C11.1 55.2 11.1 52.3 11.7 49.4C12.2 46.4 12.8 43.2 14.3 40.5C15.8 37.8 18.0 35.0 20.7 33.1C23.4 31.2 27.0 29.9 30.3 29.1C33.7 28.3 37.4 28.3 40.6 28.3C43.9 28.2 46.9 28.5 50.0 28.6C53.1 28.7 56.0 28.5 59.3 28.6C62.5 28.8 66.1 28.7 69.4 29.4C72.8 30.2 76.5 31.3 79.3 33.1C82.1 34.9 84.6 37.6 86.2 40.3C87.7 43.0 88.3 46.3 88.8 49.3C89.3 52.2 89.1 55.2 89.0 58.1Z" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /></clipPath>
|
|
11
|
+
<clipPath id="e0pkgsrc-56-dc-38" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><ellipse cx="39.07" cy="52.158168587244646" rx="5.4" ry="5.832000000000001" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /></clipPath>
|
|
12
|
+
<clipPath id="o0pkgsrc-56-dc-38" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><ellipse cx="39.07" cy="52.158168587244646" rx="6.6000000000000005" ry="7.032000000000001" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /></clipPath>
|
|
13
|
+
<clipPath id="u0pkgsrc-56-dc-38" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><path d="M31.47 64.35V42.78Q39.07 46.28 46.67 42.78V64.35Z" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" transform="translate(0 2.052)" /></clipPath>
|
|
14
|
+
<clipPath id="l0pkgsrc-56-dc-38" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><path d="M31.47 39.96V58.04Q39.07 61.54 46.67 58.04V39.96Z" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /></clipPath><clipPath id="e1pkgsrc-56-dc-38" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><ellipse cx="60.93" cy="52.158168587244646" rx="5.4" ry="5.832000000000001" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /></clipPath>
|
|
15
|
+
<clipPath id="o1pkgsrc-56-dc-38" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><ellipse cx="60.93" cy="52.158168587244646" rx="6.6000000000000005" ry="7.032000000000001" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /></clipPath>
|
|
16
|
+
<clipPath id="u1pkgsrc-56-dc-38" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><path d="M53.33 64.35V42.78Q60.93 46.28 68.53 42.78V64.35Z" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" transform="translate(0 2.052)" /></clipPath>
|
|
17
|
+
<clipPath id="l1pkgsrc-56-dc-38" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><path d="M53.33 39.96V58.04Q60.93 61.54 68.53 58.04V39.96Z" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /></clipPath>
|
|
18
|
+
</defs>
|
|
19
|
+
<ellipse cx="50" cy="91" fill="url(#spkgsrc-56-dc-38)" rx="32.76" ry="5" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" />
|
|
20
|
+
<circle cx="50" cy="55" r="46" fill="none" stroke="oklch(0.4901 0.013 274.7)" stroke-width="2.5px" opacity="0" stroke-linecap="butt" stroke-linejoin="miter" />
|
|
21
|
+
<circle cx="50" cy="55" r="46" pathLength="100" fill="none" stroke="oklch(0.4901 0.013 274.7)" stroke-width="4.2px" opacity="0" stroke-linecap="round" stroke-linejoin="miter" stroke-dasharray="9px, 91px" />
|
|
22
|
+
<g transform="translate(76 6) scale(0.8)" display="none" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><circle cx="12" cy="12" r="11" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /><path d="M6 12h12" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" /></g>
|
|
23
|
+
<g fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><g fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><g fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter">
|
|
24
|
+
<path d="M89.0 58.1C88.9 61.1 88.9 64.0 88.3 66.9C87.8 69.8 87.2 73.0 85.7 75.7C84.2 78.5 82.0 81.2 79.3 83.2C76.6 85.1 73.0 86.4 69.7 87.2C66.3 88.0 62.6 87.9 59.4 88.0C56.1 88.1 53.1 87.7 50.0 87.7C46.9 87.6 44.0 87.8 40.7 87.6C37.5 87.5 33.9 87.6 30.6 86.9C27.2 86.1 23.5 85.0 20.7 83.2C17.9 81.3 15.4 78.6 13.8 76.0C12.3 73.3 11.7 70.0 11.2 67.0C10.7 64.0 10.9 61.1 11.0 58.1C11.1 55.2 11.1 52.3 11.7 49.4C12.2 46.4 12.8 43.2 14.3 40.5C15.8 37.8 18.0 35.0 20.7 33.1C23.4 31.2 27.0 29.9 30.3 29.1C33.7 28.3 37.4 28.3 40.6 28.3C43.9 28.2 46.9 28.5 50.0 28.6C53.1 28.7 56.0 28.5 59.3 28.6C62.5 28.8 66.1 28.7 69.4 29.4C72.8 30.2 76.5 31.3 79.3 33.1C82.1 34.9 84.6 37.6 86.2 40.3C87.7 43.0 88.3 46.3 88.8 49.3C89.3 52.2 89.1 55.2 89.0 58.1Z" fill="url(#bpkgsrc-56-dc-38)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" />
|
|
25
|
+
<g clip-path="url(#kpkgsrc-56-dc-38)" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter">
|
|
26
|
+
<circle cx="50" cy="71.27" r="16" fill="url(#cpkgsrc-56-dc-38)" stroke="none" stroke-width="1px" opacity="0.35" stroke-linecap="butt" stroke-linejoin="miter" />
|
|
27
|
+
<rect x="11.00" y="28.26" width="78.00" height="59.74" fill="url(#dpkgsrc-56-dc-38)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" />
|
|
28
|
+
<ellipse cx="34.40" cy="40.21" rx="13.26" ry="5.97" fill="url(#gpkgsrc-56-dc-38)" transform="rotate(-24 34.40 40.21)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" />
|
|
29
|
+
</g>
|
|
30
|
+
</g></g>
|
|
31
|
+
<g fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><g fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter">
|
|
32
|
+
<g fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter">
|
|
33
|
+
<g clip-path="url(#u0pkgsrc-56-dc-38)" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><g clip-path="url(#l0pkgsrc-56-dc-38)" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter">
|
|
34
|
+
<ellipse cx="39.07" cy="52.158168587244646" rx="6.6000000000000005" ry="7.032000000000001" fill="oklch(0.25 0.05 260 / 0.14)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" />
|
|
35
|
+
<ellipse cx="39.07" cy="52.158168587244646" rx="5.4" ry="5.832000000000001" fill="url(#wpkgsrc-56-dc-38)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" />
|
|
36
|
+
<g clip-path="url(#e0pkgsrc-56-dc-38)" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><g fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter">
|
|
37
|
+
<circle cx="39.07" cy="52.158168587244646" r="3.56" fill="url(#ipkgsrc-56-dc-38)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" />
|
|
38
|
+
<circle cx="39.07" cy="52.158168587244646" r="1.85" fill="oklch(0.14 0.02 260)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" />
|
|
39
|
+
<circle cx="37.79" cy="50.73" r="0.93" fill="oklch(1 0 none / 0.92)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" />
|
|
40
|
+
<circle cx="40.28" cy="53.44" r="0.43" fill="oklch(1 0 none / 0.92)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" />
|
|
41
|
+
</g></g>
|
|
42
|
+
</g></g>
|
|
43
|
+
<g clip-path="url(#o0pkgsrc-56-dc-38)" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><g fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" transform="translate(0 2.052)"><path d="M31.47 42.78Q39.07 46.28 46.67 42.78" fill="none" stroke="oklch(0.22 0.04 260 / 0.85)" stroke-width="0.9px" opacity="0" stroke-linecap="round" stroke-linejoin="miter" /></g></g>
|
|
44
|
+
</g><g fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter">
|
|
45
|
+
<g clip-path="url(#u1pkgsrc-56-dc-38)" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><g clip-path="url(#l1pkgsrc-56-dc-38)" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter">
|
|
46
|
+
<ellipse cx="60.93" cy="52.158168587244646" rx="6.6000000000000005" ry="7.032000000000001" fill="oklch(0.25 0.05 260 / 0.14)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" />
|
|
47
|
+
<ellipse cx="60.93" cy="52.158168587244646" rx="5.4" ry="5.832000000000001" fill="url(#wpkgsrc-56-dc-38)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" />
|
|
48
|
+
<g clip-path="url(#e1pkgsrc-56-dc-38)" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><g fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter">
|
|
49
|
+
<circle cx="60.93" cy="52.158168587244646" r="3.56" fill="url(#ipkgsrc-56-dc-38)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" />
|
|
50
|
+
<circle cx="60.93" cy="52.158168587244646" r="1.85" fill="oklch(0.14 0.02 260)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" />
|
|
51
|
+
<circle cx="59.65" cy="50.73" r="0.93" fill="oklch(1 0 none / 0.92)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" />
|
|
52
|
+
<circle cx="62.14" cy="53.44" r="0.43" fill="oklch(1 0 none / 0.92)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" />
|
|
53
|
+
</g></g>
|
|
54
|
+
</g></g>
|
|
55
|
+
<g clip-path="url(#o1pkgsrc-56-dc-38)" fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter"><g fill="rgb(0, 0, 0)" stroke="none" stroke-width="1px" opacity="1" stroke-linecap="butt" stroke-linejoin="miter" transform="translate(0 2.052)"><path d="M53.33 42.78Q60.93 46.28 68.53 42.78" fill="none" stroke="oklch(0.22 0.04 260 / 0.85)" stroke-width="0.9px" opacity="0" stroke-linecap="round" stroke-linejoin="miter" /></g></g>
|
|
56
|
+
</g>
|
|
57
|
+
<path d="M33.67 42.88Q39.07 39.13 44.47 42.23Q39.07 41.73 33.67 42.88Z" fill="oklch(0.36 0.09 291)" stroke="oklch(0.36 0.09 291)" stroke-width="0.6px" opacity="1" stroke-linecap="butt" stroke-linejoin="round" /><path d="M66.33 42.88Q60.93 39.13 55.53 42.23Q60.93 41.73 66.33 42.88Z" fill="oklch(0.36 0.09 291)" stroke="oklch(0.36 0.09 291)" stroke-width="0.6px" opacity="1" stroke-linecap="butt" stroke-linejoin="round" />
|
|
58
|
+
</g></g>
|
|
59
|
+
</g>
|
|
60
|
+
</svg>
|