Diffstat (limited to 'noncore/net/wellenreiter/gui/configwindow.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/net/wellenreiter/gui/configwindow.cpp | 103 |
1 files changed, 96 insertions, 7 deletions
diff --git a/noncore/net/wellenreiter/gui/configwindow.cpp b/noncore/net/wellenreiter/gui/configwindow.cpp index f536f4e..1341d03 100644 --- a/noncore/net/wellenreiter/gui/configwindow.cpp +++ b/noncore/net/wellenreiter/gui/configwindow.cpp | |||
@@ -4,52 +4,53 @@ | |||
4 | ** This file is part of Opie Environment. | 4 | ** This file is part of Opie Environment. |
5 | ** | 5 | ** |
6 | ** This file may be distributed and/or modified under the terms of the | 6 | ** This file may be distributed and/or modified under the terms of the |
7 | ** GNU General Public License version 2 as published by the Free Software | 7 | ** GNU General Public License version 2 as published by the Free Software |
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | 8 | ** Foundation and appearing in the file LICENSE.GPL included in the |
9 | ** packaging of this file. | 9 | ** packaging of this file. |
10 | ** | 10 | ** |
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | 11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE |
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | 12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
13 | ** | 13 | ** |
14 | **********************************************************************/ | 14 | **********************************************************************/ |
15 | 15 | ||
16 | /* LOCAL */ | 16 | /* LOCAL */ |
17 | #include "configwindow.h" | 17 | #include "configwindow.h" |
18 | #include "mainwindow.h" | 18 | #include "mainwindow.h" |
19 | 19 | ||
20 | /* OPIE */ | ||
21 | #include <opie2/onetwork.h> | ||
22 | #ifdef QWS | ||
23 | #include <opie2/oapplication.h> | ||
24 | #include <opie2/oconfig.h> | ||
25 | #endif | ||
26 | |||
20 | /* QT */ | 27 | /* QT */ |
21 | #include <qapplication.h> | 28 | #include <qapplication.h> |
22 | #include <qcheckbox.h> | 29 | #include <qcheckbox.h> |
23 | #include <qcombobox.h> | 30 | #include <qcombobox.h> |
24 | #include <qfile.h> | 31 | #include <qfile.h> |
25 | #include <qlineedit.h> | 32 | #include <qlineedit.h> |
26 | #include <qlayout.h> | 33 | #include <qlayout.h> |
27 | #include <qmap.h> | 34 | #include <qmap.h> |
28 | #include <qpushbutton.h> | 35 | #include <qpushbutton.h> |
36 | #include <qtabwidget.h> | ||
29 | #include <qtoolbutton.h> | 37 | #include <qtoolbutton.h> |
30 | #include <qspinbox.h> | 38 | #include <qspinbox.h> |
31 | #include <qtextstream.h> | 39 | #include <qtextstream.h> |
32 | 40 | ||
33 | /* OPIE */ | ||
34 | #include <opie2/onetwork.h> | ||
35 | |||
36 | #ifdef QWS | ||
37 | #include <opie2/oapplication.h> | ||
38 | #include <opie2/oconfig.h> | ||
39 | #endif | ||
40 | 41 | ||
41 | WellenreiterConfigWindow* WellenreiterConfigWindow::_instance = 0; | 42 | WellenreiterConfigWindow* WellenreiterConfigWindow::_instance = 0; |
42 | 43 | ||
43 | WellenreiterConfigWindow::WellenreiterConfigWindow( QWidget * parent, const char * name, WFlags f ) | 44 | WellenreiterConfigWindow::WellenreiterConfigWindow( QWidget * parent, const char * name, WFlags f ) |
44 | :WellenreiterConfigBase( parent, name, true, f ) | 45 | :WellenreiterConfigBase( parent, name, true, f ) |
45 | { | 46 | { |
46 | _devicetype[ "cisco" ] = DEVTYPE_CISCO; | 47 | _devicetype[ "cisco" ] = DEVTYPE_CISCO; |
47 | _devicetype[ "wlan-ng" ] = DEVTYPE_WLAN_NG; | 48 | _devicetype[ "wlan-ng" ] = DEVTYPE_WLAN_NG; |
48 | _devicetype[ "hostap" ] = DEVTYPE_HOSTAP; | 49 | _devicetype[ "hostap" ] = DEVTYPE_HOSTAP; |
49 | _devicetype[ "orinoco" ] = DEVTYPE_ORINOCO; | 50 | _devicetype[ "orinoco" ] = DEVTYPE_ORINOCO; |
50 | _devicetype[ "<manual>" ] = DEVTYPE_MANUAL; | 51 | _devicetype[ "<manual>" ] = DEVTYPE_MANUAL; |
51 | _devicetype[ "<file>" ] = DEVTYPE_FILE; | 52 | _devicetype[ "<file>" ] = DEVTYPE_FILE; |
52 | 53 | ||
53 | // gather possible interface names from ONetwork | 54 | // gather possible interface names from ONetwork |
54 | ONetwork* net = ONetwork::instance(); | 55 | ONetwork* net = ONetwork::instance(); |
55 | ONetwork::InterfaceIterator it = net->iterator(); | 56 | ONetwork::InterfaceIterator it = net->iterator(); |
@@ -59,38 +60,44 @@ WellenreiterConfigWindow::WellenreiterConfigWindow( QWidget * parent, const char | |||
59 | interfaceName->insertItem( it.current()->name() ); | 60 | interfaceName->insertItem( it.current()->name() ); |
60 | ++it; | 61 | ++it; |
61 | } | 62 | } |
62 | 63 | ||
63 | load(); | 64 | load(); |
64 | 65 | ||
65 | #ifdef Q_WS_X11 // We're on X11: adding an Ok-Button for the Dialog here | 66 | #ifdef Q_WS_X11 // We're on X11: adding an Ok-Button for the Dialog here |
66 | QPushButton* okButton = new QPushButton( "ok", this ); | 67 | QPushButton* okButton = new QPushButton( "ok", this ); |
67 | okButton->show(); | 68 | okButton->show(); |
68 | WellenreiterConfigBaseLayout->addWidget( okButton, 0, 3 ); //FIXME: rename this in configbase.ui | 69 | WellenreiterConfigBaseLayout->addWidget( okButton, 0, 3 ); //FIXME: rename this in configbase.ui |
69 | connect( okButton, SIGNAL( clicked() ), this, SLOT( accept() ) ); | 70 | connect( okButton, SIGNAL( clicked() ), this, SLOT( accept() ) ); |
70 | #endif | 71 | #endif |
71 | 72 | ||
72 | WellenreiterConfigWindow::_instance = this; | 73 | WellenreiterConfigWindow::_instance = this; |
73 | 74 | ||
74 | connect( deviceType, SIGNAL( activated(int) ), this, SLOT( changedDeviceType(int) ) ); | 75 | connect( deviceType, SIGNAL( activated(int) ), this, SLOT( changedDeviceType(int) ) ); |
76 | connect( newNetworkAction, SIGNAL( activated(int) ), this, SLOT( changedNetworkAction(int) ) ); | ||
77 | connect( newClientAction, SIGNAL( activated(int) ), this, SLOT( changedClientAction(int) ) ); | ||
78 | connect( newStationAction, SIGNAL( activated(int) ), this, SLOT( changedStationAction(int) ) ); | ||
75 | connect( getCaptureFileName, SIGNAL( clicked() ), this, SLOT( getCaptureFileNameClicked() ) ); | 79 | connect( getCaptureFileName, SIGNAL( clicked() ), this, SLOT( getCaptureFileNameClicked() ) ); |
76 | 80 | ||
77 | // make the checkbox 'channelAll' control all other channels | 81 | // make the checkbox 'channelAll' control all other channels |
78 | connect( channelAll, SIGNAL( stateChanged(int) ), this, SLOT( channelAllClicked(int) ) ); | 82 | connect( channelAll, SIGNAL( stateChanged(int) ), this, SLOT( channelAllClicked(int) ) ); |
79 | 83 | ||
80 | connect( autodetect, SIGNAL( clicked() ), this, SLOT( performAutodetection() ) ); | 84 | connect( autodetect, SIGNAL( clicked() ), this, SLOT( performAutodetection() ) ); |
85 | |||
86 | // hide tab4 (parse) until Wellenreiter 1.2 | ||
87 | tab->removePage( tab_4 ); | ||
81 | }; | 88 | }; |
82 | 89 | ||
83 | 90 | ||
84 | WellenreiterConfigWindow::~WellenreiterConfigWindow() | 91 | WellenreiterConfigWindow::~WellenreiterConfigWindow() |
85 | { | 92 | { |
86 | save(); | 93 | save(); |
87 | } | 94 | } |
88 | 95 | ||
89 | 96 | ||
90 | void WellenreiterConfigWindow::performAutodetection() | 97 | void WellenreiterConfigWindow::performAutodetection() |
91 | { | 98 | { |
92 | //TODO: insert modal splash screen here | 99 | //TODO: insert modal splash screen here |
93 | // and sleep a second, so that it looks | 100 | // and sleep a second, so that it looks |
94 | // like we're actually doing something fancy... ;-) | 101 | // like we're actually doing something fancy... ;-) |
95 | 102 | ||
96 | qDebug( "WellenreiterConfigWindow::performAutodetection()" ); | 103 | qDebug( "WellenreiterConfigWindow::performAutodetection()" ); |
@@ -172,32 +179,62 @@ void WellenreiterConfigWindow::changedDeviceType(int t) | |||
172 | { | 179 | { |
173 | if ( t != DEVTYPE_FILE ) return; | 180 | if ( t != DEVTYPE_FILE ) return; |
174 | QString name = ( (WellenreiterMainWindow*) qApp->mainWidget() )->getFileName(false); | 181 | QString name = ( (WellenreiterMainWindow*) qApp->mainWidget() )->getFileName(false); |
175 | if ( !name.isEmpty() && QFile::exists( name ) ) | 182 | if ( !name.isEmpty() && QFile::exists( name ) ) |
176 | { | 183 | { |
177 | interfaceName->insertItem( name ); | 184 | interfaceName->insertItem( name ); |
178 | interfaceName->setCurrentItem( interfaceName->count()-1 ); | 185 | interfaceName->setCurrentItem( interfaceName->count()-1 ); |
179 | } | 186 | } |
180 | else | 187 | else |
181 | { | 188 | { |
182 | deviceType->setCurrentItem( _guess ); | 189 | deviceType->setCurrentItem( _guess ); |
183 | } | 190 | } |
184 | 191 | ||
185 | } | 192 | } |
186 | 193 | ||
187 | 194 | ||
195 | void WellenreiterConfigWindow::synchronizeActionsAndScripts() | ||
196 | { | ||
197 | if ( newNetworkAction->currentItem() == 4 ) newNetworkScript->show(); else newNetworkScript->hide(); | ||
198 | if ( newClientAction->currentItem() == 4 ) newClientScript->show(); else newClientScript->hide(); | ||
199 | if ( newStationAction->currentItem() == 4 ) newStationScript->show(); else newStationScript->hide(); | ||
200 | |||
201 | //newNetworkScript->setEnabled( newNetworkAction->currentItem() == 4 ); | ||
202 | //newClientScript->setEnabled( newClientAction->currentItem() == 4 ); | ||
203 | //newStationScript->setEnabled( newStationAction->currentItem() == 4 ); | ||
204 | } | ||
205 | |||
206 | |||
207 | void WellenreiterConfigWindow::changedNetworkAction(int t) | ||
208 | { | ||
209 | synchronizeActionsAndScripts(); | ||
210 | } | ||
211 | |||
212 | |||
213 | void WellenreiterConfigWindow::changedClientAction(int t) | ||
214 | { | ||
215 | synchronizeActionsAndScripts(); | ||
216 | } | ||
217 | |||
218 | |||
219 | void WellenreiterConfigWindow::changedStationAction(int t) | ||
220 | { | ||
221 | synchronizeActionsAndScripts(); | ||
222 | } | ||
223 | |||
224 | |||
188 | void WellenreiterConfigWindow::getCaptureFileNameClicked() | 225 | void WellenreiterConfigWindow::getCaptureFileNameClicked() |
189 | { | 226 | { |
190 | QString name = ( (WellenreiterMainWindow*) qApp->mainWidget() )->getFileName(true); | 227 | QString name = ( (WellenreiterMainWindow*) qApp->mainWidget() )->getFileName(true); |
191 | qDebug( "name = %s", (const char*) name ); | 228 | qDebug( "name = %s", (const char*) name ); |
192 | if ( !name.isEmpty() ) | 229 | if ( !name.isEmpty() ) |
193 | { | 230 | { |
194 | captureFileName->setText( name ); | 231 | captureFileName->setText( name ); |
195 | } | 232 | } |
196 | } | 233 | } |
197 | 234 | ||
198 | 235 | ||
199 | void WellenreiterConfigWindow::channelAllClicked(int state) | 236 | void WellenreiterConfigWindow::channelAllClicked(int state) |
200 | { | 237 | { |
201 | bool b = state; | 238 | bool b = state; |
202 | channel1->setChecked( b ); | 239 | channel1->setChecked( b ); |
203 | channel2->setChecked( b ); | 240 | channel2->setChecked( b ); |
@@ -222,32 +259,71 @@ bool WellenreiterConfigWindow::useGPS() const | |||
222 | } | 259 | } |
223 | 260 | ||
224 | 261 | ||
225 | const QString WellenreiterConfigWindow::gpsHost() const | 262 | const QString WellenreiterConfigWindow::gpsHost() const |
226 | { | 263 | { |
227 | return useGPS() ? gpsdHost->currentText() : QString::null; | 264 | return useGPS() ? gpsdHost->currentText() : QString::null; |
228 | } | 265 | } |
229 | 266 | ||
230 | 267 | ||
231 | int WellenreiterConfigWindow::gpsPort() const | 268 | int WellenreiterConfigWindow::gpsPort() const |
232 | { | 269 | { |
233 | bool ok; | 270 | bool ok; |
234 | return useGPS() ? gpsdPort->value() : -1; | 271 | return useGPS() ? gpsdPort->value() : -1; |
235 | } | 272 | } |
236 | 273 | ||
237 | 274 | ||
275 | void WellenreiterConfigWindow::performAction( const QString& type ) | ||
276 | { | ||
277 | int action; | ||
278 | QString script; | ||
279 | |||
280 | if ( type == "network" ) | ||
281 | { | ||
282 | action = newNetworkAction->currentItem(); | ||
283 | script = newNetworkScript->text(); | ||
284 | } | ||
285 | else if ( type == "managed" || type == "adhoc" ) | ||
286 | { | ||
287 | action = newClientAction->currentItem(); | ||
288 | script = newClientScript->text(); | ||
289 | } | ||
290 | else if ( type == "station" ) | ||
291 | { | ||
292 | action = newStationAction->currentItem(); | ||
293 | script = newStationScript->text(); | ||
294 | } | ||
295 | else | ||
296 | { | ||
297 | qWarning( "WellenreiterConfigWindow::performAction(): unknown type '%s'", (const char*) type ); | ||
298 | return; | ||
299 | } | ||
300 | |||
301 | qDebug( "going to perform action %d (script='%s')", action, (const char*) script ); | ||
302 | |||
303 | /* | ||
304 | |||
305 | if ( sound == "Ignore" ) return; | ||
306 | else if ( sound == "Touch" ) ODevice::inst()->touchSound(); | ||
307 | else if ( sound == "Key" ) ODevice::inst()->keySound(); | ||
308 | else if ( sound == "Alarm" ) ODevice::inst()->alarmSound(); | ||
309 | |||
310 | */ | ||
311 | } | ||
312 | |||
313 | |||
238 | void WellenreiterConfigWindow::load() | 314 | void WellenreiterConfigWindow::load() |
239 | { | 315 | { |
240 | #ifdef Q_WS_X11 | 316 | #ifdef Q_WS_X11 |
241 | #warning Persistent Configuration not yet implemented for standalone X11 build | 317 | #warning Persistent Configuration not yet implemented for standalone X11 build |
242 | performAutodetection(); | 318 | performAutodetection(); |
243 | #else | 319 | #else |
244 | qDebug( "loading configuration settings..." ); | 320 | qDebug( "loading configuration settings..." ); |
245 | 321 | ||
246 | /* This is dumb monkey typing stuff... We _need_ to do this automatically! */ | 322 | /* This is dumb monkey typing stuff... We _need_ to do this automatically! */ |
247 | 323 | ||
248 | OConfig* c = oApp->config(); | 324 | OConfig* c = oApp->config(); |
249 | 325 | ||
250 | c->setGroup( "Interface" ); | 326 | c->setGroup( "Interface" ); |
251 | 327 | ||
252 | QString interface = c->readEntry( "name", "<none>" ); | 328 | QString interface = c->readEntry( "name", "<none>" ); |
253 | if ( interface != "<none>" ) | 329 | if ( interface != "<none>" ) |
@@ -277,32 +353,39 @@ void WellenreiterConfigWindow::load() | |||
277 | { | 353 | { |
278 | performAutodetection(); | 354 | performAutodetection(); |
279 | } | 355 | } |
280 | 356 | ||
281 | prismHeader->setChecked( c->readBoolEntry( "prism", false ) ); | 357 | prismHeader->setChecked( c->readBoolEntry( "prism", false ) ); |
282 | hopChannels->setChecked( c->readBoolEntry( "hop", true ) ); | 358 | hopChannels->setChecked( c->readBoolEntry( "hop", true ) ); |
283 | hopInterval->setValue( c->readNumEntry( "interval", 250 ) ); | 359 | hopInterval->setValue( c->readNumEntry( "interval", 250 ) ); |
284 | adaptiveHopping->setChecked( c->readBoolEntry( "adaptive", true ) ); | 360 | adaptiveHopping->setChecked( c->readBoolEntry( "adaptive", true ) ); |
285 | 361 | ||
286 | c->setGroup( "Capture" ); | 362 | c->setGroup( "Capture" ); |
287 | captureFileName->setText( c->readEntry( "filename", "/tmp/capture" ) ); | 363 | captureFileName->setText( c->readEntry( "filename", "/tmp/capture" ) ); |
288 | 364 | ||
289 | c->setGroup( "UI" ); | 365 | c->setGroup( "UI" ); |
290 | lookupVendor->setChecked( c->readBoolEntry( "lookupVendor", true ) ); | 366 | lookupVendor->setChecked( c->readBoolEntry( "lookupVendor", true ) ); |
291 | openTree->setChecked( c->readBoolEntry( "openTree", true ) ); | 367 | openTree->setChecked( c->readBoolEntry( "openTree", true ) ); |
292 | disablePM->setChecked( c->readBoolEntry( "disablePM", true ) ); | 368 | disablePM->setChecked( c->readBoolEntry( "disablePM", true ) ); |
369 | newNetworkAction->setCurrentItem( c->readNumEntry( "newNetworkAction", 0 ) ); | ||
370 | newNetworkScript->setText( c->readEntry( "newNetworkScript", "" ) ); | ||
371 | newClientAction->setCurrentItem( c->readNumEntry( "newClientAction", 0 ) ); | ||
372 | newClientScript->setText( c->readEntry( "newClientScript", "" ) ); | ||
373 | newStationAction->setCurrentItem( c->readNumEntry( "newStationAction", 0 ) ); | ||
374 | newStationScript->setText( c->readEntry( "newStationScript", "" ) ); | ||
375 | synchronizeActionsAndScripts(); // needed for showing/hiding the script QLineEdit on demand | ||
293 | 376 | ||
294 | c->setGroup( "GPS" ); | 377 | c->setGroup( "GPS" ); |
295 | enableGPS->setChecked( c->readBoolEntry( "use", false ) ); | 378 | enableGPS->setChecked( c->readBoolEntry( "use", false ) ); |
296 | #if QT_VERSION < 300 | 379 | #if QT_VERSION < 300 |
297 | gpsdHost->insertItem( c->readEntry( "host", "localhost" ), 0 ); | 380 | gpsdHost->insertItem( c->readEntry( "host", "localhost" ), 0 ); |
298 | gpsdHost->setCurrentItem( 0 ); | 381 | gpsdHost->setCurrentItem( 0 ); |
299 | #else | 382 | #else |
300 | gpsdHost->setCurrentText( c->readEntry( "host", "localhost" ) ); | 383 | gpsdHost->setCurrentText( c->readEntry( "host", "localhost" ) ); |
301 | #endif | 384 | #endif |
302 | gpsdPort->setValue( c->readNumEntry( "port", 2947 ) ); | 385 | gpsdPort->setValue( c->readNumEntry( "port", 2947 ) ); |
303 | startGPS->setChecked( c->readBoolEntry( "start", false ) ); | 386 | startGPS->setChecked( c->readBoolEntry( "start", false ) ); |
304 | commandGPS->setText( c->readEntry( "command", "gpsd -p /dev/ttyS3 -s 57600" ) ); | 387 | commandGPS->setText( c->readEntry( "command", "gpsd -p /dev/ttyS3 -s 57600" ) ); |
305 | 388 | ||
306 | #endif | 389 | #endif |
307 | } | 390 | } |
308 | 391 | ||
@@ -320,28 +403,34 @@ void WellenreiterConfigWindow::save() | |||
320 | 403 | ||
321 | c->setGroup( "Interface" ); | 404 | c->setGroup( "Interface" ); |
322 | c->writeEntry( "name", interfaceName->currentText() ); | 405 | c->writeEntry( "name", interfaceName->currentText() ); |
323 | c->writeEntry( "type", deviceType->currentText() ); | 406 | c->writeEntry( "type", deviceType->currentText() ); |
324 | c->writeEntry( "prism", prismHeader->isChecked() ); | 407 | c->writeEntry( "prism", prismHeader->isChecked() ); |
325 | c->writeEntry( "hop", hopChannels->isChecked() ); | 408 | c->writeEntry( "hop", hopChannels->isChecked() ); |
326 | c->writeEntry( "interval", hopInterval->value() ); | 409 | c->writeEntry( "interval", hopInterval->value() ); |
327 | c->writeEntry( "adaptive", adaptiveHopping->isChecked() ); | 410 | c->writeEntry( "adaptive", adaptiveHopping->isChecked() ); |
328 | 411 | ||
329 | c->setGroup( "Capture" ); | 412 | c->setGroup( "Capture" ); |
330 | c->writeEntry( "filename", captureFileName->text() ); | 413 | c->writeEntry( "filename", captureFileName->text() ); |
331 | 414 | ||
332 | c->setGroup( "UI" ); | 415 | c->setGroup( "UI" ); |
333 | c->writeEntry( "lookupVendor", lookupVendor->isChecked() ); | 416 | c->writeEntry( "lookupVendor", lookupVendor->isChecked() ); |
334 | c->writeEntry( "openTree", openTree->isChecked() ); | 417 | c->writeEntry( "openTree", openTree->isChecked() ); |
335 | c->writeEntry( "disablePM", disablePM->isChecked() ); | 418 | c->writeEntry( "disablePM", disablePM->isChecked() ); |
419 | c->writeEntry( "newNetworkAction", newNetworkAction->currentItem() ); | ||
420 | c->writeEntry( "newNetworkScript", newNetworkScript->text() ); | ||
421 | c->writeEntry( "newClientAction", newClientAction->currentItem() ); | ||
422 | c->writeEntry( "newClientScript", newClientScript->text() ); | ||
423 | c->writeEntry( "newStationAction", newStationAction->currentItem() ); | ||
424 | c->writeEntry( "newStationScript", newStationScript->text() ); | ||
336 | 425 | ||
337 | c->setGroup( "GPS" ); | 426 | c->setGroup( "GPS" ); |
338 | c->writeEntry( "use", enableGPS->isChecked() ); | 427 | c->writeEntry( "use", enableGPS->isChecked() ); |
339 | c->writeEntry( "host", gpsdHost->currentText() ); | 428 | c->writeEntry( "host", gpsdHost->currentText() ); |
340 | c->writeEntry( "port", gpsdPort->value() ); | 429 | c->writeEntry( "port", gpsdPort->value() ); |
341 | c->writeEntry( "start", startGPS->isChecked() ); | 430 | c->writeEntry( "start", startGPS->isChecked() ); |
342 | c->writeEntry( "command", commandGPS->text() ); | 431 | c->writeEntry( "command", commandGPS->text() ); |
343 | 432 | ||
344 | c->write(); | 433 | c->write(); |
345 | 434 | ||
346 | #endif | 435 | #endif |
347 | } | 436 | } |