@vltpkg/query 0.0.0-0.1730239248325
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/LICENSE +15 -0
- package/README.md +90 -0
- package/dist/esm/attribute.d.ts +15 -0
- package/dist/esm/attribute.d.ts.map +1 -0
- package/dist/esm/attribute.js +131 -0
- package/dist/esm/attribute.js.map +1 -0
- package/dist/esm/class.d.ts +6 -0
- package/dist/esm/class.d.ts.map +1 -0
- package/dist/esm/class.js +127 -0
- package/dist/esm/class.js.map +1 -0
- package/dist/esm/combinator.d.ts +6 -0
- package/dist/esm/combinator.d.ts.map +1 -0
- package/dist/esm/combinator.js +108 -0
- package/dist/esm/combinator.js.map +1 -0
- package/dist/esm/id.d.ts +6 -0
- package/dist/esm/id.d.ts.map +1 -0
- package/dist/esm/id.js +20 -0
- package/dist/esm/id.js.map +1 -0
- package/dist/esm/index.d.ts +13 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +118 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/pseudo.d.ts +13 -0
- package/dist/esm/pseudo.d.ts.map +1 -0
- package/dist/esm/pseudo.js +365 -0
- package/dist/esm/pseudo.js.map +1 -0
- package/dist/esm/types.d.ts +40 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +93 -0
- package/dist/esm/types.js.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { error } from '@vltpkg/error-cause';
|
|
2
|
+
import postcssSelectorParser from 'postcss-selector-parser';
|
|
3
|
+
import { attribute } from './attribute.js';
|
|
4
|
+
import { classFn } from './class.js';
|
|
5
|
+
import { combinator } from './combinator.js';
|
|
6
|
+
import { id } from './id.js';
|
|
7
|
+
import { pseudo } from './pseudo.js';
|
|
8
|
+
import { isPostcssNodeWithChildren, asPostcssNodeWithChildren, isSelectorNode, } from './types.js';
|
|
9
|
+
export * from './types.js';
|
|
10
|
+
const noopFn = async (state) => state;
|
|
11
|
+
const selectors = {
|
|
12
|
+
attribute,
|
|
13
|
+
class: classFn,
|
|
14
|
+
combinator,
|
|
15
|
+
comment: noopFn,
|
|
16
|
+
id,
|
|
17
|
+
nesting: noopFn,
|
|
18
|
+
pseudo,
|
|
19
|
+
root: noopFn,
|
|
20
|
+
selector: async (state) => {
|
|
21
|
+
state.partial.nodes = new Set(state.initial.nodes);
|
|
22
|
+
state.partial.edges = new Set(state.initial.edges);
|
|
23
|
+
return state;
|
|
24
|
+
},
|
|
25
|
+
string: async (state) => {
|
|
26
|
+
throw error('Unsupported selector', { found: state.current });
|
|
27
|
+
},
|
|
28
|
+
tag: async (state) => {
|
|
29
|
+
if (state.current.value !== '{' && state.current.value !== '}') {
|
|
30
|
+
throw error('Unsupported selector', { found: state.current });
|
|
31
|
+
}
|
|
32
|
+
return state;
|
|
33
|
+
},
|
|
34
|
+
universal: noopFn,
|
|
35
|
+
};
|
|
36
|
+
const selectorsMap = new Map(Object.entries(selectors));
|
|
37
|
+
export const walk = async (state) => {
|
|
38
|
+
const parserFn = selectorsMap.get(state.current.type);
|
|
39
|
+
if (!parserFn) {
|
|
40
|
+
if (state.loose) {
|
|
41
|
+
return state;
|
|
42
|
+
}
|
|
43
|
+
throw new Error(`Missing parser for query node: ${state.current.type}`);
|
|
44
|
+
}
|
|
45
|
+
state = await parserFn(state);
|
|
46
|
+
// pseudo selectors handle their own sub selectors
|
|
47
|
+
if (isPostcssNodeWithChildren(state.current) &&
|
|
48
|
+
state.current.type !== 'pseudo') {
|
|
49
|
+
const node = asPostcssNodeWithChildren(state.current);
|
|
50
|
+
if (node.nodes.length) {
|
|
51
|
+
for (let i = 0; i < node.nodes.length; i++) {
|
|
52
|
+
const current = node.nodes[i];
|
|
53
|
+
/* c8 ignore next -- impossible but TS doesn't know that */
|
|
54
|
+
if (!current)
|
|
55
|
+
continue;
|
|
56
|
+
const childState = {
|
|
57
|
+
...state,
|
|
58
|
+
current,
|
|
59
|
+
next: node.nodes[i + 1],
|
|
60
|
+
prev: node.nodes[i - 1],
|
|
61
|
+
};
|
|
62
|
+
state = await walk(childState);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (isSelectorNode(node)) {
|
|
66
|
+
for (const edge of state.partial.edges) {
|
|
67
|
+
state.collect.edges.add(edge);
|
|
68
|
+
}
|
|
69
|
+
for (const node of state.partial.nodes) {
|
|
70
|
+
state.collect.nodes.add(node);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return state;
|
|
75
|
+
};
|
|
76
|
+
export class Query {
|
|
77
|
+
#cache;
|
|
78
|
+
#graph;
|
|
79
|
+
constructor({ graph }) {
|
|
80
|
+
this.#cache = new Map();
|
|
81
|
+
this.#graph = graph;
|
|
82
|
+
}
|
|
83
|
+
async search(query) {
|
|
84
|
+
if (typeof query !== 'string') {
|
|
85
|
+
throw new TypeError('Query search argument needs to be a string');
|
|
86
|
+
}
|
|
87
|
+
if (!query)
|
|
88
|
+
return { edges: [], nodes: [] };
|
|
89
|
+
const cachedResult = this.#cache.get(query);
|
|
90
|
+
if (cachedResult) {
|
|
91
|
+
return cachedResult;
|
|
92
|
+
}
|
|
93
|
+
const nodes = new Set(Array.from(this.#graph.nodes.values()));
|
|
94
|
+
const edges = new Set(Array.from(this.#graph.edges));
|
|
95
|
+
// builds initial state and walks over it,
|
|
96
|
+
// retrieving the collected result
|
|
97
|
+
const { collect } = await walk({
|
|
98
|
+
current: postcssSelectorParser().astSync(query),
|
|
99
|
+
initial: {
|
|
100
|
+
nodes: new Set(nodes),
|
|
101
|
+
edges: new Set(edges),
|
|
102
|
+
},
|
|
103
|
+
collect: {
|
|
104
|
+
nodes: new Set(),
|
|
105
|
+
edges: new Set(),
|
|
106
|
+
},
|
|
107
|
+
partial: { nodes, edges },
|
|
108
|
+
walk,
|
|
109
|
+
});
|
|
110
|
+
const res = {
|
|
111
|
+
edges: Array.from(collect.edges),
|
|
112
|
+
nodes: Array.from(collect.nodes),
|
|
113
|
+
};
|
|
114
|
+
this.#cache.set(query, res);
|
|
115
|
+
return res;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { error } from '@vltpkg/error-cause'\nimport type { EdgeLike, GraphLike, NodeLike } from '@vltpkg/graph'\nimport postcssSelectorParser from 'postcss-selector-parser'\nimport { attribute } from './attribute.js'\nimport { classFn } from './class.js'\nimport { combinator } from './combinator.js'\nimport { id } from './id.js'\nimport { pseudo } from './pseudo.js'\nimport {\n type PostcssNodeWithChildren,\n type ParserState,\n type ParserFn,\n isPostcssNodeWithChildren,\n asPostcssNodeWithChildren,\n isSelectorNode,\n QueryResponse,\n} from './types.js'\n\nexport * from './types.js'\n\nconst noopFn = async (state: ParserState) => state\n\nconst selectors = {\n attribute,\n class: classFn,\n combinator,\n comment: noopFn,\n id,\n nesting: noopFn,\n pseudo,\n root: noopFn,\n selector: async (state: ParserState) => {\n state.partial.nodes = new Set(state.initial.nodes)\n state.partial.edges = new Set(state.initial.edges)\n return state\n },\n string: async (state: ParserState) => {\n throw error('Unsupported selector', { found: state.current })\n },\n tag: async (state: ParserState) => {\n if (state.current.value !== '{' && state.current.value !== '}') {\n throw error('Unsupported selector', { found: state.current })\n }\n return state\n },\n universal: noopFn,\n}\nconst selectorsMap = new Map<string, ParserFn>(\n Object.entries(selectors),\n)\n\nexport const walk = async (\n state: ParserState,\n): Promise<ParserState> => {\n const parserFn = selectorsMap.get(state.current.type)\n\n if (!parserFn) {\n if (state.loose) {\n return state\n }\n\n throw new Error(\n `Missing parser for query node: ${state.current.type}`,\n )\n }\n state = await parserFn(state)\n\n // pseudo selectors handle their own sub selectors\n if (\n isPostcssNodeWithChildren(state.current) &&\n state.current.type !== 'pseudo'\n ) {\n const node: PostcssNodeWithChildren = asPostcssNodeWithChildren(\n state.current,\n )\n\n if (node.nodes.length) {\n for (let i = 0; i < node.nodes.length; i++) {\n const current = node.nodes[i]\n /* c8 ignore next -- impossible but TS doesn't know that */\n if (!current) continue\n\n const childState: ParserState = {\n ...state,\n current,\n next: node.nodes[i + 1],\n prev: node.nodes[i - 1],\n }\n state = await walk(childState)\n }\n }\n\n if (isSelectorNode(node)) {\n for (const edge of state.partial.edges) {\n state.collect.edges.add(edge)\n }\n for (const node of state.partial.nodes) {\n state.collect.nodes.add(node)\n }\n }\n }\n return state\n}\n\nexport type QueryOptions = {\n graph: GraphLike\n}\n\nexport class Query {\n #cache: Map<string, QueryResponse>\n #graph: GraphLike\n\n constructor({ graph }: QueryOptions) {\n this.#cache = new Map()\n this.#graph = graph\n }\n\n async search(query: string): Promise<QueryResponse> {\n if (typeof query !== 'string') {\n throw new TypeError(\n 'Query search argument needs to be a string',\n )\n }\n\n if (!query) return { edges: [], nodes: [] }\n\n const cachedResult = this.#cache.get(query)\n if (cachedResult) {\n return cachedResult\n }\n\n const nodes = new Set<NodeLike>(\n Array.from(this.#graph.nodes.values()),\n )\n const edges = new Set<EdgeLike>(Array.from(this.#graph.edges))\n\n // builds initial state and walks over it,\n // retrieving the collected result\n const { collect } = await walk({\n current: postcssSelectorParser().astSync(query),\n initial: {\n nodes: new Set(nodes),\n edges: new Set(edges),\n },\n collect: {\n nodes: new Set<NodeLike>(),\n edges: new Set<EdgeLike>(),\n },\n partial: { nodes, edges },\n walk,\n })\n\n const res: QueryResponse = {\n edges: Array.from(collect.edges),\n nodes: Array.from(collect.nodes),\n }\n this.#cache.set(query, res)\n return res\n }\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ParserState } from './types.js';
|
|
2
|
+
export type AttrInternals = {
|
|
3
|
+
attribute: string;
|
|
4
|
+
insensitive: boolean;
|
|
5
|
+
operator?: string;
|
|
6
|
+
value?: string;
|
|
7
|
+
properties: string[];
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Parsers the `pseudo` node types.
|
|
11
|
+
*/
|
|
12
|
+
export declare const pseudo: (state: ParserState) => Promise<ParserState>;
|
|
13
|
+
//# sourceMappingURL=pseudo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pseudo.d.ts","sourceRoot":"","sources":["../../src/pseudo.ts"],"names":[],"mappings":"AAQA,OAAO,EAOL,WAAW,EAEZ,MAAM,YAAY,CAAA;AAEnB,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,EAAE,CAAA;CACrB,CAAA;AAoYD;;GAEG;AACH,eAAO,MAAM,MAAM,UAAiB,WAAW,yBAe9C,CAAA"}
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
import { splitDepID } from '@vltpkg/dep-id/browser';
|
|
2
|
+
import { error } from '@vltpkg/error-cause';
|
|
3
|
+
import { asManifest } from '@vltpkg/types';
|
|
4
|
+
import { attributeSelectorsMap, filterAttributes, } from './attribute.js';
|
|
5
|
+
import { asAttributeNode, asPostcssNodeWithChildren, asPseudoNode, asTagNode, isSelectorNode, } from './types.js';
|
|
6
|
+
const removeNode = (state, node) => {
|
|
7
|
+
for (const edge of node.edgesIn) {
|
|
8
|
+
state.partial.edges.delete(edge);
|
|
9
|
+
}
|
|
10
|
+
state.partial.nodes.delete(node);
|
|
11
|
+
};
|
|
12
|
+
const removeDanglingEdges = (state) => {
|
|
13
|
+
for (const edge of state.partial.edges) {
|
|
14
|
+
if (!edge.to) {
|
|
15
|
+
state.partial.edges.delete(edge);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Parses the internal / nested selectors of a `:attr` selector.
|
|
21
|
+
*/
|
|
22
|
+
const parseAttrInternals = (nodes) => {
|
|
23
|
+
// the last part is the attribute selector
|
|
24
|
+
const attributeSelector = asAttributeNode(asPostcssNodeWithChildren(nodes.pop()).nodes[0]);
|
|
25
|
+
// all preppending selectors are naming nested properties
|
|
26
|
+
const properties = [];
|
|
27
|
+
for (const selector of nodes) {
|
|
28
|
+
properties.push(asTagNode(asPostcssNodeWithChildren(selector).nodes[0]).value);
|
|
29
|
+
}
|
|
30
|
+
// include the attribute selector as the last part of the property lookup
|
|
31
|
+
properties.push(attributeSelector.attribute);
|
|
32
|
+
return {
|
|
33
|
+
attribute: attributeSelector.attribute,
|
|
34
|
+
insensitive: attributeSelector.insensitive || false,
|
|
35
|
+
operator: attributeSelector.operator,
|
|
36
|
+
value: attributeSelector.value,
|
|
37
|
+
properties,
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* :attr Pseudo-Selector, allows for retrieving nodes based on nested
|
|
42
|
+
* properties of the `package.json` metadata.
|
|
43
|
+
*/
|
|
44
|
+
const attr = async (state) => {
|
|
45
|
+
// Parses and retrieves the values for the nested selectors
|
|
46
|
+
let internals;
|
|
47
|
+
try {
|
|
48
|
+
internals = parseAttrInternals(asPostcssNodeWithChildren(state.current).nodes);
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
throw error('Failed to parse :attr selector', {
|
|
52
|
+
cause: err,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
// reuses the attribute selector logic to filter the nodes
|
|
56
|
+
const comparator = internals.operator ?
|
|
57
|
+
attributeSelectorsMap.get(internals.operator)
|
|
58
|
+
: undefined;
|
|
59
|
+
const value = internals.value || '';
|
|
60
|
+
const propertyName = internals.attribute;
|
|
61
|
+
const insensitive = internals.insensitive;
|
|
62
|
+
const prefixProperties = internals.properties;
|
|
63
|
+
return filterAttributes(state, comparator, value, propertyName, insensitive, prefixProperties);
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* :empty Pseudo-Selector, matches only nodes that have no children.
|
|
67
|
+
*/
|
|
68
|
+
const empty = async (state) => {
|
|
69
|
+
for (const node of state.partial.nodes) {
|
|
70
|
+
if (node.edgesOut.size > 0) {
|
|
71
|
+
removeNode(state, node);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return state;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* :has Pseudo-Selector, matches only nodes that have valid results
|
|
78
|
+
* for its nested selector expressions.
|
|
79
|
+
*/
|
|
80
|
+
const has = async (state) => {
|
|
81
|
+
const top = asPostcssNodeWithChildren(state.current);
|
|
82
|
+
const collectNodes = new Set();
|
|
83
|
+
const collectEdges = new Set();
|
|
84
|
+
for (const node of top.nodes) {
|
|
85
|
+
if (isSelectorNode(node)) {
|
|
86
|
+
const nestedState = await state.walk({
|
|
87
|
+
initial: {
|
|
88
|
+
edges: new Set(state.initial.edges),
|
|
89
|
+
nodes: new Set(state.initial.nodes),
|
|
90
|
+
},
|
|
91
|
+
current: node,
|
|
92
|
+
walk: state.walk,
|
|
93
|
+
collect: {
|
|
94
|
+
edges: new Set(),
|
|
95
|
+
nodes: new Set(),
|
|
96
|
+
},
|
|
97
|
+
partial: {
|
|
98
|
+
edges: new Set(state.partial.edges),
|
|
99
|
+
nodes: new Set(state.partial.nodes),
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
for (const n of nestedState.collect.nodes) {
|
|
103
|
+
collectNodes.add(n);
|
|
104
|
+
}
|
|
105
|
+
for (const e of nestedState.partial.edges) {
|
|
106
|
+
collectEdges.add(e);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// if the nested selector did not match anything, that means
|
|
111
|
+
// no current node has any matches
|
|
112
|
+
if (collectNodes.size === 0) {
|
|
113
|
+
state.partial.edges.clear();
|
|
114
|
+
state.partial.nodes.clear();
|
|
115
|
+
return state;
|
|
116
|
+
}
|
|
117
|
+
// handles transitive dependencies
|
|
118
|
+
// compareNodes collects a list of all ancestor nodes
|
|
119
|
+
// from the resulting nodes of the nested selector
|
|
120
|
+
const compareNodes = new Set();
|
|
121
|
+
const traverse = new Set(collectNodes);
|
|
122
|
+
for (const node of traverse) {
|
|
123
|
+
for (const edge of node.edgesIn) {
|
|
124
|
+
compareNodes.add(edge.from);
|
|
125
|
+
if (edge.from.edgesIn.size) {
|
|
126
|
+
traverse.add(edge.from);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// for each node in the current list checks to see if
|
|
131
|
+
// it has a node in the resulting nested state that is
|
|
132
|
+
// a transitive dependency / children.
|
|
133
|
+
nodesLoop: for (const node of state.partial.nodes) {
|
|
134
|
+
if (node.edgesOut.size === 0 || !compareNodes.has(node)) {
|
|
135
|
+
removeNode(state, node);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
for (const edge of node.edgesOut.values()) {
|
|
139
|
+
if (collectEdges.has(edge)) {
|
|
140
|
+
continue nodesLoop;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
removeNode(state, node);
|
|
144
|
+
}
|
|
145
|
+
removeDanglingEdges(state);
|
|
146
|
+
return state;
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* :is Pseudo-selector, acts as a shortcut for writing more compact expressions
|
|
150
|
+
* by allowing multiple nested selectors to match on the previous results.
|
|
151
|
+
*
|
|
152
|
+
* It also enables the loose parsing mode, skipping instead of erroring usage
|
|
153
|
+
* of non-existing classes, identifiers, pseudo-classes, etc.
|
|
154
|
+
*/
|
|
155
|
+
const is = async (state) => {
|
|
156
|
+
const top = asPostcssNodeWithChildren(state.current);
|
|
157
|
+
const collect = new Set();
|
|
158
|
+
for (const node of top.nodes) {
|
|
159
|
+
if (isSelectorNode(node)) {
|
|
160
|
+
const nestedState = await state.walk({
|
|
161
|
+
collect: {
|
|
162
|
+
edges: new Set(),
|
|
163
|
+
nodes: new Set(),
|
|
164
|
+
},
|
|
165
|
+
current: node,
|
|
166
|
+
initial: state.initial,
|
|
167
|
+
loose: true,
|
|
168
|
+
partial: {
|
|
169
|
+
nodes: new Set(state.partial.nodes),
|
|
170
|
+
edges: new Set(state.partial.edges),
|
|
171
|
+
},
|
|
172
|
+
walk: state.walk,
|
|
173
|
+
});
|
|
174
|
+
for (const n of nestedState.collect.nodes) {
|
|
175
|
+
collect.add(n);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
for (const node of state.partial.nodes) {
|
|
180
|
+
if (!collect.has(node)) {
|
|
181
|
+
removeNode(state, node);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return state;
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* :missing Pseudo-Selector, matches only
|
|
188
|
+
* edges that are not linked to any node.
|
|
189
|
+
*/
|
|
190
|
+
const missing = async (state) => {
|
|
191
|
+
for (const edge of state.partial.edges) {
|
|
192
|
+
if (edge.to) {
|
|
193
|
+
state.partial.edges.delete(edge);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
state.partial.nodes.clear();
|
|
197
|
+
return state;
|
|
198
|
+
};
|
|
199
|
+
/**
|
|
200
|
+
* :not Pseudo-class, serves to create negate expressions, anything that
|
|
201
|
+
* matches selectors declared inside the `:not()` expression is going to be
|
|
202
|
+
* filtered out in the final result.
|
|
203
|
+
*/
|
|
204
|
+
const not = async (state) => {
|
|
205
|
+
const top = asPostcssNodeWithChildren(state.current);
|
|
206
|
+
const collect = new Set();
|
|
207
|
+
for (const node of top.nodes) {
|
|
208
|
+
if (isSelectorNode(node)) {
|
|
209
|
+
const nestedState = await state.walk({
|
|
210
|
+
collect: {
|
|
211
|
+
edges: new Set(),
|
|
212
|
+
nodes: new Set(),
|
|
213
|
+
},
|
|
214
|
+
current: node,
|
|
215
|
+
initial: state.initial,
|
|
216
|
+
partial: {
|
|
217
|
+
nodes: new Set(state.partial.nodes),
|
|
218
|
+
edges: new Set(state.partial.edges),
|
|
219
|
+
},
|
|
220
|
+
walk: state.walk,
|
|
221
|
+
});
|
|
222
|
+
for (const n of nestedState.collect.nodes) {
|
|
223
|
+
collect.add(n);
|
|
224
|
+
}
|
|
225
|
+
/* c8 ignore start - should be impossible */
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
throw error('Error parsing :not() selectors', {
|
|
229
|
+
wanted: { type: 'selector' },
|
|
230
|
+
found: node,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
/* c8 ignore stop */
|
|
234
|
+
}
|
|
235
|
+
for (const node of state.partial.nodes) {
|
|
236
|
+
if (collect.has(node)) {
|
|
237
|
+
removeNode(state, node);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return state;
|
|
241
|
+
};
|
|
242
|
+
/**
|
|
243
|
+
* :private Pseudo-Selector will only match packages that have
|
|
244
|
+
* a `private: true` key set in their `package.json` metadata.
|
|
245
|
+
*/
|
|
246
|
+
const privateFn = async (state) => {
|
|
247
|
+
for (const node of state.partial.nodes) {
|
|
248
|
+
if (!node.manifest || !asManifest(node.manifest).private) {
|
|
249
|
+
removeNode(state, node);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
removeDanglingEdges(state);
|
|
253
|
+
return state;
|
|
254
|
+
};
|
|
255
|
+
/**
|
|
256
|
+
* :root Pseudo-Element will return the project root node for the graph.
|
|
257
|
+
*/
|
|
258
|
+
const root = async (state) => {
|
|
259
|
+
const [anyNode] = state.initial.nodes.values();
|
|
260
|
+
const mainImporter = anyNode?.graph.mainImporter;
|
|
261
|
+
if (!mainImporter) {
|
|
262
|
+
throw error(':root pseudo-element works on local graphs only');
|
|
263
|
+
}
|
|
264
|
+
for (const edge of state.partial.edges) {
|
|
265
|
+
if (edge.to !== mainImporter) {
|
|
266
|
+
state.partial.edges.delete(edge);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
state.partial.nodes.clear();
|
|
270
|
+
state.partial.nodes.add(mainImporter);
|
|
271
|
+
return state;
|
|
272
|
+
};
|
|
273
|
+
/**
|
|
274
|
+
* :project Pseudo-Element, returns all graph importers (e.g: the
|
|
275
|
+
* root node along with any configured workspace)
|
|
276
|
+
*/
|
|
277
|
+
const project = async (state) => {
|
|
278
|
+
const [anyNode] = state.initial.nodes.values();
|
|
279
|
+
const importers = anyNode?.graph.importers;
|
|
280
|
+
if (!importers?.size) {
|
|
281
|
+
throw error(':project pseudo-element works on local graphs only');
|
|
282
|
+
}
|
|
283
|
+
// make a list of all edges that are coming from importers
|
|
284
|
+
// so that we can filter out any edges that are not direct
|
|
285
|
+
// dependencies of the importers
|
|
286
|
+
const importersEdgesIn = new Set();
|
|
287
|
+
for (const importer of importers) {
|
|
288
|
+
for (const edge of importer.edgesIn) {
|
|
289
|
+
importersEdgesIn.add(edge);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
for (const edge of state.partial.edges) {
|
|
293
|
+
if (!edge.to || !importersEdgesIn.has(edge)) {
|
|
294
|
+
state.partial.edges.delete(edge);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
state.partial.nodes.clear();
|
|
298
|
+
for (const importer of importers) {
|
|
299
|
+
state.partial.nodes.add(importer);
|
|
300
|
+
}
|
|
301
|
+
return state;
|
|
302
|
+
};
|
|
303
|
+
/**
|
|
304
|
+
* :scope Pseudo-Element, returns the original scope of items
|
|
305
|
+
* at the start of a given selector.
|
|
306
|
+
*/
|
|
307
|
+
const scope = async (state) => {
|
|
308
|
+
state.partial.edges.clear();
|
|
309
|
+
state.partial.nodes.clear();
|
|
310
|
+
for (const edge of state.initial.edges) {
|
|
311
|
+
state.partial.edges.add(edge);
|
|
312
|
+
}
|
|
313
|
+
for (const node of state.initial.nodes) {
|
|
314
|
+
state.partial.nodes.add(node);
|
|
315
|
+
}
|
|
316
|
+
return state;
|
|
317
|
+
};
|
|
318
|
+
/**
|
|
319
|
+
* :type(str) Pseudo-Element will match only nodes that are of
|
|
320
|
+
* the same type as the value used
|
|
321
|
+
*/
|
|
322
|
+
const typeFn = async (state) => {
|
|
323
|
+
const type = asPostcssNodeWithChildren(state.current);
|
|
324
|
+
const selector = asPostcssNodeWithChildren(type.nodes[0]);
|
|
325
|
+
const name = asTagNode(selector.nodes[0]).value;
|
|
326
|
+
for (const node of state.partial.nodes) {
|
|
327
|
+
const nodeType = splitDepID(node.id)[0];
|
|
328
|
+
if (nodeType !== name) {
|
|
329
|
+
removeNode(state, node);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return state;
|
|
333
|
+
};
|
|
334
|
+
const pseudoSelectors = new Map(Object.entries({
|
|
335
|
+
attr,
|
|
336
|
+
empty,
|
|
337
|
+
has,
|
|
338
|
+
is,
|
|
339
|
+
// TODO: link
|
|
340
|
+
missing,
|
|
341
|
+
not,
|
|
342
|
+
// TODO: overridden
|
|
343
|
+
private: privateFn,
|
|
344
|
+
project,
|
|
345
|
+
root,
|
|
346
|
+
scope,
|
|
347
|
+
type: typeFn,
|
|
348
|
+
// TODO: semver
|
|
349
|
+
// TODO: outdated
|
|
350
|
+
}));
|
|
351
|
+
/**
|
|
352
|
+
* Parsers the `pseudo` node types.
|
|
353
|
+
*/
|
|
354
|
+
export const pseudo = async (state) => {
|
|
355
|
+
const curr = asPseudoNode(state.current);
|
|
356
|
+
const parserFn = curr.value && pseudoSelectors.get(curr.value.slice(1));
|
|
357
|
+
if (!parserFn) {
|
|
358
|
+
if (state.loose) {
|
|
359
|
+
return state;
|
|
360
|
+
}
|
|
361
|
+
throw new Error(`Unsupported pseudo-class: ${state.current.value}`);
|
|
362
|
+
}
|
|
363
|
+
return parserFn(state);
|
|
364
|
+
};
|
|
365
|
+
//# sourceMappingURL=pseudo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pseudo.js","sourceRoot":"","sources":["../../src/pseudo.ts"],"names":[],"mappings":"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","sourcesContent":["import { splitDepID } from '@vltpkg/dep-id/browser'\nimport { error } from '@vltpkg/error-cause'\nimport type { EdgeLike, NodeLike } from '@vltpkg/graph'\nimport { asManifest } from '@vltpkg/types'\nimport {\n attributeSelectorsMap,\n filterAttributes,\n} from './attribute.js'\nimport {\n asAttributeNode,\n asPostcssNodeWithChildren,\n asPseudoNode,\n asTagNode,\n isSelectorNode,\n ParserFn,\n ParserState,\n PostcssNode,\n} from './types.js'\n\nexport type AttrInternals = {\n attribute: string\n insensitive: boolean\n operator?: string\n value?: string\n properties: string[]\n}\n\nconst removeNode = (state: ParserState, node: NodeLike) => {\n for (const edge of node.edgesIn) {\n state.partial.edges.delete(edge)\n }\n state.partial.nodes.delete(node)\n}\n\nconst removeDanglingEdges = (state: ParserState) => {\n for (const edge of state.partial.edges) {\n if (!edge.to) {\n state.partial.edges.delete(edge)\n }\n }\n}\n\n/**\n * Parses the internal / nested selectors of a `:attr` selector.\n */\nconst parseAttrInternals = (nodes: PostcssNode[]): AttrInternals => {\n // the last part is the attribute selector\n const attributeSelector = asAttributeNode(\n asPostcssNodeWithChildren(nodes.pop()).nodes[0],\n )\n // all preppending selectors are naming nested properties\n const properties: string[] = []\n for (const selector of nodes) {\n properties.push(\n asTagNode(asPostcssNodeWithChildren(selector).nodes[0]).value,\n )\n }\n // include the attribute selector as the last part of the property lookup\n properties.push(attributeSelector.attribute)\n\n return {\n attribute: attributeSelector.attribute,\n insensitive: attributeSelector.insensitive || false,\n operator: attributeSelector.operator,\n value: attributeSelector.value,\n properties,\n }\n}\n\n/**\n * :attr Pseudo-Selector, allows for retrieving nodes based on nested\n * properties of the `package.json` metadata.\n */\nconst attr = async (state: ParserState) => {\n // Parses and retrieves the values for the nested selectors\n let internals\n try {\n internals = parseAttrInternals(\n asPostcssNodeWithChildren(state.current).nodes,\n )\n } catch (err) {\n throw error('Failed to parse :attr selector', {\n cause: err as Error,\n })\n }\n\n // reuses the attribute selector logic to filter the nodes\n const comparator =\n internals.operator ?\n attributeSelectorsMap.get(internals.operator)\n : undefined\n const value = internals.value || ''\n const propertyName = internals.attribute\n const insensitive = internals.insensitive\n const prefixProperties = internals.properties\n return filterAttributes(\n state,\n comparator,\n value,\n propertyName,\n insensitive,\n prefixProperties,\n )\n}\n/**\n * :empty Pseudo-Selector, matches only nodes that have no children.\n */\nconst empty = async (state: ParserState) => {\n for (const node of state.partial.nodes) {\n if (node.edgesOut.size > 0) {\n removeNode(state, node)\n }\n }\n return state\n}\n\n/**\n * :has Pseudo-Selector, matches only nodes that have valid results\n * for its nested selector expressions.\n */\nconst has = async (state: ParserState) => {\n const top = asPostcssNodeWithChildren(state.current)\n const collectNodes = new Set<NodeLike>()\n const collectEdges = new Set<EdgeLike>()\n\n for (const node of top.nodes) {\n if (isSelectorNode(node)) {\n const nestedState = await state.walk({\n initial: {\n edges: new Set(state.initial.edges),\n nodes: new Set(state.initial.nodes),\n },\n current: node,\n walk: state.walk,\n collect: {\n edges: new Set(),\n nodes: new Set(),\n },\n partial: {\n edges: new Set(state.partial.edges),\n nodes: new Set(state.partial.nodes),\n },\n })\n for (const n of nestedState.collect.nodes) {\n collectNodes.add(n)\n }\n for (const e of nestedState.partial.edges) {\n collectEdges.add(e)\n }\n }\n }\n\n // if the nested selector did not match anything, that means\n // no current node has any matches\n if (collectNodes.size === 0) {\n state.partial.edges.clear()\n state.partial.nodes.clear()\n return state\n }\n\n // handles transitive dependencies\n // compareNodes collects a list of all ancestor nodes\n // from the resulting nodes of the nested selector\n const compareNodes = new Set<NodeLike>()\n const traverse = new Set(collectNodes)\n for (const node of traverse) {\n for (const edge of node.edgesIn) {\n compareNodes.add(edge.from)\n if (edge.from.edgesIn.size) {\n traverse.add(edge.from)\n }\n }\n }\n\n // for each node in the current list checks to see if\n // it has a node in the resulting nested state that is\n // a transitive dependency / children.\n nodesLoop: for (const node of state.partial.nodes) {\n if (node.edgesOut.size === 0 || !compareNodes.has(node)) {\n removeNode(state, node)\n continue\n }\n\n for (const edge of node.edgesOut.values()) {\n if (collectEdges.has(edge)) {\n continue nodesLoop\n }\n }\n removeNode(state, node)\n }\n\n removeDanglingEdges(state)\n\n return state\n}\n\n/**\n * :is Pseudo-selector, acts as a shortcut for writing more compact expressions\n * by allowing multiple nested selectors to match on the previous results.\n *\n * It also enables the loose parsing mode, skipping instead of erroring usage\n * of non-existing classes, identifiers, pseudo-classes, etc.\n */\nconst is = async (state: ParserState) => {\n const top = asPostcssNodeWithChildren(state.current)\n const collect = new Set()\n for (const node of top.nodes) {\n if (isSelectorNode(node)) {\n const nestedState = await state.walk({\n collect: {\n edges: new Set(),\n nodes: new Set(),\n },\n current: node,\n initial: state.initial,\n loose: true,\n partial: {\n nodes: new Set(state.partial.nodes),\n edges: new Set(state.partial.edges),\n },\n walk: state.walk,\n })\n for (const n of nestedState.collect.nodes) {\n collect.add(n)\n }\n }\n }\n for (const node of state.partial.nodes) {\n if (!collect.has(node)) {\n removeNode(state, node)\n }\n }\n return state\n}\n\n/**\n * :missing Pseudo-Selector, matches only\n * edges that are not linked to any node.\n */\nconst missing = async (state: ParserState) => {\n for (const edge of state.partial.edges) {\n if (edge.to) {\n state.partial.edges.delete(edge)\n }\n }\n state.partial.nodes.clear()\n return state\n}\n\n/**\n * :not Pseudo-class, serves to create negate expressions, anything that\n * matches selectors declared inside the `:not()` expression is going to be\n * filtered out in the final result.\n */\nconst not = async (state: ParserState) => {\n const top = asPostcssNodeWithChildren(state.current)\n const collect = new Set()\n for (const node of top.nodes) {\n if (isSelectorNode(node)) {\n const nestedState = await state.walk({\n collect: {\n edges: new Set(),\n nodes: new Set(),\n },\n current: node,\n initial: state.initial,\n partial: {\n nodes: new Set(state.partial.nodes),\n edges: new Set(state.partial.edges),\n },\n walk: state.walk,\n })\n for (const n of nestedState.collect.nodes) {\n collect.add(n)\n }\n /* c8 ignore start - should be impossible */\n } else {\n throw error('Error parsing :not() selectors', {\n wanted: { type: 'selector' },\n found: node,\n })\n }\n /* c8 ignore stop */\n }\n for (const node of state.partial.nodes) {\n if (collect.has(node)) {\n removeNode(state, node)\n }\n }\n return state\n}\n\n/**\n * :private Pseudo-Selector will only match packages that have\n * a `private: true` key set in their `package.json` metadata.\n */\nconst privateFn = async (state: ParserState) => {\n for (const node of state.partial.nodes) {\n if (!node.manifest || !asManifest(node.manifest).private) {\n removeNode(state, node)\n }\n }\n\n removeDanglingEdges(state)\n\n return state\n}\n\n/**\n * :root Pseudo-Element will return the project root node for the graph.\n */\nconst root = async (state: ParserState) => {\n const [anyNode] = state.initial.nodes.values()\n const mainImporter = anyNode?.graph.mainImporter\n if (!mainImporter) {\n throw error(':root pseudo-element works on local graphs only')\n }\n for (const edge of state.partial.edges) {\n if (edge.to !== mainImporter) {\n state.partial.edges.delete(edge)\n }\n }\n state.partial.nodes.clear()\n state.partial.nodes.add(mainImporter)\n return state\n}\n\n/**\n * :project Pseudo-Element, returns all graph importers (e.g: the\n * root node along with any configured workspace)\n */\nconst project = async (state: ParserState) => {\n const [anyNode] = state.initial.nodes.values()\n const importers = anyNode?.graph.importers\n if (!importers?.size) {\n throw error(':project pseudo-element works on local graphs only')\n }\n\n // make a list of all edges that are coming from importers\n // so that we can filter out any edges that are not direct\n // dependencies of the importers\n const importersEdgesIn = new Set<EdgeLike>()\n for (const importer of importers) {\n for (const edge of importer.edgesIn) {\n importersEdgesIn.add(edge)\n }\n }\n\n for (const edge of state.partial.edges) {\n if (!edge.to || !importersEdgesIn.has(edge)) {\n state.partial.edges.delete(edge)\n }\n }\n state.partial.nodes.clear()\n for (const importer of importers) {\n state.partial.nodes.add(importer)\n }\n return state\n}\n\n/**\n * :scope Pseudo-Element, returns the original scope of items\n * at the start of a given selector.\n */\nconst scope = async (state: ParserState) => {\n state.partial.edges.clear()\n state.partial.nodes.clear()\n for (const edge of state.initial.edges) {\n state.partial.edges.add(edge)\n }\n for (const node of state.initial.nodes) {\n state.partial.nodes.add(node)\n }\n return state\n}\n\n/**\n * :type(str) Pseudo-Element will match only nodes that are of\n * the same type as the value used\n */\nconst typeFn = async (state: ParserState) => {\n const type = asPostcssNodeWithChildren(state.current)\n const selector = asPostcssNodeWithChildren(type.nodes[0])\n const name = asTagNode(selector.nodes[0]).value\n for (const node of state.partial.nodes) {\n const nodeType = splitDepID(node.id)[0]\n if (nodeType !== name) {\n removeNode(state, node)\n }\n }\n return state\n}\n\nconst pseudoSelectors = new Map<string, ParserFn>(\n Object.entries({\n attr,\n empty,\n has,\n is,\n // TODO: link\n missing,\n not,\n // TODO: overridden\n private: privateFn,\n project,\n root,\n scope,\n type: typeFn,\n // TODO: semver\n // TODO: outdated\n }),\n)\n\n/**\n * Parsers the `pseudo` node types.\n */\nexport const pseudo = async (state: ParserState) => {\n const curr = asPseudoNode(state.current)\n const parserFn =\n curr.value && pseudoSelectors.get(curr.value.slice(1))\n\n if (!parserFn) {\n if (state.loose) {\n return state\n }\n\n throw new Error(\n `Unsupported pseudo-class: ${state.current.value}`,\n )\n }\n return parserFn(state)\n}\n"]}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { EdgeLike, NodeLike } from '@vltpkg/graph';
|
|
2
|
+
import type { Tag, String, Selector, Root, Pseudo, Nesting, Identifier, Comment, Combinator, ClassName, Attribute, Universal } from 'postcss-selector-parser';
|
|
3
|
+
export type PostcssNode = Tag | String | Selector | Root | Pseudo | Nesting | Identifier | Comment | Combinator | ClassName | Attribute | Universal;
|
|
4
|
+
export type PostcssNodeWithChildren = Selector | Root | Pseudo;
|
|
5
|
+
export type GraphSelectionState = {
|
|
6
|
+
nodes: Set<NodeLike>;
|
|
7
|
+
edges: Set<EdgeLike>;
|
|
8
|
+
};
|
|
9
|
+
export type ParserState = {
|
|
10
|
+
collect: GraphSelectionState;
|
|
11
|
+
current: PostcssNode;
|
|
12
|
+
initial: GraphSelectionState;
|
|
13
|
+
loose?: boolean;
|
|
14
|
+
next?: PostcssNode;
|
|
15
|
+
prev?: PostcssNode;
|
|
16
|
+
result?: NodeLike[];
|
|
17
|
+
walk: ParserFn;
|
|
18
|
+
partial: GraphSelectionState;
|
|
19
|
+
};
|
|
20
|
+
export type QueryResponse = {
|
|
21
|
+
edges: EdgeLike[];
|
|
22
|
+
nodes: NodeLike[];
|
|
23
|
+
};
|
|
24
|
+
export type ParserFn = (opt: ParserState) => Promise<ParserState>;
|
|
25
|
+
export declare const isPostcssNodeWithChildren: (node: any) => node is PostcssNodeWithChildren;
|
|
26
|
+
export declare const asPostcssNodeWithChildren: (node?: PostcssNode) => PostcssNodeWithChildren;
|
|
27
|
+
export declare const isAttributeNode: (node: any) => node is Attribute;
|
|
28
|
+
export declare const asAttributeNode: (node?: PostcssNode) => Attribute;
|
|
29
|
+
export declare const isClassNode: (node: any) => node is ClassName;
|
|
30
|
+
export declare const asClassNode: (node?: PostcssNode) => ClassName;
|
|
31
|
+
export declare const isCombinatorNode: (node: any) => node is Combinator;
|
|
32
|
+
export declare const asCombinatorNode: (node?: PostcssNode) => Combinator;
|
|
33
|
+
export declare const isIdentifierNode: (node: any) => node is Identifier;
|
|
34
|
+
export declare const asIdentifierNode: (node?: PostcssNode) => Identifier;
|
|
35
|
+
export declare const isSelectorNode: (node: any) => node is Selector;
|
|
36
|
+
export declare const isPseudoNode: (node: any) => node is Pseudo;
|
|
37
|
+
export declare const asPseudoNode: (node?: PostcssNode) => Pseudo;
|
|
38
|
+
export declare const isTagNode: (node: any) => node is Tag;
|
|
39
|
+
export declare const asTagNode: (node?: PostcssNode) => Tag;
|
|
40
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACvD,OAAO,KAAK,EACV,GAAG,EACH,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,OAAO,EACP,UAAU,EACV,OAAO,EACP,UAAU,EACV,SAAS,EACT,SAAS,EACT,SAAS,EACV,MAAM,yBAAyB,CAAA;AAEhC,MAAM,MAAM,WAAW,GACnB,GAAG,GACH,MAAM,GACN,QAAQ,GACR,IAAI,GACJ,MAAM,GACN,OAAO,GACP,UAAU,GACV,OAAO,GACP,UAAU,GACV,SAAS,GACT,SAAS,GACT,SAAS,CAAA;AAEb,MAAM,MAAM,uBAAuB,GAAG,QAAQ,GAAG,IAAI,GAAG,MAAM,CAAA;AAE9D,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAA;IACpB,KAAK,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,mBAAmB,CAAA;IAC5B,OAAO,EAAE,WAAW,CAAA;IACpB,OAAO,EAAE,mBAAmB,CAAA;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,IAAI,CAAC,EAAE,WAAW,CAAA;IAClB,IAAI,CAAC,EAAE,WAAW,CAAA;IAClB,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAA;IACnB,IAAI,EAAE,QAAQ,CAAA;IACd,OAAO,EAAE,mBAAmB,CAAA;CAC7B,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,QAAQ,EAAE,CAAA;IACjB,KAAK,EAAE,QAAQ,EAAE,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,WAAW,CAAC,CAAA;AAEjE,eAAO,MAAM,yBAAyB,SAC9B,GAAG,KACR,IAAI,IAAI,uBACwB,CAAA;AAEnC,eAAO,MAAM,yBAAyB,UAC7B,WAAW,KACjB,uBAWF,CAAA;AAED,eAAO,MAAM,eAAe,SAAU,GAAG,KAAG,IAAI,IAAI,SACP,CAAA;AAE7C,eAAO,MAAM,eAAe,UAAW,WAAW,KAAG,SAYpD,CAAA;AAED,eAAO,MAAM,WAAW,SAAU,GAAG,KAAG,IAAI,IAAI,SACX,CAAA;AAErC,eAAO,MAAM,WAAW,UAAW,WAAW,KAAG,SAYhD,CAAA;AAED,eAAO,MAAM,gBAAgB,SAAU,GAAG,KAAG,IAAI,IAAI,UACX,CAAA;AAE1C,eAAO,MAAM,gBAAgB,UAAW,WAAW,KAAG,UAYrD,CAAA;AAED,eAAO,MAAM,gBAAgB,SAAU,GAAG,KAAG,IAAI,IAAI,UACnB,CAAA;AAElC,eAAO,MAAM,gBAAgB,UAAW,WAAW,KAAG,UAYrD,CAAA;AAED,eAAO,MAAM,cAAc,SAAU,GAAG,KAAG,IAAI,IAAI,QACU,CAAA;AAE7D,eAAO,MAAM,YAAY,SAAU,GAAG,KAAG,IAAI,IAAI,MACX,CAAA;AAEtC,eAAO,MAAM,YAAY,UAAW,WAAW,KAAG,MAYjD,CAAA;AAED,eAAO,MAAM,SAAS,SAAU,GAAG,KAAG,IAAI,IAAI,GACX,CAAA;AAEnC,eAAO,MAAM,SAAS,UAAW,WAAW,KAAG,GAa9C,CAAA"}
|