diff options
author | Jacek Antonelli | 2008-08-15 23:45:42 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:42 -0500 |
commit | ce28e056c20bf2723f565bbf464b87781ec248a2 (patch) | |
tree | ef7b0501c4de4b631a916305cbc2a5fdc125e52d /linden/indra/newview/llfloatersettingsdebug.cpp | |
parent | Second Life viewer sources 1.19.1.4b (diff) | |
download | meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.zip meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.gz meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.bz2 meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.xz |
Second Life viewer sources 1.20.2
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/llfloatersettingsdebug.cpp | 492 |
1 files changed, 492 insertions, 0 deletions
diff --git a/linden/indra/newview/llfloatersettingsdebug.cpp b/linden/indra/newview/llfloatersettingsdebug.cpp new file mode 100644 index 0000000..2e14aac --- /dev/null +++ b/linden/indra/newview/llfloatersettingsdebug.cpp | |||
@@ -0,0 +1,492 @@ | |||
1 | /** | ||
2 | * @file llfloatersettingsdebug.cpp | ||
3 | * @brief floater for debugging internal viewer settings | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2001&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2001-2008, Linden Research, Inc. | ||
8 | * | ||
9 | * Second Life Viewer Source Code | ||
10 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
11 | * to you under the terms of the GNU General Public License, version 2.0 | ||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
16 | * | ||
17 | * There are special exceptions to the terms and conditions of the GPL as | ||
18 | * it is applied to this Source Code. View the full text of the exception | ||
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
21 | * | ||
22 | * By copying, modifying or distributing this software, you acknowledge | ||
23 | * that you have read and understood your obligations described above, | ||
24 | * and agree to abide by those obligations. | ||
25 | * | ||
26 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
27 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
28 | * COMPLETENESS OR PERFORMANCE. | ||
29 | * $/LicenseInfo$ | ||
30 | */ | ||
31 | |||
32 | #include "llviewerprecompiledheaders.h" | ||
33 | #include "llfloatersettingsdebug.h" | ||
34 | #include "llfloater.h" | ||
35 | #include "lluictrlfactory.h" | ||
36 | #include "llfirstuse.h" | ||
37 | #include "llcombobox.h" | ||
38 | #include "llspinctrl.h" | ||
39 | #include "llcolorswatch.h" | ||
40 | #include "llviewercontrol.h" | ||
41 | |||
42 | LLFloaterSettingsDebug* LLFloaterSettingsDebug::sInstance = NULL; | ||
43 | |||
44 | LLFloaterSettingsDebug::LLFloaterSettingsDebug() : LLFloater("Configuration Editor") | ||
45 | { | ||
46 | } | ||
47 | |||
48 | LLFloaterSettingsDebug::~LLFloaterSettingsDebug() | ||
49 | { | ||
50 | sInstance = NULL; | ||
51 | } | ||
52 | |||
53 | BOOL LLFloaterSettingsDebug::postBuild() | ||
54 | { | ||
55 | LLComboBox* settings_combo = getChild<LLComboBox>("settings_combo"); | ||
56 | |||
57 | struct f : public LLControlGroup::ApplyFunctor | ||
58 | { | ||
59 | LLComboBox* combo; | ||
60 | f(LLComboBox* c) : combo(c) {} | ||
61 | virtual void apply(const LLString& name, LLControlVariable* control) | ||
62 | { | ||
63 | combo->add(name, (void*)control); | ||
64 | } | ||
65 | } func(settings_combo); | ||
66 | |||
67 | gSavedSettings.applyToAll(&func); | ||
68 | gSavedPerAccountSettings.applyToAll(&func); | ||
69 | gColors.applyToAll(&func); | ||
70 | |||
71 | settings_combo->sortByName(); | ||
72 | settings_combo->setCommitCallback(onSettingSelect); | ||
73 | settings_combo->setCallbackUserData(this); | ||
74 | settings_combo->updateSelection(); | ||
75 | |||
76 | childSetCommitCallback("val_spinner_1", onCommitSettings); | ||
77 | childSetUserData("val_spinner_1", this); | ||
78 | childSetCommitCallback("val_spinner_2", onCommitSettings); | ||
79 | childSetUserData("val_spinner_2", this); | ||
80 | childSetCommitCallback("val_spinner_3", onCommitSettings); | ||
81 | childSetUserData("val_spinner_3", this); | ||
82 | childSetCommitCallback("val_spinner_4", onCommitSettings); | ||
83 | childSetUserData("val_spinner_4", this); | ||
84 | childSetCommitCallback("val_text", onCommitSettings); | ||
85 | childSetUserData("val_text", this); | ||
86 | childSetCommitCallback("boolean_combo", onCommitSettings); | ||
87 | childSetUserData("boolean_combo", this); | ||
88 | childSetCommitCallback("color_swatch", onCommitSettings); | ||
89 | childSetUserData("color_swatch", this); | ||
90 | childSetAction("default_btn", onClickDefault, this); | ||
91 | mComment = getChild<LLTextEditor>("comment_text"); | ||
92 | return TRUE; | ||
93 | } | ||
94 | |||
95 | void LLFloaterSettingsDebug::draw() | ||
96 | { | ||
97 | LLComboBox* settings_combo = getChild<LLComboBox>("settings_combo"); | ||
98 | LLControlVariable* controlp = (LLControlVariable*)settings_combo->getCurrentUserdata(); | ||
99 | updateControl(controlp); | ||
100 | |||
101 | LLFloater::draw(); | ||
102 | } | ||
103 | |||
104 | //static | ||
105 | void LLFloaterSettingsDebug::show(void*) | ||
106 | { | ||
107 | if (sInstance == NULL) | ||
108 | { | ||
109 | sInstance = new LLFloaterSettingsDebug(); | ||
110 | |||
111 | LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_settings_debug.xml"); | ||
112 | } | ||
113 | |||
114 | sInstance->open(); /* Flawfinder: ignore */ | ||
115 | } | ||
116 | |||
117 | //static | ||
118 | void LLFloaterSettingsDebug::onSettingSelect(LLUICtrl* ctrl, void* user_data) | ||
119 | { | ||
120 | LLFloaterSettingsDebug* floaterp = (LLFloaterSettingsDebug*)user_data; | ||
121 | LLComboBox* combo_box = (LLComboBox*)ctrl; | ||
122 | LLControlVariable* controlp = (LLControlVariable*)combo_box->getCurrentUserdata(); | ||
123 | |||
124 | floaterp->updateControl(controlp); | ||
125 | } | ||
126 | |||
127 | //static | ||
128 | void LLFloaterSettingsDebug::onCommitSettings(LLUICtrl* ctrl, void* user_data) | ||
129 | { | ||
130 | LLFloaterSettingsDebug* floaterp = (LLFloaterSettingsDebug*)user_data; | ||
131 | |||
132 | LLComboBox* settings_combo = floaterp->getChild<LLComboBox>("settings_combo"); | ||
133 | LLControlVariable* controlp = (LLControlVariable*)settings_combo->getCurrentUserdata(); | ||
134 | |||
135 | LLVector3 vector; | ||
136 | LLVector3d vectord; | ||
137 | LLRect rect; | ||
138 | LLColor4 col4; | ||
139 | LLColor3 col3; | ||
140 | LLColor4U col4U; | ||
141 | LLColor4 color_with_alpha; | ||
142 | |||
143 | switch(controlp->type()) | ||
144 | { | ||
145 | case TYPE_U32: | ||
146 | controlp->set(floaterp->childGetValue("val_spinner_1")); | ||
147 | break; | ||
148 | case TYPE_S32: | ||
149 | controlp->set(floaterp->childGetValue("val_spinner_1")); | ||
150 | break; | ||
151 | case TYPE_F32: | ||
152 | controlp->set(LLSD(floaterp->childGetValue("val_spinner_1").asReal())); | ||
153 | break; | ||
154 | case TYPE_BOOLEAN: | ||
155 | controlp->set(floaterp->childGetValue("boolean_combo")); | ||
156 | break; | ||
157 | case TYPE_STRING: | ||
158 | controlp->set(LLSD(floaterp->childGetValue("val_text").asString())); | ||
159 | break; | ||
160 | case TYPE_VEC3: | ||
161 | vector.mV[VX] = (F32)floaterp->childGetValue("val_spinner_1").asReal(); | ||
162 | vector.mV[VY] = (F32)floaterp->childGetValue("val_spinner_2").asReal(); | ||
163 | vector.mV[VZ] = (F32)floaterp->childGetValue("val_spinner_3").asReal(); | ||
164 | controlp->set(vector.getValue()); | ||
165 | break; | ||
166 | case TYPE_VEC3D: | ||
167 | vectord.mdV[VX] = floaterp->childGetValue("val_spinner_1").asReal(); | ||
168 | vectord.mdV[VY] = floaterp->childGetValue("val_spinner_2").asReal(); | ||
169 | vectord.mdV[VZ] = floaterp->childGetValue("val_spinner_3").asReal(); | ||
170 | controlp->set(vectord.getValue()); | ||
171 | break; | ||
172 | case TYPE_RECT: | ||
173 | rect.mLeft = floaterp->childGetValue("val_spinner_1").asInteger(); | ||
174 | rect.mRight = floaterp->childGetValue("val_spinner_2").asInteger(); | ||
175 | rect.mBottom = floaterp->childGetValue("val_spinner_3").asInteger(); | ||
176 | rect.mTop = floaterp->childGetValue("val_spinner_4").asInteger(); | ||
177 | controlp->set(rect.getValue()); | ||
178 | break; | ||
179 | case TYPE_COL4: | ||
180 | col3.setValue(floaterp->childGetValue("color_swatch")); | ||
181 | col4 = LLColor4(col3, (F32)floaterp->childGetValue("val_spinner_4").asReal()); | ||
182 | controlp->set(col4.getValue()); | ||
183 | break; | ||
184 | case TYPE_COL3: | ||
185 | controlp->set(floaterp->childGetValue("color_swatch")); | ||
186 | //col3.mV[VRED] = (F32)floaterp->childGetValue("val_spinner_1").asC(); | ||
187 | //col3.mV[VGREEN] = (F32)floaterp->childGetValue("val_spinner_2").asReal(); | ||
188 | //col3.mV[VBLUE] = (F32)floaterp->childGetValue("val_spinner_3").asReal(); | ||
189 | //controlp->set(col3.getValue()); | ||
190 | break; | ||
191 | case TYPE_COL4U: | ||
192 | col3.setValue(floaterp->childGetValue("color_swatch")); | ||
193 | col4U.setVecScaleClamp(col3); | ||
194 | col4U.mV[VALPHA] = floaterp->childGetValue("val_spinner_4").asInteger(); | ||
195 | controlp->set(col4U.getValue()); | ||
196 | break; | ||
197 | default: | ||
198 | break; | ||
199 | } | ||
200 | } | ||
201 | |||
202 | // static | ||
203 | void LLFloaterSettingsDebug::onClickDefault(void* user_data) | ||
204 | { | ||
205 | LLFloaterSettingsDebug* floaterp = (LLFloaterSettingsDebug*)user_data; | ||
206 | LLComboBox* settings_combo = floaterp->getChild<LLComboBox>("settings_combo"); | ||
207 | LLControlVariable* controlp = (LLControlVariable*)settings_combo->getCurrentUserdata(); | ||
208 | |||
209 | if (controlp) | ||
210 | { | ||
211 | controlp->resetToDefault(); | ||
212 | floaterp->updateControl(controlp); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | // we've switched controls, or doing per-frame update, so update spinners, etc. | ||
217 | void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp) | ||
218 | { | ||
219 | LLSpinCtrl* spinner1 = getChild<LLSpinCtrl>("val_spinner_1"); | ||
220 | LLSpinCtrl* spinner2 = getChild<LLSpinCtrl>("val_spinner_2"); | ||
221 | LLSpinCtrl* spinner3 = getChild<LLSpinCtrl>("val_spinner_3"); | ||
222 | LLSpinCtrl* spinner4 = getChild<LLSpinCtrl>("val_spinner_4"); | ||
223 | LLColorSwatchCtrl* color_swatch = getChild<LLColorSwatchCtrl>("color_swatch"); | ||
224 | |||
225 | if (!spinner1 || !spinner2 || !spinner3 || !spinner4 || !color_swatch) | ||
226 | { | ||
227 | llwarns << "Could not find all desired controls by name" | ||
228 | << llendl; | ||
229 | return; | ||
230 | } | ||
231 | |||
232 | spinner1->setVisible(FALSE); | ||
233 | spinner2->setVisible(FALSE); | ||
234 | spinner3->setVisible(FALSE); | ||
235 | spinner4->setVisible(FALSE); | ||
236 | color_swatch->setVisible(FALSE); | ||
237 | childSetVisible("val_text", FALSE); | ||
238 | mComment->setText(LLString::null); | ||
239 | |||
240 | if (controlp) | ||
241 | { | ||
242 | eControlType type = controlp->type(); | ||
243 | |||
244 | //hide combo box only for non booleans, otherwise this will result in the combo box closing every frame | ||
245 | childSetVisible("boolean_combo", type == TYPE_BOOLEAN); | ||
246 | |||
247 | |||
248 | mComment->setText(controlp->getComment()); | ||
249 | spinner1->setMaxValue(F32_MAX); | ||
250 | spinner2->setMaxValue(F32_MAX); | ||
251 | spinner3->setMaxValue(F32_MAX); | ||
252 | spinner4->setMaxValue(F32_MAX); | ||
253 | spinner1->setMinValue(-F32_MAX); | ||
254 | spinner2->setMinValue(-F32_MAX); | ||
255 | spinner3->setMinValue(-F32_MAX); | ||
256 | spinner4->setMinValue(-F32_MAX); | ||
257 | if (!spinner1->hasFocus()) | ||
258 | { | ||
259 | spinner1->setIncrement(0.1f); | ||
260 | } | ||
261 | if (!spinner2->hasFocus()) | ||
262 | { | ||
263 | spinner2->setIncrement(0.1f); | ||
264 | } | ||
265 | if (!spinner3->hasFocus()) | ||
266 | { | ||
267 | spinner3->setIncrement(0.1f); | ||
268 | } | ||
269 | if (!spinner4->hasFocus()) | ||
270 | { | ||
271 | spinner4->setIncrement(0.1f); | ||
272 | } | ||
273 | |||
274 | LLSD sd = controlp->get(); | ||
275 | switch(type) | ||
276 | { | ||
277 | case TYPE_U32: | ||
278 | spinner1->setVisible(TRUE); | ||
279 | spinner1->setLabel(LLString("value")); // Debug, don't translate | ||
280 | if (!spinner1->hasFocus()) | ||
281 | { | ||
282 | spinner1->setValue(sd); | ||
283 | spinner1->setMinValue((F32)U32_MIN); | ||
284 | spinner1->setMaxValue((F32)U32_MAX); | ||
285 | spinner1->setIncrement(1.f); | ||
286 | spinner1->setPrecision(0); | ||
287 | } | ||
288 | break; | ||
289 | case TYPE_S32: | ||
290 | spinner1->setVisible(TRUE); | ||
291 | spinner1->setLabel(LLString("value")); // Debug, don't translate | ||
292 | if (!spinner1->hasFocus()) | ||
293 | { | ||
294 | spinner1->setValue(sd); | ||
295 | spinner1->setMinValue((F32)S32_MIN); | ||
296 | spinner1->setMaxValue((F32)S32_MAX); | ||
297 | spinner1->setIncrement(1.f); | ||
298 | spinner1->setPrecision(0); | ||
299 | } | ||
300 | break; | ||
301 | case TYPE_F32: | ||
302 | spinner1->setVisible(TRUE); | ||
303 | spinner1->setLabel(LLString("value")); // Debug, don't translate | ||
304 | if (!spinner1->hasFocus()) | ||
305 | { | ||
306 | spinner1->setPrecision(3); | ||
307 | spinner1->setValue(sd); | ||
308 | } | ||
309 | break; | ||
310 | case TYPE_BOOLEAN: | ||
311 | if (!childHasFocus("boolean_combo")) | ||
312 | { | ||
313 | if (sd.asBoolean()) | ||
314 | { | ||
315 | childSetValue("boolean_combo", LLSD("true")); | ||
316 | } | ||
317 | else | ||
318 | { | ||
319 | childSetValue("boolean_combo", LLSD("")); | ||
320 | } | ||
321 | } | ||
322 | break; | ||
323 | case TYPE_STRING: | ||
324 | childSetVisible("val_text", TRUE); | ||
325 | if (!childHasFocus("val_text")) | ||
326 | { | ||
327 | childSetValue("val_text", sd); | ||
328 | } | ||
329 | break; | ||
330 | case TYPE_VEC3: | ||
331 | { | ||
332 | LLVector3 v; | ||
333 | v.setValue(sd); | ||
334 | spinner1->setVisible(TRUE); | ||
335 | spinner1->setLabel(LLString("X")); | ||
336 | spinner2->setVisible(TRUE); | ||
337 | spinner2->setLabel(LLString("Y")); | ||
338 | spinner3->setVisible(TRUE); | ||
339 | spinner3->setLabel(LLString("Z")); | ||
340 | if (!spinner1->hasFocus()) | ||
341 | { | ||
342 | spinner1->setPrecision(3); | ||
343 | spinner1->setValue(v[VX]); | ||
344 | } | ||
345 | if (!spinner2->hasFocus()) | ||
346 | { | ||
347 | spinner2->setPrecision(3); | ||
348 | spinner2->setValue(v[VY]); | ||
349 | } | ||
350 | if (!spinner3->hasFocus()) | ||
351 | { | ||
352 | spinner3->setPrecision(3); | ||
353 | spinner3->setValue(v[VZ]); | ||
354 | } | ||
355 | break; | ||
356 | } | ||
357 | case TYPE_VEC3D: | ||
358 | { | ||
359 | LLVector3d v; | ||
360 | v.setValue(sd); | ||
361 | spinner1->setVisible(TRUE); | ||
362 | spinner1->setLabel(LLString("X")); | ||
363 | spinner2->setVisible(TRUE); | ||
364 | spinner2->setLabel(LLString("Y")); | ||
365 | spinner3->setVisible(TRUE); | ||
366 | spinner3->setLabel(LLString("Z")); | ||
367 | if (!spinner1->hasFocus()) | ||
368 | { | ||
369 | spinner1->setPrecision(3); | ||
370 | spinner1->setValue(v[VX]); | ||
371 | } | ||
372 | if (!spinner2->hasFocus()) | ||
373 | { | ||
374 | spinner2->setPrecision(3); | ||
375 | spinner2->setValue(v[VY]); | ||
376 | } | ||
377 | if (!spinner3->hasFocus()) | ||
378 | { | ||
379 | spinner3->setPrecision(3); | ||
380 | spinner3->setValue(v[VZ]); | ||
381 | } | ||
382 | break; | ||
383 | } | ||
384 | case TYPE_RECT: | ||
385 | { | ||
386 | LLRect r; | ||
387 | r.setValue(sd); | ||
388 | spinner1->setVisible(TRUE); | ||
389 | spinner1->setLabel(LLString("Left")); | ||
390 | spinner2->setVisible(TRUE); | ||
391 | spinner2->setLabel(LLString("Right")); | ||
392 | spinner3->setVisible(TRUE); | ||
393 | spinner3->setLabel(LLString("Bottom")); | ||
394 | spinner4->setVisible(TRUE); | ||
395 | spinner4->setLabel(LLString("Top")); | ||
396 | if (!spinner1->hasFocus()) | ||
397 | { | ||
398 | spinner1->setPrecision(0); | ||
399 | spinner1->setValue(r.mLeft); | ||
400 | } | ||
401 | if (!spinner2->hasFocus()) | ||
402 | { | ||
403 | spinner2->setPrecision(0); | ||
404 | spinner2->setValue(r.mRight); | ||
405 | } | ||
406 | if (!spinner3->hasFocus()) | ||
407 | { | ||
408 | spinner3->setPrecision(0); | ||
409 | spinner3->setValue(r.mBottom); | ||
410 | } | ||
411 | if (!spinner4->hasFocus()) | ||
412 | { | ||
413 | spinner4->setPrecision(0); | ||
414 | spinner4->setValue(r.mTop); | ||
415 | } | ||
416 | |||
417 | spinner1->setMinValue((F32)S32_MIN); | ||
418 | spinner1->setMaxValue((F32)S32_MAX); | ||
419 | spinner1->setIncrement(1.f); | ||
420 | |||
421 | spinner2->setMinValue((F32)S32_MIN); | ||
422 | spinner2->setMaxValue((F32)S32_MAX); | ||
423 | spinner2->setIncrement(1.f); | ||
424 | |||
425 | spinner3->setMinValue((F32)S32_MIN); | ||
426 | spinner3->setMaxValue((F32)S32_MAX); | ||
427 | spinner3->setIncrement(1.f); | ||
428 | |||
429 | spinner4->setMinValue((F32)S32_MIN); | ||
430 | spinner4->setMaxValue((F32)S32_MAX); | ||
431 | spinner4->setIncrement(1.f); | ||
432 | break; | ||
433 | } | ||
434 | case TYPE_COL4: | ||
435 | { | ||
436 | LLColor4 clr; | ||
437 | clr.setValue(sd); | ||
438 | color_swatch->setVisible(TRUE); | ||
439 | // only set if changed so color picker doesn't update | ||
440 | if(clr != LLColor4(color_swatch->getValue())) | ||
441 | { | ||
442 | color_swatch->set(LLColor4(sd), TRUE, FALSE); | ||
443 | } | ||
444 | spinner4->setVisible(TRUE); | ||
445 | spinner4->setLabel(LLString("Alpha")); | ||
446 | if (!spinner4->hasFocus()) | ||
447 | { | ||
448 | spinner4->setPrecision(3); | ||
449 | spinner4->setMinValue(0.0); | ||
450 | spinner4->setMaxValue(1.f); | ||
451 | spinner4->setValue(clr.mV[VALPHA]); | ||
452 | } | ||
453 | break; | ||
454 | } | ||
455 | case TYPE_COL3: | ||
456 | { | ||
457 | LLColor3 clr; | ||
458 | clr.setValue(sd); | ||
459 | color_swatch->setVisible(TRUE); | ||
460 | color_swatch->setValue(sd); | ||
461 | break; | ||
462 | } | ||
463 | case TYPE_COL4U: | ||
464 | { | ||
465 | LLColor4U clr; | ||
466 | clr.setValue(sd); | ||
467 | color_swatch->setVisible(TRUE); | ||
468 | if(LLColor4(clr) != LLColor4(color_swatch->getValue())) | ||
469 | { | ||
470 | color_swatch->set(LLColor4(clr), TRUE, FALSE); | ||
471 | } | ||
472 | spinner4->setVisible(TRUE); | ||
473 | spinner4->setLabel(LLString("Alpha")); | ||
474 | if(!spinner4->hasFocus()) | ||
475 | { | ||
476 | spinner4->setPrecision(0); | ||
477 | spinner4->setValue(clr.mV[VALPHA]); | ||
478 | } | ||
479 | |||
480 | spinner4->setMinValue(0); | ||
481 | spinner4->setMaxValue(255); | ||
482 | spinner4->setIncrement(1.f); | ||
483 | |||
484 | break; | ||
485 | } | ||
486 | default: | ||
487 | mComment->setText(LLString("unknown")); | ||
488 | break; | ||
489 | } | ||
490 | } | ||
491 | |||
492 | } | ||