mage-engine 3.24.4 → 3.24.6

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 (87) hide show
  1. package/.github/workflows/test.yml +29 -0
  2. package/__mocks__/three.js +178 -0
  3. package/coverage/clover.xml +3094 -0
  4. package/coverage/coverage-final.json +60 -0
  5. package/coverage/lcov-report/base.css +224 -0
  6. package/coverage/lcov-report/block-navigation.js +87 -0
  7. package/coverage/lcov-report/entities/Element.js.html +3463 -0
  8. package/coverage/lcov-report/entities/Entity.js.html +2740 -0
  9. package/coverage/lcov-report/entities/animations/AnimationHandler.js.html +1006 -0
  10. package/coverage/lcov-report/entities/animations/SpriteAnimationHandler.js.html +91 -0
  11. package/coverage/lcov-report/entities/animations/index.html +131 -0
  12. package/coverage/lcov-report/entities/animations/lib/NodeFrame.js.html +214 -0
  13. package/coverage/lcov-report/entities/animations/lib/index.html +116 -0
  14. package/coverage/lcov-report/entities/base/AnimatedSprite.js.html +220 -0
  15. package/coverage/lcov-report/entities/base/Axes.js.html +316 -0
  16. package/coverage/lcov-report/entities/base/Box.js.html +253 -0
  17. package/coverage/lcov-report/entities/base/Cone.js.html +304 -0
  18. package/coverage/lcov-report/entities/base/Cube.js.html +217 -0
  19. package/coverage/lcov-report/entities/base/CurveLine.js.html +166 -0
  20. package/coverage/lcov-report/entities/base/Cylinder.js.html +259 -0
  21. package/coverage/lcov-report/entities/base/Grid.js.html +190 -0
  22. package/coverage/lcov-report/entities/base/HelperSprite.js.html +163 -0
  23. package/coverage/lcov-report/entities/base/Label.js.html +373 -0
  24. package/coverage/lcov-report/entities/base/Line.js.html +334 -0
  25. package/coverage/lcov-report/entities/base/Plane.js.html +265 -0
  26. package/coverage/lcov-report/entities/base/Sphere.js.html +217 -0
  27. package/coverage/lcov-report/entities/base/Sprite.js.html +445 -0
  28. package/coverage/lcov-report/entities/base/index.html +326 -0
  29. package/coverage/lcov-report/entities/base/index.js.html +172 -0
  30. package/coverage/lcov-report/entities/camera.js.html +751 -0
  31. package/coverage/lcov-report/entities/constants.js.html +655 -0
  32. package/coverage/lcov-report/entities/index.html +176 -0
  33. package/coverage/lcov-report/entities/index.js.html +187 -0
  34. package/coverage/lcov-report/favicon.png +0 -0
  35. package/coverage/lcov-report/images/Images.js.html +724 -0
  36. package/coverage/lcov-report/images/index.html +116 -0
  37. package/coverage/lcov-report/index.html +266 -0
  38. package/coverage/lcov-report/lib/Color.js.html +187 -0
  39. package/coverage/lcov-report/lib/array.js.html +97 -0
  40. package/coverage/lcov-report/lib/colliders.js.html +217 -0
  41. package/coverage/lcov-report/lib/constants.js.html +1171 -0
  42. package/coverage/lcov-report/lib/dom.js.html +202 -0
  43. package/coverage/lcov-report/lib/easing.js.html +229 -0
  44. package/coverage/lcov-report/lib/features.js.html +826 -0
  45. package/coverage/lcov-report/lib/functions.js.html +130 -0
  46. package/coverage/lcov-report/lib/index.html +401 -0
  47. package/coverage/lcov-report/lib/location.js.html +127 -0
  48. package/coverage/lcov-report/lib/map.js.html +172 -0
  49. package/coverage/lcov-report/lib/math.js.html +511 -0
  50. package/coverage/lcov-report/lib/meshUtils.js.html +685 -0
  51. package/coverage/lcov-report/lib/messages.js.html +415 -0
  52. package/coverage/lcov-report/lib/network.js.html +136 -0
  53. package/coverage/lcov-report/lib/object.js.html +187 -0
  54. package/coverage/lcov-report/lib/palettes.js.html +259 -0
  55. package/coverage/lcov-report/lib/query.js.html +172 -0
  56. package/coverage/lcov-report/lib/strings.js.html +139 -0
  57. package/coverage/lcov-report/lib/url.js.html +85 -0
  58. package/coverage/lcov-report/lib/utils/assets.js.html +94 -0
  59. package/coverage/lcov-report/lib/utils/index.html +116 -0
  60. package/coverage/lcov-report/lib/uuid.js.html +112 -0
  61. package/coverage/lcov-report/models/Models.js.html +1489 -0
  62. package/coverage/lcov-report/models/SkeletonUtils.js.html +1879 -0
  63. package/coverage/lcov-report/models/index.html +131 -0
  64. package/coverage/lcov-report/physics/constants.js.html +307 -0
  65. package/coverage/lcov-report/physics/hitbox.js.html +235 -0
  66. package/coverage/lcov-report/physics/index.html +176 -0
  67. package/coverage/lcov-report/physics/index.js.html +1324 -0
  68. package/coverage/lcov-report/physics/messages.js.html +238 -0
  69. package/coverage/lcov-report/physics/utils.js.html +679 -0
  70. package/coverage/lcov-report/physics/worker/effects.js.html +325 -0
  71. package/coverage/lcov-report/physics/worker/elements.js.html +694 -0
  72. package/coverage/lcov-report/physics/worker/index.html +176 -0
  73. package/coverage/lcov-report/physics/worker/lib/dispatcher.js.html +160 -0
  74. package/coverage/lcov-report/physics/worker/lib/index.html +131 -0
  75. package/coverage/lcov-report/physics/worker/lib/math.js.html +109 -0
  76. package/coverage/lcov-report/physics/worker/player.js.html +301 -0
  77. package/coverage/lcov-report/physics/worker/vehicles.js.html +832 -0
  78. package/coverage/lcov-report/physics/worker/world.js.html +796 -0
  79. package/coverage/lcov-report/prettify.css +1 -0
  80. package/coverage/lcov-report/prettify.js +2 -0
  81. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  82. package/coverage/lcov-report/sorter.js +210 -0
  83. package/coverage/lcov.info +6368 -0
  84. package/dist/mage.js +8012 -9023
  85. package/eslint.config.js +73 -0
  86. package/jest.config.js +31 -0
  87. package/package.json +17 -5
