@luma.gl/engine 9.0.0-alpha.9 → 9.0.0-beta.1

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.
Files changed (191) hide show
  1. package/LICENSE +3 -1
  2. package/dist/animation/key-frames.d.ts +1 -1
  3. package/dist/animation/key-frames.d.ts.map +1 -1
  4. package/dist/animation/key-frames.js +6 -27
  5. package/dist/animation/key-frames.js.map +1 -1
  6. package/dist/animation/timeline.d.ts +8 -8
  7. package/dist/animation/timeline.d.ts.map +1 -1
  8. package/dist/animation/timeline.js +18 -49
  9. package/dist/animation/timeline.js.map +1 -1
  10. package/dist/animation-loop/animation-loop-template.d.ts +23 -0
  11. package/dist/animation-loop/animation-loop-template.d.ts.map +1 -0
  12. package/dist/animation-loop/animation-loop-template.js +7 -0
  13. package/dist/animation-loop/animation-loop-template.js.map +1 -0
  14. package/dist/{lib → animation-loop}/animation-loop.d.ts +30 -22
  15. package/dist/animation-loop/animation-loop.d.ts.map +1 -0
  16. package/dist/{lib → animation-loop}/animation-loop.js +77 -192
  17. package/dist/animation-loop/animation-loop.js.map +1 -0
  18. package/dist/{lib → animation-loop}/animation-props.d.ts +2 -3
  19. package/dist/animation-loop/animation-props.d.ts.map +1 -0
  20. package/dist/animation-loop/animation-props.js.map +1 -0
  21. package/dist/animation-loop/make-animation-loop.d.ts +6 -0
  22. package/dist/animation-loop/make-animation-loop.d.ts.map +1 -0
  23. package/dist/animation-loop/make-animation-loop.js +28 -0
  24. package/dist/animation-loop/make-animation-loop.js.map +1 -0
  25. package/dist/debug/copy-texture-to-image.d.ts +26 -0
  26. package/dist/debug/copy-texture-to-image.d.ts.map +1 -0
  27. package/dist/debug/copy-texture-to-image.js +46 -0
  28. package/dist/debug/copy-texture-to-image.js.map +1 -0
  29. package/dist/debug/debug-framebuffer.d.ts +11 -0
  30. package/dist/debug/debug-framebuffer.d.ts.map +1 -0
  31. package/dist/debug/debug-framebuffer.js +43 -0
  32. package/dist/debug/debug-framebuffer.js.map +1 -0
  33. package/dist/debug/debug-shader-layout.d.ts +9 -0
  34. package/dist/debug/debug-shader-layout.d.ts.map +1 -0
  35. package/dist/debug/debug-shader-layout.js +28 -0
  36. package/dist/debug/debug-shader-layout.js.map +1 -0
  37. package/dist/debug/pixel-data-utils.d.ts +24 -0
  38. package/dist/debug/pixel-data-utils.d.ts.map +1 -0
  39. package/dist/debug/pixel-data-utils.js +41 -0
  40. package/dist/debug/pixel-data-utils.js.map +1 -0
  41. package/dist/dist.dev.js +10081 -0
  42. package/dist/geometries/cone-geometry.d.ts +1 -1
  43. package/dist/geometries/cone-geometry.d.ts.map +1 -1
  44. package/dist/geometries/cone-geometry.js +6 -5
  45. package/dist/geometries/cone-geometry.js.map +1 -1
  46. package/dist/geometries/cube-geometry.d.ts +2 -2
  47. package/dist/geometries/cube-geometry.d.ts.map +1 -1
  48. package/dist/geometries/cube-geometry.js +16 -10
  49. package/dist/geometries/cube-geometry.js.map +1 -1
  50. package/dist/geometries/cylinder-geometry.d.ts +1 -1
  51. package/dist/geometries/cylinder-geometry.d.ts.map +1 -1
  52. package/dist/geometries/cylinder-geometry.js +6 -5
  53. package/dist/geometries/cylinder-geometry.js.map +1 -1
  54. package/dist/geometries/ico-sphere-geometry.d.ts +2 -2
  55. package/dist/geometries/ico-sphere-geometry.d.ts.map +1 -1
  56. package/dist/geometries/ico-sphere-geometry.js +10 -19
  57. package/dist/geometries/ico-sphere-geometry.js.map +1 -1
  58. package/dist/geometries/plane-geometry.d.ts +2 -2
  59. package/dist/geometries/plane-geometry.d.ts.map +1 -1
  60. package/dist/geometries/plane-geometry.js +14 -23
  61. package/dist/geometries/plane-geometry.js.map +1 -1
  62. package/dist/geometries/sphere-geometry.d.ts +2 -2
  63. package/dist/geometries/sphere-geometry.d.ts.map +1 -1
  64. package/dist/geometries/sphere-geometry.js +9 -13
  65. package/dist/geometries/sphere-geometry.js.map +1 -1
  66. package/dist/geometries/truncated-cone-geometry.d.ts +2 -4
  67. package/dist/geometries/truncated-cone-geometry.d.ts.map +1 -1
  68. package/dist/geometries/truncated-cone-geometry.js +9 -25
  69. package/dist/geometries/truncated-cone-geometry.js.map +1 -1
  70. package/dist/geometry/geometry-table.d.ts +2 -2
  71. package/dist/geometry/geometry-table.d.ts.map +1 -1
  72. package/dist/geometry/geometry-table.js.map +1 -1
  73. package/dist/geometry/geometry-utils.d.ts.map +1 -1
  74. package/dist/geometry/geometry-utils.js +0 -9
  75. package/dist/geometry/geometry-utils.js.map +1 -1
  76. package/dist/geometry/geometry.d.ts +43 -43
  77. package/dist/geometry/geometry.d.ts.map +1 -1
  78. package/dist/geometry/geometry.js +20 -86
  79. package/dist/geometry/geometry.js.map +1 -1
  80. package/dist/geometry/gpu-geometry.d.ts +37 -0
  81. package/dist/geometry/gpu-geometry.d.ts.map +1 -0
  82. package/dist/geometry/gpu-geometry.js +110 -0
  83. package/dist/geometry/gpu-geometry.js.map +1 -0
  84. package/dist/geometry/gpu-table.d.ts +1 -0
  85. package/dist/geometry/gpu-table.d.ts.map +1 -0
  86. package/dist/geometry/gpu-table.js +2 -0
  87. package/dist/geometry/gpu-table.js.map +1 -0
  88. package/dist/index.cjs +3128 -0
  89. package/dist/index.d.ts +24 -8
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.js +23 -14
  92. package/dist/index.js.map +1 -1
  93. package/dist/lib/clip-space.d.ts +8 -0
  94. package/dist/lib/clip-space.d.ts.map +1 -1
  95. package/dist/lib/clip-space.js +47 -0
  96. package/dist/lib/clip-space.js.map +1 -1
  97. package/dist/lib/pipeline-factory.d.ts +12 -45
  98. package/dist/lib/pipeline-factory.d.ts.map +1 -1
  99. package/dist/lib/pipeline-factory.js +42 -168
  100. package/dist/lib/pipeline-factory.js.map +1 -1
  101. package/dist/model/model.d.ts +206 -0
  102. package/dist/model/model.d.ts.map +1 -0
  103. package/dist/model/model.js +435 -0
  104. package/dist/model/model.js.map +1 -0
  105. package/dist/scenegraph/group-node.d.ts +21 -0
  106. package/dist/scenegraph/group-node.d.ts.map +1 -0
  107. package/dist/scenegraph/group-node.js +94 -0
  108. package/dist/scenegraph/group-node.js.map +1 -0
  109. package/dist/scenegraph/model-node.d.ts +18 -0
  110. package/dist/scenegraph/model-node.d.ts.map +1 -0
  111. package/dist/scenegraph/model-node.js +28 -0
  112. package/dist/scenegraph/model-node.js.map +1 -0
  113. package/dist/scenegraph/scenegraph-node.d.ts +56 -0
  114. package/dist/scenegraph/scenegraph-node.d.ts.map +1 -0
  115. package/dist/scenegraph/scenegraph-node.js +141 -0
  116. package/dist/scenegraph/scenegraph-node.js.map +1 -0
  117. package/dist/shader-inputs.d.ts +63 -0
  118. package/dist/shader-inputs.d.ts.map +1 -0
  119. package/dist/shader-inputs.js +66 -0
  120. package/dist/shader-inputs.js.map +1 -0
  121. package/dist/transform/buffer-transform.d.ts +35 -0
  122. package/dist/transform/buffer-transform.d.ts.map +1 -0
  123. package/dist/transform/buffer-transform.js +62 -0
  124. package/dist/transform/buffer-transform.js.map +1 -0
  125. package/dist/transform/texture-transform.d.ts +57 -0
  126. package/dist/transform/texture-transform.d.ts.map +1 -0
  127. package/dist/transform/texture-transform.js +122 -0
  128. package/dist/transform/texture-transform.js.map +1 -0
  129. package/dist.min.js +293 -0
  130. package/package.json +21 -12
  131. package/src/animation/timeline.ts +15 -14
  132. package/src/animation-loop/animation-loop-template.ts +23 -0
  133. package/src/{lib → animation-loop}/animation-loop.ts +99 -88
  134. package/src/{lib → animation-loop}/animation-props.ts +1 -1
  135. package/src/animation-loop/make-animation-loop.ts +44 -0
  136. package/src/debug/copy-texture-to-image.ts +72 -0
  137. package/src/debug/debug-framebuffer.ts +57 -0
  138. package/src/debug/debug-shader-layout.ts +38 -0
  139. package/src/debug/pixel-data-utils.ts +57 -0
  140. package/src/geometries/cone-geometry.ts +1 -1
  141. package/src/geometries/cube-geometry.ts +47 -45
  142. package/src/geometries/cylinder-geometry.ts +2 -2
  143. package/src/geometries/ico-sphere-geometry.ts +6 -5
  144. package/src/geometries/plane-geometry.ts +5 -4
  145. package/src/geometries/sphere-geometry.ts +4 -3
  146. package/src/geometries/truncated-cone-geometry.ts +4 -13
  147. package/src/geometry/geometry-table.ts +1 -1
  148. package/src/geometry/geometry-utils.ts +3 -3
  149. package/src/geometry/geometry.ts +65 -110
  150. package/src/geometry/gpu-geometry.ts +125 -0
  151. package/src/geometry/gpu-table.ts +41 -0
  152. package/src/index.ts +34 -10
  153. package/src/lib/clip-space.ts +22 -21
  154. package/src/lib/pipeline-factory.ts +51 -168
  155. package/src/model/model.ts +726 -0
  156. package/src/scenegraph/group-node.ts +103 -0
  157. package/src/scenegraph/model-node.ts +50 -0
  158. package/src/scenegraph/scenegraph-node.ts +204 -0
  159. package/src/shader-inputs.ts +150 -0
  160. package/src/transform/buffer-transform.ts +94 -0
  161. package/src/transform/texture-transform.ts +169 -0
  162. package/dist/bundle.d.ts +0 -2
  163. package/dist/bundle.d.ts.map +0 -1
  164. package/dist/bundle.js +0 -5
  165. package/dist/bundle.js.map +0 -1
  166. package/dist/geometry/primitive-utils.d.ts +0 -1
  167. package/dist/geometry/primitive-utils.d.ts.map +0 -1
  168. package/dist/geometry/primitive-utils.js +0 -2
  169. package/dist/geometry/primitive-utils.js.map +0 -1
  170. package/dist/lib/animation-loop.d.ts.map +0 -1
  171. package/dist/lib/animation-loop.js.map +0 -1
  172. package/dist/lib/animation-props.d.ts.map +0 -1
  173. package/dist/lib/animation-props.js.map +0 -1
  174. package/dist/lib/model-utils.d.ts +0 -5
  175. package/dist/lib/model-utils.d.ts.map +0 -1
  176. package/dist/lib/model-utils.js +0 -45
  177. package/dist/lib/model-utils.js.map +0 -1
  178. package/dist/lib/model.d.ts +0 -41
  179. package/dist/lib/model.d.ts.map +0 -1
  180. package/dist/lib/model.js +0 -182
  181. package/dist/lib/model.js.map +0 -1
  182. package/dist/lib/render-loop.d.ts +0 -14
  183. package/dist/lib/render-loop.d.ts.map +0 -1
  184. package/dist/lib/render-loop.js +0 -49
  185. package/dist/lib/render-loop.js.map +0 -1
  186. package/src/bundle.ts +0 -4
  187. package/src/geometry/primitive-utils.ts +0 -30
  188. package/src/lib/model-utils.ts +0 -124
  189. package/src/lib/model.ts +0 -183
  190. package/src/lib/render-loop.ts +0 -58
  191. /package/dist/{lib → animation-loop}/animation-props.js +0 -0
