@mark1russell7/strategy-space 0.0.0-stage → 0.0.2
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 +21 -0
- package/README.md +51 -2
- package/build/claim.d.ts +10 -0
- package/build/claim.d.ts.map +1 -0
- package/build/distinct.d.ts +49 -0
- package/build/distinct.d.ts.map +1 -0
- package/build/distinct.js +61 -0
- package/build/distinct.js.map +1 -0
- package/build/index.d.ts +7 -0
- package/build/index.js +6 -0
- package/build/operators.d.ts +55 -0
- package/build/operators.d.ts.map +1 -0
- package/build/operators.js +95 -0
- package/build/operators.js.map +1 -0
- package/build/space-walk.js +48 -0
- package/build/space-walk.js.map +1 -0
- package/build/strategy-options.d.ts +189 -0
- package/build/strategy-options.d.ts.map +1 -0
- package/build/strategy-options.js +211 -0
- package/build/strategy-options.js.map +1 -0
- package/build/strategy-space.d.ts +261 -0
- package/build/strategy-space.d.ts.map +1 -0
- package/build/strategy-space.js +1034 -0
- package/build/strategy-space.js.map +1 -0
- package/build/terms.d.ts +89 -0
- package/build/terms.d.ts.map +1 -0
- package/build/terms.js +256 -0
- package/build/terms.js.map +1 -0
- package/package.json +60 -3
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { ClaimBreak } from "./claim.js";
|
|
2
|
+
/** The schema of a strategy space. */
|
|
3
|
+
export declare const STRATEGY_SPACE_SCHEMA = "strategy-space/1";
|
|
4
|
+
/** The kind of a param: a whole number, a real number, one value of a list, or `true` and `false`. */
|
|
5
|
+
export type ParamKind = "int" | "real" | "enum" | "bool";
|
|
6
|
+
/** The value of one param in a config. */
|
|
7
|
+
export type ParamValue = number | string | boolean;
|
|
8
|
+
/** The condition of a conditional param: the param is active only when an earlier param of the same option has one of the values `in`. */
|
|
9
|
+
export interface ParamWhen {
|
|
10
|
+
/** The name of an earlier param of the same option. */
|
|
11
|
+
readonly param: string;
|
|
12
|
+
/** The values of that param that make this param active. */
|
|
13
|
+
readonly in: readonly ParamValue[];
|
|
14
|
+
}
|
|
15
|
+
/** One param of a stage option, with its range. */
|
|
16
|
+
export interface SpaceParam {
|
|
17
|
+
readonly name: string;
|
|
18
|
+
readonly kind: ParamKind;
|
|
19
|
+
/** The smallest value of an `int` or `real` param. */
|
|
20
|
+
readonly min?: number;
|
|
21
|
+
/** The largest value of an `int` or `real` param. */
|
|
22
|
+
readonly max?: number;
|
|
23
|
+
/** The step of the values from `min`. An `int` param has the step 1 by default. */
|
|
24
|
+
readonly step?: number;
|
|
25
|
+
/** The scale of the grid and of the samples. The scale `log` needs a `min` above 0. The default is `linear`. */
|
|
26
|
+
readonly scale?: "linear" | "log";
|
|
27
|
+
/** The values of an `enum` param. */
|
|
28
|
+
readonly values?: readonly (string | number)[];
|
|
29
|
+
/** The value that a config gets when it does not set the param. */
|
|
30
|
+
readonly default: ParamValue;
|
|
31
|
+
/** Without `when`, the param is active each time its option is chosen. */
|
|
32
|
+
readonly when?: ParamWhen;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The rule of the members of a meta option: a count from `min` to `max`. Members with `ordered: false` are sorted by their `configId`.
|
|
36
|
+
* With `min` and `max` 0, the option chooses its members from the input, so a config lists none. This form has no `pool` and no `view`.
|
|
37
|
+
*/
|
|
38
|
+
export interface MemberRule {
|
|
39
|
+
readonly min: number;
|
|
40
|
+
readonly max: number;
|
|
41
|
+
readonly ordered: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* The member lists that the option permits. Each entry is a list of whole configs of the space of the members.
|
|
44
|
+
* Without `pool`, each list of base configs with a good count is a member list.
|
|
45
|
+
* With `pool`, a config of the option has the members of one entry, and `spaceSize` counts each entry one time.
|
|
46
|
+
*/
|
|
47
|
+
readonly pool?: readonly (readonly StrategyConfig[])[];
|
|
48
|
+
/**
|
|
49
|
+
* The view of the items that the members get. With `bounds`, the option gives its members the bounding box of each item.
|
|
50
|
+
* Then a shape filter checks the members with the kind `rect`, and the option itself with the kinds of the input. Without `view`, the members get the kinds of the input.
|
|
51
|
+
*/
|
|
52
|
+
readonly view?: "bounds";
|
|
53
|
+
/**
|
|
54
|
+
* With `true`, the option only chooses the output of one member, for example the best member by a score. It does not change that output.
|
|
55
|
+
* Such an option needs no operator. A meta option that changes the output of its members, for example a search over their layouts, is an operator.
|
|
56
|
+
*/
|
|
57
|
+
readonly chooses?: boolean;
|
|
58
|
+
}
|
|
59
|
+
/** The inputs that an option supports. A missing field supports each value. */
|
|
60
|
+
export interface OptionSupports {
|
|
61
|
+
/** The shape kinds of the boxes, as tags (for example `rect` or `circle`). Without it, the option supports each kind. */
|
|
62
|
+
readonly shape?: readonly string[];
|
|
63
|
+
}
|
|
64
|
+
/** One implementation of a stage. An option with `members` is a meta option: it chooses between whole configs, or wraps them. */
|
|
65
|
+
export interface StageOption {
|
|
66
|
+
readonly id: string;
|
|
67
|
+
readonly params: readonly SpaceParam[];
|
|
68
|
+
readonly members?: MemberRule;
|
|
69
|
+
/** The inputs that the option supports. It describes the option, so it is not part of a config or of its id. */
|
|
70
|
+
readonly supports?: OptionSupports;
|
|
71
|
+
/**
|
|
72
|
+
* With `true`, the option gives its input with no change, for example the order of the input or no local search. It needs no operator.
|
|
73
|
+
* An identity option has no params and no members. The field describes the option, so it is not part of a config or of its id.
|
|
74
|
+
*/
|
|
75
|
+
readonly identity?: boolean;
|
|
76
|
+
}
|
|
77
|
+
/** The known shape kinds of a check. Without `kinds`, each string that is not empty is a shape kind. */
|
|
78
|
+
export interface KindOptions {
|
|
79
|
+
/** The list of the known shape kinds, for example `SHAPE_KIND_IDS` of `layout-contract`. A kind that is not in the list is a problem. */
|
|
80
|
+
readonly kinds?: readonly string[];
|
|
81
|
+
}
|
|
82
|
+
/** The shape kinds of the inputs of a check, a count or an enumeration. Without `shapes`, each option counts. */
|
|
83
|
+
export interface ShapeFilter extends KindOptions {
|
|
84
|
+
/** The shape kinds of the input. Only the options that support each of these kinds count. */
|
|
85
|
+
readonly shapes?: readonly string[];
|
|
86
|
+
}
|
|
87
|
+
/** One stage of the pipeline of an engine. A config of an `optional` stage can have no option. */
|
|
88
|
+
export interface SpaceStage {
|
|
89
|
+
readonly name: string;
|
|
90
|
+
readonly options: readonly StageOption[];
|
|
91
|
+
readonly optional?: boolean;
|
|
92
|
+
}
|
|
93
|
+
/** A reference to one option of a stage. The option `null` refers to an optional stage that a config does not use. */
|
|
94
|
+
export interface OptionRef {
|
|
95
|
+
readonly stage: string;
|
|
96
|
+
readonly option: string | null;
|
|
97
|
+
}
|
|
98
|
+
/** A rule that keeps out invalid combinations. A config with the option `if` also has the option `then`, or does not have the option `then.not`. */
|
|
99
|
+
export interface SpaceConstraint {
|
|
100
|
+
readonly if: OptionRef;
|
|
101
|
+
readonly then: OptionRef | {
|
|
102
|
+
readonly not: OptionRef;
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/** The strategy space of an engine: the stages, the constraints and the named configs. `docs/STRATEGY-SPACE.md` tells the rules. */
|
|
106
|
+
export interface StrategySpace {
|
|
107
|
+
readonly schema: typeof STRATEGY_SPACE_SCHEMA;
|
|
108
|
+
/** The name of the space. A config names the space with this value. */
|
|
109
|
+
readonly engine: string;
|
|
110
|
+
/** The version of the space. It is not part of a config or of its id. A record writes it. */
|
|
111
|
+
readonly version: string;
|
|
112
|
+
readonly stages: readonly SpaceStage[];
|
|
113
|
+
readonly constraints?: readonly SpaceConstraint[];
|
|
114
|
+
/** The named strategies of the engine, as points of the space. Old records stay comparable through them. */
|
|
115
|
+
readonly named?: Readonly<Record<string, StrategyConfig>>;
|
|
116
|
+
/** The spaces of a product space, from `productSpace`. A meta option of a part takes members of that part. */
|
|
117
|
+
readonly parts?: readonly StrategySpace[];
|
|
118
|
+
}
|
|
119
|
+
/** The choice of one stage in a config: an option, its params and, for a meta option, its members. */
|
|
120
|
+
export interface StageChoice {
|
|
121
|
+
readonly option: string;
|
|
122
|
+
/** The values of the active params. A param that is not set gets its default. */
|
|
123
|
+
readonly params?: Readonly<Record<string, ParamValue>>;
|
|
124
|
+
/** The members of a meta option: configs of the same space, with no meta option. */
|
|
125
|
+
readonly members?: readonly StrategyConfig[];
|
|
126
|
+
}
|
|
127
|
+
/** One point of a strategy space. The value `null` of a stage tells that the config does not use the optional stage. */
|
|
128
|
+
export interface StrategyConfig {
|
|
129
|
+
/** The `engine` of the space, without its version. */
|
|
130
|
+
readonly space: string;
|
|
131
|
+
readonly stages: Readonly<Record<string, StageChoice | null>>;
|
|
132
|
+
}
|
|
133
|
+
/** The count of the grid points of a space. */
|
|
134
|
+
export interface SpaceSize {
|
|
135
|
+
/** The count of the configs without a meta option. */
|
|
136
|
+
readonly base: bigint;
|
|
137
|
+
/** The count of the configs with a meta option. The value is `null` when the count is more than `maxMeta`. */
|
|
138
|
+
readonly meta: bigint | null;
|
|
139
|
+
}
|
|
140
|
+
/** The options of `spaceSize`. */
|
|
141
|
+
export interface SpaceSizeOptions extends ShapeFilter {
|
|
142
|
+
/** The count of the levels of each numeric param, a whole number of 1 or more. */
|
|
143
|
+
readonly levels: number;
|
|
144
|
+
/** The largest meta count that `spaceSize` gives. The default is `10n ** 18n`. */
|
|
145
|
+
readonly maxMeta?: bigint;
|
|
146
|
+
}
|
|
147
|
+
/** The options of a grid. The grid gives only the configs without a meta option. */
|
|
148
|
+
export interface GridOptions extends ShapeFilter {
|
|
149
|
+
readonly mode: "grid";
|
|
150
|
+
readonly levels: number;
|
|
151
|
+
/** The largest count of configs. A larger grid causes a `RangeError`. The default is 100000. */
|
|
152
|
+
readonly limit?: number;
|
|
153
|
+
}
|
|
154
|
+
/** The options of a sample. */
|
|
155
|
+
export interface SampleOptions extends ShapeFilter {
|
|
156
|
+
readonly mode: "sample";
|
|
157
|
+
/** The count of the configs, a whole number of 0 or more. */
|
|
158
|
+
readonly n: number;
|
|
159
|
+
readonly seed: number;
|
|
160
|
+
/** With `skip` (the default), the sample has no meta option. With `sample`, a meta option draws its members from base samples, or one entry of its `pool`. */
|
|
161
|
+
readonly meta?: "skip" | "sample";
|
|
162
|
+
/** The largest count of option draws. The default is the larger value of 1000 and `100 * n`. */
|
|
163
|
+
readonly maxTries?: number;
|
|
164
|
+
/**
|
|
165
|
+
* How a point keeps the constraints. With `reject` (the default), a point that breaks a constraint draws again.
|
|
166
|
+
* With `walk`, a point draws its stages from the largest to the smallest. Each stage draws only from the options that keep the constraints with the stages before it.
|
|
167
|
+
* The stages of `fixed` draw before the other stages.
|
|
168
|
+
* A space whose constraints reject most draws gets its sample with `walk`. The two values give different configs for one seed.
|
|
169
|
+
* A sample of `walk` is not uniform over the valid configs. Each option of the largest stage gets an equal share, whatever count of valid configs it has.
|
|
170
|
+
* Thus a mean over this sample is not a mean of the space.
|
|
171
|
+
*/
|
|
172
|
+
readonly draw?: "reject" | "walk";
|
|
173
|
+
/**
|
|
174
|
+
* The options that each config of the sample has. A key is the name of a stage, and its value is the id of one option of that stage. The other stages draw as before.
|
|
175
|
+
* A stage of a product space has the name of its part before its own name, for example `pack.placement`.
|
|
176
|
+
* A fixed meta option needs `meta: "sample"`. A meta option of another stage of the same part goes out, because such an option replaces the fixed stage.
|
|
177
|
+
* A fixed option that the shape filter removes, or that the constraints forbid, gets a `RangeError` with the reason.
|
|
178
|
+
*/
|
|
179
|
+
readonly fixed?: Readonly<Record<string, string>>;
|
|
180
|
+
}
|
|
181
|
+
/** The options of `enumerateSpace`. */
|
|
182
|
+
export type EnumerateOptions = GridOptions | SampleOptions;
|
|
183
|
+
/** This function gives the problem of a value of a param, or `undefined` for a value in its range. The corpus dimensions of `families.ts` use it. */
|
|
184
|
+
export declare function paramProblem(param: SpaceParam, value: unknown): string | undefined;
|
|
185
|
+
/** This function tells if a param is active for the values of the earlier params. A param without `when` is always active. */
|
|
186
|
+
export declare function paramActive(param: SpaceParam, values: Readonly<Record<string, ParamValue>>): boolean;
|
|
187
|
+
/** This function gives the stable form of a value of a param: a real number gets 12 significant digits, and `-0` becomes `0`. */
|
|
188
|
+
export declare function paramValue(param: SpaceParam, value: ParamValue): ParamValue;
|
|
189
|
+
/**
|
|
190
|
+
* This function checks one config of a space. It gives one break for each problem. An empty list tells that the config is good.
|
|
191
|
+
* The `claim` of a break is the kind of the problem, for example `missing`, `unknown`, `inactive`, `param`, `constraint`, `members` or `depth`.
|
|
192
|
+
*
|
|
193
|
+
* A member list that is not an entry of the `pool` of its option gives the claim `pool`.
|
|
194
|
+
* With `shapes`, an option that does not support a kind of the list gives the claim `shape`. A member of a meta option gets the same check.
|
|
195
|
+
* A member of an option with `view: "bounds"` gets the check with the kind `rect`.
|
|
196
|
+
*/
|
|
197
|
+
export declare function checkConfig(space: StrategySpace, config: StrategyConfig, options?: ShapeFilter): ClaimBreak[];
|
|
198
|
+
/**
|
|
199
|
+
* This function checks a space. It gives one break for each problem. An empty list tells that the space is good.
|
|
200
|
+
* It finds duplicate names, empty ranges, defaults out of range, enums without values, bad log scales, unknown names and bad named configs.
|
|
201
|
+
* It also checks each entry of a `pool`: the count of its members, each member and a repeated entry.
|
|
202
|
+
* The `inputs` of a break of a named config have the name of the config.
|
|
203
|
+
* With `kinds`, a shape kind of a `supports` that is not in the list gives the claim `shape`.
|
|
204
|
+
*/
|
|
205
|
+
export declare function checkSpace(space: StrategySpace, kindOptions?: KindOptions): ClaimBreak[];
|
|
206
|
+
/**
|
|
207
|
+
* This function gives the canonical form of a config: each stage of the space, the active params only, the defaults, and stable numbers.
|
|
208
|
+
* An unused optional stage is `null`. The members of an unordered meta option are sorted by their `configId`.
|
|
209
|
+
* It throws an `Error` for a config with a break of `checkConfig`.
|
|
210
|
+
*/
|
|
211
|
+
export declare function canonicalConfig(space: StrategySpace, config: StrategyConfig): StrategyConfig;
|
|
212
|
+
/**
|
|
213
|
+
* This function gives the id of a config: the first 16 hex characters of the SHA-256 of `canonicalJson` of `canonicalConfig`.
|
|
214
|
+
* Two spellings of one config get one id. The version of the space is not part of the id.
|
|
215
|
+
*/
|
|
216
|
+
export declare function configId(space: StrategySpace, config: StrategyConfig): string;
|
|
217
|
+
/**
|
|
218
|
+
* This function gives the grid values of one param, in increasing order. An `enum` gives its values, and a `bool` gives `false` and `true`.
|
|
219
|
+
* With 1 level, a numeric param gives its default. With k levels, it gives k points from `min` to `max` on its scale and step, without repeats.
|
|
220
|
+
*/
|
|
221
|
+
export declare function paramLevels(param: SpaceParam, levels: number): ParamValue[];
|
|
222
|
+
/**
|
|
223
|
+
* This function gives the count of the grid points of a space, with `levels` levels for each numeric param.
|
|
224
|
+
* It counts only the active params and the combinations that keep the constraints. It gives the meta configs apart.
|
|
225
|
+
* A meta option with a `pool` counts each entry of the pool one time.
|
|
226
|
+
* With `shapes`, it counts only the options that support each kind of the list.
|
|
227
|
+
*/
|
|
228
|
+
export declare function spaceSize(space: StrategySpace, options: SpaceSizeOptions): SpaceSize;
|
|
229
|
+
/**
|
|
230
|
+
* This function gives configs of a space, in their canonical form. Each config keeps the constraints. The result is deterministic.
|
|
231
|
+
*
|
|
232
|
+
* - The mode `grid` gives each grid point without a meta option, in a stable order. Stages, options and values go in the order of the space.
|
|
233
|
+
* - The mode `sample` gives `n` configs of a seeded Latin hypercube. The options of a stage get equal strata, and each active param gets its own strata.
|
|
234
|
+
* - A sample draws again when a point breaks a constraint. After `maxTries` draws, it throws an `Error`. Two sampled configs can be equal.
|
|
235
|
+
* - With `draw: "walk"`, each stage draws only from the options that keep the constraints with the stages before it. The largest stage keeps its equal strata.
|
|
236
|
+
* - With `shapes`, only the options that support each kind of the list count. Without `shapes`, the result does not change.
|
|
237
|
+
* - A meta option with a `pool` gives only the entries of its pool. With `shapes`, only the entries whose members support each kind count.
|
|
238
|
+
* - A sample draws again when a point chooses a meta option without a member list. `spaceSize` gives such an option 0.
|
|
239
|
+
* - With `shapes`, a sample throws a `RangeError` when the space has no config for the kinds. The error names the stages without an option and the meta options without members.
|
|
240
|
+
* - With `fixed`, each config has the fixed option at each named stage. A fixed option that the space, the shape filter or the constraints do not permit gets a `RangeError` with the reason.
|
|
241
|
+
*/
|
|
242
|
+
export declare function enumerateSpace(space: StrategySpace, options: EnumerateOptions): StrategyConfig[];
|
|
243
|
+
/**
|
|
244
|
+
* This function gives the shape kinds that a space accepts. The value comes from the `supports` of the options.
|
|
245
|
+
* A space accepts a kind when it has at least one config without a meta option on that kind.
|
|
246
|
+
* With `kinds`, it examines the kinds of that list, in its order. Without `kinds`, it examines the kinds that the `supports` of the space name, in the order of their first use.
|
|
247
|
+
*/
|
|
248
|
+
export declare function spaceShapeKinds(space: StrategySpace, options?: KindOptions): string[];
|
|
249
|
+
/**
|
|
250
|
+
* This function joins configs of the parts of a product space into one config of the space `space`.
|
|
251
|
+
* The name of each stage gets the prefix `<space of the part>.`. The members of a meta option do not change.
|
|
252
|
+
*/
|
|
253
|
+
export declare function joinConfigs(space: string, parts: readonly StrategyConfig[]): StrategyConfig;
|
|
254
|
+
/** This function gives the config of the part `engine` of a joint config. It throws a `RangeError` when no stage has the prefix `<engine>.`. */
|
|
255
|
+
export declare function splitConfig(config: StrategyConfig, engine: string): StrategyConfig;
|
|
256
|
+
/**
|
|
257
|
+
* This function joins two spaces, for example a packer and a router, into the space `name`. The stages of `a` and `b` get the prefixes `<a.engine>.` and `<b.engine>.`.
|
|
258
|
+
* The constraints get the same prefixes. The named configs are the pairs `<name of a>+<name of b>`. It throws a `RangeError` when the two engines have the same name.
|
|
259
|
+
*/
|
|
260
|
+
export declare function productSpace(a: StrategySpace, b: StrategySpace, name: string): StrategySpace;
|
|
261
|
+
//# sourceMappingURL=strategy-space.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strategy-space.d.ts","names":[],"sources":["../src/strategy-space.ts"],"mappings":";;qBAMa;;YASD;;YAGA;;iBAGK;;WAEN;;WAEA,aAAa;;;iBAIP;WACN;WACA,MAAM;;WAEN;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA,SAAS;;WAET,OAAO;;;;;;iBAOD;WACN;WACA;WACA;;;;;;WAMA,0BAA0B;;;;;WAK1B;;;;;WAKA;;;iBAIM;;WAEN;;;iBAIM;WACN;WACA,iBAAiB;WACjB,UAAU;;WAEV,WAAW;;;;;WAKX;;;iBAIM;;WAEN;;;iBAIM,oBAAoB;;WAE1B;;;iBAIM;WACN;WACA,kBAAkB;WAClB;;;iBAIM;WACN;WACA;;;iBAIM;WACN,IAAI;WACJ,MAAM;aAAuB,KAAK;;;;iBAI5B;WACN,eAAe;;WAEf;;WAEA;WACA,iBAAiB;WACjB,uBAAuB;;WAEvB,QAAQ,SAAS,eAAe;;WAEhC,iBAAiB;;;iBAIX;WACN;;WAEA,SAAS,SAAS,eAAe;;WAEjC,mBAAmB;;;iBAIb;;WAEN;WACA,QAAQ,SAAS,eAAe;;;iBAI1B;;WAEN;;WAEA;;;iBAIM,yBAAyB;;WAE/B;;WAEA;;;iBAIM,oBAAoB;WAC1B;WACA;;WAEA;;;iBAIM,sBAAsB;WAC5B;;WAEA;WACA;;WAEA;;WAEA;;;;;;;;;WASA;;;;;;;WAOA,QAAQ,SAAS;;;YAIhB,mBAAmB,cAAc;;wBAiD7B,aAAa,OAAO,YAAY;;wBAKhC,YAAY,OAAO,YAAY,QAAQ,SAAS,eAAe;;wBAK/D,WAAW,OAAO,YAAY,OAAO,aAAa;;;;;;;;;wBAqRlD,YAAY,OAAO,eAAe,QAAQ,gBAAgB,UAAS,cAAmB;;;;;;;;wBAWtF,WAAW,OAAO,eAAe,cAAa,cAAmB;;;;;;wBA4EjE,gBAAgB,OAAO,eAAe,QAAQ,iBAAiB;;;;;wBAU/D,SAAS,OAAO,eAAe,QAAQ;;;;;wBA4CvC,YAAY,OAAO,YAAY,iBAAiB;;;;;;;wBA6JhD,UAAU,OAAO,eAAe,SAAS,mBAAmB;;;;;;;;;;;;;;wBA8U5D,eAAe,OAAO,eAAe,SAAS,mBAAmB;;;;;;wBAkCjE,gBAAgB,OAAO,eAAe,UAAS;;;;;wBAU/C,YAAY,eAAe,gBAAgB,mBAAmB;;wBAO9D,YAAY,QAAQ,gBAAgB,iBAAiB;;;;;wBAWrD,aAAa,GAAG,eAAe,GAAG,eAAe,eAAe"}
|