@@ -0,0 +1,1489 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for models/Models.js</title>
7
+ <meta charset="utf-8" />
8
+ <link rel="stylesheet" href="../prettify.css" />
9
+ <link rel="stylesheet" href="../base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="../favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
12
+ <style type='text/css'>
13
+ .coverage-summary .sorter {
14
+ background-image: url(../sort-arrow-sprite.png);
15
+ }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <div class='wrapper'>
21
+ <div class='pad1'>
22
+ <h1><a href="../index.html">All files</a> / <a href="index.html">models</a> Models.js</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">21.46% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>41/191</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">1.81% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>2/110</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">14.63% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>6/41</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">22.16% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>41/185</span>
50
+ </div>
51
+
52
+
53
+ </div>
54
+ <p class="quiet">
55
+ Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
+ </p>
57
+ <template id="filterTemplate">
58
+ <div class="quiet">
59
+ Filter:
60
+ <input type="search" id="fileSearch">
61
+ </div>
62
+ </template>
63
+ </div>
64
+ <div class='status-line low'></div>
65
+ <pre><table class="coverage">
66
+ <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
+ <a name='L2'></a><a href='#L2'>2</a>
68
+ <a name='L3'></a><a href='#L3'>3</a>
69
+ <a name='L4'></a><a href='#L4'>4</a>
70
+ <a name='L5'></a><a href='#L5'>5</a>
71
+ <a name='L6'></a><a href='#L6'>6</a>
72
+ <a name='L7'></a><a href='#L7'>7</a>
73
+ <a name='L8'></a><a href='#L8'>8</a>
74
+ <a name='L9'></a><a href='#L9'>9</a>
75
+ <a name='L10'></a><a href='#L10'>10</a>
76
+ <a name='L11'></a><a href='#L11'>11</a>
77
+ <a name='L12'></a><a href='#L12'>12</a>
78
+ <a name='L13'></a><a href='#L13'>13</a>
79
+ <a name='L14'></a><a href='#L14'>14</a>
80
+ <a name='L15'></a><a href='#L15'>15</a>
81
+ <a name='L16'></a><a href='#L16'>16</a>
82
+ <a name='L17'></a><a href='#L17'>17</a>
83
+ <a name='L18'></a><a href='#L18'>18</a>
84
+ <a name='L19'></a><a href='#L19'>19</a>
85
+ <a name='L20'></a><a href='#L20'>20</a>
86
+ <a name='L21'></a><a href='#L21'>21</a>
87
+ <a name='L22'></a><a href='#L22'>22</a>
88
+ <a name='L23'></a><a href='#L23'>23</a>
89
+ <a name='L24'></a><a href='#L24'>24</a>
90
+ <a name='L25'></a><a href='#L25'>25</a>
91
+ <a name='L26'></a><a href='#L26'>26</a>
92
+ <a name='L27'></a><a href='#L27'>27</a>
93
+ <a name='L28'></a><a href='#L28'>28</a>
94
+ <a name='L29'></a><a href='#L29'>29</a>
95
+ <a name='L30'></a><a href='#L30'>30</a>
96
+ <a name='L31'></a><a href='#L31'>31</a>
97
+ <a name='L32'></a><a href='#L32'>32</a>
98
+ <a name='L33'></a><a href='#L33'>33</a>
99
+ <a name='L34'></a><a href='#L34'>34</a>
100
+ <a name='L35'></a><a href='#L35'>35</a>
101
+ <a name='L36'></a><a href='#L36'>36</a>
102
+ <a name='L37'></a><a href='#L37'>37</a>
103
+ <a name='L38'></a><a href='#L38'>38</a>
104
+ <a name='L39'></a><a href='#L39'>39</a>
105
+ <a name='L40'></a><a href='#L40'>40</a>
106
+ <a name='L41'></a><a href='#L41'>41</a>
107
+ <a name='L42'></a><a href='#L42'>42</a>
108
+ <a name='L43'></a><a href='#L43'>43</a>
109
+ <a name='L44'></a><a href='#L44'>44</a>
110
+ <a name='L45'></a><a href='#L45'>45</a>
111
+ <a name='L46'></a><a href='#L46'>46</a>
112
+ <a name='L47'></a><a href='#L47'>47</a>
113
+ <a name='L48'></a><a href='#L48'>48</a>
114
+ <a name='L49'></a><a href='#L49'>49</a>
115
+ <a name='L50'></a><a href='#L50'>50</a>
116
+ <a name='L51'></a><a href='#L51'>51</a>
117
+ <a name='L52'></a><a href='#L52'>52</a>
118
+ <a name='L53'></a><a href='#L53'>53</a>
119
+ <a name='L54'></a><a href='#L54'>54</a>
120
+ <a name='L55'></a><a href='#L55'>55</a>
121
+ <a name='L56'></a><a href='#L56'>56</a>
122
+ <a name='L57'></a><a href='#L57'>57</a>
123
+ <a name='L58'></a><a href='#L58'>58</a>
124
+ <a name='L59'></a><a href='#L59'>59</a>
125
+ <a name='L60'></a><a href='#L60'>60</a>
126
+ <a name='L61'></a><a href='#L61'>61</a>
127
+ <a name='L62'></a><a href='#L62'>62</a>
128
+ <a name='L63'></a><a href='#L63'>63</a>
129
+ <a name='L64'></a><a href='#L64'>64</a>
130
+ <a name='L65'></a><a href='#L65'>65</a>
131
+ <a name='L66'></a><a href='#L66'>66</a>
132
+ <a name='L67'></a><a href='#L67'>67</a>
133
+ <a name='L68'></a><a href='#L68'>68</a>
134
+ <a name='L69'></a><a href='#L69'>69</a>
135
+ <a name='L70'></a><a href='#L70'>70</a>
136
+ <a name='L71'></a><a href='#L71'>71</a>
137
+ <a name='L72'></a><a href='#L72'>72</a>
138
+ <a name='L73'></a><a href='#L73'>73</a>
139
+ <a name='L74'></a><a href='#L74'>74</a>
140
+ <a name='L75'></a><a href='#L75'>75</a>
141
+ <a name='L76'></a><a href='#L76'>76</a>
142
+ <a name='L77'></a><a href='#L77'>77</a>
143
+ <a name='L78'></a><a href='#L78'>78</a>
144
+ <a name='L79'></a><a href='#L79'>79</a>
145
+ <a name='L80'></a><a href='#L80'>80</a>
146
+ <a name='L81'></a><a href='#L81'>81</a>
147
+ <a name='L82'></a><a href='#L82'>82</a>
148
+ <a name='L83'></a><a href='#L83'>83</a>
149
+ <a name='L84'></a><a href='#L84'>84</a>
150
+ <a name='L85'></a><a href='#L85'>85</a>
151
+ <a name='L86'></a><a href='#L86'>86</a>
152
+ <a name='L87'></a><a href='#L87'>87</a>
153
+ <a name='L88'></a><a href='#L88'>88</a>
154
+ <a name='L89'></a><a href='#L89'>89</a>
155
+ <a name='L90'></a><a href='#L90'>90</a>
156
+ <a name='L91'></a><a href='#L91'>91</a>
157
+ <a name='L92'></a><a href='#L92'>92</a>
158
+ <a name='L93'></a><a href='#L93'>93</a>
159
+ <a name='L94'></a><a href='#L94'>94</a>
160
+ <a name='L95'></a><a href='#L95'>95</a>
161
+ <a name='L96'></a><a href='#L96'>96</a>
162
+ <a name='L97'></a><a href='#L97'>97</a>
163
+ <a name='L98'></a><a href='#L98'>98</a>
164
+ <a name='L99'></a><a href='#L99'>99</a>
165
+ <a name='L100'></a><a href='#L100'>100</a>
166
+ <a name='L101'></a><a href='#L101'>101</a>
167
+ <a name='L102'></a><a href='#L102'>102</a>
168
+ <a name='L103'></a><a href='#L103'>103</a>
169
+ <a name='L104'></a><a href='#L104'>104</a>
170
+ <a name='L105'></a><a href='#L105'>105</a>
171
+ <a name='L106'></a><a href='#L106'>106</a>
172
+ <a name='L107'></a><a href='#L107'>107</a>
173
+ <a name='L108'></a><a href='#L108'>108</a>
174
+ <a name='L109'></a><a href='#L109'>109</a>
175
+ <a name='L110'></a><a href='#L110'>110</a>
176
+ <a name='L111'></a><a href='#L111'>111</a>
177
+ <a name='L112'></a><a href='#L112'>112</a>
178
+ <a name='L113'></a><a href='#L113'>113</a>
179
+ <a name='L114'></a><a href='#L114'>114</a>
180
+ <a name='L115'></a><a href='#L115'>115</a>
181
+ <a name='L116'></a><a href='#L116'>116</a>
182
+ <a name='L117'></a><a href='#L117'>117</a>
183
+ <a name='L118'></a><a href='#L118'>118</a>
184
+ <a name='L119'></a><a href='#L119'>119</a>
185
+ <a name='L120'></a><a href='#L120'>120</a>
186
+ <a name='L121'></a><a href='#L121'>121</a>
187
+ <a name='L122'></a><a href='#L122'>122</a>
188
+ <a name='L123'></a><a href='#L123'>123</a>
189
+ <a name='L124'></a><a href='#L124'>124</a>
190
+ <a name='L125'></a><a href='#L125'>125</a>
191
+ <a name='L126'></a><a href='#L126'>126</a>
192
+ <a name='L127'></a><a href='#L127'>127</a>
193
+ <a name='L128'></a><a href='#L128'>128</a>
194
+ <a name='L129'></a><a href='#L129'>129</a>
195
+ <a name='L130'></a><a href='#L130'>130</a>
196
+ <a name='L131'></a><a href='#L131'>131</a>
197
+ <a name='L132'></a><a href='#L132'>132</a>
198
+ <a name='L133'></a><a href='#L133'>133</a>
199
+ <a name='L134'></a><a href='#L134'>134</a>
200
+ <a name='L135'></a><a href='#L135'>135</a>
201
+ <a name='L136'></a><a href='#L136'>136</a>
202
+ <a name='L137'></a><a href='#L137'>137</a>
203
+ <a name='L138'></a><a href='#L138'>138</a>
204
+ <a name='L139'></a><a href='#L139'>139</a>
205
+ <a name='L140'></a><a href='#L140'>140</a>
206
+ <a name='L141'></a><a href='#L141'>141</a>
207
+ <a name='L142'></a><a href='#L142'>142</a>
208
+ <a name='L143'></a><a href='#L143'>143</a>
209
+ <a name='L144'></a><a href='#L144'>144</a>
210
+ <a name='L145'></a><a href='#L145'>145</a>
211
+ <a name='L146'></a><a href='#L146'>146</a>
212
+ <a name='L147'></a><a href='#L147'>147</a>
213
+ <a name='L148'></a><a href='#L148'>148</a>
214
+ <a name='L149'></a><a href='#L149'>149</a>
215
+ <a name='L150'></a><a href='#L150'>150</a>
216
+ <a name='L151'></a><a href='#L151'>151</a>
217
+ <a name='L152'></a><a href='#L152'>152</a>
218
+ <a name='L153'></a><a href='#L153'>153</a>
219
+ <a name='L154'></a><a href='#L154'>154</a>
220
+ <a name='L155'></a><a href='#L155'>155</a>
221
+ <a name='L156'></a><a href='#L156'>156</a>
222
+ <a name='L157'></a><a href='#L157'>157</a>
223
+ <a name='L158'></a><a href='#L158'>158</a>
224
+ <a name='L159'></a><a href='#L159'>159</a>
225
+ <a name='L160'></a><a href='#L160'>160</a>
226
+ <a name='L161'></a><a href='#L161'>161</a>
227
+ <a name='L162'></a><a href='#L162'>162</a>
228
+ <a name='L163'></a><a href='#L163'>163</a>
229
+ <a name='L164'></a><a href='#L164'>164</a>
230
+ <a name='L165'></a><a href='#L165'>165</a>
231
+ <a name='L166'></a><a href='#L166'>166</a>
232
+ <a name='L167'></a><a href='#L167'>167</a>
233
+ <a name='L168'></a><a href='#L168'>168</a>
234
+ <a name='L169'></a><a href='#L169'>169</a>
235
+ <a name='L170'></a><a href='#L170'>170</a>
236
+ <a name='L171'></a><a href='#L171'>171</a>
237
+ <a name='L172'></a><a href='#L172'>172</a>
238
+ <a name='L173'></a><a href='#L173'>173</a>
239
+ <a name='L174'></a><a href='#L174'>174</a>
240
+ <a name='L175'></a><a href='#L175'>175</a>
241
+ <a name='L176'></a><a href='#L176'>176</a>
242
+ <a name='L177'></a><a href='#L177'>177</a>
243
+ <a name='L178'></a><a href='#L178'>178</a>
244
+ <a name='L179'></a><a href='#L179'>179</a>
245
+ <a name='L180'></a><a href='#L180'>180</a>
246
+ <a name='L181'></a><a href='#L181'>181</a>
247
+ <a name='L182'></a><a href='#L182'>182</a>
248
+ <a name='L183'></a><a href='#L183'>183</a>
249
+ <a name='L184'></a><a href='#L184'>184</a>
250
+ <a name='L185'></a><a href='#L185'>185</a>
251
+ <a name='L186'></a><a href='#L186'>186</a>
252
+ <a name='L187'></a><a href='#L187'>187</a>
253
+ <a name='L188'></a><a href='#L188'>188</a>
254
+ <a name='L189'></a><a href='#L189'>189</a>
255
+ <a name='L190'></a><a href='#L190'>190</a>
256
+ <a name='L191'></a><a href='#L191'>191</a>
257
+ <a name='L192'></a><a href='#L192'>192</a>
258
+ <a name='L193'></a><a href='#L193'>193</a>
259
+ <a name='L194'></a><a href='#L194'>194</a>
260
+ <a name='L195'></a><a href='#L195'>195</a>
261
+ <a name='L196'></a><a href='#L196'>196</a>
262
+ <a name='L197'></a><a href='#L197'>197</a>
263
+ <a name='L198'></a><a href='#L198'>198</a>
264
+ <a name='L199'></a><a href='#L199'>199</a>
265
+ <a name='L200'></a><a href='#L200'>200</a>
266
+ <a name='L201'></a><a href='#L201'>201</a>
267
+ <a name='L202'></a><a href='#L202'>202</a>
268
+ <a name='L203'></a><a href='#L203'>203</a>
269
+ <a name='L204'></a><a href='#L204'>204</a>
270
+ <a name='L205'></a><a href='#L205'>205</a>
271
+ <a name='L206'></a><a href='#L206'>206</a>
272
+ <a name='L207'></a><a href='#L207'>207</a>
273
+ <a name='L208'></a><a href='#L208'>208</a>
274
+ <a name='L209'></a><a href='#L209'>209</a>
275
+ <a name='L210'></a><a href='#L210'>210</a>
276
+ <a name='L211'></a><a href='#L211'>211</a>
277
+ <a name='L212'></a><a href='#L212'>212</a>
278
+ <a name='L213'></a><a href='#L213'>213</a>
279
+ <a name='L214'></a><a href='#L214'>214</a>
280
+ <a name='L215'></a><a href='#L215'>215</a>
281
+ <a name='L216'></a><a href='#L216'>216</a>
282
+ <a name='L217'></a><a href='#L217'>217</a>
283
+ <a name='L218'></a><a href='#L218'>218</a>
284
+ <a name='L219'></a><a href='#L219'>219</a>
285
+ <a name='L220'></a><a href='#L220'>220</a>
286
+ <a name='L221'></a><a href='#L221'>221</a>
287
+ <a name='L222'></a><a href='#L222'>222</a>
288
+ <a name='L223'></a><a href='#L223'>223</a>
289
+ <a name='L224'></a><a href='#L224'>224</a>
290
+ <a name='L225'></a><a href='#L225'>225</a>
291
+ <a name='L226'></a><a href='#L226'>226</a>
292
+ <a name='L227'></a><a href='#L227'>227</a>
293
+ <a name='L228'></a><a href='#L228'>228</a>
294
+ <a name='L229'></a><a href='#L229'>229</a>
295
+ <a name='L230'></a><a href='#L230'>230</a>
296
+ <a name='L231'></a><a href='#L231'>231</a>
297
+ <a name='L232'></a><a href='#L232'>232</a>
298
+ <a name='L233'></a><a href='#L233'>233</a>
299
+ <a name='L234'></a><a href='#L234'>234</a>
300
+ <a name='L235'></a><a href='#L235'>235</a>
301
+ <a name='L236'></a><a href='#L236'>236</a>
302
+ <a name='L237'></a><a href='#L237'>237</a>
303
+ <a name='L238'></a><a href='#L238'>238</a>
304
+ <a name='L239'></a><a href='#L239'>239</a>
305
+ <a name='L240'></a><a href='#L240'>240</a>
306
+ <a name='L241'></a><a href='#L241'>241</a>
307
+ <a name='L242'></a><a href='#L242'>242</a>
308
+ <a name='L243'></a><a href='#L243'>243</a>
309
+ <a name='L244'></a><a href='#L244'>244</a>
310
+ <a name='L245'></a><a href='#L245'>245</a>
311
+ <a name='L246'></a><a href='#L246'>246</a>
312
+ <a name='L247'></a><a href='#L247'>247</a>
313
+ <a name='L248'></a><a href='#L248'>248</a>
314
+ <a name='L249'></a><a href='#L249'>249</a>
315
+ <a name='L250'></a><a href='#L250'>250</a>
316
+ <a name='L251'></a><a href='#L251'>251</a>
317
+ <a name='L252'></a><a href='#L252'>252</a>
318
+ <a name='L253'></a><a href='#L253'>253</a>
319
+ <a name='L254'></a><a href='#L254'>254</a>
320
+ <a name='L255'></a><a href='#L255'>255</a>
321
+ <a name='L256'></a><a href='#L256'>256</a>
322
+ <a name='L257'></a><a href='#L257'>257</a>
323
+ <a name='L258'></a><a href='#L258'>258</a>
324
+ <a name='L259'></a><a href='#L259'>259</a>
325
+ <a name='L260'></a><a href='#L260'>260</a>
326
+ <a name='L261'></a><a href='#L261'>261</a>
327
+ <a name='L262'></a><a href='#L262'>262</a>
328
+ <a name='L263'></a><a href='#L263'>263</a>
329
+ <a name='L264'></a><a href='#L264'>264</a>
330
+ <a name='L265'></a><a href='#L265'>265</a>
331
+ <a name='L266'></a><a href='#L266'>266</a>
332
+ <a name='L267'></a><a href='#L267'>267</a>
333
+ <a name='L268'></a><a href='#L268'>268</a>
334
+ <a name='L269'></a><a href='#L269'>269</a>
335
+ <a name='L270'></a><a href='#L270'>270</a>
336
+ <a name='L271'></a><a href='#L271'>271</a>
337
+ <a name='L272'></a><a href='#L272'>272</a>
338
+ <a name='L273'></a><a href='#L273'>273</a>
339
+ <a name='L274'></a><a href='#L274'>274</a>
340
+ <a name='L275'></a><a href='#L275'>275</a>
341
+ <a name='L276'></a><a href='#L276'>276</a>
342
+ <a name='L277'></a><a href='#L277'>277</a>
343
+ <a name='L278'></a><a href='#L278'>278</a>
344
+ <a name='L279'></a><a href='#L279'>279</a>
345
+ <a name='L280'></a><a href='#L280'>280</a>
346
+ <a name='L281'></a><a href='#L281'>281</a>
347
+ <a name='L282'></a><a href='#L282'>282</a>
348
+ <a name='L283'></a><a href='#L283'>283</a>
349
+ <a name='L284'></a><a href='#L284'>284</a>
350
+ <a name='L285'></a><a href='#L285'>285</a>
351
+ <a name='L286'></a><a href='#L286'>286</a>
352
+ <a name='L287'></a><a href='#L287'>287</a>
353
+ <a name='L288'></a><a href='#L288'>288</a>
354
+ <a name='L289'></a><a href='#L289'>289</a>
355
+ <a name='L290'></a><a href='#L290'>290</a>
356
+ <a name='L291'></a><a href='#L291'>291</a>
357
+ <a name='L292'></a><a href='#L292'>292</a>
358
+ <a name='L293'></a><a href='#L293'>293</a>
359
+ <a name='L294'></a><a href='#L294'>294</a>
360
+ <a name='L295'></a><a href='#L295'>295</a>
361
+ <a name='L296'></a><a href='#L296'>296</a>
362
+ <a name='L297'></a><a href='#L297'>297</a>
363
+ <a name='L298'></a><a href='#L298'>298</a>
364
+ <a name='L299'></a><a href='#L299'>299</a>
365
+ <a name='L300'></a><a href='#L300'>300</a>
366
+ <a name='L301'></a><a href='#L301'>301</a>
367
+ <a name='L302'></a><a href='#L302'>302</a>
368
+ <a name='L303'></a><a href='#L303'>303</a>
369
+ <a name='L304'></a><a href='#L304'>304</a>
370
+ <a name='L305'></a><a href='#L305'>305</a>
371
+ <a name='L306'></a><a href='#L306'>306</a>
372
+ <a name='L307'></a><a href='#L307'>307</a>
373
+ <a name='L308'></a><a href='#L308'>308</a>
374
+ <a name='L309'></a><a href='#L309'>309</a>
375
+ <a name='L310'></a><a href='#L310'>310</a>
376
+ <a name='L311'></a><a href='#L311'>311</a>
377
+ <a name='L312'></a><a href='#L312'>312</a>
378
+ <a name='L313'></a><a href='#L313'>313</a>
379
+ <a name='L314'></a><a href='#L314'>314</a>
380
+ <a name='L315'></a><a href='#L315'>315</a>
381
+ <a name='L316'></a><a href='#L316'>316</a>
382
+ <a name='L317'></a><a href='#L317'>317</a>
383
+ <a name='L318'></a><a href='#L318'>318</a>
384
+ <a name='L319'></a><a href='#L319'>319</a>
385
+ <a name='L320'></a><a href='#L320'>320</a>
386
+ <a name='L321'></a><a href='#L321'>321</a>
387
+ <a name='L322'></a><a href='#L322'>322</a>
388
+ <a name='L323'></a><a href='#L323'>323</a>
389
+ <a name='L324'></a><a href='#L324'>324</a>
390
+ <a name='L325'></a><a href='#L325'>325</a>
391
+ <a name='L326'></a><a href='#L326'>326</a>
392
+ <a name='L327'></a><a href='#L327'>327</a>
393
+ <a name='L328'></a><a href='#L328'>328</a>
394
+ <a name='L329'></a><a href='#L329'>329</a>
395
+ <a name='L330'></a><a href='#L330'>330</a>
396
+ <a name='L331'></a><a href='#L331'>331</a>
397
+ <a name='L332'></a><a href='#L332'>332</a>
398
+ <a name='L333'></a><a href='#L333'>333</a>
399
+ <a name='L334'></a><a href='#L334'>334</a>
400
+ <a name='L335'></a><a href='#L335'>335</a>
401
+ <a name='L336'></a><a href='#L336'>336</a>
402
+ <a name='L337'></a><a href='#L337'>337</a>
403
+ <a name='L338'></a><a href='#L338'>338</a>
404
+ <a name='L339'></a><a href='#L339'>339</a>
405
+ <a name='L340'></a><a href='#L340'>340</a>
406
+ <a name='L341'></a><a href='#L341'>341</a>
407
+ <a name='L342'></a><a href='#L342'>342</a>
408
+ <a name='L343'></a><a href='#L343'>343</a>
409
+ <a name='L344'></a><a href='#L344'>344</a>
410
+ <a name='L345'></a><a href='#L345'>345</a>
411
+ <a name='L346'></a><a href='#L346'>346</a>
412
+ <a name='L347'></a><a href='#L347'>347</a>
413
+ <a name='L348'></a><a href='#L348'>348</a>
414
+ <a name='L349'></a><a href='#L349'>349</a>
415
+ <a name='L350'></a><a href='#L350'>350</a>
416
+ <a name='L351'></a><a href='#L351'>351</a>
417
+ <a name='L352'></a><a href='#L352'>352</a>
418
+ <a name='L353'></a><a href='#L353'>353</a>
419
+ <a name='L354'></a><a href='#L354'>354</a>
420
+ <a name='L355'></a><a href='#L355'>355</a>
421
+ <a name='L356'></a><a href='#L356'>356</a>
422
+ <a name='L357'></a><a href='#L357'>357</a>
423
+ <a name='L358'></a><a href='#L358'>358</a>
424
+ <a name='L359'></a><a href='#L359'>359</a>
425
+ <a name='L360'></a><a href='#L360'>360</a>
426
+ <a name='L361'></a><a href='#L361'>361</a>
427
+ <a name='L362'></a><a href='#L362'>362</a>
428
+ <a name='L363'></a><a href='#L363'>363</a>
429
+ <a name='L364'></a><a href='#L364'>364</a>
430
+ <a name='L365'></a><a href='#L365'>365</a>
431
+ <a name='L366'></a><a href='#L366'>366</a>
432
+ <a name='L367'></a><a href='#L367'>367</a>
433
+ <a name='L368'></a><a href='#L368'>368</a>
434
+ <a name='L369'></a><a href='#L369'>369</a>
435
+ <a name='L370'></a><a href='#L370'>370</a>
436
+ <a name='L371'></a><a href='#L371'>371</a>
437
+ <a name='L372'></a><a href='#L372'>372</a>
438
+ <a name='L373'></a><a href='#L373'>373</a>
439
+ <a name='L374'></a><a href='#L374'>374</a>
440
+ <a name='L375'></a><a href='#L375'>375</a>
441
+ <a name='L376'></a><a href='#L376'>376</a>
442
+ <a name='L377'></a><a href='#L377'>377</a>
443
+ <a name='L378'></a><a href='#L378'>378</a>
444
+ <a name='L379'></a><a href='#L379'>379</a>
445
+ <a name='L380'></a><a href='#L380'>380</a>
446
+ <a name='L381'></a><a href='#L381'>381</a>
447
+ <a name='L382'></a><a href='#L382'>382</a>
448
+ <a name='L383'></a><a href='#L383'>383</a>
449
+ <a name='L384'></a><a href='#L384'>384</a>
450
+ <a name='L385'></a><a href='#L385'>385</a>
451
+ <a name='L386'></a><a href='#L386'>386</a>
452
+ <a name='L387'></a><a href='#L387'>387</a>
453
+ <a name='L388'></a><a href='#L388'>388</a>
454
+ <a name='L389'></a><a href='#L389'>389</a>
455
+ <a name='L390'></a><a href='#L390'>390</a>
456
+ <a name='L391'></a><a href='#L391'>391</a>
457
+ <a name='L392'></a><a href='#L392'>392</a>
458
+ <a name='L393'></a><a href='#L393'>393</a>
459
+ <a name='L394'></a><a href='#L394'>394</a>
460
+ <a name='L395'></a><a href='#L395'>395</a>
461
+ <a name='L396'></a><a href='#L396'>396</a>
462
+ <a name='L397'></a><a href='#L397'>397</a>
463
+ <a name='L398'></a><a href='#L398'>398</a>
464
+ <a name='L399'></a><a href='#L399'>399</a>
465
+ <a name='L400'></a><a href='#L400'>400</a>
466
+ <a name='L401'></a><a href='#L401'>401</a>
467
+ <a name='L402'></a><a href='#L402'>402</a>
468
+ <a name='L403'></a><a href='#L403'>403</a>
469
+ <a name='L404'></a><a href='#L404'>404</a>
470
+ <a name='L405'></a><a href='#L405'>405</a>
471
+ <a name='L406'></a><a href='#L406'>406</a>
472
+ <a name='L407'></a><a href='#L407'>407</a>
473
+ <a name='L408'></a><a href='#L408'>408</a>
474
+ <a name='L409'></a><a href='#L409'>409</a>
475
+ <a name='L410'></a><a href='#L410'>410</a>
476
+ <a name='L411'></a><a href='#L411'>411</a>
477
+ <a name='L412'></a><a href='#L412'>412</a>
478
+ <a name='L413'></a><a href='#L413'>413</a>
479
+ <a name='L414'></a><a href='#L414'>414</a>
480
+ <a name='L415'></a><a href='#L415'>415</a>
481
+ <a name='L416'></a><a href='#L416'>416</a>
482
+ <a name='L417'></a><a href='#L417'>417</a>
483
+ <a name='L418'></a><a href='#L418'>418</a>
484
+ <a name='L419'></a><a href='#L419'>419</a>
485
+ <a name='L420'></a><a href='#L420'>420</a>
486
+ <a name='L421'></a><a href='#L421'>421</a>
487
+ <a name='L422'></a><a href='#L422'>422</a>
488
+ <a name='L423'></a><a href='#L423'>423</a>
489
+ <a name='L424'></a><a href='#L424'>424</a>
490
+ <a name='L425'></a><a href='#L425'>425</a>
491
+ <a name='L426'></a><a href='#L426'>426</a>
492
+ <a name='L427'></a><a href='#L427'>427</a>
493
+ <a name='L428'></a><a href='#L428'>428</a>
494
+ <a name='L429'></a><a href='#L429'>429</a>
495
+ <a name='L430'></a><a href='#L430'>430</a>
496
+ <a name='L431'></a><a href='#L431'>431</a>
497
+ <a name='L432'></a><a href='#L432'>432</a>
498
+ <a name='L433'></a><a href='#L433'>433</a>
499
+ <a name='L434'></a><a href='#L434'>434</a>
500
+ <a name='L435'></a><a href='#L435'>435</a>
501
+ <a name='L436'></a><a href='#L436'>436</a>
502
+ <a name='L437'></a><a href='#L437'>437</a>
503
+ <a name='L438'></a><a href='#L438'>438</a>
504
+ <a name='L439'></a><a href='#L439'>439</a>
505
+ <a name='L440'></a><a href='#L440'>440</a>
506
+ <a name='L441'></a><a href='#L441'>441</a>
507
+ <a name='L442'></a><a href='#L442'>442</a>
508
+ <a name='L443'></a><a href='#L443'>443</a>
509
+ <a name='L444'></a><a href='#L444'>444</a>
510
+ <a name='L445'></a><a href='#L445'>445</a>
511
+ <a name='L446'></a><a href='#L446'>446</a>
512
+ <a name='L447'></a><a href='#L447'>447</a>
513
+ <a name='L448'></a><a href='#L448'>448</a>
514
+ <a name='L449'></a><a href='#L449'>449</a>
515
+ <a name='L450'></a><a href='#L450'>450</a>
516
+ <a name='L451'></a><a href='#L451'>451</a>
517
+ <a name='L452'></a><a href='#L452'>452</a>
518
+ <a name='L453'></a><a href='#L453'>453</a>
519
+ <a name='L454'></a><a href='#L454'>454</a>
520
+ <a name='L455'></a><a href='#L455'>455</a>
521
+ <a name='L456'></a><a href='#L456'>456</a>
522
+ <a name='L457'></a><a href='#L457'>457</a>
523
+ <a name='L458'></a><a href='#L458'>458</a>
524
+ <a name='L459'></a><a href='#L459'>459</a>
525
+ <a name='L460'></a><a href='#L460'>460</a>
526
+ <a name='L461'></a><a href='#L461'>461</a>
527
+ <a name='L462'></a><a href='#L462'>462</a>
528
+ <a name='L463'></a><a href='#L463'>463</a>
529
+ <a name='L464'></a><a href='#L464'>464</a>
530
+ <a name='L465'></a><a href='#L465'>465</a>
531
+ <a name='L466'></a><a href='#L466'>466</a>
532
+ <a name='L467'></a><a href='#L467'>467</a>
533
+ <a name='L468'></a><a href='#L468'>468</a>
534
+ <a name='L469'></a><a href='#L469'>469</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
535
+ <span class="cline-any cline-neutral">&nbsp;</span>
536
+ <span class="cline-any cline-neutral">&nbsp;</span>
537
+ <span class="cline-any cline-neutral">&nbsp;</span>
538
+ <span class="cline-any cline-neutral">&nbsp;</span>
539
+ <span class="cline-any cline-neutral">&nbsp;</span>
540
+ <span class="cline-any cline-neutral">&nbsp;</span>
541
+ <span class="cline-any cline-neutral">&nbsp;</span>
542
+ <span class="cline-any cline-neutral">&nbsp;</span>
543
+ <span class="cline-any cline-neutral">&nbsp;</span>
544
+ <span class="cline-any cline-neutral">&nbsp;</span>
545
+ <span class="cline-any cline-neutral">&nbsp;</span>
546
+ <span class="cline-any cline-neutral">&nbsp;</span>
547
+ <span class="cline-any cline-neutral">&nbsp;</span>
548
+ <span class="cline-any cline-neutral">&nbsp;</span>
549
+ <span class="cline-any cline-neutral">&nbsp;</span>
550
+ <span class="cline-any cline-neutral">&nbsp;</span>
551
+ <span class="cline-any cline-neutral">&nbsp;</span>
552
+ <span class="cline-any cline-neutral">&nbsp;</span>
553
+ <span class="cline-any cline-yes">1x</span>
554
+ <span class="cline-any cline-neutral">&nbsp;</span>
555
+ <span class="cline-any cline-neutral">&nbsp;</span>
556
+ <span class="cline-any cline-neutral">&nbsp;</span>
557
+ <span class="cline-any cline-neutral">&nbsp;</span>
558
+ <span class="cline-any cline-neutral">&nbsp;</span>
559
+ <span class="cline-any cline-neutral">&nbsp;</span>
560
+ <span class="cline-any cline-neutral">&nbsp;</span>
561
+ <span class="cline-any cline-neutral">&nbsp;</span>
562
+ <span class="cline-any cline-yes">1x</span>
563
+ <span class="cline-any cline-neutral">&nbsp;</span>
564
+ <span class="cline-any cline-yes">1x</span>
565
+ <span class="cline-any cline-no">&nbsp;</span>
566
+ <span class="cline-any cline-neutral">&nbsp;</span>
567
+ <span class="cline-any cline-no">&nbsp;</span>
568
+ <span class="cline-any cline-no">&nbsp;</span>
569
+ <span class="cline-any cline-neutral">&nbsp;</span>
570
+ <span class="cline-any cline-neutral">&nbsp;</span>
571
+ <span class="cline-any cline-neutral">&nbsp;</span>
572
+ <span class="cline-any cline-neutral">&nbsp;</span>
573
+ <span class="cline-any cline-neutral">&nbsp;</span>
574
+ <span class="cline-any cline-yes">1x</span>
575
+ <span class="cline-any cline-no">&nbsp;</span>
576
+ <span class="cline-any cline-no">&nbsp;</span>
577
+ <span class="cline-any cline-no">&nbsp;</span>
578
+ <span class="cline-any cline-no">&nbsp;</span>
579
+ <span class="cline-any cline-neutral">&nbsp;</span>
580
+ <span class="cline-any cline-neutral">&nbsp;</span>
581
+ <span class="cline-any cline-yes">1x</span>
582
+ <span class="cline-any cline-neutral">&nbsp;</span>
583
+ <span class="cline-any cline-neutral">&nbsp;</span>
584
+ <span class="cline-any cline-neutral">&nbsp;</span>
585
+ <span class="cline-any cline-neutral">&nbsp;</span>
586
+ <span class="cline-any cline-neutral">&nbsp;</span>
587
+ <span class="cline-any cline-neutral">&nbsp;</span>
588
+ <span class="cline-any cline-neutral">&nbsp;</span>
589
+ <span class="cline-any cline-neutral">&nbsp;</span>
590
+ <span class="cline-any cline-neutral">&nbsp;</span>
591
+ <span class="cline-any cline-neutral">&nbsp;</span>
592
+ <span class="cline-any cline-neutral">&nbsp;</span>
593
+ <span class="cline-any cline-yes">1x</span>
594
+ <span class="cline-any cline-no">&nbsp;</span>
595
+ <span class="cline-any cline-no">&nbsp;</span>
596
+ <span class="cline-any cline-no">&nbsp;</span>
597
+ <span class="cline-any cline-neutral">&nbsp;</span>
598
+ <span class="cline-any cline-no">&nbsp;</span>
599
+ <span class="cline-any cline-neutral">&nbsp;</span>
600
+ <span class="cline-any cline-neutral">&nbsp;</span>
601
+ <span class="cline-any cline-neutral">&nbsp;</span>
602
+ <span class="cline-any cline-neutral">&nbsp;</span>
603
+ <span class="cline-any cline-neutral">&nbsp;</span>
604
+ <span class="cline-any cline-neutral">&nbsp;</span>
605
+ <span class="cline-any cline-neutral">&nbsp;</span>
606
+ <span class="cline-any cline-yes">1x</span>
607
+ <span class="cline-any cline-no">&nbsp;</span>
608
+ <span class="cline-any cline-no">&nbsp;</span>
609
+ <span class="cline-any cline-neutral">&nbsp;</span>
610
+ <span class="cline-any cline-no">&nbsp;</span>
611
+ <span class="cline-any cline-neutral">&nbsp;</span>
612
+ <span class="cline-any cline-neutral">&nbsp;</span>
613
+ <span class="cline-any cline-neutral">&nbsp;</span>
614
+ <span class="cline-any cline-neutral">&nbsp;</span>
615
+ <span class="cline-any cline-neutral">&nbsp;</span>
616
+ <span class="cline-any cline-neutral">&nbsp;</span>
617
+ <span class="cline-any cline-neutral">&nbsp;</span>
618
+ <span class="cline-any cline-neutral">&nbsp;</span>
619
+ <span class="cline-any cline-yes">1x</span>
620
+ <span class="cline-any cline-no">&nbsp;</span>
621
+ <span class="cline-any cline-neutral">&nbsp;</span>
622
+ <span class="cline-any cline-neutral">&nbsp;</span>
623
+ <span class="cline-any cline-neutral">&nbsp;</span>
624
+ <span class="cline-any cline-neutral">&nbsp;</span>
625
+ <span class="cline-any cline-neutral">&nbsp;</span>
626
+ <span class="cline-any cline-neutral">&nbsp;</span>
627
+ <span class="cline-any cline-neutral">&nbsp;</span>
628
+ <span class="cline-any cline-neutral">&nbsp;</span>
629
+ <span class="cline-any cline-neutral">&nbsp;</span>
630
+ <span class="cline-any cline-neutral">&nbsp;</span>
631
+ <span class="cline-any cline-yes">1x</span>
632
+ <span class="cline-any cline-neutral">&nbsp;</span>
633
+ <span class="cline-any cline-no">&nbsp;</span>
634
+ <span class="cline-any cline-no">&nbsp;</span>
635
+ <span class="cline-any cline-neutral">&nbsp;</span>
636
+ <span class="cline-any cline-neutral">&nbsp;</span>
637
+ <span class="cline-any cline-neutral">&nbsp;</span>
638
+ <span class="cline-any cline-neutral">&nbsp;</span>
639
+ <span class="cline-any cline-no">&nbsp;</span>
640
+ <span class="cline-any cline-no">&nbsp;</span>
641
+ <span class="cline-any cline-neutral">&nbsp;</span>
642
+ <span class="cline-any cline-neutral">&nbsp;</span>
643
+ <span class="cline-any cline-neutral">&nbsp;</span>
644
+ <span class="cline-any cline-no">&nbsp;</span>
645
+ <span class="cline-any cline-no">&nbsp;</span>
646
+ <span class="cline-any cline-no">&nbsp;</span>
647
+ <span class="cline-any cline-neutral">&nbsp;</span>
648
+ <span class="cline-any cline-neutral">&nbsp;</span>
649
+ <span class="cline-any cline-neutral">&nbsp;</span>
650
+ <span class="cline-any cline-no">&nbsp;</span>
651
+ <span class="cline-any cline-no">&nbsp;</span>
652
+ <span class="cline-any cline-neutral">&nbsp;</span>
653
+ <span class="cline-any cline-neutral">&nbsp;</span>
654
+ <span class="cline-any cline-neutral">&nbsp;</span>
655
+ <span class="cline-any cline-neutral">&nbsp;</span>
656
+ <span class="cline-any cline-no">&nbsp;</span>
657
+ <span class="cline-any cline-neutral">&nbsp;</span>
658
+ <span class="cline-any cline-neutral">&nbsp;</span>
659
+ <span class="cline-any cline-neutral">&nbsp;</span>
660
+ <span class="cline-any cline-no">&nbsp;</span>
661
+ <span class="cline-any cline-neutral">&nbsp;</span>
662
+ <span class="cline-any cline-yes">1x</span>
663
+ <span class="cline-any cline-no">&nbsp;</span>
664
+ <span class="cline-any cline-no">&nbsp;</span>
665
+ <span class="cline-any cline-neutral">&nbsp;</span>
666
+ <span class="cline-any cline-no">&nbsp;</span>
667
+ <span class="cline-any cline-neutral">&nbsp;</span>
668
+ <span class="cline-any cline-neutral">&nbsp;</span>
669
+ <span class="cline-any cline-yes">1x</span>
670
+ <span class="cline-any cline-no">&nbsp;</span>
671
+ <span class="cline-any cline-no">&nbsp;</span>
672
+ <span class="cline-any cline-neutral">&nbsp;</span>
673
+ <span class="cline-any cline-no">&nbsp;</span>
674
+ <span class="cline-any cline-neutral">&nbsp;</span>
675
+ <span class="cline-any cline-no">&nbsp;</span>
676
+ <span class="cline-any cline-neutral">&nbsp;</span>
677
+ <span class="cline-any cline-neutral">&nbsp;</span>
678
+ <span class="cline-any cline-yes">1x</span>
679
+ <span class="cline-any cline-neutral">&nbsp;</span>
680
+ <span class="cline-any cline-no">&nbsp;</span>
681
+ <span class="cline-any cline-no">&nbsp;</span>
682
+ <span class="cline-any cline-neutral">&nbsp;</span>
683
+ <span class="cline-any cline-neutral">&nbsp;</span>
684
+ <span class="cline-any cline-neutral">&nbsp;</span>
685
+ <span class="cline-any cline-no">&nbsp;</span>
686
+ <span class="cline-any cline-neutral">&nbsp;</span>
687
+ <span class="cline-any cline-neutral">&nbsp;</span>
688
+ <span class="cline-any cline-no">&nbsp;</span>
689
+ <span class="cline-any cline-no">&nbsp;</span>
690
+ <span class="cline-any cline-no">&nbsp;</span>
691
+ <span class="cline-any cline-no">&nbsp;</span>
692
+ <span class="cline-any cline-neutral">&nbsp;</span>
693
+ <span class="cline-any cline-no">&nbsp;</span>
694
+ <span class="cline-any cline-no">&nbsp;</span>
695
+ <span class="cline-any cline-neutral">&nbsp;</span>
696
+ <span class="cline-any cline-neutral">&nbsp;</span>
697
+ <span class="cline-any cline-neutral">&nbsp;</span>
698
+ <span class="cline-any cline-no">&nbsp;</span>
699
+ <span class="cline-any cline-neutral">&nbsp;</span>
700
+ <span class="cline-any cline-neutral">&nbsp;</span>
701
+ <span class="cline-any cline-neutral">&nbsp;</span>
702
+ <span class="cline-any cline-neutral">&nbsp;</span>
703
+ <span class="cline-any cline-yes">1x</span>
704
+ <span class="cline-any cline-neutral">&nbsp;</span>
705
+ <span class="cline-any cline-no">&nbsp;</span>
706
+ <span class="cline-any cline-no">&nbsp;</span>
707
+ <span class="cline-any cline-neutral">&nbsp;</span>
708
+ <span class="cline-any cline-neutral">&nbsp;</span>
709
+ <span class="cline-any cline-neutral">&nbsp;</span>
710
+ <span class="cline-any cline-no">&nbsp;</span>
711
+ <span class="cline-any cline-neutral">&nbsp;</span>
712
+ <span class="cline-any cline-neutral">&nbsp;</span>
713
+ <span class="cline-any cline-no">&nbsp;</span>
714
+ <span class="cline-any cline-no">&nbsp;</span>
715
+ <span class="cline-any cline-no">&nbsp;</span>
716
+ <span class="cline-any cline-neutral">&nbsp;</span>
717
+ <span class="cline-any cline-neutral">&nbsp;</span>
718
+ <span class="cline-any cline-neutral">&nbsp;</span>
719
+ <span class="cline-any cline-no">&nbsp;</span>
720
+ <span class="cline-any cline-neutral">&nbsp;</span>
721
+ <span class="cline-any cline-yes">1x</span>
722
+ <span class="cline-any cline-neutral">&nbsp;</span>
723
+ <span class="cline-any cline-no">&nbsp;</span>
724
+ <span class="cline-any cline-no">&nbsp;</span>
725
+ <span class="cline-any cline-neutral">&nbsp;</span>
726
+ <span class="cline-any cline-neutral">&nbsp;</span>
727
+ <span class="cline-any cline-neutral">&nbsp;</span>
728
+ <span class="cline-any cline-neutral">&nbsp;</span>
729
+ <span class="cline-any cline-no">&nbsp;</span>
730
+ <span class="cline-any cline-neutral">&nbsp;</span>
731
+ <span class="cline-any cline-no">&nbsp;</span>
732
+ <span class="cline-any cline-neutral">&nbsp;</span>
733
+ <span class="cline-any cline-yes">1x</span>
734
+ <span class="cline-any cline-neutral">&nbsp;</span>
735
+ <span class="cline-any cline-no">&nbsp;</span>
736
+ <span class="cline-any cline-no">&nbsp;</span>
737
+ <span class="cline-any cline-neutral">&nbsp;</span>
738
+ <span class="cline-any cline-neutral">&nbsp;</span>
739
+ <span class="cline-any cline-neutral">&nbsp;</span>
740
+ <span class="cline-any cline-no">&nbsp;</span>
741
+ <span class="cline-any cline-neutral">&nbsp;</span>
742
+ <span class="cline-any cline-neutral">&nbsp;</span>
743
+ <span class="cline-any cline-no">&nbsp;</span>
744
+ <span class="cline-any cline-no">&nbsp;</span>
745
+ <span class="cline-any cline-no">&nbsp;</span>
746
+ <span class="cline-any cline-no">&nbsp;</span>
747
+ <span class="cline-any cline-neutral">&nbsp;</span>
748
+ <span class="cline-any cline-neutral">&nbsp;</span>
749
+ <span class="cline-any cline-neutral">&nbsp;</span>
750
+ <span class="cline-any cline-no">&nbsp;</span>
751
+ <span class="cline-any cline-neutral">&nbsp;</span>
752
+ <span class="cline-any cline-neutral">&nbsp;</span>
753
+ <span class="cline-any cline-neutral">&nbsp;</span>
754
+ <span class="cline-any cline-neutral">&nbsp;</span>
755
+ <span class="cline-any cline-neutral">&nbsp;</span>
756
+ <span class="cline-any cline-neutral">&nbsp;</span>
757
+ <span class="cline-any cline-yes">1x</span>
758
+ <span class="cline-any cline-neutral">&nbsp;</span>
759
+ <span class="cline-any cline-no">&nbsp;</span>
760
+ <span class="cline-any cline-no">&nbsp;</span>
761
+ <span class="cline-any cline-neutral">&nbsp;</span>
762
+ <span class="cline-any cline-neutral">&nbsp;</span>
763
+ <span class="cline-any cline-neutral">&nbsp;</span>
764
+ <span class="cline-any cline-neutral">&nbsp;</span>
765
+ <span class="cline-any cline-no">&nbsp;</span>
766
+ <span class="cline-any cline-neutral">&nbsp;</span>
767
+ <span class="cline-any cline-neutral">&nbsp;</span>
768
+ <span class="cline-any cline-no">&nbsp;</span>
769
+ <span class="cline-any cline-no">&nbsp;</span>
770
+ <span class="cline-any cline-no">&nbsp;</span>
771
+ <span class="cline-any cline-no">&nbsp;</span>
772
+ <span class="cline-any cline-neutral">&nbsp;</span>
773
+ <span class="cline-any cline-neutral">&nbsp;</span>
774
+ <span class="cline-any cline-neutral">&nbsp;</span>
775
+ <span class="cline-any cline-no">&nbsp;</span>
776
+ <span class="cline-any cline-neutral">&nbsp;</span>
777
+ <span class="cline-any cline-neutral">&nbsp;</span>
778
+ <span class="cline-any cline-yes">1x</span>
779
+ <span class="cline-any cline-no">&nbsp;</span>
780
+ <span class="cline-any cline-neutral">&nbsp;</span>
781
+ <span class="cline-any cline-neutral">&nbsp;</span>
782
+ <span class="cline-any cline-neutral">&nbsp;</span>
783
+ <span class="cline-any cline-neutral">&nbsp;</span>
784
+ <span class="cline-any cline-neutral">&nbsp;</span>
785
+ <span class="cline-any cline-neutral">&nbsp;</span>
786
+ <span class="cline-any cline-neutral">&nbsp;</span>
787
+ <span class="cline-any cline-yes">1x</span>
788
+ <span class="cline-any cline-neutral">&nbsp;</span>
789
+ <span class="cline-any cline-neutral">&nbsp;</span>
790
+ <span class="cline-any cline-neutral">&nbsp;</span>
791
+ <span class="cline-any cline-yes">1x</span>
792
+ <span class="cline-any cline-yes">1x</span>
793
+ <span class="cline-any cline-yes">1x</span>
794
+ <span class="cline-any cline-yes">1x</span>
795
+ <span class="cline-any cline-neutral">&nbsp;</span>
796
+ <span class="cline-any cline-neutral">&nbsp;</span>
797
+ <span class="cline-any cline-yes">1x</span>
798
+ <span class="cline-any cline-yes">1x</span>
799
+ <span class="cline-any cline-neutral">&nbsp;</span>
800
+ <span class="cline-any cline-neutral">&nbsp;</span>
801
+ <span class="cline-any cline-yes">1x</span>
802
+ <span class="cline-any cline-yes">2x</span>
803
+ <span class="cline-any cline-neutral">&nbsp;</span>
804
+ <span class="cline-any cline-neutral">&nbsp;</span>
805
+ <span class="cline-any cline-yes">1x</span>
806
+ <span class="cline-any cline-no">&nbsp;</span>
807
+ <span class="cline-any cline-no">&nbsp;</span>
808
+ <span class="cline-any cline-neutral">&nbsp;</span>
809
+ <span class="cline-any cline-neutral">&nbsp;</span>
810
+ <span class="cline-any cline-yes">1x</span>
811
+ <span class="cline-any cline-no">&nbsp;</span>
812
+ <span class="cline-any cline-no">&nbsp;</span>
813
+ <span class="cline-any cline-neutral">&nbsp;</span>
814
+ <span class="cline-any cline-neutral">&nbsp;</span>
815
+ <span class="cline-any cline-yes">1x</span>
816
+ <span class="cline-any cline-no">&nbsp;</span>
817
+ <span class="cline-any cline-no">&nbsp;</span>
818
+ <span class="cline-any cline-neutral">&nbsp;</span>
819
+ <span class="cline-any cline-no">&nbsp;</span>
820
+ <span class="cline-any cline-no">&nbsp;</span>
821
+ <span class="cline-any cline-no">&nbsp;</span>
822
+ <span class="cline-any cline-neutral">&nbsp;</span>
823
+ <span class="cline-any cline-neutral">&nbsp;</span>
824
+ <span class="cline-any cline-no">&nbsp;</span>
825
+ <span class="cline-any cline-neutral">&nbsp;</span>
826
+ <span class="cline-any cline-neutral">&nbsp;</span>
827
+ <span class="cline-any cline-no">&nbsp;</span>
828
+ <span class="cline-any cline-neutral">&nbsp;</span>
829
+ <span class="cline-any cline-neutral">&nbsp;</span>
830
+ <span class="cline-any cline-neutral">&nbsp;</span>
831
+ <span class="cline-any cline-neutral">&nbsp;</span>
832
+ <span class="cline-any cline-neutral">&nbsp;</span>
833
+ <span class="cline-any cline-neutral">&nbsp;</span>
834
+ <span class="cline-any cline-neutral">&nbsp;</span>
835
+ <span class="cline-any cline-neutral">&nbsp;</span>
836
+ <span class="cline-any cline-no">&nbsp;</span>
837
+ <span class="cline-any cline-no">&nbsp;</span>
838
+ <span class="cline-any cline-no">&nbsp;</span>
839
+ <span class="cline-any cline-no">&nbsp;</span>
840
+ <span class="cline-any cline-no">&nbsp;</span>
841
+ <span class="cline-any cline-neutral">&nbsp;</span>
842
+ <span class="cline-any cline-no">&nbsp;</span>
843
+ <span class="cline-any cline-neutral">&nbsp;</span>
844
+ <span class="cline-any cline-neutral">&nbsp;</span>
845
+ <span class="cline-any cline-no">&nbsp;</span>
846
+ <span class="cline-any cline-no">&nbsp;</span>
847
+ <span class="cline-any cline-no">&nbsp;</span>
848
+ <span class="cline-any cline-neutral">&nbsp;</span>
849
+ <span class="cline-any cline-neutral">&nbsp;</span>
850
+ <span class="cline-any cline-no">&nbsp;</span>
851
+ <span class="cline-any cline-neutral">&nbsp;</span>
852
+ <span class="cline-any cline-neutral">&nbsp;</span>
853
+ <span class="cline-any cline-neutral">&nbsp;</span>
854
+ <span class="cline-any cline-neutral">&nbsp;</span>
855
+ <span class="cline-any cline-neutral">&nbsp;</span>
856
+ <span class="cline-any cline-neutral">&nbsp;</span>
857
+ <span class="cline-any cline-neutral">&nbsp;</span>
858
+ <span class="cline-any cline-neutral">&nbsp;</span>
859
+ <span class="cline-any cline-no">&nbsp;</span>
860
+ <span class="cline-any cline-no">&nbsp;</span>
861
+ <span class="cline-any cline-no">&nbsp;</span>
862
+ <span class="cline-any cline-no">&nbsp;</span>
863
+ <span class="cline-any cline-neutral">&nbsp;</span>
864
+ <span class="cline-any cline-neutral">&nbsp;</span>
865
+ <span class="cline-any cline-neutral">&nbsp;</span>
866
+ <span class="cline-any cline-neutral">&nbsp;</span>
867
+ <span class="cline-any cline-neutral">&nbsp;</span>
868
+ <span class="cline-any cline-no">&nbsp;</span>
869
+ <span class="cline-any cline-neutral">&nbsp;</span>
870
+ <span class="cline-any cline-no">&nbsp;</span>
871
+ <span class="cline-any cline-no">&nbsp;</span>
872
+ <span class="cline-any cline-no">&nbsp;</span>
873
+ <span class="cline-any cline-neutral">&nbsp;</span>
874
+ <span class="cline-any cline-no">&nbsp;</span>
875
+ <span class="cline-any cline-neutral">&nbsp;</span>
876
+ <span class="cline-any cline-neutral">&nbsp;</span>
877
+ <span class="cline-any cline-no">&nbsp;</span>
878
+ <span class="cline-any cline-no">&nbsp;</span>
879
+ <span class="cline-any cline-neutral">&nbsp;</span>
880
+ <span class="cline-any cline-neutral">&nbsp;</span>
881
+ <span class="cline-any cline-neutral">&nbsp;</span>
882
+ <span class="cline-any cline-no">&nbsp;</span>
883
+ <span class="cline-any cline-neutral">&nbsp;</span>
884
+ <span class="cline-any cline-no">&nbsp;</span>
885
+ <span class="cline-any cline-no">&nbsp;</span>
886
+ <span class="cline-any cline-no">&nbsp;</span>
887
+ <span class="cline-any cline-neutral">&nbsp;</span>
888
+ <span class="cline-any cline-neutral">&nbsp;</span>
889
+ <span class="cline-any cline-neutral">&nbsp;</span>
890
+ <span class="cline-any cline-neutral">&nbsp;</span>
891
+ <span class="cline-any cline-no">&nbsp;</span>
892
+ <span class="cline-any cline-neutral">&nbsp;</span>
893
+ <span class="cline-any cline-neutral">&nbsp;</span>
894
+ <span class="cline-any cline-neutral">&nbsp;</span>
895
+ <span class="cline-any cline-neutral">&nbsp;</span>
896
+ <span class="cline-any cline-no">&nbsp;</span>
897
+ <span class="cline-any cline-no">&nbsp;</span>
898
+ <span class="cline-any cline-neutral">&nbsp;</span>
899
+ <span class="cline-any cline-no">&nbsp;</span>
900
+ <span class="cline-any cline-no">&nbsp;</span>
901
+ <span class="cline-any cline-neutral">&nbsp;</span>
902
+ <span class="cline-any cline-neutral">&nbsp;</span>
903
+ <span class="cline-any cline-neutral">&nbsp;</span>
904
+ <span class="cline-any cline-no">&nbsp;</span>
905
+ <span class="cline-any cline-no">&nbsp;</span>
906
+ <span class="cline-any cline-no">&nbsp;</span>
907
+ <span class="cline-any cline-neutral">&nbsp;</span>
908
+ <span class="cline-any cline-neutral">&nbsp;</span>
909
+ <span class="cline-any cline-neutral">&nbsp;</span>
910
+ <span class="cline-any cline-neutral">&nbsp;</span>
911
+ <span class="cline-any cline-neutral">&nbsp;</span>
912
+ <span class="cline-any cline-neutral">&nbsp;</span>
913
+ <span class="cline-any cline-neutral">&nbsp;</span>
914
+ <span class="cline-any cline-neutral">&nbsp;</span>
915
+ <span class="cline-any cline-no">&nbsp;</span>
916
+ <span class="cline-any cline-neutral">&nbsp;</span>
917
+ <span class="cline-any cline-neutral">&nbsp;</span>
918
+ <span class="cline-any cline-yes">1x</span>
919
+ <span class="cline-any cline-yes">1x</span>
920
+ <span class="cline-any cline-yes">1x</span>
921
+ <span class="cline-any cline-neutral">&nbsp;</span>
922
+ <span class="cline-any cline-neutral">&nbsp;</span>
923
+ <span class="cline-any cline-yes">1x</span>
924
+ <span class="cline-any cline-yes">1x</span>
925
+ <span class="cline-any cline-neutral">&nbsp;</span>
926
+ <span class="cline-any cline-yes">1x</span>
927
+ <span class="cline-any cline-neutral">&nbsp;</span>
928
+ <span class="cline-any cline-yes">1x</span>
929
+ <span class="cline-any cline-yes">1x</span>
930
+ <span class="cline-any cline-neutral">&nbsp;</span>
931
+ <span class="cline-any cline-neutral">&nbsp;</span>
932
+ <span class="cline-any cline-no">&nbsp;</span>
933
+ <span class="cline-any cline-neutral">&nbsp;</span>
934
+ <span class="cline-any cline-no">&nbsp;</span>
935
+ <span class="cline-any cline-no">&nbsp;</span>
936
+ <span class="cline-any cline-no">&nbsp;</span>
937
+ <span class="cline-any cline-neutral">&nbsp;</span>
938
+ <span class="cline-any cline-no">&nbsp;</span>
939
+ <span class="cline-any cline-neutral">&nbsp;</span>
940
+ <span class="cline-any cline-neutral">&nbsp;</span>
941
+ <span class="cline-any cline-neutral">&nbsp;</span>
942
+ <span class="cline-any cline-yes">1x</span>
943
+ <span class="cline-any cline-yes">1x</span>
944
+ <span class="cline-any cline-yes">1x</span>
945
+ <span class="cline-any cline-neutral">&nbsp;</span>
946
+ <span class="cline-any cline-neutral">&nbsp;</span>
947
+ <span class="cline-any cline-no">&nbsp;</span>
948
+ <span class="cline-any cline-neutral">&nbsp;</span>
949
+ <span class="cline-any cline-neutral">&nbsp;</span>
950
+ <span class="cline-any cline-neutral">&nbsp;</span>
951
+ <span class="cline-any cline-neutral">&nbsp;</span>
952
+ <span class="cline-any cline-no">&nbsp;</span>
953
+ <span class="cline-any cline-no">&nbsp;</span>
954
+ <span class="cline-any cline-no">&nbsp;</span>
955
+ <span class="cline-any cline-no">&nbsp;</span>
956
+ <span class="cline-any cline-no">&nbsp;</span>
957
+ <span class="cline-any cline-neutral">&nbsp;</span>
958
+ <span class="cline-any cline-neutral">&nbsp;</span>
959
+ <span class="cline-any cline-no">&nbsp;</span>
960
+ <span class="cline-any cline-neutral">&nbsp;</span>
961
+ <span class="cline-any cline-neutral">&nbsp;</span>
962
+ <span class="cline-any cline-yes">1x</span>
963
+ <span class="cline-any cline-no">&nbsp;</span>
964
+ <span class="cline-any cline-no">&nbsp;</span>
965
+ <span class="cline-any cline-neutral">&nbsp;</span>
966
+ <span class="cline-any cline-no">&nbsp;</span>
967
+ <span class="cline-any cline-no">&nbsp;</span>
968
+ <span class="cline-any cline-no">&nbsp;</span>
969
+ <span class="cline-any cline-no">&nbsp;</span>
970
+ <span class="cline-any cline-neutral">&nbsp;</span>
971
+ <span class="cline-any cline-no">&nbsp;</span>
972
+ <span class="cline-any cline-no">&nbsp;</span>
973
+ <span class="cline-any cline-neutral">&nbsp;</span>
974
+ <span class="cline-any cline-neutral">&nbsp;</span>
975
+ <span class="cline-any cline-neutral">&nbsp;</span>
976
+ <span class="cline-any cline-neutral">&nbsp;</span>
977
+ <span class="cline-any cline-neutral">&nbsp;</span>
978
+ <span class="cline-any cline-no">&nbsp;</span>
979
+ <span class="cline-any cline-no">&nbsp;</span>
980
+ <span class="cline-any cline-neutral">&nbsp;</span>
981
+ <span class="cline-any cline-neutral">&nbsp;</span>
982
+ <span class="cline-any cline-no">&nbsp;</span>
983
+ <span class="cline-any cline-neutral">&nbsp;</span>
984
+ <span class="cline-any cline-no">&nbsp;</span>
985
+ <span class="cline-any cline-no">&nbsp;</span>
986
+ <span class="cline-any cline-neutral">&nbsp;</span>
987
+ <span class="cline-any cline-neutral">&nbsp;</span>
988
+ <span class="cline-any cline-no">&nbsp;</span>
989
+ <span class="cline-any cline-neutral">&nbsp;</span>
990
+ <span class="cline-any cline-neutral">&nbsp;</span>
991
+ <span class="cline-any cline-neutral">&nbsp;</span>
992
+ <span class="cline-any cline-neutral">&nbsp;</span>
993
+ <span class="cline-any cline-no">&nbsp;</span>
994
+ <span class="cline-any cline-no">&nbsp;</span>
995
+ <span class="cline-any cline-neutral">&nbsp;</span>
996
+ <span class="cline-any cline-neutral">&nbsp;</span>
997
+ <span class="cline-any cline-neutral">&nbsp;</span>
998
+ <span class="cline-any cline-neutral">&nbsp;</span>
999
+ <span class="cline-any cline-neutral">&nbsp;</span>
1000
+ <span class="cline-any cline-neutral">&nbsp;</span>
1001
+ <span class="cline-any cline-neutral">&nbsp;</span>
1002
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import { ObjectLoader, EventDispatcher } from "three";
1003
+ &nbsp;
1004
+ import env from "../env";
1005
+ import Element from "../entities/Element";
1006
+ import { ENTITY_TYPES } from "../entities/constants";
1007
+ &nbsp;
1008
+ import { buildGLTFLoader } from "../loaders/GLTFLoader";
1009
+ import { buildFBXLoader } from "../loaders/FBXLoader";
1010
+ import { buildOBJMTLLoader } from "../loaders/OBJMTLLoader";
1011
+ import SkeletonUtils from "./SkeletonUtils";
1012
+ &nbsp;
1013
+ import { prepareModel, processMaterial } from "../lib/meshUtils";
1014
+ import { buildAssetId } from "../lib/utils/assets";
1015
+ import { ROOT } from "../lib/constants";
1016
+ import { ASSETS_MODEL_LOAD_FAIL, DEPRECATIONS } from "../lib/messages";
1017
+ import { NOOP } from "../lib/functions";
1018
+ import RequirementsTracer, { REQUIREMENTS_EVENTS } from "../loaders/RequirementsTracer";
1019
+ import ColladaLoader from "../loaders/ColladaLoader";
1020
+ &nbsp;
1021
+ const EXTENSIONS = {
1022
+ JSON: "json",
1023
+ GLB: "glb",
1024
+ GLTF: "gltf",
1025
+ FBX: "fbx",
1026
+ OBJ: "obj",
1027
+ COLLADA: "dae",
1028
+ };
1029
+ &nbsp;
1030
+ const FULL_STOP = ".";
1031
+ &nbsp;
1032
+ const DEFAULTbuildObjectLoader = <span class="fstat-no" title="function not covered" >()</span> =&gt; {
1033
+ const loader = <span class="cstat-no" title="statement not covered" >new ObjectLoader();</span>
1034
+ // Add setOptions for compatibility with the loader interface
1035
+ <span class="cstat-no" title="statement not covered" > loader.setOptions = <span class="fstat-no" title="function not covered" >()</span> =&gt; {};</span>
1036
+ <span class="cstat-no" title="statement not covered" > return {</span>
1037
+ tracer: new RequirementsTracer(),
1038
+ loader,
1039
+ };
1040
+ };
1041
+ &nbsp;
1042
+ const buildColladaLoader = <span class="fstat-no" title="function not covered" >()</span> =&gt; {
1043
+ const tracer = <span class="cstat-no" title="statement not covered" >new RequirementsTracer();</span>
1044
+ const loader = <span class="cstat-no" title="statement not covered" >new ColladaLoader();</span>
1045
+ <span class="cstat-no" title="statement not covered" > loader.setOptions = <span class="fstat-no" title="function not covered" >()</span> =&gt; {};</span>
1046
+ <span class="cstat-no" title="statement not covered" > return { tracer, loader };</span>
1047
+ };
1048
+ &nbsp;
1049
+ const loaders = {
1050
+ [EXTENSIONS.JSON]: DEFAULTbuildObjectLoader,
1051
+ [EXTENSIONS.GLB]: buildGLTFLoader,
1052
+ [EXTENSIONS.GLTF]: buildGLTFLoader,
1053
+ [EXTENSIONS.FBX]: buildFBXLoader,
1054
+ [EXTENSIONS.OBJ]: buildOBJMTLLoader,
1055
+ [EXTENSIONS.COLLADA]: buildColladaLoader,
1056
+ };
1057
+ &nbsp;
1058
+ /**
1059
+ * Checks if a path is an absolute URL (with protocol).
1060
+ */
1061
+ const isAbsoluteURL = <span class="fstat-no" title="function not covered" >pa</span>th =&gt; {
1062
+ <span class="cstat-no" title="statement not covered" > try {</span>
1063
+ <span class="cstat-no" title="statement not covered" > new URL(path);</span>
1064
+ <span class="cstat-no" title="statement not covered" > return true;</span>
1065
+ } catch (_) {
1066
+ <span class="cstat-no" title="statement not covered" > return false;</span>
1067
+ }
1068
+ };
1069
+ &nbsp;
1070
+ /**
1071
+ * Parses a URL and returns the URL object, or false if not a valid URL.
1072
+ * Used by extractExtension to get the pathname.
1073
+ */
1074
+ const isURL = <span class="fstat-no" title="function not covered" >pa</span>th =&gt; {
1075
+ <span class="cstat-no" title="statement not covered" > try {</span>
1076
+ <span class="cstat-no" title="statement not covered" > return new URL(path);</span>
1077
+ } catch (_) {
1078
+ <span class="cstat-no" title="statement not covered" > return false;</span>
1079
+ }
1080
+ };
1081
+ &nbsp;
1082
+ /**
1083
+ * Checks if a path is already a fully resolved URL.
1084
+ * The engine is agnostic about asset locations - it just needs to know
1085
+ * if the path is absolute (use as-is) or relative (prepend base URL).
1086
+ */
1087
+ const isAlreadyResolved = <span class="fstat-no" title="function not covered" >pa</span>th =&gt; {
1088
+ <span class="cstat-no" title="statement not covered" > return path &amp;&amp; isAbsoluteURL(path);</span>
1089
+ };
1090
+ &nbsp;
1091
+ /**
1092
+ * Resolves an asset path to a full URL.
1093
+ * If path is already an absolute URL or contains the API path, returns it as-is.
1094
+ * If path is root-relative (starts with /), returns it as-is (served from public folder).
1095
+ * If path is relative and MAGE_ASSETS_BASE_URL is set, prepends the base URL.
1096
+ * @param {string} path - The asset path (relative or absolute)
1097
+ * @returns {string} - The resolved full URL
1098
+ */
1099
+ const resolveAssetPath = <span class="fstat-no" title="function not covered" >pa</span>th =&gt; {
1100
+ // If already a full URL or already contains the API path, return as-is
1101
+ <span class="cstat-no" title="statement not covered" > if (isAlreadyResolved(path)) {</span>
1102
+ <span class="cstat-no" title="statement not covered" > return path;</span>
1103
+ }
1104
+ &nbsp;
1105
+ // Root-relative paths (starting with /) are served from the public folder
1106
+ // and should not be modified with base URL
1107
+ <span class="cstat-no" title="statement not covered" > if (path &amp;&amp; path.startsWith("/")) {</span>
1108
+ <span class="cstat-no" title="statement not covered" > return path;</span>
1109
+ }
1110
+ &nbsp;
1111
+ // If MAGE_ASSETS_BASE_URL is set, prepend it to the relative path
1112
+ const baseUrl = <span class="cstat-no" title="statement not covered" >env.MAGE_ASSETS_BASE_URL;</span>
1113
+ <span class="cstat-no" title="statement not covered" > if (baseUrl) {</span>
1114
+ <span class="cstat-no" title="statement not covered" > return `${baseUrl}/${path}`;</span>
1115
+ }
1116
+ &nbsp;
1117
+ // Warn if path contains colon (could be mistaken for protocol) and no base URL is set
1118
+ <span class="cstat-no" title="statement not covered" > if (path &amp;&amp; path.includes(":") &amp;&amp; !path.startsWith("/")) {</span>
1119
+ <span class="cstat-no" title="statement not covered" > console.warn(</span>
1120
+ `[Mage] Asset path "${path}" contains a colon but MAGE_ASSETS_BASE_URL is not set. ` +
1121
+ `This may cause the browser to interpret it as a protocol scheme. ` +
1122
+ `Prepending "./" to make it a relative path.`
1123
+ );
1124
+ <span class="cstat-no" title="statement not covered" > return `./${path}`;</span>
1125
+ }
1126
+ &nbsp;
1127
+ // Fallback: return the path as-is (for backwards compatibility)
1128
+ <span class="cstat-no" title="statement not covered" > return path;</span>
1129
+ };
1130
+ const extractExtension = <span class="fstat-no" title="function not covered" >pa</span>th =&gt; {
1131
+ const url = <span class="cstat-no" title="statement not covered" >isURL(path);</span>
1132
+ const _extract = <span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" >s </span>=&gt; <span class="cstat-no" title="statement not covered" >s.split(FULL_STOP).slice(-1).pop();</span></span>
1133
+ &nbsp;
1134
+ <span class="cstat-no" title="statement not covered" > return url ? _extract(url.pathname) : _extract(path);</span>
1135
+ };
1136
+ &nbsp;
1137
+ const getLoaderFromExtension = <span class="fstat-no" title="function not covered" >(e</span>xtension, options) =&gt; {
1138
+ const loaderBuilder = <span class="cstat-no" title="statement not covered" >loaders[extension] || DEFAULTbuildObjectLoader;</span>
1139
+ const { loader, tracer } = <span class="cstat-no" title="statement not covered" >loaderBuilder();</span>
1140
+ &nbsp;
1141
+ <span class="cstat-no" title="statement not covered" > loader.setOptions(options);</span>
1142
+ &nbsp;
1143
+ <span class="cstat-no" title="statement not covered" > return { tracer, loader };</span>
1144
+ };
1145
+ &nbsp;
1146
+ const glbParser = <span class="fstat-no" title="function not covered" >(g</span>ltf) =&gt; {
1147
+ // GLTF/GLB loader returns { scene, animations, ... }
1148
+ <span class="cstat-no" title="statement not covered" > if (!gltf || !gltf.scene) {</span>
1149
+ <span class="cstat-no" title="statement not covered" > console.error('[Mage] GLB parser received invalid GLTF object:', {</span>
1150
+ type: gltf?.constructor?.name,
1151
+ keys: gltf ? Object.keys(gltf) : [],
1152
+ });
1153
+ <span class="cstat-no" title="statement not covered" > return null;</span>
1154
+ }
1155
+ &nbsp;
1156
+ const { scene, animations } = <span class="cstat-no" title="statement not covered" >gltf;</span>
1157
+ <span class="cstat-no" title="statement not covered" > scene.traverse(<span class="fstat-no" title="function not covered" >ob</span>ject =&gt; {</span>
1158
+ <span class="cstat-no" title="statement not covered" > if (object.isMesh) {</span>
1159
+ <span class="cstat-no" title="statement not covered" > object.castShadow = true;</span>
1160
+ }
1161
+ <span class="cstat-no" title="statement not covered" > if (object.isSkinnedMesh) {</span>
1162
+ <span class="cstat-no" title="statement not covered" > object.frustumCulled = false;</span>
1163
+ }
1164
+ });
1165
+ &nbsp;
1166
+ <span class="cstat-no" title="statement not covered" > return {</span>
1167
+ animations,
1168
+ scene,
1169
+ };
1170
+ };
1171
+ const gltfParser = <span class="fstat-no" title="function not covered" >(g</span>ltf) =&gt; {
1172
+ // GLTF loader returns { scene, animations, ... }
1173
+ <span class="cstat-no" title="statement not covered" > if (!gltf || !gltf.scene) {</span>
1174
+ <span class="cstat-no" title="statement not covered" > console.error('[Mage] GLTF parser received invalid GLTF object:', {</span>
1175
+ type: gltf?.constructor?.name,
1176
+ keys: gltf ? Object.keys(gltf) : [],
1177
+ });
1178
+ <span class="cstat-no" title="statement not covered" > return null;</span>
1179
+ }
1180
+ &nbsp;
1181
+ <span class="cstat-no" title="statement not covered" > gltf.scene.traverse(<span class="fstat-no" title="function not covered" >no</span>de =&gt; {</span>
1182
+ <span class="cstat-no" title="statement not covered" > if (node.isSkinnedMesh) {</span>
1183
+ <span class="cstat-no" title="statement not covered" > node.frustumCulled = false;</span>
1184
+ }
1185
+ });
1186
+ &nbsp;
1187
+ <span class="cstat-no" title="statement not covered" > return { scene: gltf.scene, animations: gltf.animations };</span>
1188
+ };
1189
+ const defaultParser = <span class="fstat-no" title="function not covered" >sc</span>ene =&gt; {
1190
+ // Validate the scene is a proper THREE.js object
1191
+ <span class="cstat-no" title="statement not covered" > if (!scene || typeof scene.traverse !== 'function') {</span>
1192
+ <span class="cstat-no" title="statement not covered" > console.error('[Mage] Default parser received invalid scene object:', {</span>
1193
+ type: scene?.constructor?.name,
1194
+ isObject3D: scene?.isObject3D,
1195
+ keys: scene ? Object.keys(scene) : [],
1196
+ });
1197
+ <span class="cstat-no" title="statement not covered" > return null;</span>
1198
+ }
1199
+ <span class="cstat-no" title="statement not covered" > return { scene };</span>
1200
+ };
1201
+ const colladaParser = <span class="fstat-no" title="function not covered" >(c</span>ollada) =&gt; {
1202
+ // Collada loader returns { animations, scene, ... }
1203
+ <span class="cstat-no" title="statement not covered" > if (!collada || !collada.scene) {</span>
1204
+ <span class="cstat-no" title="statement not covered" > console.error('[Mage] Collada parser received invalid object:', {</span>
1205
+ type: collada?.constructor?.name,
1206
+ keys: collada ? Object.keys(collada) : [],
1207
+ });
1208
+ <span class="cstat-no" title="statement not covered" > return null;</span>
1209
+ }
1210
+ &nbsp;
1211
+ const { animations, scene, rawSceneData, buildVisualScene } = <span class="cstat-no" title="statement not covered" >collada;</span>
1212
+ <span class="cstat-no" title="statement not covered" > scene.traverse(<span class="fstat-no" title="function not covered" >no</span>de =&gt; {</span>
1213
+ <span class="cstat-no" title="statement not covered" > if (node.isSkinnedMesh) {</span>
1214
+ <span class="cstat-no" title="statement not covered" > node.frustumCulled = false;</span>
1215
+ }
1216
+ });
1217
+ &nbsp;
1218
+ <span class="cstat-no" title="statement not covered" > return {</span>
1219
+ animations,
1220
+ scene,
1221
+ rawSceneData,
1222
+ buildVisualScene,
1223
+ };
1224
+ };
1225
+ const fbxParser = <span class="fstat-no" title="function not covered" >sc</span>ene =&gt; {
1226
+ // Validate the FBX loader returned a proper THREE.js object
1227
+ <span class="cstat-no" title="statement not covered" > if (!scene || typeof scene.traverse !== 'function') {</span>
1228
+ <span class="cstat-no" title="statement not covered" > console.error('[Mage] FBX parser received invalid scene object:', {</span>
1229
+ type: scene?.constructor?.name,
1230
+ isObject3D: scene?.isObject3D,
1231
+ keys: scene ? Object.keys(scene) : [],
1232
+ });
1233
+ <span class="cstat-no" title="statement not covered" > return null;</span>
1234
+ }
1235
+ &nbsp;
1236
+ <span class="cstat-no" title="statement not covered" > scene.traverse(<span class="fstat-no" title="function not covered" >no</span>de =&gt; {</span>
1237
+ <span class="cstat-no" title="statement not covered" > if (node.isSkinnedMesh) {</span>
1238
+ <span class="cstat-no" title="statement not covered" > node.frustumCulled = false;</span>
1239
+ <span class="cstat-no" title="statement not covered" > processMaterial(node.material, <span class="fstat-no" title="function not covered" >ma</span>terial =&gt; (<span class="cstat-no" title="statement not covered" >material.skinning = true)</span>);</span>
1240
+ }
1241
+ });
1242
+ &nbsp;
1243
+ <span class="cstat-no" title="statement not covered" > return { scene, animations: scene.animations };</span>
1244
+ };
1245
+ &nbsp;
1246
+ const getModelParserFromExtension = <span class="fstat-no" title="function not covered" >ex</span>tension =&gt;
1247
+ (<span class="cstat-no" title="statement not covered" >{</span>
1248
+ [EXTENSIONS.JSON]: defaultParser,
1249
+ [EXTENSIONS.GLB]: glbParser,
1250
+ [EXTENSIONS.GLTF]: gltfParser,
1251
+ [EXTENSIONS.COLLADA]: colladaParser,
1252
+ [EXTENSIONS.FBX]: fbxParser,
1253
+ }[extension] || defaultParser);
1254
+ &nbsp;
1255
+ const hasAnimations = <span class="fstat-no" title="function not covered" >(a</span>nimations = <span class="branch-0 cbranch-no" title="branch not covered" >[])</span> =&gt; <span class="cstat-no" title="statement not covered" >animations.length &gt; 0;</span>
1256
+ &nbsp;
1257
+ class Models extends EventDispatcher {
1258
+ constructor() {
1259
+ super();
1260
+ this.map = {};
1261
+ this.models = {};
1262
+ this.currentLevel = ROOT;
1263
+ }
1264
+ &nbsp;
1265
+ onMissingRequirements = (modelname, cb = <span class="branch-0 cbranch-no" title="branch not covered" >NOOP)</span> =&gt; {
1266
+ this.addEventListener(`${REQUIREMENTS_EVENTS.MISSING}:${modelname}`, cb);
1267
+ };
1268
+ &nbsp;
1269
+ setCurrentLevel = level =&gt; {
1270
+ this.currentLevel = level;
1271
+ };
1272
+ &nbsp;
1273
+ getModel = <span class="fstat-no" title="function not covered" >(n</span>ame, options = <span class="branch-0 cbranch-no" title="branch not covered" >{})</span> =&gt; {
1274
+ <span class="cstat-no" title="statement not covered" > console.warn(DEPRECATIONS.MODELS_GETMODEL);</span>
1275
+ <span class="cstat-no" title="statement not covered" > return this.create(name, options);</span>
1276
+ };
1277
+ &nbsp;
1278
+ get = <span class="fstat-no" title="function not covered" >(n</span>ame, options = <span class="branch-0 cbranch-no" title="branch not covered" >{})</span> =&gt; {
1279
+ <span class="cstat-no" title="statement not covered" > console.warn(DEPRECATIONS.MODELS_GET);</span>
1280
+ <span class="cstat-no" title="statement not covered" > return this.create(name, options);</span>
1281
+ };
1282
+ &nbsp;
1283
+ create = <span class="fstat-no" title="function not covered" >(n</span>ame, options = <span class="branch-0 cbranch-no" title="branch not covered" >{})</span> =&gt; {
1284
+ const builtAssetId = <span class="cstat-no" title="statement not covered" >buildAssetId(name, this.currentLevel);</span>
1285
+ const modelData = <span class="cstat-no" title="statement not covered" >this.map[name] || this.map[builtAssetId];</span>
1286
+ &nbsp;
1287
+ <span class="cstat-no" title="statement not covered" > if (!modelData) {</span>
1288
+ <span class="cstat-no" title="statement not covered" > console.warn(`[Mage] Model "${name}" not found in map. Available: ${Object.keys(this.map).join(', ')}`);</span>
1289
+ <span class="cstat-no" title="statement not covered" > return false;</span>
1290
+ }
1291
+ &nbsp;
1292
+ const { scene, animations, extension } = <span class="cstat-no" title="statement not covered" >modelData;</span>
1293
+ &nbsp;
1294
+ // Debug: Log model structure
1295
+ <span class="cstat-no" title="statement not covered" > console.log(`[Mage] Creating model "${name}":`, {</span>
1296
+ hasScene: !!scene,
1297
+ sceneType: scene?.type,
1298
+ childrenCount: scene?.children?.length,
1299
+ animations: animations?.length || 0,
1300
+ extension,
1301
+ });
1302
+ &nbsp;
1303
+ // Debug: Check for meshes in the scene
1304
+ let meshCount = <span class="cstat-no" title="statement not covered" >0;</span>
1305
+ let skinnedMeshCount = <span class="cstat-no" title="statement not covered" >0;</span>
1306
+ <span class="cstat-no" title="statement not covered" > scene?.traverse?.(<span class="fstat-no" title="function not covered" >no</span>de =&gt; {</span>
1307
+ <span class="cstat-no" title="statement not covered" > if (node.isMesh) <span class="cstat-no" title="statement not covered" >meshCount++;</span></span>
1308
+ <span class="cstat-no" title="statement not covered" > if (node.isSkinnedMesh) <span class="cstat-no" title="statement not covered" >skinnedMeshCount++;</span></span>
1309
+ });
1310
+ <span class="cstat-no" title="statement not covered" > console.log(`[Mage] Model "${name}" contains: ${meshCount} meshes, ${skinnedMeshCount} skinned meshes`);</span>
1311
+ &nbsp;
1312
+ // Validate that scene is a valid THREE.js object with required methods
1313
+ <span class="cstat-no" title="statement not covered" > if (!scene || typeof scene.clone !== 'function' || typeof scene.traverse !== 'function') {</span>
1314
+ <span class="cstat-no" title="statement not covered" > console.warn(`[Mage] Model "${name}" has invalid scene object. Got:`, Object.keys(modelData));</span>
1315
+ <span class="cstat-no" title="statement not covered" > return false;</span>
1316
+ }
1317
+ &nbsp;
1318
+ const elementOptions = <span class="cstat-no" title="statement not covered" >{</span>
1319
+ name,
1320
+ builtAssetId,
1321
+ ...options,
1322
+ };
1323
+ &nbsp;
1324
+ let model;
1325
+ &nbsp;
1326
+ // Check if the scene contains any skinned meshes
1327
+ let hasSkinnedMeshes = <span class="cstat-no" title="statement not covered" >false;</span>
1328
+ <span class="cstat-no" title="statement not covered" > scene.traverse(<span class="fstat-no" title="function not covered" >no</span>de =&gt; {</span>
1329
+ <span class="cstat-no" title="statement not covered" > if (node.isSkinnedMesh) {</span>
1330
+ <span class="cstat-no" title="statement not covered" > hasSkinnedMeshes = true;</span>
1331
+ }
1332
+ });
1333
+ &nbsp;
1334
+ // Use SkeletonUtils.clone for models with skinned meshes OR animations
1335
+ // Regular clone() doesn't properly handle skeleton binding
1336
+ const useSkeletonClone = <span class="cstat-no" title="statement not covered" >extension !== EXTENSIONS.COLLADA &amp;&amp; (hasAnimations(animations) || hasSkinnedMeshes);</span>
1337
+ &nbsp;
1338
+ <span class="cstat-no" title="statement not covered" > try {</span>
1339
+ <span class="cstat-no" title="statement not covered" > if (useSkeletonClone) {</span>
1340
+ <span class="cstat-no" title="statement not covered" > model = SkeletonUtils.clone(scene);</span>
1341
+ } else {
1342
+ <span class="cstat-no" title="statement not covered" > model = scene.clone();</span>
1343
+ }
1344
+ } catch (cloneError) {
1345
+ <span class="cstat-no" title="statement not covered" > console.error(`[Mage] Error cloning model "${name}":`, cloneError);</span>
1346
+ <span class="cstat-no" title="statement not covered" > return false;</span>
1347
+ }
1348
+ &nbsp;
1349
+ // Validate the cloned model
1350
+ const preparedBody = <span class="cstat-no" title="statement not covered" >prepareModel(model);</span>
1351
+ &nbsp;
1352
+ <span class="cstat-no" title="statement not covered" > if (!preparedBody) {</span>
1353
+ <span class="cstat-no" title="statement not covered" > console.warn(`[Mage] Model "${name}" failed to prepare after cloning`);</span>
1354
+ <span class="cstat-no" title="statement not covered" > return false;</span>
1355
+ }
1356
+ &nbsp;
1357
+ // IMPORTANT: body must come AFTER elementOptions spread to ensure
1358
+ // our preparedBody is used, not any 'body' property from saved options
1359
+ const element = <span class="cstat-no" title="statement not covered" >new Element({</span>
1360
+ ...elementOptions,
1361
+ body: preparedBody,
1362
+ });
1363
+ &nbsp;
1364
+ <span class="cstat-no" title="statement not covered" > element.setEntityType(ENTITY_TYPES.MODEL.TYPE);</span>
1365
+ <span class="cstat-no" title="statement not covered" > element.setEntitySubtype(ENTITY_TYPES.MODEL.SUBTYPES.DEFAULT);</span>
1366
+ &nbsp;
1367
+ <span class="cstat-no" title="statement not covered" > if (hasAnimations(animations)) {</span>
1368
+ <span class="cstat-no" title="statement not covered" > element.addAnimationHandler(animations);</span>
1369
+ }
1370
+ &nbsp;
1371
+ // Debug: Log element body info
1372
+ const body = <span class="cstat-no" title="statement not covered" >element.getBody?.();</span>
1373
+ <span class="cstat-no" title="statement not covered" > if (body) {</span>
1374
+ <span class="cstat-no" title="statement not covered" > console.log(`[Mage] Element "${name}" body:`, {</span>
1375
+ type: body.type,
1376
+ visible: body.visible,
1377
+ position: body.position?.toArray?.(),
1378
+ scale: body.scale?.toArray?.(),
1379
+ childrenCount: body.children?.length,
1380
+ });
1381
+ }
1382
+ &nbsp;
1383
+ <span class="cstat-no" title="statement not covered" > return element;</span>
1384
+ };
1385
+ &nbsp;
1386
+ storeModel = (name, model, extension) =&gt; {
1387
+ model.extension = extension;
1388
+ this.map[name] = model;
1389
+ };
1390
+ &nbsp;
1391
+ loadModels = (models, level) =&gt; {
1392
+ this.models = models;
1393
+ &nbsp;
1394
+ const keys = Object.keys(models);
1395
+ &nbsp;
1396
+ <span class="missing-if-branch" title="else path not taken" >E</span>if (!keys.length) {
1397
+ return Promise.resolve("models");
1398
+ }
1399
+ &nbsp;
1400
+ const options = <span class="cstat-no" title="statement not covered" >{ level };</span>
1401
+ &nbsp;
1402
+ <span class="cstat-no" title="statement not covered" > return Promise.all(keys.map(<span class="fstat-no" title="function not covered" >na</span>me =&gt; <span class="cstat-no" title="statement not covered" >this.loadAssetByName(name, options))</span>).catch(<span class="fstat-no" title="function not covered" >e </span>=&gt; {</span>
1403
+ <span class="cstat-no" title="statement not covered" > console.log(ASSETS_MODEL_LOAD_FAIL);</span>
1404
+ <span class="cstat-no" title="statement not covered" > console.log(e);</span>
1405
+ &nbsp;
1406
+ <span class="cstat-no" title="statement not covered" > return Promise.resolve();</span>
1407
+ });
1408
+ };
1409
+ &nbsp;
1410
+ loadAssetByName = (name, options) =&gt; {
1411
+ <span class="missing-if-branch" title="else path not taken" >E</span>if (!this.models[name]) {
1412
+ return Promise.resolve();
1413
+ }
1414
+ &nbsp;
1415
+ const modelConfig = <span class="cstat-no" title="statement not covered" >this.models[name];</span>
1416
+ &nbsp;
1417
+ // Support both string paths and objects with path + dependencies
1418
+ // String format: "models/mymodel.fbx"
1419
+ // Object format: { path: "models/mymodel.fbx", dependencies: { texture: "textures/tex.png" } }
1420
+ <span class="cstat-no" title="statement not covered" > if (typeof modelConfig === "string") {</span>
1421
+ <span class="cstat-no" title="statement not covered" > return this.loadAssetByPath(modelConfig, name, options);</span>
1422
+ } else <span class="cstat-no" title="statement not covered" >if (modelConfig &amp;&amp; typeof modelConfig === "object") {</span>
1423
+ const { path, dependencies = <span class="branch-0 cbranch-no" title="branch not covered" >{} </span>} = <span class="cstat-no" title="statement not covered" >modelConfig;</span>
1424
+ <span class="cstat-no" title="statement not covered" > return this.loadAssetByPath(path, name, { ...options, ...dependencies });</span>
1425
+ }
1426
+ &nbsp;
1427
+ <span class="cstat-no" title="statement not covered" > return Promise.resolve();</span>
1428
+ };
1429
+ &nbsp;
1430
+ loadAssetByPath = <span class="fstat-no" title="function not covered" >(p</span>ath, name, options = <span class="branch-0 cbranch-no" title="branch not covered" >{})</span> =&gt; {
1431
+ const { level } = <span class="cstat-no" title="statement not covered" >options;</span>
1432
+ const id = <span class="cstat-no" title="statement not covered" >buildAssetId(name, level);</span>
1433
+ // Resolve the path using MAGE_ASSETS_BASE_URL if available
1434
+ const resolvedPath = <span class="cstat-no" title="statement not covered" >resolveAssetPath(path);</span>
1435
+ const extension = <span class="cstat-no" title="statement not covered" >extractExtension(path);</span>
1436
+ const { loader, tracer } = <span class="cstat-no" title="statement not covered" >getLoaderFromExtension(extension, options);</span>
1437
+ const parser = <span class="cstat-no" title="statement not covered" >getModelParserFromExtension(extension);</span>
1438
+ &nbsp;
1439
+ <span class="cstat-no" title="statement not covered" > tracer.addEventListener(REQUIREMENTS_EVENTS.MISSING, <span class="fstat-no" title="function not covered" >({</span> requirements }) =&gt; {</span>
1440
+ <span class="cstat-no" title="statement not covered" > this.dispatchEvent({</span>
1441
+ type: `${REQUIREMENTS_EVENTS.MISSING}:${name}`,
1442
+ requirements: requirements,
1443
+ });
1444
+ });
1445
+ &nbsp;
1446
+ <span class="cstat-no" title="statement not covered" > return new Promise(<span class="fstat-no" title="function not covered" >re</span>solve =&gt; {</span>
1447
+ <span class="cstat-no" title="statement not covered" > loader.load(</span>
1448
+ resolvedPath,
1449
+ <span class="fstat-no" title="function not covered" > mo</span>del =&gt; {
1450
+ const parsedModel = <span class="cstat-no" title="statement not covered" >parser(model);</span>
1451
+ &nbsp;
1452
+ <span class="cstat-no" title="statement not covered" > if (parsedModel) {</span>
1453
+ <span class="cstat-no" title="statement not covered" > this.storeModel(id, parsedModel, extension);</span>
1454
+ }
1455
+ &nbsp;
1456
+ <span class="cstat-no" title="statement not covered" > resolve(parsedModel);</span>
1457
+ },
1458
+ NOOP,
1459
+ <span class="fstat-no" title="function not covered" > er</span>ror =&gt; {
1460
+ // Log error but resolve anyway to allow other assets to continue loading
1461
+ <span class="cstat-no" title="statement not covered" > console.warn(`[Mage] Failed to load model "${name}" from ${resolvedPath}:`, error?.message || error);</span>
1462
+ <span class="cstat-no" title="statement not covered" > resolve(null);</span>
1463
+ },
1464
+ );
1465
+ });
1466
+ };
1467
+ }
1468
+ &nbsp;
1469
+ export default new Models();
1470
+ &nbsp;</pre></td></tr></table></pre>
1471
+
1472
+ <div class='push'></div><!-- for sticky footer -->
1473
+ </div><!-- /wrapper -->
1474
+ <div class='footer quiet pad2 space-top1 center small'>
1475
+ Code coverage generated by
1476
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
1477
+ at 2026-03-02T17:28:15.675Z
1478
+ </div>
1479
+ <script src="../prettify.js"></script>
1480
+ <script>
1481
+ window.onload = function () {
1482
+ prettyPrint();
1483
+ };
1484
+ </script>
1485
+ <script src="../sorter.js"></script>
1486
+ <script src="../block-navigation.js"></script>
1487
+ </body>
1488
+ </html>
1489
+