@@ -1,126 +1,60 @@
1
- import type {RenderPipelineProps, RenderPipelineParameters, PrimitiveTopology, ShaderLayout} from '@luma.gl/api';
2
- import {Device, RenderPipeline, ComputePipeline} from '@luma.gl/api/';
3
- import type { ShaderModule } from '@luma.gl/shadertools';
4
- import {assembleShaders} from '@luma.gl/shadertools';
1
+ // luma.gl, MIT license
2
+ import type {RenderPipelineProps} from '@luma.gl/core';
3
+ import {Device, RenderPipeline} from '@luma.gl/core';
5
4
 
6
- export type GetRenderPipelineOptions = {
5
+ /** Todo - should be same as RenderPipelineProps */
6
+ export type PipelineFactoryProps = Omit<RenderPipelineProps, 'vs' | 'fs'> & {
7
+ // Only accepts string shaders
7
8
  vs: string;
8
- fs: string | null;
9
- topology: PrimitiveTopology;
10
- layout?: ShaderLayout | null;
11
- parameters?: RenderPipelineParameters;
12
-
13
- modules?: ShaderModule[];
14
- defines?: Record<string, string | number | boolean>;
15
- inject?: Record<string, string>;
16
- transpileToGLSL100?: boolean;
17
-
18
- varyings?: string[];
19
- bufferMode?: number,
9
+ fs: string;
20
10
  };
21
11
 
22
- export type GetComputePipelineOptions = {
23
- cs: string;
24
- parameters?: RenderPipelineParameters;
25
-
26
- modules?: ShaderModule[];
27
- defines?: Record<string, string>;
28
- inject?: Record<string, string>;
29
- transpileToGLSL100?: boolean;
30
-
31
- varyings?: string[];
32
- bufferMode?: number;
33
- };
34
-
35
- const DEFAULT_RENDER_PIPELINE_OPTIONS: Required<GetRenderPipelineOptions> = {
36
- vs: '',
37
- fs: '',
38
- modules: [],
39
- defines: {},
40
- inject: {},
41
- transpileToGLSL100: false,
42
- layout: null,
43
-
44
- varyings: [],
45
- bufferMode: 0x8c8d, // // varyings/bufferMode for xform feedback, 0x8c8d: SEPARATE_ATTRIBS
46
- topology: 'triangle-list',
47
- parameters: {}
48
- };
49
-
50
- type GetUniformsFunc = (props?: Record<string, any>) => Record<string, any>;
51
-
52
- /** Efficiently create shared pipelines with varying parameters */
12
+ /**
13
+ * Efficiently creates / caches pipelines
14
+ */
53
15
  export class PipelineFactory {
16
+ static defaultProps: Required<PipelineFactoryProps> = {
17
+ ...RenderPipeline.defaultProps,
18
+ vs: undefined!,
19
+ fs: undefined!
20
+ }
21
+
54
22
  readonly device: Device;
55
23
 
56
- stateHash: number = 0; // Used to change hashing if hooks are modified
57
24
  private _hashCounter: number = 0;
58
25
  private readonly _hashes: Record<string, number> = {};
59
26
  private readonly _useCounts: Record<string, number> = {};
60
-
61
27
  private readonly _pipelineCache: Record<string, RenderPipeline> = {};
62
28
 
63
- private readonly _getUniforms: Record<string, GetUniformsFunc> = {};
64
- private readonly _hookFunctions: any[] = [];
65
- private _defaultModules: any[] = [];
66
- // private readonly _registeredModules = {}; // TODO: Remove? This isn't used anywhere in luma.gl
67
-
68
29
  static getDefaultPipelineFactory(device: Device): PipelineFactory {
69
- // @ts-expect-error Add to device
70
- device.defaultPipelineFactory = device.defaultPipelineFactory || new PipelineFactory(device);
71
- // @ts-expect-error Add to device
72
- return device.defaultPipelineFactory;
30
+ device._lumaData.defaultPipelineFactory = device._lumaData.defaultPipelineFactory || new PipelineFactory(device);
31
+ return device._lumaData.defaultPipelineFactory as PipelineFactory;
73
32
  }
74
33
 
75
34
  constructor(device: Device) {
76
35
  this.device = device;
77
36
  }
78
37
 
79
- addDefaultModule(module: ShaderModule): void {
80
- if (!this._defaultModules.find((m) => m.name === (typeof module === 'string' ? module : module.name))) {
81
- this._defaultModules.push(module);
82
- }
83
- this.stateHash++;
84
- }
85
-
86
- removeDefaultModule(module: ShaderModule): void {
87
- const moduleName = typeof module === 'string' ? module : module.name;
88
- this._defaultModules = this._defaultModules.filter((m) => m.name !== moduleName);
89
- this.stateHash++;
90
- }
91
-
92
- addShaderHook(hook, opts?): void {
93
- if (opts) {
94
- hook = Object.assign(opts, {hook});
95
- }
96
- this._hookFunctions.push(hook);
97
- this.stateHash++;
98
- }
99
-
100
- createRenderPipeline(options: GetRenderPipelineOptions): {
101
- pipeline: RenderPipeline;
102
- getUniforms: GetUniformsFunc;
103
- } {
104
- const props: Required<GetRenderPipelineOptions> = {...DEFAULT_RENDER_PIPELINE_OPTIONS, ...options};
105
-
106
- const modules = this._getModuleList(props.modules); // Combine with default modules
38
+ createRenderPipeline(options: PipelineFactoryProps): RenderPipeline {
39
+ const props: Required<PipelineFactoryProps> = {...PipelineFactory.defaultProps, ...options};
107
40
 
108
- const hash = this._hashRenderPipeline({...props, modules});
41
+ const hash = this._hashRenderPipeline({...props});
109
42
 
110
43
  if (!this._pipelineCache[hash]) {
111
- const {pipeline, getUniforms} = this._createRenderPipeline({...props, modules});
44
+ const pipeline = this.device.createRenderPipeline({
45
+ ...props,
46
+ vs: this.device.createShader({stage: 'vertex', source: props.vs}),
47
+ fs: props.fs ? this.device.createShader({stage: 'fragment', source: props.fs}) : null,
48
+ });
49
+
112
50
  pipeline.hash = hash;
113
51
  this._pipelineCache[hash] = pipeline;
114
- this._getUniforms[hash] = getUniforms || ((x?: unknown) => ({}));
115
52
  this._useCounts[hash] = 0;
116
53
  }
117
54
 
118
55
  this._useCounts[hash]++;
119
56
 
120
- return {
121
- pipeline: this._pipelineCache[hash],
122
- getUniforms: this._getUniforms[hash]
123
- };
57
+ return this._pipelineCache[hash];
124
58
  }
125
59
 
126
60
  release(pipeline: RenderPipeline): void {
@@ -129,73 +63,48 @@ export class PipelineFactory {
129
63
  if (this._useCounts[hash] === 0) {
130
64
  this._pipelineCache[hash].destroy();
131
65
  delete this._pipelineCache[hash];
132
- delete this._getUniforms[hash];
133
66
  delete this._useCounts[hash];
134
67
  }
135
68
  }
136
69
 
137
- getUniforms(pipeline: RenderPipeline) {
138
- return this._getUniforms[pipeline.hash] || null;
139
- }
140
-
141
70
  // PRIVATE
142
71
 
143
- _createRenderPipeline(props: GetRenderPipelineOptions): {
144
- pipeline: RenderPipeline,
145
- getUniforms: GetUniformsFunc
146
- } {
147
- const platformInfo = {
148
- gpu: this.device.info.gpu,
149
- features: this.device.features
150
- };
151
-
72
+ _createRenderPipeline(props: PipelineFactoryProps): RenderPipeline {
152
73
  if (!props.fs) {
153
74
  throw new Error('fs');
154
75
  }
155
76
 
156
- const assembled = assembleShaders(platformInfo, {...props, fs: props.fs, hookFunctions: this._hookFunctions});
157
-
158
77
  const pipeline = this.device.createRenderPipeline({
159
78
  ...props,
160
- vs: this.device.createShader({stage: 'vertex', source: assembled.vs}),
161
- fs: assembled.fs ? this.device.createShader({stage: 'fragment', source: assembled.fs}) : null,
79
+ vs: this.device.createShader({stage: 'vertex', source: props.vs}),
80
+ fs: props.fs ? this.device.createShader({stage: 'fragment', source: props.fs}) : null,
162
81
  });
163
82
 
164
- return {pipeline, getUniforms: assembled.getUniforms};
83
+ return pipeline;
165
84
  }
166
85
 
167
86
  /** Calculate a hash based on all the inputs for a render pipeline */
168
- _hashRenderPipeline(props: GetRenderPipelineOptions): string {
169
- const {modules = [], varyings = [], defines = [], inject = [], parameters = []} = props;
170
- const vsHash = this._getHash(props.vs);
87
+ _hashRenderPipeline(props: PipelineFactoryProps): string {
88
+ const vsHash = this._getHash(props.vs);
171
89
  const fsHash = props.fs ? this._getHash(props.fs) : 0;
172
90
 
173
- const moduleHashes = modules.map((m) => this._getHash(typeof m === 'string' ? m : m.name)).sort();
174
- const varyingHashes = varyings.map((v) => this._getHash(v));
175
-
176
- const defineKeys = Object.keys(defines).sort();
177
- const injectKeys = Object.keys(inject).sort();
178
- const defineHashes: number[] = [];
179
- const injectHashes: number[] = [];
180
-
181
- for (const key of defineKeys) {
182
- defineHashes.push(this._getHash(key));
183
- defineHashes.push(this._getHash(defines[key]));
91
+ // WebGL specific
92
+ // const {varyings = [], bufferMode = {}} = props;
93
+ // const varyingHashes = varyings.map((v) => this._getHash(v));
94
+ const varyingHash = '-'; // `${varyingHashes.join('/')}B${bufferMode}`
95
+
96
+ switch (this.device.info.type) {
97
+ case 'webgpu':
98
+ // On WebGPU we need to rebuild the pipeline if topology, parameters or bufferLayout change
99
+ const parameterHash = this._getHash(JSON.stringify(props.parameters));
100
+ const bufferLayoutHash = this._getHash(JSON.stringify(props.bufferLayout));
101
+ // TODO - Can json.stringify() generate different strings for equivalent objects if order of params is different?
102
+ // create a deepHash() to deduplicate?
103
+ return `${vsHash}/${fsHash}V${varyingHash}T${props.topology}P${parameterHash}BL${bufferLayoutHash}}`;
104
+ default:
105
+ // WebGL is more dynamic
106
+ return `${vsHash}/${fsHash}V${varyingHash}`;
184
107
  }
185
-
186
- for (const key of injectKeys) {
187
- injectHashes.push(this._getHash(key));
188
- injectHashes.push(this._getHash(inject[key]));
189
- }
190
-
191
- // TODO - hash parameters!
192
- const parameterHash = JSON.stringify(parameters);
193
-
194
- return `${vsHash}/${fsHash}D${defineHashes.join('/')}M${moduleHashes.join(
195
- '/'
196
- )}I${injectHashes.join('/')}V${varyingHashes.join('/')}H${this.stateHash}B${props.bufferMode}${
197
- props.transpileToGLSL100 ? 'T' : ''
198
- }P${parameterHash}`;
199
108
  }
200
109
 
201
110
  _getHash(key: string): number {
@@ -204,31 +113,5 @@ export class PipelineFactory {
204
113
  }
205
114
  return this._hashes[key];
206
115
  }
207
-
208
- // Dedupe and combine with default modules
209
- _getModuleList(appModules: ShaderModule[] = []): ShaderModule[] {
210
- const modules = new Array(this._defaultModules.length + appModules.length);
211
- const seen: Record<string, boolean> = {};
212
- let count = 0;
213
-
214
- for (let i = 0, len = this._defaultModules.length; i < len; ++i) {
215
- const module = this._defaultModules[i];
216
- const name = module.name;
217
- modules[count++] = module;
218
- seen[name] = true;
219
- }
220
-
221
- for (let i = 0, len = appModules.length; i < len; ++i) {
222
- const module = appModules[i];
223
- const name = module.name;
224
- if (!seen[name]) {
225
- modules[count++] = module;
226
- seen[name] = true;
227
- }
228
- }
229
-
230
- modules.length = count;
231
-
232
- return modules;
233
- }
234
116
  }
117
+