@kupcad/editor 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/README.md +76 -2
- package/package.json +60 -3
- package/src/Editor.svelte +74 -0
- package/src/editor.js +184 -0
- package/src/findings.js +74 -0
- package/src/index.js +17 -0
- package/src/language-server.js +163 -0
- package/src/language.js +131 -0
- package/src/svelte.js +4 -0
- package/src/theme.js +71 -0
- package/src/vocabulary.json +301 -0
package/src/language.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// KupCAD as CodeMirror reads it. Its literals are Ruby's (strings with interpolation, the single
|
|
2
|
+
// quoted ones, %w and %q, heredocs, symbols, comments), so CodeMirror's Ruby mode reads them and
|
|
3
|
+
// indents the blocks; its words are the core's (vocabulary.json, which `zig build grammar`
|
|
4
|
+
// writes from the lexer and the stdlib), so a word is a keyword, a function or a method as the
|
|
5
|
+
// language has it, not as Ruby does. Completion offers the same words.
|
|
6
|
+
|
|
7
|
+
import { completeFromList } from '@codemirror/autocomplete';
|
|
8
|
+
import { LanguageSupport, StreamLanguage } from '@codemirror/language';
|
|
9
|
+
import { ruby } from '@codemirror/legacy-modes/mode/ruby';
|
|
10
|
+
import vocabulary from './vocabulary.json' with { type: 'json' };
|
|
11
|
+
|
|
12
|
+
/** @import { CompletionContext, CompletionResult } from '@codemirror/autocomplete' */
|
|
13
|
+
/** @import { StreamParser, StringStream } from '@codemirror/language' */
|
|
14
|
+
|
|
15
|
+
const KEYWORDS = new Set(vocabulary.keywords);
|
|
16
|
+
const FUNCTIONS = new Set(vocabulary.functions);
|
|
17
|
+
const METHODS = new Set(vocabulary.methods);
|
|
18
|
+
/** The highlighting tags the words get: lezer's names, a modifier after a dot. */
|
|
19
|
+
const TOKENS = /** @type {const} */ ({
|
|
20
|
+
keyword: 'keyword',
|
|
21
|
+
function: 'variableName.function.standard',
|
|
22
|
+
method: 'propertyName.function.standard',
|
|
23
|
+
property: 'propertyName',
|
|
24
|
+
className: 'className',
|
|
25
|
+
definition: 'variableName.definition',
|
|
26
|
+
variable: 'variableName',
|
|
27
|
+
});
|
|
28
|
+
/** A word before the cursor, or a method's name after its dot. */
|
|
29
|
+
const WORD_BEFORE = /\.?[\w?!]*$/;
|
|
30
|
+
const METHOD_NAME = /^[\w?!]*$/;
|
|
31
|
+
|
|
32
|
+
/** @typedef {Record<string, unknown>} RubyState */
|
|
33
|
+
/** The Ruby mode, whose state starts and indents (its type leaves them optional). */
|
|
34
|
+
const rubyMode =
|
|
35
|
+
/** @type {Required<Pick<StreamParser<RubyState>, 'startState' | 'indent'>> & StreamParser<RubyState>} */ (
|
|
36
|
+
/** @type {unknown} */ (ruby)
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The Ruby mode's state, and whether a `for` waits for its `in` (a keyword there alone).
|
|
41
|
+
* @typedef {{ ruby: RubyState, forOpen: boolean }} State
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
/** @type {StreamParser<State>} */
|
|
45
|
+
const parser = {
|
|
46
|
+
name: 'kupcad',
|
|
47
|
+
startState: (indentUnit) => ({ ruby: rubyMode.startState(indentUnit), forOpen: false }),
|
|
48
|
+
copyState: (state) => ({ ruby: copyFields(state.ruby), forOpen: state.forOpen }),
|
|
49
|
+
token(stream, state) {
|
|
50
|
+
if (stream.sol()) state.forOpen = false;
|
|
51
|
+
const style = rubyMode.token(stream, state.ruby);
|
|
52
|
+
return style ? styleOf(stream, style, state) : null;
|
|
53
|
+
},
|
|
54
|
+
indent: (state, textAfter, context) => rubyMode.indent(state.ruby, textAfter, context),
|
|
55
|
+
languageData: rubyMode.languageData,
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* What the Ruby mode called a token, as KupCAD has it: a word by the core's vocabulary.
|
|
60
|
+
* @param {StringStream} stream
|
|
61
|
+
* @param {string} style the Ruby mode's
|
|
62
|
+
* @param {State} state
|
|
63
|
+
* @returns {string}
|
|
64
|
+
*/
|
|
65
|
+
function styleOf(stream, style, state) {
|
|
66
|
+
const word = stream.current();
|
|
67
|
+
switch (style) {
|
|
68
|
+
case 'property':
|
|
69
|
+
return METHODS.has(word) ? TOKENS.method : TOKENS.property;
|
|
70
|
+
case 'tag':
|
|
71
|
+
return TOKENS.className;
|
|
72
|
+
case 'def':
|
|
73
|
+
return TOKENS.definition;
|
|
74
|
+
case 'keyword':
|
|
75
|
+
case 'variable':
|
|
76
|
+
if (word === 'for') state.forOpen = true;
|
|
77
|
+
if (KEYWORDS.has(word)) return TOKENS.keyword;
|
|
78
|
+
if (word === 'in' && state.forOpen) {
|
|
79
|
+
state.forOpen = false;
|
|
80
|
+
return TOKENS.keyword;
|
|
81
|
+
}
|
|
82
|
+
return FUNCTIONS.has(word) ? TOKENS.function : TOKENS.variable;
|
|
83
|
+
default:
|
|
84
|
+
return style;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* A copy of a mode's state, as CodeMirror copies one whose mode has no copyState of its own (the
|
|
90
|
+
* Ruby mode's): its fields, an array among them copied.
|
|
91
|
+
* @param {RubyState} state
|
|
92
|
+
* @returns {RubyState}
|
|
93
|
+
*/
|
|
94
|
+
function copyFields(state) {
|
|
95
|
+
return Object.fromEntries(
|
|
96
|
+
Object.entries(state).map(([key, value]) => [key, Array.isArray(value) ? [...value] : value]),
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** KupCAD's language, for an editor to read a script by. */
|
|
101
|
+
export const kupcadLanguage = StreamLanguage.define(parser);
|
|
102
|
+
|
|
103
|
+
const completeKeywordOrFunction = completeFromList([
|
|
104
|
+
...vocabulary.keywords.map((label) => ({ label, type: 'keyword' })),
|
|
105
|
+
...vocabulary.functions.map((label) => ({ label, type: 'function' })),
|
|
106
|
+
]);
|
|
107
|
+
const METHOD_OPTIONS = vocabulary.methods.map((label) => ({ label, type: 'method' }));
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Completes a word with the keywords and the functions, and a name after a dot with the methods.
|
|
111
|
+
* @param {CompletionContext} context
|
|
112
|
+
* @returns {CompletionResult | null | Promise<CompletionResult | null>}
|
|
113
|
+
*/
|
|
114
|
+
export function completeKupcad(context) {
|
|
115
|
+
const before = context.matchBefore(WORD_BEFORE);
|
|
116
|
+
if (!before || (before.from === before.to && !context.explicit)) return null;
|
|
117
|
+
if (!before.text.startsWith('.')) return completeKeywordOrFunction(context);
|
|
118
|
+
return { from: before.from + 1, options: METHOD_OPTIONS, validFor: METHOD_NAME };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* KupCAD for an editor: the language, and completion of its words unless something else
|
|
123
|
+
* completes them (a language server, which knows the script's own names too).
|
|
124
|
+
* @param {{ complete?: boolean }} [options]
|
|
125
|
+
*/
|
|
126
|
+
export function kupcad({ complete = true } = {}) {
|
|
127
|
+
return new LanguageSupport(
|
|
128
|
+
kupcadLanguage,
|
|
129
|
+
complete ? kupcadLanguage.data.of({ autocomplete: completeKupcad }) : [],
|
|
130
|
+
);
|
|
131
|
+
}
|
package/src/svelte.js
ADDED
package/src/theme.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// How the editor looks: by the --kc-* tokens a host sets (@kupcad/ui's tokens.css), else the
|
|
2
|
+
// page's own colours (CSS system colours, light or dark as the page is); the code's colours by
|
|
3
|
+
// the --kc-code-* tokens (keyword, string, comment, constant, function, definition), else
|
|
4
|
+
// GitHub's, light or dark.
|
|
5
|
+
|
|
6
|
+
import { HighlightStyle } from '@codemirror/language';
|
|
7
|
+
import { EditorView } from '@codemirror/view';
|
|
8
|
+
import { tags } from '@lezer/highlight';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The colour of a kind of code: its token's, else GitHub's for the page's scheme.
|
|
12
|
+
* @param {string} kind
|
|
13
|
+
* @param {string} light
|
|
14
|
+
* @param {string} dark
|
|
15
|
+
*/
|
|
16
|
+
const code = (kind, light, dark) => `var(--kc-code-${kind}, light-dark(${light}, ${dark}))`;
|
|
17
|
+
const FG = 'var(--kc-fg, CanvasText)';
|
|
18
|
+
const BG = 'var(--kc-bg, Canvas)';
|
|
19
|
+
const MUTED = 'var(--kc-muted, GrayText)';
|
|
20
|
+
const BORDER = 'var(--kc-border, GrayText)';
|
|
21
|
+
const ACCENT = 'var(--kc-accent, Highlight)';
|
|
22
|
+
|
|
23
|
+
export const editorTheme = EditorView.theme({
|
|
24
|
+
'&': {
|
|
25
|
+
height: '100%',
|
|
26
|
+
color: FG,
|
|
27
|
+
backgroundColor: BG,
|
|
28
|
+
fontSize: 'var(--kc-code-font-size, var(--kc-font-size, 13px))',
|
|
29
|
+
// What light-dark() picks by, where the page says nothing of its scheme
|
|
30
|
+
colorScheme: 'light dark',
|
|
31
|
+
},
|
|
32
|
+
'.cm-scroller': {
|
|
33
|
+
fontFamily: 'var(--kc-code-font, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace)',
|
|
34
|
+
lineHeight: '1.5',
|
|
35
|
+
},
|
|
36
|
+
'.cm-gutters': { color: MUTED, backgroundColor: BG, borderRight: `1px solid ${BORDER}` },
|
|
37
|
+
'.cm-activeLine': { backgroundColor: `color-mix(in srgb, ${ACCENT} 6%, transparent)` },
|
|
38
|
+
'.cm-activeLineGutter': { backgroundColor: `color-mix(in srgb, ${ACCENT} 10%, transparent)` },
|
|
39
|
+
'.cm-cursor, .cm-dropCursor': { borderLeftColor: FG },
|
|
40
|
+
'&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {
|
|
41
|
+
backgroundColor: `color-mix(in srgb, ${ACCENT} 28%, transparent)`,
|
|
42
|
+
},
|
|
43
|
+
'.cm-matchingBracket': { backgroundColor: `color-mix(in srgb, ${ACCENT} 20%, transparent)` },
|
|
44
|
+
'.cm-tooltip': { color: FG, backgroundColor: BG, border: `1px solid ${BORDER}` },
|
|
45
|
+
'.cm-tooltip-autocomplete ul li[aria-selected]': {
|
|
46
|
+
color: 'var(--kc-accent-fg, HighlightText)',
|
|
47
|
+
backgroundColor: ACCENT,
|
|
48
|
+
},
|
|
49
|
+
'.cm-panels': { color: FG, backgroundColor: BG },
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
export const highlightStyle = HighlightStyle.define([
|
|
53
|
+
{ tag: tags.keyword, color: code('keyword', '#cf222e', '#ff7b72') },
|
|
54
|
+
{ tag: [tags.string, tags.special(tags.string)], color: code('string', '#0a3069', '#a5d6ff') },
|
|
55
|
+
{ tag: tags.comment, color: code('comment', '#6e7781', '#8b949e'), fontStyle: 'italic' },
|
|
56
|
+
{
|
|
57
|
+
tag: [tags.number, tags.bool, tags.null, tags.atom],
|
|
58
|
+
color: code('constant', '#0550ae', '#79c0ff'),
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
tag: [
|
|
62
|
+
tags.standard(tags.function(tags.variableName)),
|
|
63
|
+
tags.standard(tags.function(tags.propertyName)),
|
|
64
|
+
],
|
|
65
|
+
color: code('function', '#8250df', '#d2a8ff'),
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
tag: [tags.definition(tags.variableName), tags.className],
|
|
69
|
+
color: code('definition', '#953800', '#ffa657'),
|
|
70
|
+
},
|
|
71
|
+
]);
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
{
|
|
2
|
+
"keywords": [
|
|
3
|
+
"and",
|
|
4
|
+
"as",
|
|
5
|
+
"begin",
|
|
6
|
+
"break",
|
|
7
|
+
"case",
|
|
8
|
+
"class",
|
|
9
|
+
"def",
|
|
10
|
+
"do",
|
|
11
|
+
"else",
|
|
12
|
+
"elsif",
|
|
13
|
+
"end",
|
|
14
|
+
"ensure",
|
|
15
|
+
"export",
|
|
16
|
+
"false",
|
|
17
|
+
"for",
|
|
18
|
+
"from",
|
|
19
|
+
"if",
|
|
20
|
+
"import",
|
|
21
|
+
"module",
|
|
22
|
+
"next",
|
|
23
|
+
"nil",
|
|
24
|
+
"not",
|
|
25
|
+
"or",
|
|
26
|
+
"private",
|
|
27
|
+
"public",
|
|
28
|
+
"rescue",
|
|
29
|
+
"return",
|
|
30
|
+
"self",
|
|
31
|
+
"super",
|
|
32
|
+
"then",
|
|
33
|
+
"true",
|
|
34
|
+
"unless",
|
|
35
|
+
"until",
|
|
36
|
+
"when",
|
|
37
|
+
"while",
|
|
38
|
+
"with",
|
|
39
|
+
"yield"
|
|
40
|
+
],
|
|
41
|
+
"functions": [
|
|
42
|
+
"arc",
|
|
43
|
+
"assemble",
|
|
44
|
+
"assert",
|
|
45
|
+
"batch_hull",
|
|
46
|
+
"benchmark",
|
|
47
|
+
"block_given?",
|
|
48
|
+
"circle",
|
|
49
|
+
"cube",
|
|
50
|
+
"cylinder",
|
|
51
|
+
"debugger",
|
|
52
|
+
"defined?",
|
|
53
|
+
"ghost",
|
|
54
|
+
"highlight",
|
|
55
|
+
"import_3mf",
|
|
56
|
+
"import_dxf",
|
|
57
|
+
"import_font",
|
|
58
|
+
"import_json",
|
|
59
|
+
"import_obj",
|
|
60
|
+
"import_step",
|
|
61
|
+
"import_stl",
|
|
62
|
+
"import_svg",
|
|
63
|
+
"inspect",
|
|
64
|
+
"line",
|
|
65
|
+
"param",
|
|
66
|
+
"polygon",
|
|
67
|
+
"polyhedron",
|
|
68
|
+
"polyline",
|
|
69
|
+
"print",
|
|
70
|
+
"puts",
|
|
71
|
+
"raise",
|
|
72
|
+
"regular_polygon",
|
|
73
|
+
"sphere",
|
|
74
|
+
"square",
|
|
75
|
+
"text",
|
|
76
|
+
"torus",
|
|
77
|
+
"union",
|
|
78
|
+
"warn"
|
|
79
|
+
],
|
|
80
|
+
"methods": [
|
|
81
|
+
"abs",
|
|
82
|
+
"acos",
|
|
83
|
+
"acosd",
|
|
84
|
+
"align",
|
|
85
|
+
"all?",
|
|
86
|
+
"any?",
|
|
87
|
+
"arc_to",
|
|
88
|
+
"area",
|
|
89
|
+
"asin",
|
|
90
|
+
"asind",
|
|
91
|
+
"atan",
|
|
92
|
+
"atan2",
|
|
93
|
+
"atan2d",
|
|
94
|
+
"atand",
|
|
95
|
+
"bbox",
|
|
96
|
+
"between?",
|
|
97
|
+
"bom",
|
|
98
|
+
"bytes_allocated",
|
|
99
|
+
"cbrt",
|
|
100
|
+
"ceil",
|
|
101
|
+
"center",
|
|
102
|
+
"center_of_mass",
|
|
103
|
+
"chamfer",
|
|
104
|
+
"chars",
|
|
105
|
+
"clamp",
|
|
106
|
+
"class",
|
|
107
|
+
"clone",
|
|
108
|
+
"close",
|
|
109
|
+
"close?",
|
|
110
|
+
"cm",
|
|
111
|
+
"collect",
|
|
112
|
+
"compact",
|
|
113
|
+
"config",
|
|
114
|
+
"contains?",
|
|
115
|
+
"cos",
|
|
116
|
+
"cosd",
|
|
117
|
+
"count",
|
|
118
|
+
"cover?",
|
|
119
|
+
"current_config",
|
|
120
|
+
"decompose",
|
|
121
|
+
"deg2rad",
|
|
122
|
+
"delete",
|
|
123
|
+
"difference",
|
|
124
|
+
"dig",
|
|
125
|
+
"downcase",
|
|
126
|
+
"downto",
|
|
127
|
+
"drop",
|
|
128
|
+
"dup",
|
|
129
|
+
"each",
|
|
130
|
+
"each_cons",
|
|
131
|
+
"each_slice",
|
|
132
|
+
"each_with_index",
|
|
133
|
+
"empty?",
|
|
134
|
+
"end",
|
|
135
|
+
"end_with?",
|
|
136
|
+
"ends_with?",
|
|
137
|
+
"even?",
|
|
138
|
+
"exclusive?",
|
|
139
|
+
"exp",
|
|
140
|
+
"export_3mf",
|
|
141
|
+
"export_dxf",
|
|
142
|
+
"export_gltf",
|
|
143
|
+
"export_obj",
|
|
144
|
+
"export_step",
|
|
145
|
+
"export_stl",
|
|
146
|
+
"export_svg",
|
|
147
|
+
"extrude",
|
|
148
|
+
"fetch",
|
|
149
|
+
"fillet",
|
|
150
|
+
"filter",
|
|
151
|
+
"find",
|
|
152
|
+
"finite?",
|
|
153
|
+
"first",
|
|
154
|
+
"flat_map",
|
|
155
|
+
"flatten",
|
|
156
|
+
"floor",
|
|
157
|
+
"gcd",
|
|
158
|
+
"genus",
|
|
159
|
+
"get",
|
|
160
|
+
"ghost",
|
|
161
|
+
"group_by",
|
|
162
|
+
"helix",
|
|
163
|
+
"highlight",
|
|
164
|
+
"hull",
|
|
165
|
+
"hypot",
|
|
166
|
+
"inch",
|
|
167
|
+
"include?",
|
|
168
|
+
"infinite?",
|
|
169
|
+
"inspect",
|
|
170
|
+
"integer?",
|
|
171
|
+
"intersection",
|
|
172
|
+
"intersects?",
|
|
173
|
+
"into",
|
|
174
|
+
"invert",
|
|
175
|
+
"is_a?",
|
|
176
|
+
"join",
|
|
177
|
+
"key?",
|
|
178
|
+
"keys",
|
|
179
|
+
"last",
|
|
180
|
+
"lcm",
|
|
181
|
+
"length",
|
|
182
|
+
"lerp",
|
|
183
|
+
"line_to",
|
|
184
|
+
"ljust",
|
|
185
|
+
"loft",
|
|
186
|
+
"log",
|
|
187
|
+
"log10",
|
|
188
|
+
"log2",
|
|
189
|
+
"m",
|
|
190
|
+
"map",
|
|
191
|
+
"mass",
|
|
192
|
+
"material",
|
|
193
|
+
"max",
|
|
194
|
+
"max_by",
|
|
195
|
+
"merge",
|
|
196
|
+
"method",
|
|
197
|
+
"min",
|
|
198
|
+
"min_by",
|
|
199
|
+
"min_gap",
|
|
200
|
+
"minkowski",
|
|
201
|
+
"mirror",
|
|
202
|
+
"mm",
|
|
203
|
+
"name",
|
|
204
|
+
"named",
|
|
205
|
+
"nan?",
|
|
206
|
+
"negative?",
|
|
207
|
+
"nil?",
|
|
208
|
+
"none?",
|
|
209
|
+
"odd?",
|
|
210
|
+
"offset",
|
|
211
|
+
"parts",
|
|
212
|
+
"polar",
|
|
213
|
+
"pop",
|
|
214
|
+
"positive?",
|
|
215
|
+
"preview?",
|
|
216
|
+
"project",
|
|
217
|
+
"push",
|
|
218
|
+
"rad2deg",
|
|
219
|
+
"rand",
|
|
220
|
+
"ray_cast",
|
|
221
|
+
"reduce",
|
|
222
|
+
"reject",
|
|
223
|
+
"remap",
|
|
224
|
+
"repeat_linear",
|
|
225
|
+
"repeat_polar",
|
|
226
|
+
"replace",
|
|
227
|
+
"resize",
|
|
228
|
+
"respond_to?",
|
|
229
|
+
"reverse",
|
|
230
|
+
"revolve",
|
|
231
|
+
"rjust",
|
|
232
|
+
"rotate",
|
|
233
|
+
"round",
|
|
234
|
+
"sample",
|
|
235
|
+
"scale",
|
|
236
|
+
"seed",
|
|
237
|
+
"shell",
|
|
238
|
+
"shift",
|
|
239
|
+
"shuffle",
|
|
240
|
+
"sign",
|
|
241
|
+
"simplify",
|
|
242
|
+
"sin",
|
|
243
|
+
"sind",
|
|
244
|
+
"size",
|
|
245
|
+
"slice",
|
|
246
|
+
"smoothstep",
|
|
247
|
+
"snap",
|
|
248
|
+
"sort",
|
|
249
|
+
"sort_by",
|
|
250
|
+
"split",
|
|
251
|
+
"split_by_plane",
|
|
252
|
+
"sqrt",
|
|
253
|
+
"start",
|
|
254
|
+
"start_with?",
|
|
255
|
+
"starts_with?",
|
|
256
|
+
"step",
|
|
257
|
+
"stringify_keys",
|
|
258
|
+
"strip",
|
|
259
|
+
"stroke",
|
|
260
|
+
"sum",
|
|
261
|
+
"surface_area",
|
|
262
|
+
"sweep",
|
|
263
|
+
"symbolize_keys",
|
|
264
|
+
"take",
|
|
265
|
+
"tan",
|
|
266
|
+
"tand",
|
|
267
|
+
"tangent_arc_to",
|
|
268
|
+
"tap",
|
|
269
|
+
"times",
|
|
270
|
+
"to_a",
|
|
271
|
+
"to_f",
|
|
272
|
+
"to_h",
|
|
273
|
+
"to_i",
|
|
274
|
+
"to_s",
|
|
275
|
+
"to_sym",
|
|
276
|
+
"transform",
|
|
277
|
+
"transform_values",
|
|
278
|
+
"translate",
|
|
279
|
+
"trim",
|
|
280
|
+
"trim_by_plane",
|
|
281
|
+
"union",
|
|
282
|
+
"uniq",
|
|
283
|
+
"unshift",
|
|
284
|
+
"upcase",
|
|
285
|
+
"upto",
|
|
286
|
+
"values",
|
|
287
|
+
"volume",
|
|
288
|
+
"with_config",
|
|
289
|
+
"x_max",
|
|
290
|
+
"x_min",
|
|
291
|
+
"x_size",
|
|
292
|
+
"y_max",
|
|
293
|
+
"y_min",
|
|
294
|
+
"y_size",
|
|
295
|
+
"z_max",
|
|
296
|
+
"z_min",
|
|
297
|
+
"z_size",
|
|
298
|
+
"zero?",
|
|
299
|
+
"zip"
|
|
300
|
+
]
|
|
301
|
+
}
|